summaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2020-07-26 19:46:28 +0000
committerDimitry Andric <dim@FreeBSD.org>2020-07-26 19:46:28 +0000
commit2cedf089162d7ff08af2fb09e4adea44608e7233 (patch)
treeba6ce010fd991778200b43335a161f546d953a55 /llvm/lib/CodeGen/TwoAddressInstructionPass.cpp
parentcfca06d7963fa0909f90483b42a6d7d194d01e08 (diff)
Notes
Diffstat (limited to 'llvm/lib/CodeGen/TwoAddressInstructionPass.cpp')
-rw-r--r--llvm/lib/CodeGen/TwoAddressInstructionPass.cpp161
1 files changed, 5 insertions, 156 deletions
diff --git a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp
index de336abe607a..615ff4b8789c 100644
--- a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp
+++ b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp
@@ -70,7 +70,6 @@ STATISTIC(NumTwoAddressInstrs, "Number of two-address instructions");
STATISTIC(NumCommuted , "Number of instructions commuted to coalesce");
STATISTIC(NumAggrCommuted , "Number of instructions aggressively commuted");
STATISTIC(NumConvertedTo3Addr, "Number of instructions promoted to 3-address");
-STATISTIC(Num3AddrSunk, "Number of 3-address instructions sunk");
STATISTIC(NumReSchedUps, "Number of instructions re-scheduled up");
STATISTIC(NumReSchedDowns, "Number of instructions re-scheduled down");
@@ -109,10 +108,6 @@ class TwoAddressInstructionPass : public MachineFunctionPass {
// Set of already processed instructions in the current block.
SmallPtrSet<MachineInstr*, 8> Processed;
- // Set of instructions converted to three-address by target and then sunk
- // down current basic block.
- SmallPtrSet<MachineInstr*, 8> SunkInstrs;
-
// A map from virtual registers to physical registers which are likely targets
// to be coalesced to due to copies from physical registers to virtual
// registers. e.g. v1024 = move r0.
@@ -123,9 +118,6 @@ class TwoAddressInstructionPass : public MachineFunctionPass {
// registers. e.g. r1 = move v1024.
DenseMap<unsigned, unsigned> DstRegMap;
- bool sink3AddrInstruction(MachineInstr *MI, unsigned Reg,
- MachineBasicBlock::iterator OldPos);
-
bool isRevCopyChain(unsigned FromReg, unsigned ToReg, int Maxlen);
bool noUseAfterLastDef(unsigned Reg, unsigned Dist, unsigned &LastDef);
@@ -209,136 +201,6 @@ INITIALIZE_PASS_END(TwoAddressInstructionPass, DEBUG_TYPE,
static bool isPlainlyKilled(MachineInstr *MI, unsigned Reg, LiveIntervals *LIS);
-/// A two-address instruction has been converted to a three-address instruction
-/// to avoid clobbering a register. Try to sink it past the instruction that
-/// would kill the above mentioned register to reduce register pressure.
-bool TwoAddressInstructionPass::
-sink3AddrInstruction(MachineInstr *MI, unsigned SavedReg,
- MachineBasicBlock::iterator OldPos) {
- // FIXME: Shouldn't we be trying to do this before we three-addressify the
- // instruction? After this transformation is done, we no longer need
- // the instruction to be in three-address form.
-
- // Check if it's safe to move this instruction.
- bool SeenStore = true; // Be conservative.
- if (!MI->isSafeToMove(AA, SeenStore))
- return false;
-
- unsigned DefReg = 0;
- SmallSet<unsigned, 4> UseRegs;
-
- for (const MachineOperand &MO : MI->operands()) {
- if (!MO.isReg())
- continue;
- Register MOReg = MO.getReg();
- if (!MOReg)
- continue;
- if (MO.isUse() && MOReg != SavedReg)
- UseRegs.insert(MO.getReg());
- if (!MO.isDef())
- continue;
- if (MO.isImplicit())
- // Don't try to move it if it implicitly defines a register.
- return false;
- if (DefReg)
- // For now, don't move any instructions that define multiple registers.
- return false;
- DefReg = MO.getReg();
- }
-
- // Find the instruction that kills SavedReg.
- MachineInstr *KillMI = nullptr;
- if (LIS) {
- LiveInterval &LI = LIS->getInterval(SavedReg);
- assert(LI.end() != LI.begin() &&
- "Reg should not have empty live interval.");
-
- SlotIndex MBBEndIdx = LIS->getMBBEndIdx(MBB).getPrevSlot();
- LiveInterval::const_iterator I = LI.find(MBBEndIdx);
- if (I != LI.end() && I->start < MBBEndIdx)
- return false;
-
- --I;
- KillMI = LIS->getInstructionFromIndex(I->end);
- }
- if (!KillMI) {
- for (MachineOperand &UseMO : MRI->use_nodbg_operands(SavedReg)) {
- if (!UseMO.isKill())
- continue;
- KillMI = UseMO.getParent();
- break;
- }
- }
-
- // If we find the instruction that kills SavedReg, and it is in an
- // appropriate location, we can try to sink the current instruction
- // past it.
- if (!KillMI || KillMI->getParent() != MBB || KillMI == MI ||
- MachineBasicBlock::iterator(KillMI) == OldPos || KillMI->isTerminator())
- return false;
-
- // If any of the definitions are used by another instruction between the
- // position and the kill use, then it's not safe to sink it.
- //
- // FIXME: This can be sped up if there is an easy way to query whether an
- // instruction is before or after another instruction. Then we can use
- // MachineRegisterInfo def / use instead.
- MachineOperand *KillMO = nullptr;
- MachineBasicBlock::iterator KillPos = KillMI;
- ++KillPos;
-
- unsigned NumVisited = 0;
- for (MachineInstr &OtherMI : make_range(std::next(OldPos), KillPos)) {
- // Debug instructions cannot be counted against the limit.
- if (OtherMI.isDebugInstr())
- continue;
- if (NumVisited > 30) // FIXME: Arbitrary limit to reduce compile time cost.
- return false;
- ++NumVisited;
- for (unsigned i = 0, e = OtherMI.getNumOperands(); i != e; ++i) {
- MachineOperand &MO = OtherMI.getOperand(i);
- if (!MO.isReg())
- continue;
- Register MOReg = MO.getReg();
- if (!MOReg)
- continue;
- if (DefReg == MOReg)
- return false;
-
- if (MO.isKill() || (LIS && isPlainlyKilled(&OtherMI, MOReg, LIS))) {
- if (&OtherMI == KillMI && MOReg == SavedReg)
- // Save the operand that kills the register. We want to unset the kill
- // marker if we can sink MI past it.
- KillMO = &MO;
- else if (UseRegs.count(MOReg))
- // One of the uses is killed before the destination.
- return false;
- }
- }
- }
- assert(KillMO && "Didn't find kill");
-
- if (!LIS) {
- // Update kill and LV information.
- KillMO->setIsKill(false);
- KillMO = MI->findRegisterUseOperand(SavedReg, false, TRI);
- KillMO->setIsKill(true);
-
- if (LV)
- LV->replaceKillInstruction(SavedReg, *KillMI, *MI);
- }
-
- // Move instruction to its destination.
- MBB->remove(MI);
- MBB->insert(KillPos, MI);
-
- if (LIS)
- LIS->handleMove(*MI);
-
- ++Num3AddrSunk;
- return true;
-}
-
/// Return the MachineInstr* if it is the single def of the Reg in current BB.
static MachineInstr *getSingleDef(unsigned Reg, MachineBasicBlock *BB,
const MachineRegisterInfo *MRI) {
@@ -740,26 +602,15 @@ TwoAddressInstructionPass::convertInstTo3Addr(MachineBasicBlock::iterator &mi,
LLVM_DEBUG(dbgs() << "2addr: CONVERTING 2-ADDR: " << *mi);
LLVM_DEBUG(dbgs() << "2addr: TO 3-ADDR: " << *NewMI);
- bool Sunk = false;
if (LIS)
LIS->ReplaceMachineInstrInMaps(*mi, *NewMI);
- if (NewMI->findRegisterUseOperand(RegB, false, TRI))
- // FIXME: Temporary workaround. If the new instruction doesn't
- // uses RegB, convertToThreeAddress must have created more
- // then one instruction.
- Sunk = sink3AddrInstruction(NewMI, RegB, mi);
-
MBB->erase(mi); // Nuke the old inst.
- if (!Sunk) {
- DistanceMap.insert(std::make_pair(NewMI, Dist));
- mi = NewMI;
- nmi = std::next(mi);
- }
- else
- SunkInstrs.insert(NewMI);
+ DistanceMap.insert(std::make_pair(NewMI, Dist));
+ mi = NewMI;
+ nmi = std::next(mi);
// Update source and destination register maps.
SrcRegMap.erase(RegA);
@@ -1700,13 +1551,11 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &Func) {
SrcRegMap.clear();
DstRegMap.clear();
Processed.clear();
- SunkInstrs.clear();
for (MachineBasicBlock::iterator mi = MBB->begin(), me = MBB->end();
mi != me; ) {
MachineBasicBlock::iterator nmi = std::next(mi);
- // Don't revisit an instruction previously converted by target. It may
- // contain undef register operands (%noreg), which are not handled.
- if (mi->isDebugInstr() || SunkInstrs.count(&*mi)) {
+ // Skip debug instructions.
+ if (mi->isDebugInstr()) {
mi = nmi;
continue;
}