llvm.org GIT mirror llvm / cba2e06
Stub out RegAllocGreedy. This new register allocator is initially identical to RegAllocBasic, but it will receive all of the tricks that RegAllocBasic won't get. RegAllocGreedy will eventually replace linear scan. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@121234 91177308-0d34-0410-b5e6-96231b3b80d8 Jakob Stoklund Olesen 9 years ago
4 changed file(s) with 221 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
3535 (void) llvm::createFastRegisterAllocator();
3636 (void) llvm::createBasicRegisterAllocator();
3737 (void) llvm::createLinearScanRegisterAllocator();
38 (void) llvm::createGreedyRegisterAllocator();
3839 (void) llvm::createDefaultPBQPRegisterAllocator();
3940
4041 (void) llvm::createSimpleRegisterCoalescer();
102102 ///
103103 FunctionPass *createBasicRegisterAllocator();
104104
105 /// Greedy register allocation pass - This pass implements a global register
106 /// allocator for optimized builds.
107 ///
108 FunctionPass *createGreedyRegisterAllocator();
109
105110 /// LinearScanRegisterAllocation Pass - This pass implements the linear scan
106111 /// register allocation algorithm, a global register allocator.
107112 ///
6060 PseudoSourceValue.cpp
6161 RegAllocBasic.cpp
6262 RegAllocFast.cpp
63 RegAllocGreedy.cpp
6364 RegAllocLinearScan.cpp
6465 RegAllocPBQP.cpp
6566 RegisterCoalescer.cpp
0 //===-- RegAllocGreedy.cpp - greedy register allocator --------------------===//
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 // This file defines the RAGreedy function pass for register allocation in
10 // optimized builds.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #define DEBUG_TYPE "regalloc"
15 #include "LiveIntervalUnion.h"
16 #include "RegAllocBase.h"
17 #include "Spiller.h"
18 #include "VirtRegMap.h"
19 #include "VirtRegRewriter.h"
20 #include "llvm/ADT/OwningPtr.h"
21 #include "llvm/Analysis/AliasAnalysis.h"
22 #include "llvm/Function.h"
23 #include "llvm/PassAnalysisSupport.h"
24 #include "llvm/CodeGen/CalcSpillWeights.h"
25 #include "llvm/CodeGen/LiveIntervalAnalysis.h"
26 #include "llvm/CodeGen/LiveStackAnalysis.h"
27 #include "llvm/CodeGen/MachineFunctionPass.h"
28 #include "llvm/CodeGen/MachineInstr.h"
29 #include "llvm/CodeGen/MachineLoopInfo.h"
30 #include "llvm/CodeGen/MachineRegisterInfo.h"
31 #include "llvm/CodeGen/Passes.h"
32 #include "llvm/CodeGen/RegAllocRegistry.h"
33 #include "llvm/CodeGen/RegisterCoalescer.h"
34 #include "llvm/Target/TargetMachine.h"
35 #include "llvm/Target/TargetOptions.h"
36 #include "llvm/Target/TargetRegisterInfo.h"
37 #include "llvm/Support/Debug.h"
38 #include "llvm/Support/ErrorHandling.h"
39 #include "llvm/Support/raw_ostream.h"
40
41 using namespace llvm;
42
43 static RegisterRegAlloc greedyRegAlloc("greedy", "greedy register allocator",
44 createGreedyRegisterAllocator);
45
46 namespace {
47 class RAGreedy : public MachineFunctionPass, public RegAllocBase {
48 // context
49 MachineFunction *MF;
50 const TargetMachine *TM;
51 MachineRegisterInfo *MRI;
52
53 BitVector ReservedRegs;
54
55 // analyses
56 LiveStacks *LS;
57
58 // state
59 std::auto_ptr SpillerInstance;
60
61 public:
62 RAGreedy();
63
64 /// Return the pass name.
65 virtual const char* getPassName() const {
66 return "Basic Register Allocator";
67 }
68
69 /// RAGreedy analysis usage.
70 virtual void getAnalysisUsage(AnalysisUsage &AU) const;
71
72 virtual void releaseMemory();
73
74 virtual Spiller &spiller() { return *SpillerInstance; }
75
76 virtual unsigned selectOrSplit(LiveInterval &VirtReg,
77 SmallVectorImpl &SplitVRegs);
78
79 /// Perform register allocation.
80 virtual bool runOnMachineFunction(MachineFunction &mf);
81
82 static char ID;
83 };
84 } // end anonymous namespace
85
86 char RAGreedy::ID = 0;
87
88 FunctionPass* llvm::createGreedyRegisterAllocator() {
89 return new RAGreedy();
90 }
91
92 RAGreedy::RAGreedy(): MachineFunctionPass(ID) {
93 initializeLiveIntervalsPass(*PassRegistry::getPassRegistry());
94 initializeSlotIndexesPass(*PassRegistry::getPassRegistry());
95 initializeStrongPHIEliminationPass(*PassRegistry::getPassRegistry());
96 initializeRegisterCoalescerAnalysisGroup(*PassRegistry::getPassRegistry());
97 initializeCalculateSpillWeightsPass(*PassRegistry::getPassRegistry());
98 initializeLiveStacksPass(*PassRegistry::getPassRegistry());
99 initializeMachineDominatorTreePass(*PassRegistry::getPassRegistry());
100 initializeMachineLoopInfoPass(*PassRegistry::getPassRegistry());
101 initializeVirtRegMapPass(*PassRegistry::getPassRegistry());
102 }
103
104 void RAGreedy::getAnalysisUsage(AnalysisUsage &AU) const {
105 AU.setPreservesCFG();
106 AU.addRequired();
107 AU.addPreserved();
108 AU.addRequired();
109 AU.addPreserved();
110 if (StrongPHIElim)
111 AU.addRequiredID(StrongPHIEliminationID);
112 AU.addRequiredTransitive();
113 AU.addRequired();
114 AU.addRequired();
115 AU.addPreserved();
116 AU.addRequiredID(MachineDominatorsID);
117 AU.addPreservedID(MachineDominatorsID);
118 AU.addRequired();
119 AU.addPreserved();
120 AU.addRequired();
121 AU.addPreserved();
122 MachineFunctionPass::getAnalysisUsage(AU);
123 }
124
125 void RAGreedy::releaseMemory() {
126 SpillerInstance.reset(0);
127 RegAllocBase::releaseMemory();
128 }
129
130 unsigned RAGreedy::selectOrSplit(LiveInterval &VirtReg,
131 SmallVectorImpl &SplitVRegs) {
132 // Populate a list of physical register spill candidates.
133 SmallVector PhysRegSpillCands;
134
135 // Check for an available register in this class.
136 const TargetRegisterClass *TRC = MRI->getRegClass(VirtReg.reg);
137 DEBUG(dbgs() << "RegClass: " << TRC->getName() << ' ');
138
139 for (TargetRegisterClass::iterator I = TRC->allocation_order_begin(*MF),
140 E = TRC->allocation_order_end(*MF);
141 I != E; ++I) {
142
143 unsigned PhysReg = *I;
144 if (ReservedRegs.test(PhysReg)) continue;
145
146 // Check interference and as a side effect, intialize queries for this
147 // VirtReg and its aliases.
148 unsigned interfReg = checkPhysRegInterference(VirtReg, PhysReg);
149 if (interfReg == 0) {
150 // Found an available register.
151 return PhysReg;
152 }
153 LiveInterval *interferingVirtReg =
154 Queries[interfReg].firstInterference().liveUnionPos().value();
155
156 // The current VirtReg must either spillable, or one of its interferences
157 // must have less spill weight.
158 if (interferingVirtReg->weight < VirtReg.weight ) {
159 PhysRegSpillCands.push_back(PhysReg);
160 }
161 }
162 // Try to spill another interfering reg with less spill weight.
163 //
164 // FIXME: RAGreedy will sort this list by spill weight.
165 for (SmallVectorImpl::iterator PhysRegI = PhysRegSpillCands.begin(),
166 PhysRegE = PhysRegSpillCands.end(); PhysRegI != PhysRegE; ++PhysRegI) {
167
168 if (!spillInterferences(VirtReg, *PhysRegI, SplitVRegs)) continue;
169
170 assert(checkPhysRegInterference(VirtReg, *PhysRegI) == 0 &&
171 "Interference after spill.");
172 // Tell the caller to allocate to this newly freed physical register.
173 return *PhysRegI;
174 }
175 // No other spill candidates were found, so spill the current VirtReg.
176 DEBUG(dbgs() << "spilling: " << VirtReg << '\n');
177 SmallVector pendingSpills;
178
179 spiller().spill(&VirtReg, SplitVRegs, pendingSpills);
180
181 // The live virtual register requesting allocation was spilled, so tell
182 // the caller not to allocate anything during this round.
183 return 0;
184 }
185
186 bool RAGreedy::runOnMachineFunction(MachineFunction &mf) {
187 DEBUG(dbgs() << "********** GREEDY REGISTER ALLOCATION **********\n"
188 << "********** Function: "
189 << ((Value*)mf.getFunction())->getName() << '\n');
190
191 MF = &mf;
192 TM = &mf.getTarget();
193 MRI = &mf.getRegInfo();
194
195 const TargetRegisterInfo *TRI = TM->getRegisterInfo();
196 RegAllocBase::init(*TRI, getAnalysis(),
197 getAnalysis());
198
199 ReservedRegs = TRI->getReservedRegs(*MF);
200 SpillerInstance.reset(createSpiller(*this, *MF, *VRM));
201 allocatePhysRegs();
202 addMBBLiveIns(MF);
203
204 // Run rewriter
205 std::auto_ptr rewriter(createVirtRegRewriter());
206 rewriter->runOnMachineFunction(*MF, *VRM, LIS);
207
208 // The pass output is in VirtRegMap. Release all the transient data.
209 releaseMemory();
210
211 return true;
212 }
213