@@ -131,17 +131,17 @@ class SearchableTableEmitter {
131131 return SI->getValue ().str ();
132132 else
133133 return SI->getAsString ();
134- } else if (const auto *BI = dyn_cast<BitsInit>(I)) {
134+ }
135+ if (const auto *BI = dyn_cast<BitsInit>(I))
135136 return " 0x" + utohexstr (getAsInt (BI));
136- } else if (const auto *BI = dyn_cast<BitInit>(I)) {
137+ if (const auto *BI = dyn_cast<BitInit>(I))
137138 return BI->getValue () ? " true" : " false" ;
138- } else if (Field.IsIntrinsic ) {
139+ if (Field.IsIntrinsic )
139140 return " Intrinsic::" + getIntrinsic (I).EnumName .str ();
140- } else if (Field.IsInstruction ) {
141+ if (Field.IsInstruction )
141142 return I->getAsString ();
142143 if (Field.Enum ) {
143- const GenericEnum::Entry *Entry =
144- Field.Enum ->getEntry (cast<DefInit>(I)->getDef ());
144+ auto *Entry = Field.Enum ->EntryMap [cast<DefInit>(I)->getDef ()];
145145 if (!Entry)
146146 PrintFatalError (Loc,
147147 Twine (" Entry for field '" ) + Field.Name + " ' is null" );
@@ -174,7 +174,8 @@ class SearchableTableEmitter {
174174 if (Ctx == TypeInTempStruct)
175175 return " std::string" ;
176176 return " StringRef" ;
177- } else if (const auto *BI = dyn_cast<BitsRecTy>(Field.RecType )) {
177+ }
178+ if (const auto *BI = dyn_cast<BitsRecTy>(Field.RecType )) {
178179 unsigned NumBits = BI->getNumBits ();
179180 if (NumBits <= 8 )
180181 return " uint8_t" ;
@@ -188,11 +189,11 @@ class SearchableTableEmitter {
188189 " ' lookup method '" + Index.Name +
189190 " ', key field '" + Field.Name +
190191 " ' of type bits is too large" );
191- } else if (isa<BitRecTy>(Field.RecType )) {
192+ }
193+ if (isa<BitRecTy>(Field.RecType ))
192194 return " bool" ;
193- } else if (Field.Enum || Field.IsIntrinsic || Field.IsInstruction ) {
195+ if (Field.Enum || Field.IsIntrinsic || Field.IsInstruction )
194196 return " unsigned" ;
195- }
196197 PrintFatalError (Index.Loc ,
197198 Twine (" In table '" ) + Table.Name + " ' lookup method '" +
198199 Index.Name + " ', key field '" + Field.Name +
@@ -245,67 +246,74 @@ int64_t SearchableTableEmitter::getNumericKey(const SearchIndex &Index,
245246// / key of \p Index.
246247bool SearchableTableEmitter::compareBy (const Record *LHS, const Record *RHS,
247248 const SearchIndex &Index) {
248- for (const auto &Field : Index.Fields ) {
249- const Init *LHSI = LHS->getValueInit (Field.Name );
250- const Init *RHSI = RHS->getValueInit (Field.Name );
249+ // Compare two values and return:
250+ // true if LHS < RHS
251+ // false if LHS > RHS
252+ // std::nullopt if LHS == RHS
253+ auto CmpLTValue = [](const auto &LHS,
254+ const auto &RHS) -> std::optional<bool > {
255+ if (LHS < RHS)
256+ return true ;
257+ if (LHS > RHS)
258+ return false ;
259+ return std::nullopt ;
260+ };
251261
262+ // Compare two fields and returns:
263+ // true if LHS < RHS
264+ // false if LHS > RHS
265+ // std::nullopt if LHS == RHS
266+ auto CmpLTField = [this , &Index, CmpLTValue](
267+ const Init *LHSI, const Init *RHSI,
268+ const GenericField &Field) -> std::optional<bool > {
252269 if (isa<BitsRecTy>(Field.RecType ) || isa<IntRecTy>(Field.RecType )) {
253270 int64_t LHSi = getAsInt (LHSI);
254271 int64_t RHSi = getAsInt (RHSI);
255- if (LHSi < RHSi)
256- return true ;
257- if (LHSi > RHSi)
258- return false ;
259- } else if (Field.IsIntrinsic ) {
272+ return CmpLTValue (LHSi, RHSi);
273+ }
274+
275+ if (Field.IsIntrinsic ) {
260276 const CodeGenIntrinsic &LHSi = getIntrinsic (LHSI);
261277 const CodeGenIntrinsic &RHSi = getIntrinsic (RHSI);
262- if (std::tie (LHSi.TargetPrefix , LHSi.Name ) <
263- std::tie (RHSi.TargetPrefix , RHSi.Name ))
264- return true ;
265- if (std::tie (LHSi.TargetPrefix , LHSi.Name ) >
266- std::tie (RHSi.TargetPrefix , RHSi.Name ))
267- return false ;
268- } else if (Field.IsInstruction ) {
278+ return CmpLTValue (std::tie (LHSi.TargetPrefix , LHSi.Name ),
279+ std::tie (RHSi.TargetPrefix , RHSi.Name ));
280+ }
281+
282+ if (Field.IsInstruction ) {
269283 // This does not correctly compare the predefined instructions!
270284 const Record *LHSr = cast<DefInit>(LHSI)->getDef ();
271285 const Record *RHSr = cast<DefInit>(RHSI)->getDef ();
272286
273- bool LHSpseudo = LHSr-> getValueAsBit ( " isPseudo " );
274- bool RHSpseudo = RHSr ->getValueAsBit (" isPseudo" );
275- if (LHSpseudo && !RHSpseudo)
276- return true ;
277- if (!LHSpseudo && RHSpseudo)
278- return false ;
287+ // Order pseudo instructions before non-pseudo ones.
288+ bool LHSNotPseudo = !LHSr ->getValueAsBit (" isPseudo" );
289+ bool RHSNotPseudo = !RHSr-> getValueAsBit ( " isPseudo " );
290+ return CmpLTValue ( std::tuple (LHSNotPseudo, LHSr-> getName ()),
291+ std::tuple (RHSNotPseudo, RHSr-> getName ()));
292+ }
279293
280- int comp = LHSr->getName ().compare (RHSr->getName ());
281- if (comp < 0 )
282- return true ;
283- if (comp > 0 )
284- return false ;
285- } else if (Field.Enum ) {
286- auto LHSr = cast<DefInit>(LHSI)->getDef ();
287- auto RHSr = cast<DefInit>(RHSI)->getDef ();
288- int64_t LHSv = Field.Enum ->getEntry (LHSr)->Value ;
289- int64_t RHSv = Field.Enum ->getEntry (RHSr)->Value ;
290- if (LHSv < RHSv)
291- return true ;
292- if (LHSv > RHSv)
293- return false ;
294- } else {
295- std::string LHSs = primaryRepresentation (Index.Loc , Field, LHSI);
296- std::string RHSs = primaryRepresentation (Index.Loc , Field, RHSI);
294+ if (Field.Enum ) {
295+ const Record *LHSr = cast<DefInit>(LHSI)->getDef ();
296+ const Record *RHSr = cast<DefInit>(RHSI)->getDef ();
297+ int64_t LHSv = Field.Enum ->EntryMap [LHSr]->second ;
298+ int64_t RHSv = Field.Enum ->EntryMap [RHSr]->second ;
299+ return CmpLTValue (LHSv, RHSv);
300+ }
297301
298- if (isa<StringRecTy>(Field.RecType )) {
299- LHSs = StringRef (LHSs).upper ();
300- RHSs = StringRef (RHSs).upper ();
301- }
302+ std::string LHSs = primaryRepresentation (Index.Loc , Field, LHSI);
303+ std::string RHSs = primaryRepresentation (Index.Loc , Field, RHSI);
302304
303- int comp = LHSs.compare (RHSs);
304- if (comp < 0 )
305- return true ;
306- if (comp > 0 )
307- return false ;
305+ if (isa<StringRecTy>(Field.RecType )) {
306+ LHSs = StringRef (LHSs).upper ();
307+ RHSs = StringRef (RHSs).upper ();
308308 }
309+ return CmpLTValue (LHSs, RHSs);
310+ };
311+
312+ for (const GenericField &Field : Index.Fields ) {
313+ const Init *LHSI = LHS->getValueInit (Field.Name );
314+ const Init *RHSI = RHS->getValueInit (Field.Name );
315+ if (std::optional<bool > Cmp = CmpLTField (LHSI, RHSI, Field))
316+ return *Cmp;
309317 }
310318 return false ;
311319}
0 commit comments