blob: 0a9a739071b033fcdf7f99b0a66681d72f512dc0 [file] [log] [blame]
Vikram S. Advedaae6992001-07-21 12:42:08 +00001// $Id$
2//***************************************************************************
3// File:
4// TargetMachine.cpp
5//
6// Purpose:
7//
8// History:
9// 7/12/01 - Vikram Adve - Created
10//**************************************************************************/
11
12
Vikram S. Advedaae6992001-07-21 12:42:08 +000013//*************************** User Include Files ***************************/
14
Chris Lattner7e583cf2001-07-21 20:58:30 +000015#include "llvm/CodeGen/TargetMachine.h"
Chris Lattner68498ce2001-07-21 23:24:48 +000016#include "llvm/DerivedTypes.h"
Vikram S. Advedaae6992001-07-21 12:42:08 +000017
Vikram S. Adve44a853c2001-07-28 04:09:37 +000018//************************ Exported Constants ******************************/
19
20
21// External object describing the machine instructions
22// Initialized only when the TargetMachine class is created
23// and reset when that class is destroyed.
24//
25const MachineInstrDescriptor* TargetInstrDescriptors = NULL;
26
Vikram S. Advebf242332001-08-28 23:09:36 +000027resourceId_t MachineResource::nextId = 0;
28
29//************************* Forward Declarations **************************/
30
31static cycles_t ComputeMinGap (const InstrRUsage& fromRU,
32 const InstrRUsage& toRU);
33
34static bool RUConflict (const vector<resourceId_t>& fromRVec,
35 const vector<resourceId_t>& fromRVec);
36
Vikram S. Advedaae6992001-07-21 12:42:08 +000037
38//************************ Class Implementations **************************/
39
Vikram S. Advedaae6992001-07-21 12:42:08 +000040//---------------------------------------------------------------------------
Vikram S. Adve44a853c2001-07-28 04:09:37 +000041// class TargetMachine
Vikram S. Advedaae6992001-07-21 12:42:08 +000042//
43// Purpose:
Vikram S. Adve44a853c2001-07-28 04:09:37 +000044// Machine description.
45//
Vikram S. Advedaae6992001-07-21 12:42:08 +000046//---------------------------------------------------------------------------
47
Vikram S. Adve44a853c2001-07-28 04:09:37 +000048
49// function TargetMachine::findOptimalStorageSize
50//
51// Purpose:
Vikram S. Adve44a853c2001-07-28 04:09:37 +000052// This default implementation assumes that all sub-word data items use
53// space equal to optSizeForSubWordData, and all other primitive data
54// items use space according to the type.
55//
Chris Lattner3a13c7e2001-08-27 15:50:41 +000056unsigned int TargetMachine::findOptimalStorageSize(const Type* ty) const {
57 switch(ty->getPrimitiveID()) {
58 case Type::BoolTyID:
59 case Type::UByteTyID:
60 case Type::SByteTyID:
61 case Type::UShortTyID:
62 case Type::ShortTyID:
63 return optSizeForSubWordData;
Vikram S. Advedaae6992001-07-21 12:42:08 +000064
Chris Lattner3a13c7e2001-08-27 15:50:41 +000065 default:
66 return DataLayout.getTypeSize(ty);
67 }
Vikram S. Advedaae6992001-07-21 12:42:08 +000068}
69
Vikram S. Adve44a853c2001-07-28 04:09:37 +000070
71//---------------------------------------------------------------------------
72// class MachineInstructionInfo
73// Interface to description of machine instructions
74//---------------------------------------------------------------------------
75
76
77/*ctor*/
78MachineInstrInfo::MachineInstrInfo(const MachineInstrDescriptor* _desc,
Vikram S. Advebf242332001-08-28 23:09:36 +000079 unsigned int _descSize,
80 unsigned int _numRealOpCodes)
81 : desc(_desc), descSize(_descSize), numRealOpCodes(_numRealOpCodes)
Vikram S. Adve44a853c2001-07-28 04:09:37 +000082{
83 assert(TargetInstrDescriptors == NULL && desc != NULL);
84 TargetInstrDescriptors = desc; // initialize global variable
85}
86
87
88/*dtor*/
89MachineInstrInfo::~MachineInstrInfo()
90{
91 TargetInstrDescriptors = NULL; // reset global variable
92}
93
94
95bool
96MachineInstrInfo::constantFitsInImmedField(MachineOpCode opCode,
97 int64_t intValue) const
98{
99 // First, check if opCode has an immed field.
100 bool isSignExtended;
101 uint64_t maxImmedValue = this->maxImmedConstant(opCode, isSignExtended);
102 if (maxImmedValue != 0)
103 {
104 // Now check if the constant fits
105 if (intValue <= (int64_t) maxImmedValue &&
106 intValue >= -((int64_t) maxImmedValue+1))
107 return true;
108 }
109
110 return false;
111}
112
Vikram S. Advebf242332001-08-28 23:09:36 +0000113
114//---------------------------------------------------------------------------
115// class MachineSchedInfo
116// Interface to machine description for instruction scheduling
117//---------------------------------------------------------------------------
118
119/*ctor*/
120MachineSchedInfo::MachineSchedInfo(int _numSchedClasses,
121 const MachineInstrInfo* _mii,
122 const InstrClassRUsage* _classRUsages,
123 const InstrRUsageDelta* _usageDeltas,
124 const InstrIssueDelta* _issueDeltas,
125 unsigned int _numUsageDeltas,
126 unsigned int _numIssueDeltas)
127 : numSchedClasses(_numSchedClasses),
128 mii(_mii),
129 classRUsages(_classRUsages),
130 usageDeltas(_usageDeltas),
131 issueDeltas(_issueDeltas),
132 numUsageDeltas(_numUsageDeltas),
133 numIssueDeltas(_numIssueDeltas)
134{
135}
136
137void
138MachineSchedInfo::initializeResources()
139{
140 assert(MAX_NUM_SLOTS >= (int) getMaxNumIssueTotal()
141 && "Insufficient slots for static data! Increase MAX_NUM_SLOTS");
142
143 // First, compute common resource usage info for each class because
144 // most instructions will probably behave the same as their class.
145 // Cannot allocate a vector of InstrRUsage so new each one.
146 //
147 vector<InstrRUsage> instrRUForClasses;
148 instrRUForClasses.resize(numSchedClasses);
149 for (InstrSchedClass sc=0; sc < numSchedClasses; sc++)
150 {
151 // instrRUForClasses.push_back(new InstrRUsage);
152 instrRUForClasses[sc].setMaxSlots(getMaxNumIssueTotal());
153 instrRUForClasses[sc] = classRUsages[sc];
154 }
155
156 computeInstrResources(instrRUForClasses);
157
158 computeIssueGaps(instrRUForClasses);
159}
160
161
162void
163MachineSchedInfo::computeInstrResources(const vector<InstrRUsage>& instrRUForClasses)
164{
165 int numOpCodes = mii->getNumRealOpCodes();
166 instrRUsages.resize(numOpCodes);
167
168 // First get the resource usage information from the class resource usages.
169 for (MachineOpCode op=0; op < numOpCodes; op++)
170 {
171 InstrSchedClass sc = getSchedClass(op);
172 assert(sc >= 0 && sc < numSchedClasses);
173 instrRUsages[op] = instrRUForClasses[sc];
174 }
175
176 // Now, modify the resource usages as specified in the deltas.
177 for (unsigned i=0; i < numUsageDeltas; i++)
178 {
179 MachineOpCode op = usageDeltas[i].opCode;
180 assert(op < numOpCodes);
181 instrRUsages[op].addUsageDelta(usageDeltas[i]);
182 }
183
184 // Then modify the issue restrictions as specified in the deltas.
185 for (unsigned i=0; i < numIssueDeltas; i++)
186 {
187 MachineOpCode op = issueDeltas[i].opCode;
188 assert(op < numOpCodes);
189 instrRUsages[issueDeltas[i].opCode].addIssueDelta(issueDeltas[i]);
190 }
191}
192
193
194void
195MachineSchedInfo::computeIssueGaps(const vector<InstrRUsage>& instrRUForClasses)
196{
197 int numOpCodes = mii->getNumRealOpCodes();
198 instrRUsages.resize(numOpCodes);
199
200 assert(numOpCodes < (1 << MAX_OPCODE_SIZE) - 1
201 && "numOpCodes invalid for implementation of class OpCodePair!");
202
203 // First, compute issue gaps between pairs of classes based on common
204 // resources usages for each class, because most instruction pairs will
205 // usually behave the same as their class.
206 //
207 int classPairGaps[numSchedClasses][numSchedClasses];
208 for (InstrSchedClass fromSC=0; fromSC < numSchedClasses; fromSC++)
209 for (InstrSchedClass toSC=0; toSC < numSchedClasses; toSC++)
210 {
211 int classPairGap = ComputeMinGap(instrRUForClasses[fromSC],
212 instrRUForClasses[toSC]);
213 classPairGaps[fromSC][toSC] = classPairGap;
214 }
215
216 // Now, for each pair of instructions, use the class pair gap if both
217 // instructions have identical resource usage as their respective classes.
218 // If not, recompute the gap for the pair from scratch.
219
220 longestIssueConflict = 0;
221
222 for (MachineOpCode fromOp=0; fromOp < numOpCodes; fromOp++)
223 for (MachineOpCode toOp=0; toOp < numOpCodes; toOp++)
224 {
225 int instrPairGap =
226 (instrRUsages[fromOp].sameAsClass && instrRUsages[toOp].sameAsClass)
227 ? classPairGaps[getSchedClass(fromOp)][getSchedClass(toOp)]
228 : ComputeMinGap(instrRUsages[fromOp], instrRUsages[toOp]);
229
230 if (instrPairGap > 0)
231 {
232 issueGaps[OpCodePair(fromOp,toOp)] = instrPairGap;
233 conflictLists[fromOp].push_back(toOp);
234 longestIssueConflict = max(longestIssueConflict, instrPairGap);
235 }
236 }
237}
238
239
240// Check if fromRVec and toRVec have *any* common entries.
241// Assume the vectors are sorted in increasing order.
242// Algorithm copied from function set_intersection() for sorted ranges (stl_algo.h).
243inline static bool
244RUConflict(const vector<resourceId_t>& fromRVec,
245 const vector<resourceId_t>& toRVec)
246{
247 bool commonElementFound = false;
248
249 unsigned fN = fromRVec.size(), tN = toRVec.size();
250 unsigned fi = 0, ti = 0;
251 while (fi < fN && ti < tN)
252 if (fromRVec[fi] < toRVec[ti])
253 ++fi;
254 else if (toRVec[ti] < fromRVec[fi])
255 ++ti;
256 else
257 {
258 commonElementFound = true;
259 break;
260 }
261
262 return commonElementFound;
263}
264
265
266static cycles_t
267ComputeMinGap(const InstrRUsage& fromRU, const InstrRUsage& toRU)
268{
269 cycles_t minGap = 0;
270
271 if (fromRU.numBubbles > 0)
272 minGap = fromRU.numBubbles;
273
274 if (minGap < fromRU.numCycles)
275 {
276 // only need to check from cycle `minGap' onwards
277 for (cycles_t gap=minGap; gap <= fromRU.numCycles-1; gap++)
278 {
279 // check if instr. #2 can start executing `gap' cycles after #1
280 // by checking for resource conflicts in each overlapping cycle
281 cycles_t numOverlap = min(fromRU.numCycles - gap, toRU.numCycles);
282 for (cycles_t c = 0; c <= numOverlap-1; c++)
283 if (RUConflict(fromRU.resourcesByCycle[gap + c],
284 toRU.resourcesByCycle[c]))
285 {// conflict found so minGap must be more than `gap'
286 minGap = gap+1;
287 break;
288 }
289 }
290 }
291
292 return minGap;
293}
294
Vikram S. Advedaae6992001-07-21 12:42:08 +0000295//---------------------------------------------------------------------------