blob: 8ac8cd9716e458940a92765d20fc1149dfccea13 [file] [log] [blame]
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001//===- Record.cpp - Record implementation ---------------------------------===//
Misha Brukman650ba8e2005-04-22 00:00:37 +00002//
John Criswelld3032032003-10-20 20:20:30 +00003// The LLVM Compiler Infrastructure
4//
Chris Lattner8adcd9f2007-12-29 20:37:13 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Misha Brukman650ba8e2005-04-22 00:00:37 +00007//
John Criswelld3032032003-10-20 20:20:30 +00008//===----------------------------------------------------------------------===//
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00009//
Chris Lattner51ffbf12006-03-31 21:53:49 +000010// Implement the tablegen record classes.
Chris Lattnerf5bd1b72003-10-05 19:27:59 +000011//
12//===----------------------------------------------------------------------===//
13
14#include "Record.h"
Michael J. Spencer447762d2010-11-29 18:16:10 +000015#include "llvm/Support/DataTypes.h"
Daniel Dunbar38a22bf2009-07-03 00:10:29 +000016#include "llvm/Support/Format.h"
Chris Lattner8b9ecda2007-11-20 22:25:16 +000017#include "llvm/ADT/StringExtras.h"
Duraid Madina14492af2005-12-26 05:08:55 +000018
Chris Lattner68478662004-08-01 03:55:39 +000019using namespace llvm;
Chris Lattnerf5bd1b72003-10-05 19:27:59 +000020
21//===----------------------------------------------------------------------===//
22// Type implementations
23//===----------------------------------------------------------------------===//
24
Daniel Dunbar38a22bf2009-07-03 00:10:29 +000025void RecTy::dump() const { print(errs()); }
Chris Lattnerf5bd1b72003-10-05 19:27:59 +000026
27Init *BitRecTy::convertValue(BitsInit *BI) {
28 if (BI->getNumBits() != 1) return 0; // Only accept if just one bit!
29 return BI->getBit(0);
30}
31
32bool BitRecTy::baseClassOf(const BitsRecTy *RHS) const {
33 return RHS->getNumBits() == 1;
34}
35
36Init *BitRecTy::convertValue(IntInit *II) {
Dan Gohmanca0546f2008-10-17 01:33:43 +000037 int64_t Val = II->getValue();
Chris Lattnerf5bd1b72003-10-05 19:27:59 +000038 if (Val != 0 && Val != 1) return 0; // Only accept 0 or 1 for a bit!
Misha Brukman650ba8e2005-04-22 00:00:37 +000039
40 return new BitInit(Val != 0);
Chris Lattnerf5bd1b72003-10-05 19:27:59 +000041}
42
43Init *BitRecTy::convertValue(TypedInit *VI) {
44 if (dynamic_cast<BitRecTy*>(VI->getType()))
45 return VI; // Accept variable if it is already of bit type!
46 return 0;
47}
48
Chris Lattner8b9ecda2007-11-20 22:25:16 +000049std::string BitsRecTy::getAsString() const {
50 return "bits<" + utostr(Size) + ">";
51}
52
Chris Lattnerf5bd1b72003-10-05 19:27:59 +000053Init *BitsRecTy::convertValue(UnsetInit *UI) {
54 BitsInit *Ret = new BitsInit(Size);
55
56 for (unsigned i = 0; i != Size; ++i)
57 Ret->setBit(i, new UnsetInit());
58 return Ret;
59}
60
61Init *BitsRecTy::convertValue(BitInit *UI) {
Bill Wendling73a48d82010-12-10 22:54:30 +000062 if (Size != 1) return 0; // Can only convert single bit.
Chris Lattnerf5bd1b72003-10-05 19:27:59 +000063 BitsInit *Ret = new BitsInit(1);
64 Ret->setBit(0, UI);
65 return Ret;
66}
67
Bill Wendling73ce4a62010-12-13 01:46:19 +000068/// canFitInBitfield - Return true if the number of bits is large enough to hold
69/// the integer value.
70static bool canFitInBitfield(int64_t Value, unsigned NumBits) {
Nick Lewycky79286bf2011-06-03 08:25:39 +000071 // For example, with NumBits == 4, we permit Values from [-7 .. 15].
72 return (NumBits >= sizeof(Value) * 8) ||
73 (Value >> NumBits == 0) || (Value >> (NumBits-1) == -1);
Bill Wendling73ce4a62010-12-13 01:46:19 +000074}
75
76/// convertValue from Int initializer to bits type: Split the integer up into the
77/// appropriate bits.
78///
Chris Lattnerf5bd1b72003-10-05 19:27:59 +000079Init *BitsRecTy::convertValue(IntInit *II) {
Misha Brukman6752fb52004-06-21 18:01:47 +000080 int64_t Value = II->getValue();
Bill Wendling73a48d82010-12-10 22:54:30 +000081 // Make sure this bitfield is large enough to hold the integer value.
Bill Wendling73ce4a62010-12-13 01:46:19 +000082 if (!canFitInBitfield(Value, Size))
83 return 0;
Chris Lattnerf5bd1b72003-10-05 19:27:59 +000084
85 BitsInit *Ret = new BitsInit(Size);
86 for (unsigned i = 0; i != Size; ++i)
Jeff Cohen0add83e2006-02-18 03:20:33 +000087 Ret->setBit(i, new BitInit(Value & (1LL << i)));
Chris Lattnerf5bd1b72003-10-05 19:27:59 +000088
89 return Ret;
90}
91
92Init *BitsRecTy::convertValue(BitsInit *BI) {
93 // If the number of bits is right, return it. Otherwise we need to expand or
Bill Wendling73a48d82010-12-10 22:54:30 +000094 // truncate.
Chris Lattnerf5bd1b72003-10-05 19:27:59 +000095 if (BI->getNumBits() == Size) return BI;
96 return 0;
97}
98
99Init *BitsRecTy::convertValue(TypedInit *VI) {
100 if (BitsRecTy *BRT = dynamic_cast<BitsRecTy*>(VI->getType()))
101 if (BRT->Size == Size) {
102 BitsInit *Ret = new BitsInit(Size);
103 for (unsigned i = 0; i != Size; ++i)
Jeff Cohen88e7b722005-04-22 04:13:13 +0000104 Ret->setBit(i, new VarBitInit(VI, i));
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000105 return Ret;
106 }
Bill Wendling73ce4a62010-12-13 01:46:19 +0000107
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000108 if (Size == 1 && dynamic_cast<BitRecTy*>(VI->getType())) {
109 BitsInit *Ret = new BitsInit(1);
110 Ret->setBit(0, VI);
111 return Ret;
112 }
Misha Brukman650ba8e2005-04-22 00:00:37 +0000113
Bill Wendling73ce4a62010-12-13 01:46:19 +0000114 if (TernOpInit *Tern = dynamic_cast<TernOpInit*>(VI)) {
115 if (Tern->getOpcode() == TernOpInit::IF) {
116 Init *LHS = Tern->getLHS();
117 Init *MHS = Tern->getMHS();
118 Init *RHS = Tern->getRHS();
119
120 IntInit *MHSi = dynamic_cast<IntInit*>(MHS);
121 IntInit *RHSi = dynamic_cast<IntInit*>(RHS);
122
123 if (MHSi && RHSi) {
124 int64_t MHSVal = MHSi->getValue();
125 int64_t RHSVal = RHSi->getValue();
126
127 if (canFitInBitfield(MHSVal, Size) && canFitInBitfield(RHSVal, Size)) {
128 BitsInit *Ret = new BitsInit(Size);
129
130 for (unsigned i = 0; i != Size; ++i)
131 Ret->setBit(i, new TernOpInit(TernOpInit::IF, LHS,
132 new IntInit((MHSVal & (1LL << i)) ? 1 : 0),
133 new IntInit((RHSVal & (1LL << i)) ? 1 : 0),
134 VI->getType()));
135
136 return Ret;
137 }
138 } else {
139 BitsInit *MHSbs = dynamic_cast<BitsInit*>(MHS);
140 BitsInit *RHSbs = dynamic_cast<BitsInit*>(RHS);
141
142 if (MHSbs && RHSbs) {
143 BitsInit *Ret = new BitsInit(Size);
144
145 for (unsigned i = 0; i != Size; ++i)
146 Ret->setBit(i, new TernOpInit(TernOpInit::IF, LHS,
147 MHSbs->getBit(i),
148 RHSbs->getBit(i),
149 VI->getType()));
150
151 return Ret;
152 }
153 }
154 }
155 }
156
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000157 return 0;
158}
159
160Init *IntRecTy::convertValue(BitInit *BI) {
161 return new IntInit(BI->getValue());
162}
163
164Init *IntRecTy::convertValue(BitsInit *BI) {
Dan Gohmanca0546f2008-10-17 01:33:43 +0000165 int64_t Result = 0;
Misha Brukman650ba8e2005-04-22 00:00:37 +0000166 for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i)
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000167 if (BitInit *Bit = dynamic_cast<BitInit*>(BI->getBit(i))) {
168 Result |= Bit->getValue() << i;
169 } else {
170 return 0;
171 }
172 return new IntInit(Result);
173}
174
175Init *IntRecTy::convertValue(TypedInit *TI) {
176 if (TI->getType()->typeIsConvertibleTo(this))
177 return TI; // Accept variable if already of the right type!
178 return 0;
179}
180
David Greenee8f3b272009-05-14 21:22:49 +0000181Init *StringRecTy::convertValue(UnOpInit *BO) {
182 if (BO->getOpcode() == UnOpInit::CAST) {
183 Init *L = BO->getOperand()->convertInitializerTo(this);
184 if (L == 0) return 0;
185 if (L != BO->getOperand())
186 return new UnOpInit(UnOpInit::CAST, L, new StringRecTy);
187 return BO;
188 }
David Greene5d0c0512009-05-14 20:54:48 +0000189
David Greenee8f3b272009-05-14 21:22:49 +0000190 return convertValue((TypedInit*)BO);
191}
David Greene5d0c0512009-05-14 20:54:48 +0000192
Chris Lattner51ffbf12006-03-31 21:53:49 +0000193Init *StringRecTy::convertValue(BinOpInit *BO) {
194 if (BO->getOpcode() == BinOpInit::STRCONCAT) {
195 Init *L = BO->getLHS()->convertInitializerTo(this);
196 Init *R = BO->getRHS()->convertInitializerTo(this);
197 if (L == 0 || R == 0) return 0;
198 if (L != BO->getLHS() || R != BO->getRHS())
David Greene196ac3c2009-04-23 21:25:15 +0000199 return new BinOpInit(BinOpInit::STRCONCAT, L, R, new StringRecTy);
Chris Lattner51ffbf12006-03-31 21:53:49 +0000200 return BO;
201 }
David Greene196ac3c2009-04-23 21:25:15 +0000202
203 return convertValue((TypedInit*)BO);
Chris Lattner51ffbf12006-03-31 21:53:49 +0000204}
205
206
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000207Init *StringRecTy::convertValue(TypedInit *TI) {
208 if (dynamic_cast<StringRecTy*>(TI->getType()))
209 return TI; // Accept variable if already of the right type!
210 return 0;
211}
212
Chris Lattner8b9ecda2007-11-20 22:25:16 +0000213std::string ListRecTy::getAsString() const {
214 return "list<" + Ty->getAsString() + ">";
215}
216
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000217Init *ListRecTy::convertValue(ListInit *LI) {
218 std::vector<Init*> Elements;
219
220 // Verify that all of the elements of the list are subclasses of the
221 // appropriate class!
222 for (unsigned i = 0, e = LI->getSize(); i != e; ++i)
223 if (Init *CI = LI->getElement(i)->convertInitializerTo(Ty))
224 Elements.push_back(CI);
225 else
226 return 0;
227
David Greene8618f952009-06-08 20:23:18 +0000228 ListRecTy *LType = dynamic_cast<ListRecTy*>(LI->getType());
229 if (LType == 0) {
230 return 0;
231 }
232
233 return new ListInit(Elements, new ListRecTy(Ty));
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000234}
235
236Init *ListRecTy::convertValue(TypedInit *TI) {
237 // Ensure that TI is compatible with our class.
238 if (ListRecTy *LRT = dynamic_cast<ListRecTy*>(TI->getType()))
239 if (LRT->getElementType()->typeIsConvertibleTo(getElementType()))
240 return TI;
241 return 0;
242}
243
244Init *CodeRecTy::convertValue(TypedInit *TI) {
245 if (TI->getType()->typeIsConvertibleTo(this))
246 return TI;
247 return 0;
248}
249
250Init *DagRecTy::convertValue(TypedInit *TI) {
251 if (TI->getType()->typeIsConvertibleTo(this))
252 return TI;
253 return 0;
254}
255
David Greenee8f3b272009-05-14 21:22:49 +0000256Init *DagRecTy::convertValue(UnOpInit *BO) {
257 if (BO->getOpcode() == UnOpInit::CAST) {
258 Init *L = BO->getOperand()->convertInitializerTo(this);
259 if (L == 0) return 0;
260 if (L != BO->getOperand())
261 return new UnOpInit(UnOpInit::CAST, L, new DagRecTy);
262 return BO;
263 }
264 return 0;
265}
David Greene5d0c0512009-05-14 20:54:48 +0000266
Evan Chenga32dee22007-05-15 01:23:24 +0000267Init *DagRecTy::convertValue(BinOpInit *BO) {
268 if (BO->getOpcode() == BinOpInit::CONCAT) {
269 Init *L = BO->getLHS()->convertInitializerTo(this);
270 Init *R = BO->getRHS()->convertInitializerTo(this);
271 if (L == 0 || R == 0) return 0;
272 if (L != BO->getLHS() || R != BO->getRHS())
David Greene196ac3c2009-04-23 21:25:15 +0000273 return new BinOpInit(BinOpInit::CONCAT, L, R, new DagRecTy);
Evan Chenga32dee22007-05-15 01:23:24 +0000274 return BO;
275 }
276 return 0;
277}
278
Chris Lattner8b9ecda2007-11-20 22:25:16 +0000279std::string RecordRecTy::getAsString() const {
280 return Rec->getName();
281}
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000282
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000283Init *RecordRecTy::convertValue(DefInit *DI) {
284 // Ensure that DI is a subclass of Rec.
285 if (!DI->getDef()->isSubClassOf(Rec))
286 return 0;
287 return DI;
288}
289
290Init *RecordRecTy::convertValue(TypedInit *TI) {
291 // Ensure that TI is compatible with Rec.
292 if (RecordRecTy *RRT = dynamic_cast<RecordRecTy*>(TI->getType()))
293 if (RRT->getRecord()->isSubClassOf(getRecord()) ||
294 RRT->getRecord() == getRecord())
295 return TI;
296 return 0;
297}
298
299bool RecordRecTy::baseClassOf(const RecordRecTy *RHS) const {
Bruno Cardoso Lopesdeb20022010-06-17 23:00:16 +0000300 if (Rec == RHS->getRecord() || RHS->getRecord()->isSubClassOf(Rec))
301 return true;
302
303 const std::vector<Record*> &SC = Rec->getSuperClasses();
304 for (unsigned i = 0, e = SC.size(); i != e; ++i)
305 if (RHS->getRecord()->isSubClassOf(SC[i]))
306 return true;
307
308 return false;
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000309}
310
311
Bob Wilson7248f862009-11-22 04:24:42 +0000312/// resolveTypes - Find a common type that T1 and T2 convert to.
David Greene8618f952009-06-08 20:23:18 +0000313/// Return 0 if no such type exists.
314///
315RecTy *llvm::resolveTypes(RecTy *T1, RecTy *T2) {
316 if (!T1->typeIsConvertibleTo(T2)) {
317 if (!T2->typeIsConvertibleTo(T1)) {
318 // If one is a Record type, check superclasses
319 RecordRecTy *RecTy1 = dynamic_cast<RecordRecTy*>(T1);
320 if (RecTy1) {
321 // See if T2 inherits from a type T1 also inherits from
Bob Wilson7248f862009-11-22 04:24:42 +0000322 const std::vector<Record *> &T1SuperClasses =
323 RecTy1->getRecord()->getSuperClasses();
David Greene8618f952009-06-08 20:23:18 +0000324 for(std::vector<Record *>::const_iterator i = T1SuperClasses.begin(),
325 iend = T1SuperClasses.end();
326 i != iend;
327 ++i) {
328 RecordRecTy *SuperRecTy1 = new RecordRecTy(*i);
329 RecTy *NewType1 = resolveTypes(SuperRecTy1, T2);
330 if (NewType1 != 0) {
331 if (NewType1 != SuperRecTy1) {
332 delete SuperRecTy1;
333 }
334 return NewType1;
335 }
336 }
337 }
338 RecordRecTy *RecTy2 = dynamic_cast<RecordRecTy*>(T2);
339 if (RecTy2) {
340 // See if T1 inherits from a type T2 also inherits from
Bob Wilson7248f862009-11-22 04:24:42 +0000341 const std::vector<Record *> &T2SuperClasses =
342 RecTy2->getRecord()->getSuperClasses();
343 for (std::vector<Record *>::const_iterator i = T2SuperClasses.begin(),
David Greene8618f952009-06-08 20:23:18 +0000344 iend = T2SuperClasses.end();
345 i != iend;
346 ++i) {
347 RecordRecTy *SuperRecTy2 = new RecordRecTy(*i);
348 RecTy *NewType2 = resolveTypes(T1, SuperRecTy2);
349 if (NewType2 != 0) {
350 if (NewType2 != SuperRecTy2) {
351 delete SuperRecTy2;
352 }
353 return NewType2;
354 }
355 }
356 }
357 return 0;
358 }
359 return T2;
360 }
361 return T1;
362}
363
364
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000365//===----------------------------------------------------------------------===//
366// Initializer implementations
367//===----------------------------------------------------------------------===//
368
Daniel Dunbar38a22bf2009-07-03 00:10:29 +0000369void Init::dump() const { return print(errs()); }
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000370
371Init *BitsInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) {
372 BitsInit *BI = new BitsInit(Bits.size());
373 for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
374 if (Bits[i] >= getNumBits()) {
375 delete BI;
376 return 0;
377 }
378 BI->setBit(i, getBit(Bits[i]));
379 }
380 return BI;
381}
382
Chris Lattner695506c2007-11-22 21:05:25 +0000383std::string BitsInit::getAsString() const {
Chris Lattner695506c2007-11-22 21:05:25 +0000384 std::string Result = "{ ";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000385 for (unsigned i = 0, e = getNumBits(); i != e; ++i) {
Chris Lattner695506c2007-11-22 21:05:25 +0000386 if (i) Result += ", ";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000387 if (Init *Bit = getBit(e-i-1))
Chris Lattner695506c2007-11-22 21:05:25 +0000388 Result += Bit->getAsString();
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000389 else
Chris Lattner695506c2007-11-22 21:05:25 +0000390 Result += "*";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000391 }
Chris Lattner695506c2007-11-22 21:05:25 +0000392 return Result + " }";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000393}
394
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000395// resolveReferences - If there are any field references that refer to fields
396// that have been filled in, we can propagate the values now.
397//
Chris Lattneref943742005-04-19 03:36:21 +0000398Init *BitsInit::resolveReferences(Record &R, const RecordVal *RV) {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000399 bool Changed = false;
400 BitsInit *New = new BitsInit(getNumBits());
401
402 for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
403 Init *B;
404 Init *CurBit = getBit(i);
405
406 do {
407 B = CurBit;
Chris Lattneref943742005-04-19 03:36:21 +0000408 CurBit = CurBit->resolveReferences(R, RV);
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000409 Changed |= B != CurBit;
410 } while (B != CurBit);
411 New->setBit(i, CurBit);
412 }
413
414 if (Changed)
415 return New;
416 delete New;
417 return this;
418}
419
Chris Lattner695506c2007-11-22 21:05:25 +0000420std::string IntInit::getAsString() const {
421 return itostr(Value);
422}
423
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000424Init *IntInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) {
425 BitsInit *BI = new BitsInit(Bits.size());
426
427 for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
Dan Gohmanca0546f2008-10-17 01:33:43 +0000428 if (Bits[i] >= 64) {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000429 delete BI;
430 return 0;
431 }
Dan Gohmanca0546f2008-10-17 01:33:43 +0000432 BI->setBit(i, new BitInit(Value & (INT64_C(1) << Bits[i])));
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000433 }
434 return BI;
435}
436
Chris Lattner8bf9e062004-07-26 23:21:34 +0000437Init *ListInit::convertInitListSlice(const std::vector<unsigned> &Elements) {
438 std::vector<Init*> Vals;
439 for (unsigned i = 0, e = Elements.size(); i != e; ++i) {
440 if (Elements[i] >= getSize())
441 return 0;
442 Vals.push_back(getElement(Elements[i]));
443 }
David Greene8618f952009-06-08 20:23:18 +0000444 return new ListInit(Vals, getType());
Chris Lattner8bf9e062004-07-26 23:21:34 +0000445}
446
Chris Lattnercbebe462007-02-27 22:08:27 +0000447Record *ListInit::getElementAsRecord(unsigned i) const {
448 assert(i < Values.size() && "List element index out of range!");
449 DefInit *DI = dynamic_cast<DefInit*>(Values[i]);
450 if (DI == 0) throw "Expected record in list!";
451 return DI->getDef();
452}
453
Chris Lattneref943742005-04-19 03:36:21 +0000454Init *ListInit::resolveReferences(Record &R, const RecordVal *RV) {
Chris Lattner577fc3f2004-07-27 01:01:21 +0000455 std::vector<Init*> Resolved;
456 Resolved.reserve(getSize());
457 bool Changed = false;
458
459 for (unsigned i = 0, e = getSize(); i != e; ++i) {
460 Init *E;
461 Init *CurElt = getElement(i);
462
463 do {
464 E = CurElt;
Chris Lattneref943742005-04-19 03:36:21 +0000465 CurElt = CurElt->resolveReferences(R, RV);
Chris Lattner577fc3f2004-07-27 01:01:21 +0000466 Changed |= E != CurElt;
467 } while (E != CurElt);
468 Resolved.push_back(E);
469 }
470
471 if (Changed)
David Greene8618f952009-06-08 20:23:18 +0000472 return new ListInit(Resolved, getType());
Chris Lattner577fc3f2004-07-27 01:01:21 +0000473 return this;
474}
475
David Greene8618f952009-06-08 20:23:18 +0000476Init *ListInit::resolveListElementReference(Record &R, const RecordVal *IRV,
Bob Wilson7248f862009-11-22 04:24:42 +0000477 unsigned Elt) {
David Greene8618f952009-06-08 20:23:18 +0000478 if (Elt >= getSize())
479 return 0; // Out of range reference.
480 Init *E = getElement(Elt);
Bob Wilson67e6cab2009-11-22 03:58:57 +0000481 // If the element is set to some value, or if we are resolving a reference
482 // to a specific variable and that variable is explicitly unset, then
483 // replace the VarListElementInit with it.
484 if (IRV || !dynamic_cast<UnsetInit*>(E))
485 return E;
David Greene8618f952009-06-08 20:23:18 +0000486 return 0;
487}
488
Chris Lattner695506c2007-11-22 21:05:25 +0000489std::string ListInit::getAsString() const {
490 std::string Result = "[";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000491 for (unsigned i = 0, e = Values.size(); i != e; ++i) {
Chris Lattner695506c2007-11-22 21:05:25 +0000492 if (i) Result += ", ";
493 Result += Values[i]->getAsString();
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000494 }
Chris Lattner695506c2007-11-22 21:05:25 +0000495 return Result + "]";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000496}
497
David Greene5d0c0512009-05-14 20:54:48 +0000498Init *OpInit::resolveBitReference(Record &R, const RecordVal *IRV,
Bob Wilson7248f862009-11-22 04:24:42 +0000499 unsigned Bit) {
David Greene5d0c0512009-05-14 20:54:48 +0000500 Init *Folded = Fold(&R, 0);
501
502 if (Folded != this) {
503 TypedInit *Typed = dynamic_cast<TypedInit *>(Folded);
504 if (Typed) {
505 return Typed->resolveBitReference(R, IRV, Bit);
Bob Wilson7248f862009-11-22 04:24:42 +0000506 }
David Greene5d0c0512009-05-14 20:54:48 +0000507 }
Bob Wilson7248f862009-11-22 04:24:42 +0000508
David Greene5d0c0512009-05-14 20:54:48 +0000509 return 0;
510}
511
512Init *OpInit::resolveListElementReference(Record &R, const RecordVal *IRV,
Bob Wilson7248f862009-11-22 04:24:42 +0000513 unsigned Elt) {
David Greene5d0c0512009-05-14 20:54:48 +0000514 Init *Folded = Fold(&R, 0);
515
516 if (Folded != this) {
517 TypedInit *Typed = dynamic_cast<TypedInit *>(Folded);
518 if (Typed) {
519 return Typed->resolveListElementReference(R, IRV, Elt);
Bob Wilson7248f862009-11-22 04:24:42 +0000520 }
David Greene5d0c0512009-05-14 20:54:48 +0000521 }
Bob Wilson7248f862009-11-22 04:24:42 +0000522
David Greene5d0c0512009-05-14 20:54:48 +0000523 return 0;
524}
525
David Greenee8f3b272009-05-14 21:22:49 +0000526Init *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
527 switch (getOpcode()) {
528 default: assert(0 && "Unknown unop");
529 case CAST: {
David Greeneefa19612009-06-29 20:05:29 +0000530 if (getType()->getAsString() == "string") {
531 StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
532 if (LHSs) {
533 return LHSs;
534 }
David Greene5d0c0512009-05-14 20:54:48 +0000535
David Greeneefa19612009-06-29 20:05:29 +0000536 DefInit *LHSd = dynamic_cast<DefInit*>(LHS);
537 if (LHSd) {
538 return new StringInit(LHSd->getDef()->getName());
539 }
Bob Wilson7248f862009-11-22 04:24:42 +0000540 } else {
David Greeneefa19612009-06-29 20:05:29 +0000541 StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
542 if (LHSs) {
543 std::string Name = LHSs->getValue();
544
545 // From TGParser::ParseIDValue
546 if (CurRec) {
547 if (const RecordVal *RV = CurRec->getValue(Name)) {
Chris Lattner94026332010-10-06 00:19:21 +0000548 if (RV->getType() != getType())
549 throw "type mismatch in cast";
David Greeneefa19612009-06-29 20:05:29 +0000550 return new VarInit(Name, RV->getType());
David Greenee8f3b272009-05-14 21:22:49 +0000551 }
David Greeneefa19612009-06-29 20:05:29 +0000552
553 std::string TemplateArgName = CurRec->getName()+":"+Name;
554 if (CurRec->isTemplateArg(TemplateArgName)) {
555 const RecordVal *RV = CurRec->getValue(TemplateArgName);
556 assert(RV && "Template arg doesn't exist??");
557
Chris Lattner94026332010-10-06 00:19:21 +0000558 if (RV->getType() != getType())
559 throw "type mismatch in cast";
David Greeneefa19612009-06-29 20:05:29 +0000560
561 return new VarInit(TemplateArgName, RV->getType());
562 }
563 }
564
565 if (CurMultiClass) {
566 std::string MCName = CurMultiClass->Rec.getName()+"::"+Name;
567 if (CurMultiClass->Rec.isTemplateArg(MCName)) {
568 const RecordVal *RV = CurMultiClass->Rec.getValue(MCName);
569 assert(RV && "Template arg doesn't exist??");
Bob Wilson7248f862009-11-22 04:24:42 +0000570
Chris Lattner94026332010-10-06 00:19:21 +0000571 if (RV->getType() != getType())
572 throw "type mismatch in cast";
Bob Wilson7248f862009-11-22 04:24:42 +0000573
David Greeneefa19612009-06-29 20:05:29 +0000574 return new VarInit(MCName, RV->getType());
575 }
David Greenee8f3b272009-05-14 21:22:49 +0000576 }
Bob Wilson7248f862009-11-22 04:24:42 +0000577
Chris Lattner77d369c2010-12-13 00:23:57 +0000578 if (Record *D = (CurRec->getRecords()).getDef(Name))
David Greeneefa19612009-06-29 20:05:29 +0000579 return new DefInit(D);
David Greene5d0c0512009-05-14 20:54:48 +0000580
Jim Grosbach59ddb732011-05-06 18:47:45 +0000581 throw TGError(CurRec->getLoc(), "Undefined reference:'" + Name + "'\n");
David Greenee8f3b272009-05-14 21:22:49 +0000582 }
David Greenee8f3b272009-05-14 21:22:49 +0000583 }
584 break;
585 }
David Greene2f7cf7f2011-01-07 17:05:37 +0000586 case HEAD: {
David Greened571b3c2009-05-14 22:38:31 +0000587 ListInit *LHSl = dynamic_cast<ListInit*>(LHS);
588 if (LHSl) {
589 if (LHSl->getSize() == 0) {
590 assert(0 && "Empty list in car");
591 return 0;
592 }
593 return LHSl->getElement(0);
594 }
595 break;
596 }
David Greene2f7cf7f2011-01-07 17:05:37 +0000597 case TAIL: {
David Greened571b3c2009-05-14 22:38:31 +0000598 ListInit *LHSl = dynamic_cast<ListInit*>(LHS);
599 if (LHSl) {
600 if (LHSl->getSize() == 0) {
601 assert(0 && "Empty list in cdr");
602 return 0;
603 }
Bob Wilson7248f862009-11-22 04:24:42 +0000604 ListInit *Result = new ListInit(LHSl->begin()+1, LHSl->end(),
605 LHSl->getType());
David Greened571b3c2009-05-14 22:38:31 +0000606 return Result;
607 }
608 break;
609 }
David Greene2f7cf7f2011-01-07 17:05:37 +0000610 case EMPTY: {
David Greened571b3c2009-05-14 22:38:31 +0000611 ListInit *LHSl = dynamic_cast<ListInit*>(LHS);
612 if (LHSl) {
613 if (LHSl->getSize() == 0) {
614 return new IntInit(1);
Bob Wilson7248f862009-11-22 04:24:42 +0000615 } else {
David Greened571b3c2009-05-14 22:38:31 +0000616 return new IntInit(0);
617 }
618 }
David Greene8618f952009-06-08 20:23:18 +0000619 StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
620 if (LHSs) {
621 if (LHSs->getValue().empty()) {
622 return new IntInit(1);
Bob Wilson7248f862009-11-22 04:24:42 +0000623 } else {
David Greene8618f952009-06-08 20:23:18 +0000624 return new IntInit(0);
625 }
626 }
Bob Wilson7248f862009-11-22 04:24:42 +0000627
David Greened571b3c2009-05-14 22:38:31 +0000628 break;
629 }
David Greenee8f3b272009-05-14 21:22:49 +0000630 }
631 return this;
632}
David Greene5d0c0512009-05-14 20:54:48 +0000633
David Greenee8f3b272009-05-14 21:22:49 +0000634Init *UnOpInit::resolveReferences(Record &R, const RecordVal *RV) {
635 Init *lhs = LHS->resolveReferences(R, RV);
Bob Wilson7248f862009-11-22 04:24:42 +0000636
David Greenee8f3b272009-05-14 21:22:49 +0000637 if (LHS != lhs)
638 return (new UnOpInit(getOpcode(), lhs, getType()))->Fold(&R, 0);
639 return Fold(&R, 0);
640}
David Greene5d0c0512009-05-14 20:54:48 +0000641
David Greenee8f3b272009-05-14 21:22:49 +0000642std::string UnOpInit::getAsString() const {
643 std::string Result;
644 switch (Opc) {
645 case CAST: Result = "!cast<" + getType()->getAsString() + ">"; break;
David Greene2f7cf7f2011-01-07 17:05:37 +0000646 case HEAD: Result = "!head"; break;
647 case TAIL: Result = "!tail"; break;
648 case EMPTY: Result = "!empty"; break;
David Greenee8f3b272009-05-14 21:22:49 +0000649 }
650 return Result + "(" + LHS->getAsString() + ")";
651}
David Greene5d0c0512009-05-14 20:54:48 +0000652
David Greenea9c6c5d2009-04-22 20:18:10 +0000653Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
Chris Lattner51ffbf12006-03-31 21:53:49 +0000654 switch (getOpcode()) {
655 default: assert(0 && "Unknown binop");
Evan Chenga32dee22007-05-15 01:23:24 +0000656 case CONCAT: {
657 DagInit *LHSs = dynamic_cast<DagInit*>(LHS);
658 DagInit *RHSs = dynamic_cast<DagInit*>(RHS);
659 if (LHSs && RHSs) {
660 DefInit *LOp = dynamic_cast<DefInit*>(LHSs->getOperator());
661 DefInit *ROp = dynamic_cast<DefInit*>(RHSs->getOperator());
Chris Lattner81fd1f22010-03-18 21:07:51 +0000662 if (LOp == 0 || ROp == 0 || LOp->getDef() != ROp->getDef())
663 throw "Concated Dag operators do not match!";
Evan Chenga32dee22007-05-15 01:23:24 +0000664 std::vector<Init*> Args;
665 std::vector<std::string> ArgNames;
666 for (unsigned i = 0, e = LHSs->getNumArgs(); i != e; ++i) {
667 Args.push_back(LHSs->getArg(i));
668 ArgNames.push_back(LHSs->getArgName(i));
669 }
670 for (unsigned i = 0, e = RHSs->getNumArgs(); i != e; ++i) {
671 Args.push_back(RHSs->getArg(i));
672 ArgNames.push_back(RHSs->getArgName(i));
673 }
Nate Begemandbe3f772009-03-19 05:21:56 +0000674 return new DagInit(LHSs->getOperator(), "", Args, ArgNames);
Evan Chenga32dee22007-05-15 01:23:24 +0000675 }
676 break;
677 }
Chris Lattner51ffbf12006-03-31 21:53:49 +0000678 case STRCONCAT: {
679 StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
680 StringInit *RHSs = dynamic_cast<StringInit*>(RHS);
681 if (LHSs && RHSs)
682 return new StringInit(LHSs->getValue() + RHSs->getValue());
683 break;
684 }
David Greene297bfe62010-01-05 19:11:42 +0000685 case EQ: {
Bruno Cardoso Lopes77a4a562010-06-16 23:24:12 +0000686 // try to fold eq comparison for 'bit' and 'int', otherwise fallback
687 // to string objects.
688 IntInit* L =
689 dynamic_cast<IntInit*>(LHS->convertInitializerTo(new IntRecTy()));
690 IntInit* R =
691 dynamic_cast<IntInit*>(RHS->convertInitializerTo(new IntRecTy()));
692
693 if (L && R)
694 return new IntInit(L->getValue() == R->getValue());
695
David Greene297bfe62010-01-05 19:11:42 +0000696 StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
697 StringInit *RHSs = dynamic_cast<StringInit*>(RHS);
Bruno Cardoso Lopes77a4a562010-06-16 23:24:12 +0000698
699 // Make sure we've resolved
David Greene297bfe62010-01-05 19:11:42 +0000700 if (LHSs && RHSs)
701 return new IntInit(LHSs->getValue() == RHSs->getValue());
702
703 break;
704 }
Chris Lattner51ffbf12006-03-31 21:53:49 +0000705 case SHL:
706 case SRA:
707 case SRL: {
708 IntInit *LHSi = dynamic_cast<IntInit*>(LHS);
709 IntInit *RHSi = dynamic_cast<IntInit*>(RHS);
710 if (LHSi && RHSi) {
Dan Gohmanca0546f2008-10-17 01:33:43 +0000711 int64_t LHSv = LHSi->getValue(), RHSv = RHSi->getValue();
712 int64_t Result;
Chris Lattner51ffbf12006-03-31 21:53:49 +0000713 switch (getOpcode()) {
714 default: assert(0 && "Bad opcode!");
715 case SHL: Result = LHSv << RHSv; break;
716 case SRA: Result = LHSv >> RHSv; break;
Dan Gohmanca0546f2008-10-17 01:33:43 +0000717 case SRL: Result = (uint64_t)LHSv >> (uint64_t)RHSv; break;
Chris Lattner51ffbf12006-03-31 21:53:49 +0000718 }
719 return new IntInit(Result);
720 }
721 break;
722 }
723 }
724 return this;
725}
726
727Init *BinOpInit::resolveReferences(Record &R, const RecordVal *RV) {
728 Init *lhs = LHS->resolveReferences(R, RV);
729 Init *rhs = RHS->resolveReferences(R, RV);
Bob Wilson7248f862009-11-22 04:24:42 +0000730
Chris Lattner51ffbf12006-03-31 21:53:49 +0000731 if (LHS != lhs || RHS != rhs)
David Greene196ac3c2009-04-23 21:25:15 +0000732 return (new BinOpInit(getOpcode(), lhs, rhs, getType()))->Fold(&R, 0);
David Greenea9c6c5d2009-04-22 20:18:10 +0000733 return Fold(&R, 0);
Chris Lattner51ffbf12006-03-31 21:53:49 +0000734}
735
Chris Lattner695506c2007-11-22 21:05:25 +0000736std::string BinOpInit::getAsString() const {
737 std::string Result;
Chris Lattner51ffbf12006-03-31 21:53:49 +0000738 switch (Opc) {
Chris Lattner695506c2007-11-22 21:05:25 +0000739 case CONCAT: Result = "!con"; break;
740 case SHL: Result = "!shl"; break;
741 case SRA: Result = "!sra"; break;
742 case SRL: Result = "!srl"; break;
David Greene297bfe62010-01-05 19:11:42 +0000743 case EQ: Result = "!eq"; break;
Chris Lattner695506c2007-11-22 21:05:25 +0000744 case STRCONCAT: Result = "!strconcat"; break;
Chris Lattner51ffbf12006-03-31 21:53:49 +0000745 }
Chris Lattner695506c2007-11-22 21:05:25 +0000746 return Result + "(" + LHS->getAsString() + ", " + RHS->getAsString() + ")";
Chris Lattner51ffbf12006-03-31 21:53:49 +0000747}
748
David Greenee917fff2009-05-14 22:23:47 +0000749static Init *ForeachHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type,
750 Record *CurRec, MultiClass *CurMultiClass);
751
752static Init *EvaluateOperation(OpInit *RHSo, Init *LHS, Init *Arg,
753 RecTy *Type, Record *CurRec,
754 MultiClass *CurMultiClass) {
755 std::vector<Init *> NewOperands;
756
757 TypedInit *TArg = dynamic_cast<TypedInit*>(Arg);
758
759 // If this is a dag, recurse
760 if (TArg && TArg->getType()->getAsString() == "dag") {
761 Init *Result = ForeachHelper(LHS, Arg, RHSo, Type,
762 CurRec, CurMultiClass);
763 if (Result != 0) {
764 return Result;
Bob Wilson7248f862009-11-22 04:24:42 +0000765 } else {
David Greenee917fff2009-05-14 22:23:47 +0000766 return 0;
767 }
768 }
769
770 for (int i = 0; i < RHSo->getNumOperands(); ++i) {
771 OpInit *RHSoo = dynamic_cast<OpInit*>(RHSo->getOperand(i));
772
773 if (RHSoo) {
774 Init *Result = EvaluateOperation(RHSoo, LHS, Arg,
775 Type, CurRec, CurMultiClass);
776 if (Result != 0) {
777 NewOperands.push_back(Result);
Bob Wilson7248f862009-11-22 04:24:42 +0000778 } else {
David Greenee917fff2009-05-14 22:23:47 +0000779 NewOperands.push_back(Arg);
780 }
Bob Wilson7248f862009-11-22 04:24:42 +0000781 } else if (LHS->getAsString() == RHSo->getOperand(i)->getAsString()) {
David Greenee917fff2009-05-14 22:23:47 +0000782 NewOperands.push_back(Arg);
Bob Wilson7248f862009-11-22 04:24:42 +0000783 } else {
David Greenee917fff2009-05-14 22:23:47 +0000784 NewOperands.push_back(RHSo->getOperand(i));
785 }
786 }
787
788 // Now run the operator and use its result as the new leaf
789 OpInit *NewOp = RHSo->clone(NewOperands);
790 Init *NewVal = NewOp->Fold(CurRec, CurMultiClass);
791 if (NewVal != NewOp) {
792 delete NewOp;
793 return NewVal;
794 }
795 return 0;
796}
797
798static Init *ForeachHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type,
799 Record *CurRec, MultiClass *CurMultiClass) {
800 DagInit *MHSd = dynamic_cast<DagInit*>(MHS);
801 ListInit *MHSl = dynamic_cast<ListInit*>(MHS);
802
803 DagRecTy *DagType = dynamic_cast<DagRecTy*>(Type);
804 ListRecTy *ListType = dynamic_cast<ListRecTy*>(Type);
805
806 OpInit *RHSo = dynamic_cast<OpInit*>(RHS);
807
808 if (!RHSo) {
Jim Grosbach59ddb732011-05-06 18:47:45 +0000809 throw TGError(CurRec->getLoc(), "!foreach requires an operator\n");
David Greenee917fff2009-05-14 22:23:47 +0000810 }
811
812 TypedInit *LHSt = dynamic_cast<TypedInit*>(LHS);
813
814 if (!LHSt) {
Jim Grosbach59ddb732011-05-06 18:47:45 +0000815 throw TGError(CurRec->getLoc(), "!foreach requires typed variable\n");
David Greenee917fff2009-05-14 22:23:47 +0000816 }
817
Nick Lewycky94298222009-05-15 03:07:14 +0000818 if ((MHSd && DagType) || (MHSl && ListType)) {
David Greenee917fff2009-05-14 22:23:47 +0000819 if (MHSd) {
820 Init *Val = MHSd->getOperator();
821 Init *Result = EvaluateOperation(RHSo, LHS, Val,
822 Type, CurRec, CurMultiClass);
823 if (Result != 0) {
824 Val = Result;
825 }
826
827 std::vector<std::pair<Init *, std::string> > args;
828 for (unsigned int i = 0; i < MHSd->getNumArgs(); ++i) {
829 Init *Arg;
830 std::string ArgName;
831 Arg = MHSd->getArg(i);
832 ArgName = MHSd->getArgName(i);
833
834 // Process args
835 Init *Result = EvaluateOperation(RHSo, LHS, Arg, Type,
836 CurRec, CurMultiClass);
837 if (Result != 0) {
838 Arg = Result;
839 }
840
841 // TODO: Process arg names
842 args.push_back(std::make_pair(Arg, ArgName));
843 }
844
845 return new DagInit(Val, "", args);
846 }
847 if (MHSl) {
848 std::vector<Init *> NewOperands;
849 std::vector<Init *> NewList(MHSl->begin(), MHSl->end());
850
851 for (ListInit::iterator li = NewList.begin(),
852 liend = NewList.end();
853 li != liend;
854 ++li) {
855 Init *Item = *li;
856 NewOperands.clear();
857 for(int i = 0; i < RHSo->getNumOperands(); ++i) {
858 // First, replace the foreach variable with the list item
859 if (LHS->getAsString() == RHSo->getOperand(i)->getAsString()) {
860 NewOperands.push_back(Item);
Bob Wilson7248f862009-11-22 04:24:42 +0000861 } else {
David Greenee917fff2009-05-14 22:23:47 +0000862 NewOperands.push_back(RHSo->getOperand(i));
863 }
864 }
865
866 // Now run the operator and use its result as the new list item
867 OpInit *NewOp = RHSo->clone(NewOperands);
868 Init *NewItem = NewOp->Fold(CurRec, CurMultiClass);
869 if (NewItem != NewOp) {
870 *li = NewItem;
871 delete NewOp;
872 }
873 }
David Greene8618f952009-06-08 20:23:18 +0000874 return new ListInit(NewList, MHSl->getType());
David Greenee917fff2009-05-14 22:23:47 +0000875 }
876 }
877 return 0;
878}
879
David Greene98ed3c72009-05-14 21:54:42 +0000880Init *TernOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
881 switch (getOpcode()) {
882 default: assert(0 && "Unknown binop");
883 case SUBST: {
884 DefInit *LHSd = dynamic_cast<DefInit*>(LHS);
885 VarInit *LHSv = dynamic_cast<VarInit*>(LHS);
886 StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
David Greene196ac3c2009-04-23 21:25:15 +0000887
David Greene98ed3c72009-05-14 21:54:42 +0000888 DefInit *MHSd = dynamic_cast<DefInit*>(MHS);
889 VarInit *MHSv = dynamic_cast<VarInit*>(MHS);
890 StringInit *MHSs = dynamic_cast<StringInit*>(MHS);
David Greene5d0c0512009-05-14 20:54:48 +0000891
David Greene98ed3c72009-05-14 21:54:42 +0000892 DefInit *RHSd = dynamic_cast<DefInit*>(RHS);
893 VarInit *RHSv = dynamic_cast<VarInit*>(RHS);
894 StringInit *RHSs = dynamic_cast<StringInit*>(RHS);
David Greene5d0c0512009-05-14 20:54:48 +0000895
David Greene98ed3c72009-05-14 21:54:42 +0000896 if ((LHSd && MHSd && RHSd)
897 || (LHSv && MHSv && RHSv)
898 || (LHSs && MHSs && RHSs)) {
899 if (RHSd) {
900 Record *Val = RHSd->getDef();
901 if (LHSd->getAsString() == RHSd->getAsString()) {
902 Val = MHSd->getDef();
903 }
904 return new DefInit(Val);
905 }
906 if (RHSv) {
907 std::string Val = RHSv->getName();
908 if (LHSv->getAsString() == RHSv->getAsString()) {
909 Val = MHSv->getName();
910 }
911 return new VarInit(Val, getType());
912 }
913 if (RHSs) {
914 std::string Val = RHSs->getValue();
David Greene5d0c0512009-05-14 20:54:48 +0000915
David Greene98ed3c72009-05-14 21:54:42 +0000916 std::string::size_type found;
David Greenedbf70742009-12-21 21:21:34 +0000917 std::string::size_type idx = 0;
David Greene98ed3c72009-05-14 21:54:42 +0000918 do {
David Greenedbf70742009-12-21 21:21:34 +0000919 found = Val.find(LHSs->getValue(), idx);
David Greene98ed3c72009-05-14 21:54:42 +0000920 if (found != std::string::npos) {
921 Val.replace(found, LHSs->getValue().size(), MHSs->getValue());
922 }
David Greenedbf70742009-12-21 21:21:34 +0000923 idx = found + MHSs->getValue().size();
David Greene98ed3c72009-05-14 21:54:42 +0000924 } while (found != std::string::npos);
David Greene5d0c0512009-05-14 20:54:48 +0000925
David Greene98ed3c72009-05-14 21:54:42 +0000926 return new StringInit(Val);
927 }
928 }
929 break;
Bob Wilson7248f862009-11-22 04:24:42 +0000930 }
David Greene5d0c0512009-05-14 20:54:48 +0000931
David Greene98ed3c72009-05-14 21:54:42 +0000932 case FOREACH: {
David Greenee917fff2009-05-14 22:23:47 +0000933 Init *Result = ForeachHelper(LHS, MHS, RHS, getType(),
934 CurRec, CurMultiClass);
935 if (Result != 0) {
936 return Result;
David Greene98ed3c72009-05-14 21:54:42 +0000937 }
938 break;
939 }
David Greene3587eed2009-05-14 23:26:46 +0000940
941 case IF: {
Bruno Cardoso Lopes7f4235d2010-06-17 01:50:39 +0000942 IntInit *LHSi = dynamic_cast<IntInit*>(LHS);
943 if (Init *I = LHS->convertInitializerTo(new IntRecTy()))
944 LHSi = dynamic_cast<IntInit*>(I);
David Greene3587eed2009-05-14 23:26:46 +0000945 if (LHSi) {
946 if (LHSi->getValue()) {
947 return MHS;
Bob Wilson7248f862009-11-22 04:24:42 +0000948 } else {
David Greene3587eed2009-05-14 23:26:46 +0000949 return RHS;
950 }
951 }
952 break;
953 }
David Greene98ed3c72009-05-14 21:54:42 +0000954 }
David Greene5d0c0512009-05-14 20:54:48 +0000955
David Greene98ed3c72009-05-14 21:54:42 +0000956 return this;
957}
David Greene5d0c0512009-05-14 20:54:48 +0000958
David Greene98ed3c72009-05-14 21:54:42 +0000959Init *TernOpInit::resolveReferences(Record &R, const RecordVal *RV) {
960 Init *lhs = LHS->resolveReferences(R, RV);
David Greeneb0354452009-06-08 19:16:56 +0000961
962 if (Opc == IF && lhs != LHS) {
Bruno Cardoso Lopes7f4235d2010-06-17 01:50:39 +0000963 IntInit *Value = dynamic_cast<IntInit*>(lhs);
964 if (Init *I = lhs->convertInitializerTo(new IntRecTy()))
965 Value = dynamic_cast<IntInit*>(I);
David Greeneb0354452009-06-08 19:16:56 +0000966 if (Value != 0) {
967 // Short-circuit
968 if (Value->getValue()) {
969 Init *mhs = MHS->resolveReferences(R, RV);
Bob Wilson7248f862009-11-22 04:24:42 +0000970 return (new TernOpInit(getOpcode(), lhs, mhs,
971 RHS, getType()))->Fold(&R, 0);
972 } else {
David Greeneb0354452009-06-08 19:16:56 +0000973 Init *rhs = RHS->resolveReferences(R, RV);
Bob Wilson7248f862009-11-22 04:24:42 +0000974 return (new TernOpInit(getOpcode(), lhs, MHS,
975 rhs, getType()))->Fold(&R, 0);
David Greeneb0354452009-06-08 19:16:56 +0000976 }
977 }
978 }
Bob Wilson7248f862009-11-22 04:24:42 +0000979
David Greene98ed3c72009-05-14 21:54:42 +0000980 Init *mhs = MHS->resolveReferences(R, RV);
981 Init *rhs = RHS->resolveReferences(R, RV);
David Greeneb0354452009-06-08 19:16:56 +0000982
David Greene98ed3c72009-05-14 21:54:42 +0000983 if (LHS != lhs || MHS != mhs || RHS != rhs)
984 return (new TernOpInit(getOpcode(), lhs, mhs, rhs, getType()))->Fold(&R, 0);
985 return Fold(&R, 0);
986}
David Greene196ac3c2009-04-23 21:25:15 +0000987
David Greene98ed3c72009-05-14 21:54:42 +0000988std::string TernOpInit::getAsString() const {
989 std::string Result;
990 switch (Opc) {
991 case SUBST: Result = "!subst"; break;
Bob Wilson7248f862009-11-22 04:24:42 +0000992 case FOREACH: Result = "!foreach"; break;
993 case IF: Result = "!if"; break;
David Greene98ed3c72009-05-14 21:54:42 +0000994 }
Bob Wilson7248f862009-11-22 04:24:42 +0000995 return Result + "(" + LHS->getAsString() + ", " + MHS->getAsString() + ", "
David Greene98ed3c72009-05-14 21:54:42 +0000996 + RHS->getAsString() + ")";
997}
David Greene196ac3c2009-04-23 21:25:15 +0000998
David Greene2a9de4d2010-09-03 21:00:49 +0000999RecTy *TypedInit::getFieldType(const std::string &FieldName) const {
1000 RecordRecTy *RecordType = dynamic_cast<RecordRecTy *>(getType());
1001 if (RecordType) {
1002 RecordVal *Field = RecordType->getRecord()->getValue(FieldName);
1003 if (Field) {
1004 return Field->getType();
1005 }
1006 }
1007 return 0;
1008}
1009
Chris Lattner577fc3f2004-07-27 01:01:21 +00001010Init *TypedInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001011 BitsRecTy *T = dynamic_cast<BitsRecTy*>(getType());
Bill Wendling73a48d82010-12-10 22:54:30 +00001012 if (T == 0) return 0; // Cannot subscript a non-bits variable.
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001013 unsigned NumBits = T->getNumBits();
1014
1015 BitsInit *BI = new BitsInit(Bits.size());
1016 for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
1017 if (Bits[i] >= NumBits) {
1018 delete BI;
1019 return 0;
1020 }
1021 BI->setBit(i, new VarBitInit(this, Bits[i]));
1022 }
1023 return BI;
1024}
1025
Chris Lattner577fc3f2004-07-27 01:01:21 +00001026Init *TypedInit::convertInitListSlice(const std::vector<unsigned> &Elements) {
1027 ListRecTy *T = dynamic_cast<ListRecTy*>(getType());
Bill Wendling73a48d82010-12-10 22:54:30 +00001028 if (T == 0) return 0; // Cannot subscript a non-list variable.
Chris Lattner577fc3f2004-07-27 01:01:21 +00001029
1030 if (Elements.size() == 1)
1031 return new VarListElementInit(this, Elements[0]);
1032
1033 std::vector<Init*> ListInits;
1034 ListInits.reserve(Elements.size());
1035 for (unsigned i = 0, e = Elements.size(); i != e; ++i)
1036 ListInits.push_back(new VarListElementInit(this, Elements[i]));
David Greene8618f952009-06-08 20:23:18 +00001037 return new ListInit(ListInits, T);
Chris Lattner577fc3f2004-07-27 01:01:21 +00001038}
1039
1040
Chris Lattneref943742005-04-19 03:36:21 +00001041Init *VarInit::resolveBitReference(Record &R, const RecordVal *IRV,
1042 unsigned Bit) {
1043 if (R.isTemplateArg(getName())) return 0;
1044 if (IRV && IRV->getName() != getName()) return 0;
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001045
1046 RecordVal *RV = R.getValue(getName());
Bob Wilson159905a2009-11-21 22:44:20 +00001047 assert(RV && "Reference to a non-existent variable?");
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001048 assert(dynamic_cast<BitsInit*>(RV->getValue()));
1049 BitsInit *BI = (BitsInit*)RV->getValue();
Misha Brukman650ba8e2005-04-22 00:00:37 +00001050
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001051 assert(Bit < BI->getNumBits() && "Bit reference out of range!");
1052 Init *B = BI->getBit(Bit);
1053
Bob Wilson67e6cab2009-11-22 03:58:57 +00001054 // If the bit is set to some value, or if we are resolving a reference to a
1055 // specific variable and that variable is explicitly unset, then replace the
1056 // VarBitInit with it.
1057 if (IRV || !dynamic_cast<UnsetInit*>(B))
1058 return B;
Chris Lattner577fc3f2004-07-27 01:01:21 +00001059 return 0;
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001060}
1061
Chris Lattneref943742005-04-19 03:36:21 +00001062Init *VarInit::resolveListElementReference(Record &R, const RecordVal *IRV,
1063 unsigned Elt) {
1064 if (R.isTemplateArg(getName())) return 0;
1065 if (IRV && IRV->getName() != getName()) return 0;
Chris Lattner577fc3f2004-07-27 01:01:21 +00001066
1067 RecordVal *RV = R.getValue(getName());
Bob Wilson159905a2009-11-21 22:44:20 +00001068 assert(RV && "Reference to a non-existent variable?");
Chris Lattner577fc3f2004-07-27 01:01:21 +00001069 ListInit *LI = dynamic_cast<ListInit*>(RV->getValue());
David Greene9d3febe2009-05-14 20:38:52 +00001070 if (!LI) {
1071 VarInit *VI = dynamic_cast<VarInit*>(RV->getValue());
1072 assert(VI && "Invalid list element!");
1073 return new VarListElementInit(VI, Elt);
1074 }
Bob Wilson7248f862009-11-22 04:24:42 +00001075
Chris Lattner577fc3f2004-07-27 01:01:21 +00001076 if (Elt >= LI->getSize())
1077 return 0; // Out of range reference.
1078 Init *E = LI->getElement(Elt);
Bob Wilson67e6cab2009-11-22 03:58:57 +00001079 // If the element is set to some value, or if we are resolving a reference
1080 // to a specific variable and that variable is explicitly unset, then
1081 // replace the VarListElementInit with it.
1082 if (IRV || !dynamic_cast<UnsetInit*>(E))
1083 return E;
Chris Lattner577fc3f2004-07-27 01:01:21 +00001084 return 0;
1085}
1086
1087
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001088RecTy *VarInit::getFieldType(const std::string &FieldName) const {
1089 if (RecordRecTy *RTy = dynamic_cast<RecordRecTy*>(getType()))
1090 if (const RecordVal *RV = RTy->getRecord()->getValue(FieldName))
1091 return RV->getType();
1092 return 0;
1093}
1094
Jakob Stoklund Olesen0e457622010-03-25 06:23:34 +00001095Init *VarInit::getFieldInit(Record &R, const RecordVal *RV,
1096 const std::string &FieldName) const {
Reid Spencer2a826862006-11-02 20:46:16 +00001097 if (dynamic_cast<RecordRecTy*>(getType()))
Jakob Stoklund Olesen0e457622010-03-25 06:23:34 +00001098 if (const RecordVal *Val = R.getValue(VarName)) {
1099 if (RV != Val && (RV || dynamic_cast<UnsetInit*>(Val->getValue())))
1100 return 0;
1101 Init *TheInit = Val->getValue();
Chris Lattnerd959ab92004-02-28 16:31:53 +00001102 assert(TheInit != this && "Infinite loop detected!");
Jakob Stoklund Olesen0e457622010-03-25 06:23:34 +00001103 if (Init *I = TheInit->getFieldInit(R, RV, FieldName))
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001104 return I;
1105 else
1106 return 0;
Chris Lattnerd959ab92004-02-28 16:31:53 +00001107 }
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001108 return 0;
1109}
1110
1111/// resolveReferences - This method is used by classes that refer to other
Bob Wilson159905a2009-11-21 22:44:20 +00001112/// variables which may not be defined at the time the expression is formed.
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001113/// If a value is set for the variable later, this method will be called on
1114/// users of the value to allow the value to propagate out.
1115///
Chris Lattneref943742005-04-19 03:36:21 +00001116Init *VarInit::resolveReferences(Record &R, const RecordVal *RV) {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001117 if (RecordVal *Val = R.getValue(VarName))
Chris Lattneref943742005-04-19 03:36:21 +00001118 if (RV == Val || (RV == 0 && !dynamic_cast<UnsetInit*>(Val->getValue())))
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001119 return Val->getValue();
1120 return this;
1121}
Misha Brukman650ba8e2005-04-22 00:00:37 +00001122
Chris Lattner695506c2007-11-22 21:05:25 +00001123std::string VarBitInit::getAsString() const {
1124 return TI->getAsString() + "{" + utostr(Bit) + "}";
1125}
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001126
Chris Lattneref943742005-04-19 03:36:21 +00001127Init *VarBitInit::resolveReferences(Record &R, const RecordVal *RV) {
1128 if (Init *I = getVariable()->resolveBitReference(R, RV, getBitNum()))
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001129 return I;
1130 return this;
1131}
1132
Chris Lattner695506c2007-11-22 21:05:25 +00001133std::string VarListElementInit::getAsString() const {
1134 return TI->getAsString() + "[" + utostr(Element) + "]";
1135}
1136
Chris Lattneref943742005-04-19 03:36:21 +00001137Init *VarListElementInit::resolveReferences(Record &R, const RecordVal *RV) {
1138 if (Init *I = getVariable()->resolveListElementReference(R, RV,
1139 getElementNum()))
Chris Lattner577fc3f2004-07-27 01:01:21 +00001140 return I;
1141 return this;
1142}
1143
Chris Lattneref943742005-04-19 03:36:21 +00001144Init *VarListElementInit::resolveBitReference(Record &R, const RecordVal *RV,
1145 unsigned Bit) {
Chris Lattner577fc3f2004-07-27 01:01:21 +00001146 // FIXME: This should be implemented, to support references like:
1147 // bit B = AA[0]{1};
1148 return 0;
1149}
1150
Chris Lattneref943742005-04-19 03:36:21 +00001151Init *VarListElementInit::
1152resolveListElementReference(Record &R, const RecordVal *RV, unsigned Elt) {
Chris Lattner577fc3f2004-07-27 01:01:21 +00001153 // FIXME: This should be implemented, to support references like:
1154 // int B = AA[0][1];
1155 return 0;
1156}
1157
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001158RecTy *DefInit::getFieldType(const std::string &FieldName) const {
1159 if (const RecordVal *RV = Def->getValue(FieldName))
1160 return RV->getType();
1161 return 0;
1162}
1163
Jakob Stoklund Olesen0e457622010-03-25 06:23:34 +00001164Init *DefInit::getFieldInit(Record &R, const RecordVal *RV,
1165 const std::string &FieldName) const {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001166 return Def->getValue(FieldName)->getValue();
1167}
1168
1169
Chris Lattner695506c2007-11-22 21:05:25 +00001170std::string DefInit::getAsString() const {
1171 return Def->getName();
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001172}
1173
Chris Lattneref943742005-04-19 03:36:21 +00001174Init *FieldInit::resolveBitReference(Record &R, const RecordVal *RV,
1175 unsigned Bit) {
Jakob Stoklund Olesen0e457622010-03-25 06:23:34 +00001176 if (Init *BitsVal = Rec->getFieldInit(R, RV, FieldName))
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001177 if (BitsInit *BI = dynamic_cast<BitsInit*>(BitsVal)) {
1178 assert(Bit < BI->getNumBits() && "Bit reference out of range!");
1179 Init *B = BI->getBit(Bit);
Misha Brukman650ba8e2005-04-22 00:00:37 +00001180
Bill Wendling73a48d82010-12-10 22:54:30 +00001181 if (dynamic_cast<BitInit*>(B)) // If the bit is set.
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001182 return B; // Replace the VarBitInit with it.
1183 }
Chris Lattner577fc3f2004-07-27 01:01:21 +00001184 return 0;
1185}
1186
Chris Lattneref943742005-04-19 03:36:21 +00001187Init *FieldInit::resolveListElementReference(Record &R, const RecordVal *RV,
1188 unsigned Elt) {
Jakob Stoklund Olesen0e457622010-03-25 06:23:34 +00001189 if (Init *ListVal = Rec->getFieldInit(R, RV, FieldName))
Chris Lattner577fc3f2004-07-27 01:01:21 +00001190 if (ListInit *LI = dynamic_cast<ListInit*>(ListVal)) {
1191 if (Elt >= LI->getSize()) return 0;
1192 Init *E = LI->getElement(Elt);
1193
Bob Wilson67e6cab2009-11-22 03:58:57 +00001194 // If the element is set to some value, or if we are resolving a
1195 // reference to a specific variable and that variable is explicitly
1196 // unset, then replace the VarListElementInit with it.
1197 if (RV || !dynamic_cast<UnsetInit*>(E))
1198 return E;
Chris Lattner577fc3f2004-07-27 01:01:21 +00001199 }
1200 return 0;
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001201}
1202
Chris Lattneref943742005-04-19 03:36:21 +00001203Init *FieldInit::resolveReferences(Record &R, const RecordVal *RV) {
1204 Init *NewRec = RV ? Rec->resolveReferences(R, RV) : Rec;
1205
Jakob Stoklund Olesen0e457622010-03-25 06:23:34 +00001206 Init *BitsVal = NewRec->getFieldInit(R, RV, FieldName);
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001207 if (BitsVal) {
Chris Lattneref943742005-04-19 03:36:21 +00001208 Init *BVR = BitsVal->resolveReferences(R, RV);
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001209 return BVR->isComplete() ? BVR : this;
1210 }
Chris Lattneref943742005-04-19 03:36:21 +00001211
1212 if (NewRec != Rec) {
Chris Lattneref943742005-04-19 03:36:21 +00001213 return new FieldInit(NewRec, FieldName);
1214 }
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001215 return this;
1216}
1217
Chris Lattner0d3ef402006-01-31 06:02:35 +00001218Init *DagInit::resolveReferences(Record &R, const RecordVal *RV) {
1219 std::vector<Init*> NewArgs;
1220 for (unsigned i = 0, e = Args.size(); i != e; ++i)
1221 NewArgs.push_back(Args[i]->resolveReferences(R, RV));
Bob Wilson7248f862009-11-22 04:24:42 +00001222
Chris Lattnerb59cf3c2006-03-30 22:50:40 +00001223 Init *Op = Val->resolveReferences(R, RV);
Bob Wilson7248f862009-11-22 04:24:42 +00001224
Chris Lattnerb59cf3c2006-03-30 22:50:40 +00001225 if (Args != NewArgs || Op != Val)
Bruno Cardoso Lopes30a28d62010-06-23 19:50:39 +00001226 return new DagInit(Op, ValName, NewArgs, ArgNames);
Bob Wilson7248f862009-11-22 04:24:42 +00001227
Chris Lattner0d3ef402006-01-31 06:02:35 +00001228 return this;
1229}
1230
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001231
Chris Lattner695506c2007-11-22 21:05:25 +00001232std::string DagInit::getAsString() const {
1233 std::string Result = "(" + Val->getAsString();
Nate Begemandbe3f772009-03-19 05:21:56 +00001234 if (!ValName.empty())
1235 Result += ":" + ValName;
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001236 if (Args.size()) {
Chris Lattner695506c2007-11-22 21:05:25 +00001237 Result += " " + Args[0]->getAsString();
1238 if (!ArgNames[0].empty()) Result += ":$" + ArgNames[0];
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001239 for (unsigned i = 1, e = Args.size(); i != e; ++i) {
Chris Lattner695506c2007-11-22 21:05:25 +00001240 Result += ", " + Args[i]->getAsString();
1241 if (!ArgNames[i].empty()) Result += ":$" + ArgNames[i];
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001242 }
1243 }
Chris Lattner695506c2007-11-22 21:05:25 +00001244 return Result + ")";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001245}
1246
1247
1248//===----------------------------------------------------------------------===//
1249// Other implementations
1250//===----------------------------------------------------------------------===//
1251
1252RecordVal::RecordVal(const std::string &N, RecTy *T, unsigned P)
1253 : Name(N), Ty(T), Prefix(P) {
1254 Value = Ty->convertValue(new UnsetInit());
1255 assert(Value && "Cannot create unset value for current type!");
1256}
1257
Daniel Dunbar38a22bf2009-07-03 00:10:29 +00001258void RecordVal::dump() const { errs() << *this; }
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001259
Daniel Dunbar38a22bf2009-07-03 00:10:29 +00001260void RecordVal::print(raw_ostream &OS, bool PrintSem) const {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001261 if (getPrefix()) OS << "field ";
1262 OS << *getType() << " " << getName();
Chris Lattneref943742005-04-19 03:36:21 +00001263
1264 if (getValue())
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001265 OS << " = " << *getValue();
Chris Lattneref943742005-04-19 03:36:21 +00001266
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001267 if (PrintSem) OS << ";\n";
1268}
1269
Daniel Dunbarced00812009-08-23 09:47:37 +00001270unsigned Record::LastID = 0;
1271
Chris Lattnerac284252005-08-19 17:58:11 +00001272void Record::setName(const std::string &Name) {
Chris Lattner77d369c2010-12-13 00:23:57 +00001273 if (TrackedRecords.getDef(getName()) == this) {
1274 TrackedRecords.removeDef(getName());
Chris Lattnerac284252005-08-19 17:58:11 +00001275 this->Name = Name;
Chris Lattner77d369c2010-12-13 00:23:57 +00001276 TrackedRecords.addDef(this);
Chris Lattnerac284252005-08-19 17:58:11 +00001277 } else {
Chris Lattner77d369c2010-12-13 00:23:57 +00001278 TrackedRecords.removeClass(getName());
Chris Lattnerac284252005-08-19 17:58:11 +00001279 this->Name = Name;
Chris Lattner77d369c2010-12-13 00:23:57 +00001280 TrackedRecords.addClass(this);
Chris Lattnerac284252005-08-19 17:58:11 +00001281 }
1282}
1283
Chris Lattneref943742005-04-19 03:36:21 +00001284/// resolveReferencesTo - If anything in this record refers to RV, replace the
1285/// reference to RV with the RHS of RV. If RV is null, we resolve all possible
1286/// references.
1287void Record::resolveReferencesTo(const RecordVal *RV) {
1288 for (unsigned i = 0, e = Values.size(); i != e; ++i) {
1289 if (Init *V = Values[i].getValue())
1290 Values[i].setValue(V->resolveReferences(*this, RV));
1291 }
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001292}
1293
Daniel Dunbar38a22bf2009-07-03 00:10:29 +00001294void Record::dump() const { errs() << *this; }
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001295
Daniel Dunbar38a22bf2009-07-03 00:10:29 +00001296raw_ostream &llvm::operator<<(raw_ostream &OS, const Record &R) {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001297 OS << R.getName();
1298
1299 const std::vector<std::string> &TArgs = R.getTemplateArgs();
1300 if (!TArgs.empty()) {
1301 OS << "<";
1302 for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
1303 if (i) OS << ", ";
1304 const RecordVal *RV = R.getValue(TArgs[i]);
1305 assert(RV && "Template argument record not found??");
1306 RV->print(OS, false);
1307 }
1308 OS << ">";
1309 }
1310
1311 OS << " {";
1312 const std::vector<Record*> &SC = R.getSuperClasses();
1313 if (!SC.empty()) {
1314 OS << "\t//";
1315 for (unsigned i = 0, e = SC.size(); i != e; ++i)
1316 OS << " " << SC[i]->getName();
1317 }
1318 OS << "\n";
1319
1320 const std::vector<RecordVal> &Vals = R.getValues();
1321 for (unsigned i = 0, e = Vals.size(); i != e; ++i)
1322 if (Vals[i].getPrefix() && !R.isTemplateArg(Vals[i].getName()))
1323 OS << Vals[i];
1324 for (unsigned i = 0, e = Vals.size(); i != e; ++i)
1325 if (!Vals[i].getPrefix() && !R.isTemplateArg(Vals[i].getName()))
1326 OS << Vals[i];
1327
1328 return OS << "}\n";
1329}
1330
1331/// getValueInit - Return the initializer for a value with the specified name,
1332/// or throw an exception if the field does not exist.
1333///
Chris Lattner42bb0c12009-09-18 18:31:37 +00001334Init *Record::getValueInit(StringRef FieldName) const {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001335 const RecordVal *R = getValue(FieldName);
1336 if (R == 0 || R->getValue() == 0)
Misha Brukman41f9f292004-10-08 14:59:05 +00001337 throw "Record `" + getName() + "' does not have a field named `" +
Chris Lattner42bb0c12009-09-18 18:31:37 +00001338 FieldName.str() + "'!\n";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001339 return R->getValue();
1340}
1341
1342
1343/// getValueAsString - This method looks up the specified field and returns its
1344/// value as a string, throwing an exception if the field does not exist or if
1345/// the value is not a string.
1346///
Chris Lattner42bb0c12009-09-18 18:31:37 +00001347std::string Record::getValueAsString(StringRef FieldName) const {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001348 const RecordVal *R = getValue(FieldName);
1349 if (R == 0 || R->getValue() == 0)
Misha Brukman41f9f292004-10-08 14:59:05 +00001350 throw "Record `" + getName() + "' does not have a field named `" +
Chris Lattner42bb0c12009-09-18 18:31:37 +00001351 FieldName.str() + "'!\n";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001352
1353 if (const StringInit *SI = dynamic_cast<const StringInit*>(R->getValue()))
1354 return SI->getValue();
Chris Lattner42bb0c12009-09-18 18:31:37 +00001355 throw "Record `" + getName() + "', field `" + FieldName.str() +
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001356 "' does not have a string initializer!";
1357}
1358
1359/// getValueAsBitsInit - This method looks up the specified field and returns
1360/// its value as a BitsInit, throwing an exception if the field does not exist
1361/// or if the value is not the right type.
1362///
Chris Lattner42bb0c12009-09-18 18:31:37 +00001363BitsInit *Record::getValueAsBitsInit(StringRef FieldName) const {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001364 const RecordVal *R = getValue(FieldName);
1365 if (R == 0 || R->getValue() == 0)
Misha Brukman41f9f292004-10-08 14:59:05 +00001366 throw "Record `" + getName() + "' does not have a field named `" +
Chris Lattner42bb0c12009-09-18 18:31:37 +00001367 FieldName.str() + "'!\n";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001368
1369 if (BitsInit *BI = dynamic_cast<BitsInit*>(R->getValue()))
1370 return BI;
Chris Lattner42bb0c12009-09-18 18:31:37 +00001371 throw "Record `" + getName() + "', field `" + FieldName.str() +
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001372 "' does not have a BitsInit initializer!";
1373}
1374
1375/// getValueAsListInit - This method looks up the specified field and returns
1376/// its value as a ListInit, throwing an exception if the field does not exist
1377/// or if the value is not the right type.
1378///
Chris Lattner42bb0c12009-09-18 18:31:37 +00001379ListInit *Record::getValueAsListInit(StringRef FieldName) const {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001380 const RecordVal *R = getValue(FieldName);
1381 if (R == 0 || R->getValue() == 0)
Misha Brukman41f9f292004-10-08 14:59:05 +00001382 throw "Record `" + getName() + "' does not have a field named `" +
Chris Lattner42bb0c12009-09-18 18:31:37 +00001383 FieldName.str() + "'!\n";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001384
1385 if (ListInit *LI = dynamic_cast<ListInit*>(R->getValue()))
1386 return LI;
Chris Lattner42bb0c12009-09-18 18:31:37 +00001387 throw "Record `" + getName() + "', field `" + FieldName.str() +
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001388 "' does not have a list initializer!";
1389}
1390
Chris Lattner7ad0bed2005-10-28 22:49:02 +00001391/// getValueAsListOfDefs - This method looks up the specified field and returns
Jim Laskeyb04feb62005-10-28 21:46:31 +00001392/// its value as a vector of records, throwing an exception if the field does
1393/// not exist or if the value is not the right type.
1394///
Bob Wilson7248f862009-11-22 04:24:42 +00001395std::vector<Record*>
Chris Lattner42bb0c12009-09-18 18:31:37 +00001396Record::getValueAsListOfDefs(StringRef FieldName) const {
Jim Laskeyb04feb62005-10-28 21:46:31 +00001397 ListInit *List = getValueAsListInit(FieldName);
1398 std::vector<Record*> Defs;
1399 for (unsigned i = 0; i < List->getSize(); i++) {
1400 if (DefInit *DI = dynamic_cast<DefInit*>(List->getElement(i))) {
1401 Defs.push_back(DI->getDef());
1402 } else {
Chris Lattner42bb0c12009-09-18 18:31:37 +00001403 throw "Record `" + getName() + "', field `" + FieldName.str() +
Jim Laskeyb04feb62005-10-28 21:46:31 +00001404 "' list is not entirely DefInit!";
1405 }
1406 }
1407 return Defs;
1408}
1409
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001410/// getValueAsInt - This method looks up the specified field and returns its
Dan Gohmanca0546f2008-10-17 01:33:43 +00001411/// value as an int64_t, throwing an exception if the field does not exist or if
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001412/// the value is not the right type.
1413///
Chris Lattner42bb0c12009-09-18 18:31:37 +00001414int64_t Record::getValueAsInt(StringRef FieldName) const {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001415 const RecordVal *R = getValue(FieldName);
1416 if (R == 0 || R->getValue() == 0)
Misha Brukman41f9f292004-10-08 14:59:05 +00001417 throw "Record `" + getName() + "' does not have a field named `" +
Chris Lattner42bb0c12009-09-18 18:31:37 +00001418 FieldName.str() + "'!\n";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001419
1420 if (IntInit *II = dynamic_cast<IntInit*>(R->getValue()))
1421 return II->getValue();
Chris Lattner42bb0c12009-09-18 18:31:37 +00001422 throw "Record `" + getName() + "', field `" + FieldName.str() +
Nate Begemanf621b332005-11-30 18:37:14 +00001423 "' does not have an int initializer!";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001424}
1425
Anton Korobeynikova468a112007-11-11 11:19:37 +00001426/// getValueAsListOfInts - This method looks up the specified field and returns
1427/// its value as a vector of integers, throwing an exception if the field does
1428/// not exist or if the value is not the right type.
1429///
Bob Wilson7248f862009-11-22 04:24:42 +00001430std::vector<int64_t>
Chris Lattner42bb0c12009-09-18 18:31:37 +00001431Record::getValueAsListOfInts(StringRef FieldName) const {
Anton Korobeynikova468a112007-11-11 11:19:37 +00001432 ListInit *List = getValueAsListInit(FieldName);
Dan Gohmanca0546f2008-10-17 01:33:43 +00001433 std::vector<int64_t> Ints;
Anton Korobeynikova468a112007-11-11 11:19:37 +00001434 for (unsigned i = 0; i < List->getSize(); i++) {
1435 if (IntInit *II = dynamic_cast<IntInit*>(List->getElement(i))) {
1436 Ints.push_back(II->getValue());
1437 } else {
Chris Lattner42bb0c12009-09-18 18:31:37 +00001438 throw "Record `" + getName() + "', field `" + FieldName.str() +
Anton Korobeynikova468a112007-11-11 11:19:37 +00001439 "' does not have a list of ints initializer!";
1440 }
1441 }
1442 return Ints;
1443}
1444
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001445/// getValueAsDef - This method looks up the specified field and returns its
1446/// value as a Record, throwing an exception if the field does not exist or if
1447/// the value is not the right type.
1448///
Chris Lattner42bb0c12009-09-18 18:31:37 +00001449Record *Record::getValueAsDef(StringRef FieldName) const {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001450 const RecordVal *R = getValue(FieldName);
1451 if (R == 0 || R->getValue() == 0)
Misha Brukman41f9f292004-10-08 14:59:05 +00001452 throw "Record `" + getName() + "' does not have a field named `" +
Chris Lattner42bb0c12009-09-18 18:31:37 +00001453 FieldName.str() + "'!\n";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001454
1455 if (DefInit *DI = dynamic_cast<DefInit*>(R->getValue()))
1456 return DI->getDef();
Chris Lattner42bb0c12009-09-18 18:31:37 +00001457 throw "Record `" + getName() + "', field `" + FieldName.str() +
Nate Begemanf621b332005-11-30 18:37:14 +00001458 "' does not have a def initializer!";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001459}
1460
1461/// getValueAsBit - This method looks up the specified field and returns its
1462/// value as a bit, throwing an exception if the field does not exist or if
1463/// the value is not the right type.
1464///
Chris Lattner42bb0c12009-09-18 18:31:37 +00001465bool Record::getValueAsBit(StringRef FieldName) const {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001466 const RecordVal *R = getValue(FieldName);
1467 if (R == 0 || R->getValue() == 0)
Misha Brukman41f9f292004-10-08 14:59:05 +00001468 throw "Record `" + getName() + "' does not have a field named `" +
Chris Lattner42bb0c12009-09-18 18:31:37 +00001469 FieldName.str() + "'!\n";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001470
1471 if (BitInit *BI = dynamic_cast<BitInit*>(R->getValue()))
1472 return BI->getValue();
Chris Lattner42bb0c12009-09-18 18:31:37 +00001473 throw "Record `" + getName() + "', field `" + FieldName.str() +
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001474 "' does not have a bit initializer!";
1475}
1476
1477/// getValueAsDag - This method looks up the specified field and returns its
1478/// value as an Dag, throwing an exception if the field does not exist or if
1479/// the value is not the right type.
1480///
Chris Lattner42bb0c12009-09-18 18:31:37 +00001481DagInit *Record::getValueAsDag(StringRef FieldName) const {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001482 const RecordVal *R = getValue(FieldName);
1483 if (R == 0 || R->getValue() == 0)
Misha Brukman41f9f292004-10-08 14:59:05 +00001484 throw "Record `" + getName() + "' does not have a field named `" +
Chris Lattner42bb0c12009-09-18 18:31:37 +00001485 FieldName.str() + "'!\n";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001486
1487 if (DagInit *DI = dynamic_cast<DagInit*>(R->getValue()))
1488 return DI;
Chris Lattner42bb0c12009-09-18 18:31:37 +00001489 throw "Record `" + getName() + "', field `" + FieldName.str() +
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001490 "' does not have a dag initializer!";
1491}
1492
Chris Lattner42bb0c12009-09-18 18:31:37 +00001493std::string Record::getValueAsCode(StringRef FieldName) const {
Chris Lattnerae939eb2005-09-13 21:44:28 +00001494 const RecordVal *R = getValue(FieldName);
1495 if (R == 0 || R->getValue() == 0)
1496 throw "Record `" + getName() + "' does not have a field named `" +
Chris Lattner42bb0c12009-09-18 18:31:37 +00001497 FieldName.str() + "'!\n";
Bob Wilson7248f862009-11-22 04:24:42 +00001498
Chris Lattnerae939eb2005-09-13 21:44:28 +00001499 if (const CodeInit *CI = dynamic_cast<const CodeInit*>(R->getValue()))
1500 return CI->getValue();
Chris Lattner42bb0c12009-09-18 18:31:37 +00001501 throw "Record `" + getName() + "', field `" + FieldName.str() +
Chris Lattnerae939eb2005-09-13 21:44:28 +00001502 "' does not have a code initializer!";
1503}
1504
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001505
David Greene7049e792009-04-24 16:55:41 +00001506void MultiClass::dump() const {
Daniel Dunbar38a22bf2009-07-03 00:10:29 +00001507 errs() << "Record:\n";
David Greene7049e792009-04-24 16:55:41 +00001508 Rec.dump();
Bob Wilson7248f862009-11-22 04:24:42 +00001509
Daniel Dunbar38a22bf2009-07-03 00:10:29 +00001510 errs() << "Defs:\n";
David Greene7049e792009-04-24 16:55:41 +00001511 for (RecordVector::const_iterator r = DefPrototypes.begin(),
1512 rend = DefPrototypes.end();
1513 r != rend;
1514 ++r) {
1515 (*r)->dump();
1516 }
1517}
1518
1519
Daniel Dunbar38a22bf2009-07-03 00:10:29 +00001520void RecordKeeper::dump() const { errs() << *this; }
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001521
Daniel Dunbar38a22bf2009-07-03 00:10:29 +00001522raw_ostream &llvm::operator<<(raw_ostream &OS, const RecordKeeper &RK) {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001523 OS << "------------- Classes -----------------\n";
1524 const std::map<std::string, Record*> &Classes = RK.getClasses();
1525 for (std::map<std::string, Record*>::const_iterator I = Classes.begin(),
Jeff Cohen88e7b722005-04-22 04:13:13 +00001526 E = Classes.end(); I != E; ++I)
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001527 OS << "class " << *I->second;
Misha Brukman650ba8e2005-04-22 00:00:37 +00001528
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001529 OS << "------------- Defs -----------------\n";
1530 const std::map<std::string, Record*> &Defs = RK.getDefs();
1531 for (std::map<std::string, Record*>::const_iterator I = Defs.begin(),
Jeff Cohen88e7b722005-04-22 04:13:13 +00001532 E = Defs.end(); I != E; ++I)
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001533 OS << "def " << *I->second;
1534 return OS;
1535}
1536
1537
1538/// getAllDerivedDefinitions - This method returns all concrete definitions
1539/// that derive from the specified class name. If a class with the specified
1540/// name does not exist, an error is printed and true is returned.
1541std::vector<Record*>
1542RecordKeeper::getAllDerivedDefinitions(const std::string &ClassName) const {
Chris Lattner97049072010-12-13 00:20:52 +00001543 Record *Class = getClass(ClassName);
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001544 if (!Class)
Misha Brukman41f9f292004-10-08 14:59:05 +00001545 throw "ERROR: Couldn't find the `" + ClassName + "' class!\n";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001546
1547 std::vector<Record*> Defs;
1548 for (std::map<std::string, Record*>::const_iterator I = getDefs().begin(),
1549 E = getDefs().end(); I != E; ++I)
1550 if (I->second->isSubClassOf(Class))
1551 Defs.push_back(I->second);
1552
1553 return Defs;
1554}
Brian Gaeke960707c2003-11-11 22:41:34 +00001555