summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/docs/CodeGenerator.rst11
-rw-r--r--llvm/docs/CommandGuide/llc.rst8
-rw-r--r--llvm/include/llvm/CodeGen/AsmPrinter.h2
-rw-r--r--llvm/include/llvm/CodeGen/CommandFlags.def5
-rw-r--r--llvm/include/llvm/MC/MCObjectFileInfo.h5
-rw-r--r--llvm/include/llvm/Target/TargetOptions.h5
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp28
-rw-r--r--llvm/lib/MC/MCObjectFileInfo.cpp2
-rw-r--r--llvm/test/CodeGen/X86/stack-size-section.ll30
9 files changed, 95 insertions, 1 deletions
diff --git a/llvm/docs/CodeGenerator.rst b/llvm/docs/CodeGenerator.rst
index bcdc7228356..5c0fb064959 100644
--- a/llvm/docs/CodeGenerator.rst
+++ b/llvm/docs/CodeGenerator.rst
@@ -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
---------------
diff --git a/llvm/docs/CommandGuide/llc.rst b/llvm/docs/CommandGuide/llc.rst
index 5094259f9f9..95945e68d13 100644
--- a/llvm/docs/CommandGuide/llc.rst
+++ b/llvm/docs/CommandGuide/llc.rst
@@ -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
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h
index 1d65f703b84..b8944a66800 100644
--- a/llvm/include/llvm/CodeGen/AsmPrinter.h
+++ b/llvm/include/llvm/CodeGen/AsmPrinter.h
@@ -295,6 +295,8 @@ public:
void emitFrameAlloc(const MachineInstr &MI);
+ void emitStackSizeSection(const MachineFunction &MF);
+
enum CFIMoveType { CFI_M_None, CFI_M_EH, CFI_M_Debug };
CFIMoveType needsCFIMoves() const;
diff --git a/llvm/include/llvm/CodeGen/CommandFlags.def b/llvm/include/llvm/CodeGen/CommandFlags.def
index 83cbeb0341f..fe96033a9c6 100644
--- a/llvm/include/llvm/CodeGen/CommandFlags.def
+++ b/llvm/include/llvm/CodeGen/CommandFlags.def
@@ -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() {
@@ -281,6 +285,7 @@ static TargetOptions InitTargetOptionsFromCodeGenFlags() {
Options.UniqueSectionNames = UniqueSectionNames;
Options.EmulatedTLS = EmulatedTLS;
Options.ExceptionModel = ExceptionModel;
+ Options.EmitStackSizeSection = EnableStackSizeSection;
Options.MCOptions = InitMCTargetOptionsFromFlags();
diff --git a/llvm/include/llvm/MC/MCObjectFileInfo.h b/llvm/include/llvm/MC/MCObjectFileInfo.h
index d95f84d1d81..c0b1443591c 100644
--- a/llvm/include/llvm/MC/MCObjectFileInfo.h
+++ b/llvm/include/llvm/MC/MCObjectFileInfo.h
@@ -154,6 +154,9 @@ protected:
/// 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;
@@ -287,6 +290,8 @@ public:
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 {
diff --git a/llvm/include/llvm/Target/TargetOptions.h b/llvm/include/llvm/Target/TargetOptions.h
index 5c2063880f8..70fac7833f3 100644
--- a/llvm/include/llvm/Target/TargetOptions.h
+++ b/llvm/include/llvm/Target/TargetOptions.h
@@ -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
@@ -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
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index c9b0f9aa556..2d82f81ed70 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -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())
@@ -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";
diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp
index d8077df1469..ba0146fd9fc 100644
--- a/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -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) {
diff --git a/llvm/test/CodeGen/X86/stack-size-section.ll b/llvm/test/CodeGen/X86/stack-size-section.ll
new file mode 100644
index 00000000000..28b26ae572e
--- /dev/null
+++ b/llvm/test/CodeGen/X86/stack-size-section.ll
@@ -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" }
OpenPOWER on IntegriCloud