diff options
author | Luo Xionghu <xionghu.luo@intel.com> | 2014-10-17 11:33:23 +0800 |
---|---|---|
committer | Zhigang Gong <zhigang.gong@intel.com> | 2014-10-23 09:15:09 +0800 |
commit | 2edb7451a8f92295f79e29ef16740b5cd16127f2 (patch) | |
tree | ef19452c3bc4594ecfd38af25d36fca9ec152b4c | |
parent | 8fe98a5e87f7f06176b29ddfcd9f62d0fc280d60 (diff) |
use global flag 0.0 to control unstructured simple block.
filter the simple block out and replace the if/endif with global flag
to control.
v2: fix the luxmark sala performance degression due to extern flag in a
BRA instruction.
v3: fix compiler_switch regression, LOAD/STORE instruction could
call replaceSrc/replaceDst to generate 2 extra MOV instruction; exclude
the scalar instructions since they don't have prediction.
this patch is somewhat dangerous to change the instruction structure of block,
will add sanity check after emitInstructionStream to assert if illegally
modified.
Signed-off-by: Luo Xionghu <xionghu.luo@intel.com>
Reviewed-by: Zhigang Gong <zhigang.gong@intel.com>
-rw-r--r-- | backend/src/backend/gen_insn_selection.cpp | 107 | ||||
-rw-r--r-- | backend/src/backend/gen_insn_selection.hpp | 1 | ||||
-rw-r--r-- | backend/src/backend/gen_reg_allocation.cpp | 3 |
3 files changed, 88 insertions, 23 deletions
diff --git a/backend/src/backend/gen_insn_selection.cpp b/backend/src/backend/gen_insn_selection.cpp index 5ca363a3..410f6b59 100644 --- a/backend/src/backend/gen_insn_selection.cpp +++ b/backend/src/backend/gen_insn_selection.cpp @@ -217,7 +217,7 @@ namespace gbe // SelectionBlock /////////////////////////////////////////////////////////////////////////// - SelectionBlock::SelectionBlock(const ir::BasicBlock *bb) : bb(bb), isLargeBlock(false), endifLabel( (ir::LabelIndex) 0){} + SelectionBlock::SelectionBlock(const ir::BasicBlock *bb) : bb(bb), isLargeBlock(false), endifLabel( (ir::LabelIndex) 0), removeSimpleIfEndif(false){} void SelectionBlock::append(ir::Register reg) { tmp.push_back(reg); } @@ -405,6 +405,8 @@ namespace gbe uint32_t buildBasicBlockDAG(const ir::BasicBlock &bb); /*! Perform the selection on the basic block */ void matchBasicBlock(const ir::BasicBlock &bb, uint32_t insnNum); + /*! a simple block can use predication instead of if/endif*/ + bool isSimpleBlock(const ir::BasicBlock &bb, uint32_t insnNum); /*! A root instruction needs to be generated */ bool isRoot(const ir::Instruction &insn) const; @@ -925,6 +927,11 @@ namespace gbe SelectionInstruction *mov = this->create(SEL_OP_MOV, 1, 1); mov->src(0) = GenRegister::retype(insn->src(regID), gr.type); mov->state = GenInstructionState(simdWidth); + if(this->block->removeSimpleIfEndif){ + mov->state.predicate = GEN_PREDICATE_NORMAL; + mov->state.flag = 0; + mov->state.subFlag = 0; + } if (this->isScalarReg(insn->src(regID).reg())) mov->state.noMask = 1; mov->dst(0) = gr; @@ -954,6 +961,11 @@ namespace gbe SelectionInstruction *mov = this->create(SEL_OP_MOV, 1, 1); mov->dst(0) = GenRegister::retype(insn->dst(regID), gr.type); mov->state = GenInstructionState(simdWidth); + if(this->block->removeSimpleIfEndif){ + mov->state.predicate = GEN_PREDICATE_NORMAL; + mov->state.flag = 0; + mov->state.subFlag = 0; + } if (simdWidth == 1) { mov->state.noMask = 1; mov->src(0) = GenRegister::retype(GenRegister::vec1(GEN_GENERAL_REGISTER_FILE, gr.reg()), gr.type); @@ -1482,6 +1494,40 @@ namespace gbe return false; } + bool Selection::Opaque::isSimpleBlock(const ir::BasicBlock &bb, uint32_t insnNum) { + + // FIXME should include structured innermost if/else/endif + if(bb.belongToStructure) + return false; + + // FIXME scalar reg should not be excluded and just need some special handling. + for (int32_t insnID = insnNum-1; insnID >= 0; --insnID) { + SelectionDAG &dag = *insnDAG[insnID]; + const ir::Instruction& insn = dag.insn; + if ( (insn.getDstNum() && this->isScalarReg(insn.getDst(0)) == true) || + insn.isMemberOf<ir::CompareInstruction>() || + insn.isMemberOf<ir::SelectInstruction>() || + insn.getOpcode() == ir::OP_SIMD_ANY || + insn.getOpcode() == ir::OP_SIMD_ALL || + insn.getOpcode() == ir::OP_ELSE) + return false; + } + + // there would generate a extra CMP instruction for predicated BRA with extern flag, + // should retrun false to keep the if/endif. + if((insnDAG[insnNum-1]->insn.isMemberOf<ir::BranchInstruction>())){ + if (insnDAG[insnNum-1]->insn.getOpcode() == ir::OP_BRA) { + const ir::BranchInstruction &insn = ir::cast<ir::BranchInstruction>(insnDAG[insnNum-1]->insn); + if(insn.isPredicated() && insnDAG[insnNum-1]->child[0] == NULL){ + return false; + } + } + } + + return true; + } + + uint32_t Selection::Opaque::buildBasicBlockDAG(const ir::BasicBlock &bb) { using namespace ir; @@ -1562,7 +1608,8 @@ namespace gbe // Bottom up code generation bool needEndif = this->block->hasBranch == false && !this->block->hasBarrier; needEndif = needEndif && bb.needEndif; - if (needEndif) { + this->block->removeSimpleIfEndif = insnNum < 10 && isSimpleBlock(bb, insnNum); + if (needEndif && !this->block->removeSimpleIfEndif) { if(!bb.needIf) // this basic block is the exit of a structure this->ENDIF(GenRegister::immd(0), bb.endifLabel, bb.endifLabel); else { @@ -1583,6 +1630,13 @@ namespace gbe // Start a new code fragment this->startBackwardGeneration(); + + if(this->block->removeSimpleIfEndif){ + this->push(); + this->curr.predicate = GEN_PREDICATE_NORMAL; + this->curr.flag = 0; + this->curr.subFlag = 0; + } // If there is no branch at the end of this block. // Try all the patterns from best to worst @@ -1592,6 +1646,13 @@ namespace gbe ++it; } while (it != end); GBE_ASSERT(it != end); + + if(this->block->removeSimpleIfEndif){ + this->curr.predicate = GEN_PREDICATE_NONE; + this->curr.flag = 0; + this->curr.subFlag = 0; + this->pop(); + } // If we are in if/endif fix mode, and this block is // large enough, we need to insert endif/if pair to eliminate // the too long if/endif block. @@ -3852,15 +3913,17 @@ namespace gbe sel.JMPI(GenRegister::immd(0), jip, label); sel.pop(); } - sel.push(); - sel.curr.predicate = GEN_PREDICATE_NORMAL; - if(!insn.getParent()->needEndif && insn.getParent()->needIf) { - ir::LabelIndex label = insn.getParent()->endifLabel; - sel.IF(GenRegister::immd(0), label, label); - } - else - sel.IF(GenRegister::immd(0), sel.block->endifLabel, sel.block->endifLabel); - sel.pop(); + if(!sel.block->removeSimpleIfEndif){ + sel.push(); + sel.curr.predicate = GEN_PREDICATE_NORMAL; + if(!insn.getParent()->needEndif && insn.getParent()->needIf) { + ir::LabelIndex label = insn.getParent()->endifLabel; + sel.IF(GenRegister::immd(0), label, label); + } + else + sel.IF(GenRegister::immd(0), sel.block->endifLabel, sel.block->endifLabel); + sel.pop(); + } } return true; @@ -4121,7 +4184,7 @@ namespace gbe sel.curr.predicate = GEN_PREDICATE_NORMAL; sel.MOV(ip, GenRegister::immuw(uint16_t(dst))); sel.curr.predicate = GEN_PREDICATE_NONE; - if (!sel.block->hasBarrier) + if (!sel.block->hasBarrier && !sel.block->removeSimpleIfEndif) sel.ENDIF(GenRegister::immd(0), nextLabel); sel.block->endifOffset = -1; sel.pop(); @@ -4131,7 +4194,7 @@ namespace gbe if(insn.getParent()->needEndif) sel.MOV(ip, GenRegister::immuw(uint16_t(dst))); - if (!sel.block->hasBarrier) { + if (!sel.block->hasBarrier && !sel.block->removeSimpleIfEndif) { if(insn.getParent()->needEndif && !insn.getParent()->needIf) sel.ENDIF(GenRegister::immd(0), insn.getParent()->endifLabel, insn.getParent()->endifLabel); else if(insn.getParent()->needEndif) @@ -4179,7 +4242,7 @@ namespace gbe sel.MOV(ip, GenRegister::immuw(uint16_t(dst))); sel.block->endifOffset = -1; sel.curr.predicate = GEN_PREDICATE_NONE; - if (!sel.block->hasBarrier) + if (!sel.block->hasBarrier && !sel.block->removeSimpleIfEndif) sel.ENDIF(GenRegister::immd(0), next); sel.curr.execWidth = 1; if (simdWidth == 16) @@ -4195,7 +4258,7 @@ namespace gbe if(insn.getParent()->needEndif) sel.MOV(ip, GenRegister::immuw(uint16_t(dst))); sel.block->endifOffset = -1; - if (!sel.block->hasBarrier) { + if (!sel.block->hasBarrier && !sel.block->removeSimpleIfEndif) { if(insn.getParent()->needEndif && !insn.getParent()->needIf) sel.ENDIF(GenRegister::immd(0), insn.getParent()->endifLabel, insn.getParent()->endifLabel); else if(insn.getParent()->needEndif) @@ -4265,13 +4328,13 @@ namespace gbe const Register pred = insn.getPredicateIndex(); const LabelIndex jip = insn.getLabelIndex(); sel.push(); - sel.curr.physicalFlag = 0; - sel.curr.flagIndex = (uint64_t)pred; - sel.curr.externFlag = 1; - sel.curr.inversePredicate = insn.getInversePredicated(); - sel.curr.predicate = GEN_PREDICATE_NORMAL; - sel.WHILE(GenRegister::immd(0), jip); - sel.curr.inversePredicate = 0; + sel.curr.physicalFlag = 0; + sel.curr.flagIndex = (uint64_t)pred; + sel.curr.externFlag = 1; + sel.curr.inversePredicate = insn.getInversePredicated(); + sel.curr.predicate = GEN_PREDICATE_NORMAL; + sel.WHILE(GenRegister::immd(0), jip); + sel.curr.inversePredicate = 0; sel.pop(); } else NOT_IMPLEMENTED; diff --git a/backend/src/backend/gen_insn_selection.hpp b/backend/src/backend/gen_insn_selection.hpp index e39aa6ef..761c5c1c 100644 --- a/backend/src/backend/gen_insn_selection.hpp +++ b/backend/src/backend/gen_insn_selection.hpp @@ -233,6 +233,7 @@ namespace gbe int endifOffset; bool hasBarrier; bool hasBranch; + bool removeSimpleIfEndif; }; /*! Owns the selection engine */ diff --git a/backend/src/backend/gen_reg_allocation.cpp b/backend/src/backend/gen_reg_allocation.cpp index 067c9ce0..a57edb3f 100644 --- a/backend/src/backend/gen_reg_allocation.cpp +++ b/backend/src/backend/gen_reg_allocation.cpp @@ -1072,7 +1072,8 @@ namespace gbe insn.opcode == SEL_OP_JMPI || insn.state.predicate == GEN_PREDICATE_NONE || (block.hasBarrier && insn.opcode == SEL_OP_MOV) || - (insn.state.flag == 0 && insn.state.subFlag == 1))); + (insn.state.flag == 0 && insn.state.subFlag == 1) || + (block.removeSimpleIfEndif && insn.state.flag == 0 && insn.state.subFlag == 0) )); } lastID = insnID; insnID++; |