Index: include/llvm/CodeGen/LivePhysRegs.h =================================================================== --- include/llvm/CodeGen/LivePhysRegs.h +++ include/llvm/CodeGen/LivePhysRegs.h @@ -155,6 +155,13 @@ return OS; } +/// Compute the live-in list for \p MBB assuming all of its successors live-in +/// lists are up-to-date. Uses the given LivePhysReg instance \p LiveRegs; This +/// is just here to avoid repeated heap allocations when calling this multiple +/// times in a pass. +void computeLiveIns(LivePhysRegs &LiveRegs, const TargetRegisterInfo &TRI, + MachineBasicBlock &MBB); + } // end namespace llvm #endif // LLVM_CODEGEN_LIVEPHYSREGS_H Index: include/llvm/CodeGen/MachineBasicBlock.h =================================================================== --- include/llvm/CodeGen/MachineBasicBlock.h +++ include/llvm/CodeGen/MachineBasicBlock.h @@ -290,6 +290,9 @@ /// LiveIn insertion. void sortUniqueLiveIns(); + /// Clear live in list. + void clearLiveIns(); + /// Add PhysReg as live in to this block, and ensure that there is a copy of /// PhysReg to a virtual register of class RC. Return the virtual register /// that is a copy of the live in PhysReg. Index: lib/CodeGen/BranchFolding.h =================================================================== --- lib/CodeGen/BranchFolding.h +++ lib/CodeGen/BranchFolding.h @@ -137,7 +137,6 @@ MachineBasicBlock* PredBB, unsigned MinCommonTailLength); void setCommonTailEdgeWeights(MachineBasicBlock &TailMBB); - void computeLiveIns(MachineBasicBlock &MBB); void ReplaceTailWithBranchTo(MachineBasicBlock::iterator OldInst, MachineBasicBlock *NewDest); MachineBasicBlock *SplitMBBAt(MachineBasicBlock &CurMBB, Index: lib/CodeGen/BranchFolding.cpp =================================================================== --- lib/CodeGen/BranchFolding.cpp +++ lib/CodeGen/BranchFolding.cpp @@ -349,37 +349,16 @@ return TailLen; } -void BranchFolder::computeLiveIns(MachineBasicBlock &MBB) { - if (!UpdateLiveIns) - return; - - LiveRegs.init(*TRI); - LiveRegs.addLiveOutsNoPristines(MBB); - for (MachineInstr &MI : make_range(MBB.rbegin(), MBB.rend())) - LiveRegs.stepBackward(MI); - - for (unsigned Reg : LiveRegs) { - // Skip the register if we are about to add one of its super registers. - bool ContainsSuperReg = false; - for (MCSuperRegIterator SReg(Reg, TRI); SReg.isValid(); ++SReg) { - if (LiveRegs.contains(*SReg)) { - ContainsSuperReg = true; - break; - } - } - if (ContainsSuperReg) - continue; - MBB.addLiveIn(Reg); - } -} - /// ReplaceTailWithBranchTo - Delete the instruction OldInst and everything /// after it, replacing it with an unconditional branch to NewDest. void BranchFolder::ReplaceTailWithBranchTo(MachineBasicBlock::iterator OldInst, MachineBasicBlock *NewDest) { TII->ReplaceTailWithBranchTo(OldInst, NewDest); - computeLiveIns(*NewDest); + if (UpdateLiveIns) { + NewDest->clearLiveIns(); + computeLiveIns(LiveRegs, *TRI, *NewDest); + } ++NumTailMerge; } @@ -417,7 +396,8 @@ // NewMBB inherits CurMBB's block frequency. MBBFreqInfo.setBlockFreq(NewMBB, MBBFreqInfo.getBlockFreq(&CurMBB)); - computeLiveIns(*NewMBB); + if (UpdateLiveIns) + computeLiveIns(LiveRegs, *TRI, *NewMBB); // Add the new block to the funclet. const auto &FuncletI = FuncletMembership.find(&CurMBB); Index: lib/CodeGen/BranchRelaxation.cpp =================================================================== --- lib/CodeGen/BranchRelaxation.cpp +++ lib/CodeGen/BranchRelaxation.cpp @@ -10,6 +10,7 @@ #include "llvm/CodeGen/Passes.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" +#include "llvm/CodeGen/LivePhysRegs.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/RegisterScavenging.h" #include "llvm/Target/TargetInstrInfo.h" @@ -69,8 +70,10 @@ SmallVector BlockInfo; std::unique_ptr RS; + LivePhysRegs LiveRegs; MachineFunction *MF; + const TargetRegisterInfo *TRI; const TargetInstrInfo *TII; bool relaxBranchInstructions(); @@ -252,6 +255,10 @@ // All BBOffsets following these blocks must be modified. adjustBlockOffsets(*OrigBB); + // Need to fix live-in lists if we track liveness. + if (TRI->trackLivenessAfterRegAlloc(*MF)) + computeLiveIns(LiveRegs, *TRI, *NewBB); + ++NumSplit; return NewBB; @@ -411,8 +418,9 @@ for (MachineFunction::iterator I = MF->begin(); I != MF->end(); ++I) { MachineBasicBlock &MBB = *I; - auto Last = MBB.rbegin(); - if (Last == MBB.rend()) // Empty block. + // Empty block? + MachineBasicBlock::iterator Last = MBB.getLastNonDebugInstr(); + if (Last == MBB.end()) continue; // Expand the unconditional branch first if necessary. If there is a @@ -473,7 +481,7 @@ const TargetSubtargetInfo &ST = MF->getSubtarget(); TII = ST.getInstrInfo(); - const TargetRegisterInfo *TRI = ST.getRegisterInfo(); + TRI = ST.getRegisterInfo(); if (TRI->trackLivenessAfterRegAlloc(*MF)) RS.reset(new RegScavenger()); Index: lib/CodeGen/LivePhysRegs.cpp =================================================================== --- lib/CodeGen/LivePhysRegs.cpp +++ lib/CodeGen/LivePhysRegs.cpp @@ -195,3 +195,26 @@ addPristines(*this, MF, MFI, *TRI); addBlockLiveIns(MBB); } + +void llvm::computeLiveIns(LivePhysRegs &LiveRegs, const TargetRegisterInfo &TRI, + MachineBasicBlock &MBB) { + assert(MBB.livein_empty()); + LiveRegs.init(TRI); + LiveRegs.addLiveOutsNoPristines(MBB); + for (MachineInstr &MI : make_range(MBB.rbegin(), MBB.rend())) + LiveRegs.stepBackward(MI); + + for (unsigned Reg : LiveRegs) { + // Skip the register if we are about to add one of its super registers. + bool ContainsSuperReg = false; + for (MCSuperRegIterator SReg(Reg, &TRI); SReg.isValid(); ++SReg) { + if (LiveRegs.contains(*SReg)) { + ContainsSuperReg = true; + break; + } + } + if (ContainsSuperReg) + continue; + MBB.addLiveIn(Reg); + } +} Index: lib/CodeGen/MachineBasicBlock.cpp =================================================================== --- lib/CodeGen/MachineBasicBlock.cpp +++ lib/CodeGen/MachineBasicBlock.cpp @@ -1298,6 +1298,10 @@ return isReturnBlock() && !succ_empty() ? TRI->getNoPreservedMask() : nullptr; } +void MachineBasicBlock::clearLiveIns() { + LiveIns.clear(); +} + iterator_range MachineBasicBlock::liveins() const { assert(getParent()->getProperties().hasProperty(