From: Zhigang Gong <[email protected]> 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 <[email protected]> --- 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 _______________________________________________ Beignet mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/beignet
