Factors out and reuses live-in computation code from BranchFolding.
Differential Revision: https://reviews.llvm.org/D27558
llvm-svn: 290013
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
/// 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.
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;
}
// 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);
MachineBasicBlock* PredBB,
unsigned MinCommonTailLength);
void setCommonTailEdgeWeights(MachineBasicBlock &TailMBB);
- void computeLiveIns(MachineBasicBlock &MBB);
void ReplaceTailWithBranchTo(MachineBasicBlock::iterator OldInst,
MachineBasicBlock *NewDest);
MachineBasicBlock *SplitMBBAt(MachineBasicBlock &CurMBB,
#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"
SmallVector<BasicBlockInfo, 16> BlockInfo;
std::unique_ptr<RegScavenger> RS;
+ LivePhysRegs LiveRegs;
MachineFunction *MF;
+ const TargetRegisterInfo *TRI;
const TargetInstrInfo *TII;
bool relaxBranchInstructions();
// 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;
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
const TargetSubtargetInfo &ST = MF->getSubtarget();
TII = ST.getInstrInfo();
- const TargetRegisterInfo *TRI = ST.getRegisterInfo();
+ TRI = ST.getRegisterInfo();
if (TRI->trackLivenessAfterRegAlloc(*MF))
RS.reset(new RegScavenger());
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);
+ }
+}
// care what kind of return it is, putting a mask after it is a no-op.
return isReturnBlock() && !succ_empty() ? TRI->getNoPreservedMask() : nullptr;
}
+
+void MachineBasicBlock::clearLiveIns() {
+ LiveIns.clear();
+}