Add bundle aware API for querying instruction properties and switch the code
[oota-llvm.git] / lib / Target / TargetInstrInfo.cpp
1 //===-- TargetInstrInfo.cpp - Target Instruction Information --------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the TargetInstrInfo class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/Target/TargetInstrInfo.h"
15 #include "llvm/Target/TargetRegisterInfo.h"
16 #include "llvm/CodeGen/SelectionDAGNodes.h"
17 #include "llvm/MC/MCAsmInfo.h"
18 #include "llvm/MC/MCInstrItineraries.h"
19 #include "llvm/Support/ErrorHandling.h"
20 #include <cctype>
21 using namespace llvm;
22
23 //===----------------------------------------------------------------------===//
24 //  TargetInstrInfo
25 //===----------------------------------------------------------------------===//
26
27 TargetInstrInfo::~TargetInstrInfo() {
28 }
29
30 const TargetRegisterClass*
31 TargetInstrInfo::getRegClass(const MCInstrDesc &MCID, unsigned OpNum,
32                              const TargetRegisterInfo *TRI) const {
33   if (OpNum >= MCID.getNumOperands())
34     return 0;
35
36   short RegClass = MCID.OpInfo[OpNum].RegClass;
37   if (MCID.OpInfo[OpNum].isLookupPtrRegClass())
38     return TRI->getPointerRegClass(RegClass);
39
40   // Instructions like INSERT_SUBREG do not have fixed register classes.
41   if (RegClass < 0)
42     return 0;
43
44   // Otherwise just look it up normally.
45   return TRI->getRegClass(RegClass);
46 }
47
48 unsigned
49 TargetInstrInfo::getNumMicroOps(const InstrItineraryData *ItinData,
50                                 const MachineInstr *MI) const {
51   if (!ItinData || ItinData->isEmpty())
52     return 1;
53
54   unsigned Class = MI->getDesc().getSchedClass();
55   unsigned UOps = ItinData->Itineraries[Class].NumMicroOps;
56   if (UOps)
57     return UOps;
58
59   // The # of u-ops is dynamically determined. The specific target should
60   // override this function to return the right number.
61   return 1;
62 }
63
64 int
65 TargetInstrInfo::getOperandLatency(const InstrItineraryData *ItinData,
66                              const MachineInstr *DefMI, unsigned DefIdx,
67                              const MachineInstr *UseMI, unsigned UseIdx) const {
68   if (!ItinData || ItinData->isEmpty())
69     return -1;
70
71   unsigned DefClass = DefMI->getDesc().getSchedClass();
72   unsigned UseClass = UseMI->getDesc().getSchedClass();
73   return ItinData->getOperandLatency(DefClass, DefIdx, UseClass, UseIdx);
74 }
75
76 int
77 TargetInstrInfo::getOperandLatency(const InstrItineraryData *ItinData,
78                                    SDNode *DefNode, unsigned DefIdx,
79                                    SDNode *UseNode, unsigned UseIdx) const {
80   if (!ItinData || ItinData->isEmpty())
81     return -1;
82
83   if (!DefNode->isMachineOpcode())
84     return -1;
85
86   unsigned DefClass = get(DefNode->getMachineOpcode()).getSchedClass();
87   if (!UseNode->isMachineOpcode())
88     return ItinData->getOperandCycle(DefClass, DefIdx);
89   unsigned UseClass = get(UseNode->getMachineOpcode()).getSchedClass();
90   return ItinData->getOperandLatency(DefClass, DefIdx, UseClass, UseIdx);
91 }
92
93 int TargetInstrInfo::getInstrLatency(const InstrItineraryData *ItinData,
94                                      const MachineInstr *MI,
95                                      unsigned *PredCost) const {
96   if (!ItinData || ItinData->isEmpty())
97     return 1;
98
99   return ItinData->getStageLatency(MI->getDesc().getSchedClass());
100 }
101
102 int TargetInstrInfo::getInstrLatency(const InstrItineraryData *ItinData,
103                                      SDNode *N) const {
104   if (!ItinData || ItinData->isEmpty())
105     return 1;
106
107   if (!N->isMachineOpcode())
108     return 1;
109
110   return ItinData->getStageLatency(get(N->getMachineOpcode()).getSchedClass());
111 }
112
113 bool TargetInstrInfo::hasLowDefLatency(const InstrItineraryData *ItinData,
114                                        const MachineInstr *DefMI,
115                                        unsigned DefIdx) const {
116   if (!ItinData || ItinData->isEmpty())
117     return false;
118
119   unsigned DefClass = DefMI->getDesc().getSchedClass();
120   int DefCycle = ItinData->getOperandCycle(DefClass, DefIdx);
121   return (DefCycle != -1 && DefCycle <= 1);
122 }
123
124 /// insertNoop - Insert a noop into the instruction stream at the specified
125 /// point.
126 void TargetInstrInfo::insertNoop(MachineBasicBlock &MBB,
127                                  MachineBasicBlock::iterator MI) const {
128   llvm_unreachable("Target didn't implement insertNoop!");
129 }
130
131
132 bool TargetInstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const {
133   if (!MI->isTerminator()) return false;
134
135   // Conditional branch is a special case.
136   if (MI->isBranch() && !MI->isBarrier())
137     return true;
138   if (!MI->isPredicable())
139     return true;
140   return !isPredicated(MI);
141 }
142
143
144 /// Measure the specified inline asm to determine an approximation of its
145 /// length.
146 /// Comments (which run till the next SeparatorString or newline) do not
147 /// count as an instruction.
148 /// Any other non-whitespace text is considered an instruction, with
149 /// multiple instructions separated by SeparatorString or newlines.
150 /// Variable-length instructions are not handled here; this function
151 /// may be overloaded in the target code to do that.
152 unsigned TargetInstrInfo::getInlineAsmLength(const char *Str,
153                                              const MCAsmInfo &MAI) const {
154
155
156   // Count the number of instructions in the asm.
157   bool atInsnStart = true;
158   unsigned Length = 0;
159   for (; *Str; ++Str) {
160     if (*Str == '\n' || strncmp(Str, MAI.getSeparatorString(),
161                                 strlen(MAI.getSeparatorString())) == 0)
162       atInsnStart = true;
163     if (atInsnStart && !std::isspace(*Str)) {
164       Length += MAI.getMaxInstLength();
165       atInsnStart = false;
166     }
167     if (atInsnStart && strncmp(Str, MAI.getCommentString(),
168                                strlen(MAI.getCommentString())) == 0)
169       atInsnStart = false;
170   }
171
172   return Length;
173 }