bool BranchRelaxation::fixupUnconditionalBranch(MachineInstr &MI) { MachineBasicBlock *MBB = MI.getParent(); unsigned OldBrSize = TII->getInstSizeInBytes(MI); MachineBasicBlock *DestBB = TII->getBranchDestBlock(MI); int64_t DestOffset = BlockInfo[DestBB->getNumber()].Offset; int64_t SrcOffset = getInstrOffset(MI); assert(!TII->isBranchOffsetInRange(MI.getOpcode(), DestOffset - SrcOffset)); BlockInfo[MBB->getNumber()].Size -= OldBrSize; MachineBasicBlock *BranchBB = MBB; // If this was an expanded conditional branch, there is already a single // unconditional branch in a block. if (!MBB->empty()) { BranchBB = createNewBlockAfter(*MBB); // Add live outs. for (const MachineBasicBlock *Succ : MBB->successors()) { for (const MachineBasicBlock::RegisterMaskPair &LiveIn : Succ->liveins()) BranchBB->addLiveIn(LiveIn); } BranchBB->sortUniqueLiveIns(); BranchBB->addSuccessor(DestBB); MBB->replaceSuccessor(DestBB, BranchBB); } DebugLoc DL = MI.getDebugLoc(); MI.eraseFromParent(); BlockInfo[BranchBB->getNumber()].Size += TII->insertIndirectBranch( *BranchBB, *DestBB, DL, DestOffset - SrcOffset, RS.get()); adjustBlockOffsets(*MBB); return true; }
// All currently live registers must remain so in the remainder block. void SILowerControlFlow::splitBlockLiveIns(const MachineBasicBlock &MBB, const MachineInstr &MI, MachineBasicBlock &LoopBB, MachineBasicBlock &RemainderBB, unsigned SaveReg, const MachineOperand &IdxReg) { LivePhysRegs RemainderLiveRegs(TRI); RemainderLiveRegs.addLiveOuts(MBB); for (MachineBasicBlock::const_reverse_iterator I = MBB.rbegin(), E(&MI); I != E; ++I) { RemainderLiveRegs.stepBackward(*I); } // Add reg defined in loop body. RemainderLiveRegs.addReg(SaveReg); if (const MachineOperand *Val = TII->getNamedOperand(MI, AMDGPU::OpName::val)) { if (!Val->isUndef()) { RemainderLiveRegs.addReg(Val->getReg()); LoopBB.addLiveIn(Val->getReg()); } } const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); for (unsigned Reg : RemainderLiveRegs) { if (MRI.isAllocatable(Reg)) RemainderBB.addLiveIn(Reg); } const MachineOperand *Src = TII->getNamedOperand(MI, AMDGPU::OpName::src); if (!Src->isUndef()) LoopBB.addLiveIn(Src->getReg()); if (!IdxReg.isUndef()) LoopBB.addLiveIn(IdxReg.getReg()); LoopBB.sortUniqueLiveIns(); }