LLVM API Documentation

Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

TargetSchedInfo.h

Go to the documentation of this file.
00001 //===- Target/TargetSchedInfo.h - Target Instruction Sched Info -*- C++ -*-===//
00002 // 
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file was developed by the LLVM research group and is distributed under
00006 // the University of Illinois Open Source License. See LICENSE.TXT for details.
00007 // 
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file describes the target machine to the instruction scheduler.
00011 //
00012 // NOTE: This file is currently sparc V9 specific.
00013 //
00014 //===----------------------------------------------------------------------===//
00015 
00016 #ifndef LLVM_TARGET_TARGETSCHEDINFO_H
00017 #define LLVM_TARGET_TARGETSCHEDINFO_H
00018 
00019 #include "llvm/Target/TargetInstrInfo.h"
00020 #include "llvm/ADT/hash_map"
00021 #include <string>
00022 
00023 namespace llvm {
00024 
00025 typedef long long cycles_t; 
00026 static const cycles_t HUGE_LATENCY = ~((long long) 1 << (sizeof(cycles_t)-2));
00027 static const cycles_t INVALID_LATENCY = -HUGE_LATENCY; 
00028 
00029 //---------------------------------------------------------------------------
00030 // class MachineResource 
00031 // class CPUResource
00032 // 
00033 // Purpose:
00034 //   Representation of a single machine resource used in specifying
00035 //   resource usages of machine instructions for scheduling.
00036 //---------------------------------------------------------------------------
00037 
00038 
00039 typedef unsigned resourceId_t;
00040 
00041 struct CPUResource {
00042   const std::string rname;
00043   resourceId_t rid;
00044   int maxNumUsers;   // MAXINT if no restriction
00045   
00046   CPUResource(const std::string& resourceName, int maxUsers);
00047   static CPUResource* getCPUResource(resourceId_t id);
00048 private:
00049   static resourceId_t nextId;
00050 };
00051 
00052 
00053 //---------------------------------------------------------------------------
00054 // struct InstrClassRUsage
00055 // struct InstrRUsageDelta 
00056 // struct InstrIssueDelta 
00057 // struct InstrRUsage 
00058 // 
00059 // Purpose:
00060 //   The first three are structures used to specify machine resource 
00061 //   usages for each instruction in a machine description file:
00062 //    InstrClassRUsage : resource usages common to all instrs. in a class
00063 //    InstrRUsageDelta : add/delete resource usage for individual instrs. 
00064 //    InstrIssueDelta  : add/delete instr. issue info for individual instrs 
00065 //   
00066 //   The last one (InstrRUsage) is the internal representation of
00067 //   instruction resource usage constructed from the above three.
00068 //---------------------------------------------------------------------------
00069 
00070 const int MAX_NUM_SLOTS  = 32;
00071 const int MAX_NUM_CYCLES = 32;
00072 
00073 struct InstrClassRUsage {
00074   InstrSchedClass schedClass;
00075   int   totCycles;
00076   
00077   // Issue restrictions common to instructions in this class
00078   unsigned      maxNumIssue;
00079   bool          isSingleIssue;
00080   bool          breaksGroup;
00081   cycles_t      numBubbles;
00082   
00083   // Feasible slots to use for instructions in this class.
00084   // The size of vector S[] is `numSlots'.
00085   unsigned      numSlots;
00086   unsigned      feasibleSlots[MAX_NUM_SLOTS];
00087   
00088   // Resource usages common to instructions in this class.
00089   // The size of vector V[] is `numRUEntries'.
00090   unsigned      numRUEntries;
00091   struct {
00092     resourceId_t resourceId;
00093     unsigned    startCycle;
00094     int         numCycles;
00095   } V[MAX_NUM_CYCLES];
00096 };
00097 
00098 struct InstrRUsageDelta {
00099   MachineOpCode opCode;
00100   resourceId_t  resourceId;
00101   unsigned      startCycle;
00102   int   numCycles;
00103 };
00104 
00105 // Specify instruction issue restrictions for individual instructions
00106 // that differ from the common rules for the class.
00107 // 
00108 struct InstrIssueDelta {
00109   MachineOpCode opCode;
00110   bool    isSingleIssue;
00111   bool    breaksGroup;
00112   cycles_t  numBubbles;
00113 };
00114 
00115 
00116 struct InstrRUsage {
00117   bool    sameAsClass;
00118   
00119   // Issue restrictions for this instruction
00120   bool    isSingleIssue;
00121   bool    breaksGroup;
00122   cycles_t  numBubbles;
00123   
00124   // Feasible slots to use for this instruction.
00125   std::vector<bool> feasibleSlots;
00126   
00127   // Resource usages for this instruction, with one resource vector per cycle.
00128   cycles_t  numCycles;
00129   std::vector<std::vector<resourceId_t> > resourcesByCycle;
00130   
00131 private:
00132   // Conveniences for initializing this structure
00133   void setTo(const InstrClassRUsage& classRU);
00134 
00135   void addIssueDelta(const InstrIssueDelta& delta) {
00136     sameAsClass = false;
00137     isSingleIssue = delta.isSingleIssue;
00138     breaksGroup = delta.breaksGroup;
00139     numBubbles = delta.numBubbles;
00140   }
00141 
00142   void addUsageDelta  (const InstrRUsageDelta& delta);
00143   void setMaxSlots  (int maxNumSlots) {
00144     feasibleSlots.resize(maxNumSlots);
00145   }
00146   
00147   friend class TargetSchedInfo; // give access to these functions
00148 };
00149 
00150 
00151 //---------------------------------------------------------------------------
00152 /// TargetSchedInfo - Common interface to machine information for 
00153 /// instruction scheduling
00154 ///
00155 class TargetSchedInfo {
00156 public:
00157   const TargetMachine& target;
00158   
00159   unsigned maxNumIssueTotal;
00160   int longestIssueConflict;
00161   
00162 protected:
00163   inline const InstrRUsage& getInstrRUsage(MachineOpCode opCode) const {
00164     assert(opCode >= 0 && opCode < (int) instrRUsages.size());
00165     return instrRUsages[opCode];
00166   }
00167   const InstrClassRUsage& getClassRUsage(const InstrSchedClass& sc) const {
00168     assert(sc < numSchedClasses);
00169     return classRUsages[sc];
00170   }
00171 
00172 private:
00173   TargetSchedInfo(const TargetSchedInfo &);  // DO NOT IMPLEMENT
00174   void operator=(const TargetSchedInfo &);  // DO NOT IMPLEMENT
00175 public:
00176   /*ctor*/     TargetSchedInfo  (const TargetMachine& tgt,
00177                                          int                  _numSchedClasses,
00178            const InstrClassRUsage* _classRUsages,
00179            const InstrRUsageDelta* _usageDeltas,
00180            const InstrIssueDelta*  _issueDeltas,
00181            unsigned _numUsageDeltas,
00182            unsigned _numIssueDeltas);
00183   /*dtor*/ virtual ~TargetSchedInfo() {}
00184   
00185   inline const TargetInstrInfo& getInstrInfo() const {
00186     return *mii;
00187   }
00188   
00189   inline int    getNumSchedClasses()  const {
00190     return numSchedClasses;
00191   }  
00192   
00193   inline  unsigned getMaxNumIssueTotal() const {
00194     return maxNumIssueTotal;
00195   }
00196   
00197   inline  unsigned getMaxIssueForClass(const InstrSchedClass& sc) const {
00198     assert(sc < numSchedClasses);
00199     return classRUsages[sc].maxNumIssue;
00200   }
00201 
00202   inline InstrSchedClass getSchedClass  (MachineOpCode opCode) const {
00203     return getInstrInfo().getSchedClass(opCode);
00204   } 
00205   
00206   inline  bool  instrCanUseSlot   (MachineOpCode opCode,
00207            unsigned s) const {
00208     assert(s < getInstrRUsage(opCode).feasibleSlots.size() && "Invalid slot!");
00209     return getInstrRUsage(opCode).feasibleSlots[s];
00210   }
00211   
00212   inline int  getLongestIssueConflict () const {
00213     return longestIssueConflict;
00214   }
00215 
00216   inline  int   getMinIssueGap    (MachineOpCode fromOp,
00217            MachineOpCode toOp)   const {
00218     assert(fromOp < (int) issueGaps.size());
00219     const std::vector<int>& toGaps = issueGaps[fromOp];
00220     return (toOp < (int) toGaps.size())? toGaps[toOp] : 0;
00221   }
00222 
00223   inline const std::vector<MachineOpCode>&
00224     getConflictList(MachineOpCode opCode) const {
00225     assert(opCode < (int) conflictLists.size());
00226     return conflictLists[opCode];
00227   }
00228 
00229   inline  bool  isSingleIssue   (MachineOpCode opCode) const {
00230     return getInstrRUsage(opCode).isSingleIssue;
00231   }
00232   
00233   inline  bool  breaksIssueGroup  (MachineOpCode opCode) const {
00234     return getInstrRUsage(opCode).breaksGroup;
00235   }
00236   
00237   inline  unsigned numBubblesAfter  (MachineOpCode opCode) const {
00238     return getInstrRUsage(opCode).numBubbles;
00239   }
00240   
00241   inline unsigned getCPUResourceNum(int rd)const{
00242     for(unsigned i=0;i<resourceNumVector.size();i++){
00243       if(resourceNumVector[i].first == rd) return resourceNumVector[i].second;
00244     }
00245     assert( 0&&"resource not found");
00246     return 0;
00247   }
00248   
00249 
00250 protected:
00251   virtual void  initializeResources ();
00252   
00253 private:
00254   void computeInstrResources(const std::vector<InstrRUsage>& instrRUForClasses);
00255   void computeIssueGaps(const std::vector<InstrRUsage>& instrRUForClasses);
00256   
00257   void setGap(int gap, MachineOpCode fromOp, MachineOpCode toOp) {
00258     std::vector<int>& toGaps = issueGaps[fromOp];
00259     if (toOp >= (int) toGaps.size())
00260       toGaps.resize(toOp+1);
00261     toGaps[toOp] = gap;
00262   }
00263   
00264 public:
00265   std::vector<std::pair<int,int> > resourceNumVector;
00266   
00267 protected:
00268   unsigned             numSchedClasses;
00269   const TargetInstrInfo*   mii;
00270   const InstrClassRUsage*  classRUsages;        // raw array by sclass
00271   const InstrRUsageDelta*  usageDeltas;         // raw array [1:numUsageDeltas]
00272   const InstrIssueDelta*   issueDeltas;         // raw array [1:numIssueDeltas]
00273   unsigned       numUsageDeltas;
00274   unsigned       numIssueDeltas;
00275   
00276   std::vector<InstrRUsage> instrRUsages;    // indexed by opcode
00277   std::vector<std::vector<int> > issueGaps; // indexed by [opcode1][opcode2]
00278   std::vector<std::vector<MachineOpCode> >
00279          conflictLists;   // indexed by [opcode]
00280 
00281 
00282   friend class ModuloSchedulingPass;
00283   friend class MSSchedule;
00284   
00285 };
00286 
00287 } // End llvm namespace
00288 
00289 #endif