[Beignet] [PATCH 4/7] Backend: Refine instruction ID for sel ir
Xiuli Pan
xiuli.pan at intel.com
Mon Nov 14 08:20:05 UTC 2016
From: Pan Xiuli <xiuli.pan at intel.com>
We now make each sel ir instruction with ID of step 2. Thus we can spilt
src and dst in simple instruction into different ID. We should re-number
the instruction in case pre reg alloction schedule change the instruction
order.
Signed-off-by: Pan Xiuli <xiuli.pan at intel.com>
---
backend/src/backend/gen_context.cpp | 2 ++
backend/src/backend/gen_insn_selection.cpp | 31 ++++++++++++++++++++++
backend/src/backend/gen_insn_selection.hpp | 4 +++
.../src/backend/gen_insn_selection_optimize.cpp | 10 +++++++
backend/src/backend/gen_insn_selection_output.cpp | 1 +
backend/src/backend/gen_reg_allocation.cpp | 12 ++++++---
6 files changed, 56 insertions(+), 4 deletions(-)
diff --git a/backend/src/backend/gen_context.cpp b/backend/src/backend/gen_context.cpp
index d16085d..a9820e0 100644
--- a/backend/src/backend/gen_context.cpp
+++ b/backend/src/backend/gen_context.cpp
@@ -4036,9 +4036,11 @@ namespace gbe
sel->select();
if (OCL_OPTIMIZE_SEL_IR)
sel->optimize();
+ sel->addID();
if (OCL_OUTPUT_SEL_IR)
outputSelectionIR(*this, this->sel, genKernel->getName());
schedulePreRegAllocation(*this, *this->sel);
+ sel->addID();
if (UNLIKELY(ra->allocate(*this->sel) == false))
return false;
schedulePostRegAllocation(*this, *this->sel);
diff --git a/backend/src/backend/gen_insn_selection.cpp b/backend/src/backend/gen_insn_selection.cpp
index 5adcaed..b8ef523 100644
--- a/backend/src/backend/gen_insn_selection.cpp
+++ b/backend/src/backend/gen_insn_selection.cpp
@@ -234,6 +234,37 @@ namespace gbe
return this->opcode == SEL_OP_LABEL;
}
+ bool SelectionInstruction::isNative(void) const {
+ return this->opcode == SEL_OP_NOT || /* ALU1 */
+ this->opcode == SEL_OP_LZD ||
+ this->opcode == SEL_OP_RNDZ ||
+ this->opcode == SEL_OP_RNDE ||
+ this->opcode == SEL_OP_RNDD ||
+ this->opcode == SEL_OP_RNDU ||
+ this->opcode == SEL_OP_FRC ||
+ this->opcode == SEL_OP_F16TO32 ||
+ this->opcode == SEL_OP_F32TO16 ||
+ this->opcode == SEL_OP_CBIT ||
+ this->opcode == SEL_OP_SEL || /* ALU2 */
+ this->opcode == SEL_OP_AND ||
+ this->opcode == SEL_OP_OR ||
+ this->opcode == SEL_OP_XOR ||
+ this->opcode == SEL_OP_SHR ||
+ this->opcode == SEL_OP_SHL ||
+ this->opcode == SEL_OP_RSR ||
+ this->opcode == SEL_OP_RSL ||
+ this->opcode == SEL_OP_ASR ||
+ this->opcode == SEL_OP_SEL ||
+ this->opcode == SEL_OP_ADD ||
+ this->opcode == SEL_OP_MUL ||
+ this->opcode == SEL_OP_FBH ||
+ this->opcode == SEL_OP_FBL ||
+ this->opcode == SEL_OP_MACH ||
+ this->opcode == SEL_OP_MATH ||
+ this->opcode == SEL_OP_LRP || /* ALU3 */
+ this->opcode == SEL_OP_MAD;
+ }
+
///////////////////////////////////////////////////////////////////////////
// SelectionVector
///////////////////////////////////////////////////////////////////////////
diff --git a/backend/src/backend/gen_insn_selection.hpp b/backend/src/backend/gen_insn_selection.hpp
index ba287e8..bee35d2 100644
--- a/backend/src/backend/gen_insn_selection.hpp
+++ b/backend/src/backend/gen_insn_selection.hpp
@@ -82,6 +82,8 @@ namespace gbe
bool isBranch(void) const;
/*! Is it a label instruction (i.e. change the implicit mask) */
bool isLabel(void) const;
+ /*! Is it a simple navtive instruction (i.e. will be one simple ISA) */
+ bool isNative(void) const;
/*! Get the destination register */
GenRegister &dst(uint32_t dstID) { return regs[dstID]; }
/*! Get the source register */
@@ -313,6 +315,8 @@ namespace gbe
void optimize(void);
uint32_t opt_features;
+ /* Add insn ID for sel IR */
+ void addID(void);
const GenContext &getCtx();
/*! Use custom allocators */
diff --git a/backend/src/backend/gen_insn_selection_optimize.cpp b/backend/src/backend/gen_insn_selection_optimize.cpp
index 56c7615..eac0f36 100644
--- a/backend/src/backend/gen_insn_selection_optimize.cpp
+++ b/backend/src/backend/gen_insn_selection_optimize.cpp
@@ -285,4 +285,14 @@ namespace gbe
//do global optimization
}
+
+ void Selection::addID()
+ {
+ uint32_t insnID = 0;
+ for (auto &block : *blockList)
+ for (auto &insn : block.insnList) {
+ insn.ID = insnID;
+ insnID += 2;
+ }
+ }
} /* namespace gbe */
diff --git a/backend/src/backend/gen_insn_selection_output.cpp b/backend/src/backend/gen_insn_selection_output.cpp
index 7bdd8fd..b683869 100644
--- a/backend/src/backend/gen_insn_selection_output.cpp
+++ b/backend/src/backend/gen_insn_selection_output.cpp
@@ -102,6 +102,7 @@ namespace gbe
cout << "WARNING: not completed yet, welcome for the FIX!" << endl;
for (SelectionBlock &block : *sel->blockList) {
for (SelectionInstruction &insn : block.insnList) {
+ cout<<"["<<insn.ID<<"]";
char opname[OP_NAME_LENGTH];
if (insn.isLabel()) {
cout << " L" << insn.index << ":" << endl;
diff --git a/backend/src/backend/gen_reg_allocation.cpp b/backend/src/backend/gen_reg_allocation.cpp
index 2a889a0..ebca368 100644
--- a/backend/src/backend/gen_reg_allocation.cpp
+++ b/backend/src/backend/gen_reg_allocation.cpp
@@ -1236,7 +1236,7 @@ namespace gbe
RegIntervalMap *boolsMap = new RegIntervalMap;
for (auto &insn : block.insnList) {
const uint32_t srcNum = insn.srcNum, dstNum = insn.dstNum;
- insn.ID = insnID;
+ assert(insnID == (int32_t)insn.ID);
bool is3SrcOp = insn.opcode == SEL_OP_MAD;
for (uint32_t srcID = 0; srcID < srcNum; ++srcID) {
const GenRegister &selReg = insn.src(srcID);
@@ -1261,8 +1261,12 @@ namespace gbe
if (this->intervals[reg].conflictReg == 0 ||
this->intervals[reg].conflictReg > conflictReg)
this->intervals[reg].conflictReg = conflictReg;
- this->intervals[reg].minID = std::min(this->intervals[reg].minID, insnID);
- this->intervals[reg].maxID = std::max(this->intervals[reg].maxID, insnID);
+ int insnsrcID = insnID;
+ // If instruction is simple, src and dst can be reused and they will have different IDs
+ if (insn.isNative())
+ insnsrcID -= 1;
+ this->intervals[reg].minID = std::min(this->intervals[reg].minID, insnsrcID);
+ this->intervals[reg].maxID = std::max(this->intervals[reg].maxID, insnsrcID);
}
for (uint32_t dstID = 0; dstID < dstNum; ++dstID) {
const GenRegister &selReg = insn.dst(dstID);
@@ -1317,7 +1321,7 @@ namespace gbe
(insn.state.flag == 0 && insn.state.subFlag == 1) ));
}
lastID = insnID;
- insnID++;
+ insnID += 2;
}
// All registers alive at the begining of the block must update their intervals.
--
2.7.4
More information about the Beignet
mailing list