LLVM API Documentation

RegAllocPBQP.h
Go to the documentation of this file.
00001 //===-- RegAllocPBQP.h ------------------------------------------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file defines the PBQPBuilder interface, for classes which build PBQP
00011 // instances to represent register allocation problems, and the RegAllocPBQP
00012 // interface.
00013 //
00014 //===----------------------------------------------------------------------===//
00015 
00016 #ifndef LLVM_CODEGEN_REGALLOCPBQP_H
00017 #define LLVM_CODEGEN_REGALLOCPBQP_H
00018 
00019 #include "llvm/ADT/DenseMap.h"
00020 #include "llvm/ADT/SmallVector.h"
00021 #include "llvm/CodeGen/MachineFunctionPass.h"
00022 #include "llvm/CodeGen/PBQP/RegAllocSolver.h"
00023 #include <map>
00024 #include <set>
00025 
00026 namespace llvm {
00027 
00028   class LiveIntervals;
00029   class MachineBlockFrequencyInfo;
00030   class MachineFunction;
00031   class TargetRegisterInfo;
00032 
00033   typedef PBQP::RegAlloc::Graph PBQPRAGraph;
00034 
00035   /// This class wraps up a PBQP instance representing a register allocation
00036   /// problem, plus the structures necessary to map back from the PBQP solution
00037   /// to a register allocation solution. (i.e. The PBQP-node <--> vreg map,
00038   /// and the PBQP option <--> storage location map).
00039   class PBQPRAProblem {
00040   public:
00041 
00042     typedef SmallVector<unsigned, 16> AllowedSet;
00043 
00044     PBQPRAGraph& getGraph() { return graph; }
00045 
00046     const PBQPRAGraph& getGraph() const { return graph; }
00047 
00048     /// Record the mapping between the given virtual register and PBQP node,
00049     /// and the set of allowed pregs for the vreg.
00050     ///
00051     /// If you are extending
00052     /// PBQPBuilder you are unlikely to need this: Nodes and options for all
00053     /// vregs will already have been set up for you by the base class.
00054     template <typename AllowedRegsItr>
00055     void recordVReg(unsigned vreg, PBQPRAGraph::NodeId nodeId,
00056                     AllowedRegsItr arBegin, AllowedRegsItr arEnd) {
00057       assert(node2VReg.find(nodeId) == node2VReg.end() && "Re-mapping node.");
00058       assert(vreg2Node.find(vreg) == vreg2Node.end() && "Re-mapping vreg.");
00059       assert(allowedSets[vreg].empty() && "vreg already has pregs.");
00060 
00061       node2VReg[nodeId] = vreg;
00062       vreg2Node[vreg] = nodeId;
00063       std::copy(arBegin, arEnd, std::back_inserter(allowedSets[vreg]));
00064     }
00065 
00066     /// Get the virtual register corresponding to the given PBQP node.
00067     unsigned getVRegForNode(PBQPRAGraph::NodeId nodeId) const;
00068 
00069     /// Get the PBQP node corresponding to the given virtual register.
00070     PBQPRAGraph::NodeId getNodeForVReg(unsigned vreg) const;
00071 
00072     /// Returns true if the given PBQP option represents a physical register,
00073     /// false otherwise.
00074     bool isPRegOption(unsigned vreg, unsigned option) const {
00075       // At present we only have spills or pregs, so anything that's not a
00076       // spill is a preg. (This might be extended one day to support remat).
00077       return !isSpillOption(vreg, option);
00078     }
00079 
00080     /// Returns true if the given PBQP option represents spilling, false
00081     /// otherwise.
00082     bool isSpillOption(unsigned vreg, unsigned option) const {
00083       // We hardcode option zero as the spill option.
00084       return option == 0;
00085     }
00086 
00087     /// Returns the allowed set for the given virtual register.
00088     const AllowedSet& getAllowedSet(unsigned vreg) const;
00089 
00090     /// Get PReg for option.
00091     unsigned getPRegForOption(unsigned vreg, unsigned option) const;
00092 
00093   private:
00094 
00095     typedef std::map<PBQPRAGraph::NodeId, unsigned>  Node2VReg;
00096     typedef DenseMap<unsigned, PBQPRAGraph::NodeId> VReg2Node;
00097     typedef DenseMap<unsigned, AllowedSet> AllowedSetMap;
00098 
00099     PBQPRAGraph graph;
00100     Node2VReg node2VReg;
00101     VReg2Node vreg2Node;
00102 
00103     AllowedSetMap allowedSets;
00104 
00105   };
00106 
00107   /// Builds PBQP instances to represent register allocation problems. Includes
00108   /// spill, interference and coalescing costs by default. You can extend this
00109   /// class to support additional constraints for your architecture.
00110   class PBQPBuilder {
00111   private:
00112     PBQPBuilder(const PBQPBuilder&) LLVM_DELETED_FUNCTION;
00113     void operator=(const PBQPBuilder&) LLVM_DELETED_FUNCTION;
00114   public:
00115 
00116     typedef std::set<unsigned> RegSet;
00117 
00118     /// Default constructor.
00119     PBQPBuilder() {}
00120 
00121     /// Clean up a PBQPBuilder.
00122     virtual ~PBQPBuilder() {}
00123 
00124     /// Build a PBQP instance to represent the register allocation problem for
00125     /// the given MachineFunction.
00126     virtual std::unique_ptr<PBQPRAProblem>
00127     build(MachineFunction *mf, const LiveIntervals *lis,
00128           const MachineBlockFrequencyInfo *mbfi, const RegSet &vregs);
00129 
00130   private:
00131 
00132     void addSpillCosts(PBQP::Vector &costVec, PBQP::PBQPNum spillCost);
00133 
00134     void addInterferenceCosts(PBQP::Matrix &costMat,
00135                               const PBQPRAProblem::AllowedSet &vr1Allowed,
00136                               const PBQPRAProblem::AllowedSet &vr2Allowed,
00137                               const TargetRegisterInfo *tri);
00138   };
00139 
00140   /// Extended builder which adds coalescing constraints to a problem.
00141   class PBQPBuilderWithCoalescing : public PBQPBuilder {
00142   public:
00143 
00144     /// Build a PBQP instance to represent the register allocation problem for
00145     /// the given MachineFunction.
00146     std::unique_ptr<PBQPRAProblem> build(MachineFunction *mf,
00147                                          const LiveIntervals *lis,
00148                                          const MachineBlockFrequencyInfo *mbfi,
00149                                          const RegSet &vregs) override;
00150 
00151   private:
00152 
00153     void addPhysRegCoalesce(PBQP::Vector &costVec, unsigned pregOption,
00154                             PBQP::PBQPNum benefit);
00155 
00156     void addVirtRegCoalesce(PBQP::Matrix &costMat,
00157                             const PBQPRAProblem::AllowedSet &vr1Allowed,
00158                             const PBQPRAProblem::AllowedSet &vr2Allowed,
00159                             PBQP::PBQPNum benefit);
00160   };
00161 
00162   FunctionPass *
00163   createPBQPRegisterAllocator(std::unique_ptr<PBQPBuilder> builder,
00164                               char *customPassID = nullptr);
00165 }
00166 
00167 #endif /* LLVM_CODEGEN_REGALLOCPBQP_H */