LLVM API Documentation

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 CycleCount_t;
00026 static const CycleCount_t HUGE_LATENCY = ~((long long) 1 << (sizeof(CycleCount_t)-2));
00027 static const CycleCount_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   CycleCount_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   CycleCount_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   CycleCount_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   CycleCount_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   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   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 ModuloSchedulingSBPass;
00284   friend class MSSchedule;
00285   friend class MSScheduleSB;
00286   friend class MSchedGraphSB;
00287 
00288 };
00289 
00290 } // End llvm namespace
00291 
00292 #endif