1 //===-- RegAllocPBQP.h ------------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines the PBQPBuilder interface, for classes which build PBQP 11 // instances to represent register allocation problems, and the RegAllocPBQP 12 // interface. 13 // 14 //===----------------------------------------------------------------------===// 15 16 #ifndef LLVM_CODEGEN_REGALLOCPBQP_H 17 #define LLVM_CODEGEN_REGALLOCPBQP_H 18 19 #include "llvm/ADT/DenseMap.h" 20 #include "llvm/CodeGen/MachineFunctionPass.h" 21 #include "llvm/CodeGen/PBQP/Graph.h" 22 #include "llvm/CodeGen/PBQP/Solution.h" 23 24 #include <map> 25 #include <set> 26 27 namespace llvm { 28 29 class LiveIntervals; 30 class MachineFunction; 31 class MachineLoopInfo; 32 33 /// This class wraps up a PBQP instance representing a register allocation 34 /// problem, plus the structures necessary to map back from the PBQP solution 35 /// to a register allocation solution. (i.e. The PBQP-node <--> vreg map, 36 /// and the PBQP option <--> storage location map). 37 38 class PBQPRAProblem { 39 public: 40 41 typedef SmallVector<unsigned, 16> AllowedSet; 42 getGraph()43 PBQP::Graph& getGraph() { return graph; } 44 getGraph()45 const PBQP::Graph& getGraph() const { return graph; } 46 47 /// Record the mapping between the given virtual register and PBQP node, 48 /// and the set of allowed pregs for the vreg. 49 /// 50 /// If you are extending 51 /// PBQPBuilder you are unlikely to need this: Nodes and options for all 52 /// vregs will already have been set up for you by the base class. 53 template <typename AllowedRegsItr> recordVReg(unsigned vreg,PBQP::Graph::NodeItr node,AllowedRegsItr arBegin,AllowedRegsItr arEnd)54 void recordVReg(unsigned vreg, PBQP::Graph::NodeItr node, 55 AllowedRegsItr arBegin, AllowedRegsItr arEnd) { 56 assert(node2VReg.find(node) == node2VReg.end() && "Re-mapping node."); 57 assert(vreg2Node.find(vreg) == vreg2Node.end() && "Re-mapping vreg."); 58 assert(allowedSets[vreg].empty() && "vreg already has pregs."); 59 60 node2VReg[node] = vreg; 61 vreg2Node[vreg] = node; 62 std::copy(arBegin, arEnd, std::back_inserter(allowedSets[vreg])); 63 } 64 65 /// Get the virtual register corresponding to the given PBQP node. 66 unsigned getVRegForNode(PBQP::Graph::ConstNodeItr node) const; 67 68 /// Get the PBQP node corresponding to the given virtual register. 69 PBQP::Graph::NodeItr getNodeForVReg(unsigned vreg) const; 70 71 /// Returns true if the given PBQP option represents a physical register, 72 /// false otherwise. isPRegOption(unsigned vreg,unsigned option)73 bool isPRegOption(unsigned vreg, unsigned option) const { 74 // At present we only have spills or pregs, so anything that's not a 75 // spill is a preg. (This might be extended one day to support remat). 76 return !isSpillOption(vreg, option); 77 } 78 79 /// Returns true if the given PBQP option represents spilling, false 80 /// otherwise. isSpillOption(unsigned vreg,unsigned option)81 bool isSpillOption(unsigned vreg, unsigned option) const { 82 // We hardcode option zero as the spill option. 83 return option == 0; 84 } 85 86 /// Returns the allowed set for the given virtual register. 87 const AllowedSet& getAllowedSet(unsigned vreg) const; 88 89 /// Get PReg for option. 90 unsigned getPRegForOption(unsigned vreg, unsigned option) const; 91 92 private: 93 94 typedef std::map<PBQP::Graph::ConstNodeItr, unsigned, 95 PBQP::NodeItrComparator> Node2VReg; 96 typedef DenseMap<unsigned, PBQP::Graph::NodeItr> VReg2Node; 97 typedef DenseMap<unsigned, AllowedSet> AllowedSetMap; 98 99 PBQP::Graph graph; 100 Node2VReg node2VReg; 101 VReg2Node vreg2Node; 102 103 AllowedSetMap allowedSets; 104 105 }; 106 107 /// Builds PBQP instances to represent register allocation problems. Includes 108 /// spill, interference and coalescing costs by default. You can extend this 109 /// class to support additional constraints for your architecture. 110 class PBQPBuilder { 111 private: PBQPBuilder(const PBQPBuilder &)112 PBQPBuilder(const PBQPBuilder&) {} 113 void operator=(const PBQPBuilder&) {} 114 public: 115 116 typedef std::set<unsigned> RegSet; 117 118 /// Default constructor. PBQPBuilder()119 PBQPBuilder() {} 120 121 /// Clean up a PBQPBuilder. ~PBQPBuilder()122 virtual ~PBQPBuilder() {} 123 124 /// Build a PBQP instance to represent the register allocation problem for 125 /// the given MachineFunction. 126 virtual std::auto_ptr<PBQPRAProblem> build( 127 MachineFunction *mf, 128 const LiveIntervals *lis, 129 const MachineLoopInfo *loopInfo, 130 const RegSet &vregs); 131 private: 132 133 void addSpillCosts(PBQP::Vector &costVec, PBQP::PBQPNum spillCost); 134 135 void addInterferenceCosts(PBQP::Matrix &costMat, 136 const PBQPRAProblem::AllowedSet &vr1Allowed, 137 const PBQPRAProblem::AllowedSet &vr2Allowed, 138 const TargetRegisterInfo *tri); 139 }; 140 141 /// Extended builder which adds coalescing constraints to a problem. 142 class PBQPBuilderWithCoalescing : public PBQPBuilder { 143 public: 144 145 /// Build a PBQP instance to represent the register allocation problem for 146 /// the given MachineFunction. 147 virtual std::auto_ptr<PBQPRAProblem> build( 148 MachineFunction *mf, 149 const LiveIntervals *lis, 150 const MachineLoopInfo *loopInfo, 151 const RegSet &vregs); 152 153 private: 154 155 void addPhysRegCoalesce(PBQP::Vector &costVec, unsigned pregOption, 156 PBQP::PBQPNum benefit); 157 158 void addVirtRegCoalesce(PBQP::Matrix &costMat, 159 const PBQPRAProblem::AllowedSet &vr1Allowed, 160 const PBQPRAProblem::AllowedSet &vr2Allowed, 161 PBQP::PBQPNum benefit); 162 }; 163 164 FunctionPass* createPBQPRegisterAllocator(std::auto_ptr<PBQPBuilder> builder, 165 char *customPassID=0); 166 } 167 168 #endif /* LLVM_CODEGEN_REGALLOCPBQP_H */ 169