@@ -125,54 +125,138 @@ std::string DagRecTy::getAsString() const {
125
125
return " dag" ;
126
126
}
127
127
128
- RecordRecTy *RecordRecTy::get (Record *R) {
129
- return dyn_cast<RecordRecTy>(R->getDefInit ()->getType ());
128
+ static void ProfileRecordRecTy (FoldingSetNodeID &ID,
129
+ ArrayRef<Record *> Classes) {
130
+ ID.AddInteger (Classes.size ());
131
+ for (Record *R : Classes)
132
+ ID.AddPointer (R);
133
+ }
134
+
135
+ RecordRecTy *RecordRecTy::get (ArrayRef<Record *> UnsortedClasses) {
136
+ if (UnsortedClasses.empty ()) {
137
+ static RecordRecTy AnyRecord (0 );
138
+ return &AnyRecord;
139
+ }
140
+
141
+ FoldingSet<RecordRecTy> &ThePool =
142
+ UnsortedClasses[0 ]->getRecords ().RecordTypePool ;
143
+
144
+ SmallVector<Record *, 4 > Classes (UnsortedClasses.begin (),
145
+ UnsortedClasses.end ());
146
+ std::sort (Classes.begin (), Classes.end (),
147
+ [](Record *LHS, Record *RHS) {
148
+ return LHS->getNameInitAsString () < RHS->getNameInitAsString ();
149
+ });
150
+
151
+ FoldingSetNodeID ID;
152
+ ProfileRecordRecTy (ID, Classes);
153
+
154
+ void *IP = nullptr ;
155
+ if (RecordRecTy *Ty = ThePool.FindNodeOrInsertPos (ID, IP))
156
+ return Ty;
157
+
158
+ #ifndef NDEBUG
159
+ // Check for redundancy.
160
+ for (unsigned i = 0 ; i < Classes.size (); ++i) {
161
+ for (unsigned j = 0 ; j < Classes.size (); ++j) {
162
+ assert (i == j || !Classes[i]->isSubClassOf (Classes[j]));
163
+ }
164
+ assert (&Classes[0 ]->getRecords () == &Classes[i]->getRecords ());
165
+ }
166
+ #endif
167
+
168
+ void *Mem = Allocator.Allocate (totalSizeToAlloc<Record *>(Classes.size ()),
169
+ alignof (RecordRecTy));
170
+ RecordRecTy *Ty = new (Mem) RecordRecTy (Classes.size ());
171
+ std::uninitialized_copy (Classes.begin (), Classes.end (),
172
+ Ty->getTrailingObjects <Record *>());
173
+ ThePool.InsertNode (Ty, IP);
174
+ return Ty;
175
+ }
176
+
177
+ void RecordRecTy::Profile (FoldingSetNodeID &ID) const {
178
+ ProfileRecordRecTy (ID, getClasses ());
130
179
}
131
180
132
181
std::string RecordRecTy::getAsString () const {
133
- return Rec->getName ();
182
+ if (NumClasses == 1 )
183
+ return getClasses ()[0 ]->getName ();
184
+
185
+ std::string Str = " {" ;
186
+ bool First = true ;
187
+ for (Record *R : getClasses ()) {
188
+ if (!First)
189
+ Str += " , " ;
190
+ First = false ;
191
+ Str += R->getName ();
192
+ }
193
+ Str += " }" ;
194
+ return Str;
195
+ }
196
+
197
+ bool RecordRecTy::isSubClassOf (Record *Class) const {
198
+ return llvm::any_of (getClasses (), [Class](Record *MySuperClass) {
199
+ return MySuperClass == Class ||
200
+ MySuperClass->isSubClassOf (Class);
201
+ });
134
202
}
135
203
136
204
bool RecordRecTy::typeIsConvertibleTo (const RecTy *RHS) const {
205
+ if (this == RHS)
206
+ return true ;
207
+
137
208
const RecordRecTy *RTy = dyn_cast<RecordRecTy>(RHS);
138
209
if (!RTy)
139
210
return false ;
140
211
141
- if (RTy->getRecord () == Rec || Rec->isSubClassOf (RTy->getRecord ()))
142
- return true ;
212
+ return llvm::all_of (RTy->getClasses (), [this ](Record *TargetClass) {
213
+ return isSubClassOf (TargetClass);
214
+ });
215
+ }
143
216
144
- for ( const auto &SCPair : RTy-> getRecord ()-> getSuperClasses ())
145
- if (Rec-> isSubClassOf (SCPair. first ))
146
- return true ;
217
+ static RecordRecTy * resolveRecordTypes (RecordRecTy *T1, RecordRecTy *T2) {
218
+ SmallVector<Record *, 4 > CommonSuperClasses;
219
+ SmallVector<Record *, 4 > Stack ;
147
220
148
- return false ;
221
+ Stack.insert (Stack.end (), T1->classes_begin (), T1->classes_end ());
222
+
223
+ while (!Stack.empty ()) {
224
+ Record *R = Stack.back ();
225
+ Stack.pop_back ();
226
+
227
+ if (T2->isSubClassOf (R)) {
228
+ CommonSuperClasses.push_back (R);
229
+ } else {
230
+ R->getDirectSuperClasses (Stack);
231
+ }
232
+ }
233
+
234
+ return RecordRecTy::get (CommonSuperClasses);
149
235
}
150
236
151
237
RecTy *llvm::resolveTypes (RecTy *T1, RecTy *T2) {
238
+ if (T1 == T2)
239
+ return T1;
240
+
241
+ if (RecordRecTy *RecTy1 = dyn_cast<RecordRecTy>(T1)) {
242
+ if (RecordRecTy *RecTy2 = dyn_cast<RecordRecTy>(T2))
243
+ return resolveRecordTypes (RecTy1, RecTy2);
244
+ }
245
+
152
246
if (T1->typeIsConvertibleTo (T2))
153
247
return T2;
154
248
if (T2->typeIsConvertibleTo (T1))
155
249
return T1;
156
250
157
- // If one is a Record type, check superclasses
158
- if (RecordRecTy *RecTy1 = dyn_cast<RecordRecTy>(T1)) {
159
- // See if T2 inherits from a type T1 also inherits from
160
- for (const auto &SuperPair1 : RecTy1->getRecord ()->getSuperClasses ()) {
161
- RecordRecTy *SuperRecTy1 = RecordRecTy::get (SuperPair1.first );
162
- RecTy *NewType1 = resolveTypes (SuperRecTy1, T2);
163
- if (NewType1)
164
- return NewType1;
165
- }
166
- }
167
- if (RecordRecTy *RecTy2 = dyn_cast<RecordRecTy>(T2)) {
168
- // See if T1 inherits from a type T2 also inherits from
169
- for (const auto &SuperPair2 : RecTy2->getRecord ()->getSuperClasses ()) {
170
- RecordRecTy *SuperRecTy2 = RecordRecTy::get (SuperPair2.first );
171
- RecTy *NewType2 = resolveTypes (T1, SuperRecTy2);
172
- if (NewType2)
173
- return NewType2;
251
+ if (ListRecTy *ListTy1 = dyn_cast<ListRecTy>(T1)) {
252
+ if (ListRecTy *ListTy2 = dyn_cast<ListRecTy>(T2)) {
253
+ RecTy* NewType = resolveTypes (ListTy1->getElementType (),
254
+ ListTy2->getElementType ());
255
+ if (NewType)
256
+ return NewType->getListTy ();
174
257
}
175
258
}
259
+
176
260
return nullptr ;
177
261
}
178
262
@@ -1082,9 +1166,12 @@ std::string TernOpInit::getAsString() const {
1082
1166
}
1083
1167
1084
1168
RecTy *TypedInit::getFieldType (StringInit *FieldName) const {
1085
- if (RecordRecTy *RecordType = dyn_cast<RecordRecTy>(getType ()))
1086
- if (RecordVal *Field = RecordType->getRecord ()->getValue (FieldName))
1087
- return Field->getType ();
1169
+ if (RecordRecTy *RecordType = dyn_cast<RecordRecTy>(getType ())) {
1170
+ for (Record *Rec : RecordType->getClasses ()) {
1171
+ if (RecordVal *Field = Rec->getValue (FieldName))
1172
+ return Field->getType ();
1173
+ }
1174
+ }
1088
1175
return nullptr ;
1089
1176
}
1090
1177
@@ -1159,11 +1246,8 @@ TypedInit::convertInitializerTo(RecTy *Ty) const {
1159
1246
}
1160
1247
1161
1248
if (auto *SRRT = dyn_cast<RecordRecTy>(Ty)) {
1162
- // Ensure that this is compatible with Rec.
1163
- if (RecordRecTy *DRRT = dyn_cast<RecordRecTy>(getType ()))
1164
- if (DRRT->getRecord ()->isSubClassOf (SRRT->getRecord ()) ||
1165
- DRRT->getRecord () == SRRT->getRecord ())
1166
- return const_cast <TypedInit *>(this );
1249
+ if (getType ()->typeIsConvertibleTo (SRRT))
1250
+ return const_cast <TypedInit *>(this );
1167
1251
return nullptr ;
1168
1252
}
1169
1253
@@ -1302,13 +1386,22 @@ Init *VarListElementInit::getBit(unsigned Bit) const {
1302
1386
return VarBitInit::get (const_cast <VarListElementInit*>(this ), Bit);
1303
1387
}
1304
1388
1389
+ static RecordRecTy *makeDefInitType (Record *Rec) {
1390
+ SmallVector<Record *, 4 > SuperClasses;
1391
+ Rec->getDirectSuperClasses (SuperClasses);
1392
+ return RecordRecTy::get (SuperClasses);
1393
+ }
1394
+
1395
+ DefInit::DefInit (Record *D)
1396
+ : TypedInit(IK_DefInit, makeDefInitType(D)), Def(D) {}
1397
+
1305
1398
DefInit *DefInit::get (Record *R) {
1306
1399
return R->getDefInit ();
1307
1400
}
1308
1401
1309
1402
Init *DefInit::convertInitializerTo (RecTy *Ty) const {
1310
1403
if (auto *RRT = dyn_cast<RecordRecTy>(Ty))
1311
- if (getDef ()->isSubClassOf (RRT-> getRecord () ))
1404
+ if (getType ()->typeIsConvertibleTo (RRT))
1312
1405
return const_cast <DefInit *>(this );
1313
1406
return nullptr ;
1314
1407
}
@@ -1497,7 +1590,7 @@ void Record::checkName() {
1497
1590
1498
1591
DefInit *Record::getDefInit () {
1499
1592
if (!TheInit)
1500
- TheInit = new (Allocator) DefInit (this , new (Allocator) RecordRecTy ( this ) );
1593
+ TheInit = new (Allocator) DefInit (this );
1501
1594
return TheInit;
1502
1595
}
1503
1596
@@ -1517,6 +1610,17 @@ void Record::setName(Init *NewName) {
1517
1610
// this. See TGParser::ParseDef and TGParser::ParseDefm.
1518
1611
}
1519
1612
1613
+ void Record::getDirectSuperClasses (SmallVectorImpl<Record *> &Classes) const {
1614
+ ArrayRef<std::pair<Record *, SMRange>> SCs = getSuperClasses ();
1615
+ while (!SCs.empty ()) {
1616
+ // Superclasses are in reverse preorder, so 'back' is a direct superclass,
1617
+ // and its transitive superclasses are directly preceding it.
1618
+ Record *SC = SCs.back ().first ;
1619
+ SCs = SCs.drop_back (1 + SC->getSuperClasses ().size ());
1620
+ Classes.push_back (SC);
1621
+ }
1622
+ }
1623
+
1520
1624
void Record::resolveReferences (Resolver &R, const RecordVal *SkipVal) {
1521
1625
for (RecordVal &Value : Values) {
1522
1626
if (SkipVal == &Value) // Skip resolve the same field as the given one
0 commit comments