diff options
Diffstat (limited to 'backend/src/ir/function.cpp')
-rw-r--r-- | backend/src/ir/function.cpp | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/backend/src/ir/function.cpp b/backend/src/ir/function.cpp index deb65ef..3767d9c 100644 --- a/backend/src/ir/function.cpp +++ b/backend/src/ir/function.cpp @@ -260,14 +260,23 @@ namespace ir { jumpToNext = &bb; return; } - const BranchInstruction &insn = cast<BranchInstruction>(*last); - if (insn.getOpcode() == OP_BRA) { + ir::BasicBlock::iterator it = --bb.end(); + uint32_t handledInsns = 0; + while ((handledInsns < 2 && it != bb.end()) && + static_cast<ir::BranchInstruction *>(&*it)->getOpcode() == OP_BRA) { + const BranchInstruction &insn = cast<BranchInstruction>(*it); + if (insn.getOpcode() != OP_BRA) + break; const LabelIndex label = insn.getLabelIndex(); BasicBlock *target = this->blocks[label]; GBE_ASSERT(target != NULL); target->predecessors.insert(&bb); bb.successors.insert(target); - if ( insn.isPredicated() == true) jumpToNext = &bb; + if (insn.isPredicated() == true) jumpToNext = &bb; + // If we are going to handle the second bra, this bra must be a predicated bra + GBE_ASSERT(handledInsns == 0 || insn.isPredicated() == true); + --it; + ++handledInsns; } }); } @@ -324,7 +333,9 @@ namespace ir { BasicBlock::BasicBlock(Function &fn) : needEndif(true), needIf(true), endifLabel(0), matchingEndifLabel(0), matchingElseLabel(0), thisElseLabel(0), belongToStructure(false), - isStructureExit(false), matchingStructureEntry(NULL), + isStructureExit(false), isLoopExit(false), + hasExtraBra(false), + matchingStructureEntry(NULL), fn(fn) { this->nextBlock = this->prevBlock = NULL; } |