blob: 730eca1b3ca5d94e087e3b6c8e4271587ef65788 [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"
Jim Grosbach797cff02011-06-21 22:55:50 +000015#include "Error.h"
Michael J. Spencer447762d2010-11-29 18:16:10 +000016#include "llvm/Support/DataTypes.h"
Daniel Dunbar38a22bf2009-07-03 00:10:29 +000017#include "llvm/Support/Format.h"
Chris Lattner8b9ecda2007-11-20 22:25:16 +000018#include "llvm/ADT/StringExtras.h"
Duraid Madina14492af2005-12-26 05:08:55 +000019
Chris Lattner68478662004-08-01 03:55:39 +000020using namespace llvm;
Chris Lattnerf5bd1b72003-10-05 19:27:59 +000021
22//===----------------------------------------------------------------------===//
23// Type implementations
24//===----------------------------------------------------------------------===//
25
Daniel Dunbar38a22bf2009-07-03 00:10:29 +000026void RecTy::dump() const { print(errs()); }
Chris Lattnerf5bd1b72003-10-05 19:27:59 +000027
28Init *BitRecTy::convertValue(BitsInit *BI) {
29 if (BI->getNumBits() != 1) return 0; // Only accept if just one bit!
30 return BI->getBit(0);
31}
32
33bool BitRecTy::baseClassOf(const BitsRecTy *RHS) const {
34 return RHS->getNumBits() == 1;
35}
36
37Init *BitRecTy::convertValue(IntInit *II) {
Dan Gohmanca0546f2008-10-17 01:33:43 +000038 int64_t Val = II->getValue();
Chris Lattnerf5bd1b72003-10-05 19:27:59 +000039 if (Val != 0 && Val != 1) return 0; // Only accept 0 or 1 for a bit!
Misha Brukman650ba8e2005-04-22 00:00:37 +000040
41 return new BitInit(Val != 0);
Chris Lattnerf5bd1b72003-10-05 19:27:59 +000042}
43
44Init *BitRecTy::convertValue(TypedInit *VI) {
45 if (dynamic_cast<BitRecTy*>(VI->getType()))
46 return VI; // Accept variable if it is already of bit type!
47 return 0;
48}
49
Chris Lattner8b9ecda2007-11-20 22:25:16 +000050std::string BitsRecTy::getAsString() const {
51 return "bits<" + utostr(Size) + ">";
52}
53
Chris Lattnerf5bd1b72003-10-05 19:27:59 +000054Init *BitsRecTy::convertValue(UnsetInit *UI) {
55 BitsInit *Ret = new BitsInit(Size);
56
57 for (unsigned i = 0; i != Size; ++i)
58 Ret->setBit(i, new UnsetInit());
59 return Ret;
60}
61
62Init *BitsRecTy::convertValue(BitInit *UI) {
Bill Wendling73a48d82010-12-10 22:54:30 +000063 if (Size != 1) return 0; // Can only convert single bit.
Chris Lattnerf5bd1b72003-10-05 19:27:59 +000064 BitsInit *Ret = new BitsInit(1);
65 Ret->setBit(0, UI);
66 return Ret;
67}
68
Bill Wendling73ce4a62010-12-13 01:46:19 +000069/// canFitInBitfield - Return true if the number of bits is large enough to hold
70/// the integer value.
71static bool canFitInBitfield(int64_t Value, unsigned NumBits) {
Nick Lewycky79286bf2011-06-03 08:25:39 +000072 // For example, with NumBits == 4, we permit Values from [-7 .. 15].
73 return (NumBits >= sizeof(Value) * 8) ||
74 (Value >> NumBits == 0) || (Value >> (NumBits-1) == -1);
Bill Wendling73ce4a62010-12-13 01:46:19 +000075}
76
77/// convertValue from Int initializer to bits type: Split the integer up into the
78/// appropriate bits.
79///
Chris Lattnerf5bd1b72003-10-05 19:27:59 +000080Init *BitsRecTy::convertValue(IntInit *II) {
Misha Brukman6752fb52004-06-21 18:01:47 +000081 int64_t Value = II->getValue();
Bill Wendling73a48d82010-12-10 22:54:30 +000082 // Make sure this bitfield is large enough to hold the integer value.
Bill Wendling73ce4a62010-12-13 01:46:19 +000083 if (!canFitInBitfield(Value, Size))
84 return 0;
Chris Lattnerf5bd1b72003-10-05 19:27:59 +000085
86 BitsInit *Ret = new BitsInit(Size);
87 for (unsigned i = 0; i != Size; ++i)
Jeff Cohen0add83e2006-02-18 03:20:33 +000088 Ret->setBit(i, new BitInit(Value & (1LL << i)));
Chris Lattnerf5bd1b72003-10-05 19:27:59 +000089
90 return Ret;
91}
92
93Init *BitsRecTy::convertValue(BitsInit *BI) {
94 // If the number of bits is right, return it. Otherwise we need to expand or
Bill Wendling73a48d82010-12-10 22:54:30 +000095 // truncate.
Chris Lattnerf5bd1b72003-10-05 19:27:59 +000096 if (BI->getNumBits() == Size) return BI;
97 return 0;
98}
99
100Init *BitsRecTy::convertValue(TypedInit *VI) {
101 if (BitsRecTy *BRT = dynamic_cast<BitsRecTy*>(VI->getType()))
102 if (BRT->Size == Size) {
103 BitsInit *Ret = new BitsInit(Size);
104 for (unsigned i = 0; i != Size; ++i)
Jeff Cohen88e7b722005-04-22 04:13:13 +0000105 Ret->setBit(i, new VarBitInit(VI, i));
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000106 return Ret;
107 }
Bill Wendling73ce4a62010-12-13 01:46:19 +0000108
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000109 if (Size == 1 && dynamic_cast<BitRecTy*>(VI->getType())) {
110 BitsInit *Ret = new BitsInit(1);
111 Ret->setBit(0, VI);
112 return Ret;
113 }
Misha Brukman650ba8e2005-04-22 00:00:37 +0000114
Bill Wendling73ce4a62010-12-13 01:46:19 +0000115 if (TernOpInit *Tern = dynamic_cast<TernOpInit*>(VI)) {
116 if (Tern->getOpcode() == TernOpInit::IF) {
117 Init *LHS = Tern->getLHS();
118 Init *MHS = Tern->getMHS();
119 Init *RHS = Tern->getRHS();
120
121 IntInit *MHSi = dynamic_cast<IntInit*>(MHS);
122 IntInit *RHSi = dynamic_cast<IntInit*>(RHS);
123
124 if (MHSi && RHSi) {
125 int64_t MHSVal = MHSi->getValue();
126 int64_t RHSVal = RHSi->getValue();
127
128 if (canFitInBitfield(MHSVal, Size) && canFitInBitfield(RHSVal, Size)) {
129 BitsInit *Ret = new BitsInit(Size);
130
131 for (unsigned i = 0; i != Size; ++i)
132 Ret->setBit(i, new TernOpInit(TernOpInit::IF, LHS,
133 new IntInit((MHSVal & (1LL << i)) ? 1 : 0),
134 new IntInit((RHSVal & (1LL << i)) ? 1 : 0),
135 VI->getType()));
136
137 return Ret;
138 }
139 } else {
140 BitsInit *MHSbs = dynamic_cast<BitsInit*>(MHS);
141 BitsInit *RHSbs = dynamic_cast<BitsInit*>(RHS);
142
143 if (MHSbs && RHSbs) {
144 BitsInit *Ret = new BitsInit(Size);
145
146 for (unsigned i = 0; i != Size; ++i)
147 Ret->setBit(i, new TernOpInit(TernOpInit::IF, LHS,
148 MHSbs->getBit(i),
149 RHSbs->getBit(i),
150 VI->getType()));
151
152 return Ret;
153 }
154 }
155 }
156 }
157
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000158 return 0;
159}
160
161Init *IntRecTy::convertValue(BitInit *BI) {
162 return new IntInit(BI->getValue());
163}
164
165Init *IntRecTy::convertValue(BitsInit *BI) {
Dan Gohmanca0546f2008-10-17 01:33:43 +0000166 int64_t Result = 0;
Misha Brukman650ba8e2005-04-22 00:00:37 +0000167 for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i)
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000168 if (BitInit *Bit = dynamic_cast<BitInit*>(BI->getBit(i))) {
169 Result |= Bit->getValue() << i;
170 } else {
171 return 0;
172 }
173 return new IntInit(Result);
174}
175
176Init *IntRecTy::convertValue(TypedInit *TI) {
177 if (TI->getType()->typeIsConvertibleTo(this))
178 return TI; // Accept variable if already of the right type!
179 return 0;
180}
181
David Greenee8f3b272009-05-14 21:22:49 +0000182Init *StringRecTy::convertValue(UnOpInit *BO) {
183 if (BO->getOpcode() == UnOpInit::CAST) {
184 Init *L = BO->getOperand()->convertInitializerTo(this);
185 if (L == 0) return 0;
186 if (L != BO->getOperand())
187 return new UnOpInit(UnOpInit::CAST, L, new StringRecTy);
188 return BO;
189 }
David Greene5d0c0512009-05-14 20:54:48 +0000190
David Greenee8f3b272009-05-14 21:22:49 +0000191 return convertValue((TypedInit*)BO);
192}
David Greene5d0c0512009-05-14 20:54:48 +0000193
Chris Lattner51ffbf12006-03-31 21:53:49 +0000194Init *StringRecTy::convertValue(BinOpInit *BO) {
195 if (BO->getOpcode() == BinOpInit::STRCONCAT) {
196 Init *L = BO->getLHS()->convertInitializerTo(this);
197 Init *R = BO->getRHS()->convertInitializerTo(this);
198 if (L == 0 || R == 0) return 0;
199 if (L != BO->getLHS() || R != BO->getRHS())
David Greene196ac3c2009-04-23 21:25:15 +0000200 return new BinOpInit(BinOpInit::STRCONCAT, L, R, new StringRecTy);
Chris Lattner51ffbf12006-03-31 21:53:49 +0000201 return BO;
202 }
David Greene196ac3c2009-04-23 21:25:15 +0000203
204 return convertValue((TypedInit*)BO);
Chris Lattner51ffbf12006-03-31 21:53:49 +0000205}
206
207
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000208Init *StringRecTy::convertValue(TypedInit *TI) {
209 if (dynamic_cast<StringRecTy*>(TI->getType()))
210 return TI; // Accept variable if already of the right type!
211 return 0;
212}
213
Chris Lattner8b9ecda2007-11-20 22:25:16 +0000214std::string ListRecTy::getAsString() const {
215 return "list<" + Ty->getAsString() + ">";
216}
217
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000218Init *ListRecTy::convertValue(ListInit *LI) {
219 std::vector<Init*> Elements;
220
221 // Verify that all of the elements of the list are subclasses of the
222 // appropriate class!
223 for (unsigned i = 0, e = LI->getSize(); i != e; ++i)
224 if (Init *CI = LI->getElement(i)->convertInitializerTo(Ty))
225 Elements.push_back(CI);
226 else
227 return 0;
228
David Greene8618f952009-06-08 20:23:18 +0000229 ListRecTy *LType = dynamic_cast<ListRecTy*>(LI->getType());
230 if (LType == 0) {
231 return 0;
232 }
233
234 return new ListInit(Elements, new ListRecTy(Ty));
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000235}
236
237Init *ListRecTy::convertValue(TypedInit *TI) {
238 // Ensure that TI is compatible with our class.
239 if (ListRecTy *LRT = dynamic_cast<ListRecTy*>(TI->getType()))
240 if (LRT->getElementType()->typeIsConvertibleTo(getElementType()))
241 return TI;
242 return 0;
243}
244
245Init *CodeRecTy::convertValue(TypedInit *TI) {
246 if (TI->getType()->typeIsConvertibleTo(this))
247 return TI;
248 return 0;
249}
250
251Init *DagRecTy::convertValue(TypedInit *TI) {
252 if (TI->getType()->typeIsConvertibleTo(this))
253 return TI;
254 return 0;
255}
256
David Greenee8f3b272009-05-14 21:22:49 +0000257Init *DagRecTy::convertValue(UnOpInit *BO) {
258 if (BO->getOpcode() == UnOpInit::CAST) {
259 Init *L = BO->getOperand()->convertInitializerTo(this);
260 if (L == 0) return 0;
261 if (L != BO->getOperand())
262 return new UnOpInit(UnOpInit::CAST, L, new DagRecTy);
263 return BO;
264 }
265 return 0;
266}
David Greene5d0c0512009-05-14 20:54:48 +0000267
Evan Chenga32dee22007-05-15 01:23:24 +0000268Init *DagRecTy::convertValue(BinOpInit *BO) {
269 if (BO->getOpcode() == BinOpInit::CONCAT) {
270 Init *L = BO->getLHS()->convertInitializerTo(this);
271 Init *R = BO->getRHS()->convertInitializerTo(this);
272 if (L == 0 || R == 0) return 0;
273 if (L != BO->getLHS() || R != BO->getRHS())
David Greene196ac3c2009-04-23 21:25:15 +0000274 return new BinOpInit(BinOpInit::CONCAT, L, R, new DagRecTy);
Evan Chenga32dee22007-05-15 01:23:24 +0000275 return BO;
276 }
277 return 0;
278}
279
Chris Lattner8b9ecda2007-11-20 22:25:16 +0000280std::string RecordRecTy::getAsString() const {
281 return Rec->getName();
282}
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000283
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000284Init *RecordRecTy::convertValue(DefInit *DI) {
285 // Ensure that DI is a subclass of Rec.
286 if (!DI->getDef()->isSubClassOf(Rec))
287 return 0;
288 return DI;
289}
290
291Init *RecordRecTy::convertValue(TypedInit *TI) {
292 // Ensure that TI is compatible with Rec.
293 if (RecordRecTy *RRT = dynamic_cast<RecordRecTy*>(TI->getType()))
294 if (RRT->getRecord()->isSubClassOf(getRecord()) ||
295 RRT->getRecord() == getRecord())
296 return TI;
297 return 0;
298}
299
300bool RecordRecTy::baseClassOf(const RecordRecTy *RHS) const {
Bruno Cardoso Lopesdeb20022010-06-17 23:00:16 +0000301 if (Rec == RHS->getRecord() || RHS->getRecord()->isSubClassOf(Rec))
302 return true;
303
304 const std::vector<Record*> &SC = Rec->getSuperClasses();
305 for (unsigned i = 0, e = SC.size(); i != e; ++i)
306 if (RHS->getRecord()->isSubClassOf(SC[i]))
307 return true;
308
309 return false;
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000310}
311
312
Bob Wilson7248f862009-11-22 04:24:42 +0000313/// resolveTypes - Find a common type that T1 and T2 convert to.
David Greene8618f952009-06-08 20:23:18 +0000314/// Return 0 if no such type exists.
315///
316RecTy *llvm::resolveTypes(RecTy *T1, RecTy *T2) {
317 if (!T1->typeIsConvertibleTo(T2)) {
318 if (!T2->typeIsConvertibleTo(T1)) {
319 // If one is a Record type, check superclasses
320 RecordRecTy *RecTy1 = dynamic_cast<RecordRecTy*>(T1);
321 if (RecTy1) {
322 // See if T2 inherits from a type T1 also inherits from
Bob Wilson7248f862009-11-22 04:24:42 +0000323 const std::vector<Record *> &T1SuperClasses =
324 RecTy1->getRecord()->getSuperClasses();
David Greene8618f952009-06-08 20:23:18 +0000325 for(std::vector<Record *>::const_iterator i = T1SuperClasses.begin(),
326 iend = T1SuperClasses.end();
327 i != iend;
328 ++i) {
329 RecordRecTy *SuperRecTy1 = new RecordRecTy(*i);
330 RecTy *NewType1 = resolveTypes(SuperRecTy1, T2);
331 if (NewType1 != 0) {
332 if (NewType1 != SuperRecTy1) {
333 delete SuperRecTy1;
334 }
335 return NewType1;
336 }
337 }
338 }
339 RecordRecTy *RecTy2 = dynamic_cast<RecordRecTy*>(T2);
340 if (RecTy2) {
341 // See if T1 inherits from a type T2 also inherits from
Bob Wilson7248f862009-11-22 04:24:42 +0000342 const std::vector<Record *> &T2SuperClasses =
343 RecTy2->getRecord()->getSuperClasses();
344 for (std::vector<Record *>::const_iterator i = T2SuperClasses.begin(),
David Greene8618f952009-06-08 20:23:18 +0000345 iend = T2SuperClasses.end();
346 i != iend;
347 ++i) {
348 RecordRecTy *SuperRecTy2 = new RecordRecTy(*i);
349 RecTy *NewType2 = resolveTypes(T1, SuperRecTy2);
350 if (NewType2 != 0) {
351 if (NewType2 != SuperRecTy2) {
352 delete SuperRecTy2;
353 }
354 return NewType2;
355 }
356 }
357 }
358 return 0;
359 }
360 return T2;
361 }
362 return T1;
363}
364
365
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000366//===----------------------------------------------------------------------===//
367// Initializer implementations
368//===----------------------------------------------------------------------===//
369
Daniel Dunbar38a22bf2009-07-03 00:10:29 +0000370void Init::dump() const { return print(errs()); }
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000371
372Init *BitsInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) {
373 BitsInit *BI = new BitsInit(Bits.size());
374 for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
375 if (Bits[i] >= getNumBits()) {
376 delete BI;
377 return 0;
378 }
379 BI->setBit(i, getBit(Bits[i]));
380 }
381 return BI;
382}
383
Chris Lattner695506c2007-11-22 21:05:25 +0000384std::string BitsInit::getAsString() const {
Chris Lattner695506c2007-11-22 21:05:25 +0000385 std::string Result = "{ ";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000386 for (unsigned i = 0, e = getNumBits(); i != e; ++i) {
Chris Lattner695506c2007-11-22 21:05:25 +0000387 if (i) Result += ", ";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000388 if (Init *Bit = getBit(e-i-1))
Chris Lattner695506c2007-11-22 21:05:25 +0000389 Result += Bit->getAsString();
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000390 else
Chris Lattner695506c2007-11-22 21:05:25 +0000391 Result += "*";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000392 }
Chris Lattner695506c2007-11-22 21:05:25 +0000393 return Result + " }";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000394}
395
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000396// resolveReferences - If there are any field references that refer to fields
397// that have been filled in, we can propagate the values now.
398//
Chris Lattneref943742005-04-19 03:36:21 +0000399Init *BitsInit::resolveReferences(Record &R, const RecordVal *RV) {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000400 bool Changed = false;
401 BitsInit *New = new BitsInit(getNumBits());
402
403 for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
404 Init *B;
405 Init *CurBit = getBit(i);
406
407 do {
408 B = CurBit;
Chris Lattneref943742005-04-19 03:36:21 +0000409 CurBit = CurBit->resolveReferences(R, RV);
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000410 Changed |= B != CurBit;
411 } while (B != CurBit);
412 New->setBit(i, CurBit);
413 }
414
415 if (Changed)
416 return New;
417 delete New;
418 return this;
419}
420
Chris Lattner695506c2007-11-22 21:05:25 +0000421std::string IntInit::getAsString() const {
422 return itostr(Value);
423}
424
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000425Init *IntInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) {
426 BitsInit *BI = new BitsInit(Bits.size());
427
428 for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
Dan Gohmanca0546f2008-10-17 01:33:43 +0000429 if (Bits[i] >= 64) {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000430 delete BI;
431 return 0;
432 }
Dan Gohmanca0546f2008-10-17 01:33:43 +0000433 BI->setBit(i, new BitInit(Value & (INT64_C(1) << Bits[i])));
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000434 }
435 return BI;
436}
437
Chris Lattner8bf9e062004-07-26 23:21:34 +0000438Init *ListInit::convertInitListSlice(const std::vector<unsigned> &Elements) {
439 std::vector<Init*> Vals;
440 for (unsigned i = 0, e = Elements.size(); i != e; ++i) {
441 if (Elements[i] >= getSize())
442 return 0;
443 Vals.push_back(getElement(Elements[i]));
444 }
David Greene8618f952009-06-08 20:23:18 +0000445 return new ListInit(Vals, getType());
Chris Lattner8bf9e062004-07-26 23:21:34 +0000446}
447
Chris Lattnercbebe462007-02-27 22:08:27 +0000448Record *ListInit::getElementAsRecord(unsigned i) const {
449 assert(i < Values.size() && "List element index out of range!");
450 DefInit *DI = dynamic_cast<DefInit*>(Values[i]);
451 if (DI == 0) throw "Expected record in list!";
452 return DI->getDef();
453}
454
Chris Lattneref943742005-04-19 03:36:21 +0000455Init *ListInit::resolveReferences(Record &R, const RecordVal *RV) {
Chris Lattner577fc3f2004-07-27 01:01:21 +0000456 std::vector<Init*> Resolved;
457 Resolved.reserve(getSize());
458 bool Changed = false;
459
460 for (unsigned i = 0, e = getSize(); i != e; ++i) {
461 Init *E;
462 Init *CurElt = getElement(i);
463
464 do {
465 E = CurElt;
Chris Lattneref943742005-04-19 03:36:21 +0000466 CurElt = CurElt->resolveReferences(R, RV);
Chris Lattner577fc3f2004-07-27 01:01:21 +0000467 Changed |= E != CurElt;
468 } while (E != CurElt);
469 Resolved.push_back(E);
470 }
471
472 if (Changed)
David Greene8618f952009-06-08 20:23:18 +0000473 return new ListInit(Resolved, getType());
Chris Lattner577fc3f2004-07-27 01:01:21 +0000474 return this;
475}
476
David Greene8618f952009-06-08 20:23:18 +0000477Init *ListInit::resolveListElementReference(Record &R, const RecordVal *IRV,
Bob Wilson7248f862009-11-22 04:24:42 +0000478 unsigned Elt) {
David Greene8618f952009-06-08 20:23:18 +0000479 if (Elt >= getSize())
480 return 0; // Out of range reference.
481 Init *E = getElement(Elt);
Bob Wilson67e6cab2009-11-22 03:58:57 +0000482 // If the element is set to some value, or if we are resolving a reference
483 // to a specific variable and that variable is explicitly unset, then
484 // replace the VarListElementInit with it.
485 if (IRV || !dynamic_cast<UnsetInit*>(E))
486 return E;
David Greene8618f952009-06-08 20:23:18 +0000487 return 0;
488}
489
Chris Lattner695506c2007-11-22 21:05:25 +0000490std::string ListInit::getAsString() const {
491 std::string Result = "[";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000492 for (unsigned i = 0, e = Values.size(); i != e; ++i) {
Chris Lattner695506c2007-11-22 21:05:25 +0000493 if (i) Result += ", ";
494 Result += Values[i]->getAsString();
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000495 }
Chris Lattner695506c2007-11-22 21:05:25 +0000496 return Result + "]";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +0000497}
498
David Greene5d0c0512009-05-14 20:54:48 +0000499Init *OpInit::resolveBitReference(Record &R, const RecordVal *IRV,
Bob Wilson7248f862009-11-22 04:24:42 +0000500 unsigned Bit) {
David Greene5d0c0512009-05-14 20:54:48 +0000501 Init *Folded = Fold(&R, 0);
502
503 if (Folded != this) {
504 TypedInit *Typed = dynamic_cast<TypedInit *>(Folded);
505 if (Typed) {
506 return Typed->resolveBitReference(R, IRV, Bit);
Bob Wilson7248f862009-11-22 04:24:42 +0000507 }
David Greene5d0c0512009-05-14 20:54:48 +0000508 }
Bob Wilson7248f862009-11-22 04:24:42 +0000509
David Greene5d0c0512009-05-14 20:54:48 +0000510 return 0;
511}
512
513Init *OpInit::resolveListElementReference(Record &R, const RecordVal *IRV,
Bob Wilson7248f862009-11-22 04:24:42 +0000514 unsigned Elt) {
David Greene5d0c0512009-05-14 20:54:48 +0000515 Init *Folded = Fold(&R, 0);
516
517 if (Folded != this) {
518 TypedInit *Typed = dynamic_cast<TypedInit *>(Folded);
519 if (Typed) {
520 return Typed->resolveListElementReference(R, IRV, Elt);
Bob Wilson7248f862009-11-22 04:24:42 +0000521 }
David Greene5d0c0512009-05-14 20:54:48 +0000522 }
Bob Wilson7248f862009-11-22 04:24:42 +0000523
David Greene5d0c0512009-05-14 20:54:48 +0000524 return 0;
525}
526
David Greenee8f3b272009-05-14 21:22:49 +0000527Init *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
528 switch (getOpcode()) {
529 default: assert(0 && "Unknown unop");
530 case CAST: {
David Greeneefa19612009-06-29 20:05:29 +0000531 if (getType()->getAsString() == "string") {
532 StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
533 if (LHSs) {
534 return LHSs;
535 }
David Greene5d0c0512009-05-14 20:54:48 +0000536
David Greeneefa19612009-06-29 20:05:29 +0000537 DefInit *LHSd = dynamic_cast<DefInit*>(LHS);
538 if (LHSd) {
539 return new StringInit(LHSd->getDef()->getName());
540 }
Bob Wilson7248f862009-11-22 04:24:42 +0000541 } else {
David Greeneefa19612009-06-29 20:05:29 +0000542 StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
543 if (LHSs) {
544 std::string Name = LHSs->getValue();
545
546 // From TGParser::ParseIDValue
547 if (CurRec) {
548 if (const RecordVal *RV = CurRec->getValue(Name)) {
Chris Lattner94026332010-10-06 00:19:21 +0000549 if (RV->getType() != getType())
550 throw "type mismatch in cast";
David Greeneefa19612009-06-29 20:05:29 +0000551 return new VarInit(Name, RV->getType());
David Greenee8f3b272009-05-14 21:22:49 +0000552 }
David Greeneefa19612009-06-29 20:05:29 +0000553
554 std::string TemplateArgName = CurRec->getName()+":"+Name;
555 if (CurRec->isTemplateArg(TemplateArgName)) {
556 const RecordVal *RV = CurRec->getValue(TemplateArgName);
557 assert(RV && "Template arg doesn't exist??");
558
Chris Lattner94026332010-10-06 00:19:21 +0000559 if (RV->getType() != getType())
560 throw "type mismatch in cast";
David Greeneefa19612009-06-29 20:05:29 +0000561
562 return new VarInit(TemplateArgName, RV->getType());
563 }
564 }
565
566 if (CurMultiClass) {
567 std::string MCName = CurMultiClass->Rec.getName()+"::"+Name;
568 if (CurMultiClass->Rec.isTemplateArg(MCName)) {
569 const RecordVal *RV = CurMultiClass->Rec.getValue(MCName);
570 assert(RV && "Template arg doesn't exist??");
Bob Wilson7248f862009-11-22 04:24:42 +0000571
Chris Lattner94026332010-10-06 00:19:21 +0000572 if (RV->getType() != getType())
573 throw "type mismatch in cast";
Bob Wilson7248f862009-11-22 04:24:42 +0000574
David Greeneefa19612009-06-29 20:05:29 +0000575 return new VarInit(MCName, RV->getType());
576 }
David Greenee8f3b272009-05-14 21:22:49 +0000577 }
Bob Wilson7248f862009-11-22 04:24:42 +0000578
Chris Lattner77d369c2010-12-13 00:23:57 +0000579 if (Record *D = (CurRec->getRecords()).getDef(Name))
David Greeneefa19612009-06-29 20:05:29 +0000580 return new DefInit(D);
David Greene5d0c0512009-05-14 20:54:48 +0000581
Jim Grosbach59ddb732011-05-06 18:47:45 +0000582 throw TGError(CurRec->getLoc(), "Undefined reference:'" + Name + "'\n");
David Greenee8f3b272009-05-14 21:22:49 +0000583 }
David Greenee8f3b272009-05-14 21:22:49 +0000584 }
585 break;
586 }
David Greene2f7cf7f2011-01-07 17:05:37 +0000587 case HEAD: {
David Greened571b3c2009-05-14 22:38:31 +0000588 ListInit *LHSl = dynamic_cast<ListInit*>(LHS);
589 if (LHSl) {
590 if (LHSl->getSize() == 0) {
591 assert(0 && "Empty list in car");
592 return 0;
593 }
594 return LHSl->getElement(0);
595 }
596 break;
597 }
David Greene2f7cf7f2011-01-07 17:05:37 +0000598 case TAIL: {
David Greened571b3c2009-05-14 22:38:31 +0000599 ListInit *LHSl = dynamic_cast<ListInit*>(LHS);
600 if (LHSl) {
601 if (LHSl->getSize() == 0) {
602 assert(0 && "Empty list in cdr");
603 return 0;
604 }
Bob Wilson7248f862009-11-22 04:24:42 +0000605 ListInit *Result = new ListInit(LHSl->begin()+1, LHSl->end(),
606 LHSl->getType());
David Greened571b3c2009-05-14 22:38:31 +0000607 return Result;
608 }
609 break;
610 }
David Greene2f7cf7f2011-01-07 17:05:37 +0000611 case EMPTY: {
David Greened571b3c2009-05-14 22:38:31 +0000612 ListInit *LHSl = dynamic_cast<ListInit*>(LHS);
613 if (LHSl) {
614 if (LHSl->getSize() == 0) {
615 return new IntInit(1);
Bob Wilson7248f862009-11-22 04:24:42 +0000616 } else {
David Greened571b3c2009-05-14 22:38:31 +0000617 return new IntInit(0);
618 }
619 }
David Greene8618f952009-06-08 20:23:18 +0000620 StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
621 if (LHSs) {
622 if (LHSs->getValue().empty()) {
623 return new IntInit(1);
Bob Wilson7248f862009-11-22 04:24:42 +0000624 } else {
David Greene8618f952009-06-08 20:23:18 +0000625 return new IntInit(0);
626 }
627 }
Bob Wilson7248f862009-11-22 04:24:42 +0000628
David Greened571b3c2009-05-14 22:38:31 +0000629 break;
630 }
David Greenee8f3b272009-05-14 21:22:49 +0000631 }
632 return this;
633}
David Greene5d0c0512009-05-14 20:54:48 +0000634
David Greenee8f3b272009-05-14 21:22:49 +0000635Init *UnOpInit::resolveReferences(Record &R, const RecordVal *RV) {
636 Init *lhs = LHS->resolveReferences(R, RV);
Bob Wilson7248f862009-11-22 04:24:42 +0000637
David Greenee8f3b272009-05-14 21:22:49 +0000638 if (LHS != lhs)
639 return (new UnOpInit(getOpcode(), lhs, getType()))->Fold(&R, 0);
640 return Fold(&R, 0);
641}
David Greene5d0c0512009-05-14 20:54:48 +0000642
David Greenee8f3b272009-05-14 21:22:49 +0000643std::string UnOpInit::getAsString() const {
644 std::string Result;
645 switch (Opc) {
646 case CAST: Result = "!cast<" + getType()->getAsString() + ">"; break;
David Greene2f7cf7f2011-01-07 17:05:37 +0000647 case HEAD: Result = "!head"; break;
648 case TAIL: Result = "!tail"; break;
649 case EMPTY: Result = "!empty"; break;
David Greenee8f3b272009-05-14 21:22:49 +0000650 }
651 return Result + "(" + LHS->getAsString() + ")";
652}
David Greene5d0c0512009-05-14 20:54:48 +0000653
David Greenea9c6c5d2009-04-22 20:18:10 +0000654Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
Chris Lattner51ffbf12006-03-31 21:53:49 +0000655 switch (getOpcode()) {
656 default: assert(0 && "Unknown binop");
Evan Chenga32dee22007-05-15 01:23:24 +0000657 case CONCAT: {
658 DagInit *LHSs = dynamic_cast<DagInit*>(LHS);
659 DagInit *RHSs = dynamic_cast<DagInit*>(RHS);
660 if (LHSs && RHSs) {
661 DefInit *LOp = dynamic_cast<DefInit*>(LHSs->getOperator());
662 DefInit *ROp = dynamic_cast<DefInit*>(RHSs->getOperator());
Chris Lattner81fd1f22010-03-18 21:07:51 +0000663 if (LOp == 0 || ROp == 0 || LOp->getDef() != ROp->getDef())
664 throw "Concated Dag operators do not match!";
Evan Chenga32dee22007-05-15 01:23:24 +0000665 std::vector<Init*> Args;
666 std::vector<std::string> ArgNames;
667 for (unsigned i = 0, e = LHSs->getNumArgs(); i != e; ++i) {
668 Args.push_back(LHSs->getArg(i));
669 ArgNames.push_back(LHSs->getArgName(i));
670 }
671 for (unsigned i = 0, e = RHSs->getNumArgs(); i != e; ++i) {
672 Args.push_back(RHSs->getArg(i));
673 ArgNames.push_back(RHSs->getArgName(i));
674 }
Nate Begemandbe3f772009-03-19 05:21:56 +0000675 return new DagInit(LHSs->getOperator(), "", Args, ArgNames);
Evan Chenga32dee22007-05-15 01:23:24 +0000676 }
677 break;
678 }
Chris Lattner51ffbf12006-03-31 21:53:49 +0000679 case STRCONCAT: {
680 StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
681 StringInit *RHSs = dynamic_cast<StringInit*>(RHS);
682 if (LHSs && RHSs)
683 return new StringInit(LHSs->getValue() + RHSs->getValue());
684 break;
685 }
David Greene297bfe62010-01-05 19:11:42 +0000686 case EQ: {
Bruno Cardoso Lopes77a4a562010-06-16 23:24:12 +0000687 // try to fold eq comparison for 'bit' and 'int', otherwise fallback
688 // to string objects.
689 IntInit* L =
690 dynamic_cast<IntInit*>(LHS->convertInitializerTo(new IntRecTy()));
691 IntInit* R =
692 dynamic_cast<IntInit*>(RHS->convertInitializerTo(new IntRecTy()));
693
694 if (L && R)
695 return new IntInit(L->getValue() == R->getValue());
696
David Greene297bfe62010-01-05 19:11:42 +0000697 StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
698 StringInit *RHSs = dynamic_cast<StringInit*>(RHS);
Bruno Cardoso Lopes77a4a562010-06-16 23:24:12 +0000699
700 // Make sure we've resolved
David Greene297bfe62010-01-05 19:11:42 +0000701 if (LHSs && RHSs)
702 return new IntInit(LHSs->getValue() == RHSs->getValue());
703
704 break;
705 }
Chris Lattner51ffbf12006-03-31 21:53:49 +0000706 case SHL:
707 case SRA:
708 case SRL: {
709 IntInit *LHSi = dynamic_cast<IntInit*>(LHS);
710 IntInit *RHSi = dynamic_cast<IntInit*>(RHS);
711 if (LHSi && RHSi) {
Dan Gohmanca0546f2008-10-17 01:33:43 +0000712 int64_t LHSv = LHSi->getValue(), RHSv = RHSi->getValue();
713 int64_t Result;
Chris Lattner51ffbf12006-03-31 21:53:49 +0000714 switch (getOpcode()) {
715 default: assert(0 && "Bad opcode!");
716 case SHL: Result = LHSv << RHSv; break;
717 case SRA: Result = LHSv >> RHSv; break;
Dan Gohmanca0546f2008-10-17 01:33:43 +0000718 case SRL: Result = (uint64_t)LHSv >> (uint64_t)RHSv; break;
Chris Lattner51ffbf12006-03-31 21:53:49 +0000719 }
720 return new IntInit(Result);
721 }
722 break;
723 }
724 }
725 return this;
726}
727
728Init *BinOpInit::resolveReferences(Record &R, const RecordVal *RV) {
729 Init *lhs = LHS->resolveReferences(R, RV);
730 Init *rhs = RHS->resolveReferences(R, RV);
Bob Wilson7248f862009-11-22 04:24:42 +0000731
Chris Lattner51ffbf12006-03-31 21:53:49 +0000732 if (LHS != lhs || RHS != rhs)
David Greene196ac3c2009-04-23 21:25:15 +0000733 return (new BinOpInit(getOpcode(), lhs, rhs, getType()))->Fold(&R, 0);
David Greenea9c6c5d2009-04-22 20:18:10 +0000734 return Fold(&R, 0);
Chris Lattner51ffbf12006-03-31 21:53:49 +0000735}
736
Chris Lattner695506c2007-11-22 21:05:25 +0000737std::string BinOpInit::getAsString() const {
738 std::string Result;
Chris Lattner51ffbf12006-03-31 21:53:49 +0000739 switch (Opc) {
Chris Lattner695506c2007-11-22 21:05:25 +0000740 case CONCAT: Result = "!con"; break;
741 case SHL: Result = "!shl"; break;
742 case SRA: Result = "!sra"; break;
743 case SRL: Result = "!srl"; break;
David Greene297bfe62010-01-05 19:11:42 +0000744 case EQ: Result = "!eq"; break;
Chris Lattner695506c2007-11-22 21:05:25 +0000745 case STRCONCAT: Result = "!strconcat"; break;
Chris Lattner51ffbf12006-03-31 21:53:49 +0000746 }
Chris Lattner695506c2007-11-22 21:05:25 +0000747 return Result + "(" + LHS->getAsString() + ", " + RHS->getAsString() + ")";
Chris Lattner51ffbf12006-03-31 21:53:49 +0000748}
749
David Greenee917fff2009-05-14 22:23:47 +0000750static Init *ForeachHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type,
751 Record *CurRec, MultiClass *CurMultiClass);
752
753static Init *EvaluateOperation(OpInit *RHSo, Init *LHS, Init *Arg,
754 RecTy *Type, Record *CurRec,
755 MultiClass *CurMultiClass) {
756 std::vector<Init *> NewOperands;
757
758 TypedInit *TArg = dynamic_cast<TypedInit*>(Arg);
759
760 // If this is a dag, recurse
761 if (TArg && TArg->getType()->getAsString() == "dag") {
762 Init *Result = ForeachHelper(LHS, Arg, RHSo, Type,
763 CurRec, CurMultiClass);
764 if (Result != 0) {
765 return Result;
Bob Wilson7248f862009-11-22 04:24:42 +0000766 } else {
David Greenee917fff2009-05-14 22:23:47 +0000767 return 0;
768 }
769 }
770
771 for (int i = 0; i < RHSo->getNumOperands(); ++i) {
772 OpInit *RHSoo = dynamic_cast<OpInit*>(RHSo->getOperand(i));
773
774 if (RHSoo) {
775 Init *Result = EvaluateOperation(RHSoo, LHS, Arg,
776 Type, CurRec, CurMultiClass);
777 if (Result != 0) {
778 NewOperands.push_back(Result);
Bob Wilson7248f862009-11-22 04:24:42 +0000779 } else {
David Greenee917fff2009-05-14 22:23:47 +0000780 NewOperands.push_back(Arg);
781 }
Bob Wilson7248f862009-11-22 04:24:42 +0000782 } else if (LHS->getAsString() == RHSo->getOperand(i)->getAsString()) {
David Greenee917fff2009-05-14 22:23:47 +0000783 NewOperands.push_back(Arg);
Bob Wilson7248f862009-11-22 04:24:42 +0000784 } else {
David Greenee917fff2009-05-14 22:23:47 +0000785 NewOperands.push_back(RHSo->getOperand(i));
786 }
787 }
788
789 // Now run the operator and use its result as the new leaf
790 OpInit *NewOp = RHSo->clone(NewOperands);
791 Init *NewVal = NewOp->Fold(CurRec, CurMultiClass);
792 if (NewVal != NewOp) {
793 delete NewOp;
794 return NewVal;
795 }
796 return 0;
797}
798
799static Init *ForeachHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type,
800 Record *CurRec, MultiClass *CurMultiClass) {
801 DagInit *MHSd = dynamic_cast<DagInit*>(MHS);
802 ListInit *MHSl = dynamic_cast<ListInit*>(MHS);
803
804 DagRecTy *DagType = dynamic_cast<DagRecTy*>(Type);
805 ListRecTy *ListType = dynamic_cast<ListRecTy*>(Type);
806
807 OpInit *RHSo = dynamic_cast<OpInit*>(RHS);
808
809 if (!RHSo) {
Jim Grosbach59ddb732011-05-06 18:47:45 +0000810 throw TGError(CurRec->getLoc(), "!foreach requires an operator\n");
David Greenee917fff2009-05-14 22:23:47 +0000811 }
812
813 TypedInit *LHSt = dynamic_cast<TypedInit*>(LHS);
814
815 if (!LHSt) {
Jim Grosbach59ddb732011-05-06 18:47:45 +0000816 throw TGError(CurRec->getLoc(), "!foreach requires typed variable\n");
David Greenee917fff2009-05-14 22:23:47 +0000817 }
818
Nick Lewycky94298222009-05-15 03:07:14 +0000819 if ((MHSd && DagType) || (MHSl && ListType)) {
David Greenee917fff2009-05-14 22:23:47 +0000820 if (MHSd) {
821 Init *Val = MHSd->getOperator();
822 Init *Result = EvaluateOperation(RHSo, LHS, Val,
823 Type, CurRec, CurMultiClass);
824 if (Result != 0) {
825 Val = Result;
826 }
827
828 std::vector<std::pair<Init *, std::string> > args;
829 for (unsigned int i = 0; i < MHSd->getNumArgs(); ++i) {
830 Init *Arg;
831 std::string ArgName;
832 Arg = MHSd->getArg(i);
833 ArgName = MHSd->getArgName(i);
834
835 // Process args
836 Init *Result = EvaluateOperation(RHSo, LHS, Arg, Type,
837 CurRec, CurMultiClass);
838 if (Result != 0) {
839 Arg = Result;
840 }
841
842 // TODO: Process arg names
843 args.push_back(std::make_pair(Arg, ArgName));
844 }
845
846 return new DagInit(Val, "", args);
847 }
848 if (MHSl) {
849 std::vector<Init *> NewOperands;
850 std::vector<Init *> NewList(MHSl->begin(), MHSl->end());
851
852 for (ListInit::iterator li = NewList.begin(),
853 liend = NewList.end();
854 li != liend;
855 ++li) {
856 Init *Item = *li;
857 NewOperands.clear();
858 for(int i = 0; i < RHSo->getNumOperands(); ++i) {
859 // First, replace the foreach variable with the list item
860 if (LHS->getAsString() == RHSo->getOperand(i)->getAsString()) {
861 NewOperands.push_back(Item);
Bob Wilson7248f862009-11-22 04:24:42 +0000862 } else {
David Greenee917fff2009-05-14 22:23:47 +0000863 NewOperands.push_back(RHSo->getOperand(i));
864 }
865 }
866
867 // Now run the operator and use its result as the new list item
868 OpInit *NewOp = RHSo->clone(NewOperands);
869 Init *NewItem = NewOp->Fold(CurRec, CurMultiClass);
870 if (NewItem != NewOp) {
871 *li = NewItem;
872 delete NewOp;
873 }
874 }
David Greene8618f952009-06-08 20:23:18 +0000875 return new ListInit(NewList, MHSl->getType());
David Greenee917fff2009-05-14 22:23:47 +0000876 }
877 }
878 return 0;
879}
880
David Greene98ed3c72009-05-14 21:54:42 +0000881Init *TernOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
882 switch (getOpcode()) {
883 default: assert(0 && "Unknown binop");
884 case SUBST: {
885 DefInit *LHSd = dynamic_cast<DefInit*>(LHS);
886 VarInit *LHSv = dynamic_cast<VarInit*>(LHS);
887 StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
David Greene196ac3c2009-04-23 21:25:15 +0000888
David Greene98ed3c72009-05-14 21:54:42 +0000889 DefInit *MHSd = dynamic_cast<DefInit*>(MHS);
890 VarInit *MHSv = dynamic_cast<VarInit*>(MHS);
891 StringInit *MHSs = dynamic_cast<StringInit*>(MHS);
David Greene5d0c0512009-05-14 20:54:48 +0000892
David Greene98ed3c72009-05-14 21:54:42 +0000893 DefInit *RHSd = dynamic_cast<DefInit*>(RHS);
894 VarInit *RHSv = dynamic_cast<VarInit*>(RHS);
895 StringInit *RHSs = dynamic_cast<StringInit*>(RHS);
David Greene5d0c0512009-05-14 20:54:48 +0000896
David Greene98ed3c72009-05-14 21:54:42 +0000897 if ((LHSd && MHSd && RHSd)
898 || (LHSv && MHSv && RHSv)
899 || (LHSs && MHSs && RHSs)) {
900 if (RHSd) {
901 Record *Val = RHSd->getDef();
902 if (LHSd->getAsString() == RHSd->getAsString()) {
903 Val = MHSd->getDef();
904 }
905 return new DefInit(Val);
906 }
907 if (RHSv) {
908 std::string Val = RHSv->getName();
909 if (LHSv->getAsString() == RHSv->getAsString()) {
910 Val = MHSv->getName();
911 }
912 return new VarInit(Val, getType());
913 }
914 if (RHSs) {
915 std::string Val = RHSs->getValue();
David Greene5d0c0512009-05-14 20:54:48 +0000916
David Greene98ed3c72009-05-14 21:54:42 +0000917 std::string::size_type found;
David Greenedbf70742009-12-21 21:21:34 +0000918 std::string::size_type idx = 0;
David Greene98ed3c72009-05-14 21:54:42 +0000919 do {
David Greenedbf70742009-12-21 21:21:34 +0000920 found = Val.find(LHSs->getValue(), idx);
David Greene98ed3c72009-05-14 21:54:42 +0000921 if (found != std::string::npos) {
922 Val.replace(found, LHSs->getValue().size(), MHSs->getValue());
923 }
David Greenedbf70742009-12-21 21:21:34 +0000924 idx = found + MHSs->getValue().size();
David Greene98ed3c72009-05-14 21:54:42 +0000925 } while (found != std::string::npos);
David Greene5d0c0512009-05-14 20:54:48 +0000926
David Greene98ed3c72009-05-14 21:54:42 +0000927 return new StringInit(Val);
928 }
929 }
930 break;
Bob Wilson7248f862009-11-22 04:24:42 +0000931 }
David Greene5d0c0512009-05-14 20:54:48 +0000932
David Greene98ed3c72009-05-14 21:54:42 +0000933 case FOREACH: {
David Greenee917fff2009-05-14 22:23:47 +0000934 Init *Result = ForeachHelper(LHS, MHS, RHS, getType(),
935 CurRec, CurMultiClass);
936 if (Result != 0) {
937 return Result;
David Greene98ed3c72009-05-14 21:54:42 +0000938 }
939 break;
940 }
David Greene3587eed2009-05-14 23:26:46 +0000941
942 case IF: {
Bruno Cardoso Lopes7f4235d2010-06-17 01:50:39 +0000943 IntInit *LHSi = dynamic_cast<IntInit*>(LHS);
944 if (Init *I = LHS->convertInitializerTo(new IntRecTy()))
945 LHSi = dynamic_cast<IntInit*>(I);
David Greene3587eed2009-05-14 23:26:46 +0000946 if (LHSi) {
947 if (LHSi->getValue()) {
948 return MHS;
Bob Wilson7248f862009-11-22 04:24:42 +0000949 } else {
David Greene3587eed2009-05-14 23:26:46 +0000950 return RHS;
951 }
952 }
953 break;
954 }
David Greene98ed3c72009-05-14 21:54:42 +0000955 }
David Greene5d0c0512009-05-14 20:54:48 +0000956
David Greene98ed3c72009-05-14 21:54:42 +0000957 return this;
958}
David Greene5d0c0512009-05-14 20:54:48 +0000959
David Greene98ed3c72009-05-14 21:54:42 +0000960Init *TernOpInit::resolveReferences(Record &R, const RecordVal *RV) {
961 Init *lhs = LHS->resolveReferences(R, RV);
David Greeneb0354452009-06-08 19:16:56 +0000962
963 if (Opc == IF && lhs != LHS) {
Bruno Cardoso Lopes7f4235d2010-06-17 01:50:39 +0000964 IntInit *Value = dynamic_cast<IntInit*>(lhs);
965 if (Init *I = lhs->convertInitializerTo(new IntRecTy()))
966 Value = dynamic_cast<IntInit*>(I);
David Greeneb0354452009-06-08 19:16:56 +0000967 if (Value != 0) {
968 // Short-circuit
969 if (Value->getValue()) {
970 Init *mhs = MHS->resolveReferences(R, RV);
Bob Wilson7248f862009-11-22 04:24:42 +0000971 return (new TernOpInit(getOpcode(), lhs, mhs,
972 RHS, getType()))->Fold(&R, 0);
973 } else {
David Greeneb0354452009-06-08 19:16:56 +0000974 Init *rhs = RHS->resolveReferences(R, RV);
Bob Wilson7248f862009-11-22 04:24:42 +0000975 return (new TernOpInit(getOpcode(), lhs, MHS,
976 rhs, getType()))->Fold(&R, 0);
David Greeneb0354452009-06-08 19:16:56 +0000977 }
978 }
979 }
Bob Wilson7248f862009-11-22 04:24:42 +0000980
David Greene98ed3c72009-05-14 21:54:42 +0000981 Init *mhs = MHS->resolveReferences(R, RV);
982 Init *rhs = RHS->resolveReferences(R, RV);
David Greeneb0354452009-06-08 19:16:56 +0000983
David Greene98ed3c72009-05-14 21:54:42 +0000984 if (LHS != lhs || MHS != mhs || RHS != rhs)
985 return (new TernOpInit(getOpcode(), lhs, mhs, rhs, getType()))->Fold(&R, 0);
986 return Fold(&R, 0);
987}
David Greene196ac3c2009-04-23 21:25:15 +0000988
David Greene98ed3c72009-05-14 21:54:42 +0000989std::string TernOpInit::getAsString() const {
990 std::string Result;
991 switch (Opc) {
992 case SUBST: Result = "!subst"; break;
Bob Wilson7248f862009-11-22 04:24:42 +0000993 case FOREACH: Result = "!foreach"; break;
994 case IF: Result = "!if"; break;
David Greene98ed3c72009-05-14 21:54:42 +0000995 }
Bob Wilson7248f862009-11-22 04:24:42 +0000996 return Result + "(" + LHS->getAsString() + ", " + MHS->getAsString() + ", "
David Greene98ed3c72009-05-14 21:54:42 +0000997 + RHS->getAsString() + ")";
998}
David Greene196ac3c2009-04-23 21:25:15 +0000999
David Greene2a9de4d2010-09-03 21:00:49 +00001000RecTy *TypedInit::getFieldType(const std::string &FieldName) const {
1001 RecordRecTy *RecordType = dynamic_cast<RecordRecTy *>(getType());
1002 if (RecordType) {
1003 RecordVal *Field = RecordType->getRecord()->getValue(FieldName);
1004 if (Field) {
1005 return Field->getType();
1006 }
1007 }
1008 return 0;
1009}
1010
Chris Lattner577fc3f2004-07-27 01:01:21 +00001011Init *TypedInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001012 BitsRecTy *T = dynamic_cast<BitsRecTy*>(getType());
Bill Wendling73a48d82010-12-10 22:54:30 +00001013 if (T == 0) return 0; // Cannot subscript a non-bits variable.
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001014 unsigned NumBits = T->getNumBits();
1015
1016 BitsInit *BI = new BitsInit(Bits.size());
1017 for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
1018 if (Bits[i] >= NumBits) {
1019 delete BI;
1020 return 0;
1021 }
1022 BI->setBit(i, new VarBitInit(this, Bits[i]));
1023 }
1024 return BI;
1025}
1026
Chris Lattner577fc3f2004-07-27 01:01:21 +00001027Init *TypedInit::convertInitListSlice(const std::vector<unsigned> &Elements) {
1028 ListRecTy *T = dynamic_cast<ListRecTy*>(getType());
Bill Wendling73a48d82010-12-10 22:54:30 +00001029 if (T == 0) return 0; // Cannot subscript a non-list variable.
Chris Lattner577fc3f2004-07-27 01:01:21 +00001030
1031 if (Elements.size() == 1)
1032 return new VarListElementInit(this, Elements[0]);
1033
1034 std::vector<Init*> ListInits;
1035 ListInits.reserve(Elements.size());
1036 for (unsigned i = 0, e = Elements.size(); i != e; ++i)
1037 ListInits.push_back(new VarListElementInit(this, Elements[i]));
David Greene8618f952009-06-08 20:23:18 +00001038 return new ListInit(ListInits, T);
Chris Lattner577fc3f2004-07-27 01:01:21 +00001039}
1040
1041
Chris Lattneref943742005-04-19 03:36:21 +00001042Init *VarInit::resolveBitReference(Record &R, const RecordVal *IRV,
1043 unsigned Bit) {
1044 if (R.isTemplateArg(getName())) return 0;
1045 if (IRV && IRV->getName() != getName()) return 0;
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001046
1047 RecordVal *RV = R.getValue(getName());
Bob Wilson159905a2009-11-21 22:44:20 +00001048 assert(RV && "Reference to a non-existent variable?");
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001049 assert(dynamic_cast<BitsInit*>(RV->getValue()));
1050 BitsInit *BI = (BitsInit*)RV->getValue();
Misha Brukman650ba8e2005-04-22 00:00:37 +00001051
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001052 assert(Bit < BI->getNumBits() && "Bit reference out of range!");
1053 Init *B = BI->getBit(Bit);
1054
Bob Wilson67e6cab2009-11-22 03:58:57 +00001055 // If the bit is set to some value, or if we are resolving a reference to a
1056 // specific variable and that variable is explicitly unset, then replace the
1057 // VarBitInit with it.
1058 if (IRV || !dynamic_cast<UnsetInit*>(B))
1059 return B;
Chris Lattner577fc3f2004-07-27 01:01:21 +00001060 return 0;
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001061}
1062
Chris Lattneref943742005-04-19 03:36:21 +00001063Init *VarInit::resolveListElementReference(Record &R, const RecordVal *IRV,
1064 unsigned Elt) {
1065 if (R.isTemplateArg(getName())) return 0;
1066 if (IRV && IRV->getName() != getName()) return 0;
Chris Lattner577fc3f2004-07-27 01:01:21 +00001067
1068 RecordVal *RV = R.getValue(getName());
Bob Wilson159905a2009-11-21 22:44:20 +00001069 assert(RV && "Reference to a non-existent variable?");
Chris Lattner577fc3f2004-07-27 01:01:21 +00001070 ListInit *LI = dynamic_cast<ListInit*>(RV->getValue());
David Greene9d3febe2009-05-14 20:38:52 +00001071 if (!LI) {
1072 VarInit *VI = dynamic_cast<VarInit*>(RV->getValue());
1073 assert(VI && "Invalid list element!");
1074 return new VarListElementInit(VI, Elt);
1075 }
Bob Wilson7248f862009-11-22 04:24:42 +00001076
Chris Lattner577fc3f2004-07-27 01:01:21 +00001077 if (Elt >= LI->getSize())
1078 return 0; // Out of range reference.
1079 Init *E = LI->getElement(Elt);
Bob Wilson67e6cab2009-11-22 03:58:57 +00001080 // If the element is set to some value, or if we are resolving a reference
1081 // to a specific variable and that variable is explicitly unset, then
1082 // replace the VarListElementInit with it.
1083 if (IRV || !dynamic_cast<UnsetInit*>(E))
1084 return E;
Chris Lattner577fc3f2004-07-27 01:01:21 +00001085 return 0;
1086}
1087
1088
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001089RecTy *VarInit::getFieldType(const std::string &FieldName) const {
1090 if (RecordRecTy *RTy = dynamic_cast<RecordRecTy*>(getType()))
1091 if (const RecordVal *RV = RTy->getRecord()->getValue(FieldName))
1092 return RV->getType();
1093 return 0;
1094}
1095
Jakob Stoklund Olesen0e457622010-03-25 06:23:34 +00001096Init *VarInit::getFieldInit(Record &R, const RecordVal *RV,
1097 const std::string &FieldName) const {
Reid Spencer2a826862006-11-02 20:46:16 +00001098 if (dynamic_cast<RecordRecTy*>(getType()))
Jakob Stoklund Olesen0e457622010-03-25 06:23:34 +00001099 if (const RecordVal *Val = R.getValue(VarName)) {
1100 if (RV != Val && (RV || dynamic_cast<UnsetInit*>(Val->getValue())))
1101 return 0;
1102 Init *TheInit = Val->getValue();
Chris Lattnerd959ab92004-02-28 16:31:53 +00001103 assert(TheInit != this && "Infinite loop detected!");
Jakob Stoklund Olesen0e457622010-03-25 06:23:34 +00001104 if (Init *I = TheInit->getFieldInit(R, RV, FieldName))
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001105 return I;
1106 else
1107 return 0;
Chris Lattnerd959ab92004-02-28 16:31:53 +00001108 }
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001109 return 0;
1110}
1111
1112/// resolveReferences - This method is used by classes that refer to other
Bob Wilson159905a2009-11-21 22:44:20 +00001113/// variables which may not be defined at the time the expression is formed.
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001114/// If a value is set for the variable later, this method will be called on
1115/// users of the value to allow the value to propagate out.
1116///
Chris Lattneref943742005-04-19 03:36:21 +00001117Init *VarInit::resolveReferences(Record &R, const RecordVal *RV) {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001118 if (RecordVal *Val = R.getValue(VarName))
Chris Lattneref943742005-04-19 03:36:21 +00001119 if (RV == Val || (RV == 0 && !dynamic_cast<UnsetInit*>(Val->getValue())))
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001120 return Val->getValue();
1121 return this;
1122}
Misha Brukman650ba8e2005-04-22 00:00:37 +00001123
Chris Lattner695506c2007-11-22 21:05:25 +00001124std::string VarBitInit::getAsString() const {
1125 return TI->getAsString() + "{" + utostr(Bit) + "}";
1126}
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001127
Chris Lattneref943742005-04-19 03:36:21 +00001128Init *VarBitInit::resolveReferences(Record &R, const RecordVal *RV) {
1129 if (Init *I = getVariable()->resolveBitReference(R, RV, getBitNum()))
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001130 return I;
1131 return this;
1132}
1133
Chris Lattner695506c2007-11-22 21:05:25 +00001134std::string VarListElementInit::getAsString() const {
1135 return TI->getAsString() + "[" + utostr(Element) + "]";
1136}
1137
Chris Lattneref943742005-04-19 03:36:21 +00001138Init *VarListElementInit::resolveReferences(Record &R, const RecordVal *RV) {
1139 if (Init *I = getVariable()->resolveListElementReference(R, RV,
1140 getElementNum()))
Chris Lattner577fc3f2004-07-27 01:01:21 +00001141 return I;
1142 return this;
1143}
1144
Chris Lattneref943742005-04-19 03:36:21 +00001145Init *VarListElementInit::resolveBitReference(Record &R, const RecordVal *RV,
1146 unsigned Bit) {
Chris Lattner577fc3f2004-07-27 01:01:21 +00001147 // FIXME: This should be implemented, to support references like:
1148 // bit B = AA[0]{1};
1149 return 0;
1150}
1151
Chris Lattneref943742005-04-19 03:36:21 +00001152Init *VarListElementInit::
1153resolveListElementReference(Record &R, const RecordVal *RV, unsigned Elt) {
Chris Lattner577fc3f2004-07-27 01:01:21 +00001154 // FIXME: This should be implemented, to support references like:
1155 // int B = AA[0][1];
1156 return 0;
1157}
1158
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001159RecTy *DefInit::getFieldType(const std::string &FieldName) const {
1160 if (const RecordVal *RV = Def->getValue(FieldName))
1161 return RV->getType();
1162 return 0;
1163}
1164
Jakob Stoklund Olesen0e457622010-03-25 06:23:34 +00001165Init *DefInit::getFieldInit(Record &R, const RecordVal *RV,
1166 const std::string &FieldName) const {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001167 return Def->getValue(FieldName)->getValue();
1168}
1169
1170
Chris Lattner695506c2007-11-22 21:05:25 +00001171std::string DefInit::getAsString() const {
1172 return Def->getName();
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001173}
1174
Chris Lattneref943742005-04-19 03:36:21 +00001175Init *FieldInit::resolveBitReference(Record &R, const RecordVal *RV,
1176 unsigned Bit) {
Jakob Stoklund Olesen0e457622010-03-25 06:23:34 +00001177 if (Init *BitsVal = Rec->getFieldInit(R, RV, FieldName))
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001178 if (BitsInit *BI = dynamic_cast<BitsInit*>(BitsVal)) {
1179 assert(Bit < BI->getNumBits() && "Bit reference out of range!");
1180 Init *B = BI->getBit(Bit);
Misha Brukman650ba8e2005-04-22 00:00:37 +00001181
Bill Wendling73a48d82010-12-10 22:54:30 +00001182 if (dynamic_cast<BitInit*>(B)) // If the bit is set.
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001183 return B; // Replace the VarBitInit with it.
1184 }
Chris Lattner577fc3f2004-07-27 01:01:21 +00001185 return 0;
1186}
1187
Chris Lattneref943742005-04-19 03:36:21 +00001188Init *FieldInit::resolveListElementReference(Record &R, const RecordVal *RV,
1189 unsigned Elt) {
Jakob Stoklund Olesen0e457622010-03-25 06:23:34 +00001190 if (Init *ListVal = Rec->getFieldInit(R, RV, FieldName))
Chris Lattner577fc3f2004-07-27 01:01:21 +00001191 if (ListInit *LI = dynamic_cast<ListInit*>(ListVal)) {
1192 if (Elt >= LI->getSize()) return 0;
1193 Init *E = LI->getElement(Elt);
1194
Bob Wilson67e6cab2009-11-22 03:58:57 +00001195 // If the element is set to some value, or if we are resolving a
1196 // reference to a specific variable and that variable is explicitly
1197 // unset, then replace the VarListElementInit with it.
1198 if (RV || !dynamic_cast<UnsetInit*>(E))
1199 return E;
Chris Lattner577fc3f2004-07-27 01:01:21 +00001200 }
1201 return 0;
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001202}
1203
Chris Lattneref943742005-04-19 03:36:21 +00001204Init *FieldInit::resolveReferences(Record &R, const RecordVal *RV) {
1205 Init *NewRec = RV ? Rec->resolveReferences(R, RV) : Rec;
1206
Jakob Stoklund Olesen0e457622010-03-25 06:23:34 +00001207 Init *BitsVal = NewRec->getFieldInit(R, RV, FieldName);
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001208 if (BitsVal) {
Chris Lattneref943742005-04-19 03:36:21 +00001209 Init *BVR = BitsVal->resolveReferences(R, RV);
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001210 return BVR->isComplete() ? BVR : this;
1211 }
Chris Lattneref943742005-04-19 03:36:21 +00001212
1213 if (NewRec != Rec) {
Chris Lattneref943742005-04-19 03:36:21 +00001214 return new FieldInit(NewRec, FieldName);
1215 }
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001216 return this;
1217}
1218
Chris Lattner0d3ef402006-01-31 06:02:35 +00001219Init *DagInit::resolveReferences(Record &R, const RecordVal *RV) {
1220 std::vector<Init*> NewArgs;
1221 for (unsigned i = 0, e = Args.size(); i != e; ++i)
1222 NewArgs.push_back(Args[i]->resolveReferences(R, RV));
Bob Wilson7248f862009-11-22 04:24:42 +00001223
Chris Lattnerb59cf3c2006-03-30 22:50:40 +00001224 Init *Op = Val->resolveReferences(R, RV);
Bob Wilson7248f862009-11-22 04:24:42 +00001225
Chris Lattnerb59cf3c2006-03-30 22:50:40 +00001226 if (Args != NewArgs || Op != Val)
Bruno Cardoso Lopes30a28d62010-06-23 19:50:39 +00001227 return new DagInit(Op, ValName, NewArgs, ArgNames);
Bob Wilson7248f862009-11-22 04:24:42 +00001228
Chris Lattner0d3ef402006-01-31 06:02:35 +00001229 return this;
1230}
1231
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001232
Chris Lattner695506c2007-11-22 21:05:25 +00001233std::string DagInit::getAsString() const {
1234 std::string Result = "(" + Val->getAsString();
Nate Begemandbe3f772009-03-19 05:21:56 +00001235 if (!ValName.empty())
1236 Result += ":" + ValName;
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001237 if (Args.size()) {
Chris Lattner695506c2007-11-22 21:05:25 +00001238 Result += " " + Args[0]->getAsString();
1239 if (!ArgNames[0].empty()) Result += ":$" + ArgNames[0];
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001240 for (unsigned i = 1, e = Args.size(); i != e; ++i) {
Chris Lattner695506c2007-11-22 21:05:25 +00001241 Result += ", " + Args[i]->getAsString();
1242 if (!ArgNames[i].empty()) Result += ":$" + ArgNames[i];
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001243 }
1244 }
Chris Lattner695506c2007-11-22 21:05:25 +00001245 return Result + ")";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001246}
1247
1248
1249//===----------------------------------------------------------------------===//
1250// Other implementations
1251//===----------------------------------------------------------------------===//
1252
1253RecordVal::RecordVal(const std::string &N, RecTy *T, unsigned P)
1254 : Name(N), Ty(T), Prefix(P) {
1255 Value = Ty->convertValue(new UnsetInit());
1256 assert(Value && "Cannot create unset value for current type!");
1257}
1258
Daniel Dunbar38a22bf2009-07-03 00:10:29 +00001259void RecordVal::dump() const { errs() << *this; }
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001260
Daniel Dunbar38a22bf2009-07-03 00:10:29 +00001261void RecordVal::print(raw_ostream &OS, bool PrintSem) const {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001262 if (getPrefix()) OS << "field ";
1263 OS << *getType() << " " << getName();
Chris Lattneref943742005-04-19 03:36:21 +00001264
1265 if (getValue())
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001266 OS << " = " << *getValue();
Chris Lattneref943742005-04-19 03:36:21 +00001267
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001268 if (PrintSem) OS << ";\n";
1269}
1270
Daniel Dunbarced00812009-08-23 09:47:37 +00001271unsigned Record::LastID = 0;
1272
Chris Lattnerac284252005-08-19 17:58:11 +00001273void Record::setName(const std::string &Name) {
Chris Lattner77d369c2010-12-13 00:23:57 +00001274 if (TrackedRecords.getDef(getName()) == this) {
1275 TrackedRecords.removeDef(getName());
Chris Lattnerac284252005-08-19 17:58:11 +00001276 this->Name = Name;
Chris Lattner77d369c2010-12-13 00:23:57 +00001277 TrackedRecords.addDef(this);
Chris Lattnerac284252005-08-19 17:58:11 +00001278 } else {
Chris Lattner77d369c2010-12-13 00:23:57 +00001279 TrackedRecords.removeClass(getName());
Chris Lattnerac284252005-08-19 17:58:11 +00001280 this->Name = Name;
Chris Lattner77d369c2010-12-13 00:23:57 +00001281 TrackedRecords.addClass(this);
Chris Lattnerac284252005-08-19 17:58:11 +00001282 }
1283}
1284
Chris Lattneref943742005-04-19 03:36:21 +00001285/// resolveReferencesTo - If anything in this record refers to RV, replace the
1286/// reference to RV with the RHS of RV. If RV is null, we resolve all possible
1287/// references.
1288void Record::resolveReferencesTo(const RecordVal *RV) {
1289 for (unsigned i = 0, e = Values.size(); i != e; ++i) {
1290 if (Init *V = Values[i].getValue())
1291 Values[i].setValue(V->resolveReferences(*this, RV));
1292 }
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001293}
1294
Daniel Dunbar38a22bf2009-07-03 00:10:29 +00001295void Record::dump() const { errs() << *this; }
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001296
Daniel Dunbar38a22bf2009-07-03 00:10:29 +00001297raw_ostream &llvm::operator<<(raw_ostream &OS, const Record &R) {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001298 OS << R.getName();
1299
1300 const std::vector<std::string> &TArgs = R.getTemplateArgs();
1301 if (!TArgs.empty()) {
1302 OS << "<";
1303 for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
1304 if (i) OS << ", ";
1305 const RecordVal *RV = R.getValue(TArgs[i]);
1306 assert(RV && "Template argument record not found??");
1307 RV->print(OS, false);
1308 }
1309 OS << ">";
1310 }
1311
1312 OS << " {";
1313 const std::vector<Record*> &SC = R.getSuperClasses();
1314 if (!SC.empty()) {
1315 OS << "\t//";
1316 for (unsigned i = 0, e = SC.size(); i != e; ++i)
1317 OS << " " << SC[i]->getName();
1318 }
1319 OS << "\n";
1320
1321 const std::vector<RecordVal> &Vals = R.getValues();
1322 for (unsigned i = 0, e = Vals.size(); i != e; ++i)
1323 if (Vals[i].getPrefix() && !R.isTemplateArg(Vals[i].getName()))
1324 OS << Vals[i];
1325 for (unsigned i = 0, e = Vals.size(); i != e; ++i)
1326 if (!Vals[i].getPrefix() && !R.isTemplateArg(Vals[i].getName()))
1327 OS << Vals[i];
1328
1329 return OS << "}\n";
1330}
1331
1332/// getValueInit - Return the initializer for a value with the specified name,
1333/// or throw an exception if the field does not exist.
1334///
Chris Lattner42bb0c12009-09-18 18:31:37 +00001335Init *Record::getValueInit(StringRef FieldName) const {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001336 const RecordVal *R = getValue(FieldName);
1337 if (R == 0 || R->getValue() == 0)
Misha Brukman41f9f292004-10-08 14:59:05 +00001338 throw "Record `" + getName() + "' does not have a field named `" +
Chris Lattner42bb0c12009-09-18 18:31:37 +00001339 FieldName.str() + "'!\n";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001340 return R->getValue();
1341}
1342
1343
1344/// getValueAsString - This method looks up the specified field and returns its
1345/// value as a string, throwing an exception if the field does not exist or if
1346/// the value is not a string.
1347///
Chris Lattner42bb0c12009-09-18 18:31:37 +00001348std::string Record::getValueAsString(StringRef FieldName) const {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001349 const RecordVal *R = getValue(FieldName);
1350 if (R == 0 || R->getValue() == 0)
Misha Brukman41f9f292004-10-08 14:59:05 +00001351 throw "Record `" + getName() + "' does not have a field named `" +
Chris Lattner42bb0c12009-09-18 18:31:37 +00001352 FieldName.str() + "'!\n";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001353
1354 if (const StringInit *SI = dynamic_cast<const StringInit*>(R->getValue()))
1355 return SI->getValue();
Chris Lattner42bb0c12009-09-18 18:31:37 +00001356 throw "Record `" + getName() + "', field `" + FieldName.str() +
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001357 "' does not have a string initializer!";
1358}
1359
1360/// getValueAsBitsInit - This method looks up the specified field and returns
1361/// its value as a BitsInit, throwing an exception if the field does not exist
1362/// or if the value is not the right type.
1363///
Chris Lattner42bb0c12009-09-18 18:31:37 +00001364BitsInit *Record::getValueAsBitsInit(StringRef FieldName) const {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001365 const RecordVal *R = getValue(FieldName);
1366 if (R == 0 || R->getValue() == 0)
Misha Brukman41f9f292004-10-08 14:59:05 +00001367 throw "Record `" + getName() + "' does not have a field named `" +
Chris Lattner42bb0c12009-09-18 18:31:37 +00001368 FieldName.str() + "'!\n";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001369
1370 if (BitsInit *BI = dynamic_cast<BitsInit*>(R->getValue()))
1371 return BI;
Chris Lattner42bb0c12009-09-18 18:31:37 +00001372 throw "Record `" + getName() + "', field `" + FieldName.str() +
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001373 "' does not have a BitsInit initializer!";
1374}
1375
1376/// getValueAsListInit - This method looks up the specified field and returns
1377/// its value as a ListInit, throwing an exception if the field does not exist
1378/// or if the value is not the right type.
1379///
Chris Lattner42bb0c12009-09-18 18:31:37 +00001380ListInit *Record::getValueAsListInit(StringRef FieldName) const {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001381 const RecordVal *R = getValue(FieldName);
1382 if (R == 0 || R->getValue() == 0)
Misha Brukman41f9f292004-10-08 14:59:05 +00001383 throw "Record `" + getName() + "' does not have a field named `" +
Chris Lattner42bb0c12009-09-18 18:31:37 +00001384 FieldName.str() + "'!\n";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001385
1386 if (ListInit *LI = dynamic_cast<ListInit*>(R->getValue()))
1387 return LI;
Chris Lattner42bb0c12009-09-18 18:31:37 +00001388 throw "Record `" + getName() + "', field `" + FieldName.str() +
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001389 "' does not have a list initializer!";
1390}
1391
Chris Lattner7ad0bed2005-10-28 22:49:02 +00001392/// getValueAsListOfDefs - This method looks up the specified field and returns
Jim Laskeyb04feb62005-10-28 21:46:31 +00001393/// its value as a vector of records, throwing an exception if the field does
1394/// not exist or if the value is not the right type.
1395///
Bob Wilson7248f862009-11-22 04:24:42 +00001396std::vector<Record*>
Chris Lattner42bb0c12009-09-18 18:31:37 +00001397Record::getValueAsListOfDefs(StringRef FieldName) const {
Jim Laskeyb04feb62005-10-28 21:46:31 +00001398 ListInit *List = getValueAsListInit(FieldName);
1399 std::vector<Record*> Defs;
1400 for (unsigned i = 0; i < List->getSize(); i++) {
1401 if (DefInit *DI = dynamic_cast<DefInit*>(List->getElement(i))) {
1402 Defs.push_back(DI->getDef());
1403 } else {
Chris Lattner42bb0c12009-09-18 18:31:37 +00001404 throw "Record `" + getName() + "', field `" + FieldName.str() +
Jim Laskeyb04feb62005-10-28 21:46:31 +00001405 "' list is not entirely DefInit!";
1406 }
1407 }
1408 return Defs;
1409}
1410
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001411/// getValueAsInt - This method looks up the specified field and returns its
Dan Gohmanca0546f2008-10-17 01:33:43 +00001412/// value as an int64_t, throwing an exception if the field does not exist or if
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001413/// the value is not the right type.
1414///
Chris Lattner42bb0c12009-09-18 18:31:37 +00001415int64_t Record::getValueAsInt(StringRef FieldName) const {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001416 const RecordVal *R = getValue(FieldName);
1417 if (R == 0 || R->getValue() == 0)
Misha Brukman41f9f292004-10-08 14:59:05 +00001418 throw "Record `" + getName() + "' does not have a field named `" +
Chris Lattner42bb0c12009-09-18 18:31:37 +00001419 FieldName.str() + "'!\n";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001420
1421 if (IntInit *II = dynamic_cast<IntInit*>(R->getValue()))
1422 return II->getValue();
Chris Lattner42bb0c12009-09-18 18:31:37 +00001423 throw "Record `" + getName() + "', field `" + FieldName.str() +
Nate Begemanf621b332005-11-30 18:37:14 +00001424 "' does not have an int initializer!";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001425}
1426
Anton Korobeynikova468a112007-11-11 11:19:37 +00001427/// getValueAsListOfInts - This method looks up the specified field and returns
1428/// its value as a vector of integers, throwing an exception if the field does
1429/// not exist or if the value is not the right type.
1430///
Bob Wilson7248f862009-11-22 04:24:42 +00001431std::vector<int64_t>
Chris Lattner42bb0c12009-09-18 18:31:37 +00001432Record::getValueAsListOfInts(StringRef FieldName) const {
Anton Korobeynikova468a112007-11-11 11:19:37 +00001433 ListInit *List = getValueAsListInit(FieldName);
Dan Gohmanca0546f2008-10-17 01:33:43 +00001434 std::vector<int64_t> Ints;
Anton Korobeynikova468a112007-11-11 11:19:37 +00001435 for (unsigned i = 0; i < List->getSize(); i++) {
1436 if (IntInit *II = dynamic_cast<IntInit*>(List->getElement(i))) {
1437 Ints.push_back(II->getValue());
1438 } else {
Chris Lattner42bb0c12009-09-18 18:31:37 +00001439 throw "Record `" + getName() + "', field `" + FieldName.str() +
Anton Korobeynikova468a112007-11-11 11:19:37 +00001440 "' does not have a list of ints initializer!";
1441 }
1442 }
1443 return Ints;
1444}
1445
Owen Andersona84be6c2011-06-27 21:06:21 +00001446/// getValueAsListOfStrings - This method looks up the specified field and
1447/// returns its value as a vector of strings, throwing an exception if the
1448/// field does not exist or if the value is not the right type.
1449///
1450std::vector<std::string>
1451Record::getValueAsListOfStrings(StringRef FieldName) const {
1452 ListInit *List = getValueAsListInit(FieldName);
1453 std::vector<std::string> Strings;
1454 for (unsigned i = 0; i < List->getSize(); i++) {
1455 if (StringInit *II = dynamic_cast<StringInit*>(List->getElement(i))) {
1456 Strings.push_back(II->getValue());
1457 } else {
1458 throw "Record `" + getName() + "', field `" + FieldName.str() +
1459 "' does not have a list of strings initializer!";
1460 }
1461 }
1462 return Strings;
1463}
1464
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001465/// getValueAsDef - This method looks up the specified field and returns its
1466/// value as a Record, throwing an exception if the field does not exist or if
1467/// the value is not the right type.
1468///
Chris Lattner42bb0c12009-09-18 18:31:37 +00001469Record *Record::getValueAsDef(StringRef FieldName) const {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001470 const RecordVal *R = getValue(FieldName);
1471 if (R == 0 || R->getValue() == 0)
Misha Brukman41f9f292004-10-08 14:59:05 +00001472 throw "Record `" + getName() + "' does not have a field named `" +
Chris Lattner42bb0c12009-09-18 18:31:37 +00001473 FieldName.str() + "'!\n";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001474
1475 if (DefInit *DI = dynamic_cast<DefInit*>(R->getValue()))
1476 return DI->getDef();
Chris Lattner42bb0c12009-09-18 18:31:37 +00001477 throw "Record `" + getName() + "', field `" + FieldName.str() +
Nate Begemanf621b332005-11-30 18:37:14 +00001478 "' does not have a def initializer!";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001479}
1480
1481/// getValueAsBit - This method looks up the specified field and returns its
1482/// value as a bit, throwing an exception if the field does not exist or if
1483/// the value is not the right type.
1484///
Chris Lattner42bb0c12009-09-18 18:31:37 +00001485bool Record::getValueAsBit(StringRef FieldName) const {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001486 const RecordVal *R = getValue(FieldName);
1487 if (R == 0 || R->getValue() == 0)
Misha Brukman41f9f292004-10-08 14:59:05 +00001488 throw "Record `" + getName() + "' does not have a field named `" +
Chris Lattner42bb0c12009-09-18 18:31:37 +00001489 FieldName.str() + "'!\n";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001490
1491 if (BitInit *BI = dynamic_cast<BitInit*>(R->getValue()))
1492 return BI->getValue();
Chris Lattner42bb0c12009-09-18 18:31:37 +00001493 throw "Record `" + getName() + "', field `" + FieldName.str() +
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001494 "' does not have a bit initializer!";
1495}
1496
1497/// getValueAsDag - This method looks up the specified field and returns its
1498/// value as an Dag, throwing an exception if the field does not exist or if
1499/// the value is not the right type.
1500///
Chris Lattner42bb0c12009-09-18 18:31:37 +00001501DagInit *Record::getValueAsDag(StringRef FieldName) const {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001502 const RecordVal *R = getValue(FieldName);
1503 if (R == 0 || R->getValue() == 0)
Misha Brukman41f9f292004-10-08 14:59:05 +00001504 throw "Record `" + getName() + "' does not have a field named `" +
Chris Lattner42bb0c12009-09-18 18:31:37 +00001505 FieldName.str() + "'!\n";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001506
1507 if (DagInit *DI = dynamic_cast<DagInit*>(R->getValue()))
1508 return DI;
Chris Lattner42bb0c12009-09-18 18:31:37 +00001509 throw "Record `" + getName() + "', field `" + FieldName.str() +
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001510 "' does not have a dag initializer!";
1511}
1512
Chris Lattner42bb0c12009-09-18 18:31:37 +00001513std::string Record::getValueAsCode(StringRef FieldName) const {
Chris Lattnerae939eb2005-09-13 21:44:28 +00001514 const RecordVal *R = getValue(FieldName);
1515 if (R == 0 || R->getValue() == 0)
1516 throw "Record `" + getName() + "' does not have a field named `" +
Chris Lattner42bb0c12009-09-18 18:31:37 +00001517 FieldName.str() + "'!\n";
Bob Wilson7248f862009-11-22 04:24:42 +00001518
Chris Lattnerae939eb2005-09-13 21:44:28 +00001519 if (const CodeInit *CI = dynamic_cast<const CodeInit*>(R->getValue()))
1520 return CI->getValue();
Chris Lattner42bb0c12009-09-18 18:31:37 +00001521 throw "Record `" + getName() + "', field `" + FieldName.str() +
Chris Lattnerae939eb2005-09-13 21:44:28 +00001522 "' does not have a code initializer!";
1523}
1524
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001525
David Greene7049e792009-04-24 16:55:41 +00001526void MultiClass::dump() const {
Daniel Dunbar38a22bf2009-07-03 00:10:29 +00001527 errs() << "Record:\n";
David Greene7049e792009-04-24 16:55:41 +00001528 Rec.dump();
Bob Wilson7248f862009-11-22 04:24:42 +00001529
Daniel Dunbar38a22bf2009-07-03 00:10:29 +00001530 errs() << "Defs:\n";
David Greene7049e792009-04-24 16:55:41 +00001531 for (RecordVector::const_iterator r = DefPrototypes.begin(),
1532 rend = DefPrototypes.end();
1533 r != rend;
1534 ++r) {
1535 (*r)->dump();
1536 }
1537}
1538
1539
Daniel Dunbar38a22bf2009-07-03 00:10:29 +00001540void RecordKeeper::dump() const { errs() << *this; }
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001541
Daniel Dunbar38a22bf2009-07-03 00:10:29 +00001542raw_ostream &llvm::operator<<(raw_ostream &OS, const RecordKeeper &RK) {
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001543 OS << "------------- Classes -----------------\n";
1544 const std::map<std::string, Record*> &Classes = RK.getClasses();
1545 for (std::map<std::string, Record*>::const_iterator I = Classes.begin(),
Jeff Cohen88e7b722005-04-22 04:13:13 +00001546 E = Classes.end(); I != E; ++I)
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001547 OS << "class " << *I->second;
Misha Brukman650ba8e2005-04-22 00:00:37 +00001548
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001549 OS << "------------- Defs -----------------\n";
1550 const std::map<std::string, Record*> &Defs = RK.getDefs();
1551 for (std::map<std::string, Record*>::const_iterator I = Defs.begin(),
Jeff Cohen88e7b722005-04-22 04:13:13 +00001552 E = Defs.end(); I != E; ++I)
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001553 OS << "def " << *I->second;
1554 return OS;
1555}
1556
1557
1558/// getAllDerivedDefinitions - This method returns all concrete definitions
1559/// that derive from the specified class name. If a class with the specified
1560/// name does not exist, an error is printed and true is returned.
1561std::vector<Record*>
1562RecordKeeper::getAllDerivedDefinitions(const std::string &ClassName) const {
Chris Lattner97049072010-12-13 00:20:52 +00001563 Record *Class = getClass(ClassName);
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001564 if (!Class)
Misha Brukman41f9f292004-10-08 14:59:05 +00001565 throw "ERROR: Couldn't find the `" + ClassName + "' class!\n";
Chris Lattnerf5bd1b72003-10-05 19:27:59 +00001566
1567 std::vector<Record*> Defs;
1568 for (std::map<std::string, Record*>::const_iterator I = getDefs().begin(),
1569 E = getDefs().end(); I != E; ++I)
1570 if (I->second->isSubClassOf(Class))
1571 Defs.push_back(I->second);
1572
1573 return Defs;
1574}
Brian Gaeke960707c2003-11-11 22:41:34 +00001575