summaryrefslogtreecommitdiff
path: root/lib/CodeGen/RegisterCoalescer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/RegisterCoalescer.cpp')
-rw-r--r--lib/CodeGen/RegisterCoalescer.cpp291
1 files changed, 158 insertions, 133 deletions
diff --git a/lib/CodeGen/RegisterCoalescer.cpp b/lib/CodeGen/RegisterCoalescer.cpp
index a67d07b36474..00a2e93c71ca 100644
--- a/lib/CodeGen/RegisterCoalescer.cpp
+++ b/lib/CodeGen/RegisterCoalescer.cpp
@@ -1,4 +1,4 @@
-//===- RegisterCoalescer.cpp - Generic Register Coalescing Interface -------==//
+//===- RegisterCoalescer.cpp - Generic Register Coalescing Interface ------===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,32 +14,49 @@
//===----------------------------------------------------------------------===//
#include "RegisterCoalescer.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/CodeGen/LiveIntervalAnalysis.h"
+#include "llvm/CodeGen/LiveInterval.h"
+#include "llvm/CodeGen/LiveIntervals.h"
#include "llvm/CodeGen/LiveRangeEdit.h"
-#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
+#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/RegisterClassInfo.h"
-#include "llvm/CodeGen/VirtRegMap.h"
-#include "llvm/IR/Value.h"
+#include "llvm/CodeGen/SlotIndexes.h"
+#include "llvm/CodeGen/TargetInstrInfo.h"
+#include "llvm/CodeGen/TargetOpcodes.h"
+#include "llvm/CodeGen/TargetRegisterInfo.h"
+#include "llvm/CodeGen/TargetSubtargetInfo.h"
+#include "llvm/IR/DebugLoc.h"
+#include "llvm/MC/LaneBitmask.h"
+#include "llvm/MC/MCInstrDesc.h"
+#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetInstrInfo.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetRegisterInfo.h"
-#include "llvm/Target/TargetSubtargetInfo.h"
#include <algorithm>
-#include <cmath>
+#include <cassert>
+#include <iterator>
+#include <limits>
+#include <tuple>
+#include <utility>
+#include <vector>
+
using namespace llvm;
#define DEBUG_TYPE "regalloc"
@@ -53,10 +70,9 @@ STATISTIC(NumInflated , "Number of register classes inflated");
STATISTIC(NumLaneConflicts, "Number of dead lane conflicts tested");
STATISTIC(NumLaneResolves, "Number of dead lane conflicts resolved");
-static cl::opt<bool>
-EnableJoining("join-liveintervals",
- cl::desc("Coalesce copies (default=true)"),
- cl::init(true));
+static cl::opt<bool> EnableJoining("join-liveintervals",
+ cl::desc("Coalesce copies (default=true)"),
+ cl::init(true), cl::Hidden);
static cl::opt<bool> UseTerminalRule("terminal-rule",
cl::desc("Apply the terminal rule"),
@@ -79,11 +95,11 @@ VerifyCoalescing("verify-coalescing",
cl::Hidden);
namespace {
+
class RegisterCoalescer : public MachineFunctionPass,
private LiveRangeEdit::Delegate {
MachineFunction* MF;
MachineRegisterInfo* MRI;
- const TargetMachine* TM;
const TargetRegisterInfo* TRI;
const TargetInstrInfo* TII;
LiveIntervals *LIS;
@@ -211,9 +227,9 @@ namespace {
/// flag.
/// This can happen when undef uses were previously concealed by a copy
/// which we coalesced. Example:
- /// %vreg0:sub0<def,read-undef> = ...
- /// %vreg1 = COPY %vreg0 <-- Coalescing COPY reveals undef
- /// = use %vreg1:sub1 <-- hidden undef use
+ /// %0:sub0<def,read-undef> = ...
+ /// %1 = COPY %0 <-- Coalescing COPY reveals undef
+ /// = use %1:sub1 <-- hidden undef use
void addUndefFlag(const LiveInterval &Int, SlotIndex UseIdx,
MachineOperand &MO, unsigned SubRegIdx);
@@ -248,8 +264,19 @@ namespace {
}
}
+ /// Wrapper Method to do all the necessary work when an Instruction is
+ /// deleted.
+ /// Optimizations should use this to make sure that deleted instructions
+ /// are always accounted for.
+ void deleteInstr(MachineInstr* MI) {
+ ErasedInstrs.insert(MI);
+ LIS->RemoveMachineInstrFromMaps(*MI);
+ MI->eraseFromParent();
+ }
+
public:
static char ID; ///< Class identification, replacement for typeinfo
+
RegisterCoalescer() : MachineFunctionPass(ID) {
initializeRegisterCoalescerPass(*PassRegistry::getPassRegistry());
}
@@ -264,8 +291,11 @@ namespace {
/// Implement the dump method.
void print(raw_ostream &O, const Module* = nullptr) const override;
};
+
} // end anonymous namespace
+char RegisterCoalescer::ID = 0;
+
char &llvm::RegisterCoalescerID = RegisterCoalescer::ID;
INITIALIZE_PASS_BEGIN(RegisterCoalescer, "simple-register-coalescing",
@@ -277,8 +307,6 @@ INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
INITIALIZE_PASS_END(RegisterCoalescer, "simple-register-coalescing",
"Simple Register Coalescing", false, false)
-char RegisterCoalescer::ID = 0;
-
static bool isMoveInstr(const TargetRegisterInfo &tri, const MachineInstr *MI,
unsigned &Src, unsigned &Dst,
unsigned &SrcSub, unsigned &DstSub) {
@@ -334,7 +362,7 @@ bool CoalescerPair::setRegisters(const MachineInstr *MI) {
Flipped = true;
}
- const MachineRegisterInfo &MRI = MI->getParent()->getParent()->getRegInfo();
+ const MachineRegisterInfo &MRI = MI->getMF()->getRegInfo();
if (TargetRegisterInfo::isPhysicalRegister(Dst)) {
// Eliminate DstSub on a physreg.
@@ -540,7 +568,7 @@ bool RegisterCoalescer::adjustCopiesBackFrom(const CoalescerPair &CP,
// in IntB, we can merge them.
if (ValS+1 != BS) return false;
- DEBUG(dbgs() << "Extending: " << PrintReg(IntB.reg, TRI));
+ DEBUG(dbgs() << "Extending: " << printReg(IntB.reg, TRI));
SlotIndex FillerStart = ValS->end, FillerEnd = BS->start;
// We are about to delete CopyMI, so need to remove it as the 'instruction
@@ -616,8 +644,7 @@ bool RegisterCoalescer::hasOtherReachingDefs(LiveInterval &IntA,
/// Copy segements with value number @p SrcValNo from liverange @p Src to live
/// range @Dst and use value number @p DstValNo there.
static void addSegmentsWithValNo(LiveRange &Dst, VNInfo *DstValNo,
- const LiveRange &Src, const VNInfo *SrcValNo)
-{
+ const LiveRange &Src, const VNInfo *SrcValNo) {
for (const LiveRange::Segment &S : Src.segments) {
if (S.valno != SrcValNo)
continue;
@@ -640,7 +667,7 @@ bool RegisterCoalescer::removeCopyByCommutingDef(const CoalescerPair &CP,
// its other operand is coalesced to the copy dest register, see if we can
// transform the copy into a noop by commuting the definition. For example,
//
- // A3 = op A2 B0<kill>
+ // A3 = op A2 killed B0
// ...
// B1 = A3 <- this copy
// ...
@@ -648,7 +675,7 @@ bool RegisterCoalescer::removeCopyByCommutingDef(const CoalescerPair &CP,
//
// ==>
//
- // B2 = op B0 A2<kill>
+ // B2 = op B0 killed A2
// ...
// B1 = B2 <- now an identity copy
// ...
@@ -741,7 +768,7 @@ bool RegisterCoalescer::removeCopyByCommutingDef(const CoalescerPair &CP,
// ...
// B = A
// ...
- // C = A<kill>
+ // C = killed A
// ...
// = B
@@ -797,9 +824,7 @@ bool RegisterCoalescer::removeCopyByCommutingDef(const CoalescerPair &CP,
S.MergeValueNumberInto(SubDVNI, SubBValNo);
}
- ErasedInstrs.insert(UseMI);
- LIS->RemoveMachineInstrFromMaps(*UseMI);
- UseMI->eraseFromParent();
+ deleteInstr(UseMI);
}
// Extend BValNo by merging in IntA live segments of AValNo. Val# definition
@@ -966,8 +991,8 @@ bool RegisterCoalescer::removePartialRedundancy(const CoalescerPair &CP,
// Now ok to move copy.
if (CopyLeftBB) {
- DEBUG(dbgs() << "\tremovePartialRedundancy: Move the copy to BB#"
- << CopyLeftBB->getNumber() << '\t' << CopyMI);
+ DEBUG(dbgs() << "\tremovePartialRedundancy: Move the copy to "
+ << printMBBReference(*CopyLeftBB) << '\t' << CopyMI);
// Insert new copy to CopyLeftBB.
auto InsPos = CopyLeftBB->getFirstTerminator();
@@ -985,18 +1010,16 @@ bool RegisterCoalescer::removePartialRedundancy(const CoalescerPair &CP,
// the deleted list.
ErasedInstrs.erase(NewCopyMI);
} else {
- DEBUG(dbgs() << "\tremovePartialRedundancy: Remove the copy from BB#"
- << MBB.getNumber() << '\t' << CopyMI);
+ DEBUG(dbgs() << "\tremovePartialRedundancy: Remove the copy from "
+ << printMBBReference(MBB) << '\t' << CopyMI);
}
// Remove CopyMI.
// Note: This is fine to remove the copy before updating the live-ranges.
// While updating the live-ranges, we only look at slot indices and
// never go back to the instruction.
- LIS->RemoveMachineInstrFromMaps(CopyMI);
// Mark instructions as deleted.
- ErasedInstrs.insert(&CopyMI);
- CopyMI.eraseFromParent();
+ deleteInstr(&CopyMI);
// Update the liveness.
SmallVector<SlotIndex, 8> EndPoints;
@@ -1119,10 +1142,10 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP,
NewMI.setDebugLoc(DL);
// In a situation like the following:
- // %vreg0:subreg = instr ; DefMI, subreg = DstIdx
- // %vreg1 = copy %vreg0:subreg ; CopyMI, SrcIdx = 0
- // instead of widening %vreg1 to the register class of %vreg0 simply do:
- // %vreg1 = instr
+ // %0:subreg = instr ; DefMI, subreg = DstIdx
+ // %1 = copy %0:subreg ; CopyMI, SrcIdx = 0
+ // instead of widening %1 to the register class of %0 simply do:
+ // %1 = instr
const TargetRegisterClass *NewRC = CP.getNewRC();
if (DstIdx != 0) {
MachineOperand &DefMO = NewMI.getOperand(0);
@@ -1202,12 +1225,12 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP,
// This could happen if the rematerialization instruction is rematerializing
// more than actually is used in the register.
// An example would be:
- // vreg1 = LOAD CONSTANTS 5, 8 ; Loading both 5 and 8 in different subregs
+ // %1 = LOAD CONSTANTS 5, 8 ; Loading both 5 and 8 in different subregs
// ; Copying only part of the register here, but the rest is undef.
- // vreg2:sub_16bit<def, read-undef> = COPY vreg1:sub_16bit
+ // %2:sub_16bit<def, read-undef> = COPY %1:sub_16bit
// ==>
// ; Materialize all the constants but only using one
- // vreg2 = LOAD_CONSTANTS 5, 8
+ // %2 = LOAD_CONSTANTS 5, 8
//
// at this point for the part that wasn't defined before we could have
// subranges missing the definition.
@@ -1230,11 +1253,11 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP,
// Make sure that the subrange for resultant undef is removed
// For example:
- // vreg1:sub1<def,read-undef> = LOAD CONSTANT 1
- // vreg2<def> = COPY vreg1
+ // %1:sub1<def,read-undef> = LOAD CONSTANT 1
+ // %2 = COPY %1
// ==>
- // vreg2:sub1<def, read-undef> = LOAD CONSTANT 1
- // ; Correct but need to remove the subrange for vreg2:sub0
+ // %2:sub1<def, read-undef> = LOAD CONSTANT 1
+ // ; Correct but need to remove the subrange for %2:sub0
// ; as it is now undef
if (NewIdx != 0 && DstInt.hasSubRanges()) {
// The affected subregister segments can be removed.
@@ -1268,15 +1291,15 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP,
// Otherwise, variables that live through may miss some
// interferences, thus creating invalid allocation.
// E.g., i386 code:
- // vreg1 = somedef ; vreg1 GR8
- // vreg2 = remat ; vreg2 GR32
- // CL = COPY vreg2.sub_8bit
- // = somedef vreg1 ; vreg1 GR8
+ // %1 = somedef ; %1 GR8
+ // %2 = remat ; %2 GR32
+ // CL = COPY %2.sub_8bit
+ // = somedef %1 ; %1 GR8
// =>
- // vreg1 = somedef ; vreg1 GR8
- // ECX<def, dead> = remat ; CL<imp-def>
- // = somedef vreg1 ; vreg1 GR8
- // vreg1 will see the inteferences with CL but not with CH since
+ // %1 = somedef ; %1 GR8
+ // dead ECX = remat ; implicit-def CL
+ // = somedef %1 ; %1 GR8
+ // %1 will see the inteferences with CL but not with CH since
// no live-ranges would have been created for ECX.
// Fix that!
SlotIndex NewMIIdx = LIS->getInstructionIndex(NewMI);
@@ -1313,6 +1336,9 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP,
MachineInstr *UseMI = UseMO.getParent();
if (UseMI->isDebugValue()) {
UseMO.setReg(DstReg);
+ // Move the debug value directly after the def of the rematerialized
+ // value in DstReg.
+ MBB->splice(std::next(NewMI.getIterator()), UseMI->getParent(), UseMI);
DEBUG(dbgs() << "\t\tupdated: " << *UseMI);
}
}
@@ -1326,9 +1352,9 @@ bool RegisterCoalescer::eliminateUndefCopy(MachineInstr *CopyMI) {
// ProcessImpicitDefs may leave some copies of <undef> values, it only removes
// local variables. When we have a copy like:
//
- // %vreg1 = COPY %vreg2<undef>
+ // %1 = COPY undef %2
//
- // We delete the copy and remove the corresponding value number from %vreg1.
+ // We delete the copy and remove the corresponding value number from %1.
// Any uses of that value number are marked as <undef>.
// Note that we do not query CoalescerPair here but redo isMoveInstr as the
@@ -1540,7 +1566,6 @@ bool RegisterCoalescer::canJoinPhys(const CoalescerPair &CP) {
}
bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) {
-
Again = false;
DEBUG(dbgs() << LIS->getInstructionIndex(*CopyMI) << '\t' << *CopyMI);
@@ -1560,7 +1585,7 @@ bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) {
std::swap(SrcRC, DstRC);
}
if (!TRI->shouldCoalesce(CopyMI, SrcRC, SrcIdx, DstRC, DstIdx,
- CP.getNewRC())) {
+ CP.getNewRC(), *LIS)) {
DEBUG(dbgs() << "\tSubtarget bailed on coalescing.\n");
return false;
}
@@ -1578,8 +1603,7 @@ bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) {
// Eliminate undefs.
if (!CP.isPhys() && eliminateUndefCopy(CopyMI)) {
- LIS->RemoveMachineInstrFromMaps(*CopyMI);
- CopyMI->eraseFromParent();
+ deleteInstr(CopyMI);
return false; // Not coalescable.
}
@@ -1607,15 +1631,14 @@ bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) {
}
DEBUG(dbgs() << "\tMerged values: " << LI << '\n');
}
- LIS->RemoveMachineInstrFromMaps(*CopyMI);
- CopyMI->eraseFromParent();
+ deleteInstr(CopyMI);
return true;
}
// Enforce policies.
if (CP.isPhys()) {
- DEBUG(dbgs() << "\tConsidering merging " << PrintReg(CP.getSrcReg(), TRI)
- << " with " << PrintReg(CP.getDstReg(), TRI, CP.getSrcIdx())
+ DEBUG(dbgs() << "\tConsidering merging " << printReg(CP.getSrcReg(), TRI)
+ << " with " << printReg(CP.getDstReg(), TRI, CP.getSrcIdx())
<< '\n');
if (!canJoinPhys(CP)) {
// Before giving up coalescing, if definition of source is defined by
@@ -1637,13 +1660,13 @@ bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) {
dbgs() << "\tConsidering merging to "
<< TRI->getRegClassName(CP.getNewRC()) << " with ";
if (CP.getDstIdx() && CP.getSrcIdx())
- dbgs() << PrintReg(CP.getDstReg()) << " in "
+ dbgs() << printReg(CP.getDstReg()) << " in "
<< TRI->getSubRegIndexName(CP.getDstIdx()) << " and "
- << PrintReg(CP.getSrcReg()) << " in "
+ << printReg(CP.getSrcReg()) << " in "
<< TRI->getSubRegIndexName(CP.getSrcIdx()) << '\n';
else
- dbgs() << PrintReg(CP.getSrcReg(), TRI) << " in "
- << PrintReg(CP.getDstReg(), TRI, CP.getSrcIdx()) << '\n';
+ dbgs() << printReg(CP.getSrcReg(), TRI) << " in "
+ << printReg(CP.getDstReg(), TRI, CP.getSrcIdx()) << '\n';
});
}
@@ -1668,8 +1691,7 @@ bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) {
if (!CP.isPartial() && !CP.isPhys()) {
if (adjustCopiesBackFrom(CP, CopyMI) ||
removeCopyByCommutingDef(CP, CopyMI)) {
- LIS->RemoveMachineInstrFromMaps(*CopyMI);
- CopyMI->eraseFromParent();
+ deleteInstr(CopyMI);
DEBUG(dbgs() << "\tTrivial!\n");
return true;
}
@@ -1735,11 +1757,11 @@ bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) {
TRI->updateRegAllocHint(CP.getSrcReg(), CP.getDstReg(), *MF);
DEBUG({
- dbgs() << "\tSuccess: " << PrintReg(CP.getSrcReg(), TRI, CP.getSrcIdx())
- << " -> " << PrintReg(CP.getDstReg(), TRI, CP.getDstIdx()) << '\n';
+ dbgs() << "\tSuccess: " << printReg(CP.getSrcReg(), TRI, CP.getSrcIdx())
+ << " -> " << printReg(CP.getDstReg(), TRI, CP.getDstIdx()) << '\n';
dbgs() << "\tResult = ";
if (CP.isPhys())
- dbgs() << PrintReg(CP.getDstReg(), TRI);
+ dbgs() << printReg(CP.getDstReg(), TRI);
else
dbgs() << LIS->getInterval(CP.getDstReg());
dbgs() << '\n';
@@ -1774,7 +1796,7 @@ bool RegisterCoalescer::joinReservedPhysReg(CoalescerPair &CP) {
return false;
}
if (RHS.overlaps(LIS->getRegUnit(*UI))) {
- DEBUG(dbgs() << "\t\tInterference: " << PrintRegUnit(*UI, TRI) << '\n');
+ DEBUG(dbgs() << "\t\tInterference: " << printRegUnit(*UI, TRI) << '\n');
return false;
}
}
@@ -1797,20 +1819,20 @@ bool RegisterCoalescer::joinReservedPhysReg(CoalescerPair &CP) {
MachineInstr *CopyMI;
if (CP.isFlipped()) {
// Physreg is copied into vreg
- // %vregY = COPY %X
- // ... //< no other def of %X here
- // use %vregY
+ // %y = COPY %physreg_x
+ // ... //< no other def of %x here
+ // use %y
// =>
// ...
- // use %X
+ // use %x
CopyMI = MRI->getVRegDef(SrcReg);
} else {
// VReg is copied into physreg:
- // %vregX = def
- // ... //< no other def or use of %Y here
- // %Y = COPY %vregX
+ // %y = def
+ // ... //< no other def or use of %y here
+ // %y = COPY %physreg_x
// =>
- // %Y = def
+ // %y = def
// ...
if (!MRI->hasOneNonDBGUse(SrcReg)) {
DEBUG(dbgs() << "\t\tMultiple vreg uses!\n");
@@ -1829,7 +1851,7 @@ bool RegisterCoalescer::joinReservedPhysReg(CoalescerPair &CP) {
if (!MRI->isConstantPhysReg(DstReg)) {
// We checked above that there are no interfering defs of the physical
- // register. However, for this case, where we intent to move up the def of
+ // register. However, for this case, where we intend to move up the def of
// the physical register, we also need to check for interfering uses.
SlotIndexes *Indexes = LIS->getSlotIndexes();
for (SlotIndex SI = Indexes->getNextNonNullIndex(DestRegIdx);
@@ -1844,7 +1866,7 @@ bool RegisterCoalescer::joinReservedPhysReg(CoalescerPair &CP) {
// We're going to remove the copy which defines a physical reserved
// register, so remove its valno, etc.
- DEBUG(dbgs() << "\t\tRemoving phys reg def of " << PrintReg(DstReg, TRI)
+ DEBUG(dbgs() << "\t\tRemoving phys reg def of " << printReg(DstReg, TRI)
<< " at " << CopyRegIdx << "\n");
LIS->removePhysRegDefAt(DstReg, CopyRegIdx);
@@ -1855,8 +1877,7 @@ bool RegisterCoalescer::joinReservedPhysReg(CoalescerPair &CP) {
}
}
- LIS->RemoveMachineInstrFromMaps(*CopyMI);
- CopyMI->eraseFromParent();
+ deleteInstr(CopyMI);
// We don't track kills for reserved registers.
MRI->clearKillFlags(CP.getSrcReg());
@@ -1906,7 +1927,7 @@ bool RegisterCoalescer::joinReservedPhysReg(CoalescerPair &CP) {
//
// %dst:ssub0<def,read-undef> = FOO
// %src = BAR
-// %dst:ssub1<def> = COPY %src
+// %dst:ssub1 = COPY %src
//
// The live range of %src overlaps the %dst value defined by FOO, but
// merging %src into %dst:ssub1 is only going to clobber the ssub1 lane
@@ -1921,14 +1942,15 @@ bool RegisterCoalescer::joinReservedPhysReg(CoalescerPair &CP) {
// is live, but never read. This can happen because we don't compute
// individual live ranges per lane.
//
-// %dst<def> = FOO
+// %dst = FOO
// %src = BAR
-// %dst:ssub1<def> = COPY %src
+// %dst:ssub1 = COPY %src
//
// This kind of interference is only resolved locally. If the clobbered
// lane value escapes the block, the join is aborted.
namespace {
+
/// Track information about values in a single virtual register about to be
/// joined. Objects of this class are always created in pairs - one for each
/// side of the CoalescerPair (or one for each lane of a side of the coalescer
@@ -1936,6 +1958,7 @@ namespace {
class JoinVals {
/// Live range we work on.
LiveRange &LR;
+
/// (Main) register we work on.
const unsigned Reg;
@@ -1943,6 +1966,7 @@ class JoinVals {
/// subregister SubIdx in the coalesced register. Either CP.DstIdx or
/// CP.SrcIdx.
const unsigned SubIdx;
+
/// The LaneMask that this liverange will occupy the coalesced register. May
/// be smaller than the lanemask produced by SubIdx when merging subranges.
const LaneBitmask LaneMask;
@@ -1950,6 +1974,7 @@ class JoinVals {
/// This is true when joining sub register ranges, false when joining main
/// ranges.
const bool SubRangeJoin;
+
/// Whether the current LiveInterval tracks subregister liveness.
const bool TrackSubRegLiveness;
@@ -1997,7 +2022,7 @@ class JoinVals {
/// joined register, so they can be compared directly between SrcReg and
/// DstReg.
struct Val {
- ConflictResolution Resolution;
+ ConflictResolution Resolution = CR_Keep;
/// Lanes written by this def, 0 for unanalyzed values.
LaneBitmask WriteLanes;
@@ -2007,10 +2032,10 @@ class JoinVals {
LaneBitmask ValidLanes;
/// Value in LI being redefined by this def.
- VNInfo *RedefVNI;
+ VNInfo *RedefVNI = nullptr;
/// Value in the other live range that overlaps this def, if any.
- VNInfo *OtherVNI;
+ VNInfo *OtherVNI = nullptr;
/// Is this value an IMPLICIT_DEF that can be erased?
///
@@ -2023,18 +2048,16 @@ class JoinVals {
/// ProcessImplicitDefs can very rarely create IMPLICIT_DEF values with
/// longer live ranges. Such IMPLICIT_DEF values should be treated like
/// normal values.
- bool ErasableImplicitDef;
+ bool ErasableImplicitDef = false;
/// True when the live range of this value will be pruned because of an
/// overlapping CR_Replace value in the other live range.
- bool Pruned;
+ bool Pruned = false;
/// True once Pruned above has been computed.
- bool PrunedComputed;
+ bool PrunedComputed = false;
- Val() : Resolution(CR_Keep), WriteLanes(), ValidLanes(),
- RedefVNI(nullptr), OtherVNI(nullptr), ErasableImplicitDef(false),
- Pruned(false), PrunedComputed(false) {}
+ Val() = default;
bool isAnalyzed() const { return WriteLanes.any(); }
};
@@ -2081,8 +2104,9 @@ class JoinVals {
/// entry to TaintedVals.
///
/// Returns false if the tainted lanes extend beyond the basic block.
- bool taintExtent(unsigned, LaneBitmask, JoinVals&,
- SmallVectorImpl<std::pair<SlotIndex, LaneBitmask> >&);
+ bool
+ taintExtent(unsigned ValNo, LaneBitmask TaintedLanes, JoinVals &Other,
+ SmallVectorImpl<std::pair<SlotIndex, LaneBitmask>> &TaintExtent);
/// Return true if MI uses any of the given Lanes from Reg.
/// This does not include partial redefinitions of Reg.
@@ -2104,8 +2128,7 @@ public:
: LR(LR), Reg(Reg), SubIdx(SubIdx), LaneMask(LaneMask),
SubRangeJoin(SubRangeJoin), TrackSubRegLiveness(TrackSubRegLiveness),
NewVNInfo(newVNInfo), CP(cp), LIS(lis), Indexes(LIS->getSlotIndexes()),
- TRI(TRI), Assignments(LR.getNumValNums(), -1), Vals(LR.getNumValNums())
- {}
+ TRI(TRI), Assignments(LR.getNumValNums(), -1), Vals(LR.getNumValNums()) {}
/// Analyze defs in LR and compute a value mapping in NewVNInfo.
/// Returns false if any conflicts were impossible to resolve.
@@ -2149,6 +2172,7 @@ public:
/// Get the value assignments suitable for passing to LiveInterval::join.
const int *getAssignments() const { return Assignments.data(); }
};
+
} // end anonymous namespace
LaneBitmask JoinVals::computeWriteLanes(const MachineInstr *DefMI, bool &Redef)
@@ -2239,7 +2263,7 @@ JoinVals::analyzeValue(unsigned ValNo, JoinVals &Other) {
const MachineInstr *DefMI = nullptr;
if (VNI->isPHIDef()) {
// Conservatively assume that all lanes in a PHI are valid.
- LaneBitmask Lanes = SubRangeJoin ? LaneBitmask(1)
+ LaneBitmask Lanes = SubRangeJoin ? LaneBitmask::getLane(0)
: TRI->getSubRegIndexLaneMask(SubIdx);
V.ValidLanes = V.WriteLanes = Lanes;
} else {
@@ -2247,7 +2271,7 @@ JoinVals::analyzeValue(unsigned ValNo, JoinVals &Other) {
assert(DefMI != nullptr);
if (SubRangeJoin) {
// We don't care about the lanes when joining subregister ranges.
- V.WriteLanes = V.ValidLanes = LaneBitmask(1);
+ V.WriteLanes = V.ValidLanes = LaneBitmask::getLane(0);
if (DefMI->isImplicitDef()) {
V.ValidLanes = LaneBitmask::getNone();
V.ErasableImplicitDef = true;
@@ -2263,7 +2287,7 @@ JoinVals::analyzeValue(unsigned ValNo, JoinVals &Other) {
//
// This adds ssub1 to the set of valid lanes in %src:
//
- // %src:ssub1<def> = FOO
+ // %src:ssub1 = FOO
//
// This leaves only ssub1 valid, making any other lanes undef:
//
@@ -2352,7 +2376,7 @@ JoinVals::analyzeValue(unsigned ValNo, JoinVals &Other) {
if (OtherV.ErasableImplicitDef && DefMI &&
DefMI->getParent() != Indexes->getMBBFromIndex(V.OtherVNI->def)) {
DEBUG(dbgs() << "IMPLICIT_DEF defined at " << V.OtherVNI->def
- << " extends into BB#" << DefMI->getParent()->getNumber()
+ << " extends into " << printMBBReference(*DefMI->getParent())
<< ", keeping it.\n");
OtherV.ErasableImplicitDef = false;
}
@@ -2401,9 +2425,9 @@ JoinVals::analyzeValue(unsigned ValNo, JoinVals &Other) {
//
// 1 %dst:ssub0 = FOO <-- OtherVNI
// 2 %src = BAR <-- VNI
- // 3 %dst:ssub1 = COPY %src<kill> <-- Eliminate this copy.
- // 4 BAZ %dst<kill>
- // 5 QUUX %src<kill>
+ // 3 %dst:ssub1 = COPY killed %src <-- Eliminate this copy.
+ // 4 BAZ killed %dst
+ // 5 QUUX killed %src
//
// Here OtherVNI will map to itself in [1;2), but to VNI in [2;5). CR_Replace
// handles this complex value mapping.
@@ -2413,7 +2437,7 @@ JoinVals::analyzeValue(unsigned ValNo, JoinVals &Other) {
// If the other live range is killed by DefMI and the live ranges are still
// overlapping, it must be because we're looking at an early clobber def:
//
- // %dst<def,early-clobber> = ASM %src<kill>
+ // %dst<def,early-clobber> = ASM killed %src
//
// In this case, it is illegal to merge the two live ranges since the early
// clobber def would clobber %src before it was read.
@@ -2463,9 +2487,9 @@ void JoinVals::computeAssignment(unsigned ValNo, JoinVals &Other) {
assert(V.OtherVNI && "OtherVNI not assigned, can't merge.");
assert(Other.Vals[V.OtherVNI->id].isAnalyzed() && "Missing recursion");
Assignments[ValNo] = Other.Assignments[V.OtherVNI->id];
- DEBUG(dbgs() << "\t\tmerge " << PrintReg(Reg) << ':' << ValNo << '@'
+ DEBUG(dbgs() << "\t\tmerge " << printReg(Reg) << ':' << ValNo << '@'
<< LR.getValNumInfo(ValNo)->def << " into "
- << PrintReg(Other.Reg) << ':' << V.OtherVNI->id << '@'
+ << printReg(Other.Reg) << ':' << V.OtherVNI->id << '@'
<< V.OtherVNI->def << " --> @"
<< NewVNInfo[Assignments[ValNo]]->def << '\n');
break;
@@ -2493,7 +2517,7 @@ bool JoinVals::mapValues(JoinVals &Other) {
for (unsigned i = 0, e = LR.getNumValNums(); i != e; ++i) {
computeAssignment(i, Other);
if (Vals[i].Resolution == CR_Impossible) {
- DEBUG(dbgs() << "\t\tinterference at " << PrintReg(Reg) << ':' << i
+ DEBUG(dbgs() << "\t\tinterference at " << printReg(Reg) << ':' << i
<< '@' << LR.getValNumInfo(i)->def << '\n');
return false;
}
@@ -2503,7 +2527,7 @@ bool JoinVals::mapValues(JoinVals &Other) {
bool JoinVals::
taintExtent(unsigned ValNo, LaneBitmask TaintedLanes, JoinVals &Other,
- SmallVectorImpl<std::pair<SlotIndex, LaneBitmask> > &TaintExtent) {
+ SmallVectorImpl<std::pair<SlotIndex, LaneBitmask>> &TaintExtent) {
VNInfo *VNI = LR.getValNumInfo(ValNo);
MachineBasicBlock *MBB = Indexes->getMBBFromIndex(VNI->def);
SlotIndex MBBEnd = Indexes->getMBBEndIdx(MBB);
@@ -2516,11 +2540,11 @@ taintExtent(unsigned ValNo, LaneBitmask TaintedLanes, JoinVals &Other,
// lanes escape the block.
SlotIndex End = OtherI->end;
if (End >= MBBEnd) {
- DEBUG(dbgs() << "\t\ttaints global " << PrintReg(Other.Reg) << ':'
+ DEBUG(dbgs() << "\t\ttaints global " << printReg(Other.Reg) << ':'
<< OtherI->valno->id << '@' << OtherI->start << '\n');
return false;
}
- DEBUG(dbgs() << "\t\ttaints local " << PrintReg(Other.Reg) << ':'
+ DEBUG(dbgs() << "\t\ttaints local " << printReg(Other.Reg) << ':'
<< OtherI->valno->id << '@' << OtherI->start
<< " to " << End << '\n');
// A dead def is not a problem.
@@ -2560,10 +2584,10 @@ bool JoinVals::usesLanes(const MachineInstr &MI, unsigned Reg, unsigned SubIdx,
bool JoinVals::resolveConflicts(JoinVals &Other) {
for (unsigned i = 0, e = LR.getNumValNums(); i != e; ++i) {
Val &V = Vals[i];
- assert (V.Resolution != CR_Impossible && "Unresolvable conflict");
+ assert(V.Resolution != CR_Impossible && "Unresolvable conflict");
if (V.Resolution != CR_Unresolved)
continue;
- DEBUG(dbgs() << "\t\tconflict at " << PrintReg(Reg) << ':' << i
+ DEBUG(dbgs() << "\t\tconflict at " << printReg(Reg) << ':' << i
<< '@' << LR.getValNumInfo(i)->def << '\n');
if (SubRangeJoin)
return false;
@@ -2598,7 +2622,7 @@ bool JoinVals::resolveConflicts(JoinVals &Other) {
Indexes->getInstructionFromIndex(TaintExtent.front().first);
assert(LastMI && "Range must end at a proper instruction");
unsigned TaintNum = 0;
- for (;;) {
+ while (true) {
assert(MI != MBB->end() && "Bad LastMI");
if (usesLanes(*MI, Other.Reg, Other.SubIdx, TaintedLanes)) {
DEBUG(dbgs() << "\t\ttainted lanes used by: " << *MI);
@@ -2658,13 +2682,13 @@ void JoinVals::pruneValues(JoinVals &Other,
if (!Def.isBlock()) {
if (changeInstrs) {
// Remove <def,read-undef> flags. This def is now a partial redef.
- // Also remove <def,dead> flags since the joined live range will
+ // Also remove dead flags since the joined live range will
// continue past this instruction.
for (MachineOperand &MO :
Indexes->getInstructionFromIndex(Def)->operands()) {
if (MO.isReg() && MO.isDef() && MO.getReg() == Reg) {
- if (MO.getSubReg() != 0)
- MO.setIsUndef(EraseImpDef);
+ if (MO.getSubReg() != 0 && MO.isUndef() && !EraseImpDef)
+ MO.setIsUndef(false);
MO.setIsDead(false);
}
}
@@ -2674,7 +2698,7 @@ void JoinVals::pruneValues(JoinVals &Other,
if (!EraseImpDef)
EndPoints.push_back(Def);
}
- DEBUG(dbgs() << "\t\tpruned " << PrintReg(Other.Reg) << " at " << Def
+ DEBUG(dbgs() << "\t\tpruned " << printReg(Other.Reg) << " at " << Def
<< ": " << Other.LR << '\n');
break;
}
@@ -2686,7 +2710,7 @@ void JoinVals::pruneValues(JoinVals &Other,
// computeAssignment(), the value that was originally copied could have
// been replaced.
LIS->pruneValue(LR, Def, &EndPoints);
- DEBUG(dbgs() << "\t\tpruned all of " << PrintReg(Reg) << " at "
+ DEBUG(dbgs() << "\t\tpruned all of " << printReg(Reg) << " at "
<< Def << ": " << LR << '\n');
}
break;
@@ -2994,7 +3018,7 @@ bool RegisterCoalescer::joinVirtRegs(CoalescerPair &CP) {
R.LaneMask = Mask;
}
}
- DEBUG(dbgs() << "\t\tLHST = " << PrintReg(CP.getDstReg())
+ DEBUG(dbgs() << "\t\tLHST = " << printReg(CP.getDstReg())
<< ' ' << LHS << '\n');
// Determine lanemasks of RHS in the coalesced register and merge subranges.
@@ -3068,6 +3092,7 @@ bool RegisterCoalescer::joinIntervals(CoalescerPair &CP) {
}
namespace {
+
/// Information concerning MBB coalescing priority.
struct MBBPriorityInfo {
MachineBasicBlock *MBB;
@@ -3077,7 +3102,8 @@ struct MBBPriorityInfo {
MBBPriorityInfo(MachineBasicBlock *mbb, unsigned depth, bool issplit)
: MBB(mbb), Depth(depth), IsSplit(issplit) {}
};
-}
+
+} // end anonymous namespace
/// C-style comparator that sorts first based on the loop depth of the basic
/// block (the unsigned), and then on the MBB number.
@@ -3194,7 +3220,7 @@ bool RegisterCoalescer::applyTerminalRule(const MachineInstr &Copy) const {
continue;
// Check that OtherReg interfere with DstReg.
if (LIS->getInterval(OtherReg).overlaps(DstLI)) {
- DEBUG(dbgs() << "Apply terminal rule for: " << PrintReg(DstReg) << '\n');
+ DEBUG(dbgs() << "Apply terminal rule for: " << printReg(DstReg) << '\n');
return true;
}
}
@@ -3281,7 +3307,7 @@ void RegisterCoalescer::joinAllIntervals() {
array_pod_sort(MBBs.begin(), MBBs.end(), compareMBBPriority);
// Coalesce intervals in MBB priority order.
- unsigned CurrDepth = UINT_MAX;
+ unsigned CurrDepth = std::numeric_limits<unsigned>::max();
for (unsigned i = 0, e = MBBs.size(); i != e; ++i) {
// Try coalescing the collected local copies for deeper loops.
if (JoinGlobalCopies && MBBs[i].Depth < CurrDepth) {
@@ -3308,7 +3334,6 @@ void RegisterCoalescer::releaseMemory() {
bool RegisterCoalescer::runOnMachineFunction(MachineFunction &fn) {
MF = &fn;
MRI = &fn.getRegInfo();
- TM = &fn.getTarget();
const TargetSubtargetInfo &STI = fn.getSubtarget();
TRI = STI.getRegisterInfo();
TII = STI.getInstrInfo();
@@ -3349,7 +3374,7 @@ bool RegisterCoalescer::runOnMachineFunction(MachineFunction &fn) {
if (MRI->reg_nodbg_empty(Reg))
continue;
if (MRI->recomputeRegClass(Reg)) {
- DEBUG(dbgs() << PrintReg(Reg) << " inflated to "
+ DEBUG(dbgs() << printReg(Reg) << " inflated to "
<< TRI->getRegClassName(MRI->getRegClass(Reg)) << '\n');
++NumInflated;