Skip to content

Commit 72911e4

Browse files
committed
Create a new LiveRangeEdit class to keep track of the new registers created when
splitting or spillling, and to help with rematerialization. Use LiveRangeEdit in InlineSpiller and SplitKit. This will eventually make it possible to share remat code between InlineSpiller and SplitKit. llvm-svn: 116543
1 parent 36f3b36 commit 72911e4

File tree

6 files changed

+206
-125
lines changed

6 files changed

+206
-125
lines changed

llvm/lib/CodeGen/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ add_llvm_library(LLVMCodeGen
2323
LiveIntervalAnalysis.cpp
2424
LiveStackAnalysis.cpp
2525
LiveVariables.cpp
26+
LiveRangeEdit.cpp
2627
LocalStackSlotAllocation.cpp
2728
LowerSubregs.cpp
2829
MachineBasicBlock.cpp

llvm/lib/CodeGen/InlineSpiller.cpp

Lines changed: 45 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#define DEBUG_TYPE "spiller"
1616
#include "Spiller.h"
17+
#include "LiveRangeEdit.h"
1718
#include "SplitKit.h"
1819
#include "VirtRegMap.h"
1920
#include "llvm/CodeGen/LiveIntervalAnalysis.h"
@@ -44,11 +45,9 @@ class InlineSpiller : public Spiller {
4445
SplitAnalysis splitAnalysis_;
4546

4647
// Variables that are valid during spill(), but used by multiple methods.
47-
LiveInterval *li_;
48-
SmallVectorImpl<LiveInterval*> *newIntervals_;
48+
LiveRangeEdit *edit_;
4949
const TargetRegisterClass *rc_;
5050
int stackSlot_;
51-
const SmallVectorImpl<LiveInterval*> *spillIs_;
5251

5352
// Values of the current interval that can potentially remat.
5453
SmallPtrSet<VNInfo*, 8> reMattable_;
@@ -78,11 +77,11 @@ class InlineSpiller : public Spiller {
7877
SmallVectorImpl<LiveInterval*> &newIntervals,
7978
SmallVectorImpl<LiveInterval*> &spillIs);
8079

80+
void spill(LiveRangeEdit &);
81+
8182
private:
8283
bool split();
8384

84-
bool allUsesAvailableAt(const MachineInstr *OrigMI, SlotIndex OrigIdx,
85-
SlotIndex UseIdx);
8685
bool reMaterializeFor(MachineBasicBlock::iterator MI);
8786
void reMaterializeAll();
8887

@@ -105,75 +104,43 @@ Spiller *createInlineSpiller(MachineFunctionPass &pass,
105104
/// split - try splitting the current interval into pieces that may allocate
106105
/// separately. Return true if successful.
107106
bool InlineSpiller::split() {
108-
splitAnalysis_.analyze(li_);
107+
splitAnalysis_.analyze(&edit_->getParent());
109108

110109
// Try splitting around loops.
111110
if (const MachineLoop *loop = splitAnalysis_.getBestSplitLoop()) {
112-
SplitEditor(splitAnalysis_, lis_, vrm_, *newIntervals_)
111+
SplitEditor(splitAnalysis_, lis_, vrm_, *edit_)
113112
.splitAroundLoop(loop);
114113
return true;
115114
}
116115

117116
// Try splitting into single block intervals.
118117
SplitAnalysis::BlockPtrSet blocks;
119118
if (splitAnalysis_.getMultiUseBlocks(blocks)) {
120-
SplitEditor(splitAnalysis_, lis_, vrm_, *newIntervals_)
119+
SplitEditor(splitAnalysis_, lis_, vrm_, *edit_)
121120
.splitSingleBlocks(blocks);
122121
return true;
123122
}
124123

125124
// Try splitting inside a basic block.
126125
if (const MachineBasicBlock *MBB = splitAnalysis_.getBlockForInsideSplit()) {
127-
SplitEditor(splitAnalysis_, lis_, vrm_, *newIntervals_)
126+
SplitEditor(splitAnalysis_, lis_, vrm_, *edit_)
128127
.splitInsideBlock(MBB);
129128
return true;
130129
}
131130

132131
return false;
133132
}
134133

135-
/// allUsesAvailableAt - Return true if all registers used by OrigMI at
136-
/// OrigIdx are also available with the same value at UseIdx.
137-
bool InlineSpiller::allUsesAvailableAt(const MachineInstr *OrigMI,
138-
SlotIndex OrigIdx,
139-
SlotIndex UseIdx) {
140-
OrigIdx = OrigIdx.getUseIndex();
141-
UseIdx = UseIdx.getUseIndex();
142-
for (unsigned i = 0, e = OrigMI->getNumOperands(); i != e; ++i) {
143-
const MachineOperand &MO = OrigMI->getOperand(i);
144-
if (!MO.isReg() || !MO.getReg() || MO.getReg() == li_->reg)
145-
continue;
146-
// Reserved registers are OK.
147-
if (MO.isUndef() || !lis_.hasInterval(MO.getReg()))
148-
continue;
149-
// We don't want to move any defs.
150-
if (MO.isDef())
151-
return false;
152-
// We cannot depend on virtual registers in spillIs_. They will be spilled.
153-
for (unsigned si = 0, se = spillIs_->size(); si != se; ++si)
154-
if ((*spillIs_)[si]->reg == MO.getReg())
155-
return false;
156-
157-
LiveInterval &LI = lis_.getInterval(MO.getReg());
158-
const VNInfo *OVNI = LI.getVNInfoAt(OrigIdx);
159-
if (!OVNI)
160-
continue;
161-
if (OVNI != LI.getVNInfoAt(UseIdx))
162-
return false;
163-
}
164-
return true;
165-
}
166-
167-
/// reMaterializeFor - Attempt to rematerialize li_->reg before MI instead of
134+
/// reMaterializeFor - Attempt to rematerialize edit_->getReg() before MI instead of
168135
/// reloading it.
169136
bool InlineSpiller::reMaterializeFor(MachineBasicBlock::iterator MI) {
170137
SlotIndex UseIdx = lis_.getInstructionIndex(MI).getUseIndex();
171-
VNInfo *OrigVNI = li_->getVNInfoAt(UseIdx);
138+
VNInfo *OrigVNI = edit_->getParent().getVNInfoAt(UseIdx);
172139
if (!OrigVNI) {
173140
DEBUG(dbgs() << "\tadding <undef> flags: ");
174141
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
175142
MachineOperand &MO = MI->getOperand(i);
176-
if (MO.isReg() && MO.isUse() && MO.getReg() == li_->reg)
143+
if (MO.isReg() && MO.isUse() && MO.getReg() == edit_->getReg())
177144
MO.setIsUndef();
178145
}
179146
DEBUG(dbgs() << UseIdx << '\t' << *MI);
@@ -185,17 +152,17 @@ bool InlineSpiller::reMaterializeFor(MachineBasicBlock::iterator MI) {
185152
return false;
186153
}
187154
MachineInstr *OrigMI = lis_.getInstructionFromIndex(OrigVNI->def);
188-
if (!allUsesAvailableAt(OrigMI, OrigVNI->def, UseIdx)) {
155+
if (!edit_->allUsesAvailableAt(OrigMI, OrigVNI->def, UseIdx, lis_)) {
189156
usedValues_.insert(OrigVNI);
190157
DEBUG(dbgs() << "\tcannot remat for " << UseIdx << '\t' << *MI);
191158
return false;
192159
}
193160

194-
// If the instruction also writes li_->reg, it had better not require the same
161+
// If the instruction also writes edit_->getReg(), it had better not require the same
195162
// register for uses and defs.
196163
bool Reads, Writes;
197164
SmallVector<unsigned, 8> Ops;
198-
tie(Reads, Writes) = MI->readsWritesVirtualRegister(li_->reg, &Ops);
165+
tie(Reads, Writes) = MI->readsWritesVirtualRegister(edit_->getReg(), &Ops);
199166
if (Writes) {
200167
for (unsigned i = 0, e = Ops.size(); i != e; ++i) {
201168
MachineOperand &MO = MI->getOperand(Ops[i]);
@@ -208,11 +175,8 @@ bool InlineSpiller::reMaterializeFor(MachineBasicBlock::iterator MI) {
208175
}
209176

210177
// Alocate a new register for the remat.
211-
unsigned NewVReg = mri_.createVirtualRegister(rc_);
212-
vrm_.grow();
213-
LiveInterval &NewLI = lis_.getOrCreateInterval(NewVReg);
178+
LiveInterval &NewLI = edit_->create(mri_, lis_, vrm_);
214179
NewLI.markNotSpillable();
215-
newIntervals_->push_back(&NewLI);
216180

217181
// Finally we can rematerialize OrigMI before MI.
218182
MachineBasicBlock &MBB = *MI->getParent();
@@ -224,8 +188,8 @@ bool InlineSpiller::reMaterializeFor(MachineBasicBlock::iterator MI) {
224188
// Replace operands
225189
for (unsigned i = 0, e = Ops.size(); i != e; ++i) {
226190
MachineOperand &MO = MI->getOperand(Ops[i]);
227-
if (MO.isReg() && MO.isUse() && MO.getReg() == li_->reg) {
228-
MO.setReg(NewVReg);
191+
if (MO.isReg() && MO.isUse() && MO.getReg() == edit_->getReg()) {
192+
MO.setReg(NewLI.reg);
229193
MO.setIsKill();
230194
}
231195
}
@@ -237,14 +201,14 @@ bool InlineSpiller::reMaterializeFor(MachineBasicBlock::iterator MI) {
237201
return true;
238202
}
239203

240-
/// reMaterializeAll - Try to rematerialize as many uses of li_ as possible,
204+
/// reMaterializeAll - Try to rematerialize as many uses as possible,
241205
/// and trim the live ranges after.
242206
void InlineSpiller::reMaterializeAll() {
243207
// Do a quick scan of the interval values to find if any are remattable.
244208
reMattable_.clear();
245209
usedValues_.clear();
246-
for (LiveInterval::const_vni_iterator I = li_->vni_begin(),
247-
E = li_->vni_end(); I != E; ++I) {
210+
for (LiveInterval::const_vni_iterator I = edit_->getParent().vni_begin(),
211+
E = edit_->getParent().vni_end(); I != E; ++I) {
248212
VNInfo *VNI = *I;
249213
if (VNI->isUnused())
250214
continue;
@@ -258,10 +222,10 @@ void InlineSpiller::reMaterializeAll() {
258222
if (reMattable_.empty())
259223
return;
260224

261-
// Try to remat before all uses of li_->reg.
225+
// Try to remat before all uses of edit_->getReg().
262226
bool anyRemat = false;
263227
for (MachineRegisterInfo::use_nodbg_iterator
264-
RI = mri_.use_nodbg_begin(li_->reg);
228+
RI = mri_.use_nodbg_begin(edit_->getReg());
265229
MachineInstr *MI = RI.skipInstruction();)
266230
anyRemat |= reMaterializeFor(MI);
267231

@@ -287,16 +251,17 @@ void InlineSpiller::reMaterializeAll() {
287251
if (!anyRemoved)
288252
return;
289253

290-
// Removing values may cause debug uses where li_ is not live.
291-
for (MachineRegisterInfo::use_iterator RI = mri_.use_begin(li_->reg);
254+
// Removing values may cause debug uses where parent is not live.
255+
for (MachineRegisterInfo::use_iterator RI = mri_.use_begin(edit_->getReg());
292256
MachineInstr *MI = RI.skipInstruction();) {
293257
if (!MI->isDebugValue())
294258
continue;
295-
// Try to preserve the debug value if li_ is live immediately after it.
259+
// Try to preserve the debug value if parent is live immediately after it.
296260
MachineBasicBlock::iterator NextMI = MI;
297261
++NextMI;
298262
if (NextMI != MI->getParent()->end() && !lis_.isNotInMIMap(NextMI)) {
299-
VNInfo *VNI = li_->getVNInfoAt(lis_.getInstructionIndex(NextMI));
263+
SlotIndex Idx = lis_.getInstructionIndex(NextMI);
264+
VNInfo *VNI = edit_->getParent().getVNInfoAt(Idx);
300265
if (VNI && (VNI->hasPHIKill() || usedValues_.count(VNI)))
301266
continue;
302267
}
@@ -314,7 +279,7 @@ bool InlineSpiller::coalesceStackAccess(MachineInstr *MI) {
314279
return false;
315280

316281
// We have a stack access. Is it the right register and slot?
317-
if (reg != li_->reg || FI != stackSlot_)
282+
if (reg != edit_->getReg() || FI != stackSlot_)
318283
return false;
319284

320285
DEBUG(dbgs() << "Coalescing stack access: " << *MI);
@@ -385,30 +350,33 @@ void InlineSpiller::insertSpill(LiveInterval &NewLI,
385350
void InlineSpiller::spill(LiveInterval *li,
386351
SmallVectorImpl<LiveInterval*> &newIntervals,
387352
SmallVectorImpl<LiveInterval*> &spillIs) {
388-
DEBUG(dbgs() << "Inline spilling " << *li << "\n");
389-
assert(li->isSpillable() && "Attempting to spill already spilled value.");
390-
assert(!li->isStackSlot() && "Trying to spill a stack slot.");
353+
LiveRangeEdit edit(*li, newIntervals, spillIs);
354+
spill(edit);
355+
}
391356

392-
li_ = li;
393-
newIntervals_ = &newIntervals;
394-
rc_ = mri_.getRegClass(li->reg);
395-
spillIs_ = &spillIs;
357+
void InlineSpiller::spill(LiveRangeEdit &edit) {
358+
edit_ = &edit;
359+
DEBUG(dbgs() << "Inline spilling " << edit.getParent() << "\n");
360+
assert(edit.getParent().isSpillable() &&
361+
"Attempting to spill already spilled value.");
362+
assert(!edit.getParent().isStackSlot() && "Trying to spill a stack slot.");
396363

397364
if (split())
398365
return;
399366

400367
reMaterializeAll();
401368

402369
// Remat may handle everything.
403-
if (li_->empty())
370+
if (edit_->getParent().empty())
404371
return;
405372

406-
stackSlot_ = vrm_.getStackSlot(li->reg);
373+
rc_ = mri_.getRegClass(edit.getReg());
374+
stackSlot_ = vrm_.getStackSlot(edit.getReg());
407375
if (stackSlot_ == VirtRegMap::NO_STACK_SLOT)
408-
stackSlot_ = vrm_.assignVirt2StackSlot(li->reg);
376+
stackSlot_ = vrm_.assignVirt2StackSlot(edit.getReg());
409377

410378
// Iterate over instructions using register.
411-
for (MachineRegisterInfo::reg_iterator RI = mri_.reg_begin(li->reg);
379+
for (MachineRegisterInfo::reg_iterator RI = mri_.reg_begin(edit.getReg());
412380
MachineInstr *MI = RI.skipInstruction();) {
413381

414382
// Debug values are not allowed to affect codegen.
@@ -436,17 +404,15 @@ void InlineSpiller::spill(LiveInterval *li,
436404
// Analyze instruction.
437405
bool Reads, Writes;
438406
SmallVector<unsigned, 8> Ops;
439-
tie(Reads, Writes) = MI->readsWritesVirtualRegister(li->reg, &Ops);
407+
tie(Reads, Writes) = MI->readsWritesVirtualRegister(edit.getReg(), &Ops);
440408

441409
// Attempt to fold memory ops.
442410
if (foldMemoryOperand(MI, Ops))
443411
continue;
444412

445413
// Allocate interval around instruction.
446414
// FIXME: Infer regclass from instruction alone.
447-
unsigned NewVReg = mri_.createVirtualRegister(rc_);
448-
vrm_.grow();
449-
LiveInterval &NewLI = lis_.getOrCreateInterval(NewVReg);
415+
LiveInterval &NewLI = edit.create(mri_, lis_, vrm_);
450416
NewLI.markNotSpillable();
451417

452418
if (Reads)
@@ -456,7 +422,7 @@ void InlineSpiller::spill(LiveInterval *li,
456422
bool hasLiveDef = false;
457423
for (unsigned i = 0, e = Ops.size(); i != e; ++i) {
458424
MachineOperand &MO = MI->getOperand(Ops[i]);
459-
MO.setReg(NewVReg);
425+
MO.setReg(NewLI.reg);
460426
if (MO.isUse()) {
461427
if (!MI->isRegTiedToDefOperand(Ops[i]))
462428
MO.setIsKill();
@@ -471,6 +437,5 @@ void InlineSpiller::spill(LiveInterval *li,
471437
insertSpill(NewLI, MI);
472438

473439
DEBUG(dbgs() << "\tinterval: " << NewLI << '\n');
474-
newIntervals.push_back(&NewLI);
475440
}
476441
}

llvm/lib/CodeGen/LiveRangeEdit.cpp

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
//===--- LiveRangeEdit.cpp - Basic tools for editing a register live range --===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
//
10+
// The LiveRangeEdit class represents changes done to a virtual register when it
11+
// is spilled or split.
12+
//===----------------------------------------------------------------------===//
13+
14+
#include "LiveRangeEdit.h"
15+
#include "VirtRegMap.h"
16+
#include "llvm/CodeGen/LiveIntervalAnalysis.h"
17+
#include "llvm/CodeGen/MachineRegisterInfo.h"
18+
19+
using namespace llvm;
20+
21+
LiveInterval &LiveRangeEdit::create(MachineRegisterInfo &mri,
22+
LiveIntervals &lis,
23+
VirtRegMap &vrm) {
24+
const TargetRegisterClass *RC = mri.getRegClass(parent_.reg);
25+
unsigned VReg = mri.createVirtualRegister(RC);
26+
vrm.grow();
27+
LiveInterval &li = lis.getOrCreateInterval(VReg);
28+
newRegs_.push_back(&li);
29+
return li;
30+
}
31+
32+
/// allUsesAvailableAt - Return true if all registers used by OrigMI at
33+
/// OrigIdx are also available with the same value at UseIdx.
34+
bool LiveRangeEdit::allUsesAvailableAt(const MachineInstr *OrigMI,
35+
SlotIndex OrigIdx,
36+
SlotIndex UseIdx,
37+
LiveIntervals &lis) {
38+
OrigIdx = OrigIdx.getUseIndex();
39+
UseIdx = UseIdx.getUseIndex();
40+
for (unsigned i = 0, e = OrigMI->getNumOperands(); i != e; ++i) {
41+
const MachineOperand &MO = OrigMI->getOperand(i);
42+
if (!MO.isReg() || !MO.getReg() || MO.getReg() == getReg())
43+
continue;
44+
// Reserved registers are OK.
45+
if (MO.isUndef() || !lis.hasInterval(MO.getReg()))
46+
continue;
47+
// We don't want to move any defs.
48+
if (MO.isDef())
49+
return false;
50+
// We cannot depend on virtual registers in uselessRegs_.
51+
for (unsigned ui = 0, ue = uselessRegs_.size(); ui != ue; ++ui)
52+
if (uselessRegs_[ui]->reg == MO.getReg())
53+
return false;
54+
55+
LiveInterval &li = lis.getInterval(MO.getReg());
56+
const VNInfo *OVNI = li.getVNInfoAt(OrigIdx);
57+
if (!OVNI)
58+
continue;
59+
if (OVNI != li.getVNInfoAt(UseIdx))
60+
return false;
61+
}
62+
return true;
63+
}
64+

0 commit comments

Comments
 (0)