Index: include/llvm/Target/TargetInstrInfo.h =================================================================== --- include/llvm/Target/TargetInstrInfo.h +++ include/llvm/Target/TargetInstrInfo.h @@ -525,15 +525,18 @@ /// Remove the branching code at the end of the specific MBB. /// This is only invoked in cases where AnalyzeBranch returns success. It /// returns the number of instructions that were removed. - virtual unsigned RemoveBranch(MachineBasicBlock &MBB) const { + /// If \p BytesRemoved is non-null, report the change in code size from the + /// removed instructions. + virtual unsigned RemoveBranch(MachineBasicBlock &MBB, + int *BytesRemoved = nullptr) const { llvm_unreachable("Target didn't implement TargetInstrInfo::RemoveBranch!"); } - /// Insert branch code into the end of the specified MachineBasicBlock. - /// The operands to this method are the same as those - /// returned by AnalyzeBranch. This is only invoked in cases where - /// AnalyzeBranch returns success. It returns the number of instructions - /// inserted. + /// Insert branch code into the end of the specified MachineBasicBlock. The + /// operands to this method are the same as those returned by AnalyzeBranch. + /// This is only invoked in cases where AnalyzeBranch returns success. It + /// returns the number of instructions inserted. If \p BytesAdded is non-null, + /// report the change in code size from the added instructions. /// /// It is also invoked by tail merging to add unconditional branches in /// cases where AnalyzeBranch doesn't apply because there was no original @@ -545,10 +548,17 @@ virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef Cond, - const DebugLoc &DL) const { + const DebugLoc &DL, + int *BytesAdded = nullptr) const { llvm_unreachable("Target didn't implement TargetInstrInfo::InsertBranch!"); } + unsigned InsertUnconditionalBranch(MachineBasicBlock &MBB, + MachineBasicBlock *DestBB, + const DebugLoc &DL) const { + return InsertBranch(MBB, DestBB, nullptr, ArrayRef(), DL); + } + /// Analyze the loop code, return true if it cannot be understoo. Upon /// success, this function returns false and returns information about the /// induction variable and compare instruction used at the end. Index: lib/Target/AArch64/AArch64BranchRelaxation.cpp =================================================================== --- lib/Target/AArch64/AArch64BranchRelaxation.cpp +++ lib/Target/AArch64/AArch64BranchRelaxation.cpp @@ -74,15 +74,6 @@ void adjustBlockOffsets(MachineBasicBlock &MBB); bool isBlockInRange(const MachineInstr &MI, const MachineBasicBlock &BB) const; - unsigned insertInvertedConditionalBranch(MachineBasicBlock &SrcBB, - MachineBasicBlock::iterator InsPt, - const DebugLoc &DL, - const MachineInstr &OldBr, - MachineBasicBlock &NewDestBB) const; - unsigned insertUnconditionalBranch(MachineBasicBlock &MBB, - MachineBasicBlock &NewDestBB, - const DebugLoc &DL) const; - bool fixupConditionalBranch(MachineInstr &MI); void computeBlockSize(const MachineBasicBlock &MBB); unsigned getInstrOffset(const MachineInstr &MI) const; @@ -130,22 +121,6 @@ } } -// FIXME: This is a less precise version of MachineBasicBlock::canFallThrough? - -/// \returns true if the specified basic block can fallthrough -/// into the block immediately after it. -static bool hasFallthrough(const MachineBasicBlock &MBB) { - // Get the next machine basic block in the function. - MachineFunction::const_iterator MBBI(MBB); - - // Can't fall off end of function. - auto NextBB = std::next(MBBI); - if (NextBB == MBB.getParent()->end()) - return false; - - return MBB.isSuccessor(&*NextBB); -} - /// scanFunction - Do the initial scan of the function, building up /// information about each block. void AArch64BranchRelaxation::scanFunction() { @@ -228,7 +203,7 @@ // Note the new unconditional branch is not being recorded. // There doesn't seem to be meaningful DebugInfo available; this doesn't // correspond to anything in the source. - insertUnconditionalBranch(*OrigBB, *NewBB, DebugLoc()); + TII->InsertUnconditionalBranch(*OrigBB, NewBB, DebugLoc()); // Insert an entry into BlockInfo to align it properly with the block numbers. BlockInfo.insert(BlockInfo.begin() + NewBB->getNumber(), BasicBlockInfo()); @@ -293,91 +268,18 @@ } } -static unsigned getOppositeConditionOpcode(unsigned Opc) { - switch (Opc) { - default: - llvm_unreachable("unexpected opcode!"); - case AArch64::TBNZW: return AArch64::TBZW; - case AArch64::TBNZX: return AArch64::TBZX; - case AArch64::TBZW: return AArch64::TBNZW; - case AArch64::TBZX: return AArch64::TBNZX; - case AArch64::CBNZW: return AArch64::CBZW; - case AArch64::CBNZX: return AArch64::CBZX; - case AArch64::CBZW: return AArch64::CBNZW; - case AArch64::CBZX: return AArch64::CBNZX; - case AArch64::Bcc: return AArch64::Bcc; // Condition is an operand for Bcc. - } -} - -static inline void invertBccCondition(MachineInstr &MI) { - assert(MI.getOpcode() == AArch64::Bcc && "Unexpected opcode!"); - MachineOperand &CCOp = MI.getOperand(0); - - AArch64CC::CondCode CC = static_cast(CCOp.getImm()); - CCOp.setImm(AArch64CC::getInvertedCondCode(CC)); -} - -/// Insert a conditional branch at the end of \p MBB to \p NewDestBB, using the -/// inverse condition of branch \p OldBr. -/// \returns The number of bytes added to the block. -unsigned AArch64BranchRelaxation::insertInvertedConditionalBranch( - MachineBasicBlock &SrcMBB, - MachineBasicBlock::iterator InsPt, - const DebugLoc &DL, - const MachineInstr &OldBr, - MachineBasicBlock &NewDestBB) const { - unsigned OppositeCondOpc = getOppositeConditionOpcode(OldBr.getOpcode()); - - MachineInstrBuilder MIB = - BuildMI(SrcMBB, InsPt, DL, TII->get(OppositeCondOpc)) - .addOperand(OldBr.getOperand(0)); - - unsigned Opc = OldBr.getOpcode(); - - if (Opc == AArch64::TBZW || Opc == AArch64::TBNZW || - Opc == AArch64::TBZX || Opc == AArch64::TBNZX) - MIB.addOperand(OldBr.getOperand(1)); - - if (OldBr.getOpcode() == AArch64::Bcc) - invertBccCondition(*MIB); - - MIB.addMBB(&NewDestBB); - - return TII->getInstSizeInBytes(*MIB); -} - -/// Insert an unconditional branch at the end of \p MBB to \p DestBB. -/// \returns the number of bytes emitted. -unsigned AArch64BranchRelaxation::insertUnconditionalBranch( - MachineBasicBlock &MBB, - MachineBasicBlock &DestBB, - const DebugLoc &DL) const { - MachineInstr *MI = BuildMI(&MBB, DL, TII->get(AArch64::B)) - .addMBB(&DestBB); - - return TII->getInstSizeInBytes(*MI); -} - -static void changeBranchDestBlock(MachineInstr &MI, - MachineBasicBlock &NewDestBB) { - unsigned OpNum = 0; - unsigned Opc = MI.getOpcode(); - - if (Opc != AArch64::B) { - OpNum = (Opc == AArch64::TBZW || - Opc == AArch64::TBNZW || - Opc == AArch64::TBZX || - Opc == AArch64::TBNZX) ? 2 : 1; - } - - MI.getOperand(OpNum).setMBB(&NewDestBB); -} - /// fixupConditionalBranch - Fix up a conditional branch whose destination is /// too far away to fit in its displacement field. It is converted to an inverse /// conditional branch + an unconditional branch to the destination. bool AArch64BranchRelaxation::fixupConditionalBranch(MachineInstr &MI) { - MachineBasicBlock *DestBB = getDestBlock(MI); + DebugLoc DL = MI.getDebugLoc(); + MachineBasicBlock *MBB = MI.getParent(); + MachineBasicBlock *TBB = nullptr, *FBB = nullptr; + SmallVector Cond; + + bool Fail = TII->analyzeBranch(*MBB, TBB, FBB, Cond); + assert(!Fail && "branches to be relaxed must be analyzable"); + (void)Fail; // Add an unconditional branch to the destination and invert the branch // condition to jump over it: @@ -387,80 +289,61 @@ // b L1 // L2: - // If the branch is at the end of its MBB and that has a fall-through block, - // direct the updated conditional branch to the fall-through block. Otherwise, - // split the MBB before the next instruction. - MachineBasicBlock *MBB = MI.getParent(); - MachineInstr *BMI = &MBB->back(); - bool NeedSplit = (BMI != &MI) || !hasFallthrough(*MBB); - - if (BMI != &MI) { - if (std::next(MachineBasicBlock::iterator(MI)) == - std::prev(MBB->getLastNonDebugInstr()) && - BMI->isUnconditionalBranch()) { - // Last MI in the BB is an unconditional branch. We can simply invert the - // condition and swap destinations: - // beq L1 - // b L2 - // => - // bne L2 - // b L1 - MachineBasicBlock *NewDest = getDestBlock(*BMI); - if (isBlockInRange(MI, *NewDest)) { - DEBUG(dbgs() << " Invert condition and swap its destination with " - << *BMI); - changeBranchDestBlock(*BMI, *DestBB); - - int NewSize = - insertInvertedConditionalBranch(*MBB, MI.getIterator(), - MI.getDebugLoc(), MI, *NewDest); - int OldSize = TII->getInstSizeInBytes(MI); - BlockInfo[MBB->getNumber()].Size += (NewSize - OldSize); - MI.eraseFromParent(); - return true; - } - } - } + if (FBB && isBlockInRange(MI, *FBB)) { + // Last MI in the BB is an unconditional branch. We can simply invert the + // condition and swap destinations: + // beq L1 + // b L2 + // => + // bne L2 + // b L1 + DEBUG(dbgs() << " Invert condition and swap its destination with "); + + TII->ReverseBranchCondition(Cond); + int OldSize = 0, NewSize = 0; + TII->RemoveBranch(*MBB, &OldSize); + TII->InsertBranch(*MBB, FBB, TBB, Cond, DL, &NewSize); + + BlockInfo[MBB->getNumber()].Size += (NewSize - OldSize); + return true; + } else if (FBB) { + // We need to split the basic block here to obtain two long-range + // unconditional branches. + auto &NewBB = *MF->CreateMachineBasicBlock(MBB->getBasicBlock()); + MF->insert(++MBB->getIterator(), &NewBB); + + // Insert an entry into BlockInfo to align it properly with the block + // numbers. + BlockInfo.insert(BlockInfo.begin() + NewBB.getNumber(), BasicBlockInfo()); - if (NeedSplit) { - // Analyze the branch so we know how to update the successor lists. - MachineBasicBlock *TBB = nullptr, *FBB = nullptr; - SmallVector Cond; - bool Fail = TII->analyzeBranch(*MBB, TBB, FBB, Cond, false); - assert(!Fail && "branches to relax should be analyzable"); - (void)Fail; - - MachineBasicBlock *NewBB = splitBlockBeforeInstr(MI); - // No need for the branch to the next block. We're adding an unconditional - // branch to the destination. - int delta = TII->getInstSizeInBytes(MBB->back()); - BlockInfo[MBB->getNumber()].Size -= delta; - MBB->back().eraseFromParent(); - // BlockInfo[SplitBB].Offset is wrong temporarily, fixed below + unsigned &NewBBSize = BlockInfo[NewBB.getNumber()].Size; + NewBBSize += 4 * TII->InsertUnconditionalBranch(NewBB, FBB, DL); // Update the successor lists according to the transformation to follow. // Do it here since if there's no split, no update is needed. - MBB->replaceSuccessor(FBB, NewBB); - NewBB->addSuccessor(FBB); + MBB->replaceSuccessor(FBB, &NewBB); + NewBB.addSuccessor(FBB); } + // We now have an appropriate fall-through block in place (either naturally or + // just created), so we can invert the condition. MachineBasicBlock &NextBB = *std::next(MachineFunction::iterator(MBB)); - DEBUG(dbgs() << " Insert B to BB#" << DestBB->getNumber() + DEBUG(dbgs() << " Insert B to BB#" << TBB->getNumber() << ", invert condition and change dest. to BB#" << NextBB.getNumber() << '\n'); unsigned &MBBSize = BlockInfo[MBB->getNumber()].Size; // Insert a new conditional branch and a new unconditional branch. - MBBSize += insertInvertedConditionalBranch(*MBB, MBB->end(), - MI.getDebugLoc(), MI, NextBB); - - MBBSize += insertUnconditionalBranch(*MBB, *DestBB, MI.getDebugLoc()); - - // Remove the old conditional branch. It may or may not still be in MBB. - MBBSize -= TII->getInstSizeInBytes(MI); - MI.eraseFromParent(); + int RemovedSize = 0; + TII->ReverseBranchCondition(Cond); + TII->RemoveBranch(*MBB, &RemovedSize); + MBBSize -= RemovedSize; + + int AddedSize = 0; + TII->InsertBranch(*MBB, &NextBB, TBB, Cond, DL, &AddedSize); + MBBSize += AddedSize; // Finally, keep the block offsets up to date. adjustBlockOffsets(*MBB); Index: lib/Target/AArch64/AArch64InstrInfo.h =================================================================== --- lib/Target/AArch64/AArch64InstrInfo.h +++ lib/Target/AArch64/AArch64InstrInfo.h @@ -183,10 +183,12 @@ MachineBasicBlock *&FBB, SmallVectorImpl &Cond, bool AllowModify = false) const override; - unsigned RemoveBranch(MachineBasicBlock &MBB) const override; + unsigned RemoveBranch(MachineBasicBlock &MBB, + int *BytesRemoved = nullptr) const override; unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef Cond, - const DebugLoc &DL) const override; + const DebugLoc &DL, + int *BytesAdded = nullptr) const override; bool ReverseBranchCondition(SmallVectorImpl &Cond) const override; bool canInsertSelect(const MachineBasicBlock &, ArrayRef Cond, Index: lib/Target/AArch64/AArch64InstrInfo.cpp =================================================================== --- lib/Target/AArch64/AArch64InstrInfo.cpp +++ lib/Target/AArch64/AArch64InstrInfo.cpp @@ -281,7 +281,8 @@ return false; } -unsigned AArch64InstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { +unsigned AArch64InstrInfo::RemoveBranch(MachineBasicBlock &MBB, + int *BytesRemoved) const { MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr(); if (I == MBB.end()) return 0; @@ -295,14 +296,23 @@ I = MBB.end(); - if (I == MBB.begin()) + if (I == MBB.begin()) { + if (BytesRemoved) + *BytesRemoved = 4; return 1; + } --I; - if (!isCondBranchOpcode(I->getOpcode())) + if (!isCondBranchOpcode(I->getOpcode())) { + if (BytesRemoved) + *BytesRemoved = 4; return 1; + } // Remove the branch. I->eraseFromParent(); + if (BytesRemoved) + *BytesRemoved = 8; + return 2; } @@ -327,7 +337,8 @@ MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef Cond, - const DebugLoc &DL) const { + const DebugLoc &DL, + int *BytesAdded) const { // Shouldn't be a fall through. assert(TBB && "InsertBranch must not be told to insert a fallthrough"); @@ -336,12 +347,20 @@ BuildMI(&MBB, DL, get(AArch64::B)).addMBB(TBB); else instantiateCondBranch(MBB, DL, TBB, Cond); + + if (BytesAdded) + *BytesAdded = 4; + return 1; } // Two-way conditional branch. instantiateCondBranch(MBB, DL, TBB, Cond); BuildMI(&MBB, DL, get(AArch64::B)).addMBB(FBB); + + if (BytesAdded) + *BytesAdded = 8; + return 2; } Index: lib/Target/AMDGPU/R600InstrInfo.h =================================================================== --- lib/Target/AMDGPU/R600InstrInfo.h +++ lib/Target/AMDGPU/R600InstrInfo.h @@ -169,9 +169,11 @@ unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef Cond, - const DebugLoc &DL) const override; + const DebugLoc &DL, + int *BytesAdded = nullptr) const override; - unsigned RemoveBranch(MachineBasicBlock &MBB) const override; + unsigned RemoveBranch(MachineBasicBlock &MBB, + int *BytesRemvoed = nullptr) const override; bool isPredicated(const MachineInstr &MI) const override; Index: lib/Target/AMDGPU/R600InstrInfo.cpp =================================================================== --- lib/Target/AMDGPU/R600InstrInfo.cpp +++ lib/Target/AMDGPU/R600InstrInfo.cpp @@ -735,8 +735,10 @@ MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef Cond, - const DebugLoc &DL) const { + const DebugLoc &DL, + int *BytesAdded) const { assert(TBB && "InsertBranch must not be told to insert a fallthrough"); + assert(!BytesAdded && "code size not handled"); if (!FBB) { if (Cond.empty()) { @@ -776,8 +778,9 @@ } } -unsigned -R600InstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { +unsigned R600InstrInfo::RemoveBranch(MachineBasicBlock &MBB, + int *BytesRemoved) const { + assert(!BytesRemoved && "code size not handled"); // Note : we leave PRED* instructions there. // They may be needed when predicating instructions. Index: lib/Target/AMDGPU/SIInstrInfo.h =================================================================== --- lib/Target/AMDGPU/SIInstrInfo.h +++ lib/Target/AMDGPU/SIInstrInfo.h @@ -154,11 +154,13 @@ SmallVectorImpl &Cond, bool AllowModify) const override; - unsigned RemoveBranch(MachineBasicBlock &MBB) const override; + unsigned RemoveBranch(MachineBasicBlock &MBB, + int *BytesRemoved = nullptr) const override; unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef Cond, - const DebugLoc &DL) const override; + const DebugLoc &DL, + int *BytesAdded = nullptr) const override; bool ReverseBranchCondition( SmallVectorImpl &Cond) const override; Index: lib/Target/AMDGPU/SIInstrInfo.cpp =================================================================== --- lib/Target/AMDGPU/SIInstrInfo.cpp +++ lib/Target/AMDGPU/SIInstrInfo.cpp @@ -1116,17 +1116,23 @@ return true; } -unsigned SIInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { +unsigned SIInstrInfo::RemoveBranch(MachineBasicBlock &MBB, + int *BytesRemoved) const { MachineBasicBlock::iterator I = MBB.getFirstTerminator(); unsigned Count = 0; + unsigned RemovedSize = 0; while (I != MBB.end()) { MachineBasicBlock::iterator Next = std::next(I); + RemovedSize += getInstSizeInBytes(*I); I->eraseFromParent(); ++Count; I = Next; } + if (BytesRemoved) + *BytesRemoved = RemovedSize; + return Count; } @@ -1134,11 +1140,14 @@ MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef Cond, - const DebugLoc &DL) const { + const DebugLoc &DL, + int *BytesAdded) const { if (!FBB && Cond.empty()) { BuildMI(&MBB, DL, get(AMDGPU::S_BRANCH)) .addMBB(TBB); + if (BytesAdded) + *BytesAdded = 4; return 1; } @@ -1150,6 +1159,9 @@ if (!FBB) { BuildMI(&MBB, DL, get(Opcode)) .addMBB(TBB); + + if (BytesAdded) + *BytesAdded = 4; return 1; } @@ -1160,6 +1172,9 @@ BuildMI(&MBB, DL, get(AMDGPU::S_BRANCH)) .addMBB(FBB); + if (BytesAdded) + *BytesAdded = 8; + return 2; } Index: lib/Target/ARM/ARMBaseInstrInfo.h =================================================================== --- lib/Target/ARM/ARMBaseInstrInfo.h +++ lib/Target/ARM/ARMBaseInstrInfo.h @@ -124,10 +124,12 @@ MachineBasicBlock *&FBB, SmallVectorImpl &Cond, bool AllowModify = false) const override; - unsigned RemoveBranch(MachineBasicBlock &MBB) const override; + unsigned RemoveBranch(MachineBasicBlock &MBB, + int *BytesRemoved = nullptr) const override; unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef Cond, - const DebugLoc &DL) const override; + const DebugLoc &DL, + int *BytesAdded = nullptr) const override; bool ReverseBranchCondition(SmallVectorImpl &Cond) const override; Index: lib/Target/ARM/ARMBaseInstrInfo.cpp =================================================================== --- lib/Target/ARM/ARMBaseInstrInfo.cpp +++ lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -382,7 +382,10 @@ } -unsigned ARMBaseInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { +unsigned ARMBaseInstrInfo::RemoveBranch(MachineBasicBlock &MBB, + int *BytesRemoved) const { + assert(!BytesRemoved && "code size not handled"); + MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr(); if (I == MBB.end()) return 0; @@ -410,7 +413,9 @@ MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef Cond, - const DebugLoc &DL) const { + const DebugLoc &DL, + int *BytesAdded) const { + assert(!BytesAdded && "code size not handled"); ARMFunctionInfo *AFI = MBB.getParent()->getInfo(); int BOpc = !AFI->isThumbFunction() ? ARM::B : (AFI->isThumb2Function() ? ARM::t2B : ARM::tB); Index: lib/Target/AVR/AVRInstrInfo.h =================================================================== --- lib/Target/AVR/AVRInstrInfo.h +++ lib/Target/AVR/AVRInstrInfo.h @@ -96,8 +96,10 @@ bool AllowModify = false) const override; unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef Cond, - const DebugLoc &DL) const override; - unsigned RemoveBranch(MachineBasicBlock &MBB) const override; + const DebugLoc &DL, + int *BytesAdded = nullptr) const override; + unsigned RemoveBranch(MachineBasicBlock &MBB, + int *BytesRemoved = nullptr) const override; bool ReverseBranchCondition(SmallVectorImpl &Cond) const override; Index: lib/Target/AVR/AVRInstrInfo.cpp =================================================================== --- lib/Target/AVR/AVRInstrInfo.cpp +++ lib/Target/AVR/AVRInstrInfo.cpp @@ -377,7 +377,10 @@ MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef Cond, - const DebugLoc &DL) const { + const DebugLoc &DL, + int *BytesAdded) const { + assert(!BytesAdded && "code size not handled"); + // Shouldn't be a fall through. assert(TBB && "InsertBranch must not be told to insert a fallthrough"); assert((Cond.size() == 1 || Cond.size() == 0) && @@ -404,7 +407,10 @@ return Count; } -unsigned AVRInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { +unsigned AVRInstrInfo::RemoveBranch(MachineBasicBlock &MBB, + int *BytesRemoved) const { + assert(!BytesRemoved && "code size not handled"); + MachineBasicBlock::iterator I = MBB.end(); unsigned Count = 0; Index: lib/Target/BPF/BPFInstrInfo.h =================================================================== --- lib/Target/BPF/BPFInstrInfo.h +++ lib/Target/BPF/BPFInstrInfo.h @@ -49,10 +49,12 @@ SmallVectorImpl &Cond, bool AllowModify) const override; - unsigned RemoveBranch(MachineBasicBlock &MBB) const override; + unsigned RemoveBranch(MachineBasicBlock &MBB, + int *BytesRemoved = nullptr) const override; unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef Cond, - const DebugLoc &DL) const override; + const DebugLoc &DL, + int *BytesAdded = nullptr) const override; }; } Index: lib/Target/BPF/BPFInstrInfo.cpp =================================================================== --- lib/Target/BPF/BPFInstrInfo.cpp +++ lib/Target/BPF/BPFInstrInfo.cpp @@ -134,7 +134,10 @@ MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef Cond, - const DebugLoc &DL) const { + const DebugLoc &DL, + int *BytesAdded) const { + assert(!BytesAdded && "code size not handled"); + // Shouldn't be a fall through. assert(TBB && "InsertBranch must not be told to insert a fallthrough"); @@ -148,7 +151,10 @@ llvm_unreachable("Unexpected conditional branch"); } -unsigned BPFInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { +unsigned BPFInstrInfo::RemoveBranch(MachineBasicBlock &MBB, + int *BytesRemoved) const { + assert(!BytesRemoved && "code size not handled"); + MachineBasicBlock::iterator I = MBB.end(); unsigned Count = 0; Index: lib/Target/Hexagon/HexagonInstrInfo.h =================================================================== --- lib/Target/Hexagon/HexagonInstrInfo.h +++ lib/Target/Hexagon/HexagonInstrInfo.h @@ -87,7 +87,8 @@ /// Remove the branching code at the end of the specific MBB. /// This is only invoked in cases where AnalyzeBranch returns success. It /// returns the number of instructions that were removed. - unsigned RemoveBranch(MachineBasicBlock &MBB) const override; + unsigned RemoveBranch(MachineBasicBlock &MBB, + int *BytesRemoved = nullptr) const override; /// Insert branch code into the end of the specified MachineBasicBlock. /// The operands to this method are the same as those @@ -101,7 +102,8 @@ /// merging needs to be disabled. unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef Cond, - const DebugLoc &DL) const override; + const DebugLoc &DL, + int *BytesAdded = nullptr) const override; /// Analyze the loop code, return true if it cannot be understood. Upon /// success, this function returns false and returns information about the Index: lib/Target/Hexagon/HexagonInstrInfo.cpp =================================================================== --- lib/Target/Hexagon/HexagonInstrInfo.cpp +++ lib/Target/Hexagon/HexagonInstrInfo.cpp @@ -537,7 +537,10 @@ } -unsigned HexagonInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { +unsigned HexagonInstrInfo::RemoveBranch(MachineBasicBlock &MBB, + int *BytesRemoved) const { + assert(!BytesRemoved && "code size not handled"); + DEBUG(dbgs() << "\nRemoving branches out of BB#" << MBB.getNumber()); MachineBasicBlock::iterator I = MBB.end(); unsigned Count = 0; @@ -561,11 +564,13 @@ MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef Cond, - const DebugLoc &DL) const { + const DebugLoc &DL, + int *BytesAdded) const { unsigned BOpc = Hexagon::J2_jump; unsigned BccOpc = Hexagon::J2_jumpt; assert(validateBranchCond(Cond) && "Invalid branching condition"); assert(TBB && "InsertBranch must not be told to insert a fallthrough"); + assert(!BytesAdded && "code size not handled"); // Check if ReverseBranchCondition has asked to reverse this branch // If we want to reverse the branch an odd number of times, we want Index: lib/Target/Lanai/LanaiInstrInfo.h =================================================================== --- lib/Target/Lanai/LanaiInstrInfo.h +++ lib/Target/Lanai/LanaiInstrInfo.h @@ -86,7 +86,8 @@ SmallVectorImpl &Condition, bool AllowModify) const override; - unsigned RemoveBranch(MachineBasicBlock &MBB) const override; + unsigned RemoveBranch(MachineBasicBlock &MBB, + int *BytesRemoved = nullptr) const override; // For a comparison instruction, return the source registers in SrcReg and // SrcReg2 if having two register operands, and the value it compares against @@ -135,7 +136,8 @@ unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TrueBlock, MachineBasicBlock *FalseBlock, ArrayRef Condition, - const DebugLoc &DL) const override; + const DebugLoc &DL, + int *BytesAdded = nullptr) const override; }; static inline bool isSPLSOpcode(unsigned Opcode) { Index: lib/Target/Lanai/LanaiInstrInfo.cpp =================================================================== --- lib/Target/Lanai/LanaiInstrInfo.cpp +++ lib/Target/Lanai/LanaiInstrInfo.cpp @@ -662,9 +662,11 @@ MachineBasicBlock *TrueBlock, MachineBasicBlock *FalseBlock, ArrayRef Condition, - const DebugLoc &DL) const { + const DebugLoc &DL, + int *BytesAdded) const { // Shouldn't be a fall through. assert(TrueBlock && "InsertBranch must not be told to insert a fallthrough"); + assert(!BytesAdded && "code size not handled"); // If condition is empty then an unconditional branch is being inserted. if (Condition.empty()) { @@ -688,7 +690,10 @@ return 2; } -unsigned LanaiInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { +unsigned LanaiInstrInfo::RemoveBranch(MachineBasicBlock &MBB, + int *BytesRemoved) const { + assert(!BytesRemoved && "code size not handled"); + MachineBasicBlock::iterator Instruction = MBB.end(); unsigned Count = 0; Index: lib/Target/MSP430/MSP430InstrInfo.h =================================================================== --- lib/Target/MSP430/MSP430InstrInfo.h +++ lib/Target/MSP430/MSP430InstrInfo.h @@ -79,10 +79,12 @@ SmallVectorImpl &Cond, bool AllowModify) const override; - unsigned RemoveBranch(MachineBasicBlock &MBB) const override; + unsigned RemoveBranch(MachineBasicBlock &MBB, + int *BytesRemoved = nullptr) const override; unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef Cond, - const DebugLoc &DL) const override; + const DebugLoc &DL, + int *BytesAdded = nullptr) const override; }; } Index: lib/Target/MSP430/MSP430InstrInfo.cpp =================================================================== --- lib/Target/MSP430/MSP430InstrInfo.cpp +++ lib/Target/MSP430/MSP430InstrInfo.cpp @@ -104,7 +104,10 @@ .addReg(SrcReg, getKillRegState(KillSrc)); } -unsigned MSP430InstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { +unsigned MSP430InstrInfo::RemoveBranch(MachineBasicBlock &MBB, + int *BytesRemoved) const { + assert(!BytesRemoved && "code size not handled"); + MachineBasicBlock::iterator I = MBB.end(); unsigned Count = 0; @@ -264,11 +267,13 @@ MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef Cond, - const DebugLoc &DL) const { + const DebugLoc &DL, + int *BytesAdded) const { // Shouldn't be a fall through. assert(TBB && "InsertBranch must not be told to insert a fallthrough"); assert((Cond.size() == 1 || Cond.size() == 0) && "MSP430 branch conditions have one component!"); + assert(!BytesAdded && "code size not handled"); if (Cond.empty()) { // Unconditional branch? Index: lib/Target/Mips/MipsInstrInfo.h =================================================================== --- lib/Target/Mips/MipsInstrInfo.h +++ lib/Target/Mips/MipsInstrInfo.h @@ -55,11 +55,13 @@ SmallVectorImpl &Cond, bool AllowModify) const override; - unsigned RemoveBranch(MachineBasicBlock &MBB) const override; + unsigned RemoveBranch(MachineBasicBlock &MBB, + int *BytesRemoved = nullptr) const override; unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef Cond, - const DebugLoc &DL) const override; + const DebugLoc &DL, + int *BytesAdded = nullptr) const override; bool ReverseBranchCondition(SmallVectorImpl &Cond) const override; Index: lib/Target/Mips/MipsInstrInfo.cpp =================================================================== --- lib/Target/Mips/MipsInstrInfo.cpp +++ lib/Target/Mips/MipsInstrInfo.cpp @@ -117,9 +117,11 @@ MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef Cond, - const DebugLoc &DL) const { + const DebugLoc &DL, + int *BytesAdded) const { // Shouldn't be a fall through. assert(TBB && "InsertBranch must not be told to insert a fallthrough"); + assert(!BytesAdded && "code size not handled"); // # of condition operands: // Unconditional branches: 0 @@ -145,7 +147,10 @@ return 1; } -unsigned MipsInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { +unsigned MipsInstrInfo::RemoveBranch(MachineBasicBlock &MBB, + int *BytesRemoved) const { + assert(!BytesRemoved && "code size not handled"); + MachineBasicBlock::reverse_iterator I = MBB.rbegin(), REnd = MBB.rend(); MachineBasicBlock::reverse_iterator FirstBr; unsigned removed; Index: lib/Target/NVPTX/NVPTXInstrInfo.h =================================================================== --- lib/Target/NVPTX/NVPTXInstrInfo.h +++ lib/Target/NVPTX/NVPTXInstrInfo.h @@ -63,10 +63,12 @@ MachineBasicBlock *&FBB, SmallVectorImpl &Cond, bool AllowModify) const override; - unsigned RemoveBranch(MachineBasicBlock &MBB) const override; + unsigned RemoveBranch(MachineBasicBlock &MBB, + int *BytesRemoved = nullptr) const override; unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef Cond, - const DebugLoc &DL) const override; + const DebugLoc &DL, + int *BytesAdded = nullptr) const override; unsigned getLdStCodeAddrSpace(const MachineInstr &MI) const { return MI.getOperand(2).getImm(); } Index: lib/Target/NVPTX/NVPTXInstrInfo.cpp =================================================================== --- lib/Target/NVPTX/NVPTXInstrInfo.cpp +++ lib/Target/NVPTX/NVPTXInstrInfo.cpp @@ -205,7 +205,9 @@ return true; } -unsigned NVPTXInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { +unsigned NVPTXInstrInfo::RemoveBranch(MachineBasicBlock &MBB, + int *BytesRemoved) const { + assert(!BytesRemoved && "code size not handled"); MachineBasicBlock::iterator I = MBB.end(); if (I == MBB.begin()) return 0; @@ -233,7 +235,10 @@ MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef Cond, - const DebugLoc &DL) const { + const DebugLoc &DL, + int *BytesAdded) const { + assert(!BytesAdded && "code size not handled"); + // Shouldn't be a fall through. assert(TBB && "InsertBranch must not be told to insert a fallthrough"); assert((Cond.size() == 1 || Cond.size() == 0) && Index: lib/Target/PowerPC/PPCInstrInfo.h =================================================================== --- lib/Target/PowerPC/PPCInstrInfo.h +++ lib/Target/PowerPC/PPCInstrInfo.h @@ -168,10 +168,12 @@ MachineBasicBlock *&FBB, SmallVectorImpl &Cond, bool AllowModify) const override; - unsigned RemoveBranch(MachineBasicBlock &MBB) const override; + unsigned RemoveBranch(MachineBasicBlock &MBB, + int *BytesRemoved = nullptr) const override; unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef Cond, - const DebugLoc &DL) const override; + const DebugLoc &DL, + int *BytesAdded = nullptr) const override; // Select analysis. bool canInsertSelect(const MachineBasicBlock &, ArrayRef Cond, Index: lib/Target/PowerPC/PPCInstrInfo.cpp =================================================================== --- lib/Target/PowerPC/PPCInstrInfo.cpp +++ lib/Target/PowerPC/PPCInstrInfo.cpp @@ -605,7 +605,10 @@ return true; } -unsigned PPCInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { +unsigned PPCInstrInfo::RemoveBranch(MachineBasicBlock &MBB, + int *BytesRemoved) const { + assert(!BytesRemoved && "code size not handled"); + MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr(); if (I == MBB.end()) return 0; @@ -638,11 +641,13 @@ MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef Cond, - const DebugLoc &DL) const { + const DebugLoc &DL, + int *BytesAdded) const { // Shouldn't be a fall through. assert(TBB && "InsertBranch must not be told to insert a fallthrough"); assert((Cond.size() == 2 || Cond.size() == 0) && "PPC branch conditions have two components!"); + assert(!BytesAdded && "code size not handled"); bool isPPC64 = Subtarget.isPPC64(); Index: lib/Target/Sparc/SparcInstrInfo.h =================================================================== --- lib/Target/Sparc/SparcInstrInfo.h +++ lib/Target/Sparc/SparcInstrInfo.h @@ -70,11 +70,13 @@ SmallVectorImpl &Cond, bool AllowModify = false) const override; - unsigned RemoveBranch(MachineBasicBlock &MBB) const override; + unsigned RemoveBranch(MachineBasicBlock &MBB, + int *BytesRemoved = nullptr) const override; unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef Cond, - const DebugLoc &DL) const override; + const DebugLoc &DL, + int *BytesAdded = nullptr) const override; bool ReverseBranchCondition(SmallVectorImpl &Cond) const override; Index: lib/Target/Sparc/SparcInstrInfo.cpp =================================================================== --- lib/Target/Sparc/SparcInstrInfo.cpp +++ lib/Target/Sparc/SparcInstrInfo.cpp @@ -244,10 +244,12 @@ MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef Cond, - const DebugLoc &DL) const { + const DebugLoc &DL, + int *BytesAdded) const { assert(TBB && "InsertBranch must not be told to insert a fallthrough"); assert((Cond.size() == 1 || Cond.size() == 0) && "Sparc branch conditions should have one component!"); + assert(!BytesAdded && "code size not handled"); if (Cond.empty()) { assert(!FBB && "Unconditional branch with multiple successors!"); @@ -269,8 +271,10 @@ return 2; } -unsigned SparcInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const -{ +unsigned SparcInstrInfo::RemoveBranch(MachineBasicBlock &MBB, + int *BytesRemoved) const { + assert(!BytesRemoved && "code size not handled"); + MachineBasicBlock::iterator I = MBB.end(); unsigned Count = 0; while (I != MBB.begin()) { Index: lib/Target/SystemZ/SystemZInstrInfo.h =================================================================== --- lib/Target/SystemZ/SystemZInstrInfo.h +++ lib/Target/SystemZ/SystemZInstrInfo.h @@ -164,10 +164,12 @@ MachineBasicBlock *&FBB, SmallVectorImpl &Cond, bool AllowModify) const override; - unsigned RemoveBranch(MachineBasicBlock &MBB) const override; + unsigned RemoveBranch(MachineBasicBlock &MBB, + int *BytesRemoved = nullptr) const override; unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef Cond, - const DebugLoc &DL) const override; + const DebugLoc &DL, + int *BytesAdded = nullptr) const override; bool analyzeCompare(const MachineInstr &MI, unsigned &SrcReg, unsigned &SrcReg2, int &Mask, int &Value) const override; bool optimizeCompareInstr(MachineInstr &CmpInstr, unsigned SrcReg, Index: lib/Target/SystemZ/SystemZInstrInfo.cpp =================================================================== --- lib/Target/SystemZ/SystemZInstrInfo.cpp +++ lib/Target/SystemZ/SystemZInstrInfo.cpp @@ -363,7 +363,10 @@ return false; } -unsigned SystemZInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { +unsigned SystemZInstrInfo::RemoveBranch(MachineBasicBlock &MBB, + int *BytesRemoved) const { + assert(!BytesRemoved && "code size not handled"); + // Most of the code and comments here are boilerplate. MachineBasicBlock::iterator I = MBB.end(); unsigned Count = 0; @@ -396,7 +399,8 @@ MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef Cond, - const DebugLoc &DL) const { + const DebugLoc &DL, + int *BytesAdded) const { // In this function we output 32-bit branches, which should always // have enough range. They can be shortened and relaxed by later code // in the pipeline, if desired. @@ -405,6 +409,7 @@ assert(TBB && "InsertBranch must not be told to insert a fallthrough"); assert((Cond.size() == 2 || Cond.size() == 0) && "SystemZ branch conditions have one component!"); + assert(!BytesAdded && "code size not handled"); if (Cond.empty()) { // Unconditional branch? Index: lib/Target/WebAssembly/WebAssemblyInstrInfo.h =================================================================== --- lib/Target/WebAssembly/WebAssemblyInstrInfo.h +++ lib/Target/WebAssembly/WebAssemblyInstrInfo.h @@ -48,10 +48,12 @@ MachineBasicBlock *&FBB, SmallVectorImpl &Cond, bool AllowModify = false) const override; - unsigned RemoveBranch(MachineBasicBlock &MBB) const override; + unsigned RemoveBranch(MachineBasicBlock &MBB, + int *BytesRemoved = nullptr) const override; unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef Cond, - const DebugLoc &DL) const override; + const DebugLoc &DL, + int *BytesAdded = nullptr) const override; bool ReverseBranchCondition(SmallVectorImpl &Cond) const override; }; Index: lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp =================================================================== --- lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp +++ lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp @@ -142,7 +142,10 @@ return false; } -unsigned WebAssemblyInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { +unsigned WebAssemblyInstrInfo::RemoveBranch(MachineBasicBlock &MBB, + int *BytesRemoved) const { + assert(!BytesRemoved && "code size not handled"); + MachineBasicBlock::instr_iterator I = MBB.instr_end(); unsigned Count = 0; @@ -165,7 +168,10 @@ MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef Cond, - const DebugLoc &DL) const { + const DebugLoc &DL, + int *BytesAdded) const { + assert(!BytesAdded && "code size not handled"); + if (Cond.empty()) { if (!TBB) return 0; Index: lib/Target/X86/X86InstrInfo.h =================================================================== --- lib/Target/X86/X86InstrInfo.h +++ lib/Target/X86/X86InstrInfo.h @@ -335,10 +335,12 @@ TargetInstrInfo::MachineBranchPredicate &MBP, bool AllowModify = false) const override; - unsigned RemoveBranch(MachineBasicBlock &MBB) const override; + unsigned RemoveBranch(MachineBasicBlock &MBB, + int *BytesRemoved = nullptr) const override; unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef Cond, - const DebugLoc &DL) const override; + const DebugLoc &DL, + int *BytesAdded = nullptr) const override; bool canInsertSelect(const MachineBasicBlock&, ArrayRef Cond, unsigned, unsigned, int&, int&, int&) const override; void insertSelect(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Index: lib/Target/X86/X86InstrInfo.cpp =================================================================== --- lib/Target/X86/X86InstrInfo.cpp +++ lib/Target/X86/X86InstrInfo.cpp @@ -4358,7 +4358,10 @@ return true; } -unsigned X86InstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { +unsigned X86InstrInfo::RemoveBranch(MachineBasicBlock &MBB, + int *BytesRemoved) const { + assert(!BytesRemoved && "code size not handled"); + MachineBasicBlock::iterator I = MBB.end(); unsigned Count = 0; @@ -4382,11 +4385,13 @@ MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef Cond, - const DebugLoc &DL) const { + const DebugLoc &DL, + int *BytesAdded) const { // Shouldn't be a fall through. assert(TBB && "InsertBranch must not be told to insert a fallthrough"); assert((Cond.size() == 1 || Cond.size() == 0) && "X86 branch conditions have one component!"); + assert(!BytesAdded && "code size not handled"); if (Cond.empty()) { // Unconditional branch? Index: lib/Target/XCore/XCoreInstrInfo.h =================================================================== --- lib/Target/XCore/XCoreInstrInfo.h +++ lib/Target/XCore/XCoreInstrInfo.h @@ -57,9 +57,11 @@ unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef Cond, - const DebugLoc &DL) const override; + const DebugLoc &DL, + int *BytesAdded = nullptr) const override; - unsigned RemoveBranch(MachineBasicBlock &MBB) const override; + unsigned RemoveBranch(MachineBasicBlock &MBB, + int *BytesRemoved = nullptr) const override; void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, unsigned DestReg, unsigned SrcReg, Index: lib/Target/XCore/XCoreInstrInfo.cpp =================================================================== --- lib/Target/XCore/XCoreInstrInfo.cpp +++ lib/Target/XCore/XCoreInstrInfo.cpp @@ -273,12 +273,14 @@ MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef Cond, - const DebugLoc &DL) const { + const DebugLoc &DL, + int *BytesAdded) const { // Shouldn't be a fall through. assert(TBB && "InsertBranch must not be told to insert a fallthrough"); assert((Cond.size() == 2 || Cond.size() == 0) && "Unexpected number of components!"); - + assert(!BytesAdded && "code size not handled"); + if (!FBB) { // One way branch. if (Cond.empty()) { // Unconditional branch @@ -302,7 +304,9 @@ } unsigned -XCoreInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { +XCoreInstrInfo::RemoveBranch(MachineBasicBlock &MBB, int *BytesRemoved) const { + assert(!BytesRemoved && "code size not handled"); + MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr(); if (I == MBB.end()) return 0;