aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/LivePhysRegs.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/LivePhysRegs.cpp')
-rw-r--r--lib/CodeGen/LivePhysRegs.cpp123
1 files changed, 104 insertions, 19 deletions
diff --git a/lib/CodeGen/LivePhysRegs.cpp b/lib/CodeGen/LivePhysRegs.cpp
index cde6ccd29dfd..f4b43a9b8ead 100644
--- a/lib/CodeGen/LivePhysRegs.cpp
+++ b/lib/CodeGen/LivePhysRegs.cpp
@@ -40,10 +40,8 @@ void LivePhysRegs::removeRegsInMask(const MachineOperand &MO,
}
}
-/// Simulates liveness when stepping backwards over an instruction(bundle):
-/// Remove Defs, add uses. This is the recommended way of calculating liveness.
-void LivePhysRegs::stepBackward(const MachineInstr &MI) {
- // Remove defined registers and regmask kills from the set.
+/// Remove defined registers and regmask kills from the set.
+void LivePhysRegs::removeDefs(const MachineInstr &MI) {
for (ConstMIBundleOperands O(MI); O.isValid(); ++O) {
if (O->isReg()) {
if (!O->isDef())
@@ -55,8 +53,10 @@ void LivePhysRegs::stepBackward(const MachineInstr &MI) {
} else if (O->isRegMask())
removeRegsInMask(*O);
}
+}
- // Add uses to the set.
+/// Add uses to the set.
+void LivePhysRegs::addUses(const MachineInstr &MI) {
for (ConstMIBundleOperands O(MI); O.isValid(); ++O) {
if (!O->isReg() || !O->readsReg())
continue;
@@ -67,6 +67,16 @@ void LivePhysRegs::stepBackward(const MachineInstr &MI) {
}
}
+/// Simulates liveness when stepping backwards over an instruction(bundle):
+/// Remove Defs, add uses. This is the recommended way of calculating liveness.
+void LivePhysRegs::stepBackward(const MachineInstr &MI) {
+ // Remove defined registers and regmask kills from the set.
+ removeDefs(MI);
+
+ // Add uses to the set.
+ addUses(MI);
+}
+
/// Simulates liveness when stepping forward over an instruction(bundle): Remove
/// killed-uses, add defs. This is the not recommended way, because it depends
/// on accurate kill flags. If possible use stepBackward() instead of this
@@ -116,7 +126,7 @@ void LivePhysRegs::print(raw_ostream &OS) const {
}
for (const_iterator I = begin(), E = end(); I != E; ++I)
- OS << " " << PrintReg(*I, TRI);
+ OS << " " << printReg(*I, TRI);
OS << "\n";
}
@@ -166,17 +176,32 @@ static void addCalleeSavedRegs(LivePhysRegs &LiveRegs,
LiveRegs.addReg(*CSR);
}
-/// Adds pristine registers to the given \p LiveRegs. Pristine registers are
-/// callee saved registers that are unused in the function.
-static void addPristines(LivePhysRegs &LiveRegs, const MachineFunction &MF) {
+void LivePhysRegs::addPristines(const MachineFunction &MF) {
const MachineFrameInfo &MFI = MF.getFrameInfo();
if (!MFI.isCalleeSavedInfoValid())
return;
+ /// This function will usually be called on an empty object, handle this
+ /// as a special case.
+ if (empty()) {
+ /// Add all callee saved regs, then remove the ones that are saved and
+ /// restored.
+ addCalleeSavedRegs(*this, MF);
+ /// Remove the ones that are not saved/restored; they are pristine.
+ for (const CalleeSavedInfo &Info : MFI.getCalleeSavedInfo())
+ removeReg(Info.getReg());
+ return;
+ }
+ /// If a callee-saved register that is not pristine is already present
+ /// in the set, we should make sure that it stays in it. Precompute the
+ /// set of pristine registers in a separate object.
/// Add all callee saved regs, then remove the ones that are saved+restored.
- addCalleeSavedRegs(LiveRegs, MF);
+ LivePhysRegs Pristine(*TRI);
+ addCalleeSavedRegs(Pristine, MF);
/// Remove the ones that are not saved/restored; they are pristine.
for (const CalleeSavedInfo &Info : MFI.getCalleeSavedInfo())
- LiveRegs.removeReg(Info.getReg());
+ Pristine.removeReg(Info.getReg());
+ for (MCPhysReg R : Pristine)
+ addReg(R);
}
void LivePhysRegs::addLiveOutsNoPristines(const MachineBasicBlock &MBB) {
@@ -192,7 +217,8 @@ void LivePhysRegs::addLiveOutsNoPristines(const MachineBasicBlock &MBB) {
const MachineFrameInfo &MFI = MF.getFrameInfo();
if (MFI.isCalleeSavedInfoValid()) {
for (const CalleeSavedInfo &Info : MFI.getCalleeSavedInfo())
- addReg(Info.getReg());
+ if (Info.isRestored())
+ addReg(Info.getReg());
}
}
}
@@ -200,7 +226,7 @@ void LivePhysRegs::addLiveOutsNoPristines(const MachineBasicBlock &MBB) {
void LivePhysRegs::addLiveOuts(const MachineBasicBlock &MBB) {
const MachineFunction &MF = *MBB.getParent();
if (!MBB.succ_empty()) {
- addPristines(*this, MF);
+ addPristines(MF);
addLiveOutsNoPristines(MBB);
} else if (MBB.isReturnBlock()) {
// For the return block: Add all callee saved registers.
@@ -212,21 +238,27 @@ void LivePhysRegs::addLiveOuts(const MachineBasicBlock &MBB) {
void LivePhysRegs::addLiveIns(const MachineBasicBlock &MBB) {
const MachineFunction &MF = *MBB.getParent();
- addPristines(*this, MF);
+ addPristines(MF);
addBlockLiveIns(MBB);
}
void llvm::computeLiveIns(LivePhysRegs &LiveRegs,
- const MachineRegisterInfo &MRI,
- MachineBasicBlock &MBB) {
+ const MachineBasicBlock &MBB) {
+ const MachineFunction &MF = *MBB.getParent();
+ const MachineRegisterInfo &MRI = MF.getRegInfo();
const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
- assert(MBB.livein_empty());
LiveRegs.init(TRI);
LiveRegs.addLiveOutsNoPristines(MBB);
- for (MachineInstr &MI : make_range(MBB.rbegin(), MBB.rend()))
+ for (const MachineInstr &MI : make_range(MBB.rbegin(), MBB.rend()))
LiveRegs.stepBackward(MI);
+}
- for (unsigned Reg : LiveRegs) {
+void llvm::addLiveIns(MachineBasicBlock &MBB, const LivePhysRegs &LiveRegs) {
+ assert(MBB.livein_empty() && "Expected empty live-in list");
+ const MachineFunction &MF = *MBB.getParent();
+ const MachineRegisterInfo &MRI = MF.getRegInfo();
+ const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
+ for (MCPhysReg Reg : LiveRegs) {
if (MRI.isReserved(Reg))
continue;
// Skip the register if we are about to add one of its super registers.
@@ -242,3 +274,56 @@ void llvm::computeLiveIns(LivePhysRegs &LiveRegs,
MBB.addLiveIn(Reg);
}
}
+
+void llvm::recomputeLivenessFlags(MachineBasicBlock &MBB) {
+ const MachineFunction &MF = *MBB.getParent();
+ const MachineRegisterInfo &MRI = MF.getRegInfo();
+ const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
+
+ // We walk through the block backwards and start with the live outs.
+ LivePhysRegs LiveRegs;
+ LiveRegs.init(TRI);
+ LiveRegs.addLiveOutsNoPristines(MBB);
+
+ for (MachineInstr &MI : make_range(MBB.rbegin(), MBB.rend())) {
+ // Recompute dead flags.
+ for (MIBundleOperands MO(MI); MO.isValid(); ++MO) {
+ if (!MO->isReg() || !MO->isDef() || MO->isDebug())
+ continue;
+
+ unsigned Reg = MO->getReg();
+ if (Reg == 0)
+ continue;
+ assert(TargetRegisterInfo::isPhysicalRegister(Reg));
+
+ bool IsNotLive = LiveRegs.available(MRI, Reg);
+ MO->setIsDead(IsNotLive);
+ }
+
+ // Step backward over defs.
+ LiveRegs.removeDefs(MI);
+
+ // Recompute kill flags.
+ for (MIBundleOperands MO(MI); MO.isValid(); ++MO) {
+ if (!MO->isReg() || !MO->readsReg() || MO->isDebug())
+ continue;
+
+ unsigned Reg = MO->getReg();
+ if (Reg == 0)
+ continue;
+ assert(TargetRegisterInfo::isPhysicalRegister(Reg));
+
+ bool IsNotLive = LiveRegs.available(MRI, Reg);
+ MO->setIsKill(IsNotLive);
+ }
+
+ // Complete the stepbackward.
+ LiveRegs.addUses(MI);
+ }
+}
+
+void llvm::computeAndAddLiveIns(LivePhysRegs &LiveRegs,
+ MachineBasicBlock &MBB) {
+ computeLiveIns(LiveRegs, MBB);
+ addLiveIns(MBB, LiveRegs);
+}