@@ -66,7 +66,6 @@ STATISTIC(EmittedFillFragments,
6666STATISTIC (EmittedNopsFragments, " Number of emitted assembler fragments - nops" );
6767STATISTIC (EmittedOrgFragments, " Number of emitted assembler fragments - org" );
6868STATISTIC (evaluateFixup, " Number of evaluated fixups" );
69- STATISTIC (FragmentLayouts, " Number of fragment layouts" );
7069STATISTIC (ObjectBytes, " Number of emitted object file bytes" );
7170STATISTIC (RelaxationSteps, " Number of assembler layout and relaxation steps" );
7271STATISTIC (RelaxedInstructions, " Number of relaxed instructions" );
@@ -404,29 +403,7 @@ uint64_t MCAssembler::computeFragmentSize(const MCAsmLayout &Layout,
404403 llvm_unreachable (" invalid fragment kind" );
405404}
406405
407- void MCAsmLayout::layoutFragment (MCFragment *F) {
408- MCFragment *Prev = F->getPrevNode ();
409-
410- // We should never try to recompute something which is valid.
411- assert (!isFragmentValid (F) && " Attempt to recompute a valid fragment!" );
412- // We should never try to compute the fragment layout if its predecessor
413- // isn't valid.
414- assert ((!Prev || isFragmentValid (Prev)) &&
415- " Attempt to compute fragment before its predecessor!" );
416-
417- assert (!F->IsBeingLaidOut && " Already being laid out!" );
418- F->IsBeingLaidOut = true ;
419-
420- ++stats::FragmentLayouts;
421-
422- // Compute fragment offset and size.
423- if (Prev)
424- F->Offset = Prev->Offset + getAssembler ().computeFragmentSize (*this , *Prev);
425- else
426- F->Offset = 0 ;
427- F->IsBeingLaidOut = false ;
428- LastValidFragment[F->getParent ()] = F;
429-
406+ void MCAsmLayout::layoutBundle (MCFragment *F) {
430407 // If bundling is enabled and this fragment has instructions in it, it has to
431408 // obey the bundling restrictions. With padding, we'll have:
432409 //
@@ -454,21 +431,40 @@ void MCAsmLayout::layoutFragment(MCFragment *F) {
454431 // within-fragment padding (which would produce less padding when N is less
455432 // than the bundle size), but for now we don't.
456433 //
457- if (Assembler.isBundlingEnabled () && F->hasInstructions ()) {
458- assert (isa<MCEncodedFragment>(F) &&
459- " Only MCEncodedFragment implementations have instructions" );
460- MCEncodedFragment *EF = cast<MCEncodedFragment>(F);
461- uint64_t FSize = Assembler.computeFragmentSize (*this , *EF);
462-
463- if (!Assembler.getRelaxAll () && FSize > Assembler.getBundleAlignSize ())
464- report_fatal_error (" Fragment can't be larger than a bundle size" );
465-
466- uint64_t RequiredBundlePadding =
467- computeBundlePadding (Assembler, EF, EF->Offset , FSize);
468- if (RequiredBundlePadding > UINT8_MAX)
469- report_fatal_error (" Padding cannot exceed 255 bytes" );
470- EF->setBundlePadding (static_cast <uint8_t >(RequiredBundlePadding));
471- EF->Offset += RequiredBundlePadding;
434+ assert (isa<MCEncodedFragment>(F) &&
435+ " Only MCEncodedFragment implementations have instructions" );
436+ MCEncodedFragment *EF = cast<MCEncodedFragment>(F);
437+ uint64_t FSize = Assembler.computeFragmentSize (*this , *EF);
438+
439+ if (!Assembler.getRelaxAll () && FSize > Assembler.getBundleAlignSize ())
440+ report_fatal_error (" Fragment can't be larger than a bundle size" );
441+
442+ uint64_t RequiredBundlePadding =
443+ computeBundlePadding (Assembler, EF, EF->Offset , FSize);
444+ if (RequiredBundlePadding > UINT8_MAX)
445+ report_fatal_error (" Padding cannot exceed 255 bytes" );
446+ EF->setBundlePadding (static_cast <uint8_t >(RequiredBundlePadding));
447+ EF->Offset += RequiredBundlePadding;
448+ }
449+
450+ uint64_t MCAsmLayout::getFragmentOffset (const MCFragment *F) const {
451+ ensureValid (F);
452+ return F->Offset ;
453+ }
454+
455+ void MCAsmLayout::ensureValid (const MCFragment *Frag) const {
456+ MCSection &Sec = *Frag->getParent ();
457+ if (Sec.hasLayout ())
458+ return ;
459+ Sec.setHasLayout (true );
460+ uint64_t Offset = 0 ;
461+ for (MCFragment &F : Sec) {
462+ F.Offset = Offset;
463+ if (Assembler.isBundlingEnabled () && F.hasInstructions ()) {
464+ const_cast <MCAsmLayout *>(this )->layoutBundle (&F);
465+ Offset = F.Offset ;
466+ }
467+ Offset += getAssembler ().computeFragmentSize (*this , F);
472468 }
473469}
474470
@@ -848,7 +844,7 @@ void MCAssembler::layout(MCAsmLayout &Layout) {
848844 // another. If any fragment has changed size, we have to re-layout (and
849845 // as a result possibly further relax) all.
850846 for (MCSection &Sec : *this )
851- Layout. invalidateFragmentsFrom (&* Sec.begin () );
847+ Sec.setHasLayout ( false );
852848 }
853849
854850 DEBUG_WITH_TYPE (" mc-dump" , {
@@ -1109,7 +1105,6 @@ bool MCAssembler::relaxBoundaryAlign(MCAsmLayout &Layout,
11091105 if (NewSize == BF.getSize ())
11101106 return false ;
11111107 BF.setSize (NewSize);
1112- Layout.invalidateFragmentsFrom (&BF);
11131108 return true ;
11141109}
11151110
@@ -1219,47 +1214,19 @@ bool MCAssembler::relaxFragment(MCAsmLayout &Layout, MCFragment &F) {
12191214 }
12201215}
12211216
1222- bool MCAssembler::layoutSectionOnce (MCAsmLayout &Layout, MCSection &Sec) {
1223- // Holds the first fragment which needed relaxing during this layout. It will
1224- // remain NULL if none were relaxed.
1225- // When a fragment is relaxed, all the fragments following it should get
1226- // invalidated because their offset is going to change.
1227- MCFragment *FirstRelaxedFragment = nullptr ;
1228-
1229- // Attempt to relax all the fragments in the section.
1230- for (MCFragment &Frag : Sec) {
1231- // Check if this is a fragment that needs relaxation.
1232- bool RelaxedFrag = relaxFragment (Layout, Frag);
1233- if (RelaxedFrag && !FirstRelaxedFragment)
1234- FirstRelaxedFragment = &Frag;
1235- }
1236- if (FirstRelaxedFragment) {
1237- Layout.invalidateFragmentsFrom (FirstRelaxedFragment);
1238- return true ;
1239- }
1240- return false ;
1241- }
1242-
12431217bool MCAssembler::layoutOnce (MCAsmLayout &Layout) {
12441218 ++stats::RelaxationSteps;
12451219
1246- bool WasRelaxed = false ;
1247- for (MCSection &Sec : *this ) {
1248- while (layoutSectionOnce (Layout, Sec))
1249- WasRelaxed = true ;
1250- }
1251-
1252- return WasRelaxed;
1220+ bool Changed = false ;
1221+ for (MCSection &Sec : *this )
1222+ for (MCFragment &Frag : Sec)
1223+ if (relaxFragment (Layout, Frag))
1224+ Changed = true ;
1225+ return Changed;
12531226}
12541227
12551228void MCAssembler::finishLayout (MCAsmLayout &Layout) {
12561229 assert (getBackendPtr () && " Expected assembler backend" );
1257- // The layout is done. Mark every fragment as valid.
1258- for (unsigned int i = 0 , n = Layout.getSectionOrder ().size (); i != n; ++i) {
1259- MCSection &Section = *Layout.getSectionOrder ()[i];
1260- Layout.getFragmentOffset (&*Section.getFragmentList ().rbegin ());
1261- computeFragmentSize (Layout, *Section.getFragmentList ().rbegin ());
1262- }
12631230 getBackend ().finishLayout (*this , Layout);
12641231}
12651232
0 commit comments