@@ -129,15 +129,15 @@ class BinaryEmitter {
129
129
130
130
// / Emit function code. The caller is responsible for emitting function
131
131
// / symbol(s) and setting the section to emit the code to.
132
- void emitFunctionBody (BinaryFunction &BF, bool EmitColdPart ,
132
+ void emitFunctionBody (BinaryFunction &BF, const FunctionFragment &FF ,
133
133
bool EmitCodeOnly = false );
134
134
135
135
private:
136
136
// / Emit function code.
137
137
void emitFunctions ();
138
138
139
139
// / Emit a single function.
140
- bool emitFunction (BinaryFunction &BF, bool EmitColdPart );
140
+ bool emitFunction (BinaryFunction &BF, const FunctionFragment &FF );
141
141
142
142
// / Helper for emitFunctionBody to write data inside a function
143
143
// / (used for AArch64)
@@ -234,13 +234,24 @@ void BinaryEmitter::emitFunctions() {
234
234
!Function->hasValidProfile ())
235
235
Streamer.setAllowAutoPadding (false );
236
236
237
- Emitted |= emitFunction (*Function, /* EmitColdPart=*/ false );
237
+ const FunctionLayout &Layout = Function->getLayout ();
238
+ Emitted |= emitFunction (*Function, Layout.getMainFragment ());
238
239
239
240
if (Function->isSplit ()) {
240
241
if (opts::X86AlignBranchBoundaryHotOnly)
241
242
Streamer.setAllowAutoPadding (false );
242
- Emitted |= emitFunction (*Function, /* EmitColdPart=*/ true );
243
+
244
+ assert ((Layout.fragment_size () == 1 || Function->isSimple ()) &&
245
+ " Only simple functions can have fragments" );
246
+ for (const FunctionFragment FF : Layout.getSplitFragments ()) {
247
+ // Skip empty fragments so no symbols and sections for empty fragments
248
+ // are generated
249
+ if (FF.empty () && !Function->hasConstantIsland ())
250
+ continue ;
251
+ Emitted |= emitFunction (*Function, FF);
252
+ }
243
253
}
254
+
244
255
Streamer.setAllowAutoPadding (OriginalAllowAutoPadding);
245
256
246
257
if (Emitted)
@@ -268,16 +279,18 @@ void BinaryEmitter::emitFunctions() {
268
279
}
269
280
}
270
281
271
- bool BinaryEmitter::emitFunction (BinaryFunction &Function, bool EmitColdPart) {
282
+ bool BinaryEmitter::emitFunction (BinaryFunction &Function,
283
+ const FunctionFragment &FF) {
272
284
if (Function.size () == 0 && !Function.hasIslandsInfo ())
273
285
return false ;
274
286
275
287
if (Function.getState () == BinaryFunction::State::Empty)
276
288
return false ;
277
289
278
- MCSection *Section =
279
- BC.getCodeSection (EmitColdPart ? Function.getColdCodeSectionName ()
280
- : Function.getCodeSectionName ());
290
+ MCSection *Section = BC.getCodeSection (
291
+ FF.isSplitFragment ()
292
+ ? Function.getColdCodeSectionName (FF.getFragmentNum ())
293
+ : Function.getCodeSectionName ());
281
294
Streamer.switchSection (Section);
282
295
Section->setHasInstructions (true );
283
296
BC.Ctx ->addGenDwarfSection (Section);
@@ -290,8 +303,9 @@ bool BinaryEmitter::emitFunction(BinaryFunction &Function, bool EmitColdPart) {
290
303
Section->setAlignment (Align (opts::AlignFunctions));
291
304
292
305
Streamer.emitCodeAlignment (BinaryFunction::MinAlign, &*BC.STI );
293
- uint16_t MaxAlignBytes = EmitColdPart ? Function.getMaxColdAlignmentBytes ()
294
- : Function.getMaxAlignmentBytes ();
306
+ uint16_t MaxAlignBytes = FF.isSplitFragment ()
307
+ ? Function.getMaxColdAlignmentBytes ()
308
+ : Function.getMaxAlignmentBytes ();
295
309
if (MaxAlignBytes > 0 )
296
310
Streamer.emitCodeAlignment (Function.getAlignment (), &*BC.STI ,
297
311
MaxAlignBytes);
@@ -302,29 +316,29 @@ bool BinaryEmitter::emitFunction(BinaryFunction &Function, bool EmitColdPart) {
302
316
MCContext &Context = Streamer.getContext ();
303
317
const MCAsmInfo *MAI = Context.getAsmInfo ();
304
318
305
- MCSymbol *StartSymbol = nullptr ;
319
+ MCSymbol *const StartSymbol = Function. getSymbol (FF. getFragmentNum ()) ;
306
320
307
321
// Emit all symbols associated with the main function entry.
308
- if (!EmitColdPart) {
309
- StartSymbol = Function.getSymbol ();
322
+ if (FF.isMainFragment ()) {
310
323
for (MCSymbol *Symbol : Function.getSymbols ()) {
311
324
Streamer.emitSymbolAttribute (Symbol, MCSA_ELF_TypeFunction);
312
325
Streamer.emitLabel (Symbol);
313
326
}
314
327
} else {
315
- StartSymbol = Function.getColdSymbol ();
316
328
Streamer.emitSymbolAttribute (StartSymbol, MCSA_ELF_TypeFunction);
317
329
Streamer.emitLabel (StartSymbol);
318
330
}
319
331
320
332
// Emit CFI start
321
333
if (Function.hasCFI ()) {
334
+ assert (Function.getLayout ().isHotColdSplit () &&
335
+ " Exceptions supported only with hot/cold splitting." );
322
336
Streamer.emitCFIStartProc (/* IsSimple=*/ false );
323
337
if (Function.getPersonalityFunction () != nullptr )
324
338
Streamer.emitCFIPersonality (Function.getPersonalityFunction (),
325
339
Function.getPersonalityEncoding ());
326
- MCSymbol *LSDASymbol =
327
- EmitColdPart ? Function. getColdLSDASymbol () : Function.getLSDASymbol ();
340
+ MCSymbol *LSDASymbol = FF. isSplitFragment () ? Function. getColdLSDASymbol ()
341
+ : Function.getLSDASymbol ();
328
342
if (LSDASymbol)
329
343
Streamer.emitCFILsda (LSDASymbol, BC.LSDAEncoding );
330
344
else
@@ -353,7 +367,7 @@ bool BinaryEmitter::emitFunction(BinaryFunction &Function, bool EmitColdPart) {
353
367
}
354
368
355
369
// Emit code.
356
- emitFunctionBody (Function, EmitColdPart , /* EmitCodeOnly=*/ false );
370
+ emitFunctionBody (Function, FF , /* EmitCodeOnly=*/ false );
357
371
358
372
// Emit padding if requested.
359
373
if (size_t Padding = opts::padFunction (Function)) {
@@ -369,8 +383,9 @@ bool BinaryEmitter::emitFunction(BinaryFunction &Function, bool EmitColdPart) {
369
383
if (Function.hasCFI ())
370
384
Streamer.emitCFIEndProc ();
371
385
372
- MCSymbol *EndSymbol = EmitColdPart ? Function.getFunctionColdEndLabel ()
373
- : Function.getFunctionEndLabel ();
386
+ MCSymbol *EndSymbol = FF.isSplitFragment ()
387
+ ? Function.getFunctionColdEndLabel ()
388
+ : Function.getFunctionEndLabel ();
374
389
Streamer.emitLabel (EndSymbol);
375
390
376
391
if (MAI->hasDotTypeDotSizeDirective ()) {
@@ -384,21 +399,22 @@ bool BinaryEmitter::emitFunction(BinaryFunction &Function, bool EmitColdPart) {
384
399
emitLineInfoEnd (Function, EndSymbol);
385
400
386
401
// Exception handling info for the function.
387
- emitLSDA (Function, EmitColdPart );
402
+ emitLSDA (Function, FF. isSplitFragment () );
388
403
389
- if (!EmitColdPart && opts::JumpTables > JTS_NONE)
404
+ if (FF. isMainFragment () && opts::JumpTables > JTS_NONE)
390
405
emitJumpTables (Function);
391
406
392
407
return true ;
393
408
}
394
409
395
- void BinaryEmitter::emitFunctionBody (BinaryFunction &BF, bool EmitColdPart,
410
+ void BinaryEmitter::emitFunctionBody (BinaryFunction &BF,
411
+ const FunctionFragment &FF,
396
412
bool EmitCodeOnly) {
397
- if (!EmitCodeOnly && EmitColdPart && BF.hasConstantIsland ())
413
+ if (!EmitCodeOnly && FF.isSplitFragment () && BF.hasConstantIsland ()) {
414
+ assert (FF.getFragmentNum () == FragmentNum::cold () &&
415
+ " Constant island support only with hot/cold split" );
398
416
BF.duplicateConstantIslands ();
399
-
400
- const FunctionFragment FF = BF.getLayout ().getFragment (
401
- EmitColdPart ? FragmentNum::cold () : FragmentNum::hot ());
417
+ }
402
418
403
419
if (!FF.empty () && FF.front ()->isLandingPad ()) {
404
420
assert (!FF.front ()->isEntryPoint () &&
@@ -488,7 +504,7 @@ void BinaryEmitter::emitFunctionBody(BinaryFunction &BF, bool EmitColdPart,
488
504
}
489
505
490
506
if (!EmitCodeOnly)
491
- emitConstantIslands (BF, EmitColdPart );
507
+ emitConstantIslands (BF, FF. isSplitFragment () );
492
508
}
493
509
494
510
void BinaryEmitter::emitConstantIslands (BinaryFunction &BF, bool EmitColdPart,
@@ -904,7 +920,7 @@ void BinaryEmitter::emitLSDA(BinaryFunction &BF, bool EmitColdPart) {
904
920
905
921
// Corresponding FDE start.
906
922
const MCSymbol *StartSymbol =
907
- EmitColdPart ? BF.getColdSymbol ( ) : BF.getSymbol ();
923
+ EmitColdPart ? BF.getSymbol ( FragmentNum::cold () ) : BF.getSymbol ();
908
924
909
925
// Emit the LSDA header.
910
926
@@ -1148,9 +1164,9 @@ void emitBinaryContext(MCStreamer &Streamer, BinaryContext &BC,
1148
1164
}
1149
1165
1150
1166
void emitFunctionBody (MCStreamer &Streamer, BinaryFunction &BF,
1151
- bool EmitColdPart , bool EmitCodeOnly) {
1167
+ const FunctionFragment &FF , bool EmitCodeOnly) {
1152
1168
BinaryEmitter (Streamer, BF.getBinaryContext ())
1153
- .emitFunctionBody (BF, EmitColdPart , EmitCodeOnly);
1169
+ .emitFunctionBody (BF, FF , EmitCodeOnly);
1154
1170
}
1155
1171
1156
1172
} // namespace bolt
0 commit comments