| //===-- RegAllocPBQP.h ------------------------------------------*- C++ -*-===// | |
| // | |
| // The LLVM Compiler Infrastructure | |
| // | |
| // This file is distributed under the University of Illinois Open Source | |
| // License. See LICENSE.TXT for details. | |
| // | |
| //===----------------------------------------------------------------------===// | |
| // | |
| // This file defines the PBQPBuilder interface, for classes which build PBQP | |
| // instances to represent register allocation problems, and the RegAllocPBQP | |
| // interface. | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #ifndef LLVM_CODEGEN_REGALLOCPBQP_H | |
| #define LLVM_CODEGEN_REGALLOCPBQP_H | |
| #include "llvm/ADT/DenseMap.h" | |
| #include "llvm/CodeGen/MachineFunctionPass.h" | |
| #include "llvm/CodeGen/PBQP/Graph.h" | |
| #include "llvm/CodeGen/PBQP/Solution.h" | |
| #include <map> | |
| #include <set> | |
| namespace llvm { | |
| class LiveIntervals; | |
| class MachineFunction; | |
| class MachineLoopInfo; | |
| /// This class wraps up a PBQP instance representing a register allocation | |
| /// problem, plus the structures necessary to map back from the PBQP solution | |
| /// to a register allocation solution. (i.e. The PBQP-node <--> vreg map, | |
| /// and the PBQP option <--> storage location map). | |
| class PBQPRAProblem { | |
| public: | |
| typedef SmallVector<unsigned, 16> AllowedSet; | |
| PBQP::Graph& getGraph() { return graph; } | |
| const PBQP::Graph& getGraph() const { return graph; } | |
| /// Record the mapping between the given virtual register and PBQP node, | |
| /// and the set of allowed pregs for the vreg. | |
| /// | |
| /// If you are extending | |
| /// PBQPBuilder you are unlikely to need this: Nodes and options for all | |
| /// vregs will already have been set up for you by the base class. | |
| template <typename AllowedRegsItr> | |
| void recordVReg(unsigned vreg, PBQP::Graph::NodeItr node, | |
| AllowedRegsItr arBegin, AllowedRegsItr arEnd) { | |
| assert(node2VReg.find(node) == node2VReg.end() && "Re-mapping node."); | |
| assert(vreg2Node.find(vreg) == vreg2Node.end() && "Re-mapping vreg."); | |
| assert(allowedSets[vreg].empty() && "vreg already has pregs."); | |
| node2VReg[node] = vreg; | |
| vreg2Node[vreg] = node; | |
| std::copy(arBegin, arEnd, std::back_inserter(allowedSets[vreg])); | |
| } | |
| /// Get the virtual register corresponding to the given PBQP node. | |
| unsigned getVRegForNode(PBQP::Graph::ConstNodeItr node) const; | |
| /// Get the PBQP node corresponding to the given virtual register. | |
| PBQP::Graph::NodeItr getNodeForVReg(unsigned vreg) const; | |
| /// Returns true if the given PBQP option represents a physical register, | |
| /// false otherwise. | |
| bool isPRegOption(unsigned vreg, unsigned option) const { | |
| // At present we only have spills or pregs, so anything that's not a | |
| // spill is a preg. (This might be extended one day to support remat). | |
| return !isSpillOption(vreg, option); | |
| } | |
| /// Returns true if the given PBQP option represents spilling, false | |
| /// otherwise. | |
| bool isSpillOption(unsigned vreg, unsigned option) const { | |
| // We hardcode option zero as the spill option. | |
| return option == 0; | |
| } | |
| /// Returns the allowed set for the given virtual register. | |
| const AllowedSet& getAllowedSet(unsigned vreg) const; | |
| /// Get PReg for option. | |
| unsigned getPRegForOption(unsigned vreg, unsigned option) const; | |
| private: | |
| typedef std::map<PBQP::Graph::ConstNodeItr, unsigned, | |
| PBQP::NodeItrComparator> Node2VReg; | |
| typedef DenseMap<unsigned, PBQP::Graph::NodeItr> VReg2Node; | |
| typedef DenseMap<unsigned, AllowedSet> AllowedSetMap; | |
| PBQP::Graph graph; | |
| Node2VReg node2VReg; | |
| VReg2Node vreg2Node; | |
| AllowedSetMap allowedSets; | |
| }; | |
| /// Builds PBQP instances to represent register allocation problems. Includes | |
| /// spill, interference and coalescing costs by default. You can extend this | |
| /// class to support additional constraints for your architecture. | |
| class PBQPBuilder { | |
| private: | |
| PBQPBuilder(const PBQPBuilder&) {} | |
| void operator=(const PBQPBuilder&) {} | |
| public: | |
| typedef std::set<unsigned> RegSet; | |
| /// Default constructor. | |
| PBQPBuilder() {} | |
| /// Clean up a PBQPBuilder. | |
| virtual ~PBQPBuilder() {} | |
| /// Build a PBQP instance to represent the register allocation problem for | |
| /// the given MachineFunction. | |
| virtual std::auto_ptr<PBQPRAProblem> build( | |
| MachineFunction *mf, | |
| const LiveIntervals *lis, | |
| const MachineLoopInfo *loopInfo, | |
| const RegSet &vregs); | |
| private: | |
| void addSpillCosts(PBQP::Vector &costVec, PBQP::PBQPNum spillCost); | |
| void addInterferenceCosts(PBQP::Matrix &costMat, | |
| const PBQPRAProblem::AllowedSet &vr1Allowed, | |
| const PBQPRAProblem::AllowedSet &vr2Allowed, | |
| const TargetRegisterInfo *tri); | |
| }; | |
| /// Extended builder which adds coalescing constraints to a problem. | |
| class PBQPBuilderWithCoalescing : public PBQPBuilder { | |
| public: | |
| /// Build a PBQP instance to represent the register allocation problem for | |
| /// the given MachineFunction. | |
| virtual std::auto_ptr<PBQPRAProblem> build( | |
| MachineFunction *mf, | |
| const LiveIntervals *lis, | |
| const MachineLoopInfo *loopInfo, | |
| const RegSet &vregs); | |
| private: | |
| void addPhysRegCoalesce(PBQP::Vector &costVec, unsigned pregOption, | |
| PBQP::PBQPNum benefit); | |
| void addVirtRegCoalesce(PBQP::Matrix &costMat, | |
| const PBQPRAProblem::AllowedSet &vr1Allowed, | |
| const PBQPRAProblem::AllowedSet &vr2Allowed, | |
| PBQP::PBQPNum benefit); | |
| }; | |
| FunctionPass* createPBQPRegisterAllocator(std::auto_ptr<PBQPBuilder> builder, | |
| char *customPassID=0); | |
| } | |
| #endif /* LLVM_CODEGEN_REGALLOCPBQP_H */ |