llvm.org GIT mirror llvm / ab494c9
[MC] Function stack size section. Re applying after fixing issues in the diff, sorry for any painful conflicts/merges! Original RFC: http://lists.llvm.org/pipermail/llvm-dev/2017-August/117028.html This change adds a '.stack-size' section containing metadata on function stack sizes to output ELF files behind the new -stack-size-section flag. The section contains pairs of function symbol references (8 byte) and stack sizes (unsigned LEB128). The contents of this section can be used to measure changes to stack sizes between different versions of the compiler or a source base. The advantage of having a section is that we can extract this information when examining binaries that we didn't build, and it allows users and tools easy access to that information just by referencing the binary. There is a follow up change to add an option to clang. Thanks. Reviewers: hfinkel, MatzeB Reviewed By: MatzeB Subscribers: thegameg, asb, llvm-commits Differential Revision: https://reviews.llvm.org/D39788 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@319430 91177308-0d34-0410-b5e6-96231b3b80d8 Sean Eveson 1 year, 9 months ago
9 changed file(s) with 95 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
15771577 important if you want to support direct .o file emission, or would like to
15781578 implement an assembler for your target.
15791579
1580 Emitting function stack size information
1581 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1582
1583 A section containing metadata on function stack sizes will be emitted when
1584 ``TargetLoweringObjectFile::StackSizesSection`` is not null, and
1585 ``TargetOptions::EmitStackSizeSection`` is set (-stack-size-section). The
1586 section will contain an array of pairs of function symbol references (8 byte)
1587 and stack sizes (unsigned LEB128). The stack size values only include the space
1588 allocated in the function prologue. Functions with dynamic stack allocations are
1589 not included.
1590
15801591 VLIW Packetizer
15811592 ---------------
15821593
131131 Specify which EABI version should conform to. Valid EABI versions are *gnu*,
132132 *4* and *5*. Default value (*default*) depends on the triple.
133133
134 .. option:: -stack-size-section
135
136 Emit the .stack_sizes section which contains stack size metadata. The section
137 contains an array of pairs of function symbol references (8 byte) and stack
138 sizes (unsigned LEB128). The stack size values only include the space allocated
139 in the function prologue. Functions with dynamic stack allocations are not
140 included.
141
134142
135143 Tuning/Configuration Options
136144 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
294294
295295 void emitFrameAlloc(const MachineInstr &MI);
296296
297 void emitStackSizeSection(const MachineFunction &MF);
298
297299 enum CFIMoveType { CFI_M_None, CFI_M_EH, CFI_M_Debug };
298300 CFIMoveType needsCFIMoves() const;
299301
253253 cl::values(clEnumValN(DebuggerKind::GDB, "gdb", "gdb"),
254254 clEnumValN(DebuggerKind::LLDB, "lldb", "lldb"),
255255 clEnumValN(DebuggerKind::SCE, "sce", "SCE targets (e.g. PS4)")));
256
257 static cl::opt EnableStackSizeSection(
258 "stack-size-section",
259 cl::desc("Emit a section containing stack size metadata"), cl::init(false));
256260
257261 // Common utility function tightly tied to the options listed here. Initializes
258262 // a TargetOptions object with CodeGen flags and returns it.
280284 Options.UniqueSectionNames = UniqueSectionNames;
281285 Options.EmulatedTLS = EmulatedTLS;
282286 Options.ExceptionModel = ExceptionModel;
287 Options.EmitStackSizeSection = EnableStackSizeSection;
283288
284289 Options.MCOptions = InitMCTargetOptionsFromFlags();
285290
153153 /// It is initialized on demand so it can be overwritten (with uniquing).
154154 MCSection *EHFrameSection;
155155
156 /// Section containing metadata on function stack sizes.
157 MCSection *StackSizesSection;
158
156159 // ELF specific sections.
157160 MCSection *DataRelROSection;
158161 MCSection *MergeableConst4Section;
286289 MCSection *getStackMapSection() const { return StackMapSection; }
287290 MCSection *getFaultMapSection() const { return FaultMapSection; }
288291
292 MCSection *getStackSizesSection() const { return StackSizesSection; }
293
289294 // ELF specific sections.
290295 MCSection *getDataRelROSection() const { return DataRelROSection; }
291296 const MCSection *getMergeableConst4Section() const {
107107 DisableIntegratedAS(false), RelaxELFRelocations(false),
108108 FunctionSections(false), DataSections(false),
109109 UniqueSectionNames(true), TrapUnreachable(false), EmulatedTLS(false),
110 EnableIPRA(false) {}
110 EnableIPRA(false), EmitStackSizeSection(false) {}
111111
112112 /// PrintMachineCode - This flag is enabled when the -print-machineinstrs
113113 /// option is specified on the command line, and should enable debugging
214214
215215 /// This flag enables InterProcedural Register Allocation (IPRA).
216216 unsigned EnableIPRA : 1;
217
218 /// Emit section containing metadata on function stack sizes.
219 unsigned EmitStackSizeSection : 1;
217220
218221 /// FloatABIType - This setting is set by -float-abi=xxx option is specfied
219222 /// on the command line. This setting may either be Default, Soft, or Hard.
963963 MCConstantExpr::create(FrameOffset, OutContext));
964964 }
965965
966 void AsmPrinter::emitStackSizeSection(const MachineFunction &MF) {
967 if (!MF.getTarget().Options.EmitStackSizeSection)
968 return;
969
970 MCSection *StackSizeSection = getObjFileLowering().getStackSizesSection();
971 if (!StackSizeSection)
972 return;
973
974 const MachineFrameInfo &FrameInfo = MF.getFrameInfo();
975 // Don't emit functions with dynamic stack allocations.
976 if (FrameInfo.hasVarSizedObjects())
977 return;
978
979 OutStreamer->PushSection();
980 OutStreamer->SwitchSection(StackSizeSection);
981
982 const MCSymbol *FunctionSymbol = getSymbol(MF.getFunction());
983 uint64_t StackSize = FrameInfo.getStackSize();
984 OutStreamer->EmitValue(MCSymbolRefExpr::create(FunctionSymbol, OutContext),
985 /* size = */ 8);
986 OutStreamer->EmitULEB128IntValue(StackSize);
987
988 OutStreamer->PopSection();
989 }
990
966991 static bool needFuncLabelsForEHOrDebugInfo(const MachineFunction &MF,
967992 MachineModuleInfo *MMI) {
968993 if (!MF.getLandingPads().empty() || MF.hasEHFunclets() || MMI->hasDebugInfo())
11341159 HI.Handler->endFunction(MF);
11351160 }
11361161
1162 // Emit section containing stack size metadata.
1163 emitStackSizeSection(*MF);
1164
11371165 if (isVerbose())
11381166 OutStreamer->GetCommentOS() << "-- End function\n";
11391167
593593
594594 EHFrameSection =
595595 Ctx->getELFSection(".eh_frame", EHSectionType, EHSectionFlags);
596
597 StackSizesSection = Ctx->getELFSection(".stack_sizes", ELF::SHT_PROGBITS, 0);
596598 }
597599
598600 void MCObjectFileInfo::initCOFFMCObjectFileInfo(const Triple &T) {
0 ; RUN: llc < %s -mtriple=x86_64-linux -stack-size-section | FileCheck %s
1
2 ; CHECK-LABEL: func1:
3 ; CHECK: .section .stack_sizes,"",@progbits
4 ; CHECK-NEXT: .quad func1
5 ; CHECK-NEXT: .byte 8
6 define void @func1(i32, i32) #0 {
7 alloca i32, align 4
8 alloca i32, align 4
9 ret void
10 }
11
12 ; CHECK-LABEL: func2:
13 ; CHECK: .section .stack_sizes,"",@progbits
14 ; CHECK-NEXT: .quad func2
15 ; CHECK-NEXT: .byte 24
16 define void @func2() #0 {
17 alloca i32, align 4
18 call void @func1(i32 1, i32 2)
19 ret void
20 }
21
22 ; CHECK-LABEL: dynalloc:
23 ; CHECK-NOT: .section .stack_sizes
24 define void @dynalloc(i32 %N) #0 {
25 alloca i32, i32 %N
26 ret void
27 }
28
29 attributes #0 = { "no-frame-pointer-elim"="true" }