// If main trace ends with an unconditional jump, and the target is not // reached by any other branch, then copy the target of the jump to the // end of the trace static void elimUnconditionalJump(Trace* trace, IRFactory* irFactory) { boost::dynamic_bitset<> isJoin(irFactory->numLabels()); boost::dynamic_bitset<> havePred(irFactory->numLabels()); IRInstruction::List& instList = trace->getInstructionList(); for (IRInstruction* inst : instList) { if (inst->isControlFlowInstruction()) { auto id = inst->getLabel()->getLabelId(); isJoin[id] = havePred[id]; havePred[id] = 1; } } IRInstruction::Iterator lastInst = instList.end(); --lastInst; // go back to the last instruction IRInstruction* jmp = *lastInst; if (jmp->getOpcode() == Jmp_ && !isJoin[jmp->getLabel()->getLabelId()]) { Trace* targetTrace = jmp->getLabel()->getParent(); IRInstruction::List& targetInstList = targetTrace->getInstructionList(); IRInstruction::Iterator instIter = targetInstList.begin(); instIter++; // skip over label // update the parent trace of the moved instructions for (IRInstruction::Iterator it = instIter; it != targetInstList.end(); ++it) { (*it)->setParent(trace); } instList.splice(lastInst, targetInstList, instIter, targetInstList.end()); // delete the jump instruction instList.erase(lastInst); } }
// If main trace ends with an unconditional jump, and the target is not // reached by any other branch, then copy the target of the jump to the // end of the trace static void elimUnconditionalJump(Trace* trace, IRFactory* irFactory) { boost::dynamic_bitset<> isJoin(irFactory->numBlocks()); boost::dynamic_bitset<> havePred(irFactory->numBlocks()); for (Block* block : trace->getBlocks()) { if (block->getTaken()) { auto id = block->getTaken()->getId(); isJoin[id] = havePred[id]; havePred[id] = 1; } if (block->getNext()) { auto id = block->getNext()->getId(); isJoin[id] = havePred[id]; havePred[id] = 1; } } Block* lastBlock = trace->back(); auto lastInst = lastBlock->backIter(); // iterator to last instruction IRInstruction& jmp = *lastInst; if (jmp.getOpcode() == Jmp_ && !isJoin[jmp.getTaken()->getId()]) { Block* target = jmp.getTaken(); lastBlock->splice(lastInst, target, target->skipLabel(), target->end()); lastBlock->erase(lastInst); // delete the jmp } }