@@ -261,11 +261,7 @@ uint64_t MCAssembler::computeFragmentSize(const MCFragment &F) const {
261
261
}
262
262
int64_t Size = NumValues * FF.getValueSize ();
263
263
if (Size < 0 ) {
264
- // The expression might use symbol values which have not yet converged.
265
- // Allow the first few iterations to have temporary negative values. The
266
- // limit is somewhat arbitrary but allows contrived interdependency.
267
- if (RelaxSteps >= 2 )
268
- getContext ().reportError (FF.getLoc (), " invalid number of bytes" );
264
+ getContext ().reportError (FF.getLoc (), " invalid number of bytes" );
269
265
return 0 ;
270
266
}
271
267
return Size;
@@ -432,6 +428,28 @@ void MCAssembler::layoutBundle(MCFragment *Prev, MCFragment *F) const {
432
428
DF->Offset = EF->Offset ;
433
429
}
434
430
431
+ void MCAssembler::ensureValid (MCSection &Sec) const {
432
+ if (Sec.hasLayout ())
433
+ return ;
434
+ Sec.setHasLayout (true );
435
+ MCFragment *Prev = nullptr ;
436
+ uint64_t Offset = 0 ;
437
+ for (MCFragment &F : Sec) {
438
+ F.Offset = Offset;
439
+ if (isBundlingEnabled () && F.hasInstructions ()) {
440
+ layoutBundle (Prev, &F);
441
+ Offset = F.Offset ;
442
+ }
443
+ Offset += computeFragmentSize (F);
444
+ Prev = &F;
445
+ }
446
+ }
447
+
448
+ uint64_t MCAssembler::getFragmentOffset (const MCFragment &F) const {
449
+ ensureValid (*F.getParent ());
450
+ return F.Offset ;
451
+ }
452
+
435
453
// Simple getSymbolOffset helper for the non-variable case.
436
454
static bool getLabelOffset (const MCAssembler &Asm, const MCSymbol &S,
437
455
bool ReportError, uint64_t &Val) {
@@ -911,38 +929,22 @@ void MCAssembler::layout() {
911
929
912
930
// Layout until everything fits.
913
931
this ->HasLayout = true ;
914
- for (MCSection &Sec : *this ) {
915
- MCFragment *Prev = nullptr ;
916
- uint64_t Offset = 0 ;
917
- for (MCFragment &F : Sec) {
918
- F.Offset = Offset;
919
- if (LLVM_UNLIKELY (isBundlingEnabled ())) {
920
- if (F.hasInstructions ()) {
921
- layoutBundle (Prev, &F);
922
- Offset = F.Offset ;
923
- }
924
- Prev = &F;
925
- }
926
- Offset += computeFragmentSize (F);
927
- }
928
- }
929
- while (relaxOnce ())
932
+ while (layoutOnce ()) {
930
933
if (getContext ().hadError ())
931
934
return ;
935
+ // Size of fragments in one section can depend on the size of fragments in
936
+ // another. If any fragment has changed size, we have to re-layout (and
937
+ // as a result possibly further relax) all.
938
+ for (MCSection &Sec : *this )
939
+ Sec.setHasLayout (false );
940
+ }
932
941
933
942
DEBUG_WITH_TYPE (" mc-dump" , {
934
943
errs () << " assembler backend - post-relaxation\n --\n " ;
935
944
dump (); });
936
945
937
- // Some targets might want to adjust fragment offsets. If so, perform another
938
- // relaxation loop.
939
- if (getBackend ().finishLayout (*this ))
940
- while (relaxOnce ())
941
- if (getContext ().hadError ())
942
- return ;
943
-
944
- // Trigger computeFragmentSize errors.
945
- RelaxSteps = UINT_MAX;
946
+ // Finalize the layout, including fragment lowering.
947
+ getBackend ().finishLayout (*this );
946
948
947
949
DEBUG_WITH_TYPE (" mc-dump" , {
948
950
errs () << " assembler backend - final-layout\n --\n " ;
@@ -1071,11 +1073,11 @@ bool MCAssembler::fragmentNeedsRelaxation(const MCRelaxableFragment *F) const {
1071
1073
return false ;
1072
1074
}
1073
1075
1074
- void MCAssembler::relaxInstruction (MCRelaxableFragment &F) {
1076
+ bool MCAssembler::relaxInstruction (MCRelaxableFragment &F) {
1075
1077
assert (getEmitterPtr () &&
1076
1078
" Expected CodeEmitter defined for relaxInstruction" );
1077
1079
if (!fragmentNeedsRelaxation (&F))
1078
- return ;
1080
+ return false ;
1079
1081
1080
1082
++stats::RelaxedInstructions;
1081
1083
@@ -1093,9 +1095,10 @@ void MCAssembler::relaxInstruction(MCRelaxableFragment &F) {
1093
1095
F.getContents ().clear ();
1094
1096
getEmitter ().encodeInstruction (Relaxed, F.getContents (), F.getFixups (),
1095
1097
*F.getSubtargetInfo ());
1098
+ return true ;
1096
1099
}
1097
1100
1098
- void MCAssembler::relaxLEB (MCLEBFragment &LF) {
1101
+ bool MCAssembler::relaxLEB (MCLEBFragment &LF) {
1099
1102
const unsigned OldSize = static_cast <unsigned >(LF.getContents ().size ());
1100
1103
unsigned PadTo = OldSize;
1101
1104
int64_t Value;
@@ -1131,6 +1134,7 @@ void MCAssembler::relaxLEB(MCLEBFragment &LF) {
1131
1134
encodeSLEB128 (Value, OSE, PadTo);
1132
1135
else
1133
1136
encodeULEB128 (Value, OSE, PadTo);
1137
+ return OldSize != LF.getContents ().size ();
1134
1138
}
1135
1139
1136
1140
// / Check if the branch crosses the boundary.
@@ -1170,11 +1174,11 @@ static bool needPadding(uint64_t StartAddr, uint64_t Size,
1170
1174
isAgainstBoundary (StartAddr, Size, BoundaryAlignment);
1171
1175
}
1172
1176
1173
- void MCAssembler::relaxBoundaryAlign (MCBoundaryAlignFragment &BF) {
1177
+ bool MCAssembler::relaxBoundaryAlign (MCBoundaryAlignFragment &BF) {
1174
1178
// BoundaryAlignFragment that doesn't need to align any fragment should not be
1175
1179
// relaxed.
1176
1180
if (!BF.getLastFragment ())
1177
- return ;
1181
+ return false ;
1178
1182
1179
1183
uint64_t AlignedOffset = getFragmentOffset (BF);
1180
1184
uint64_t AlignedSize = 0 ;
@@ -1188,15 +1192,19 @@ void MCAssembler::relaxBoundaryAlign(MCBoundaryAlignFragment &BF) {
1188
1192
uint64_t NewSize = needPadding (AlignedOffset, AlignedSize, BoundaryAlignment)
1189
1193
? offsetToAlignment (AlignedOffset, BoundaryAlignment)
1190
1194
: 0U ;
1195
+ if (NewSize == BF.getSize ())
1196
+ return false ;
1191
1197
BF.setSize (NewSize);
1198
+ return true ;
1192
1199
}
1193
1200
1194
- void MCAssembler::relaxDwarfLineAddr (MCDwarfLineAddrFragment &DF) {
1201
+ bool MCAssembler::relaxDwarfLineAddr (MCDwarfLineAddrFragment &DF) {
1195
1202
bool WasRelaxed;
1196
1203
if (getBackend ().relaxDwarfLineAddr (*this , DF, WasRelaxed))
1197
- return ;
1204
+ return WasRelaxed ;
1198
1205
1199
1206
MCContext &Context = getContext ();
1207
+ uint64_t OldSize = DF.getContents ().size ();
1200
1208
int64_t AddrDelta;
1201
1209
bool Abs = DF.getAddrDelta ().evaluateKnownAbsolute (AddrDelta, *this );
1202
1210
assert (Abs && " We created a line delta with an invalid expression" );
@@ -1209,12 +1217,13 @@ void MCAssembler::relaxDwarfLineAddr(MCDwarfLineAddrFragment &DF) {
1209
1217
1210
1218
MCDwarfLineAddr::encode (Context, getDWARFLinetableParams (), LineDelta,
1211
1219
AddrDelta, Data);
1220
+ return OldSize != Data.size ();
1212
1221
}
1213
1222
1214
- void MCAssembler::relaxDwarfCallFrameFragment (MCDwarfCallFrameFragment &DF) {
1223
+ bool MCAssembler::relaxDwarfCallFrameFragment (MCDwarfCallFrameFragment &DF) {
1215
1224
bool WasRelaxed;
1216
1225
if (getBackend ().relaxDwarfCFA (*this , DF, WasRelaxed))
1217
- return ;
1226
+ return WasRelaxed ;
1218
1227
1219
1228
MCContext &Context = getContext ();
1220
1229
int64_t Value;
@@ -1223,25 +1232,31 @@ void MCAssembler::relaxDwarfCallFrameFragment(MCDwarfCallFrameFragment &DF) {
1223
1232
getContext ().reportError (DF.getAddrDelta ().getLoc (),
1224
1233
" invalid CFI advance_loc expression" );
1225
1234
DF.setAddrDelta (MCConstantExpr::create (0 , Context));
1226
- return ;
1235
+ return false ;
1227
1236
}
1228
1237
1229
1238
SmallVectorImpl<char > &Data = DF.getContents ();
1239
+ uint64_t OldSize = Data.size ();
1230
1240
Data.clear ();
1231
1241
DF.getFixups ().clear ();
1232
1242
1233
1243
MCDwarfFrameEmitter::encodeAdvanceLoc (Context, Value, Data);
1244
+ return OldSize != Data.size ();
1234
1245
}
1235
1246
1236
- void MCAssembler::relaxCVInlineLineTable (MCCVInlineLineTableFragment &F) {
1247
+ bool MCAssembler::relaxCVInlineLineTable (MCCVInlineLineTableFragment &F) {
1248
+ unsigned OldSize = F.getContents ().size ();
1237
1249
getContext ().getCVContext ().encodeInlineLineTable (*this , F);
1250
+ return OldSize != F.getContents ().size ();
1238
1251
}
1239
1252
1240
- void MCAssembler::relaxCVDefRange (MCCVDefRangeFragment &F) {
1253
+ bool MCAssembler::relaxCVDefRange (MCCVDefRangeFragment &F) {
1254
+ unsigned OldSize = F.getContents ().size ();
1241
1255
getContext ().getCVContext ().encodeDefRange (*this , F);
1256
+ return OldSize != F.getContents ().size ();
1242
1257
}
1243
1258
1244
- void MCAssembler::relaxPseudoProbeAddr (MCPseudoProbeAddrFragment &PF) {
1259
+ bool MCAssembler::relaxPseudoProbeAddr (MCPseudoProbeAddrFragment &PF) {
1245
1260
uint64_t OldSize = PF.getContents ().size ();
1246
1261
int64_t AddrDelta;
1247
1262
bool Abs = PF.getAddrDelta ().evaluateKnownAbsolute (AddrDelta, *this );
@@ -1254,12 +1269,13 @@ void MCAssembler::relaxPseudoProbeAddr(MCPseudoProbeAddrFragment &PF) {
1254
1269
1255
1270
// AddrDelta is a signed integer
1256
1271
encodeSLEB128 (AddrDelta, OSE, OldSize);
1272
+ return OldSize != Data.size ();
1257
1273
}
1258
1274
1259
- void MCAssembler::relaxFragment (MCFragment &F) {
1275
+ bool MCAssembler::relaxFragment (MCFragment &F) {
1260
1276
switch (F.getKind ()) {
1261
1277
default :
1262
- return ;
1278
+ return false ;
1263
1279
case MCFragment::FT_Relaxable:
1264
1280
assert (!getRelaxAll () &&
1265
1281
" Did not expect a MCRelaxableFragment in RelaxAll mode" );
@@ -1281,57 +1297,15 @@ void MCAssembler::relaxFragment(MCFragment &F) {
1281
1297
}
1282
1298
}
1283
1299
1284
- bool MCAssembler::relaxOnce () {
1300
+ bool MCAssembler::layoutOnce () {
1285
1301
++stats::RelaxationSteps;
1286
- ++RelaxSteps;
1287
-
1288
- // Size of fragments in one section can depend on the size of fragments in
1289
- // another. If any fragment has changed size, we have to re-layout (and
1290
- // as a result possibly further relax) all sections.
1291
- bool ChangedAny = false , Changed;
1292
- for (MCSection &Sec : *this ) {
1293
- // Assume each iteration finalizes at least one extra fragment. If the
1294
- // layout does not converge after N+1 iterations, bail out.
1295
- auto MaxIter = Sec.curFragList ()->Tail ->getLayoutOrder () + 1 ;
1296
- uint64_t OldSize = getSectionAddressSize (Sec);
1297
- do {
1298
- uint64_t Offset = 0 ;
1299
- Changed = false ;
1300
- if (LLVM_UNLIKELY (isBundlingEnabled ())) {
1301
- MCFragment *Prev = nullptr ;
1302
- for (MCFragment &F : Sec) {
1303
- F.Offset = Offset;
1304
- relaxFragment (F);
1305
- if (F.hasInstructions ()) {
1306
- layoutBundle (Prev, &F);
1307
- Offset = F.Offset ;
1308
- }
1309
- Prev = &F;
1310
- if (F.Offset != Offset) {
1311
- F.Offset = Offset;
1312
- Changed = true ;
1313
- }
1314
- Offset += computeFragmentSize (F);
1315
- }
1316
- } else {
1317
- for (MCFragment &F : Sec) {
1318
- if (F.Offset != Offset) {
1319
- F.Offset = Offset;
1320
- Changed = true ;
1321
- }
1322
- relaxFragment (F);
1323
- Offset += computeFragmentSize (F);
1324
- }
1325
- }
1326
1302
1327
- Changed |= OldSize != Offset;
1328
- ChangedAny |= Changed;
1329
- OldSize = Offset;
1330
- } while (Changed && --MaxIter);
1331
- if (MaxIter == 0 )
1332
- return false ;
1333
- }
1334
- return ChangedAny;
1303
+ bool Changed = false ;
1304
+ for (MCSection &Sec : *this )
1305
+ for (MCFragment &Frag : Sec)
1306
+ if (relaxFragment (Frag))
1307
+ Changed = true ;
1308
+ return Changed;
1335
1309
}
1336
1310
1337
1311
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
0 commit comments