summaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2021-02-16 20:13:02 +0000
committerDimitry Andric <dim@FreeBSD.org>2021-02-16 20:13:02 +0000
commitb60736ec1405bb0a8dd40989f67ef4c93da068ab (patch)
tree5c43fbb7c9fc45f0f87e0e6795a86267dbd12f9d /llvm/lib/CodeGen/TwoAddressInstructionPass.cpp
parentcfca06d7963fa0909f90483b42a6d7d194d01e08 (diff)
Diffstat (limited to 'llvm/lib/CodeGen/TwoAddressInstructionPass.cpp')
-rw-r--r--llvm/lib/CodeGen/TwoAddressInstructionPass.cpp421
1 files changed, 138 insertions, 283 deletions
diff --git a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp
index de336abe607a..ecee4aed7f88 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,47 +108,38 @@ 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.
- DenseMap<unsigned, unsigned> SrcRegMap;
+ DenseMap<Register, Register> SrcRegMap;
// A map from virtual registers to physical registers which are likely targets
// to be coalesced to due to copies to physical registers from virtual
// registers. e.g. r1 = move v1024.
- DenseMap<unsigned, unsigned> DstRegMap;
-
- bool sink3AddrInstruction(MachineInstr *MI, unsigned Reg,
- MachineBasicBlock::iterator OldPos);
+ DenseMap<Register, Register> DstRegMap;
- bool isRevCopyChain(unsigned FromReg, unsigned ToReg, int Maxlen);
+ bool isRevCopyChain(Register FromReg, Register ToReg, int Maxlen);
- bool noUseAfterLastDef(unsigned Reg, unsigned Dist, unsigned &LastDef);
+ bool noUseAfterLastDef(Register Reg, unsigned Dist, unsigned &LastDef);
- bool isProfitableToCommute(unsigned regA, unsigned regB, unsigned regC,
+ bool isProfitableToCommute(Register RegA, Register RegB, Register RegC,
MachineInstr *MI, unsigned Dist);
bool commuteInstruction(MachineInstr *MI, unsigned DstIdx,
unsigned RegBIdx, unsigned RegCIdx, unsigned Dist);
- bool isProfitableToConv3Addr(unsigned RegA, unsigned RegB);
+ bool isProfitableToConv3Addr(Register RegA, Register RegB);
bool convertInstTo3Addr(MachineBasicBlock::iterator &mi,
- MachineBasicBlock::iterator &nmi,
- unsigned RegA, unsigned RegB, unsigned Dist);
+ MachineBasicBlock::iterator &nmi, Register RegA,
+ Register RegB, unsigned Dist);
- bool isDefTooClose(unsigned Reg, unsigned Dist, MachineInstr *MI);
+ bool isDefTooClose(Register Reg, unsigned Dist, MachineInstr *MI);
bool rescheduleMIBelowKill(MachineBasicBlock::iterator &mi,
- MachineBasicBlock::iterator &nmi,
- unsigned Reg);
+ MachineBasicBlock::iterator &nmi, Register Reg);
bool rescheduleKillAboveMI(MachineBasicBlock::iterator &mi,
- MachineBasicBlock::iterator &nmi,
- unsigned Reg);
+ MachineBasicBlock::iterator &nmi, Register Reg);
bool tryInstructionTransform(MachineBasicBlock::iterator &mi,
MachineBasicBlock::iterator &nmi,
@@ -161,7 +151,7 @@ class TwoAddressInstructionPass : public MachineFunctionPass {
unsigned BaseOpIdx,
bool BaseOpKilled,
unsigned Dist);
- void scanUses(unsigned DstReg);
+ void scanUses(Register DstReg);
void processCopy(MachineInstr *MI);
@@ -207,140 +197,10 @@ INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
INITIALIZE_PASS_END(TwoAddressInstructionPass, DEBUG_TYPE,
"Two-Address instruction pass", false, false)
-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;
-}
+static bool isPlainlyKilled(MachineInstr *MI, Register Reg, LiveIntervals *LIS);
/// Return the MachineInstr* if it is the single def of the Reg in current BB.
-static MachineInstr *getSingleDef(unsigned Reg, MachineBasicBlock *BB,
+static MachineInstr *getSingleDef(Register Reg, MachineBasicBlock *BB,
const MachineRegisterInfo *MRI) {
MachineInstr *Ret = nullptr;
for (MachineInstr &DefMI : MRI->def_instructions(Reg)) {
@@ -361,9 +221,9 @@ static MachineInstr *getSingleDef(unsigned Reg, MachineBasicBlock *BB,
/// %Tmp2 = copy %ToReg;
/// MaxLen specifies the maximum length of the copy chain the func
/// can walk through.
-bool TwoAddressInstructionPass::isRevCopyChain(unsigned FromReg, unsigned ToReg,
+bool TwoAddressInstructionPass::isRevCopyChain(Register FromReg, Register ToReg,
int Maxlen) {
- unsigned TmpReg = FromReg;
+ Register TmpReg = FromReg;
for (int i = 0; i < Maxlen; i++) {
MachineInstr *Def = getSingleDef(TmpReg, MBB, MRI);
if (!Def || !Def->isCopy())
@@ -381,7 +241,7 @@ bool TwoAddressInstructionPass::isRevCopyChain(unsigned FromReg, unsigned ToReg,
/// in the MBB that defines the specified register and the two-address
/// instruction which is being processed. It also returns the last def location
/// by reference.
-bool TwoAddressInstructionPass::noUseAfterLastDef(unsigned Reg, unsigned Dist,
+bool TwoAddressInstructionPass::noUseAfterLastDef(Register Reg, unsigned Dist,
unsigned &LastDef) {
LastDef = 0;
unsigned LastUse = Dist;
@@ -405,8 +265,8 @@ bool TwoAddressInstructionPass::noUseAfterLastDef(unsigned Reg, unsigned Dist,
/// instruction. It also returns the source and destination registers and
/// whether they are physical registers by reference.
static bool isCopyToReg(MachineInstr &MI, const TargetInstrInfo *TII,
- unsigned &SrcReg, unsigned &DstReg,
- bool &IsSrcPhys, bool &IsDstPhys) {
+ Register &SrcReg, Register &DstReg, bool &IsSrcPhys,
+ bool &IsDstPhys) {
SrcReg = 0;
DstReg = 0;
if (MI.isCopy()) {
@@ -415,19 +275,20 @@ static bool isCopyToReg(MachineInstr &MI, const TargetInstrInfo *TII,
} else if (MI.isInsertSubreg() || MI.isSubregToReg()) {
DstReg = MI.getOperand(0).getReg();
SrcReg = MI.getOperand(2).getReg();
- } else
+ } else {
return false;
+ }
- IsSrcPhys = Register::isPhysicalRegister(SrcReg);
- IsDstPhys = Register::isPhysicalRegister(DstReg);
+ IsSrcPhys = SrcReg.isPhysical();
+ IsDstPhys = DstReg.isPhysical();
return true;
}
/// Test if the given register value, which is used by the
/// given instruction, is killed by the given instruction.
-static bool isPlainlyKilled(MachineInstr *MI, unsigned Reg,
+static bool isPlainlyKilled(MachineInstr *MI, Register Reg,
LiveIntervals *LIS) {
- if (LIS && Register::isVirtualRegister(Reg) && !LIS->isNotInMIMap(*MI)) {
+ if (LIS && Reg.isVirtual() && !LIS->isNotInMIMap(*MI)) {
// FIXME: Sometimes tryInstructionTransform() will add instructions and
// test whether they can be folded before keeping them. In this case it
// sets a kill before recursively calling tryInstructionTransform() again.
@@ -466,20 +327,17 @@ static bool isPlainlyKilled(MachineInstr *MI, unsigned Reg,
///
/// If allowFalsePositives is true then likely kills are treated as kills even
/// if it can't be proven that they are kills.
-static bool isKilled(MachineInstr &MI, unsigned Reg,
- const MachineRegisterInfo *MRI,
- const TargetInstrInfo *TII,
- LiveIntervals *LIS,
- bool allowFalsePositives) {
+static bool isKilled(MachineInstr &MI, Register Reg,
+ const MachineRegisterInfo *MRI, const TargetInstrInfo *TII,
+ LiveIntervals *LIS, bool allowFalsePositives) {
MachineInstr *DefMI = &MI;
while (true) {
// All uses of physical registers are likely to be kills.
- if (Register::isPhysicalRegister(Reg) &&
- (allowFalsePositives || MRI->hasOneUse(Reg)))
+ if (Reg.isPhysical() && (allowFalsePositives || MRI->hasOneUse(Reg)))
return true;
if (!isPlainlyKilled(DefMI, Reg, LIS))
return false;
- if (Register::isPhysicalRegister(Reg))
+ if (Reg.isPhysical())
return true;
MachineRegisterInfo::def_iterator Begin = MRI->def_begin(Reg);
// If there are multiple defs, we can't do a simple analysis, so just
@@ -488,7 +346,7 @@ static bool isKilled(MachineInstr &MI, unsigned Reg,
return true;
DefMI = Begin->getParent();
bool IsSrcPhys, IsDstPhys;
- unsigned SrcReg, DstReg;
+ Register SrcReg, DstReg;
// If the def is something other than a copy, then it isn't going to
// be coalesced, so follow the kill flag.
if (!isCopyToReg(*DefMI, TII, SrcReg, DstReg, IsSrcPhys, IsDstPhys))
@@ -499,7 +357,7 @@ static bool isKilled(MachineInstr &MI, unsigned Reg,
/// Return true if the specified MI uses the specified register as a two-address
/// use. If so, return the destination register by reference.
-static bool isTwoAddrUse(MachineInstr &MI, unsigned Reg, unsigned &DstReg) {
+static bool isTwoAddrUse(MachineInstr &MI, Register Reg, Register &DstReg) {
for (unsigned i = 0, NumOps = MI.getNumOperands(); i != NumOps; ++i) {
const MachineOperand &MO = MI.getOperand(i);
if (!MO.isReg() || !MO.isUse() || MO.getReg() != Reg)
@@ -515,19 +373,17 @@ static bool isTwoAddrUse(MachineInstr &MI, unsigned Reg, unsigned &DstReg) {
/// Given a register, if has a single in-basic block use, return the use
/// instruction if it's a copy or a two-address use.
-static
-MachineInstr *findOnlyInterestingUse(unsigned Reg, MachineBasicBlock *MBB,
- MachineRegisterInfo *MRI,
- const TargetInstrInfo *TII,
- bool &IsCopy,
- unsigned &DstReg, bool &IsDstPhys) {
+static MachineInstr *
+findOnlyInterestingUse(Register Reg, MachineBasicBlock *MBB,
+ MachineRegisterInfo *MRI, const TargetInstrInfo *TII,
+ bool &IsCopy, Register &DstReg, bool &IsDstPhys) {
if (!MRI->hasOneNonDBGUse(Reg))
// None or more than one use.
return nullptr;
MachineInstr &UseMI = *MRI->use_instr_nodbg_begin(Reg);
if (UseMI.getParent() != MBB)
return nullptr;
- unsigned SrcReg;
+ Register SrcReg;
bool IsSrcPhys;
if (isCopyToReg(UseMI, TII, SrcReg, DstReg, IsSrcPhys, IsDstPhys)) {
IsCopy = true;
@@ -535,7 +391,7 @@ MachineInstr *findOnlyInterestingUse(unsigned Reg, MachineBasicBlock *MBB,
}
IsDstPhys = false;
if (isTwoAddrUse(UseMI, Reg, DstReg)) {
- IsDstPhys = Register::isPhysicalRegister(DstReg);
+ IsDstPhys = DstReg.isPhysical();
return &UseMI;
}
return nullptr;
@@ -543,22 +399,22 @@ MachineInstr *findOnlyInterestingUse(unsigned Reg, MachineBasicBlock *MBB,
/// Return the physical register the specified virtual register might be mapped
/// to.
-static unsigned
-getMappedReg(unsigned Reg, DenseMap<unsigned, unsigned> &RegMap) {
- while (Register::isVirtualRegister(Reg)) {
- DenseMap<unsigned, unsigned>::iterator SI = RegMap.find(Reg);
+static MCRegister getMappedReg(Register Reg,
+ DenseMap<Register, Register> &RegMap) {
+ while (Reg.isVirtual()) {
+ DenseMap<Register, Register>::iterator SI = RegMap.find(Reg);
if (SI == RegMap.end())
return 0;
Reg = SI->second;
}
- if (Register::isPhysicalRegister(Reg))
+ if (Reg.isPhysical())
return Reg;
return 0;
}
/// Return true if the two registers are equal or aliased.
-static bool
-regsAreCompatible(unsigned RegA, unsigned RegB, const TargetRegisterInfo *TRI) {
+static bool regsAreCompatible(Register RegA, Register RegB,
+ const TargetRegisterInfo *TRI) {
if (RegA == RegB)
return true;
if (!RegA || !RegB)
@@ -567,7 +423,7 @@ regsAreCompatible(unsigned RegA, unsigned RegB, const TargetRegisterInfo *TRI) {
}
// Returns true if Reg is equal or aliased to at least one register in Set.
-static bool regOverlapsSet(const SmallVectorImpl<unsigned> &Set, unsigned Reg,
+static bool regOverlapsSet(const SmallVectorImpl<Register> &Set, Register Reg,
const TargetRegisterInfo *TRI) {
for (unsigned R : Set)
if (TRI->regsOverlap(R, Reg))
@@ -578,10 +434,11 @@ static bool regOverlapsSet(const SmallVectorImpl<unsigned> &Set, unsigned Reg,
/// Return true if it's potentially profitable to commute the two-address
/// instruction that's being processed.
-bool
-TwoAddressInstructionPass::
-isProfitableToCommute(unsigned regA, unsigned regB, unsigned regC,
- MachineInstr *MI, unsigned Dist) {
+bool TwoAddressInstructionPass::isProfitableToCommute(Register RegA,
+ Register RegB,
+ Register RegC,
+ MachineInstr *MI,
+ unsigned Dist) {
if (OptLevel == CodeGenOpt::None)
return false;
@@ -603,7 +460,7 @@ isProfitableToCommute(unsigned regA, unsigned regB, unsigned regC,
// insert => %reg1030 = COPY %reg1029
// %reg1030 = ADD8rr killed %reg1029, killed %reg1028, implicit dead %eflags
- if (!isPlainlyKilled(MI, regC, LIS))
+ if (!isPlainlyKilled(MI, RegC, LIS))
return false;
// Ok, we have something like:
@@ -616,10 +473,10 @@ isProfitableToCommute(unsigned regA, unsigned regB, unsigned regC,
// %reg1026 = ADD %reg1024, %reg1025
// r0 = MOV %reg1026
// Commute the ADD to hopefully eliminate an otherwise unavoidable copy.
- unsigned ToRegA = getMappedReg(regA, DstRegMap);
+ MCRegister ToRegA = getMappedReg(RegA, DstRegMap);
if (ToRegA) {
- unsigned FromRegB = getMappedReg(regB, SrcRegMap);
- unsigned FromRegC = getMappedReg(regC, SrcRegMap);
+ MCRegister FromRegB = getMappedReg(RegB, SrcRegMap);
+ MCRegister FromRegC = getMappedReg(RegC, SrcRegMap);
bool CompB = FromRegB && regsAreCompatible(FromRegB, ToRegA, TRI);
bool CompC = FromRegC && regsAreCompatible(FromRegC, ToRegA, TRI);
@@ -637,16 +494,16 @@ isProfitableToCommute(unsigned regA, unsigned regB, unsigned regC,
return false;
}
- // If there is a use of regC between its last def (could be livein) and this
+ // If there is a use of RegC between its last def (could be livein) and this
// instruction, then bail.
unsigned LastDefC = 0;
- if (!noUseAfterLastDef(regC, Dist, LastDefC))
+ if (!noUseAfterLastDef(RegC, Dist, LastDefC))
return false;
- // If there is a use of regB between its last def (could be livein) and this
+ // If there is a use of RegB between its last def (could be livein) and this
// instruction, then go ahead and make this transformation.
unsigned LastDefB = 0;
- if (!noUseAfterLastDef(regB, Dist, LastDefB))
+ if (!noUseAfterLastDef(RegB, Dist, LastDefB))
return true;
// Look for situation like this:
@@ -664,14 +521,14 @@ isProfitableToCommute(unsigned regA, unsigned regB, unsigned regC,
// To more generally minimize register copies, ideally the logic of two addr
// instruction pass should be integrated with register allocation pass where
// interference graph is available.
- if (isRevCopyChain(regC, regA, MaxDataFlowEdge))
+ if (isRevCopyChain(RegC, RegA, MaxDataFlowEdge))
return true;
- if (isRevCopyChain(regB, regA, MaxDataFlowEdge))
+ if (isRevCopyChain(RegB, RegA, MaxDataFlowEdge))
return false;
// Since there are no intervening uses for both registers, then commute
- // if the def of regC is closer. Its live interval is shorter.
+ // if the def of RegC is closer. Its live interval is shorter.
return LastDefB && LastDefC && LastDefC > LastDefB;
}
@@ -697,7 +554,7 @@ bool TwoAddressInstructionPass::commuteInstruction(MachineInstr *MI,
"instruction unless it was requested.");
// Update source register map.
- unsigned FromRegC = getMappedReg(RegC, SrcRegMap);
+ MCRegister FromRegC = getMappedReg(RegC, SrcRegMap);
if (FromRegC) {
Register RegA = MI->getOperand(DstIdx).getReg();
SrcRegMap[RegA] = FromRegC;
@@ -708,28 +565,26 @@ bool TwoAddressInstructionPass::commuteInstruction(MachineInstr *MI,
/// Return true if it is profitable to convert the given 2-address instruction
/// to a 3-address one.
-bool
-TwoAddressInstructionPass::isProfitableToConv3Addr(unsigned RegA,unsigned RegB){
+bool TwoAddressInstructionPass::isProfitableToConv3Addr(Register RegA,
+ Register RegB) {
// Look for situations like this:
// %reg1024 = MOV r1
// %reg1025 = MOV r0
// %reg1026 = ADD %reg1024, %reg1025
// r2 = MOV %reg1026
// Turn ADD into a 3-address instruction to avoid a copy.
- unsigned FromRegB = getMappedReg(RegB, SrcRegMap);
+ MCRegister FromRegB = getMappedReg(RegB, SrcRegMap);
if (!FromRegB)
return false;
- unsigned ToRegA = getMappedReg(RegA, DstRegMap);
+ MCRegister ToRegA = getMappedReg(RegA, DstRegMap);
return (ToRegA && !regsAreCompatible(FromRegB, ToRegA, TRI));
}
/// Convert the specified two-address instruction into a three address one.
/// Return true if this transformation was successful.
-bool
-TwoAddressInstructionPass::convertInstTo3Addr(MachineBasicBlock::iterator &mi,
- MachineBasicBlock::iterator &nmi,
- unsigned RegA, unsigned RegB,
- unsigned Dist) {
+bool TwoAddressInstructionPass::convertInstTo3Addr(
+ MachineBasicBlock::iterator &mi, MachineBasicBlock::iterator &nmi,
+ Register RegA, Register RegB, unsigned Dist) {
// FIXME: Why does convertToThreeAddress() need an iterator reference?
MachineFunction::iterator MFI = MBB->getIterator();
MachineInstr *NewMI = TII->convertToThreeAddress(MFI, *mi, LV);
@@ -740,26 +595,33 @@ 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);
+ // If the old instruction is debug value tracked, an update is required.
+ if (auto OldInstrNum = mi->peekDebugInstrNum()) {
+ // Sanity check.
+ assert(mi->getNumExplicitDefs() == 1);
+ assert(NewMI->getNumExplicitDefs() == 1);
- MBB->erase(mi); // Nuke the old inst.
+ // Find the old and new def location.
+ auto OldIt = mi->defs().begin();
+ auto NewIt = NewMI->defs().begin();
+ unsigned OldIdx = mi->getOperandNo(OldIt);
+ unsigned NewIdx = NewMI->getOperandNo(NewIt);
- if (!Sunk) {
- DistanceMap.insert(std::make_pair(NewMI, Dist));
- mi = NewMI;
- nmi = std::next(mi);
+ // Record that one def has been replaced by the other.
+ unsigned NewInstrNum = NewMI->getDebugInstrNum();
+ MF->makeDebugValueSubstitution(std::make_pair(OldInstrNum, OldIdx),
+ std::make_pair(NewInstrNum, NewIdx));
}
- else
- SunkInstrs.insert(NewMI);
+
+ MBB->erase(mi); // Nuke the old inst.
+
+ DistanceMap.insert(std::make_pair(NewMI, Dist));
+ mi = NewMI;
+ nmi = std::next(mi);
// Update source and destination register maps.
SrcRegMap.erase(RegA);
@@ -769,13 +631,12 @@ TwoAddressInstructionPass::convertInstTo3Addr(MachineBasicBlock::iterator &mi,
/// Scan forward recursively for only uses, update maps if the use is a copy or
/// a two-address instruction.
-void
-TwoAddressInstructionPass::scanUses(unsigned DstReg) {
- SmallVector<unsigned, 4> VirtRegPairs;
+void TwoAddressInstructionPass::scanUses(Register DstReg) {
+ SmallVector<Register, 4> VirtRegPairs;
bool IsDstPhys;
bool IsCopy = false;
- unsigned NewReg = 0;
- unsigned Reg = DstReg;
+ Register NewReg;
+ Register Reg = DstReg;
while (MachineInstr *UseMI = findOnlyInterestingUse(Reg, MBB, MRI, TII,IsCopy,
NewReg, IsDstPhys)) {
if (IsCopy && !Processed.insert(UseMI).second)
@@ -831,13 +692,13 @@ void TwoAddressInstructionPass::processCopy(MachineInstr *MI) {
return;
bool IsSrcPhys, IsDstPhys;
- unsigned SrcReg, DstReg;
+ Register SrcReg, DstReg;
if (!isCopyToReg(*MI, TII, SrcReg, DstReg, IsSrcPhys, IsDstPhys))
return;
- if (IsDstPhys && !IsSrcPhys)
+ if (IsDstPhys && !IsSrcPhys) {
DstRegMap.insert(std::make_pair(SrcReg, DstReg));
- else if (!IsDstPhys && IsSrcPhys) {
+ } else if (!IsDstPhys && IsSrcPhys) {
bool isNew = SrcRegMap.insert(std::make_pair(DstReg, SrcReg)).second;
if (!isNew)
assert(SrcRegMap[DstReg] == SrcReg &&
@@ -852,10 +713,9 @@ void TwoAddressInstructionPass::processCopy(MachineInstr *MI) {
/// If there is one more local instruction that reads 'Reg' and it kills 'Reg,
/// consider moving the instruction below the kill instruction in order to
/// eliminate the need for the copy.
-bool TwoAddressInstructionPass::
-rescheduleMIBelowKill(MachineBasicBlock::iterator &mi,
- MachineBasicBlock::iterator &nmi,
- unsigned Reg) {
+bool TwoAddressInstructionPass::rescheduleMIBelowKill(
+ MachineBasicBlock::iterator &mi, MachineBasicBlock::iterator &nmi,
+ Register Reg) {
// Bail immediately if we don't have LV or LIS available. We use them to find
// kills efficiently.
if (!LV && !LIS)
@@ -892,7 +752,7 @@ rescheduleMIBelowKill(MachineBasicBlock::iterator &mi,
// Don't move pass calls, etc.
return false;
- unsigned DstReg;
+ Register DstReg;
if (isTwoAddrUse(*KillMI, Reg, DstReg))
return false;
@@ -904,9 +764,9 @@ rescheduleMIBelowKill(MachineBasicBlock::iterator &mi,
// FIXME: Needs more sophisticated heuristics.
return false;
- SmallVector<unsigned, 2> Uses;
- SmallVector<unsigned, 2> Kills;
- SmallVector<unsigned, 2> Defs;
+ SmallVector<Register, 2> Uses;
+ SmallVector<Register, 2> Kills;
+ SmallVector<Register, 2> Defs;
for (const MachineOperand &MO : MI->operands()) {
if (!MO.isReg())
continue;
@@ -1021,7 +881,7 @@ rescheduleMIBelowKill(MachineBasicBlock::iterator &mi,
/// Return true if the re-scheduling will put the given instruction too close
/// to the defs of its register dependencies.
-bool TwoAddressInstructionPass::isDefTooClose(unsigned Reg, unsigned Dist,
+bool TwoAddressInstructionPass::isDefTooClose(Register Reg, unsigned Dist,
MachineInstr *MI) {
for (MachineInstr &DefMI : MRI->def_instructions(Reg)) {
if (DefMI.getParent() != MBB || DefMI.isCopy() || DefMI.isCopyLike())
@@ -1042,10 +902,9 @@ bool TwoAddressInstructionPass::isDefTooClose(unsigned Reg, unsigned Dist,
/// If there is one more local instruction that reads 'Reg' and it kills 'Reg,
/// consider moving the kill instruction above the current two-address
/// instruction in order to eliminate the need for the copy.
-bool TwoAddressInstructionPass::
-rescheduleKillAboveMI(MachineBasicBlock::iterator &mi,
- MachineBasicBlock::iterator &nmi,
- unsigned Reg) {
+bool TwoAddressInstructionPass::rescheduleKillAboveMI(
+ MachineBasicBlock::iterator &mi, MachineBasicBlock::iterator &nmi,
+ Register Reg) {
// Bail immediately if we don't have LV or LIS available. We use them to find
// kills efficiently.
if (!LV && !LIS)
@@ -1077,7 +936,7 @@ rescheduleKillAboveMI(MachineBasicBlock::iterator &mi,
// Don't mess with copies, they may be coalesced later.
return false;
- unsigned DstReg;
+ Register DstReg;
if (isTwoAddrUse(*KillMI, Reg, DstReg))
return false;
@@ -1085,10 +944,10 @@ rescheduleKillAboveMI(MachineBasicBlock::iterator &mi,
if (!KillMI->isSafeToMove(AA, SeenStore))
return false;
- SmallSet<unsigned, 2> Uses;
- SmallSet<unsigned, 2> Kills;
- SmallSet<unsigned, 2> Defs;
- SmallSet<unsigned, 2> LiveDefs;
+ SmallVector<Register, 2> Uses;
+ SmallVector<Register, 2> Kills;
+ SmallVector<Register, 2> Defs;
+ SmallVector<Register, 2> LiveDefs;
for (const MachineOperand &MO : KillMI->operands()) {
if (!MO.isReg())
continue;
@@ -1101,13 +960,13 @@ rescheduleKillAboveMI(MachineBasicBlock::iterator &mi,
bool isKill = MO.isKill() || (LIS && isPlainlyKilled(KillMI, MOReg, LIS));
if (MOReg == Reg && !isKill)
return false;
- Uses.insert(MOReg);
+ Uses.push_back(MOReg);
if (isKill && MOReg != Reg)
- Kills.insert(MOReg);
- } else if (Register::isPhysicalRegister(MOReg)) {
- Defs.insert(MOReg);
+ Kills.push_back(MOReg);
+ } else if (MOReg.isPhysical()) {
+ Defs.push_back(MOReg);
if (!MO.isDead())
- LiveDefs.insert(MOReg);
+ LiveDefs.push_back(MOReg);
}
}
@@ -1125,7 +984,7 @@ rescheduleKillAboveMI(MachineBasicBlock::iterator &mi,
OtherMI.isBranch() || OtherMI.isTerminator())
// Don't move pass calls, etc.
return false;
- SmallVector<unsigned, 2> OtherDefs;
+ SmallVector<Register, 2> OtherDefs;
for (const MachineOperand &MO : OtherMI.operands()) {
if (!MO.isReg())
continue;
@@ -1133,11 +992,11 @@ rescheduleKillAboveMI(MachineBasicBlock::iterator &mi,
if (!MOReg)
continue;
if (MO.isUse()) {
- if (Defs.count(MOReg))
+ if (regOverlapsSet(Defs, MOReg, TRI))
// Moving KillMI can clobber the physical register if the def has
// not been seen.
return false;
- if (Kills.count(MOReg))
+ if (regOverlapsSet(Kills, MOReg, TRI))
// Don't want to extend other live ranges and update kills.
return false;
if (&OtherMI != MI && MOReg == Reg &&
@@ -1150,13 +1009,13 @@ rescheduleKillAboveMI(MachineBasicBlock::iterator &mi,
}
for (unsigned i = 0, e = OtherDefs.size(); i != e; ++i) {
- unsigned MOReg = OtherDefs[i];
- if (Uses.count(MOReg))
+ Register MOReg = OtherDefs[i];
+ if (regOverlapsSet(Uses, MOReg, TRI))
return false;
- if (Register::isPhysicalRegister(MOReg) && LiveDefs.count(MOReg))
+ if (MOReg.isPhysical() && regOverlapsSet(LiveDefs, MOReg, TRI))
return false;
// Physical register def is seen.
- Defs.erase(MOReg);
+ llvm::erase_value(Defs, MOReg);
}
}
@@ -1274,11 +1133,10 @@ tryInstructionTransform(MachineBasicBlock::iterator &mi,
Register regA = MI.getOperand(DstIdx).getReg();
Register regB = MI.getOperand(SrcIdx).getReg();
- assert(Register::isVirtualRegister(regB) &&
- "cannot make instruction into two-address form");
+ assert(regB.isVirtual() && "cannot make instruction into two-address form");
bool regBKilled = isKilled(MI, regB, MRI, TII, LIS, true);
- if (Register::isVirtualRegister(regA))
+ if (regA.isVirtual())
scanUses(regA);
bool Commuted = tryInstructionCommute(&MI, DstIdx, SrcIdx, regBKilled, Dist);
@@ -1394,7 +1252,7 @@ tryInstructionTransform(MachineBasicBlock::iterator &mi,
if (LV) {
for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
MachineOperand &MO = MI.getOperand(i);
- if (MO.isReg() && Register::isVirtualRegister(MO.getReg())) {
+ if (MO.isReg() && MO.getReg().isVirtual()) {
if (MO.isUse()) {
if (MO.isKill()) {
if (NewMIs[0]->killsRegister(MO.getReg()))
@@ -1479,7 +1337,7 @@ collectTiedOperands(MachineInstr *MI, TiedOperandMap &TiedOperands) {
// Deal with undef uses immediately - simply rewrite the src operand.
if (SrcMO.isUndef() && !DstMO.getSubReg()) {
// Constrain the DstReg register class if required.
- if (Register::isVirtualRegister(DstReg))
+ if (DstReg.isVirtual())
if (const TargetRegisterClass *RC = TII->getRegClass(MCID, SrcIdx,
TRI, *MF))
MRI->constrainRegClass(DstReg, RC);
@@ -1509,7 +1367,7 @@ TwoAddressInstructionPass::processTiedPairs(MachineInstr *MI,
bool AllUsesCopied = true;
unsigned LastCopiedReg = 0;
SlotIndex LastCopyIdx;
- unsigned RegB = 0;
+ Register RegB = 0;
unsigned SubRegB = 0;
for (unsigned tpi = 0, tpe = TiedPairs.size(); tpi != tpe; ++tpi) {
unsigned SrcIdx = TiedPairs[tpi].first;
@@ -1532,8 +1390,7 @@ TwoAddressInstructionPass::processTiedPairs(MachineInstr *MI,
}
LastCopiedReg = RegA;
- assert(Register::isVirtualRegister(RegB) &&
- "cannot make instruction into two-address form");
+ assert(RegB.isVirtual() && "cannot make instruction into two-address form");
#ifndef NDEBUG
// First, verify that we don't have a use of "a" in the instruction
@@ -1553,7 +1410,7 @@ TwoAddressInstructionPass::processTiedPairs(MachineInstr *MI,
MIB.addReg(RegB, 0, SubRegB);
const TargetRegisterClass *RC = MRI->getRegClass(RegB);
if (SubRegB) {
- if (Register::isVirtualRegister(RegA)) {
+ if (RegA.isVirtual()) {
assert(TRI->getMatchingSuperRegClass(RC, MRI->getRegClass(RegA),
SubRegB) &&
"tied subregister must be a truncation");
@@ -1574,7 +1431,7 @@ TwoAddressInstructionPass::processTiedPairs(MachineInstr *MI,
if (LIS) {
LastCopyIdx = LIS->InsertMachineInstrInMaps(*PrevMI).getRegSlot();
- if (Register::isVirtualRegister(RegA)) {
+ if (RegA.isVirtual()) {
LiveInterval &LI = LIS->getInterval(RegA);
VNInfo *VNI = LI.getNextValue(LastCopyIdx, LIS->getVNInfoAllocator());
SlotIndex endIdx =
@@ -1594,7 +1451,7 @@ TwoAddressInstructionPass::processTiedPairs(MachineInstr *MI,
}
// Make sure regA is a legal regclass for the SrcIdx operand.
- if (Register::isVirtualRegister(RegA) && Register::isVirtualRegister(RegB))
+ if (RegA.isVirtual() && RegB.isVirtual())
MRI->constrainRegClass(RegA, RC);
MO.setReg(RegA);
// The getMatchingSuper asserts guarantee that the register class projected
@@ -1700,13 +1557,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;
}
@@ -1800,7 +1655,7 @@ void TwoAddressInstructionPass::
eliminateRegSequence(MachineBasicBlock::iterator &MBBI) {
MachineInstr &MI = *MBBI;
Register DstReg = MI.getOperand(0).getReg();
- if (MI.getOperand(0).getSubReg() || Register::isPhysicalRegister(DstReg) ||
+ if (MI.getOperand(0).getSubReg() || DstReg.isPhysical() ||
!(MI.getNumOperands() & 1)) {
LLVM_DEBUG(dbgs() << "Illegal REG_SEQUENCE instruction:" << MI);
llvm_unreachable(nullptr);
@@ -1850,7 +1705,7 @@ eliminateRegSequence(MachineBasicBlock::iterator &MBBI) {
DefEmitted = true;
// Update LiveVariables' kill info.
- if (LV && isKill && !Register::isPhysicalRegister(SrcReg))
+ if (LV && isKill && !SrcReg.isPhysical())
LV->replaceKillInstruction(SrcReg, MI, *CopyMI);
LLVM_DEBUG(dbgs() << "Inserted: " << *CopyMI);