@@ -795,7 +795,8 @@ void MCAssembler::layout() {
795795 this ->HasLayout = true ;
796796 for (MCSection &Sec : *this )
797797 layoutSection (Sec);
798- while (relaxOnce ())
798+ unsigned FirstStable = Sections.size ();
799+ while ((FirstStable = relaxOnce (FirstStable)) > 0 )
799800 if (getContext ().hadError ())
800801 return ;
801802
@@ -1127,31 +1128,36 @@ void MCAssembler::layoutSection(MCSection &Sec) {
11271128 }
11281129}
11291130
1130- bool MCAssembler::relaxOnce () {
1131+ unsigned MCAssembler::relaxOnce (unsigned FirstStable ) {
11311132 ++stats::RelaxationSteps;
11321133 PendingErrors.clear ();
11331134
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) {
11391137 // Assume each iteration finalizes at least one extra fragment. If the
11401138 // layout does not converge after N+1 iterations, bail out.
1139+ auto &Sec = *Sections[I];
11411140 auto MaxIter = Sec.curFragList ()->Tail ->getLayoutOrder () + 1 ;
11421141 for (;;) {
11431142 bool Changed = false ;
11441143 for (MCFragment &F : Sec)
11451144 if (relaxFragment (F))
11461145 Changed = true ;
11471146
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 )
11501154 break ;
11511155 layoutSection (Sec);
11521156 }
11531157 }
1154- return ChangedAny;
1158+ // The subsequent relaxOnce call only needs to visit Sections [0,Res) if no
1159+ // change occurred.
1160+ return Res;
11551161}
11561162
11571163void MCAssembler::reportError (SMLoc L, const Twine &Msg) const {
0 commit comments