1 //===-- llvm/Target/Machine.h - General Target Information -------*- C++ -*-==//
3 // This file describes the general parts of a Target machine.
5 //===----------------------------------------------------------------------===//
7 #ifndef LLVM_TARGET_MACHINE_H
8 #define LLVM_TARGET_MACHINE_H
10 #include "llvm/Target/Data.h"
11 #include "llvm/Support/NonCopyable.h"
12 #include "llvm/Support/DataTypes.h"
19 struct MachineInstrDescriptor;
22 //---------------------------------------------------------------------------
23 // Data types used to define information about a single machine instruction
24 //---------------------------------------------------------------------------
26 typedef int MachineOpCode;
27 typedef int OpCodeMask;
28 typedef int InstrSchedClass;
30 static const unsigned MAX_OPCODE_SIZE = 16;
32 typedef long long cycles_t;
33 const cycles_t HUGE_LATENCY = ~((unsigned long long) 1 << sizeof(cycles_t)-1);
34 const cycles_t INVALID_LATENCY = -HUGE_LATENCY;
39 long val; // make long by concatenating two opcodes
40 OpCodePair(MachineOpCode op1, MachineOpCode op2)
41 : val((op1 < 0 || op2 < 0)?
42 -1 : (long)((((unsigned) op1) << MAX_OPCODE_SIZE) | (unsigned) op2)) {}
43 bool operator==(const OpCodePair& op) const {
47 OpCodePair(); // disable for now
51 template <> struct hash<OpCodePair> {
52 size_t operator()(const OpCodePair& pair) const {
53 return hash<long>()(pair.val);
58 // Global variable holding an array of descriptors for machine instructions.
59 // The actual object needs to be created separately for each target machine.
60 // This variable is initialized and reset by class MachineInstrInfo.
62 extern const MachineInstrDescriptor* TargetInstrDescriptors;
65 //---------------------------------------------------------------------------
66 // struct MachineInstrDescriptor:
67 // Predefined information about each machine instruction.
68 // Designed to initialized statically.
70 // class MachineInstructionInfo
71 // Interface to description of machine instructions
73 //---------------------------------------------------------------------------
76 const unsigned int M_NOP_FLAG = 1;
77 const unsigned int M_BRANCH_FLAG = 1 << 1;
78 const unsigned int M_CALL_FLAG = 1 << 2;
79 const unsigned int M_RET_FLAG = 1 << 3;
80 const unsigned int M_ARITH_FLAG = 1 << 4;
81 const unsigned int M_CC_FLAG = 1 << 6;
82 const unsigned int M_LOGICAL_FLAG = 1 << 6;
83 const unsigned int M_INT_FLAG = 1 << 7;
84 const unsigned int M_FLOAT_FLAG = 1 << 8;
85 const unsigned int M_CONDL_FLAG = 1 << 9;
86 const unsigned int M_LOAD_FLAG = 1 << 10;
87 const unsigned int M_PREFETCH_FLAG = 1 << 11;
88 const unsigned int M_STORE_FLAG = 1 << 12;
89 const unsigned int M_DUMMY_PHI_FLAG = 1 << 13;
92 struct MachineInstrDescriptor {
93 string opCodeString; // Assembly language mnemonic for the opcode.
94 int numOperands; // Number of args; -1 if variable #args
95 int resultPos; // Position of the result; -1 if no result
96 unsigned int maxImmedConst; // Largest +ve constant in IMMMED field or 0.
97 bool immedIsSignExtended; // Is IMMED field sign-extended? If so,
98 // smallest -ve value is -(maxImmedConst+1).
99 unsigned int numDelaySlots; // Number of delay slots after instruction
100 unsigned int latency; // Latency in machine cycles
101 InstrSchedClass schedClass; // enum identifying instr sched class
102 unsigned int iclass; // flags identifying machine instr class
106 class MachineInstrInfo : public NonCopyableV {
108 const MachineInstrDescriptor* desc; // raw array to allow static init'n
109 unsigned int descSize; // number of entries in the desc array
110 unsigned int numRealOpCodes; // number of non-dummy op codes
113 /*ctor*/ MachineInstrInfo(const MachineInstrDescriptor* _desc,
114 unsigned int _descSize,
115 unsigned int _numRealOpCodes);
116 /*dtor*/ virtual ~MachineInstrInfo();
118 unsigned int getNumRealOpCodes() const {
119 return numRealOpCodes;
122 unsigned int getNumTotalOpCodes() const {
126 const MachineInstrDescriptor& getDescriptor(MachineOpCode opCode) const {
127 assert(opCode >= 0 && opCode < (int) descSize);
131 int getNumOperands (MachineOpCode opCode) const {
132 return getDescriptor(opCode).numOperands;
135 int getResultPos (MachineOpCode opCode) const {
136 return getDescriptor(opCode).resultPos;
139 unsigned int getNumDelaySlots(MachineOpCode opCode) const {
140 return getDescriptor(opCode).numDelaySlots;
143 InstrSchedClass getSchedClass (MachineOpCode opCode) const {
144 return getDescriptor(opCode).schedClass;
148 // Query instruction class flags according to the machine-independent
149 // flags listed above.
151 unsigned int getIClass (MachineOpCode opCode) const {
152 return getDescriptor(opCode).iclass;
154 bool isNop (MachineOpCode opCode) const {
155 return getDescriptor(opCode).iclass & M_NOP_FLAG;
157 bool isBranch (MachineOpCode opCode) const {
158 return getDescriptor(opCode).iclass & M_BRANCH_FLAG;
160 bool isCall (MachineOpCode opCode) const {
161 return getDescriptor(opCode).iclass & M_CALL_FLAG;
163 bool isReturn (MachineOpCode opCode) const {
164 return getDescriptor(opCode).iclass & M_RET_FLAG;
166 bool isControlFlow (MachineOpCode opCode) const {
167 return getDescriptor(opCode).iclass & M_BRANCH_FLAG
168 || getDescriptor(opCode).iclass & M_CALL_FLAG
169 || getDescriptor(opCode).iclass & M_RET_FLAG;
171 bool isArith (MachineOpCode opCode) const {
172 return getDescriptor(opCode).iclass & M_RET_FLAG;
174 bool isCCInstr (MachineOpCode opCode) const {
175 return getDescriptor(opCode).iclass & M_CC_FLAG;
177 bool isLogical (MachineOpCode opCode) const {
178 return getDescriptor(opCode).iclass & M_LOGICAL_FLAG;
180 bool isIntInstr (MachineOpCode opCode) const {
181 return getDescriptor(opCode).iclass & M_INT_FLAG;
183 bool isFloatInstr (MachineOpCode opCode) const {
184 return getDescriptor(opCode).iclass & M_FLOAT_FLAG;
186 bool isConditional (MachineOpCode opCode) const {
187 return getDescriptor(opCode).iclass & M_CONDL_FLAG;
189 bool isLoad (MachineOpCode opCode) const {
190 return getDescriptor(opCode).iclass & M_LOAD_FLAG;
192 bool isPrefetch (MachineOpCode opCode) const {
193 return getDescriptor(opCode).iclass & M_PREFETCH_FLAG;
195 bool isLoadOrPrefetch (MachineOpCode opCode) const {
196 return getDescriptor(opCode).iclass & M_LOAD_FLAG
197 || getDescriptor(opCode).iclass & M_PREFETCH_FLAG;
199 bool isStore (MachineOpCode opCode) const {
200 return getDescriptor(opCode).iclass & M_STORE_FLAG;
202 bool isMemoryAccess (MachineOpCode opCode) const {
203 return getDescriptor(opCode).iclass & M_LOAD_FLAG
204 || getDescriptor(opCode).iclass & M_PREFETCH_FLAG
205 || getDescriptor(opCode).iclass & M_STORE_FLAG;
207 bool isDummyPhiInstr (MachineOpCode opCode) const {
208 return getDescriptor(opCode).iclass & M_DUMMY_PHI_FLAG;
212 // delete this later *******
213 bool isPhi(MachineOpCode opCode) { return isDummyPhiInstr(opCode); }
217 // Check if an instruction can be issued before its operands are ready,
218 // or if a subsequent instruction that uses its result can be issued
219 // before the results are ready.
220 // Default to true since most instructions on many architectures allow this.
222 virtual bool hasOperandInterlock(MachineOpCode opCode) const {
226 virtual bool hasResultInterlock(MachineOpCode opCode) const {
231 // Latencies for individual instructions and instruction pairs
233 virtual int minLatency (MachineOpCode opCode) const {
234 return getDescriptor(opCode).latency;
237 virtual int maxLatency (MachineOpCode opCode) const {
238 return getDescriptor(opCode).latency;
241 // Check if the specified constant fits in the immediate field
242 // of this machine instruction
244 virtual bool constantFitsInImmedField(MachineOpCode opCode,
245 int64_t intValue) const;
247 // Return the largest +ve constant that can be held in the IMMMED field
248 // of this machine instruction.
249 // isSignExtended is set to true if the value is sign-extended before use
250 // (this is true for all immediate fields in SPARC instructions).
251 // Return 0 if the instruction has no IMMED field.
253 virtual uint64_t maxImmedConstant(MachineOpCode opCode,
254 bool& isSignExtended) const {
255 isSignExtended = getDescriptor(opCode).immedIsSignExtended;
256 return getDescriptor(opCode).maxImmedConst;
261 //---------------------------------------------------------------------------
262 // class MachineResource
266 // Representation of a single machine resource used in specifying
267 // resource usages of machine instructions for scheduling.
268 //---------------------------------------------------------------------------
271 typedef unsigned int resourceId_t;
273 class MachineResource {
278 /*ctor*/ MachineResource(const string& resourceName)
279 : rname(resourceName), rid(nextId++) {}
282 static resourceId_t nextId;
283 MachineResource(); // disable
287 class CPUResource : public MachineResource {
289 int maxNumUsers; // MAXINT if no restriction
291 /*ctor*/ CPUResource(const string& rname, int maxUsers)
292 : MachineResource(rname), maxNumUsers(maxUsers) {}
296 //---------------------------------------------------------------------------
297 // struct InstrClassRUsage
298 // struct InstrRUsageDelta
299 // struct InstrIssueDelta
300 // struct InstrRUsage
303 // The first three are structures used to specify machine resource
304 // usages for each instruction in a machine description file:
305 // InstrClassRUsage : resource usages common to all instrs. in a class
306 // InstrRUsageDelta : add/delete resource usage for individual instrs.
307 // InstrIssueDelta : add/delete instr. issue info for individual instrs
309 // The last one (InstrRUsage) is the internal representation of
310 // instruction resource usage constructed from the above three.
311 //---------------------------------------------------------------------------
313 const int MAX_NUM_SLOTS = 32;
314 const int MAX_NUM_CYCLES = 32;
316 struct InstrClassRUsage {
317 InstrSchedClass schedClass;
320 // Issue restrictions common to instructions in this class
321 unsigned int maxNumIssue;
326 // Feasible slots to use for instructions in this class.
327 // The size of vector S[] is `numSlots'.
328 unsigned int numSlots;
329 unsigned int feasibleSlots[MAX_NUM_SLOTS];
331 // Resource usages common to instructions in this class.
332 // The size of vector V[] is `numRUEntries'.
333 unsigned int numRUEntries;
335 resourceId_t resourceId;
336 unsigned int startCycle;
341 struct InstrRUsageDelta {
342 MachineOpCode opCode;
343 resourceId_t resourceId;
344 unsigned int startCycle;
348 // Specify instruction issue restrictions for individual instructions
349 // that differ from the common rules for the class.
351 struct InstrIssueDelta {
352 MachineOpCode opCode;
360 /*ctor*/ InstrRUsage () {}
361 /*ctor*/ InstrRUsage (const InstrRUsage& instrRU);
362 InstrRUsage& operator= (const InstrRUsage& instrRU);
366 // Issue restrictions for this instruction
371 // Feasible slots to use for this instruction.
372 vector<bool> feasibleSlots;
374 // Resource usages for this instruction, with one resource vector per cycle.
376 vector<vector<resourceId_t> > resourcesByCycle;
379 // Conveniences for initializing this structure
380 InstrRUsage& operator= (const InstrClassRUsage& classRU);
381 void addIssueDelta (const InstrIssueDelta& delta);
382 void addUsageDelta (const InstrRUsageDelta& delta);
383 void setMaxSlots (int maxNumSlots);
385 friend class MachineSchedInfo; // give access to these functions
390 InstrRUsage::setMaxSlots(int maxNumSlots)
392 feasibleSlots.resize(maxNumSlots);
396 InstrRUsage::operator=(const InstrRUsage& instrRU)
398 sameAsClass = instrRU.sameAsClass;
399 isSingleIssue = instrRU.isSingleIssue;
400 breaksGroup = instrRU.breaksGroup;
401 numBubbles = instrRU.numBubbles;
402 feasibleSlots = instrRU.feasibleSlots;
403 numCycles = instrRU.numCycles;
404 resourcesByCycle = instrRU.resourcesByCycle;
409 InstrRUsage::InstrRUsage(const InstrRUsage& instrRU)
415 InstrRUsage::operator=(const InstrClassRUsage& classRU)
418 isSingleIssue = classRU.isSingleIssue;
419 breaksGroup = classRU.breaksGroup;
420 numBubbles = classRU.numBubbles;
422 for (unsigned i=0; i < classRU.numSlots; i++)
424 unsigned slot = classRU.feasibleSlots[i];
425 assert(slot < feasibleSlots.size() && "Invalid slot specified!");
426 this->feasibleSlots[slot] = true;
429 this->numCycles = classRU.totCycles;
430 this->resourcesByCycle.resize(this->numCycles);
432 for (unsigned i=0; i < classRU.numRUEntries; i++)
433 for (unsigned c=classRU.V[i].startCycle, NC = c + classRU.V[i].numCycles;
435 this->resourcesByCycle[c].push_back(classRU.V[i].resourceId);
437 // Sort each resource usage vector by resourceId_t to speed up conflict checking
438 for (unsigned i=0; i < this->resourcesByCycle.size(); i++)
439 sort(resourcesByCycle[i].begin(), resourcesByCycle[i].end());
446 InstrRUsage::addIssueDelta(const InstrIssueDelta& delta)
449 isSingleIssue = delta.isSingleIssue;
450 breaksGroup = delta.breaksGroup;
451 numBubbles = delta.numBubbles;
455 // Add the extra resource usage requirements specified in the delta.
456 // Note that a negative value of `numCycles' means one entry for that
457 // resource should be deleted for each cycle.
460 InstrRUsage::addUsageDelta(const InstrRUsageDelta& delta)
462 int NC = delta.numCycles;
464 this->sameAsClass = false;
466 // resize the resources vector if more cycles are specified
467 unsigned maxCycles = this->numCycles;
468 maxCycles = max(maxCycles, delta.startCycle + abs(NC) - 1);
469 if (maxCycles > this->numCycles)
471 this->resourcesByCycle.resize(maxCycles);
472 this->numCycles = maxCycles;
476 for (unsigned c=delta.startCycle, last=c+NC-1; c <= last; c++)
477 this->resourcesByCycle[c].push_back(delta.resourceId);
479 // Remove the resource from all NC cycles.
480 for (unsigned c=delta.startCycle, last=(c-NC)-1; c <= last; c++)
482 // Look for the resource backwards so we remove the last entry
483 // for that resource in each cycle.
484 vector<resourceId_t>& rvec = this->resourcesByCycle[c];
486 for (r = (int) rvec.size(); r >= 0; r--)
487 if (rvec[r] == delta.resourceId)
488 {// found last entry for the resource
489 rvec.erase(rvec.begin() + r);
492 assert(r >= 0 && "Resource to remove was unused in cycle c!");
497 //---------------------------------------------------------------------------
498 // class MachineSchedInfo
501 // Common interface to machine information for instruction scheduling
502 //---------------------------------------------------------------------------
504 class MachineSchedInfo : public NonCopyableV {
506 unsigned int maxNumIssueTotal;
507 int longestIssueConflict;
509 int branchMispredictPenalty; // 4 for SPARC IIi
510 int branchTargetUnknownPenalty; // 2 for SPARC IIi
511 int l1DCacheMissPenalty; // 7 or 9 for SPARC IIi
512 int l1ICacheMissPenalty; // ? for SPARC IIi
514 bool inOrderLoads; // true for SPARC IIi
515 bool inOrderIssue; // true for SPARC IIi
516 bool inOrderExec; // false for most architectures
517 bool inOrderRetire; // true for most architectures
520 inline const InstrRUsage& getInstrRUsage(MachineOpCode opCode) const {
521 assert(opCode >= 0 && opCode < (int) instrRUsages.size());
522 return instrRUsages[opCode];
524 inline const InstrClassRUsage&
525 getClassRUsage(const InstrSchedClass& sc) const {
526 assert(sc >= 0 && sc < numSchedClasses);
527 return classRUsages[sc];
531 /*ctor*/ MachineSchedInfo (int _numSchedClasses,
532 const MachineInstrInfo* _mii,
533 const InstrClassRUsage* _classRUsages,
534 const InstrRUsageDelta* _usageDeltas,
535 const InstrIssueDelta* _issueDeltas,
536 unsigned int _numUsageDeltas,
537 unsigned int _numIssueDeltas);
538 /*dtor*/ virtual ~MachineSchedInfo () {}
540 inline const MachineInstrInfo& getInstrInfo() const {
544 inline int getNumSchedClasses() const {
545 return numSchedClasses;
548 inline unsigned int getMaxNumIssueTotal() const {
549 return maxNumIssueTotal;
552 inline unsigned int getMaxIssueForClass(const InstrSchedClass& sc) const {
553 assert(sc >= 0 && sc < numSchedClasses);
554 return classRUsages[sc].maxNumIssue;
557 inline InstrSchedClass getSchedClass (MachineOpCode opCode) const {
558 return getInstrInfo().getSchedClass(opCode);
561 inline bool instrCanUseSlot (MachineOpCode opCode,
563 assert(s < getInstrRUsage(opCode).feasibleSlots.size() && "Invalid slot!");
564 return getInstrRUsage(opCode).feasibleSlots[s];
567 inline int getLongestIssueConflict () const {
568 return longestIssueConflict;
571 inline int getMinIssueGap (MachineOpCode fromOp,
572 MachineOpCode toOp) const {
573 hash_map<OpCodePair,int>::const_iterator
574 I = issueGaps.find(OpCodePair(fromOp, toOp));
575 return (I == issueGaps.end())? 0 : (*I).second;
578 inline const vector<MachineOpCode>*
579 getConflictList(MachineOpCode opCode) const {
580 hash_map<MachineOpCode,vector<MachineOpCode> >::const_iterator
581 I = conflictLists.find(opCode);
582 return (I == conflictLists.end())? NULL : & (*I).second;
585 inline bool isSingleIssue (MachineOpCode opCode) const {
586 return getInstrRUsage(opCode).isSingleIssue;
589 inline bool breaksIssueGroup (MachineOpCode opCode) const {
590 return getInstrRUsage(opCode).breaksGroup;
593 inline unsigned int numBubblesAfter (MachineOpCode opCode) const {
594 return getInstrRUsage(opCode).numBubbles;
598 virtual void initializeResources ();
601 void computeInstrResources(const vector<InstrRUsage>& instrRUForClasses);
602 void computeIssueGaps(const vector<InstrRUsage>& instrRUForClasses);
606 const MachineInstrInfo* mii;
607 const InstrClassRUsage* classRUsages; // raw array by sclass
608 const InstrRUsageDelta* usageDeltas; // raw array [1:numUsageDeltas]
609 const InstrIssueDelta* issueDeltas; // raw array [1:numIssueDeltas]
610 unsigned int numUsageDeltas;
611 unsigned int numIssueDeltas;
613 vector<InstrRUsage> instrRUsages; // indexed by opcode
614 hash_map<OpCodePair,int> issueGaps; // indexed by opcode pair
615 hash_map<MachineOpCode,vector<MachineOpCode> >
616 conflictLists; // indexed by opcode
621 //-----------------------------------------------------------------------------
622 // class MachineRegClassInfo
625 // Interface to description of machine register class (e.g., int reg class
626 // float reg class etc)
628 //--------------------------------------------------------------------------
633 class MachineRegClassInfo {
637 const unsigned RegClassID; // integer ID of a reg class
638 const unsigned NumOfAvailRegs; // # of avail for coloring -without SP etc.
639 const unsigned NumOfAllRegs; // # of all registers -including SP,g0 etc.
643 inline unsigned getRegClassID() const { return RegClassID; }
644 inline unsigned getNumOfAvailRegs() const { return NumOfAvailRegs; }
645 inline unsigned getNumOfAllRegs() const { return NumOfAllRegs; }
649 // This method should find a color which is not used by neighbors
650 // (i.e., a false position in IsColorUsedArr) and
651 virtual void colorIGNode(IGNode * Node, bool IsColorUsedArr[] ) const = 0;
654 MachineRegClassInfo(const unsigned ID, const unsigned NVR,
655 const unsigned NAR): RegClassID(ID), NumOfAvailRegs(NVR),
657 { } // empty constructor
664 //---------------------------------------------------------------------------
665 // class MachineRegInfo
668 // Interface to register info of target machine
670 //--------------------------------------------------------------------------
678 typedef hash_map<const MachineInstr *, AddedInstrns *> AddedInstrMapType;
680 // A vector of all machine register classes
681 typedef vector<const MachineRegClassInfo *> MachineRegClassArrayType;
684 class MachineRegInfo : public NonCopyableV {
688 MachineRegClassArrayType MachineRegClassArr;
694 inline unsigned int getNumOfRegClasses() const {
695 return MachineRegClassArr.size();
698 const MachineRegClassInfo *const getMachineRegClass(unsigned i) const {
699 return MachineRegClassArr[i];
703 virtual unsigned getRegClassIDOfValue (const Value *const Val) const = 0;
705 virtual void colorArgs(const Method *const Meth,
706 LiveRangeInfo & LRI) const = 0;
708 virtual void colorCallArgs(vector<const Instruction *> & CallInstrList,
710 AddedInstrMapType& AddedInstrMap ) const = 0;
712 virtual int getUnifiedRegNum(int RegClassID, int reg) const = 0;
714 virtual const string getUnifiedRegName(int reg) const = 0;
716 //virtual void printReg(const LiveRange *const LR) const =0;
726 //---------------------------------------------------------------------------
727 // class TargetMachine
730 // Primary interface to machine description for the target machine.
732 //---------------------------------------------------------------------------
734 class TargetMachine : public NonCopyableV {
736 const string TargetName;
737 const TargetData DataLayout; // Calculates type size & alignment
738 int optSizeForSubWordData;
739 int minMemOpWordSize;
740 int maxAtomicMemOpWordSize;
742 // Register information. This needs to be reorganized into a single class.
743 int zeroRegNum; // register that gives 0 if any (-1 if none)
746 TargetMachine(const string &targetname,
747 unsigned char PtrSize = 8, unsigned char PtrAl = 8,
748 unsigned char DoubleAl = 8, unsigned char FloatAl = 4,
749 unsigned char LongAl = 8, unsigned char IntAl = 4,
750 unsigned char ShortAl = 2, unsigned char ByteAl = 1)
751 : TargetName(targetname), DataLayout(targetname, PtrSize, PtrAl,
752 DoubleAl, FloatAl, LongAl, IntAl,
754 virtual ~TargetMachine() {}
756 virtual const MachineInstrInfo& getInstrInfo() const = 0;
758 virtual unsigned int findOptimalStorageSize (const Type* ty) const;
760 // This really should be in the register info class
761 virtual bool regsMayBeAliased (unsigned int regNum1,
762 unsigned int regNum2) const {
763 return (regNum1 == regNum2);
766 // compileMethod - This does everything neccesary to compile a method into the
767 // built in representation. This allows the target to have complete control
768 // over how it does compilation. This does not emit assembly or output
769 // machine code however, this is done later.
771 virtual bool compileMethod(Method *M) = 0;
773 // emitAssembly - Output assembly language code (a .s file) for the specified
774 // method. The specified method must have been compiled before this may be
777 virtual void emitAssembly(Method *M, ostream &OutStr) { /* todo */ }