llvm.org GIT mirror llvm / e2b201b
New Spiller interface and trivial implementation. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@72030 91177308-0d34-0410-b5e6-96231b3b80d8 Lang Hames 11 years ago
3 changed file(s) with 262 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
1313 #define DEBUG_TYPE "regalloc"
1414 #include "VirtRegMap.h"
1515 #include "VirtRegRewriter.h"
16 #include "Spiller.h"
1617 #include "llvm/Function.h"
1718 #include "llvm/CodeGen/LiveIntervalAnalysis.h"
1819 #include "llvm/CodeGen/LiveStackAnalysis.h"
5556 cl::desc("Pre-register allocation live interval splitting"),
5657 cl::init(false), cl::Hidden);
5758
59 static cl::opt
60 NewSpillFramework("new-spill-framework",
61 cl::desc("New spilling framework"),
62 cl::init(false), cl::Hidden);
63
5864 static RegisterRegAlloc
5965 linearscanRegAlloc("linearscan", "linear scan register allocator",
6066 createLinearScanRegisterAllocator);
125131 VirtRegMap* vrm_;
126132
127133 std::auto_ptr rewriter_;
134
135 std::auto_ptr spiller_;
128136
129137 public:
130138 virtual const char* getPassName() const {
419427
420428 vrm_ = &getAnalysis();
421429 if (!rewriter_.get()) rewriter_.reset(createVirtRegRewriter());
430
431 if (NewSpillFramework) {
432 spiller_.reset(createSpiller(mf_, li_, vrm_));
433 }
434 else {
435 spiller_.reset(0);
436 }
422437
423438 initIntervalSets();
424439
11071122 if (cur->weight != HUGE_VALF && cur->weight <= minWeight) {
11081123 DOUT << "\t\t\tspilling(c): " << *cur << '\n';
11091124 SmallVector spillIs;
1110 std::vector added =
1111 li_->addIntervalsForSpills(*cur, spillIs, loopInfo, *vrm_);
1125 std::vector added;
1126
1127 if (!NewSpillFramework) {
1128 added = li_->addIntervalsForSpills(*cur, spillIs, loopInfo, *vrm_);
1129 }
1130 else {
1131 added = spiller_->spill(cur);
1132 }
1133
11121134 std::sort(added.begin(), added.end(), LISorter());
11131135 addStackInterval(cur, ls_, li_, mri_, *vrm_);
11141136 if (added.empty())
0 //===-- llvm/CodeGen/Spiller.cpp - Spiller -------------------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #define DEBUG_TYPE "spiller"
10
11 #include "Spiller.h"
12 #include "VirtRegMap.h"
13 #include "llvm/CodeGen/LiveIntervalAnalysis.h"
14 #include "llvm/CodeGen/MachineFunction.h"
15 #include "llvm/CodeGen/MachineRegisterInfo.h"
16 #include "llvm/CodeGen/MachineFrameInfo.h"
17 #include "llvm/Target/TargetMachine.h"
18 #include "llvm/Target/TargetInstrInfo.h"
19 #include "llvm/Support/Debug.h"
20
21 #include
22 #include
23
24 using namespace llvm;
25
26 Spiller::~Spiller() {}
27
28 namespace {
29
30 class TrivialSpiller : public Spiller {
31 public:
32 TrivialSpiller(MachineFunction *mf, LiveIntervals *lis, VirtRegMap *vrm) :
33 mf(mf), lis(lis), vrm(vrm)
34 {
35 mfi = mf->getFrameInfo();
36 mri = &mf->getRegInfo();
37 tii = mf->getTarget().getInstrInfo();
38 }
39
40 std::vector spill(LiveInterval *li) {
41
42 DOUT << "Trivial spiller spilling " << *li << "\n";
43
44 assert(li->weight != HUGE_VALF &&
45 "Attempting to spill already spilled value.");
46
47 assert(!li->isStackSlot() &&
48 "Trying to spill a stack slot.");
49
50 std::vector added;
51
52 const TargetRegisterClass *trc = mri->getRegClass(li->reg);
53 /*unsigned ss = mfi->CreateStackObject(trc->getSize(),
54 trc->getAlignment());*/
55 unsigned ss = vrm->assignVirt2StackSlot(li->reg);
56
57 MachineRegisterInfo::reg_iterator regItr = mri->reg_begin(li->reg);
58
59 while (regItr != mri->reg_end()) {
60
61 MachineInstr *mi = &*regItr;
62
63 SmallVector indices;
64 bool hasUse = false;
65 bool hasDef = false;
66
67 for (unsigned i = 0; i != mi->getNumOperands(); ++i) {
68 MachineOperand &op = mi->getOperand(i);
69
70 if (!op.isReg() || op.getReg() != li->reg)
71 continue;
72
73 hasUse |= mi->getOperand(i).isUse();
74 hasDef |= mi->getOperand(i).isDef();
75
76 indices.push_back(i);
77 }
78
79 unsigned newVReg = mri->createVirtualRegister(trc);
80 LiveInterval *newLI = &lis->getOrCreateInterval(newVReg);
81 newLI->weight = HUGE_VALF;
82
83 vrm->grow();
84 vrm->assignVirt2StackSlot(newVReg, ss);
85
86 for (unsigned i = 0; i < indices.size(); ++i) {
87 mi->getOperand(indices[i]).setReg(newVReg);
88
89 if (mi->getOperand(indices[i]).isUse()) {
90 mi->getOperand(indices[i]).setIsKill(true);
91 }
92 }
93
94 if (hasUse) {
95 unsigned loadInstIdx = insertLoadFor(mi, ss, newVReg, trc);
96 unsigned start = lis->getDefIndex(loadInstIdx),
97 end = lis->getUseIndex(lis->getInstructionIndex(mi));
98
99 VNInfo *vni =
100 newLI->getNextValue(loadInstIdx, 0, lis->getVNInfoAllocator());
101 vni->kills.push_back(lis->getInstructionIndex(mi));
102 LiveRange lr(start, end, vni);
103
104 newLI->addRange(lr);
105 added.push_back(newLI);
106 }
107
108 if (hasDef) {
109 unsigned storeInstIdx = insertStoreFor(mi, ss, newVReg, trc);
110 unsigned start = lis->getDefIndex(lis->getInstructionIndex(mi)),
111 end = lis->getUseIndex(storeInstIdx);
112
113 VNInfo *vni =
114 newLI->getNextValue(storeInstIdx, 0, lis->getVNInfoAllocator());
115 vni->kills.push_back(storeInstIdx);
116 LiveRange lr(start, end, vni);
117
118 newLI->addRange(lr);
119 added.push_back(newLI);
120 }
121
122 regItr = mri->reg_begin(li->reg);
123 }
124
125
126 return added;
127 }
128
129
130 private:
131
132 MachineFunction *mf;
133 LiveIntervals *lis;
134 MachineFrameInfo *mfi;
135 MachineRegisterInfo *mri;
136 const TargetInstrInfo *tii;
137 VirtRegMap *vrm;
138
139
140
141 void makeRoomForInsertBefore(MachineInstr *mi) {
142 if (!lis->hasGapBeforeInstr(lis->getInstructionIndex(mi))) {
143 lis->computeNumbering();
144 }
145
146 assert(lis->hasGapBeforeInstr(lis->getInstructionIndex(mi)));
147 }
148
149 unsigned insertStoreFor(MachineInstr *mi, unsigned ss,
150 unsigned newVReg,
151 const TargetRegisterClass *trc) {
152 MachineBasicBlock::iterator nextInstItr(mi);
153 ++nextInstItr;
154
155 makeRoomForInsertBefore(&*nextInstItr);
156
157 unsigned miIdx = lis->getInstructionIndex(mi);
158
159 tii->storeRegToStackSlot(*mi->getParent(), nextInstItr, newVReg,
160 true, ss, trc);
161 MachineBasicBlock::iterator storeInstItr(mi);
162 ++storeInstItr;
163 MachineInstr *storeInst = &*storeInstItr;
164 unsigned storeInstIdx = miIdx + LiveIntervals::InstrSlots::NUM;
165
166 assert(lis->getInstructionFromIndex(storeInstIdx) == 0 &&
167 "Store inst index already in use.");
168
169 lis->InsertMachineInstrInMaps(storeInst, storeInstIdx);
170
171 return storeInstIdx;
172 }
173
174 unsigned insertLoadFor(MachineInstr *mi, unsigned ss,
175 unsigned newVReg,
176 const TargetRegisterClass *trc) {
177 MachineBasicBlock::iterator useInstItr(mi);
178
179 makeRoomForInsertBefore(mi);
180
181 unsigned miIdx = lis->getInstructionIndex(mi);
182
183 tii->loadRegFromStackSlot(*mi->getParent(), useInstItr, newVReg, ss, trc);
184 MachineBasicBlock::iterator loadInstItr(mi);
185 --loadInstItr;
186 MachineInstr *loadInst = &*loadInstItr;
187 unsigned loadInstIdx = miIdx - LiveIntervals::InstrSlots::NUM;
188
189 assert(lis->getInstructionFromIndex(loadInstIdx) == 0 &&
190 "Load inst index already in use.");
191
192 lis->InsertMachineInstrInMaps(loadInst, loadInstIdx);
193
194 return loadInstIdx;
195 }
196
197 };
198
199 }
200
201
202 llvm::Spiller* llvm::createSpiller(MachineFunction *mf, LiveIntervals *lis,
203 VirtRegMap *vrm) {
204 return new TrivialSpiller(mf, lis, vrm);
205 }
0 //===-- llvm/CodeGen/Spiller.h - Spiller -*- C++ -*------------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_CODEGEN_SPILLER_H
10 #define LLVM_CODEGEN_SPILLER_H
11
12 #include
13
14 namespace llvm {
15
16 /// Spiller interface.
17 ///
18 /// Implementations are utility classes which insert spill or remat code on
19 /// demand.
20 class Spiller {
21 public:
22 virtual ~Spiller() = 0;
23 virtual std::vector spill(class LiveInterval *li) = 0;
24 };
25
26 /// Create and return a spiller object, as specified on the command line.
27 Spiller* createSpiller(class MachineFunction *mf, class LiveIntervals *li,
28 class VirtRegMap *vrm);
29 }
30
31 #endif