bool AArch64BranchRelaxation::relaxBranchInstructions() { bool Changed = false; // Relaxing branches involves creating new basic blocks, so re-eval // end() for termination. for (MachineFunction::iterator I = MF->begin(); I != MF->end(); ++I) { MachineBasicBlock &MBB = *I; MachineBasicBlock::iterator J = MBB.getFirstTerminator(); if (J == MBB.end()) continue; MachineBasicBlock::iterator Next; for (MachineBasicBlock::iterator J = MBB.getFirstTerminator(); J != MBB.end(); J = Next) { Next = std::next(J); MachineInstr &MI = *J; if (MI.isConditionalBranch()) { MachineBasicBlock *DestBB = getDestBlock(MI); if (!isBlockInRange(MI, *DestBB)) { if (Next != MBB.end() && Next->isConditionalBranch()) { // If there are multiple conditional branches, this isn't an // analyzable block. Split later terminators into a new block so // each one will be analyzable. MachineBasicBlock *NewBB = splitBlockBeforeInstr(*Next); NewBB->transferSuccessors(&MBB); MBB.addSuccessor(NewBB); MBB.addSuccessor(DestBB); // Cleanup potential unconditional branch to successor block. NewBB->updateTerminator(); MBB.updateTerminator(); } else { fixupConditionalBranch(MI); ++NumConditionalRelaxed; } Changed = true; // This may have modified all of the terminators, so start over. Next = MBB.getFirstTerminator(); } } } } return Changed; }
bool BranchRelaxation::relaxBranchInstructions() { bool Changed = false; // Relaxing branches involves creating new basic blocks, so re-eval // end() for termination. for (MachineFunction::iterator I = MF->begin(); I != MF->end(); ++I) { MachineBasicBlock &MBB = *I; // Empty block? MachineBasicBlock::iterator Last = MBB.getLastNonDebugInstr(); if (Last == MBB.end()) continue; // Expand the unconditional branch first if necessary. If there is a // conditional branch, this will end up changing the branch destination of // it to be over the newly inserted indirect branch block, which may avoid // the need to try expanding the conditional branch first, saving an extra // jump. if (Last->isUnconditionalBranch()) { // Unconditional branch destination might be unanalyzable, assume these // are OK. if (MachineBasicBlock *DestBB = TII->getBranchDestBlock(*Last)) { if (!isBlockInRange(*Last, *DestBB)) { fixupUnconditionalBranch(*Last); ++NumUnconditionalRelaxed; Changed = true; } } } // Loop over the conditional branches. MachineBasicBlock::iterator Next; for (MachineBasicBlock::iterator J = MBB.getFirstTerminator(); J != MBB.end(); J = Next) { Next = std::next(J); MachineInstr &MI = *J; if (MI.isConditionalBranch()) { MachineBasicBlock *DestBB = TII->getBranchDestBlock(MI); if (!isBlockInRange(MI, *DestBB)) { if (Next != MBB.end() && Next->isConditionalBranch()) { // If there are multiple conditional branches, this isn't an // analyzable block. Split later terminators into a new block so // each one will be analyzable. splitBlockBeforeInstr(*Next, DestBB); } else { fixupConditionalBranch(MI); ++NumConditionalRelaxed; } Changed = true; // This may have modified all of the terminators, so start over. Next = MBB.getFirstTerminator(); } } } } return Changed; }
bool PatmosInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl<MachineOperand> &Cond, bool AllowModify) const { // If the client does not want to only simplify the branch, // the output arguments must be initialized. assert(AllowModify || (TBB==0 && FBB==0 && Cond.size()==0)); // Start from the bottom of the block and work up, examining the // terminator instructions. MachineBasicBlock::iterator I = MBB.end(); while (I != MBB.begin()) { --I; if (I->isDebugValue() || I->isPseudo()) continue; // Working from the bottom, when we see a non-terminator inst, we're done. if (!isUnpredicatedTerminator(I)) break; // A terminator that isn't a (direct) branch can't easily be handled // by this analysis. if (!I->isBranch() || I->isIndirectBranch()) return true; // Handle Unconditional branches if (!isPredicated(I)) { // fix instruction, if necessary if (!I->isUnconditionalBranch()) fixOpcodeForGuard(I); // TBB is used to indicate the unconditional destination. TBB = getBranchTarget(I); if (AllowModify) { // If the block has any instructions after an uncond branch, delete them. while (llvm::next(I) != MBB.end()) llvm::next(I)->eraseFromParent(); } continue; } // Handle conditional branches if (isPredicated(I)) { // fix instruction, if necessary if (!I->isConditionalBranch()) fixOpcodeForGuard(I); // we only treat the first conditional branch in a row if (Cond.size() > 0) return true; // Get branch condition int i = I->findFirstPredOperandIdx(); assert(i != -1 ); Cond.push_back(I->getOperand(i)); // reg Cond.push_back(I->getOperand(i+1)); // flag // We've processed an unconditional branch before, // the unconditional target goes to FBB now if (TBB) FBB = TBB; // target of conditional branch goes to TBB TBB = getBranchTarget(I); continue; } // we explicitly leave or continue. llvm_unreachable("AnalyzeBranch error."); } // left the loop? then we're done return false; }