From: Zhigang Gong Date: Fri, 25 Apr 2014 13:52:34 +0000 (+0800) Subject: GBE: reserve flag0.0 for large basic block. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e2374ee02183e69da5a271793330f8ee0782491f;p=contrib%2Fbeignet.git GBE: reserve flag0.0 for large basic block. 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 Reviewed-by: "Yang, Rong R" --- diff --git a/backend/src/backend/gen_insn_selection.cpp b/backend/src/backend/gen_insn_selection.cpp index ab885f2..88ec408 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); } @@ -1501,6 +1501,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 fd0c1cf..5098f34 100644 --- a/backend/src/backend/gen_reg_allocation.cpp +++ b/backend/src/backend/gen_reg_allocation.cpp @@ -160,6 +160,7 @@ namespace gbe vector intervals; /*! All the boolean register intervals on the corresponding BB*/ typedef map RegIntervalMap; + set flag0ReservedBlocks; map boolIntervalsMap; /*! Intervals sorting based on starting point positions */ vector starting; @@ -409,7 +410,7 @@ namespace gbe map allocatedFlags; map 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()) @@ -923,6 +924,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; @@ -977,7 +980,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++;