[Beignet] [PATCH 3/3] GBE: reserve flag0.0 for large basic block.
Zhigang Gong
zhigang.gong at intel.com
Sun Apr 27 18:00:44 PDT 2014
From: Zhigang Gong <zhigang.gong at gmail.com>
As in large basic block, there are more than one IF instruction which
need to use the flag0.0. We have to reserve flag 0.0 to those IF
instructions.
Signed-off-by: Zhigang Gong <zhigang.gong at gmail.com>
---
backend/src/backend/gen_insn_selection.cpp | 3 ++-
backend/src/backend/gen_insn_selection.hpp | 1 +
backend/src/backend/gen_reg_allocation.cpp | 15 ++++++++++++++-
3 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/backend/src/backend/gen_insn_selection.cpp b/backend/src/backend/gen_insn_selection.cpp
index d484212..850c3b6 100644
--- a/backend/src/backend/gen_insn_selection.cpp
+++ b/backend/src/backend/gen_insn_selection.cpp
@@ -196,7 +196,7 @@ namespace gbe
// SelectionBlock
///////////////////////////////////////////////////////////////////////////
- SelectionBlock::SelectionBlock(const ir::BasicBlock *bb) : bb(bb), endifLabel( (ir::LabelIndex) 0){}
+ SelectionBlock::SelectionBlock(const ir::BasicBlock *bb) : bb(bb), isLargeBlock(false), endifLabel( (ir::LabelIndex) 0){}
void SelectionBlock::append(ir::Register reg) { tmp.push_back(reg); }
@@ -1495,6 +1495,7 @@ namespace gbe
this->curr.predicate = GEN_PREDICATE_NORMAL;
this->IF(GenRegister::immd(0), jip, jip);
this->pop();
+ this->block->isLargeBlock = true;
}
if (needEndif) {
diff --git a/backend/src/backend/gen_insn_selection.hpp b/backend/src/backend/gen_insn_selection.hpp
index 018114d..150feb5 100644
--- a/backend/src/backend/gen_insn_selection.hpp
+++ b/backend/src/backend/gen_insn_selection.hpp
@@ -190,6 +190,7 @@ namespace gbe
void append(SelectionInstruction *insn);
/*! Append a new selection instruction at the beginning of the block */
void prepend(SelectionInstruction *insn);
+ bool isLargeBlock;
ir::LabelIndex endifLabel;
int endifOffset;
bool hasBarrier;
diff --git a/backend/src/backend/gen_reg_allocation.cpp b/backend/src/backend/gen_reg_allocation.cpp
index a10f57c..b3f8a78 100644
--- a/backend/src/backend/gen_reg_allocation.cpp
+++ b/backend/src/backend/gen_reg_allocation.cpp
@@ -160,6 +160,7 @@ namespace gbe
vector<GenRegInterval> intervals;
/*! All the boolean register intervals on the corresponding BB*/
typedef map<ir::Register, GenRegInterval> RegIntervalMap;
+ set<SelectionBlock *> flag0ReservedBlocks;
map<SelectionBlock *, RegIntervalMap *> boolIntervalsMap;
/*! Intervals sorting based on starting point positions */
vector<GenRegInterval*> starting;
@@ -409,7 +410,7 @@ namespace gbe
map<ir::Register, uint32_t> allocatedFlags;
map<const GenRegInterval*, uint32_t> allocatedFlagIntervals;
- const uint32_t flagNum = 3;
+ const uint32_t flagNum = flag0ReservedBlocks.contains(&block) ? 2 : 3;
uint32_t freeFlags[] = {2, 3, 0};
uint32_t freeNum = flagNum;
if (boolIntervalsMap.find(&block) == boolIntervalsMap.end())
@@ -922,6 +923,8 @@ namespace gbe
// Update the intervals of each used register. Note that we do not
// register allocate R0, so we skip all sub-registers in r0
RegIntervalMap *boolsMap = new RegIntervalMap;
+ if (block.isLargeBlock)
+ flag0ReservedBlocks.insert(&block);
for (auto &insn : block.insnList) {
const uint32_t srcNum = insn.srcNum, dstNum = insn.dstNum;
insn.ID = insnID;
@@ -976,7 +979,17 @@ namespace gbe
// is out-of the if/endif region, so we have to borrow the f0
// to get correct bits for all channels.
boolsMap->find(reg)->second.minID = 0;
+ if (flag0ReservedBlocks.contains(&block))
+ flag0ReservedBlocks.erase(&block);
}
+ } else {
+ // Make sure that instruction selection stage didn't use physiacl flags incorrectly.
+ GBE_ASSERT ((insn.opcode == SEL_OP_LABEL ||
+ insn.opcode == SEL_OP_IF ||
+ 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)));
}
lastID = insnID;
insnID++;
--
1.8.3.2
More information about the Beignet
mailing list