@@ -196,9 +196,14 @@ uint64_t MCAssembler::computeFragmentSize(const MCFragment &F) const {
196196 assert (getBackendPtr () && " Requires assembler backend" );
197197 switch (F.getKind ()) {
198198 case MCFragment::FT_Data:
199- return cast<MCDataFragment>(F).getContents ().size ();
200199 case MCFragment::FT_Relaxable:
201- return cast<MCRelaxableFragment>(F).getContents ().size ();
200+ case MCFragment::FT_LEB:
201+ case MCFragment::FT_Dwarf:
202+ case MCFragment::FT_DwarfFrame:
203+ case MCFragment::FT_CVInlineLines:
204+ case MCFragment::FT_CVDefRange:
205+ case MCFragment::FT_PseudoProbe:
206+ return cast<MCEncodedFragment>(F).getContents ().size ();
202207 case MCFragment::FT_Fill: {
203208 auto &FF = cast<MCFillFragment>(F);
204209 int64_t NumValues = 0 ;
@@ -217,9 +222,6 @@ uint64_t MCAssembler::computeFragmentSize(const MCFragment &F) const {
217222 case MCFragment::FT_Nops:
218223 return cast<MCNopsFragment>(F).getNumBytes ();
219224
220- case MCFragment::FT_LEB:
221- return cast<MCLEBFragment>(F).getContents ().size ();
222-
223225 case MCFragment::FT_BoundaryAlign:
224226 return cast<MCBoundaryAlignFragment>(F).getSize ();
225227
@@ -275,17 +277,6 @@ uint64_t MCAssembler::computeFragmentSize(const MCFragment &F) const {
275277 }
276278 return Size;
277279 }
278-
279- case MCFragment::FT_Dwarf:
280- return cast<MCDwarfLineAddrFragment>(F).getContents ().size ();
281- case MCFragment::FT_DwarfFrame:
282- return cast<MCDwarfCallFrameFragment>(F).getContents ().size ();
283- case MCFragment::FT_CVInlineLines:
284- return cast<MCCVInlineLineTableFragment>(F).getContents ().size ();
285- case MCFragment::FT_CVDefRange:
286- return cast<MCCVDefRangeFragment>(F).getContents ().size ();
287- case MCFragment::FT_PseudoProbe:
288- return cast<MCPseudoProbeAddrFragment>(F).getContents ().size ();
289280 }
290281
291282 llvm_unreachable (" invalid fragment kind" );
@@ -543,6 +534,22 @@ static void writeFragment(raw_ostream &OS, const MCAssembler &Asm,
543534 ++stats::EmittedFragments;
544535
545536 switch (F.getKind ()) {
537+ case MCFragment::FT_Data:
538+ case MCFragment::FT_Relaxable:
539+ case MCFragment::FT_LEB:
540+ case MCFragment::FT_Dwarf:
541+ case MCFragment::FT_DwarfFrame:
542+ case MCFragment::FT_CVInlineLines:
543+ case MCFragment::FT_CVDefRange:
544+ case MCFragment::FT_PseudoProbe: {
545+ if (F.getKind () == MCFragment::FT_Data)
546+ ++stats::EmittedDataFragments;
547+ else if (F.getKind () == MCFragment::FT_Relaxable)
548+ ++stats::EmittedRelaxableFragments;
549+ const auto &EF = cast<MCEncodedFragment>(F);
550+ OS << StringRef (EF.getContents ().data (), EF.getContents ().size ());
551+ break ;
552+ }
546553 case MCFragment::FT_Align: {
547554 ++stats::EmittedAlignFragments;
548555 const MCAlignFragment &AF = cast<MCAlignFragment>(F);
@@ -589,18 +596,6 @@ static void writeFragment(raw_ostream &OS, const MCAssembler &Asm,
589596 break ;
590597 }
591598
592- case MCFragment::FT_Data:
593- ++stats::EmittedDataFragments;
594- OS << StringRef (cast<MCDataFragment>(F).getContents ().data (),
595- cast<MCDataFragment>(F).getContents ().size ());
596- break ;
597-
598- case MCFragment::FT_Relaxable:
599- ++stats::EmittedRelaxableFragments;
600- OS << StringRef (cast<MCRelaxableFragment>(F).getContents ().data (),
601- cast<MCRelaxableFragment>(F).getContents ().size ());
602- break ;
603-
604599 case MCFragment::FT_Fill: {
605600 ++stats::EmittedFillFragments;
606601 const MCFillFragment &FF = cast<MCFillFragment>(F);
@@ -676,12 +671,6 @@ static void writeFragment(raw_ostream &OS, const MCAssembler &Asm,
676671 break ;
677672 }
678673
679- case MCFragment::FT_LEB: {
680- const MCLEBFragment &LF = cast<MCLEBFragment>(F);
681- OS << StringRef (LF.getContents ().data (), LF.getContents ().size ());
682- break ;
683- }
684-
685674 case MCFragment::FT_BoundaryAlign: {
686675 const MCBoundaryAlignFragment &BF = cast<MCBoundaryAlignFragment>(F);
687676 if (!Asm.getBackend ().writeNopData (OS, FragmentSize, BF.getSubtargetInfo ()))
@@ -706,31 +695,6 @@ static void writeFragment(raw_ostream &OS, const MCAssembler &Asm,
706695 break ;
707696 }
708697
709- case MCFragment::FT_Dwarf: {
710- const MCDwarfLineAddrFragment &OF = cast<MCDwarfLineAddrFragment>(F);
711- OS << StringRef (OF.getContents ().data (), OF.getContents ().size ());
712- break ;
713- }
714- case MCFragment::FT_DwarfFrame: {
715- const MCDwarfCallFrameFragment &CF = cast<MCDwarfCallFrameFragment>(F);
716- OS << StringRef (CF.getContents ().data (), CF.getContents ().size ());
717- break ;
718- }
719- case MCFragment::FT_CVInlineLines: {
720- const auto &OF = cast<MCCVInlineLineTableFragment>(F);
721- OS << StringRef (OF.getContents ().data (), OF.getContents ().size ());
722- break ;
723- }
724- case MCFragment::FT_CVDefRange: {
725- const auto &DRF = cast<MCCVDefRangeFragment>(F);
726- OS << StringRef (DRF.getContents ().data (), DRF.getContents ().size ());
727- break ;
728- }
729- case MCFragment::FT_PseudoProbe: {
730- const MCPseudoProbeAddrFragment &PF = cast<MCPseudoProbeAddrFragment>(F);
731- OS << StringRef (PF.getContents ().data (), PF.getContents ().size ());
732- break ;
733- }
734698 }
735699
736700 assert (OS.tell () - Start == FragmentSize &&
@@ -831,7 +795,8 @@ void MCAssembler::layout() {
831795 this ->HasLayout = true ;
832796 for (MCSection &Sec : *this )
833797 layoutSection (Sec);
834- while (relaxOnce ())
798+ unsigned FirstStable = Sections.size ();
799+ while ((FirstStable = relaxOnce (FirstStable)) > 0 )
835800 if (getContext ().hadError ())
836801 return ;
837802
@@ -1163,31 +1128,36 @@ void MCAssembler::layoutSection(MCSection &Sec) {
11631128 }
11641129}
11651130
1166- bool MCAssembler::relaxOnce () {
1131+ unsigned MCAssembler::relaxOnce (unsigned FirstStable ) {
11671132 ++stats::RelaxationSteps;
11681133 PendingErrors.clear ();
11691134
1170- // Size of fragments in one section can depend on the size of fragments in
1171- // another. If any fragment has changed size, we have to re-layout (and
1172- // as a result possibly further relax) all sections.
1173- bool ChangedAny = false ;
1174- for (MCSection &Sec : *this ) {
1135+ unsigned Res = 0 ;
1136+ for (unsigned I = 0 ; I != FirstStable; ++I) {
11751137 // Assume each iteration finalizes at least one extra fragment. If the
11761138 // layout does not converge after N+1 iterations, bail out.
1139+ auto &Sec = *Sections[I];
11771140 auto MaxIter = Sec.curFragList ()->Tail ->getLayoutOrder () + 1 ;
11781141 for (;;) {
11791142 bool Changed = false ;
11801143 for (MCFragment &F : Sec)
11811144 if (relaxFragment (F))
11821145 Changed = true ;
11831146
1184- ChangedAny |= Changed;
1185- 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 )
11861154 break ;
11871155 layoutSection (Sec);
11881156 }
11891157 }
1190- return ChangedAny;
1158+ // The subsequent relaxOnce call only needs to visit Sections [0,Res) if no
1159+ // change occurred.
1160+ return Res;
11911161}
11921162
11931163void MCAssembler::reportError (SMLoc L, const Twine &Msg) const {
0 commit comments