RegAllocPBQP.cpp revision 5b220213bfe9c37c2bb41a7ae0804e06a14f1007
1b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng//===------ RegAllocPBQP.cpp ---- PBQP Register Allocator -------*- C++ -*-===//
2b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng//
3b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng//                     The LLVM Compiler Infrastructure
4b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng//
5b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng// This file is distributed under the University of Illinois Open Source
6b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng// License. See LICENSE.TXT for details.
7b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng//
8b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng//===----------------------------------------------------------------------===//
92a835f947a114142071456d7586118a0949499a0Misha Brukman//
10b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng// This file contains a Partitioned Boolean Quadratic Programming (PBQP) based
11b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng// register allocator for LLVM. This allocator works by constructing a PBQP
12b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng// problem representing the register allocation problem under consideration,
13b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng// solving this using a PBQP solver, and mapping the solution back to a
14b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng// register assignment. If any variables are selected for spilling then spill
152a835f947a114142071456d7586118a0949499a0Misha Brukman// code is inserted and the process repeated.
16b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng//
17b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng// The PBQP solver (pbqp.c) provided for this allocator uses a heuristic tuned
18b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng// for register allocation. For more information on PBQP for register
19ce07e99dd6fafc51805c21d53286ae5765d1cffcMisha Brukman// allocation, see the following papers:
20b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng//
21b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng//   (1) Hames, L. and Scholz, B. 2006. Nearly optimal register allocation with
22b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng//   PBQP. In Proceedings of the 7th Joint Modular Languages Conference
23b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng//   (JMLC'06). LNCS, vol. 4228. Springer, New York, NY, USA. 346-361.
24b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng//
25b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng//   (2) Scholz, B., Eckstein, E. 2002. Register allocation for irregular
26b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng//   architectures. In Proceedings of the Joint Conference on Languages,
27b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng//   Compilers and Tools for Embedded Systems (LCTES'02), ACM Press, New York,
28b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng//   NY, USA, 139-148.
292a835f947a114142071456d7586118a0949499a0Misha Brukman//
30b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng//===----------------------------------------------------------------------===//
31b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng
32b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng#define DEBUG_TYPE "regalloc"
33b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng
3454cc2efb4e6ba3022ec297746b14a129d97fc07bLang Hames#include "RenderMachineFunction.h"
3512f35c52a533da0c2c4c3e0a04f83355514992f9Lang Hames#include "Splitter.h"
36b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng#include "VirtRegMap.h"
3787e3bcab736e5af501b1cfbf880563d3d2244497Lang Hames#include "VirtRegRewriter.h"
38fdf16ca44f130afe80c57481d0c08130aa08cc09Rafael Espindola#include "RegisterCoalescer.h"
39a937f220e14826266a8f05b58a541aad669c8912Lang Hames#include "llvm/CodeGen/CalcSpillWeights.h"
40b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng#include "llvm/CodeGen/LiveIntervalAnalysis.h"
4127601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames#include "llvm/CodeGen/LiveStackAnalysis.h"
42eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames#include "llvm/CodeGen/RegAllocPBQP.h"
432a835f947a114142071456d7586118a0949499a0Misha Brukman#include "llvm/CodeGen/MachineFunctionPass.h"
44b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng#include "llvm/CodeGen/MachineLoopInfo.h"
452a835f947a114142071456d7586118a0949499a0Misha Brukman#include "llvm/CodeGen/MachineRegisterInfo.h"
46eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames#include "llvm/CodeGen/PBQP/HeuristicSolver.h"
47eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames#include "llvm/CodeGen/PBQP/Graph.h"
48eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames#include "llvm/CodeGen/PBQP/Heuristics/Briggs.h"
492a835f947a114142071456d7586118a0949499a0Misha Brukman#include "llvm/CodeGen/RegAllocRegistry.h"
50b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng#include "llvm/Support/Debug.h"
51ce63ffb52f249b62cdf2d250c128007b13f27e71Daniel Dunbar#include "llvm/Support/raw_ostream.h"
522a835f947a114142071456d7586118a0949499a0Misha Brukman#include "llvm/Target/TargetInstrInfo.h"
532a835f947a114142071456d7586118a0949499a0Misha Brukman#include "llvm/Target/TargetMachine.h"
542a835f947a114142071456d7586118a0949499a0Misha Brukman#include <limits>
552a835f947a114142071456d7586118a0949499a0Misha Brukman#include <memory>
56b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng#include <set>
57b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng#include <vector>
58b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng
59f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hamesusing namespace llvm;
60eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames
61b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Chengstatic RegisterRegAlloc
621aecd15bd1b54f33bfd928e082a3798f0edf33aaDuncan SandsregisterPBQPRepAlloc("pbqp", "PBQP register allocator",
63f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames                       createDefaultPBQPRegisterAllocator);
64b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng
658481e3b368444386d5be5b74cd1e0ba6f858d983Lang Hamesstatic cl::opt<bool>
668481e3b368444386d5be5b74cd1e0ba6f858d983Lang HamespbqpCoalescing("pbqp-coalescing",
67030c4bfbc9885444b8a5ad0b5f1e50045a351d17Lang Hames                cl::desc("Attempt coalescing during PBQP register allocation."),
68030c4bfbc9885444b8a5ad0b5f1e50045a351d17Lang Hames                cl::init(false), cl::Hidden);
698481e3b368444386d5be5b74cd1e0ba6f858d983Lang Hames
7012f35c52a533da0c2c4c3e0a04f83355514992f9Lang Hamesstatic cl::opt<bool>
7112f35c52a533da0c2c4c3e0a04f83355514992f9Lang HamespbqpPreSplitting("pbqp-pre-splitting",
72f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames                 cl::desc("Pre-split before PBQP register allocation."),
7312f35c52a533da0c2c4c3e0a04f83355514992f9Lang Hames                 cl::init(false), cl::Hidden);
7412f35c52a533da0c2c4c3e0a04f83355514992f9Lang Hames
75f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hamesnamespace {
76f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames
77f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames///
78f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames/// PBQP based allocators solve the register allocation problem by mapping
79f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames/// register allocation problems to Partitioned Boolean Quadratic
80f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames/// Programming problems.
81f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hamesclass RegAllocPBQP : public MachineFunctionPass {
82f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hamespublic:
83f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames
84f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames  static char ID;
85f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames
86f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames  /// Construct a PBQP register allocator.
878d857660ce194f05eca3e21d149e8cf3101da9e4Lang Hames  RegAllocPBQP(std::auto_ptr<PBQPBuilder> b, char *cPassID=0)
888d857660ce194f05eca3e21d149e8cf3101da9e4Lang Hames      : MachineFunctionPass(ID), builder(b), customPassID(cPassID) {
89081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson    initializeSlotIndexesPass(*PassRegistry::getPassRegistry());
90081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson    initializeLiveIntervalsPass(*PassRegistry::getPassRegistry());
915b220213bfe9c37c2bb41a7ae0804e06a14f1007Rafael Espindola    initializeRegisterCoalescerPass(*PassRegistry::getPassRegistry());
92081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson    initializeCalculateSpillWeightsPass(*PassRegistry::getPassRegistry());
93081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson    initializeLiveStacksPass(*PassRegistry::getPassRegistry());
94081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson    initializeMachineLoopInfoPass(*PassRegistry::getPassRegistry());
95081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson    initializeLoopSplitterPass(*PassRegistry::getPassRegistry());
96081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson    initializeVirtRegMapPass(*PassRegistry::getPassRegistry());
97081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson    initializeRenderMachineFunctionPass(*PassRegistry::getPassRegistry());
98081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson  }
99f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames
100f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames  /// Return the pass name.
101f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames  virtual const char* getPassName() const {
102f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames    return "PBQP Register Allocator";
103f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames  }
104f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames
105f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames  /// PBQP analysis usage.
106f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames  virtual void getAnalysisUsage(AnalysisUsage &au) const;
107f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames
108f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames  /// Perform register allocation
109f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames  virtual bool runOnMachineFunction(MachineFunction &MF);
110f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames
111f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hamesprivate:
112f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames
113f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames  typedef std::map<const LiveInterval*, unsigned> LI2NodeMap;
114f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames  typedef std::vector<const LiveInterval*> Node2LIMap;
115f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames  typedef std::vector<unsigned> AllowedSet;
116f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames  typedef std::vector<AllowedSet> AllowedSetMap;
117f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames  typedef std::pair<unsigned, unsigned> RegPair;
118f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames  typedef std::map<RegPair, PBQP::PBQPNum> CoalesceMap;
119f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames  typedef std::vector<PBQP::Graph::NodeItr> NodeVector;
120f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames  typedef std::set<unsigned> RegSet;
121f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames
122f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames
123f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames  std::auto_ptr<PBQPBuilder> builder;
124f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames
1258d857660ce194f05eca3e21d149e8cf3101da9e4Lang Hames  char *customPassID;
1268d857660ce194f05eca3e21d149e8cf3101da9e4Lang Hames
127f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames  MachineFunction *mf;
128f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames  const TargetMachine *tm;
129f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames  const TargetRegisterInfo *tri;
130f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames  const TargetInstrInfo *tii;
131f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames  const MachineLoopInfo *loopInfo;
132f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames  MachineRegisterInfo *mri;
133f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames  RenderMachineFunction *rmf;
134f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames
135f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames  LiveIntervals *lis;
136f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames  LiveStacks *lss;
137f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames  VirtRegMap *vrm;
138f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames
139f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames  RegSet vregsToAlloc, emptyIntervalVRegs;
140f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames
141f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames  /// \brief Finds the initial set of vreg intervals to allocate.
142f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames  void findVRegIntervalsToAlloc();
143f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames
144f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames  /// \brief Adds a stack interval if the given live interval has been
145f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames  /// spilled. Used to support stack slot coloring.
146f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames  void addStackInterval(const LiveInterval *spilled,MachineRegisterInfo* mri);
147f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames
148f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames  /// \brief Given a solved PBQP problem maps this solution back to a register
149f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames  /// assignment.
150f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames  bool mapPBQPToRegAlloc(const PBQPRAProblem &problem,
151f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames                         const PBQP::Solution &solution);
152f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames
153f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames  /// \brief Postprocessing before final spilling. Sets basic block "live in"
154f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames  /// variables.
155f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames  void finalizeAlloc() const;
156f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames
157f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames};
158f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames
159eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hameschar RegAllocPBQP::ID = 0;
160eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames
161f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames} // End anonymous namespace.
162f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames
163eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hamesunsigned PBQPRAProblem::getVRegForNode(PBQP::Graph::ConstNodeItr node) const {
164eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  Node2VReg::const_iterator vregItr = node2VReg.find(node);
165eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  assert(vregItr != node2VReg.end() && "No vreg for node.");
166eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  return vregItr->second;
167eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames}
168eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames
169eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang HamesPBQP::Graph::NodeItr PBQPRAProblem::getNodeForVReg(unsigned vreg) const {
170eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  VReg2Node::const_iterator nodeItr = vreg2Node.find(vreg);
171eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  assert(nodeItr != vreg2Node.end() && "No node for vreg.");
172eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  return nodeItr->second;
173eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames
174eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames}
175eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames
176eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hamesconst PBQPRAProblem::AllowedSet&
177eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  PBQPRAProblem::getAllowedSet(unsigned vreg) const {
178eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  AllowedSetMap::const_iterator allowedSetItr = allowedSets.find(vreg);
179eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  assert(allowedSetItr != allowedSets.end() && "No pregs for vreg.");
180eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  const AllowedSet &allowedSet = allowedSetItr->second;
181eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  return allowedSet;
182eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames}
183eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames
184eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hamesunsigned PBQPRAProblem::getPRegForOption(unsigned vreg, unsigned option) const {
185eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  assert(isPRegOption(vreg, option) && "Not a preg option.");
186eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames
187eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  const AllowedSet& allowedSet = getAllowedSet(vreg);
188eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  assert(option <= allowedSet.size() && "Option outside allowed set.");
189eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  return allowedSet[option - 1];
190eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames}
191eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames
192e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hamesstd::auto_ptr<PBQPRAProblem> PBQPBuilder::build(MachineFunction *mf,
193e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames                                                const LiveIntervals *lis,
194e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames                                                const MachineLoopInfo *loopInfo,
195e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames                                                const RegSet &vregs) {
196eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames
197eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  typedef std::vector<const LiveInterval*> LIVector;
198eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames
199eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  MachineRegisterInfo *mri = &mf->getRegInfo();
200eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  const TargetRegisterInfo *tri = mf->getTarget().getRegisterInfo();
201eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames
202eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  std::auto_ptr<PBQPRAProblem> p(new PBQPRAProblem());
203eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  PBQP::Graph &g = p->getGraph();
204eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  RegSet pregs;
205eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames
206eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  // Collect the set of preg intervals, record that they're used in the MF.
207eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  for (LiveIntervals::const_iterator itr = lis->begin(), end = lis->end();
208eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames       itr != end; ++itr) {
209eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames    if (TargetRegisterInfo::isPhysicalRegister(itr->first)) {
210eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames      pregs.insert(itr->first);
211eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames      mri->setPhysRegUsed(itr->first);
212eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames    }
213eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  }
214eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames
215eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  BitVector reservedRegs = tri->getReservedRegs(*mf);
216eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames
217eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  // Iterate over vregs.
218eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  for (RegSet::const_iterator vregItr = vregs.begin(), vregEnd = vregs.end();
219eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames       vregItr != vregEnd; ++vregItr) {
220eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames    unsigned vreg = *vregItr;
221eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames    const TargetRegisterClass *trc = mri->getRegClass(vreg);
222eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames    const LiveInterval *vregLI = &lis->getInterval(vreg);
223eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames
224eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames    // Compute an initial allowed set for the current vreg.
225eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames    typedef std::vector<unsigned> VRAllowed;
226eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames    VRAllowed vrAllowed;
227714c0eb811340a41a602509b70ca83cd4b2f2868Jakob Stoklund Olesen    ArrayRef<unsigned> rawOrder = trc->getRawAllocationOrder(*mf);
228714c0eb811340a41a602509b70ca83cd4b2f2868Jakob Stoklund Olesen    for (unsigned i = 0; i != rawOrder.size(); ++i) {
229714c0eb811340a41a602509b70ca83cd4b2f2868Jakob Stoklund Olesen      unsigned preg = rawOrder[i];
230eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames      if (!reservedRegs.test(preg)) {
231eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames        vrAllowed.push_back(preg);
232eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames      }
233eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames    }
234eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames
235eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames    // Remove any physical registers which overlap.
236eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames    for (RegSet::const_iterator pregItr = pregs.begin(),
237eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames                                pregEnd = pregs.end();
238eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames         pregItr != pregEnd; ++pregItr) {
239eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames      unsigned preg = *pregItr;
240eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames      const LiveInterval *pregLI = &lis->getInterval(preg);
241eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames
2425e77f4b1d239a61dbdb37026bfc92d83d82ceb70Lang Hames      if (pregLI->empty()) {
243eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames        continue;
2445e77f4b1d239a61dbdb37026bfc92d83d82ceb70Lang Hames      }
245eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames
2465e77f4b1d239a61dbdb37026bfc92d83d82ceb70Lang Hames      if (!vregLI->overlaps(*pregLI)) {
247eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames        continue;
2485e77f4b1d239a61dbdb37026bfc92d83d82ceb70Lang Hames      }
249b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng
250eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames      // Remove the register from the allowed set.
251eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames      VRAllowed::iterator eraseItr =
252eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames        std::find(vrAllowed.begin(), vrAllowed.end(), preg);
253b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng
254eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames      if (eraseItr != vrAllowed.end()) {
255eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames        vrAllowed.erase(eraseItr);
256eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames      }
257a279bc3da55691784064cb47200a1c584408b8abDaniel Dunbar
258eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames      // Also remove any aliases.
259eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames      const unsigned *aliasItr = tri->getAliasSet(preg);
260eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames      if (aliasItr != 0) {
261eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames        for (; *aliasItr != 0; ++aliasItr) {
262eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames          VRAllowed::iterator eraseItr =
263eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames            std::find(vrAllowed.begin(), vrAllowed.end(), *aliasItr);
264b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng
265eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames          if (eraseItr != vrAllowed.end()) {
266eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames            vrAllowed.erase(eraseItr);
267eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames          }
268eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames        }
269eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames      }
270b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng    }
271b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng
272eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames    // Construct the node.
273eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames    PBQP::Graph::NodeItr node =
274eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames      g.addNode(PBQP::Vector(vrAllowed.size() + 1, 0));
275eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames
276eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames    // Record the mapping and allowed set in the problem.
277eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames    p->recordVReg(vreg, node, vrAllowed.begin(), vrAllowed.end());
278eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames
279eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames    PBQP::PBQPNum spillCost = (vregLI->weight != 0.0) ?
280eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames        vregLI->weight : std::numeric_limits<PBQP::PBQPNum>::min();
281eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames
282eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames    addSpillCosts(g.getNodeCosts(node), spillCost);
283eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  }
284eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames
285481630dee5f221c04bb26fe12f0887b4f25f8455Lang Hames  for (RegSet::const_iterator vr1Itr = vregs.begin(), vrEnd = vregs.end();
286eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames         vr1Itr != vrEnd; ++vr1Itr) {
287eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames    unsigned vr1 = *vr1Itr;
288eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames    const LiveInterval &l1 = lis->getInterval(vr1);
289eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames    const PBQPRAProblem::AllowedSet &vr1Allowed = p->getAllowedSet(vr1);
290eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames
2919e8d1f97e9f32c87aac1189edbc3263a1f4a81f3Benjamin Kramer    for (RegSet::const_iterator vr2Itr = llvm::next(vr1Itr);
292eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames         vr2Itr != vrEnd; ++vr2Itr) {
293eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames      unsigned vr2 = *vr2Itr;
294eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames      const LiveInterval &l2 = lis->getInterval(vr2);
295eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames      const PBQPRAProblem::AllowedSet &vr2Allowed = p->getAllowedSet(vr2);
296eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames
297eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames      assert(!l2.empty() && "Empty interval in vreg set?");
298eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames      if (l1.overlaps(l2)) {
299eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames        PBQP::Graph::EdgeItr edge =
300eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames          g.addEdge(p->getNodeForVReg(vr1), p->getNodeForVReg(vr2),
301eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames                    PBQP::Matrix(vr1Allowed.size()+1, vr2Allowed.size()+1, 0));
302eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames
303eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames        addInterferenceCosts(g.getEdgeCosts(edge), vr1Allowed, vr2Allowed, tri);
304eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames      }
305b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng    }
306eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  }
307eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames
308eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  return p;
309eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames}
310eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames
311eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hamesvoid PBQPBuilder::addSpillCosts(PBQP::Vector &costVec,
312eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames                                PBQP::PBQPNum spillCost) {
313eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  costVec[0] = spillCost;
314eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames}
315eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames
316e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hamesvoid PBQPBuilder::addInterferenceCosts(
317e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames                                    PBQP::Matrix &costMat,
318e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames                                    const PBQPRAProblem::AllowedSet &vr1Allowed,
319e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames                                    const PBQPRAProblem::AllowedSet &vr2Allowed,
320e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames                                    const TargetRegisterInfo *tri) {
321eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  assert(costMat.getRows() == vr1Allowed.size() + 1 && "Matrix height mismatch.");
322eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  assert(costMat.getCols() == vr2Allowed.size() + 1 && "Matrix width mismatch.");
323b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng
3245e77f4b1d239a61dbdb37026bfc92d83d82ceb70Lang Hames  for (unsigned i = 0; i != vr1Allowed.size(); ++i) {
325eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames    unsigned preg1 = vr1Allowed[i];
326b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng
3275e77f4b1d239a61dbdb37026bfc92d83d82ceb70Lang Hames    for (unsigned j = 0; j != vr2Allowed.size(); ++j) {
328eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames      unsigned preg2 = vr2Allowed[j];
329d0f6f017319bbc32b57c2e574d774ac91fe20f18Lang Hames
330eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames      if (tri->regsOverlap(preg1, preg2)) {
331eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames        costMat[i + 1][j + 1] = std::numeric_limits<PBQP::PBQPNum>::infinity();
332d0f6f017319bbc32b57c2e574d774ac91fe20f18Lang Hames      }
333eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames    }
334eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  }
335b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng}
336b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng
337e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hamesstd::auto_ptr<PBQPRAProblem> PBQPBuilderWithCoalescing::build(
338e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames                                                MachineFunction *mf,
339e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames                                                const LiveIntervals *lis,
340e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames                                                const MachineLoopInfo *loopInfo,
341e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames                                                const RegSet &vregs) {
342e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames
343e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames  std::auto_ptr<PBQPRAProblem> p = PBQPBuilder::build(mf, lis, loopInfo, vregs);
344e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames  PBQP::Graph &g = p->getGraph();
345e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames
346e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames  const TargetMachine &tm = mf->getTarget();
347e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames  CoalescerPair cp(*tm.getInstrInfo(), *tm.getRegisterInfo());
348e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames
349e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames  // Scan the machine function and add a coalescing cost whenever CoalescerPair
350e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames  // gives the Ok.
351e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames  for (MachineFunction::const_iterator mbbItr = mf->begin(),
352e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames                                       mbbEnd = mf->end();
353e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames       mbbItr != mbbEnd; ++mbbItr) {
354e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames    const MachineBasicBlock *mbb = &*mbbItr;
355e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames
356e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames    for (MachineBasicBlock::const_iterator miItr = mbb->begin(),
357e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames                                           miEnd = mbb->end();
358e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames         miItr != miEnd; ++miItr) {
359e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames      const MachineInstr *mi = &*miItr;
360e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames
3615e77f4b1d239a61dbdb37026bfc92d83d82ceb70Lang Hames      if (!cp.setRegisters(mi)) {
362e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames        continue; // Not coalescable.
3635e77f4b1d239a61dbdb37026bfc92d83d82ceb70Lang Hames      }
364e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames
3655e77f4b1d239a61dbdb37026bfc92d83d82ceb70Lang Hames      if (cp.getSrcReg() == cp.getDstReg()) {
366e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames        continue; // Already coalesced.
3675e77f4b1d239a61dbdb37026bfc92d83d82ceb70Lang Hames      }
368e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames
369f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames      unsigned dst = cp.getDstReg(),
370f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames               src = cp.getSrcReg();
371e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames
372f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames      const float copyFactor = 0.5; // Cost of copy relative to load. Current
373f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames      // value plucked randomly out of the air.
374f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames
375f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames      PBQP::PBQPNum cBenefit =
376f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames        copyFactor * LiveIntervals::getSpillWeight(false, true,
377f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames                                                   loopInfo->getLoopDepth(mbb));
378e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames
379f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames      if (cp.isPhys()) {
3805e77f4b1d239a61dbdb37026bfc92d83d82ceb70Lang Hames        if (!lis->isAllocatable(dst)) {
381f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames          continue;
3825e77f4b1d239a61dbdb37026bfc92d83d82ceb70Lang Hames        }
383e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames
384f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames        const PBQPRAProblem::AllowedSet &allowed = p->getAllowedSet(src);
385f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames        unsigned pregOpt = 0;
3865e77f4b1d239a61dbdb37026bfc92d83d82ceb70Lang Hames        while (pregOpt < allowed.size() && allowed[pregOpt] != dst) {
387f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames          ++pregOpt;
3885e77f4b1d239a61dbdb37026bfc92d83d82ceb70Lang Hames        }
389f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames        if (pregOpt < allowed.size()) {
390f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames          ++pregOpt; // +1 to account for spill option.
391f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames          PBQP::Graph::NodeItr node = p->getNodeForVReg(src);
392f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames          addPhysRegCoalesce(g.getNodeCosts(node), pregOpt, cBenefit);
393f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames        }
394f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames      } else {
395f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames        const PBQPRAProblem::AllowedSet *allowed1 = &p->getAllowedSet(dst);
396f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames        const PBQPRAProblem::AllowedSet *allowed2 = &p->getAllowedSet(src);
397f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames        PBQP::Graph::NodeItr node1 = p->getNodeForVReg(dst);
398f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames        PBQP::Graph::NodeItr node2 = p->getNodeForVReg(src);
399f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames        PBQP::Graph::EdgeItr edge = g.findEdge(node1, node2);
400f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames        if (edge == g.edgesEnd()) {
401f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames          edge = g.addEdge(node1, node2, PBQP::Matrix(allowed1->size() + 1,
402f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames                                                      allowed2->size() + 1,
403f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames                                                      0));
404e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames        } else {
405f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames          if (g.getEdgeNode1(edge) == node2) {
406f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames            std::swap(node1, node2);
407f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames            std::swap(allowed1, allowed2);
408e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames          }
409e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames        }
410f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames
411f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames        addVirtRegCoalesce(g.getEdgeCosts(edge), *allowed1, *allowed2,
412f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames                           cBenefit);
413e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames      }
414e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames    }
415e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames  }
416e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames
417e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames  return p;
418e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames}
419e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames
420e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hamesvoid PBQPBuilderWithCoalescing::addPhysRegCoalesce(PBQP::Vector &costVec,
421e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames                                                   unsigned pregOption,
422e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames                                                   PBQP::PBQPNum benefit) {
423e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames  costVec[pregOption] += -benefit;
424e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames}
425e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames
426e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hamesvoid PBQPBuilderWithCoalescing::addVirtRegCoalesce(
427e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames                                    PBQP::Matrix &costMat,
428e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames                                    const PBQPRAProblem::AllowedSet &vr1Allowed,
429e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames                                    const PBQPRAProblem::AllowedSet &vr2Allowed,
430e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames                                    PBQP::PBQPNum benefit) {
431e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames
432e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames  assert(costMat.getRows() == vr1Allowed.size() + 1 && "Size mismatch.");
433e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames  assert(costMat.getCols() == vr2Allowed.size() + 1 && "Size mismatch.");
434e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames
4355e77f4b1d239a61dbdb37026bfc92d83d82ceb70Lang Hames  for (unsigned i = 0; i != vr1Allowed.size(); ++i) {
436e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames    unsigned preg1 = vr1Allowed[i];
4375e77f4b1d239a61dbdb37026bfc92d83d82ceb70Lang Hames    for (unsigned j = 0; j != vr2Allowed.size(); ++j) {
438e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames      unsigned preg2 = vr2Allowed[j];
439e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames
440e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames      if (preg1 == preg2) {
441e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames        costMat[i + 1][j + 1] += -benefit;
442e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames      }
443e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames    }
444e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames  }
445e9c935662d77b8c5a3a26f5622dc2a3ed22d75c8Lang Hames}
446b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng
447eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames
448eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hamesvoid RegAllocPBQP::getAnalysisUsage(AnalysisUsage &au) const {
449eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  au.addRequired<SlotIndexes>();
450eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  au.addPreserved<SlotIndexes>();
451eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  au.addRequired<LiveIntervals>();
452eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  //au.addRequiredID(SplitCriticalEdgesID);
453eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  au.addRequired<RegisterCoalescer>();
4548d857660ce194f05eca3e21d149e8cf3101da9e4Lang Hames  if (customPassID)
4558d857660ce194f05eca3e21d149e8cf3101da9e4Lang Hames    au.addRequiredID(*customPassID);
456eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  au.addRequired<CalculateSpillWeights>();
457eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  au.addRequired<LiveStacks>();
458eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  au.addPreserved<LiveStacks>();
459eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  au.addRequired<MachineLoopInfo>();
460eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  au.addPreserved<MachineLoopInfo>();
461eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  if (pbqpPreSplitting)
462eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames    au.addRequired<LoopSplitter>();
463eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  au.addRequired<VirtRegMap>();
464eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  au.addRequired<RenderMachineFunction>();
465eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  MachineFunctionPass::getAnalysisUsage(au);
466eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames}
467eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames
468eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hamesvoid RegAllocPBQP::findVRegIntervalsToAlloc() {
46927601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames
47027601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames  // Iterate over all live ranges.
47127601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames  for (LiveIntervals::iterator itr = lis->begin(), end = lis->end();
47227601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames       itr != end; ++itr) {
47327601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames
47427601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames    // Ignore physical ones.
47527601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames    if (TargetRegisterInfo::isPhysicalRegister(itr->first))
47627601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames      continue;
47727601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames
47827601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames    LiveInterval *li = itr->second;
47927601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames
48027601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames    // If this live interval is non-empty we will use pbqp to allocate it.
48127601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames    // Empty intervals we allocate in a simple post-processing stage in
48227601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames    // finalizeAlloc.
48327601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames    if (!li->empty()) {
484eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames      vregsToAlloc.insert(li->reg);
4855e77f4b1d239a61dbdb37026bfc92d83d82ceb70Lang Hames    } else {
486eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames      emptyIntervalVRegs.insert(li->reg);
48727601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames    }
48827601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames  }
489b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng}
490b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng
491eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hamesvoid RegAllocPBQP::addStackInterval(const LiveInterval *spilled,
492c781a243a3d17e7e763515794168d8fa6043f565Evan Cheng                                    MachineRegisterInfo* mri) {
49327601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames  int stackSlot = vrm->getStackSlot(spilled->reg);
4942a835f947a114142071456d7586118a0949499a0Misha Brukman
4955e77f4b1d239a61dbdb37026bfc92d83d82ceb70Lang Hames  if (stackSlot == VirtRegMap::NO_STACK_SLOT) {
49627601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames    return;
4975e77f4b1d239a61dbdb37026bfc92d83d82ceb70Lang Hames  }
49827601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames
499c781a243a3d17e7e763515794168d8fa6043f565Evan Cheng  const TargetRegisterClass *RC = mri->getRegClass(spilled->reg);
500c781a243a3d17e7e763515794168d8fa6043f565Evan Cheng  LiveInterval &stackInterval = lss->getOrCreateInterval(stackSlot, RC);
50127601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames
50227601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames  VNInfo *vni;
5035e77f4b1d239a61dbdb37026bfc92d83d82ceb70Lang Hames  if (stackInterval.getNumValNums() != 0) {
50427601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames    vni = stackInterval.getValNumInfo(0);
5055e77f4b1d239a61dbdb37026bfc92d83d82ceb70Lang Hames  } else {
5068651125d2885f74546b6e2a556082111d5b75da3Lang Hames    vni = stackInterval.getNextValue(
5076e2968c85c1e162ee5bc813769eab223e3df0f15Lang Hames      SlotIndex(), 0, lss->getVNInfoAllocator());
5085e77f4b1d239a61dbdb37026bfc92d83d82ceb70Lang Hames  }
50927601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames
51027601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames  LiveInterval &rhsInterval = lis->getInterval(spilled->reg);
51127601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames  stackInterval.MergeRangesInAsValue(rhsInterval, vni);
51227601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames}
51327601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames
514f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hamesbool RegAllocPBQP::mapPBQPToRegAlloc(const PBQPRAProblem &problem,
515f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames                                     const PBQP::Solution &solution) {
516eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  // Set to true if we have any spills
517eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  bool anotherRoundNeeded = false;
518eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames
519eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  // Clear the existing allocation.
520eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  vrm->clearAllVirt();
521eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames
522eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  const PBQP::Graph &g = problem.getGraph();
523eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  // Iterate over the nodes mapping the PBQP solution to a register
524eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  // assignment.
525eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  for (PBQP::Graph::ConstNodeItr node = g.nodesBegin(),
526eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames                                 nodeEnd = g.nodesEnd();
527eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames       node != nodeEnd; ++node) {
528eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames    unsigned vreg = problem.getVRegForNode(node);
529eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames    unsigned alloc = solution.getSelection(node);
530eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames
531eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames    if (problem.isPRegOption(vreg, alloc)) {
532eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames      unsigned preg = problem.getPRegForOption(vreg, alloc);
533eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames      DEBUG(dbgs() << "VREG " << vreg << " -> " << tri->getName(preg) << "\n");
534eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames      assert(preg != 0 && "Invalid preg selected.");
535eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames      vrm->assignVirt2Phys(vreg, preg);
536eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames    } else if (problem.isSpillOption(vreg, alloc)) {
537eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames      vregsToAlloc.erase(vreg);
538eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames      const LiveInterval* spillInterval = &lis->getInterval(vreg);
539eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames      double oldWeight = spillInterval->weight;
540eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames      rmf->rememberUseDefs(spillInterval);
541eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames      std::vector<LiveInterval*> newSpills =
54238f6bd0fc8095ef79a89b3db15ff6dc734ac90e7Jakob Stoklund Olesen        lis->addIntervalsForSpills(*spillInterval, 0, loopInfo, *vrm);
543eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames      addStackInterval(spillInterval, mri);
544eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames      rmf->rememberSpills(spillInterval, newSpills);
545eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames
546eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames      (void) oldWeight;
547eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames      DEBUG(dbgs() << "VREG " << vreg << " -> SPILLED (Cost: "
548eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames                   << oldWeight << ", New vregs: ");
549eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames
550eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames      // Copy any newly inserted live intervals into the list of regs to
551eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames      // allocate.
552eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames      for (std::vector<LiveInterval*>::const_iterator
553eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames           itr = newSpills.begin(), end = newSpills.end();
554eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames           itr != end; ++itr) {
555eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames        assert(!(*itr)->empty() && "Empty spill range.");
556eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames        DEBUG(dbgs() << (*itr)->reg << " ");
557eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames        vregsToAlloc.insert((*itr)->reg);
55827601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames      }
55927601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames
560309315420669ff5bde9b0ae1213171a88216fad7David Greene      DEBUG(dbgs() << ")\n");
561b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng
562b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng      // We need another round if spill intervals were added.
563b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng      anotherRoundNeeded |= !newSpills.empty();
564eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames    } else {
565eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames      assert(false && "Unknown allocation option.");
566b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng    }
567b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng  }
568b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng
569b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng  return !anotherRoundNeeded;
570b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng}
571b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng
572eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames
573eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hamesvoid RegAllocPBQP::finalizeAlloc() const {
57427601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames  typedef LiveIntervals::iterator LIIterator;
57527601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames  typedef LiveInterval::Ranges::const_iterator LRIterator;
57627601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames
57727601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames  // First allocate registers for the empty intervals.
578eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  for (RegSet::const_iterator
579eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames         itr = emptyIntervalVRegs.begin(), end = emptyIntervalVRegs.end();
58027601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames         itr != end; ++itr) {
581eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames    LiveInterval *li = &lis->getInterval(*itr);
58227601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames
58390f95f88c6ce09c6744777dc9d140c3c77203b92Evan Cheng    unsigned physReg = vrm->getRegAllocPref(li->reg);
5846699fb27091927528f9f6059c3034d566dbed623Lang Hames
58527601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames    if (physReg == 0) {
58627601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames      const TargetRegisterClass *liRC = mri->getRegClass(li->reg);
587714c0eb811340a41a602509b70ca83cd4b2f2868Jakob Stoklund Olesen      physReg = liRC->getRawAllocationOrder(*mf).front();
58827601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames    }
5892a835f947a114142071456d7586118a0949499a0Misha Brukman
5902a835f947a114142071456d7586118a0949499a0Misha Brukman    vrm->assignVirt2Phys(li->reg, physReg);
59127601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames  }
5922a835f947a114142071456d7586118a0949499a0Misha Brukman
59327601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames  // Finally iterate over the basic blocks to compute and set the live-in sets.
59427601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames  SmallVector<MachineBasicBlock*, 8> liveInMBBs;
59527601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames  MachineBasicBlock *entryMBB = &*mf->begin();
59627601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames
59727601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames  for (LIIterator liItr = lis->begin(), liEnd = lis->end();
59827601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames       liItr != liEnd; ++liItr) {
59927601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames
60027601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames    const LiveInterval *li = liItr->second;
60127601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames    unsigned reg = 0;
6022a835f947a114142071456d7586118a0949499a0Misha Brukman
60327601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames    // Get the physical register for this interval
60427601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames    if (TargetRegisterInfo::isPhysicalRegister(li->reg)) {
60527601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames      reg = li->reg;
6065e77f4b1d239a61dbdb37026bfc92d83d82ceb70Lang Hames    } else if (vrm->isAssignedReg(li->reg)) {
60727601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames      reg = vrm->getPhys(li->reg);
6085e77f4b1d239a61dbdb37026bfc92d83d82ceb70Lang Hames    } else {
60927601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames      // Ranges which are assigned a stack slot only are ignored.
61027601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames      continue;
61127601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames    }
61227601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames
613b0e519f2bf201d96d304cb9fd330a5e1b38536feLang Hames    if (reg == 0) {
6146699fb27091927528f9f6059c3034d566dbed623Lang Hames      // Filter out zero regs - they're for intervals that were spilled.
615b0e519f2bf201d96d304cb9fd330a5e1b38536feLang Hames      continue;
616b0e519f2bf201d96d304cb9fd330a5e1b38536feLang Hames    }
617b0e519f2bf201d96d304cb9fd330a5e1b38536feLang Hames
61827601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames    // Iterate over the ranges of the current interval...
61927601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames    for (LRIterator lrItr = li->begin(), lrEnd = li->end();
62027601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames         lrItr != lrEnd; ++lrItr) {
6212a835f947a114142071456d7586118a0949499a0Misha Brukman
62227601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames      // Find the set of basic blocks which this range is live into...
62327601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames      if (lis->findLiveInMBBs(lrItr->start, lrItr->end,  liveInMBBs)) {
62427601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames        // And add the physreg for this interval to their live-in sets.
6255e77f4b1d239a61dbdb37026bfc92d83d82ceb70Lang Hames        for (unsigned i = 0; i != liveInMBBs.size(); ++i) {
62627601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames          if (liveInMBBs[i] != entryMBB) {
62727601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames            if (!liveInMBBs[i]->isLiveIn(reg)) {
62827601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames              liveInMBBs[i]->addLiveIn(reg);
62927601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames            }
63027601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames          }
63127601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames        }
63227601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames        liveInMBBs.clear();
63327601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames      }
63427601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames    }
63527601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames  }
6362a835f947a114142071456d7586118a0949499a0Misha Brukman
63727601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames}
63827601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames
639eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hamesbool RegAllocPBQP::runOnMachineFunction(MachineFunction &MF) {
64027601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames
641b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng  mf = &MF;
642b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng  tm = &mf->getTarget();
643b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng  tri = tm->getRegisterInfo();
64427601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames  tii = tm->getInstrInfo();
645233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames  mri = &mf->getRegInfo();
646b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng
64727601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames  lis = &getAnalysis<LiveIntervals>();
64827601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames  lss = &getAnalysis<LiveStacks>();
649b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng  loopInfo = &getAnalysis<MachineLoopInfo>();
65033198391d6d30127643c0d1f4ae9ed1ef85ed7f0Lang Hames  rmf = &getAnalysis<RenderMachineFunction>();
651b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng
65249c8aa0d8b2824c70d178c5d55cda64d6613c0d8Owen Anderson  vrm = &getAnalysis<VirtRegMap>();
653b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng
65454cc2efb4e6ba3022ec297746b14a129d97fc07bLang Hames
655030c4bfbc9885444b8a5ad0b5f1e50045a351d17Lang Hames  DEBUG(dbgs() << "PBQP Register Allocating for " << mf->getFunction()->getName() << "\n");
65627601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames
657b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng  // Allocator main loop:
6582a835f947a114142071456d7586118a0949499a0Misha Brukman  //
659b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng  // * Map current regalloc problem to a PBQP problem
660b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng  // * Solve the PBQP problem
661b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng  // * Map the solution back to a register allocation
662b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng  // * Spill if necessary
6632a835f947a114142071456d7586118a0949499a0Misha Brukman  //
664b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng  // This process is continued till no more spills are generated.
665b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng
66627601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames  // Find the vreg intervals in need of allocation.
66727601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames  findVRegIntervalsToAlloc();
6682a835f947a114142071456d7586118a0949499a0Misha Brukman
66927601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames  // If there are non-empty intervals allocate them using pbqp.
670eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  if (!vregsToAlloc.empty()) {
67127601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames
67227601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames    bool pbqpAllocComplete = false;
67327601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames    unsigned round = 0;
67427601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames
675ab62b7e8618bda8063b49afab181bc7ed5546104Lang Hames    while (!pbqpAllocComplete) {
676ab62b7e8618bda8063b49afab181bc7ed5546104Lang Hames      DEBUG(dbgs() << "  PBQP Regalloc round " << round << ":\n");
6776699fb27091927528f9f6059c3034d566dbed623Lang Hames
678ab62b7e8618bda8063b49afab181bc7ed5546104Lang Hames      std::auto_ptr<PBQPRAProblem> problem =
679ab62b7e8618bda8063b49afab181bc7ed5546104Lang Hames        builder->build(mf, lis, loopInfo, vregsToAlloc);
680ab62b7e8618bda8063b49afab181bc7ed5546104Lang Hames      PBQP::Solution solution =
681ab62b7e8618bda8063b49afab181bc7ed5546104Lang Hames        PBQP::HeuristicSolver<PBQP::Heuristics::Briggs>::solve(
682ab62b7e8618bda8063b49afab181bc7ed5546104Lang Hames          problem->getGraph());
683233fd9cea04468d71ae44031df3f2c8d1c3299a7Lang Hames
684ab62b7e8618bda8063b49afab181bc7ed5546104Lang Hames      pbqpAllocComplete = mapPBQPToRegAlloc(*problem, solution);
685b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng
686ab62b7e8618bda8063b49afab181bc7ed5546104Lang Hames      ++round;
68727601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames    }
688b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng  }
689b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng
69027601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames  // Finalise allocation, allocate empty ranges.
69127601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames  finalizeAlloc();
692b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng
693c4bcc778a8dcc385b129852c9aa1c712d042ad63Lang Hames  rmf->renderMachineFunction("After PBQP register allocation.", vrm);
694c4bcc778a8dcc385b129852c9aa1c712d042ad63Lang Hames
695eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  vregsToAlloc.clear();
696eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames  emptyIntervalVRegs.clear();
697b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng
698309315420669ff5bde9b0ae1213171a88216fad7David Greene  DEBUG(dbgs() << "Post alloc VirtRegMap:\n" << *vrm << "\n");
69927601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames
70087e3bcab736e5af501b1cfbf880563d3d2244497Lang Hames  // Run rewriter
70187e3bcab736e5af501b1cfbf880563d3d2244497Lang Hames  std::auto_ptr<VirtRegRewriter> rewriter(createVirtRegRewriter());
70287e3bcab736e5af501b1cfbf880563d3d2244497Lang Hames
70387e3bcab736e5af501b1cfbf880563d3d2244497Lang Hames  rewriter->runOnMachineFunction(*mf, *vrm, lis);
70427601ef8325f85b9677b55e3e2ca1a1368d8eee5Lang Hames
7052a835f947a114142071456d7586118a0949499a0Misha Brukman  return true;
706b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng}
707b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng
708f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang HamesFunctionPass* llvm::createPBQPRegisterAllocator(
7098d857660ce194f05eca3e21d149e8cf3101da9e4Lang Hames                                           std::auto_ptr<PBQPBuilder> builder,
7108d857660ce194f05eca3e21d149e8cf3101da9e4Lang Hames                                           char *customPassID) {
7118d857660ce194f05eca3e21d149e8cf3101da9e4Lang Hames  return new RegAllocPBQP(builder, customPassID);
712b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng}
713b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng
714f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang HamesFunctionPass* llvm::createDefaultPBQPRegisterAllocator() {
715f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames  if (pbqpCoalescing) {
716f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames    return createPBQPRegisterAllocator(
717f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames             std::auto_ptr<PBQPBuilder>(new PBQPBuilderWithCoalescing()));
718f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames  } // else
719f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames  return createPBQPRegisterAllocator(
720f70e7cc7a2871d498dbecbec2d1c3beb3da2af33Lang Hames           std::auto_ptr<PBQPBuilder>(new PBQPBuilder()));
721eb6c8f53b4df1488f3d07c11af8f754cc4620f3aLang Hames}
722b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng
723b1290a6cc40f7caa0351450ce7021a0d48b5f2c0Evan Cheng#undef DEBUG_TYPE
724