Skip to content

Commit

Permalink
Don't skip splitSeparateComponents in eliminateDeadDefs for HoistSpil…
Browse files Browse the repository at this point in the history
…lHelper::hoistAllSpills.

Because HoistSpillHelper::hoistAllSpills is called in postOptimization, before the
patch we didn't want LiveRangeEdit::eliminateDeadDefs to call splitSeparateComponents
and generate unassigned new vregs. However, skipping splitSeparateComponents will make
verify-machineinstrs unhappy, so I remove the early return, and use
HoistSpillHelper::LRE_DidCloneVirtReg to assign physreg/stackslot for those new vregs.

In addition, some code reorganization to make class HoistSpillHelper privately inheriting
from LiveRangeEdit::Delegate possible. This is to be consistent with class RAGreedy and
class RegisterCoalescer.

Differential Revision: http://reviews.llvm.org/D19142



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@266489 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
wmi-11 committed Apr 15, 2016
1 parent a4f4792 commit 1f5a2c3
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 22 deletions.
5 changes: 1 addition & 4 deletions include/llvm/CodeGen/LiveRangeEdit.h
Original file line number Diff line number Diff line change
Expand Up @@ -241,11 +241,8 @@ class LiveRangeEdit : private MachineRegisterInfo::Delegate {
/// RegsBeingSpilled lists registers currently being spilled by the register
/// allocator. These registers should not be split into new intervals
/// as currently those new intervals are not guaranteed to spill.
/// NoSplit indicates this func is used after the iterations of selectOrSplit
/// where registers should not be split into new intervals.
void eliminateDeadDefs(SmallVectorImpl<MachineInstr *> &Dead,
ArrayRef<unsigned> RegsBeingSpilled = None,
bool NoSplit = false);
ArrayRef<unsigned> RegsBeingSpilled = None);

/// calculateRegClassAndHint - Recompute register class and hint for each new
/// register.
Expand Down
34 changes: 22 additions & 12 deletions lib/CodeGen/InlineSpiller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ static cl::opt<bool> DisableHoisting("disable-spill-hoist", cl::Hidden,
cl::desc("Disable inline spill hoisting"));

namespace {
class HoistSpillHelper {
class HoistSpillHelper : private LiveRangeEdit::Delegate {
MachineFunction &MF;
LiveIntervals &LIS;
LiveStacks &LSS;
AliasAnalysis *AA;
Expand Down Expand Up @@ -105,7 +106,7 @@ class HoistSpillHelper {
public:
HoistSpillHelper(MachineFunctionPass &pass, MachineFunction &mf,
VirtRegMap &vrm)
: LIS(pass.getAnalysis<LiveIntervals>()),
: MF(mf), LIS(pass.getAnalysis<LiveIntervals>()),
LSS(pass.getAnalysis<LiveStacks>()),
AA(&pass.getAnalysis<AAResultsWrapperPass>().getAAResults()),
MDT(pass.getAnalysis<MachineDominatorTree>()),
Expand All @@ -118,7 +119,8 @@ class HoistSpillHelper {
void addToMergeableSpills(MachineInstr *Spill, int StackSlot,
unsigned Original);
bool rmFromMergeableSpills(MachineInstr *Spill, int StackSlot);
void hoistAllSpills(LiveRangeEdit &Edit);
void hoistAllSpills();
void LRE_DidCloneVirtReg(unsigned, unsigned) override;
};

class InlineSpiller : public Spiller {
Expand Down Expand Up @@ -1040,13 +1042,7 @@ void InlineSpiller::spill(LiveRangeEdit &edit) {

/// Optimizations after all the reg selections and spills are done.
///
void InlineSpiller::postOptimization() {
SmallVector<unsigned, 4> NewVRegs;
LiveRangeEdit LRE(nullptr, NewVRegs, MF, LIS, &VRM, nullptr);
HSpiller.hoistAllSpills(LRE);
assert(NewVRegs.size() == 0 &&
"No new vregs should be generated in hoistAllSpills");
}
void InlineSpiller::postOptimization() { HSpiller.hoistAllSpills(); }

/// When a spill is inserted, add the spill to MergeableSpills map.
///
Expand Down Expand Up @@ -1360,7 +1356,10 @@ void HoistSpillHelper::runHoistSpills(
/// its subtree to that node. In this way, we can get benefit locally even if
/// hoisting all the equal spills to one cold place is impossible.
///
void HoistSpillHelper::hoistAllSpills(LiveRangeEdit &Edit) {
void HoistSpillHelper::hoistAllSpills() {
SmallVector<unsigned, 4> NewVRegs;
LiveRangeEdit Edit(nullptr, NewVRegs, MF, LIS, &VRM, this);

// Save the mapping between stackslot and its original reg.
DenseMap<int, unsigned> SlotToOrigReg;
for (unsigned i = 0, e = MRI.getNumVirtRegs(); i != e; ++i) {
Expand Down Expand Up @@ -1436,6 +1435,17 @@ void HoistSpillHelper::hoistAllSpills(LiveRangeEdit &Edit) {
RMEnt->RemoveOperand(i - 1);
}
}
Edit.eliminateDeadDefs(SpillsToRm, None, true);
Edit.eliminateDeadDefs(SpillsToRm, None);
}
}

/// For VirtReg clone, the \p New register should have the same physreg or
/// stackslot as the \p old register.
void HoistSpillHelper::LRE_DidCloneVirtReg(unsigned New, unsigned Old) {
if (VRM.hasPhys(Old))
VRM.assignVirt2Phys(New, VRM.getPhys(Old));
else if (VRM.getStackSlot(Old) != VirtRegMap::NO_STACK_SLOT)
VRM.assignVirt2StackSlot(New, VRM.getStackSlot(Old));
else
llvm_unreachable("VReg should be assigned either physreg or stackslot");
}
6 changes: 1 addition & 5 deletions lib/CodeGen/LiveRangeEdit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -356,8 +356,7 @@ void LiveRangeEdit::eliminateDeadDef(MachineInstr *MI, ToShrinkSet &ToShrink) {
}

void LiveRangeEdit::eliminateDeadDefs(SmallVectorImpl<MachineInstr *> &Dead,
ArrayRef<unsigned> RegsBeingSpilled,
bool NoSplit) {
ArrayRef<unsigned> RegsBeingSpilled) {
ToShrinkSet ToShrink;

for (;;) {
Expand All @@ -379,9 +378,6 @@ void LiveRangeEdit::eliminateDeadDefs(SmallVectorImpl<MachineInstr *> &Dead,
if (!LIS.shrinkToUses(LI, &Dead))
continue;

if (NoSplit)
continue;

// Don't create new intervals for a register being spilled.
// The new intervals would have to be spilled anyway so its not worth it.
// Also they currently aren't spilled so creating them and not spilling
Expand Down
2 changes: 1 addition & 1 deletion test/CodeGen/X86/interval-update-remat.ll
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: llc -verify-regalloc < %s
; RUN: llc -verify-regalloc -verify-machineinstrs < %s
; PR27275: When enabling remat for vreg defined by PHIs, make sure the update
; of the live range removes dead phi. Otherwise, we may end up with PHIs with
; incorrect operands and that will trigger assertions or verifier failures
Expand Down

0 comments on commit 1f5a2c3

Please sign in to comment.