Skip to content

Commit

Permalink
[MC] Function stack size section.
Browse files Browse the repository at this point in the history
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

llvm-svn: 319430
  • Loading branch information
SeanEveson committed Nov 30, 2017
1 parent 661e4fb commit a6bcd53
Show file tree
Hide file tree
Showing 9 changed files with 95 additions and 1 deletion.
11 changes: 11 additions & 0 deletions llvm/docs/CodeGenerator.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1578,6 +1578,17 @@ which lowers MCInst's into machine code bytes and relocations. This is
important if you want to support direct .o file emission, or would like to
implement an assembler for your target.

Emitting function stack size information
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

A section containing metadata on function stack sizes will be emitted when
``TargetLoweringObjectFile::StackSizesSection`` is not null, and
``TargetOptions::EmitStackSizeSection`` is set (-stack-size-section). The
section will contain an array of pairs of function symbol references (8 byte)
and stack sizes (unsigned LEB128). The stack size values only include the space
allocated in the function prologue. Functions with dynamic stack allocations are
not included.

VLIW Packetizer
---------------

Expand Down
8 changes: 8 additions & 0 deletions llvm/docs/CommandGuide/llc.rst
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,14 @@ End-user Options
Specify which EABI version should conform to. Valid EABI versions are *gnu*,
*4* and *5*. Default value (*default*) depends on the triple.

.. option:: -stack-size-section

Emit the .stack_sizes section which contains stack size metadata. The section
contains an array of pairs of function symbol references (8 byte) and stack
sizes (unsigned LEB128). The stack size values only include the space allocated
in the function prologue. Functions with dynamic stack allocations are not
included.


Tuning/Configuration Options
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand Down
2 changes: 2 additions & 0 deletions llvm/include/llvm/CodeGen/AsmPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,8 @@ class AsmPrinter : public MachineFunctionPass {

void emitFrameAlloc(const MachineInstr &MI);

void emitStackSizeSection(const MachineFunction &MF);

enum CFIMoveType { CFI_M_None, CFI_M_EH, CFI_M_Debug };
CFIMoveType needsCFIMoves() const;

Expand Down
5 changes: 5 additions & 0 deletions llvm/include/llvm/CodeGen/CommandFlags.def
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,10 @@ static cl::opt<DebuggerKind> DebuggerTuningOpt(
clEnumValN(DebuggerKind::LLDB, "lldb", "lldb"),
clEnumValN(DebuggerKind::SCE, "sce", "SCE targets (e.g. PS4)")));

static cl::opt<bool> EnableStackSizeSection(
"stack-size-section",
cl::desc("Emit a section containing stack size metadata"), cl::init(false));

// Common utility function tightly tied to the options listed here. Initializes
// a TargetOptions object with CodeGen flags and returns it.
static TargetOptions InitTargetOptionsFromCodeGenFlags() {
Expand All @@ -281,6 +285,7 @@ static TargetOptions InitTargetOptionsFromCodeGenFlags() {
Options.UniqueSectionNames = UniqueSectionNames;
Options.EmulatedTLS = EmulatedTLS;
Options.ExceptionModel = ExceptionModel;
Options.EmitStackSizeSection = EnableStackSizeSection;

Options.MCOptions = InitMCTargetOptionsFromFlags();

Expand Down
5 changes: 5 additions & 0 deletions llvm/include/llvm/MC/MCObjectFileInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,9 @@ class MCObjectFileInfo {
/// It is initialized on demand so it can be overwritten (with uniquing).
MCSection *EHFrameSection;

/// Section containing metadata on function stack sizes.
MCSection *StackSizesSection;

// ELF specific sections.
MCSection *DataRelROSection;
MCSection *MergeableConst4Section;
Expand Down Expand Up @@ -287,6 +290,8 @@ class MCObjectFileInfo {
MCSection *getStackMapSection() const { return StackMapSection; }
MCSection *getFaultMapSection() const { return FaultMapSection; }

MCSection *getStackSizesSection() const { return StackSizesSection; }

// ELF specific sections.
MCSection *getDataRelROSection() const { return DataRelROSection; }
const MCSection *getMergeableConst4Section() const {
Expand Down
5 changes: 4 additions & 1 deletion llvm/include/llvm/Target/TargetOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ namespace llvm {
DisableIntegratedAS(false), RelaxELFRelocations(false),
FunctionSections(false), DataSections(false),
UniqueSectionNames(true), TrapUnreachable(false), EmulatedTLS(false),
EnableIPRA(false) {}
EnableIPRA(false), EmitStackSizeSection(false) {}

/// PrintMachineCode - This flag is enabled when the -print-machineinstrs
/// option is specified on the command line, and should enable debugging
Expand Down Expand Up @@ -216,6 +216,9 @@ namespace llvm {
/// This flag enables InterProcedural Register Allocation (IPRA).
unsigned EnableIPRA : 1;

/// Emit section containing metadata on function stack sizes.
unsigned EmitStackSizeSection : 1;

/// FloatABIType - This setting is set by -float-abi=xxx option is specfied
/// on the command line. This setting may either be Default, Soft, or Hard.
/// Default selects the target's default behavior. Soft selects the ABI for
Expand Down
28 changes: 28 additions & 0 deletions llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -964,6 +964,31 @@ void AsmPrinter::emitFrameAlloc(const MachineInstr &MI) {
MCConstantExpr::create(FrameOffset, OutContext));
}

void AsmPrinter::emitStackSizeSection(const MachineFunction &MF) {
if (!MF.getTarget().Options.EmitStackSizeSection)
return;

MCSection *StackSizeSection = getObjFileLowering().getStackSizesSection();
if (!StackSizeSection)
return;

const MachineFrameInfo &FrameInfo = MF.getFrameInfo();
// Don't emit functions with dynamic stack allocations.
if (FrameInfo.hasVarSizedObjects())
return;

OutStreamer->PushSection();
OutStreamer->SwitchSection(StackSizeSection);

const MCSymbol *FunctionSymbol = getSymbol(MF.getFunction());
uint64_t StackSize = FrameInfo.getStackSize();
OutStreamer->EmitValue(MCSymbolRefExpr::create(FunctionSymbol, OutContext),
/* size = */ 8);
OutStreamer->EmitULEB128IntValue(StackSize);

OutStreamer->PopSection();
}

static bool needFuncLabelsForEHOrDebugInfo(const MachineFunction &MF,
MachineModuleInfo *MMI) {
if (!MF.getLandingPads().empty() || MF.hasEHFunclets() || MMI->hasDebugInfo())
Expand Down Expand Up @@ -1135,6 +1160,9 @@ void AsmPrinter::EmitFunctionBody() {
HI.Handler->endFunction(MF);
}

// Emit section containing stack size metadata.
emitStackSizeSection(*MF);

if (isVerbose())
OutStreamer->GetCommentOS() << "-- End function\n";

Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/MC/MCObjectFileInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,8 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T, bool Large) {

EHFrameSection =
Ctx->getELFSection(".eh_frame", EHSectionType, EHSectionFlags);

StackSizesSection = Ctx->getELFSection(".stack_sizes", ELF::SHT_PROGBITS, 0);
}

void MCObjectFileInfo::initCOFFMCObjectFileInfo(const Triple &T) {
Expand Down
30 changes: 30 additions & 0 deletions llvm/test/CodeGen/X86/stack-size-section.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
; RUN: llc < %s -mtriple=x86_64-linux -stack-size-section | FileCheck %s

; CHECK-LABEL: func1:
; CHECK: .section .stack_sizes,"",@progbits
; CHECK-NEXT: .quad func1
; CHECK-NEXT: .byte 8
define void @func1(i32, i32) #0 {
alloca i32, align 4
alloca i32, align 4
ret void
}

; CHECK-LABEL: func2:
; CHECK: .section .stack_sizes,"",@progbits
; CHECK-NEXT: .quad func2
; CHECK-NEXT: .byte 24
define void @func2() #0 {
alloca i32, align 4
call void @func1(i32 1, i32 2)
ret void
}

; CHECK-LABEL: dynalloc:
; CHECK-NOT: .section .stack_sizes
define void @dynalloc(i32 %N) #0 {
alloca i32, i32 %N
ret void
}

attributes #0 = { "no-frame-pointer-elim"="true" }

0 comments on commit a6bcd53

Please sign in to comment.