[Beignet] [PATCH V2 3/5] Use instruction WHILE to manipulate structure.
Zhigang Gong
zhigang.gong at intel.com
Tue Sep 23 00:02:55 PDT 2014
From: Luo Xionghu <xionghu.luo at intel.com>
1. WHILE instruction should be non-schedulable.
2. if this WHILE instruction jumps to an ELSE instruction, the distance
need add 2.
v2:
We also need to take care of HSW for while instruction.
Signed-off-by: Luo Xionghu <xionghu.luo at intel.com>
Signed-off-by: Zhigang Gong <zhigang.gong at intel.com>
---
backend/src/backend/gen75_encoder.cpp | 22 +++++++++++++++-------
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 +-
8 files changed, 61 insertions(+), 9 deletions(-)
diff --git a/backend/src/backend/gen75_encoder.cpp b/backend/src/backend/gen75_encoder.cpp
index 321e07b..724865b 100644
--- a/backend/src/backend/gen75_encoder.cpp
+++ b/backend/src/backend/gen75_encoder.cpp
@@ -254,17 +254,25 @@ 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_IF) {
- this->setSrc1(&insn, GenRegister::immd(jumpDistance));
- return;
+ 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;
+ }
}
- else if (insn.header.opcode == GEN_OPCODE_JMPI) {
- //jumpDistance'unit is Qword, and the HSW's offset of jmpi is in byte, so multi 8
+
+ if (insn.header.opcode != GEN_OPCODE_JMPI)
+ this->setSrc1(&insn, GenRegister::immd(jumpDistance));
+ else {
+ //jumpDistance'unit is Qword, and the HSW's JMPI offset of jmpi is in byte, so multi 8
jumpDistance = (jumpDistance - 2) * 8;
+ this->setSrc1(&insn, GenRegister::immd(jumpDistance));
}
-
- this->setSrc1(&insn, GenRegister::immd(jumpDistance));
+ return;
}
} /* End of the name space. */
diff --git a/backend/src/backend/gen_context.cpp b/backend/src/backend/gen_context.cpp
index 175878d..8844233 100644
--- a/backend/src/backend/gen_context.cpp
+++ b/backend/src/backend/gen_context.cpp
@@ -255,6 +255,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 ead3e26..58ab69f 100644
--- a/backend/src/backend/gen_insn_scheduling.cpp
+++ b/backend/src/backend/gen_insn_scheduling.cpp
@@ -588,7 +588,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_READ_ARF
|| 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 f284ae1..e3ee35d 100644
--- a/backend/src/backend/gen_insn_selection.cpp
+++ b/backend/src/backend/gen_insn_selection.cpp
@@ -544,6 +544,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 */
@@ -1063,6 +1065,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;
@@ -4217,6 +4225,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 048a844..7511b84 100644
--- a/backend/src/backend/gen_insn_selection.hxx
+++ b/backend/src/backend/gen_insn_selection.hxx
@@ -86,3 +86,4 @@ DECL_SELECTION_IR(IF, UnaryInstruction)
DECL_SELECTION_IR(ENDIF, UnaryInstruction)
DECL_SELECTION_IR(ELSE, UnaryInstruction)
DECL_SELECTION_IR(READ_ARF, UnaryInstruction)
+DECL_SELECTION_IR(WHILE, UnaryInstruction)
diff --git a/backend/src/ir/structural_analysis.cpp b/backend/src/ir/structural_analysis.cpp
index 1860ee9..040a7e0 100644
--- a/backend/src/ir/structural_analysis.cpp
+++ b/backend/src/ir/structural_analysis.cpp
@@ -867,7 +867,7 @@ namespace analysis
{
Node* p = new SelfLoopNode(node);
- p->canBeHandled = false;
+ p->canBeHandled = true;
return insertNode(p);
}
--
1.8.3.2
More information about the Beignet
mailing list