summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/IfConversion.cpp55
-rw-r--r--llvm/lib/CodeGen/LivePhysRegs.cpp67
2 files changed, 65 insertions, 57 deletions
diff --git a/llvm/lib/CodeGen/IfConversion.cpp b/llvm/lib/CodeGen/IfConversion.cpp
index a0ce2541583..05600bbc0a8 100644
--- a/llvm/lib/CodeGen/IfConversion.cpp
+++ b/llvm/lib/CodeGen/IfConversion.cpp
@@ -179,7 +179,6 @@ namespace {
MachineRegisterInfo *MRI;
LivePhysRegs Redefs;
- LivePhysRegs DontKill;
bool PreRegAlloc;
bool MadeChange;
@@ -461,6 +460,9 @@ bool IfConverter::runOnMachineFunction(MachineFunction &MF) {
}
}
+ if (RetVal && MRI->tracksLiveness())
+ recomputeLivenessFlags(*BBI.BB);
+
Change |= RetVal;
NumIfCvts = NumSimple + NumSimpleFalse + NumTriangle + NumTriangleRev +
@@ -1380,13 +1382,6 @@ static void UpdatePredRedefs(MachineInstr &MI, LivePhysRegs &Redefs) {
MIB.addReg(Reg, RegState::Implicit | RegState::Define);
continue;
}
- assert(Op.isReg() && "Register operand required");
- if (Op.isDead()) {
- // If we found a dead def, but it needs to be live, then remove the dead
- // flag.
- if (Redefs.contains(Op.getReg()))
- Op.setIsDead(false);
- }
if (LiveBeforeMI.count(Reg))
MIB.addReg(Reg, RegState::Implicit);
else {
@@ -1403,26 +1398,6 @@ static void UpdatePredRedefs(MachineInstr &MI, LivePhysRegs &Redefs) {
}
}
-/// Remove kill flags from operands with a registers in the \p DontKill set.
-static void RemoveKills(MachineInstr &MI, const LivePhysRegs &DontKill) {
- for (MIBundleOperands O(MI); O.isValid(); ++O) {
- if (!O->isReg() || !O->isKill())
- continue;
- if (DontKill.contains(O->getReg()))
- O->setIsKill(false);
- }
-}
-
-/// Walks a range of machine instructions and removes kill flags for registers
-/// in the \p DontKill set.
-static void RemoveKills(MachineBasicBlock::iterator I,
- MachineBasicBlock::iterator E,
- const LivePhysRegs &DontKill,
- const MCRegisterInfo &MCRI) {
- for (MachineInstr &MI : make_range(I, E))
- RemoveKills(MI, DontKill);
-}
-
/// If convert a simple (split, no rejoin) sub-CFG.
bool IfConverter::IfConvertSimple(BBInfo &BBI, IfcvtKind Kind) {
BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
@@ -1453,16 +1428,12 @@ bool IfConverter::IfConvertSimple(BBInfo &BBI, IfcvtKind Kind) {
llvm_unreachable("Unable to reverse branch condition!");
Redefs.init(*TRI);
- DontKill.init(*TRI);
if (MRI->tracksLiveness()) {
// Initialize liveins to the first BB. These are potentiall redefined by
// predicated instructions.
Redefs.addLiveIns(CvtMBB);
Redefs.addLiveIns(NextMBB);
- // Compute a set of registers which must not be killed by instructions in
- // BB1: This is everything live-in to BB2.
- DontKill.addLiveIns(NextMBB);
}
// Remove the branches from the entry so we can add the contents of the true
@@ -1478,7 +1449,6 @@ bool IfConverter::IfConvertSimple(BBInfo &BBI, IfcvtKind Kind) {
BBI.BB->removeSuccessor(&CvtMBB, true);
} else {
// Predicate the instructions in the true block.
- RemoveKills(CvtMBB.begin(), CvtMBB.end(), DontKill, *TRI);
PredicateBlock(*CvtBBI, CvtMBB.end(), Cond);
// Merge converted block into entry block. The BB to Cvt edge is removed
@@ -1567,8 +1537,6 @@ bool IfConverter::IfConvertTriangle(BBInfo &BBI, IfcvtKind Kind) {
Redefs.addLiveIns(NextMBB);
}
- DontKill.clear();
-
bool HasEarlyExit = CvtBBI->FalseBB != nullptr;
BranchProbability CvtNext, CvtFalse, BBNext, BBCvt;
@@ -1751,25 +1719,12 @@ bool IfConverter::IfConvertDiamondCommon(
--NumDups1;
}
- // Compute a set of registers which must not be killed by instructions in BB1:
- // This is everything used+live in BB2 after the duplicated instructions. We
- // can compute this set by simulating liveness backwards from the end of BB2.
- DontKill.init(*TRI);
if (MRI->tracksLiveness()) {
- for (const MachineInstr &MI : make_range(MBB2.rbegin(), ++DI2.getReverse()))
- DontKill.stepBackward(MI);
-
for (const MachineInstr &MI : make_range(MBB1.begin(), DI1)) {
SmallVector<std::pair<unsigned, const MachineOperand*>, 4> Dummy;
Redefs.stepForward(MI, Dummy);
}
}
- // Kill flags in the true block for registers living into the false block
- // must be removed. This should be done before extracting the common
- // instructions from the beginning of the MBB1, since these instructions
- // can actually differ between MBB1 and MBB2 in terms of <kill> flags.
- RemoveKills(MBB1.begin(), MBB1.end(), DontKill, *TRI);
-
BBI.BB->splice(BBI.BB->end(), &MBB1, MBB1.begin(), DI1);
MBB2.erase(MBB2.begin(), DI2);
@@ -2085,10 +2040,6 @@ void IfConverter::CopyAndPredicateBlock(BBInfo &ToBBI, BBInfo &FromBBI,
// If the predicated instruction now redefines a register as the result of
// if-conversion, add an implicit kill.
UpdatePredRedefs(*MI, Redefs);
-
- // Some kill flags may not be correct anymore.
- if (!DontKill.empty())
- RemoveKills(*MI, DontKill);
}
if (!IgnoreBr) {
diff --git a/llvm/lib/CodeGen/LivePhysRegs.cpp b/llvm/lib/CodeGen/LivePhysRegs.cpp
index c3e46d3e0b8..779f601e402 100644
--- a/llvm/lib/CodeGen/LivePhysRegs.cpp
+++ b/llvm/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
@@ -265,6 +275,53 @@ void llvm::addLiveIns(MachineBasicBlock &MBB, const LivePhysRegs &LiveRegs) {
}
}
+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);
OpenPOWER on IntegriCloud