Precompute a bit vector of register sub-classes.
[oota-llvm.git] / utils / TableGen / CodeGenRegisters.h
index 7a51001cd102063ce5848ab206cce399e268998d..ae8f0d4abdf077d091f4e9188d73b9cb69ac7702 100644 (file)
@@ -1,10 +1,10 @@
 //===- CodeGenRegisters.h - Register and RegisterClass Info -----*- C++ -*-===//
-// 
+//
 //                     The LLVM Compiler Infrastructure
 //
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-// 
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
 //===----------------------------------------------------------------------===//
 //
 // This file defines structures to encapsulate information gleaned from the
 #ifndef CODEGEN_REGISTERS_H
 #define CODEGEN_REGISTERS_H
 
+#include "Record.h"
+#include "SetTheory.h"
+#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SetVector.h"
+#include <cstdlib>
+#include <map>
 #include <string>
+#include <set>
+#include <vector>
 
 namespace llvm {
-  class Record;
+  class CodeGenRegBank;
 
   /// CodeGenRegister - Represents a register definition.
   struct CodeGenRegister {
     Record *TheDef;
+    unsigned EnumValue;
+    unsigned CostPerUse;
+
+    // Map SubRegIndex -> Register.
+    typedef std::map<Record*, CodeGenRegister*, LessRecord> SubRegMap;
+
+    CodeGenRegister(Record *R, unsigned Enum);
+
+    const std::string &getName() const;
+
+    // Get a map of sub-registers computed lazily.
+    // This includes unique entries for all sub-sub-registers.
+    const SubRegMap &getSubRegs(CodeGenRegBank&);
+
+    const SubRegMap &getSubRegs() const {
+      assert(SubRegsComplete && "Must precompute sub-registers");
+      return SubRegs;
+    }
+
+    // Add sub-registers to OSet following a pre-order defined by the .td file.
+    void addSubRegsPreOrder(SetVector<CodeGenRegister*> &OSet) const;
+
+    // List of super-registers in topological order, small to large.
+    typedef std::vector<CodeGenRegister*> SuperRegList;
+
+    // Get the list of super-registers.
+    // This is only valid after computeDerivedInfo has visited all registers.
+    const SuperRegList &getSuperRegs() const {
+      assert(SubRegsComplete && "Must precompute sub-registers");
+      return SuperRegs;
+    }
+
+    // Order CodeGenRegister pointers by EnumValue.
+    struct Less {
+      bool operator()(const CodeGenRegister *A,
+                      const CodeGenRegister *B) const {
+        return A->EnumValue < B->EnumValue;
+      }
+    };
+
+    // Canonically ordered set.
+    typedef std::set<const CodeGenRegister*, Less> Set;
+
+  private:
+    bool SubRegsComplete;
+    SubRegMap SubRegs;
+    SuperRegList SuperRegs;
+  };
+
+
+  class CodeGenRegisterClass {
+    CodeGenRegister::Set Members;
+    const std::vector<Record*> *Elements;
+    std::vector<SmallVector<Record*, 16> > AltOrders;
+    // Bit mask of sub-classes including this, indexed by their EnumValue.
+    BitVector SubClasses;
+  public:
+    Record *TheDef;
+    unsigned EnumValue;
+    std::string Namespace;
+    std::vector<MVT::SimpleValueType> VTs;
+    unsigned SpillSize;
+    unsigned SpillAlignment;
+    int CopyCost;
+    bool Allocatable;
+    // Map SubRegIndex -> RegisterClass
+    DenseMap<Record*,Record*> SubRegClasses;
+    std::string AltOrderSelect;
+
     const std::string &getName() const;
-    
-    CodeGenRegister(Record *R) : TheDef(R) {}
+    const std::vector<MVT::SimpleValueType> &getValueTypes() const {return VTs;}
+    unsigned getNumValueTypes() const { return VTs.size(); }
+
+    MVT::SimpleValueType getValueTypeNum(unsigned VTNum) const {
+      if (VTNum < VTs.size())
+        return VTs[VTNum];
+      assert(0 && "VTNum greater than number of ValueTypes in RegClass!");
+      abort();
+    }
+
+    // Return true if this this class contains the register.
+    bool contains(const CodeGenRegister*) const;
+
+    // Returns true if RC is a subclass.
+    // RC is a sub-class of this class if it is a valid replacement for any
+    // instruction operand where a register of this classis required. It must
+    // satisfy these conditions:
+    //
+    // 1. All RC registers are also in this.
+    // 2. The RC spill size must not be smaller than our spill size.
+    // 3. RC spill alignment must be compatible with ours.
+    //
+    bool hasSubClass(const CodeGenRegisterClass *RC) const;
+
+    // Returns an ordered list of class members.
+    // The order of registers is the same as in the .td file.
+    // No = 0 is the default allocation order, No = 1 is the first alternative.
+    ArrayRef<Record*> getOrder(unsigned No = 0) const {
+      if (No == 0)
+        return *Elements;
+      else
+        return AltOrders[No - 1];
+    }
+
+    // Return the total number of allocation orders available.
+    unsigned getNumOrders() const { return 1 + AltOrders.size(); }
+
+    CodeGenRegisterClass(CodeGenRegBank&, Record *R);
+
+    // Called by CodeGenRegBank::CodeGenRegBank().
+    static void computeSubClasses(ArrayRef<CodeGenRegisterClass*>);
   };
 
+  // CodeGenRegBank - Represent a target's registers and the relations between
+  // them.
+  class CodeGenRegBank {
+    RecordKeeper &Records;
+    SetTheory Sets;
+
+    std::vector<Record*> SubRegIndices;
+    unsigned NumNamedIndices;
+    std::vector<CodeGenRegister*> Registers;
+    DenseMap<Record*, CodeGenRegister*> Def2Reg;
+
+    std::vector<CodeGenRegisterClass*> RegClasses;
+    DenseMap<Record*, CodeGenRegisterClass*> Def2RC;
+
+    // Composite SubRegIndex instances.
+    // Map (SubRegIndex, SubRegIndex) -> SubRegIndex.
+    typedef DenseMap<std::pair<Record*, Record*>, Record*> CompositeMap;
+    CompositeMap Composite;
+
+    // Populate the Composite map from sub-register relationships.
+    void computeComposites();
+
+  public:
+    CodeGenRegBank(RecordKeeper&);
+
+    SetTheory &getSets() { return Sets; }
+
+    // Sub-register indices. The first NumNamedIndices are defined by the user
+    // in the .td files. The rest are synthesized such that all sub-registers
+    // have a unique name.
+    const std::vector<Record*> &getSubRegIndices() { return SubRegIndices; }
+    unsigned getNumNamedIndices() { return NumNamedIndices; }
+
+    // Map a SubRegIndex Record to its enum value.
+    unsigned getSubRegIndexNo(Record *idx);
+
+    // Find or create a sub-register index representing the A+B composition.
+    Record *getCompositeSubRegIndex(Record *A, Record *B, bool create = false);
+
+    const std::vector<CodeGenRegister*> &getRegisters() { return Registers; }
+
+    // Find a register from its Record def.
+    CodeGenRegister *getReg(Record*);
+
+    ArrayRef<CodeGenRegisterClass*> getRegClasses() const {
+      return RegClasses;
+    }
+
+    // Find a register class from its def.
+    CodeGenRegisterClass *getRegClass(Record*);
+
+    /// getRegisterClassForRegister - Find the register class that contains the
+    /// specified physical register.  If the register is not in a register
+    /// class, return null. If the register is in multiple classes, and the
+    /// classes have a superset-subset relationship and the same set of types,
+    /// return the superclass.  Otherwise return null.
+    const CodeGenRegisterClass* getRegClassForRegister(Record *R);
 
-  struct CodeGenRegisterClass {
+    // Computed derived records such as missing sub-register indices.
+    void computeDerivedInfo();
 
+    // Compute full overlap sets for every register. These sets include the
+    // rarely used aliases that are neither sub nor super-registers.
+    //
+    // Map[R1].count(R2) is reflexive and symmetric, but not transitive.
+    //
+    // If R1 is a sub-register of R2, Map[R1] is a subset of Map[R2].
+    void computeOverlaps(std::map<const CodeGenRegister*,
+                                  CodeGenRegister::Set> &Map);
   };
 }