@@ -634,10 +634,10 @@ struct MatchableInfo {
634
634
635
635
// Compare lexicographically by operand. The matcher validates that other
636
636
// orderings wouldn't be ambiguous using \see couldMatchAmbiguouslyWith().
637
- for (unsigned i = 0 , e = AsmOperands. size (); i != e; ++i ) {
638
- if (*AsmOperands[i] .Class < *RHS. AsmOperands [i] .Class )
637
+ for (const auto &[LHSOp, RHSOp] : zip_equal ( AsmOperands, RHS. AsmOperands ) ) {
638
+ if (*LHSOp .Class < *RHSOp .Class )
639
639
return true ;
640
- if (*RHS. AsmOperands [i]. Class < *AsmOperands[i] .Class )
640
+ if (*RHSOp. Class < *LHSOp .Class )
641
641
return false ;
642
642
}
643
643
@@ -692,21 +692,21 @@ struct MatchableInfo {
692
692
693
693
// Tokens and operand kinds are unambiguous (assuming a correct target
694
694
// specific parser).
695
- for (unsigned i = 0 , e = AsmOperands.size (); i != e; ++i)
696
- if (AsmOperands[i].Class ->Kind != RHS.AsmOperands [i].Class ->Kind ||
697
- AsmOperands[i].Class ->Kind == ClassInfo::Token)
698
- if (*AsmOperands[i].Class < *RHS.AsmOperands [i].Class ||
699
- *RHS.AsmOperands [i].Class < *AsmOperands[i].Class )
695
+ for (const auto &[LHSOp, RHSOp] : zip_equal (AsmOperands, RHS.AsmOperands )) {
696
+ if (LHSOp.Class ->Kind != RHSOp.Class ->Kind ||
697
+ LHSOp.Class ->Kind == ClassInfo::Token)
698
+ if (*LHSOp.Class < *RHSOp.Class || *RHSOp.Class < *LHSOp.Class )
700
699
return false ;
700
+ }
701
701
702
702
// Otherwise, this operand could commute if all operands are equivalent, or
703
703
// there is a pair of operands that compare less than and a pair that
704
704
// compare greater than.
705
705
bool HasLT = false , HasGT = false ;
706
- for (unsigned i = 0 , e = AsmOperands. size (); i != e; ++i ) {
707
- if (*AsmOperands[i] .Class < *RHS. AsmOperands [i] .Class )
706
+ for (const auto &[LHSOp, RHSOp] : zip_equal ( AsmOperands, RHS. AsmOperands ) ) {
707
+ if (*LHSOp .Class < *RHSOp .Class )
708
708
HasLT = true ;
709
- if (*RHS. AsmOperands [i]. Class < *AsmOperands[i] .Class )
709
+ if (*RHSOp. Class < *LHSOp .Class )
710
710
HasGT = true ;
711
711
}
712
712
@@ -810,7 +810,7 @@ class AsmMatcherInfo {
810
810
811
811
// / getSubtargetFeature - Lookup or create the subtarget feature info for the
812
812
// / given operand.
813
- const SubtargetFeatureInfo *getSubtargetFeature (Record *Def) const {
813
+ const SubtargetFeatureInfo *getSubtargetFeature (const Record *Def) const {
814
814
assert (Def->isSubClassOf (" Predicate" ) && " Invalid predicate type!" );
815
815
const auto &I = SubtargetFeatures.find (Def);
816
816
return I == SubtargetFeatures.end () ? nullptr : &I->second ;
@@ -833,9 +833,8 @@ LLVM_DUMP_METHOD void MatchableInfo::dump() const {
833
833
834
834
errs () << " variant: " << AsmVariantID << " \n " ;
835
835
836
- for (unsigned i = 0 , e = AsmOperands.size (); i != e; ++i) {
837
- const AsmOperand &Op = AsmOperands[i];
838
- errs () << " op[" << i << " ] = " << Op.Class ->ClassName << " - " ;
836
+ for (const auto &[Idx, Op] : enumerate(AsmOperands)) {
837
+ errs () << " op[" << Idx << " ] = " << Op.Class ->ClassName << " - " ;
839
838
errs () << ' \" ' << Op.Token << " \"\n " ;
840
839
}
841
840
}
@@ -1490,21 +1489,18 @@ void AsmMatcherInfo::buildOperandMatchInfo() {
1490
1489
// Keep track of all operands of this instructions which belong to the
1491
1490
// same class.
1492
1491
unsigned NumOptionalOps = 0 ;
1493
- for (unsigned i = 0 , e = MI->AsmOperands .size (); i != e; ++i) {
1494
- const MatchableInfo::AsmOperand &Op = MI->AsmOperands [i];
1492
+ for (const auto &[Idx, Op] : enumerate(MI->AsmOperands )) {
1495
1493
if (CallCustomParserForAllOperands || !Op.Class ->ParserMethod .empty ()) {
1496
1494
unsigned &OperandMask = OpClassMask[Op.Class ];
1497
1495
OperandMask |= maskTrailingOnes<unsigned >(NumOptionalOps + 1 )
1498
- << (i - NumOptionalOps);
1496
+ << (Idx - NumOptionalOps);
1499
1497
}
1500
1498
if (Op.Class ->IsOptional )
1501
1499
++NumOptionalOps;
1502
1500
}
1503
1501
1504
1502
// Generate operand match info for each mnemonic/operand class pair.
1505
- for (const auto &OCM : OpClassMask) {
1506
- unsigned OpMask = OCM.second ;
1507
- ClassInfo *CI = OCM.first ;
1503
+ for (const auto [CI, OpMask] : OpClassMask) {
1508
1504
OperandMatchInfo.push_back (
1509
1505
OperandMatchEntry::create (MI.get (), CI, OpMask));
1510
1506
}
@@ -1613,11 +1609,11 @@ void AsmMatcherInfo::buildInfo() {
1613
1609
for (auto &II : Matchables) {
1614
1610
// Parse the tokens after the mnemonic.
1615
1611
// Note: buildInstructionOperandReference may insert new AsmOperands, so
1616
- // don't precompute the loop bound.
1617
- for (unsigned i = 0 ; i != II->AsmOperands .size (); ++i) {
1618
- MatchableInfo::AsmOperand &Op = II->AsmOperands [i];
1612
+ // don't precompute the loop bound, i.e., cannot use range based for loop
1613
+ // here.
1614
+ for (size_t Idx = 0 ; Idx < II->AsmOperands .size (); ++Idx) {
1615
+ MatchableInfo::AsmOperand &Op = II->AsmOperands [Idx];
1619
1616
StringRef Token = Op.Token ;
1620
-
1621
1617
// Check for singleton registers.
1622
1618
if (const Record *RegRecord = Op.SingletonReg ) {
1623
1619
Op.Class = RegisterClasses[RegRecord];
@@ -1645,7 +1641,7 @@ void AsmMatcherInfo::buildInfo() {
1645
1641
OperandName = Token.substr (1 );
1646
1642
1647
1643
if (isa<const CodeGenInstruction *>(II->DefRec ))
1648
- buildInstructionOperandReference (II.get (), OperandName, i );
1644
+ buildInstructionOperandReference (II.get (), OperandName, Idx );
1649
1645
else
1650
1646
buildAliasOperandReference (II.get (), OperandName, Op);
1651
1647
}
@@ -1779,21 +1775,21 @@ void AsmMatcherInfo::buildAliasOperandReference(MatchableInfo *II,
1779
1775
const CodeGenInstAlias &CGA = *cast<const CodeGenInstAlias *>(II->DefRec );
1780
1776
1781
1777
// Set up the operand class.
1782
- for (unsigned i = 0 , e = CGA. ResultOperands . size (); i != e; ++i)
1783
- if (CGA.ResultOperands [i]. isRecord () &&
1784
- CGA. ResultOperands [i] .getName () == OperandName) {
1778
+ for (const auto &[ResultOp, SubOpIdx] :
1779
+ zip_equal (CGA.ResultOperands , CGA. ResultInstOperandIndex )) {
1780
+ if (ResultOp. isRecord () && ResultOp .getName () == OperandName) {
1785
1781
// It's safe to go with the first one we find, because CodeGenInstAlias
1786
1782
// validates that all operands with the same name have the same record.
1787
- Op.SubOpIdx = CGA. ResultInstOperandIndex [i] .second ;
1783
+ Op.SubOpIdx = SubOpIdx .second ;
1788
1784
// Use the match class from the Alias definition, not the
1789
1785
// destination instruction, as we may have an immediate that's
1790
1786
// being munged by the match class.
1791
- Op.Class =
1792
- getOperandClass (CGA.ResultOperands [i].getRecord (), Op.SubOpIdx );
1787
+ Op.Class = getOperandClass (ResultOp.getRecord (), Op.SubOpIdx );
1793
1788
Op.SrcOpName = OperandName;
1794
1789
Op.OrigSrcOpName = OperandName;
1795
1790
return ;
1796
1791
}
1792
+ }
1797
1793
1798
1794
PrintFatalError (II->TheDef ->getLoc (),
1799
1795
" error: unable to find operand: '" + OperandName + " '" );
@@ -1862,13 +1858,11 @@ void MatchableInfo::buildAliasResultOperands(bool AliasConstraintsAreChecked) {
1862
1858
// populate them.
1863
1859
unsigned AliasOpNo = 0 ;
1864
1860
unsigned LastOpNo = CGA.ResultInstOperandIndex .size ();
1865
- for (unsigned i = 0 , e = ResultInst->Operands .size (); i != e; ++i) {
1866
- const CGIOperandList::OperandInfo *OpInfo = &ResultInst->Operands [i];
1867
-
1861
+ for (const auto &[Idx, OpInfo] : enumerate(ResultInst->Operands )) {
1868
1862
// If this is a tied operand, just copy from the previously handled operand.
1869
1863
int TiedOp = -1 ;
1870
- if (OpInfo-> MINumOperands == 1 )
1871
- TiedOp = OpInfo-> getTiedRegister ();
1864
+ if (OpInfo. MINumOperands == 1 )
1865
+ TiedOp = OpInfo. getTiedRegister ();
1872
1866
if (TiedOp != -1 ) {
1873
1867
unsigned SrcOp1 = 0 ;
1874
1868
unsigned SrcOp2 = 0 ;
@@ -1898,7 +1892,7 @@ void MatchableInfo::buildAliasResultOperands(bool AliasConstraintsAreChecked) {
1898
1892
// to benefit from the tied-operands check and just match the operand
1899
1893
// as a normal, but not copy the original (TiedOp) to the result
1900
1894
// instruction. We do this by passing -1 as the tied operand to copy.
1901
- if (ResultInst-> Operands [i] .Rec ->getName () !=
1895
+ if (OpInfo .Rec ->getName () !=
1902
1896
ResultInst->Operands [TiedOp].Rec ->getName ()) {
1903
1897
SrcOp1 = ResOperands[TiedOp].AsmOperandNum ;
1904
1898
int SubIdx = CGA.ResultInstOperandIndex [AliasOpNo].second ;
@@ -1913,9 +1907,9 @@ void MatchableInfo::buildAliasResultOperands(bool AliasConstraintsAreChecked) {
1913
1907
}
1914
1908
1915
1909
// Handle all the suboperands for this operand.
1916
- const std::string &OpName = OpInfo-> Name ;
1910
+ const std::string &OpName = OpInfo. Name ;
1917
1911
for (; AliasOpNo < LastOpNo &&
1918
- CGA.ResultInstOperandIndex [AliasOpNo].first == i ;
1912
+ CGA.ResultInstOperandIndex [AliasOpNo].first == Idx ;
1919
1913
++AliasOpNo) {
1920
1914
int SubIdx = CGA.ResultInstOperandIndex [AliasOpNo].second ;
1921
1915
@@ -1935,7 +1929,7 @@ void MatchableInfo::buildAliasResultOperands(bool AliasConstraintsAreChecked) {
1935
1929
// record won't be updated and it will fail later on.
1936
1930
OperandRefs.try_emplace (Name, SrcOperand);
1937
1931
1938
- unsigned NumOperands = (SubIdx == -1 ? OpInfo-> MINumOperands : 1 );
1932
+ unsigned NumOperands = (SubIdx == -1 ? OpInfo. MINumOperands : 1 );
1939
1933
ResOperands.push_back (
1940
1934
ResOperand::getRenderedOp (SrcOperand, NumOperands));
1941
1935
break ;
@@ -2110,9 +2104,7 @@ emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
2110
2104
// Compute the convert enum and the case body.
2111
2105
MaxRowLength = std::max (MaxRowLength, II->ResOperands .size () * 2 + 1 );
2112
2106
2113
- for (unsigned i = 0 , e = II->ResOperands .size (); i != e; ++i) {
2114
- const MatchableInfo::ResOperand &OpInfo = II->ResOperands [i];
2115
-
2107
+ for (const auto &[Idx, OpInfo] : enumerate(II->ResOperands )) {
2116
2108
// Generate code to populate each result operand.
2117
2109
switch (OpInfo.Kind ) {
2118
2110
case MatchableInfo::ResOperand::RenderAsmOperand: {
@@ -2194,7 +2186,7 @@ emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
2194
2186
uint8_t TiedOp = OpInfo.TiedOperands .ResOpnd ;
2195
2187
uint8_t SrcOp1 = OpInfo.TiedOperands .SrcOpnd1Idx + HasMnemonicFirst;
2196
2188
uint8_t SrcOp2 = OpInfo.TiedOperands .SrcOpnd2Idx + HasMnemonicFirst;
2197
- assert ((i > TiedOp || TiedOp == (uint8_t )-1 ) &&
2189
+ assert ((Idx > TiedOp || TiedOp == (uint8_t )-1 ) &&
2198
2190
" Tied operand precedes its target!" );
2199
2191
auto TiedTupleName = std::string (" Tie" ) + utostr (TiedOp) + ' _' +
2200
2192
utostr (SrcOp1) + ' _' + utostr (SrcOp2);
@@ -2730,26 +2722,21 @@ static void emitGetSubtargetFeatureName(AsmMatcherInfo &Info, raw_ostream &OS) {
2730
2722
OS << " }\n\n " ;
2731
2723
}
2732
2724
2733
- static std::string GetAliasRequiredFeatures (Record *R,
2725
+ static std::string GetAliasRequiredFeatures (const Record *R,
2734
2726
const AsmMatcherInfo &Info) {
2735
- std::vector<Record *> ReqFeatures = R->getValueAsListOfDefs (" Predicates" );
2736
2727
std::string Result;
2737
2728
2738
- if (ReqFeatures.empty ())
2739
- return Result;
2740
-
2741
- for (unsigned i = 0 , e = ReqFeatures.size (); i != e; ++i) {
2742
- const SubtargetFeatureInfo *F = Info.getSubtargetFeature (ReqFeatures[i]);
2743
-
2729
+ bool First = true ;
2730
+ for (const Record *RF : R->getValueAsListOfDefs (" Predicates" )) {
2731
+ const SubtargetFeatureInfo *F = Info.getSubtargetFeature (RF);
2744
2732
if (!F)
2745
2733
PrintFatalError (R->getLoc (),
2746
- " Predicate '" + ReqFeatures[i] ->getName () +
2734
+ " Predicate '" + RF ->getName () +
2747
2735
" ' is not marked as an AssemblerPredicate!" );
2748
-
2749
- if (i)
2736
+ if (!First)
2750
2737
Result += " && " ;
2751
-
2752
2738
Result += " Features.test(" + F->getEnumBitName () + ' )' ;
2739
+ First = false ;
2753
2740
}
2754
2741
2755
2742
return Result;
@@ -2778,16 +2765,14 @@ emitMnemonicAliasVariant(raw_ostream &OS, const AsmMatcherInfo &Info,
2778
2765
// by the string remapper.
2779
2766
std::vector<StringMatcher::StringPair> Cases;
2780
2767
for (const auto &AliasEntry : AliasesFromMnemonic) {
2781
- const std::vector<Record *> &ToVec = AliasEntry.second ;
2782
-
2783
2768
// Loop through each alias and emit code that handles each case. If there
2784
2769
// are two instructions without predicates, emit an error. If there is one,
2785
2770
// emit it last.
2786
2771
std::string MatchCode;
2787
2772
int AliasWithNoPredicate = -1 ;
2788
2773
2789
- for ( unsigned i = 0 , e = ToVec. size (); i != e; ++i) {
2790
- Record *R = ToVec[i];
2774
+ ArrayRef< const Record *> ToVec = AliasEntry. second ;
2775
+ for ( const auto &[Idx, R] : enumerate( ToVec)) {
2791
2776
std::string FeatureMask = GetAliasRequiredFeatures (R, Info);
2792
2777
2793
2778
// If this unconditionally matches, remember it for later and diagnose
@@ -2804,7 +2789,7 @@ emitMnemonicAliasVariant(raw_ostream &OS, const AsmMatcherInfo &Info,
2804
2789
PrintFatalError (R->getLoc (), " this is the other MnemonicAlias." );
2805
2790
}
2806
2791
2807
- AliasWithNoPredicate = i ;
2792
+ AliasWithNoPredicate = Idx ;
2808
2793
continue ;
2809
2794
}
2810
2795
if (R->getValueAsString (" ToMnemonic" ) == AliasEntry.first )
@@ -2819,7 +2804,7 @@ emitMnemonicAliasVariant(raw_ostream &OS, const AsmMatcherInfo &Info,
2819
2804
}
2820
2805
2821
2806
if (AliasWithNoPredicate != -1 ) {
2822
- Record *R = ToVec[AliasWithNoPredicate];
2807
+ const Record *R = ToVec[AliasWithNoPredicate];
2823
2808
if (!MatchCode.empty ())
2824
2809
MatchCode += " else\n " ;
2825
2810
MatchCode += " Mnemonic = \" " ;
@@ -2955,8 +2940,8 @@ emitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target,
2955
2940
if (II.RequiredFeatures .empty ())
2956
2941
OS << " _None" ;
2957
2942
else
2958
- for (unsigned i = 0 , e = II.RequiredFeatures . size (); i != e; ++i )
2959
- OS << ' _' << II. RequiredFeatures [i] ->TheDef ->getName ();
2943
+ for (const auto &F : II.RequiredFeatures )
2944
+ OS << ' _' << F ->TheDef ->getName ();
2960
2945
2961
2946
OS << " },\n " ;
2962
2947
}
@@ -3467,24 +3452,20 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
3467
3452
if (MI->RequiredFeatures .empty ())
3468
3453
continue ;
3469
3454
FeatureBitsets.emplace_back ();
3470
- for (unsigned I = 0 , E = MI->RequiredFeatures . size (); I != E; ++I )
3471
- FeatureBitsets.back ().push_back (MI-> RequiredFeatures [I] ->TheDef );
3455
+ for (const auto *F : MI->RequiredFeatures )
3456
+ FeatureBitsets.back ().push_back (F ->TheDef );
3472
3457
}
3473
3458
3474
- llvm::sort (FeatureBitsets, [&](const std::vector<const Record *> &A,
3475
- const std::vector<const Record *> &B) {
3476
- if (A.size () < B.size ())
3477
- return true ;
3478
- if (A.size () > B.size ())
3479
- return false ;
3480
- for (auto Pair : zip (A, B)) {
3481
- if (std::get<0 >(Pair)->getName () < std::get<1 >(Pair)->getName ())
3482
- return true ;
3483
- if (std::get<0 >(Pair)->getName () > std::get<1 >(Pair)->getName ())
3484
- return false ;
3485
- }
3486
- return false ;
3487
- });
3459
+ llvm::sort (FeatureBitsets,
3460
+ [&](ArrayRef<const Record *> A, ArrayRef<const Record *> B) {
3461
+ if (A.size () != B.size ())
3462
+ return A.size () < B.size ();
3463
+ for (const auto [ARec, BRec] : zip_equal (A, B)) {
3464
+ if (ARec->getName () != BRec->getName ())
3465
+ return ARec->getName () < BRec->getName ();
3466
+ }
3467
+ return false ;
3468
+ });
3488
3469
FeatureBitsets.erase (llvm::unique (FeatureBitsets), FeatureBitsets.end ());
3489
3470
OS << " // Feature bitsets.\n "
3490
3471
<< " enum : " << getMinimalTypeForRange (FeatureBitsets.size ()) << " {\n "
@@ -3577,8 +3558,8 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
3577
3558
if (MI->RequiredFeatures .empty ())
3578
3559
OS << " _None" ;
3579
3560
else
3580
- for (unsigned i = 0 , e = MI->RequiredFeatures . size (); i != e; ++i )
3581
- OS << ' _' << MI-> RequiredFeatures [i] ->TheDef ->getName ();
3561
+ for (const auto &F : MI->RequiredFeatures )
3562
+ OS << ' _' << F ->TheDef ->getName ();
3582
3563
3583
3564
OS << " , { " ;
3584
3565
ListSeparator LS;
0 commit comments