llvm.org GIT mirror llvm / f70e7cc
Moved the PBQP allocator class out of the header and back in to the cpp file to hide the gory details. Allocator instances can now be created by calling createPBQPRegisterAllocator. Tidied up use of CoalescerPair as per Jakob's suggestions. Made the new PBQPBuilder based construction process the default. The internal construction process remains in-place and available via -pbqp-builder=false for now. It will be removed shortly if the new process doesn't cause any regressions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@114626 91177308-0d34-0410-b5e6-96231b3b80d8 Lang Hames 9 years ago
4 changed file(s) with 197 addition(s) and 185 deletion(s). Raw diff Collapse all Expand all
3434
3535 (void) llvm::createFastRegisterAllocator();
3636 (void) llvm::createLinearScanRegisterAllocator();
37 (void) llvm::createPBQPRegisterAllocator();
37 (void) llvm::createDefaultPBQPRegisterAllocator();
3838
3939 (void) llvm::createSimpleRegisterCoalescer();
4040
102102 /// PBQPRegisterAllocation Pass - This pass implements the Partitioned Boolean
103103 /// Quadratic Prograaming (PBQP) based register allocator.
104104 ///
105 FunctionPass *createPBQPRegisterAllocator();
105 FunctionPass *createDefaultPBQPRegisterAllocator();
106106
107107 /// SimpleRegisterCoalescing Pass - Coalesce all copies possible. Can run
108108 /// independently of the register allocator.
159159 PBQP::PBQPNum benefit);
160160 };
161161
162 ///
163 /// PBQP based allocators solve the register allocation problem by mapping
164 /// register allocation problems to Partitioned Boolean Quadratic
165 /// Programming problems.
166 class RegAllocPBQP : public MachineFunctionPass {
167 public:
168
169 static char ID;
170
171 /// Construct a PBQP register allocator.
172 RegAllocPBQP(std::auto_ptr b) : MachineFunctionPass(ID), builder(b) {}
173
174 /// Return the pass name.
175 virtual const char* getPassName() const {
176 return "PBQP Register Allocator";
177 }
178
179 /// PBQP analysis usage.
180 virtual void getAnalysisUsage(AnalysisUsage &au) const;
181
182 /// Perform register allocation
183 virtual bool runOnMachineFunction(MachineFunction &MF);
184
185 private:
186
187 typedef std::map LI2NodeMap;
188 typedef std::vector Node2LIMap;
189 typedef std::vector AllowedSet;
190 typedef std::vector AllowedSetMap;
191 typedef std::pair RegPair;
192 typedef std::map CoalesceMap;
193 typedef std::vector NodeVector;
194 typedef std::set RegSet;
195
196
197 std::auto_ptr builder;
198
199 MachineFunction *mf;
200 const TargetMachine *tm;
201 const TargetRegisterInfo *tri;
202 const TargetInstrInfo *tii;
203 const MachineLoopInfo *loopInfo;
204 MachineRegisterInfo *mri;
205 RenderMachineFunction *rmf;
206
207 LiveIntervals *lis;
208 LiveStacks *lss;
209 VirtRegMap *vrm;
210
211 LI2NodeMap li2Node;
212 Node2LIMap node2LI;
213 AllowedSetMap allowedSets;
214 RegSet vregsToAlloc, emptyIntervalVRegs;
215 NodeVector problemNodes;
216
217
218 /// Builds a PBQP cost vector.
219 template
220 PBQP::Vector buildCostVector(unsigned vReg,
221 const RegContainer &allowed,
222 const CoalesceMap &cealesces,
223 PBQP::PBQPNum spillCost) const;
224
225 /// \brief Builds a PBQP interference matrix.
226 ///
227 /// @return Either a pointer to a non-zero PBQP matrix representing the
228 /// allocation option costs, or a null pointer for a zero matrix.
229 ///
230 /// Expects allowed sets for two interfering LiveIntervals. These allowed
231 /// sets should contain only allocable registers from the LiveInterval's
232 /// register class, with any interfering pre-colored registers removed.
233 template
234 PBQP::Matrix* buildInterferenceMatrix(const RegContainer &allowed1,
235 const RegContainer &allowed2) const;
236
237 ///
238 /// Expects allowed sets for two potentially coalescable LiveIntervals,
239 /// and an estimated benefit due to coalescing. The allowed sets should
240 /// contain only allocable registers from the LiveInterval's register
241 /// classes, with any interfering pre-colored registers removed.
242 template
243 PBQP::Matrix* buildCoalescingMatrix(const RegContainer &allowed1,
244 const RegContainer &allowed2,
245 PBQP::PBQPNum cBenefit) const;
246
247 /// \brief Finds coalescing opportunities and returns them as a map.
248 ///
249 /// Any entries in the map are guaranteed coalescable, even if their
250 /// corresponding live intervals overlap.
251 CoalesceMap findCoalesces();
252
253 /// \brief Finds the initial set of vreg intervals to allocate.
254 void findVRegIntervalsToAlloc();
255
256 /// \brief Constructs a PBQP problem representation of the register
257 /// allocation problem for this function.
258 ///
259 /// @return a PBQP solver object for the register allocation problem.
260 PBQP::Graph constructPBQPProblem();
261
262 /// \brief Adds a stack interval if the given live interval has been
263 /// spilled. Used to support stack slot coloring.
264 void addStackInterval(const LiveInterval *spilled,MachineRegisterInfo* mri);
265
266 /// \brief Given a solved PBQP problem maps this solution back to a register
267 /// assignment.
268 bool mapPBQPToRegAlloc(const PBQP::Solution &solution);
269
270 /// \brief Given a solved PBQP problem maps this solution back to a register
271 /// assignment.
272 bool mapPBQPToRegAlloc2(const PBQPRAProblem &problem,
273 const PBQP::Solution &solution);
274
275 /// \brief Postprocessing before final spilling. Sets basic block "live in"
276 /// variables.
277 void finalizeAlloc() const;
278
279 };
280
162 FunctionPass* createPBQPRegisterAllocator(std::auto_ptr builder);
281163 }
282164
283165 #endif /* LLVM_CODEGEN_REGALLOCPBQP_H */
5555 #include
5656 #include
5757
58 namespace llvm {
58 using namespace llvm;
5959
6060 static RegisterRegAlloc
6161 registerPBQPRepAlloc("pbqp", "PBQP register allocator",
62 llvm::createPBQPRegisterAllocator);
62 createDefaultPBQPRegisterAllocator);
6363
6464 static cl::opt
6565 pbqpCoalescing("pbqp-coalescing",
6868
6969 static cl::opt
7070 pbqpBuilder("pbqp-builder",
71 cl::desc("Use new builder system."),
72 cl::init(false), cl::Hidden);
71 cl::desc("Use new builder system."),
72 cl::init(true), cl::Hidden);
7373
7474
7575 static cl::opt
7676 pbqpPreSplitting("pbqp-pre-splitting",
77 cl::desc("Pre-splite before PBQP register allocation."),
77 cl::desc("Pre-split before PBQP register allocation."),
7878 cl::init(false), cl::Hidden);
7979
80 namespace {
81
82 ///
83 /// PBQP based allocators solve the register allocation problem by mapping
84 /// register allocation problems to Partitioned Boolean Quadratic
85 /// Programming problems.
86 class RegAllocPBQP : public MachineFunctionPass {
87 public:
88
89 static char ID;
90
91 /// Construct a PBQP register allocator.
92 RegAllocPBQP(std::auto_ptr b) : MachineFunctionPass(ID), builder(b) {}
93
94 /// Return the pass name.
95 virtual const char* getPassName() const {
96 return "PBQP Register Allocator";
97 }
98
99 /// PBQP analysis usage.
100 virtual void getAnalysisUsage(AnalysisUsage &au) const;
101
102 /// Perform register allocation
103 virtual bool runOnMachineFunction(MachineFunction &MF);
104
105 private:
106
107 typedef std::map LI2NodeMap;
108 typedef std::vector Node2LIMap;
109 typedef std::vector AllowedSet;
110 typedef std::vector AllowedSetMap;
111 typedef std::pair RegPair;
112 typedef std::map CoalesceMap;
113 typedef std::vector NodeVector;
114 typedef std::set RegSet;
115
116
117 std::auto_ptr builder;
118
119 MachineFunction *mf;
120 const TargetMachine *tm;
121 const TargetRegisterInfo *tri;
122 const TargetInstrInfo *tii;
123 const MachineLoopInfo *loopInfo;
124 MachineRegisterInfo *mri;
125 RenderMachineFunction *rmf;
126
127 LiveIntervals *lis;
128 LiveStacks *lss;
129 VirtRegMap *vrm;
130
131 LI2NodeMap li2Node;
132 Node2LIMap node2LI;
133 AllowedSetMap allowedSets;
134 RegSet vregsToAlloc, emptyIntervalVRegs;
135 NodeVector problemNodes;
136
137
138 /// Builds a PBQP cost vector.
139 template
140 PBQP::Vector buildCostVector(unsigned vReg,
141 const RegContainer &allowed,
142 const CoalesceMap &cealesces,
143 PBQP::PBQPNum spillCost) const;
144
145 /// \brief Builds a PBQP interference matrix.
146 ///
147 /// @return Either a pointer to a non-zero PBQP matrix representing the
148 /// allocation option costs, or a null pointer for a zero matrix.
149 ///
150 /// Expects allowed sets for two interfering LiveIntervals. These allowed
151 /// sets should contain only allocable registers from the LiveInterval's
152 /// register class, with any interfering pre-colored registers removed.
153 template
154 PBQP::Matrix* buildInterferenceMatrix(const RegContainer &allowed1,
155 const RegContainer &allowed2) const;
156
157 ///
158 /// Expects allowed sets for two potentially coalescable LiveIntervals,
159 /// and an estimated benefit due to coalescing. The allowed sets should
160 /// contain only allocable registers from the LiveInterval's register
161 /// classes, with any interfering pre-colored registers removed.
162 template
163 PBQP::Matrix* buildCoalescingMatrix(const RegContainer &allowed1,
164 const RegContainer &allowed2,
165 PBQP::PBQPNum cBenefit) const;
166
167 /// \brief Finds coalescing opportunities and returns them as a map.
168 ///
169 /// Any entries in the map are guaranteed coalescable, even if their
170 /// corresponding live intervals overlap.
171 CoalesceMap findCoalesces();
172
173 /// \brief Finds the initial set of vreg intervals to allocate.
174 void findVRegIntervalsToAlloc();
175
176 /// \brief Constructs a PBQP problem representation of the register
177 /// allocation problem for this function.
178 ///
179 /// Old Construction Process - this functionality has been subsumed
180 /// by PBQPBuilder. This function will only be hanging around for a little
181 /// while until the new system has been fully tested.
182 ///
183 /// @return a PBQP solver object for the register allocation problem.
184 PBQP::Graph constructPBQPProblemOld();
185
186 /// \brief Adds a stack interval if the given live interval has been
187 /// spilled. Used to support stack slot coloring.
188 void addStackInterval(const LiveInterval *spilled,MachineRegisterInfo* mri);
189
190 /// \brief Given a solved PBQP problem maps this solution back to a register
191 /// assignment.
192 ///
193 /// Old Construction Process - this functionality has been subsumed
194 /// by PBQPBuilder. This function will only be hanging around for a little
195 /// while until the new system has been fully tested.
196 ///
197 bool mapPBQPToRegAllocOld(const PBQP::Solution &solution);
198
199 /// \brief Given a solved PBQP problem maps this solution back to a register
200 /// assignment.
201 bool mapPBQPToRegAlloc(const PBQPRAProblem &problem,
202 const PBQP::Solution &solution);
203
204 /// \brief Postprocessing before final spilling. Sets basic block "live in"
205 /// variables.
206 void finalizeAlloc() const;
207
208 };
209
80210 char RegAllocPBQP::ID = 0;
211
212 } // End anonymous namespace.
81213
82214 unsigned PBQPRAProblem::getVRegForNode(PBQP::Graph::ConstNodeItr node) const {
83215 Node2VReg::const_iterator vregItr = node2VReg.find(node);
276408 miItr != miEnd; ++miItr) {
277409 const MachineInstr *mi = &*miItr;
278410
279 if (!mi->isCopy() && !mi->isSubregToReg())
280 continue; // Not coalescable.
281
282411 if (!cp.setRegisters(mi))
283412 continue; // Not coalescable.
284413
285414 if (cp.getSrcReg() == cp.getDstReg())
286415 continue; // Already coalesced.
287416
288 if (cp.isCoalescable(mi)) {
289
290 unsigned dst = cp.getDstReg(),
291 src = cp.getSrcReg();
292
293
294
295 PBQP::PBQPNum cBenefit =
296 std::pow(10.0f, (float)loopInfo->getLoopDepth(mbb));
297
298 if (cp.isPhys()) {
299 if (!lis->isAllocatable(dst))
300 continue;
301
302 const PBQPRAProblem::AllowedSet &allowed = p->getAllowedSet(src);
303 unsigned pregOpt = 0;
304 while (pregOpt < allowed.size() && allowed[pregOpt] != dst)
305 ++pregOpt;
306 if (pregOpt < allowed.size()) {
307 ++pregOpt; // +1 to account for spill option.
308 PBQP::Graph::NodeItr node = p->getNodeForVReg(src);
309 addPhysRegCoalesce(g.getNodeCosts(node), pregOpt, cBenefit);
417 unsigned dst = cp.getDstReg(),
418 src = cp.getSrcReg();
419
420 const float copyFactor = 0.5; // Cost of copy relative to load. Current
421 // value plucked randomly out of the air.
422
423 PBQP::PBQPNum cBenefit =
424 copyFactor * LiveIntervals::getSpillWeight(false, true,
425 loopInfo->getLoopDepth(mbb));
426
427 if (cp.isPhys()) {
428 if (!lis->isAllocatable(dst))
429 continue;
430
431 const PBQPRAProblem::AllowedSet &allowed = p->getAllowedSet(src);
432 unsigned pregOpt = 0;
433 while (pregOpt < allowed.size() && allowed[pregOpt] != dst)
434 ++pregOpt;
435 if (pregOpt < allowed.size()) {
436 ++pregOpt; // +1 to account for spill option.
437 PBQP::Graph::NodeItr node = p->getNodeForVReg(src);
438 addPhysRegCoalesce(g.getNodeCosts(node), pregOpt, cBenefit);
439 }
440 } else {
441 const PBQPRAProblem::AllowedSet *allowed1 = &p->getAllowedSet(dst);
442 const PBQPRAProblem::AllowedSet *allowed2 = &p->getAllowedSet(src);
443 PBQP::Graph::NodeItr node1 = p->getNodeForVReg(dst);
444 PBQP::Graph::NodeItr node2 = p->getNodeForVReg(src);
445 PBQP::Graph::EdgeItr edge = g.findEdge(node1, node2);
446 if (edge == g.edgesEnd()) {
447 edge = g.addEdge(node1, node2, PBQP::Matrix(allowed1->size() + 1,
448 allowed2->size() + 1,
449 0));
450 } else {
451 if (g.getEdgeNode1(edge) == node2) {
452 std::swap(node1, node2);
453 std::swap(allowed1, allowed2);
310454 }
311 } else {
312 const PBQPRAProblem::AllowedSet *allowed1 = &p->getAllowedSet(dst);
313 const PBQPRAProblem::AllowedSet *allowed2 = &p->getAllowedSet(src);
314 PBQP::Graph::NodeItr node1 = p->getNodeForVReg(dst);
315 PBQP::Graph::NodeItr node2 = p->getNodeForVReg(src);
316 PBQP::Graph::EdgeItr edge = g.findEdge(node1, node2);
317 if (edge == g.edgesEnd()) {
318 edge = g.addEdge(node1, node2, PBQP::Matrix(allowed1->size() + 1,
319 allowed2->size() + 1,
320 0));
321 } else {
322 if (g.getEdgeNode1(edge) == node2) {
323 std::swap(node1, node2);
324 std::swap(allowed1, allowed2);
325 }
326 }
455 }
327456
328 addVirtRegCoalesce(g.getEdgeCosts(edge), *allowed1, *allowed2,
329 cBenefit);
330 }
457 addVirtRegCoalesce(g.getEdgeCosts(edge), *allowed1, *allowed2,
458 cBenefit);
331459 }
332460 }
333461 }
334462
335463 return p;
336464 }
337
338465
339466 void PBQPBuilderWithCoalescing::addPhysRegCoalesce(PBQP::Vector &costVec,
340467 unsigned pregOption,
706833 }
707834 }
708835
709 PBQP::Graph RegAllocPBQP::constructPBQPProblem() {
836 PBQP::Graph RegAllocPBQP::constructPBQPProblemOld() {
710837
711838 typedef std::vector LIVector;
712839 typedef std::vector RegVector;
8921019 stackInterval.MergeRangesInAsValue(rhsInterval, vni);
8931020 }
8941021
895 bool RegAllocPBQP::mapPBQPToRegAlloc(const PBQP::Solution &solution) {
1022 bool RegAllocPBQP::mapPBQPToRegAllocOld(const PBQP::Solution &solution) {
8961023
8971024 // Set to true if we have any spills
8981025 bool anotherRoundNeeded = false;
9631090 return !anotherRoundNeeded;
9641091 }
9651092
966 bool RegAllocPBQP::mapPBQPToRegAlloc2(const PBQPRAProblem &problem,
967 const PBQP::Solution &solution) {
1093 bool RegAllocPBQP::mapPBQPToRegAlloc(const PBQPRAProblem &problem,
1094 const PBQP::Solution &solution) {
9681095 // Set to true if we have any spills
9691096 bool anotherRoundNeeded = false;
9701097
11311258 while (!pbqpAllocComplete) {
11321259 DEBUG(dbgs() << " PBQP Regalloc round " << round << ":\n");
11331260
1134 PBQP::Graph problem = constructPBQPProblem();
1261 PBQP::Graph problem = constructPBQPProblemOld();
11351262 PBQP::Solution solution =
11361263 PBQP::HeuristicSolver::solve(problem);
11371264
1138 pbqpAllocComplete = mapPBQPToRegAlloc(solution);
1265 pbqpAllocComplete = mapPBQPToRegAllocOld(solution);
11391266
11401267 ++round;
11411268 }
11491276 PBQP::HeuristicSolver::solve(
11501277 problem->getGraph());
11511278
1152 pbqpAllocComplete = mapPBQPToRegAlloc2(*problem, solution);
1279 pbqpAllocComplete = mapPBQPToRegAlloc(*problem, solution);
11531280
11541281 ++round;
11551282 }
11781305 return true;
11791306 }
11801307
1181 FunctionPass* createPBQPRegisterAllocator() {
1308 FunctionPass* llvm::createPBQPRegisterAllocator(
1309 std::auto_ptr builder) {
1310 return new RegAllocPBQP(builder);
1311 }
1312
1313 FunctionPass* llvm::createDefaultPBQPRegisterAllocator() {
11821314 if (pbqpCoalescing) {
1183 return new RegAllocPBQP(
1184 std::auto_ptr(new PBQPBuilderWithCoalescing()));
1315 return createPBQPRegisterAllocator(
1316 std::auto_ptr(new PBQPBuilderWithCoalescing()));
11851317 } // else
1186 return new RegAllocPBQP(
1187 std::auto_ptr(new PBQPBuilder()));
1188 }
1189
1318 return createPBQPRegisterAllocator(
1319 std::auto_ptr(new PBQPBuilder()));
11901320 }
11911321
11921322 #undef DEBUG_TYPE