//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "regalloc"
#include "RegisterCoalescer.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/Statistic.h"
#include <cmath>
using namespace llvm;
+#define DEBUG_TYPE "regalloc"
+
STATISTIC(numJoins , "Number of interval joins performed");
STATISTIC(numCrossRCs , "Number of cross class joins performed");
STATISTIC(numCommutes , "Number of instruction commuting performed");
void eliminateDeadDefs();
/// LiveRangeEdit callback.
- void LRE_WillEraseInstruction(MachineInstr *MI);
+ void LRE_WillEraseInstruction(MachineInstr *MI) override;
/// coalesceLocals - coalesce the LocalWorkList.
void coalesceLocals();
/// reMaterializeTrivialDef - If the source of a copy is defined by a
/// trivial computation, replace the copy by rematerialize the definition.
- bool reMaterializeTrivialDef(CoalescerPair &CP, MachineInstr *CopyMI);
+ bool reMaterializeTrivialDef(CoalescerPair &CP, MachineInstr *CopyMI,
+ bool &IsDefCopy);
/// canJoinPhys - Return true if a physreg copy should be joined.
bool canJoinPhys(const CoalescerPair &CP);
initializeRegisterCoalescerPass(*PassRegistry::getPassRegistry());
}
- virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
- virtual void releaseMemory();
+ void releaseMemory() override;
/// runOnMachineFunction - pass entry point
- virtual bool runOnMachineFunction(MachineFunction&);
+ bool runOnMachineFunction(MachineFunction&) override;
/// print - Implement the dump method.
- virtual void print(raw_ostream &O, const Module* = 0) const;
+ void print(raw_ostream &O, const Module* = nullptr) const override;
};
} /// end anonymous namespace
if (MBB->pred_size() != 1 || MBB->succ_size() != 1)
return false;
- for (MachineBasicBlock::const_iterator MII = MBB->begin(), E = MBB->end();
- MII != E; ++MII) {
- if (!MII->isCopyLike() && !MII->isUnconditionalBranch())
+ for (const auto &MI : *MBB) {
+ if (!MI.isCopyLike() && !MI.isUnconditionalBranch())
return false;
}
return true;
bool CoalescerPair::setRegisters(const MachineInstr *MI) {
SrcReg = DstReg = 0;
SrcIdx = DstIdx = 0;
- NewRC = 0;
+ NewRC = nullptr;
Flipped = CrossClass = false;
unsigned Src, Dst, SrcSub, DstSub;
if (SrcSub) {
Dst = TRI.getMatchingSuperReg(Dst, SrcSub, MRI.getRegClass(Src));
if (!Dst) return false;
- SrcSub = 0;
} else if (!MRI.getRegClass(Src)->contains(Dst)) {
return false;
}
}
void RegisterCoalescer::eliminateDeadDefs() {
- SmallVector<LiveInterval*, 8> NewRegs;
- LiveRangeEdit(0, NewRegs, *MF, *LIS, 0, this).eliminateDeadDefs(DeadDefs);
+ SmallVector<unsigned, 8> NewRegs;
+ LiveRangeEdit(nullptr, NewRegs, *MF, *LIS,
+ nullptr, this).eliminateDeadDefs(DeadDefs);
}
// Callback from eliminateDeadDefs().
LIS->getInterval(CP.isFlipped() ? CP.getSrcReg() : CP.getDstReg());
SlotIndex CopyIdx = LIS->getInstructionIndex(CopyMI).getRegSlot();
- // BValNo is a value number in B that is defined by a copy from A. 'B3' in
+ // BValNo is a value number in B that is defined by a copy from A. 'B1' in
// the example above.
- LiveInterval::iterator BLR = IntB.FindLiveRangeContaining(CopyIdx);
- if (BLR == IntB.end()) return false;
- VNInfo *BValNo = BLR->valno;
+ LiveInterval::iterator BS = IntB.FindSegmentContaining(CopyIdx);
+ if (BS == IntB.end()) return false;
+ VNInfo *BValNo = BS->valno;
// Get the location that B is defined at. Two options: either this value has
// an unknown definition point or it is defined at CopyIdx. If unknown, we
// AValNo is the value number in A that defines the copy, A3 in the example.
SlotIndex CopyUseIdx = CopyIdx.getRegSlot(true);
- LiveInterval::iterator ALR = IntA.FindLiveRangeContaining(CopyUseIdx);
- // The live range might not exist after fun with physreg coalescing.
- if (ALR == IntA.end()) return false;
- VNInfo *AValNo = ALR->valno;
+ LiveInterval::iterator AS = IntA.FindSegmentContaining(CopyUseIdx);
+ // The live segment might not exist after fun with physreg coalescing.
+ if (AS == IntA.end()) return false;
+ VNInfo *AValNo = AS->valno;
// If AValNo is defined as a copy from IntB, we can potentially process this.
// Get the instruction that defines this value number.
if (!CP.isCoalescable(ACopyMI) || !ACopyMI->isFullCopy())
return false;
- // Get the LiveRange in IntB that this value number starts with.
- LiveInterval::iterator ValLR =
- IntB.FindLiveRangeContaining(AValNo->def.getPrevSlot());
- if (ValLR == IntB.end())
+ // Get the Segment in IntB that this value number starts with.
+ LiveInterval::iterator ValS =
+ IntB.FindSegmentContaining(AValNo->def.getPrevSlot());
+ if (ValS == IntB.end())
return false;
- // Make sure that the end of the live range is inside the same block as
+ // Make sure that the end of the live segment is inside the same block as
// CopyMI.
- MachineInstr *ValLREndInst =
- LIS->getInstructionFromIndex(ValLR->end.getPrevSlot());
- if (!ValLREndInst || ValLREndInst->getParent() != CopyMI->getParent())
+ MachineInstr *ValSEndInst =
+ LIS->getInstructionFromIndex(ValS->end.getPrevSlot());
+ if (!ValSEndInst || ValSEndInst->getParent() != CopyMI->getParent())
return false;
- // Okay, we now know that ValLR ends in the same block that the CopyMI
- // live-range starts. If there are no intervening live ranges between them in
- // IntB, we can merge them.
- if (ValLR+1 != BLR) return false;
+ // Okay, we now know that ValS ends in the same block that the CopyMI
+ // live-range starts. If there are no intervening live segments between them
+ // in IntB, we can merge them.
+ if (ValS+1 != BS) return false;
DEBUG(dbgs() << "Extending: " << PrintReg(IntB.reg, TRI));
- SlotIndex FillerStart = ValLR->end, FillerEnd = BLR->start;
+ SlotIndex FillerStart = ValS->end, FillerEnd = BS->start;
// We are about to delete CopyMI, so need to remove it as the 'instruction
// that defines this value #'. Update the valnum with the new defining
// instruction #.
BValNo->def = FillerStart;
// Okay, we can merge them. We need to insert a new liverange:
- // [ValLR.end, BLR.begin) of either value number, then we merge the
+ // [ValS.end, BS.begin) of either value number, then we merge the
// two value numbers.
- IntB.addRange(LiveRange(FillerStart, FillerEnd, BValNo));
+ IntB.addSegment(LiveInterval::Segment(FillerStart, FillerEnd, BValNo));
// Okay, merge "B1" into the same value number as "B0".
- if (BValNo != ValLR->valno)
- IntB.MergeValueNumberInto(BValNo, ValLR->valno);
+ if (BValNo != ValS->valno)
+ IntB.MergeValueNumberInto(BValNo, ValS->valno);
DEBUG(dbgs() << " result = " << IntB << '\n');
// If the source instruction was killing the source register before the
// merge, unset the isKill marker given the live range has been extended.
- int UIdx = ValLREndInst->findRegisterUseOperandIdx(IntB.reg, true);
+ int UIdx = ValSEndInst->findRegisterUseOperandIdx(IntB.reg, true);
if (UIdx != -1) {
- ValLREndInst->getOperand(UIdx).setIsKill(false);
+ ValSEndInst->getOperand(UIdx).setIsKill(false);
}
// Rewrite the copy. If the copy instruction was killing the destination
// register before the merge, find the last use and trim the live range. That
// will also add the isKill marker.
CopyMI->substituteRegister(IntA.reg, IntB.reg, 0, *TRI);
- if (ALR->end == CopyIdx)
+ if (AS->end == CopyIdx)
LIS->shrinkToUses(&IntA);
++numExtends;
for (LiveInterval::iterator AI = IntA.begin(), AE = IntA.end();
AI != AE; ++AI) {
if (AI->valno != AValNo) continue;
- LiveInterval::Ranges::iterator BI =
- std::upper_bound(IntB.ranges.begin(), IntB.ranges.end(), AI->start);
- if (BI != IntB.ranges.begin())
+ LiveInterval::iterator BI =
+ std::upper_bound(IntB.begin(), IntB.end(), AI->start);
+ if (BI != IntB.begin())
--BI;
- for (; BI != IntB.ranges.end() && AI->end >= BI->start; ++BI) {
+ for (; BI != IntB.end() && AI->end >= BI->start; ++BI) {
if (BI->valno == BValNo)
continue;
if (BI->start <= AI->start && BI->end > AI->start)
LiveInterval &IntB =
LIS->getInterval(CP.isFlipped() ? CP.getSrcReg() : CP.getDstReg());
- // BValNo is a value number in B that is defined by a copy from A. 'B3' in
+ // BValNo is a value number in B that is defined by a copy from A. 'B1' in
// the example above.
VNInfo *BValNo = IntB.getVNInfoAt(CopyIdx);
if (!BValNo || BValNo->def != CopyIdx)
return false;
- assert(BValNo->def == CopyIdx && "Copy doesn't define the value?");
-
// AValNo is the value number in A that defines the copy, A3 in the example.
VNInfo *AValNo = IntA.getVNInfoAt(CopyIdx.getRegSlot(true));
assert(AValNo && "COPY source not live");
MachineOperand &NewDstMO = DefMI->getOperand(NewDstIdx);
unsigned NewReg = NewDstMO.getReg();
- if (NewReg != IntB.reg || !LiveRangeQuery(IntB, AValNo->def).isKill())
+ if (NewReg != IntB.reg || !IntB.Query(AValNo->def).isKill())
return false;
// Make sure there are no other definitions of IntB that would reach the
// If some of the uses of IntA.reg is already coalesced away, return false.
// It's not possible to determine whether it's safe to perform the coalescing.
- for (MachineRegisterInfo::use_nodbg_iterator UI =
- MRI->use_nodbg_begin(IntA.reg),
- UE = MRI->use_nodbg_end(); UI != UE; ++UI) {
- MachineInstr *UseMI = &*UI;
+ for (MachineOperand &MO : MRI->use_nodbg_operands(IntA.reg)) {
+ MachineInstr *UseMI = MO.getParent();
+ unsigned OpNo = &MO - &UseMI->getOperand(0);
SlotIndex UseIdx = LIS->getInstructionIndex(UseMI);
- LiveInterval::iterator ULR = IntA.FindLiveRangeContaining(UseIdx);
- if (ULR == IntA.end() || ULR->valno != AValNo)
+ LiveInterval::iterator US = IntA.FindSegmentContaining(UseIdx);
+ if (US == IntA.end() || US->valno != AValNo)
continue;
// If this use is tied to a def, we can't rewrite the register.
- if (UseMI->isRegTiedToDefOperand(UI.getOperandNo()))
+ if (UseMI->isRegTiedToDefOperand(OpNo))
return false;
}
// Update uses of IntA of the specific Val# with IntB.
for (MachineRegisterInfo::use_iterator UI = MRI->use_begin(IntA.reg),
UE = MRI->use_end(); UI != UE;) {
- MachineOperand &UseMO = UI.getOperand();
- MachineInstr *UseMI = &*UI;
+ MachineOperand &UseMO = *UI;
+ MachineInstr *UseMI = UseMO.getParent();
++UI;
if (UseMI->isDebugValue()) {
// FIXME These don't have an instruction index. Not clear we have enough
continue;
}
SlotIndex UseIdx = LIS->getInstructionIndex(UseMI).getRegSlot(true);
- LiveInterval::iterator ULR = IntA.FindLiveRangeContaining(UseIdx);
- if (ULR == IntA.end() || ULR->valno != AValNo)
+ LiveInterval::iterator US = IntA.FindSegmentContaining(UseIdx);
+ if (US == IntA.end() || US->valno != AValNo)
continue;
// Kill flags are no longer accurate. They are recomputed after RA.
UseMO.setIsKill(false);
UseMI->eraseFromParent();
}
- // Extend BValNo by merging in IntA live ranges of AValNo. Val# definition
+ // Extend BValNo by merging in IntA live segments of AValNo. Val# definition
// is updated.
VNInfo *ValNo = BValNo;
ValNo->def = AValNo->def;
for (LiveInterval::iterator AI = IntA.begin(), AE = IntA.end();
AI != AE; ++AI) {
if (AI->valno != AValNo) continue;
- IntB.addRange(LiveRange(AI->start, AI->end, ValNo));
+ IntB.addSegment(LiveInterval::Segment(AI->start, AI->end, ValNo));
}
DEBUG(dbgs() << "\t\textended: " << IntB << '\n');
/// reMaterializeTrivialDef - If the source of a copy is defined by a trivial
/// computation, replace the copy by rematerialize the definition.
bool RegisterCoalescer::reMaterializeTrivialDef(CoalescerPair &CP,
- MachineInstr *CopyMI) {
+ MachineInstr *CopyMI,
+ bool &IsDefCopy) {
+ IsDefCopy = false;
unsigned SrcReg = CP.isFlipped() ? CP.getDstReg() : CP.getSrcReg();
unsigned SrcIdx = CP.isFlipped() ? CP.getDstIdx() : CP.getSrcIdx();
unsigned DstReg = CP.isFlipped() ? CP.getSrcReg() : CP.getDstReg();
return false;
LiveInterval &SrcInt = LIS->getInterval(SrcReg);
- SlotIndex CopyIdx = LIS->getInstructionIndex(CopyMI).getRegSlot(true);
- LiveInterval::iterator SrcLR = SrcInt.FindLiveRangeContaining(CopyIdx);
- assert(SrcLR != SrcInt.end() && "Live range not found!");
- VNInfo *ValNo = SrcLR->valno;
+ SlotIndex CopyIdx = LIS->getInstructionIndex(CopyMI);
+ VNInfo *ValNo = SrcInt.Query(CopyIdx).valueIn();
+ assert(ValNo && "CopyMI input register not live");
if (ValNo->isPHIDef() || ValNo->isUnused())
return false;
MachineInstr *DefMI = LIS->getInstructionFromIndex(ValNo->def);
if (!DefMI)
return false;
- assert(DefMI && "Defining instruction disappeared");
- if (!DefMI->isAsCheapAsAMove())
+ if (DefMI->isCopyLike()) {
+ IsDefCopy = true;
+ return false;
+ }
+ if (!TII->isAsCheapAsAMove(DefMI))
return false;
if (!TII->isTriviallyReMaterializable(DefMI, AA))
return false;
if (DstOperand.getSubReg() && !DstOperand.isUndef())
return false;
+ // If both SrcIdx and DstIdx are set, correct rematerialization would widen
+ // the register substantially (beyond both source and dest size). This is bad
+ // for performance since it can cascade through a function, introducing many
+ // extra spills and fills (e.g. ARM can easily end up copying QQQQPR registers
+ // around after a few subreg copies).
+ if (SrcIdx && DstIdx)
+ return false;
+
const TargetRegisterClass *DefRC = TII->getRegClass(MCID, 0, TRI, *MF);
if (!DefMI->isImplicitDef()) {
if (TargetRegisterInfo::isPhysicalRegister(DstReg)) {
MachineBasicBlock *MBB = CopyMI->getParent();
MachineBasicBlock::iterator MII =
- llvm::next(MachineBasicBlock::iterator(CopyMI));
+ std::next(MachineBasicBlock::iterator(CopyMI));
TII->reMaterialize(*MBB, MII, DstReg, SrcIdx, DefMI, *TRI);
- MachineInstr *NewMI = prior(MII);
+ MachineInstr *NewMI = std::prev(MII);
LIS->ReplaceMachineInstrInMaps(CopyMI, NewMI);
CopyMI->eraseFromParent();
}
if (TargetRegisterInfo::isVirtualRegister(DstReg)) {
+ const TargetRegisterClass *NewRC = CP.getNewRC();
unsigned NewIdx = NewMI->getOperand(0).getSubReg();
- const TargetRegisterClass *RCForInst;
+
if (NewIdx)
- RCForInst = TRI->getMatchingSuperRegClass(MRI->getRegClass(DstReg), DefRC,
- NewIdx);
-
- if (MRI->constrainRegClass(DstReg, DefRC)) {
- // The materialized instruction is quite capable of setting DstReg
- // directly, but it may still have a now-trivial subregister index which
- // we should clear.
- NewMI->getOperand(0).setSubReg(0);
- } else if (NewIdx && RCForInst) {
- // The subreg index on NewMI is essential; we still have to make sure
- // DstReg:idx is in a class that NewMI can use.
- MRI->constrainRegClass(DstReg, RCForInst);
- } else {
- // DstReg is actually incompatible with NewMI, we have to move to a
- // super-reg's class. This could come from a sequence like:
- // GR32 = MOV32r0
- // GR8 = COPY GR32:sub_8
- MRI->setRegClass(DstReg, CP.getNewRC());
- updateRegDefsUses(DstReg, DstReg, DstIdx);
- NewMI->getOperand(0).setSubReg(
- TRI->composeSubRegIndices(SrcIdx, DefMI->getOperand(0).getSubReg()));
- }
+ NewRC = TRI->getMatchingSuperRegClass(NewRC, DefRC, NewIdx);
+ else
+ NewRC = TRI->getCommonSubClass(NewRC, DefRC);
+
+ assert(NewRC && "subreg chosen for remat incompatible with instruction");
+ MRI->setRegClass(DstReg, NewRC);
+
+ updateRegDefsUses(DstReg, DstReg, DstIdx);
+ NewMI->getOperand(0).setSubReg(NewIdx);
} else if (NewMI->getOperand(0).getReg() != CopyDstReg) {
// The New instruction may be defining a sub-register of what's actually
// been asked for. If so it must implicitly define the whole thing.
true /*IsDef*/,
true /*IsImp*/,
false /*IsKill*/));
+ // Record small dead def live-ranges for all the subregisters
+ // of the destination register.
+ // 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
+ // =>
+ // 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
+ // no live-ranges would have been created for ECX.
+ // Fix that!
+ SlotIndex NewMIIdx = LIS->getInstructionIndex(NewMI);
+ for (MCRegUnitIterator Units(NewMI->getOperand(0).getReg(), TRI);
+ Units.isValid(); ++Units)
+ if (LiveRange *LR = LIS->getCachedRegUnit(*Units))
+ LR->createDeadDef(NewMIIdx.getRegSlot(), LIS->getVNInfoAllocator());
}
if (NewMI->getOperand(0).getSubReg())
for (unsigned i = 0, e = NewMIImplDefs.size(); i != e; ++i) {
unsigned Reg = NewMIImplDefs[i];
for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units)
- if (LiveInterval *LI = LIS->getCachedRegUnit(*Units))
- LI->createDeadDef(NewMIIdx.getRegSlot(), LIS->getVNInfoAllocator());
+ if (LiveRange *LR = LIS->getCachedRegUnit(*Units))
+ LR->createDeadDef(NewMIIdx.getRegSlot(), LIS->getVNInfoAllocator());
}
DEBUG(dbgs() << "Remat: " << *NewMI);
// No intervals are live-in to CopyMI - it is undef.
if (CP.isFlipped())
DstInt = SrcInt;
- SrcInt = 0;
+ SrcInt = nullptr;
VNInfo *DeadVNI = DstInt->getVNInfoAt(Idx.getRegSlot());
assert(DeadVNI && "No value defined in DstInt");
DstInt->removeValNo(DeadVNI);
// Find new undef uses.
- for (MachineRegisterInfo::reg_nodbg_iterator
- I = MRI->reg_nodbg_begin(DstInt->reg), E = MRI->reg_nodbg_end();
- I != E; ++I) {
- MachineOperand &MO = I.getOperand();
+ for (MachineOperand &MO : MRI->reg_nodbg_operands(DstInt->reg)) {
if (MO.isDef() || MO.isUndef())
continue;
MachineInstr *MI = MO.getParent();
unsigned DstReg,
unsigned SubIdx) {
bool DstIsPhys = TargetRegisterInfo::isPhysicalRegister(DstReg);
- LiveInterval *DstInt = DstIsPhys ? 0 : &LIS->getInterval(DstReg);
+ LiveInterval *DstInt = DstIsPhys ? nullptr : &LIS->getInterval(DstReg);
SmallPtrSet<MachineInstr*, 8> Visited;
- for (MachineRegisterInfo::reg_iterator I = MRI->reg_begin(SrcReg);
- MachineInstr *UseMI = I.skipInstruction();) {
+ for (MachineRegisterInfo::reg_instr_iterator
+ I = MRI->reg_instr_begin(SrcReg), E = MRI->reg_instr_end();
+ I != E; ) {
+ MachineInstr *UseMI = &*(I++);
+
// Each instruction can only be rewritten once because sub-register
// composition is not always idempotent. When SrcReg != DstReg, rewriting
// the UseMI operands removes them from the SrcReg use-def chain, but when
SmallVector<unsigned,8> Ops;
bool Reads, Writes;
- tie(Reads, Writes) = UseMI->readsWritesVirtualRegister(SrcReg, &Ops);
+ std::tie(Reads, Writes) = UseMI->readsWritesVirtualRegister(SrcReg, &Ops);
// If SrcReg wasn't read, it may still be the case that DstReg is live-in
// because SrcReg is a sub-register.
return false;
}
+ if (CP.getNewRC()) {
+ auto SrcRC = MRI->getRegClass(CP.getSrcReg());
+ auto DstRC = MRI->getRegClass(CP.getDstReg());
+ unsigned SrcIdx = CP.getSrcIdx();
+ unsigned DstIdx = CP.getDstIdx();
+ if (CP.isFlipped()) {
+ std::swap(SrcIdx, DstIdx);
+ std::swap(SrcRC, DstRC);
+ }
+ if (!TRI->shouldCoalesce(CopyMI, SrcRC, SrcIdx, DstRC, DstIdx,
+ CP.getNewRC())) {
+ DEBUG(dbgs() << "\tSubtarget bailed on coalescing.\n");
+ return false;
+ }
+ }
+
// Dead code elimination. This really should be handled by MachineDCE, but
// sometimes dead copies slip through, and we can't generate invalid live
// ranges.
if (CP.getSrcReg() == CP.getDstReg()) {
LiveInterval &LI = LIS->getInterval(CP.getSrcReg());
DEBUG(dbgs() << "\tCopy already coalesced: " << LI << '\n');
- LiveRangeQuery LRQ(LI, LIS->getInstructionIndex(CopyMI));
+ LiveQueryResult LRQ = LI.Query(LIS->getInstructionIndex(CopyMI));
if (VNInfo *DefVNI = LRQ.valueDefined()) {
VNInfo *ReadVNI = LRQ.valueIn();
assert(ReadVNI && "No value before copy and no <undef> flag.");
if (!canJoinPhys(CP)) {
// Before giving up coalescing, if definition of source is defined by
// trivial computation, try rematerializing it.
- if (reMaterializeTrivialDef(CP, CopyMI))
+ bool IsDefCopy;
+ if (reMaterializeTrivialDef(CP, CopyMI, IsDefCopy))
return true;
+ if (IsDefCopy)
+ Again = true; // May be possible to coalesce later.
return false;
}
} else {
});
// When possible, let DstReg be the larger interval.
- if (!CP.isPartial() && LIS->getInterval(CP.getSrcReg()).ranges.size() >
- LIS->getInterval(CP.getDstReg()).ranges.size())
+ if (!CP.isPartial() && LIS->getInterval(CP.getSrcReg()).size() >
+ LIS->getInterval(CP.getDstReg()).size())
CP.flip();
}
// If definition of source is defined by trivial computation, try
// rematerializing it.
- if (reMaterializeTrivialDef(CP, CopyMI))
+ bool IsDefCopy;
+ if (reMaterializeTrivialDef(CP, CopyMI, IsDefCopy))
return true;
- // If we can eliminate the copy without merging the live ranges, do so now.
+ // If we can eliminate the copy without merging the live segments, do so
+ // now.
if (!CP.isPartial() && !CP.isPhys()) {
if (adjustCopiesBackFrom(CP, CopyMI) ||
removeCopyByCommutingDef(CP, CopyMI)) {
TRI->UpdateRegAllocHint(CP.getSrcReg(), CP.getDstReg(), *MF);
DEBUG({
- dbgs() << "\tJoined. Result = " << PrintReg(CP.getDstReg(), TRI);
- if (!CP.isPhys())
+ dbgs() << "\tJoined. Result = ";
+ if (CP.isPhys())
+ dbgs() << PrintReg(CP.getDstReg(), TRI);
+ else
dbgs() << LIS->getInterval(CP.getDstReg());
- dbgs() << '\n';
+ dbgs() << '\n';
});
++numJoins;
assert(CP.isPhys() && "Must be a physreg copy");
assert(MRI->isReserved(CP.getDstReg()) && "Not a reserved register");
LiveInterval &RHS = LIS->getInterval(CP.getSrcReg());
- DEBUG(dbgs() << "\t\tRHS = " << PrintReg(CP.getSrcReg()) << ' ' << RHS
- << '\n');
+ DEBUG(dbgs() << "\t\tRHS = " << RHS << '\n');
assert(CP.isFlipped() && RHS.containsOneValue() &&
"Invalid join with reserved register");
bool PrunedComputed;
Val() : Resolution(CR_Keep), WriteLanes(0), ValidLanes(0),
- RedefVNI(0), OtherVNI(0), ErasableImplicitDef(false),
+ RedefVNI(nullptr), OtherVNI(nullptr), ErasableImplicitDef(false),
Pruned(false), PrunedComputed(false) {}
bool isAnalyzed() const { return WriteLanes != 0; }
/// Add erased instructions to ErasedInstrs.
/// Add foreign virtual registers to ShrinkRegs if their live range ended at
/// the erased instrs.
- void eraseInstrs(SmallPtrSet<MachineInstr*, 8> &ErasedInstrs,
+ void eraseInstrs(SmallPtrSetImpl<MachineInstr*> &ErasedInstrs,
SmallVectorImpl<unsigned> &ShrinkRegs);
/// Get the value assignments suitable for passing to LiveInterval::join.
unsigned Reg = MI->getOperand(1).getReg();
if (!TargetRegisterInfo::isVirtualRegister(Reg))
break;
- LiveRangeQuery LRQ(LIS->getInterval(Reg), VNI->def);
+ LiveQueryResult LRQ = LIS->getInterval(Reg).Query(VNI->def);
if (!LRQ.valueIn())
break;
VNI = LRQ.valueIn();
}
// Get the instruction defining this value, compute the lanes written.
- const MachineInstr *DefMI = 0;
+ const MachineInstr *DefMI = nullptr;
if (VNI->isPHIDef()) {
// Conservatively assume that all lanes in a PHI are valid.
V.ValidLanes = V.WriteLanes = TRI->getSubRegIndexLaneMask(SubIdx);
// The <read-undef> flag on the def operand means that old lane values are
// not important.
if (Redef) {
- V.RedefVNI = LiveRangeQuery(LI, VNI->def).valueIn();
+ V.RedefVNI = LI.Query(VNI->def).valueIn();
assert(V.RedefVNI && "Instruction is reading nonexistent value");
computeAssignment(V.RedefVNI->id, Other);
V.ValidLanes |= Vals[V.RedefVNI->id].ValidLanes;
}
// Find the value in Other that overlaps VNI->def, if any.
- LiveRangeQuery OtherLRQ(Other.LI, VNI->def);
+ LiveQueryResult OtherLRQ = Other.LI.Query(VNI->def);
// It is possible that both values are defined by the same instruction, or
// the values are PHIs defined in the same block. When that happens, the two
}
}
-void JoinVals::eraseInstrs(SmallPtrSet<MachineInstr*, 8> &ErasedInstrs,
+void JoinVals::eraseInstrs(SmallPtrSetImpl<MachineInstr*> &ErasedInstrs,
SmallVectorImpl<unsigned> &ShrinkRegs) {
for (unsigned i = 0, e = LI.getNumValNums(); i != e; ++i) {
// Get the def location before markUnused() below invalidates it.
JoinVals RHSVals(RHS, CP.getSrcIdx(), NewVNInfo, CP, LIS, TRI);
JoinVals LHSVals(LHS, CP.getDstIdx(), NewVNInfo, CP, LIS, TRI);
- DEBUG(dbgs() << "\t\tRHS = " << PrintReg(CP.getSrcReg()) << ' ' << RHS
- << "\n\t\tLHS = " << PrintReg(CP.getDstReg()) << ' ' << LHS
+ DEBUG(dbgs() << "\t\tRHS = " << RHS
+ << "\n\t\tLHS = " << LHS
<< '\n');
// First compute NewVNInfo and the simple value mappings.
LIS->shrinkToUses(&LIS->getInterval(ShrinkRegs.pop_back_val()));
// Join RHS into LHS.
- LHS.join(RHS, LHSVals.getAssignments(), RHSVals.getAssignments(), NewVNInfo,
- MRI);
+ LHS.join(RHS, LHSVals.getAssignments(), RHSVals.getAssignments(), NewVNInfo);
// Kill flags are going to be wrong if the live ranges were overlapping.
// Eventually, we should simply clear all kill flags when computing live
// CR_Replace conflicts.
DEBUG(dbgs() << "\t\trestoring liveness to " << EndPoints.size()
<< " points: " << LHS << '\n');
- LIS->extendToIndices(&LHS, EndPoints);
+ LIS->extendToIndices(LHS, EndPoints);
return true;
}
// block (the unsigned), and then on the MBB number.
//
// EnableGlobalCopies assumes that the primary sort key is loop depth.
-static int compareMBBPriority(const void *L, const void *R) {
- const MBBPriorityInfo *LHS = static_cast<const MBBPriorityInfo*>(L);
- const MBBPriorityInfo *RHS = static_cast<const MBBPriorityInfo*>(R);
+static int compareMBBPriority(const MBBPriorityInfo *LHS,
+ const MBBPriorityInfo *RHS) {
// Deeper loops first
if (LHS->Depth != RHS->Depth)
return LHS->Depth > RHS->Depth ? -1 : 1;
if (!Copy->isCopy())
return false;
+ if (Copy->getOperand(1).isUndef())
+ return false;
+
unsigned SrcReg = Copy->getOperand(1).getReg();
unsigned DstReg = Copy->getOperand(0).getReg();
if (TargetRegisterInfo::isPhysicalRegister(SrcReg)
// Skip instruction pointers that have already been erased, for example by
// dead code elimination.
if (ErasedInstrs.erase(CurrList[i])) {
- CurrList[i] = 0;
+ CurrList[i] = nullptr;
continue;
}
bool Again = false;
bool Success = joinCopy(CurrList[i], Again);
Progress |= Success;
if (Success || !Again)
- CurrList[i] = 0;
+ CurrList[i] = nullptr;
}
return Progress;
}
// are not inherently easier to resolve, but slightly preferable until we
// have local live range splitting. In particular this is required by
// cmp+jmp macro fusion.
- for (MachineBasicBlock::reverse_iterator
- MII = MBB->rbegin(), E = MBB->rend(); MII != E; ++MII) {
+ for (MachineBasicBlock::iterator MII = MBB->begin(), E = MBB->end();
+ MII != E; ++MII) {
if (!MII->isCopyLike())
continue;
if (isLocalCopy(&(*MII), LIS))
CurrList(WorkList.begin() + PrevSize, WorkList.end());
if (copyCoalesceWorkList(CurrList))
WorkList.erase(std::remove(WorkList.begin() + PrevSize, WorkList.end(),
- (MachineInstr*)0), WorkList.end());
+ (MachineInstr*)nullptr), WorkList.end());
}
void RegisterCoalescer::coalesceLocals() {
MF = &fn;
MRI = &fn.getRegInfo();
TM = &fn.getTarget();
- TRI = TM->getRegisterInfo();
- TII = TM->getInstrInfo();
+ TRI = TM->getSubtargetImpl()->getRegisterInfo();
+ TII = TM->getSubtargetImpl()->getInstrInfo();
LIS = &getAnalysis<LiveIntervals>();
AA = &getAnalysis<AliasAnalysis>();
Loops = &getAnalysis<MachineLoopInfo>();
const TargetSubtargetInfo &ST = TM->getSubtarget<TargetSubtargetInfo>();
if (EnableGlobalCopies == cl::BOU_UNSET)
- JoinGlobalCopies = ST.enableMachineScheduler();
+ JoinGlobalCopies = ST.useMachineScheduler();
else
JoinGlobalCopies = (EnableGlobalCopies == cl::BOU_TRUE);