@@ -795,7 +795,8 @@ void MCAssembler::layout() {
795
795
this ->HasLayout = true ;
796
796
for (MCSection &Sec : *this )
797
797
layoutSection (Sec);
798
- while (relaxOnce ())
798
+ unsigned FirstStable = Sections.size ();
799
+ while ((FirstStable = relaxOnce (FirstStable)) > 0 )
799
800
if (getContext ().hadError ())
800
801
return ;
801
802
@@ -1127,31 +1128,36 @@ void MCAssembler::layoutSection(MCSection &Sec) {
1127
1128
}
1128
1129
}
1129
1130
1130
- bool MCAssembler::relaxOnce () {
1131
+ unsigned MCAssembler::relaxOnce (unsigned FirstStable ) {
1131
1132
++stats::RelaxationSteps;
1132
1133
PendingErrors.clear ();
1133
1134
1134
- // Size of fragments in one section can depend on the size of fragments in
1135
- // another. If any fragment has changed size, we have to re-layout (and
1136
- // as a result possibly further relax) all sections.
1137
- bool ChangedAny = false ;
1138
- for (MCSection &Sec : *this ) {
1135
+ unsigned Res = 0 ;
1136
+ for (unsigned I = 0 ; I != FirstStable; ++I) {
1139
1137
// Assume each iteration finalizes at least one extra fragment. If the
1140
1138
// layout does not converge after N+1 iterations, bail out.
1139
+ auto &Sec = *Sections[I];
1141
1140
auto MaxIter = Sec.curFragList ()->Tail ->getLayoutOrder () + 1 ;
1142
1141
for (;;) {
1143
1142
bool Changed = false ;
1144
1143
for (MCFragment &F : Sec)
1145
1144
if (relaxFragment (F))
1146
1145
Changed = true ;
1147
1146
1148
- ChangedAny |= Changed;
1149
- if (!Changed || --MaxIter == 0 )
1147
+ if (!Changed)
1148
+ break ;
1149
+ // If any fragment changed size, it might impact the layout of subsequent
1150
+ // sections. Therefore, we must re-evaluate all sections.
1151
+ FirstStable = Sections.size ();
1152
+ Res = I;
1153
+ if (--MaxIter == 0 )
1150
1154
break ;
1151
1155
layoutSection (Sec);
1152
1156
}
1153
1157
}
1154
- return ChangedAny;
1158
+ // The subsequent relaxOnce call only needs to visit Sections [0,Res) if no
1159
+ // change occurred.
1160
+ return Res;
1155
1161
}
1156
1162
1157
1163
void MCAssembler::reportError (SMLoc L, const Twine &Msg) const {
0 commit comments