From: Luo Xionghu <[email protected]> 1. WHILE instruction should be non-schedulable. 2. if this WHILE instruction jumps to an ELSE instruction, the distance need add 2.
Signed-off-by: Luo Xionghu <[email protected]> --- backend/src/backend/gen_context.cpp | 10 ++++++++++ backend/src/backend/gen_encoder.cpp | 11 +++++++++++ backend/src/backend/gen_encoder.hpp | 2 ++ backend/src/backend/gen_insn_scheduling.cpp | 2 +- backend/src/backend/gen_insn_selection.cpp | 20 ++++++++++++++++++++ backend/src/backend/gen_insn_selection.hxx | 1 + backend/src/ir/structural_analysis.cpp | 2 +- 7 files changed, 46 insertions(+), 2 deletions(-) diff --git a/backend/src/backend/gen_context.cpp b/backend/src/backend/gen_context.cpp index ba4a8f8..6cbfa43 100644 --- a/backend/src/backend/gen_context.cpp +++ b/backend/src/backend/gen_context.cpp @@ -254,6 +254,16 @@ namespace gbe p->ELSE(src); } break; + case SEL_OP_WHILE: + { + /*const ir::LabelIndex label0(insn.index), label1(insn.index1); + const LabelPair labelPair(label0, label1); + const GenRegister src = ra->genReg(insn.src(0)); + this->branchPos3.push_back(std::make_pair(labelPair, p->store.size()));*/ + insertJumpPos(insn); + p->WHILE(src); + } + break; default: NOT_IMPLEMENTED; } } diff --git a/backend/src/backend/gen_encoder.cpp b/backend/src/backend/gen_encoder.cpp index c67e85e..295e11d 100644 --- a/backend/src/backend/gen_encoder.cpp +++ b/backend/src/backend/gen_encoder.cpp @@ -1026,6 +1026,7 @@ namespace gbe ALU2_BRA(IF) ALU2_BRA(ELSE) ALU2_BRA(ENDIF) + ALU2_BRA(WHILE) ALU2_BRA(BRD) ALU2_BRA(BRC) @@ -1037,8 +1038,18 @@ namespace gbe insn.header.opcode == GEN_OPCODE_ENDIF || insn.header.opcode == GEN_OPCODE_IF || insn.header.opcode == GEN_OPCODE_BRC || + insn.header.opcode == GEN_OPCODE_WHILE || insn.header.opcode == GEN_OPCODE_ELSE); + if( insn.header.opcode == GEN_OPCODE_WHILE ){ + // if this WHILE instruction jump back to an ELSE instruction, + // need add distance to go to the next instruction. + GenNativeInstruction & insn_else = *(GenNativeInstruction *)&this->store[insnID+jumpDistance]; + if(insn_else.header.opcode == GEN_OPCODE_ELSE){ + jumpDistance += 2; + } + } + if (insn.header.opcode != GEN_OPCODE_JMPI || (jumpDistance > -32769 && jumpDistance < 32768)) { if (insn.header.opcode == GEN_OPCODE_IF) { this->setSrc1(&insn, GenRegister::immd(jumpDistance)); diff --git a/backend/src/backend/gen_encoder.hpp b/backend/src/backend/gen_encoder.hpp index 9844eb8..2c999ce 100644 --- a/backend/src/backend/gen_encoder.hpp +++ b/backend/src/backend/gen_encoder.hpp @@ -154,6 +154,8 @@ namespace gbe void ELSE(GenRegister src); /*! ENDIF indexed instruction */ void ENDIF(GenRegister src); + /*! WHILE indexed instruction */ + void WHILE(GenRegister src); /*! BRC indexed instruction */ void BRC(GenRegister src); /*! BRD indexed instruction */ diff --git a/backend/src/backend/gen_insn_scheduling.cpp b/backend/src/backend/gen_insn_scheduling.cpp index 4324206..035a021 100644 --- a/backend/src/backend/gen_insn_scheduling.cpp +++ b/backend/src/backend/gen_insn_scheduling.cpp @@ -590,7 +590,7 @@ namespace gbe for (int32_t insnID = 0; insnID < insnNum; ++insnID) { ScheduleDAGNode *node = tracker.insnNodes[insnID]; if (node->insn.isBranch() || node->insn.isLabel() - || node->insn.opcode == SEL_OP_EOT || node->insn.opcode == SEL_OP_IF + || node->insn.opcode == SEL_OP_EOT || node->insn.opcode == SEL_OP_IF || node->insn.opcode == SEL_OP_WHILE || node->insn.opcode == SEL_OP_BARRIER) tracker.makeBarrier(insnID, insnNum); } diff --git a/backend/src/backend/gen_insn_selection.cpp b/backend/src/backend/gen_insn_selection.cpp index 170a9d8..4509072 100644 --- a/backend/src/backend/gen_insn_selection.cpp +++ b/backend/src/backend/gen_insn_selection.cpp @@ -543,6 +543,8 @@ namespace gbe void ELSE(Reg src, ir::LabelIndex jip, ir::LabelIndex elseLabel); /*! ENDIF indexed instruction */ void ENDIF(Reg src, ir::LabelIndex jip, ir::LabelIndex endifLabel = ir::LabelIndex(0)); + /*! WHILE indexed instruction */ + void WHILE(Reg src, ir::LabelIndex jip); /*! BRD indexed instruction */ void BRD(Reg src, ir::LabelIndex jip); /*! BRC indexed instruction */ @@ -1062,6 +1064,12 @@ namespace gbe insn->index = uint16_t(this->block->endifLabel); } + void Selection::Opaque::WHILE(Reg src, ir::LabelIndex jip) { + SelectionInstruction *insn = this->appendInsn(SEL_OP_WHILE, 0, 1); + insn->src(0) = src; + insn->index = uint16_t(jip); + } + void Selection::Opaque::CMP(uint32_t conditional, Reg src0, Reg src1, Reg dst) { SelectionInstruction *insn = this->appendInsn(SEL_OP_CMP, 1, 2); insn->src(0) = src0; @@ -4033,6 +4041,18 @@ namespace gbe } else if(opcode == OP_ELSE) { const LabelIndex label = insn.getLabelIndex(); sel.ELSE(GenRegister::immd(0), label, insn.getParent()->thisElseLabel); + } else if(opcode == OP_WHILE) { + 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.pop(); } else NOT_IMPLEMENTED; diff --git a/backend/src/backend/gen_insn_selection.hxx b/backend/src/backend/gen_insn_selection.hxx index 2d70982..0e773f5 100644 --- a/backend/src/backend/gen_insn_selection.hxx +++ b/backend/src/backend/gen_insn_selection.hxx @@ -85,3 +85,4 @@ DECL_SELECTION_IR(BRD, UnaryInstruction) DECL_SELECTION_IR(IF, UnaryInstruction) DECL_SELECTION_IR(ENDIF, UnaryInstruction) DECL_SELECTION_IR(ELSE, UnaryInstruction) +DECL_SELECTION_IR(WHILE, UnaryInstruction) diff --git a/backend/src/ir/structural_analysis.cpp b/backend/src/ir/structural_analysis.cpp index 1c4bf40..0b37b61 100644 --- a/backend/src/ir/structural_analysis.cpp +++ b/backend/src/ir/structural_analysis.cpp @@ -873,7 +873,7 @@ namespace analysis { Node* p = new SelfLoopNode(node); - p->canBeHandled = false; + p->canBeHandled = true; return insertNode(p); } -- 1.7.9.5 _______________________________________________ Beignet mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/beignet
