// 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); } }
void Lanes::afterMerge() { if (boundary) return; // will be reset by changeActiveLane() for (unsigned int i = 0; i < typeVec.size(); ++i) { int& t = typeVec[i]; if (isHead(t) || isJoin(t) || t == CROSS) t = NOT_ACTIVE; else if (t == CROSS_EMPTY) t = EMPTY; else if (IS_NODE(t)) t = ACTIVE; } }
// 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 } }