https://github.com/citymarina created https://github.com/llvm/llvm-project/pull/178005
This change plumbs the stack usage filename from the various CLI entry points down to `TargetOptions::StackUsageOutput`, ultimately for use by `AsmPrinter::emitStackUsage`. rdar://143089305 >From 7b2be0234d4364c1046342e999d07dae36c029eb Mon Sep 17 00:00:00 2001 From: Marina Taylor <[email protected]> Date: Mon, 26 Jan 2026 16:51:46 +0000 Subject: [PATCH] [LTO] Make stack usage files work with LTO This change plumbs the stack usage filename from the various CLI entry points down to `TargetOptions::StackUsageOutput`, ultimately for use by `AsmPrinter::emitStackUsage`. rdar://143089305 --- clang/lib/CodeGen/BackendUtil.cpp | 1 + clang/lib/Driver/ToolChains/Darwin.cpp | 9 +++++++++ clang/test/Driver/stack-usage.c | 6 ++++++ lld/COFF/Config.h | 3 +++ lld/COFF/Driver.cpp | 1 + lld/COFF/LTO.cpp | 1 + lld/COFF/Options.td | 3 +++ lld/ELF/Config.h | 1 + lld/ELF/Driver.cpp | 1 + lld/ELF/LTO.cpp | 3 +++ lld/ELF/Options.td | 2 ++ lld/MachO/Config.h | 1 + lld/MachO/Driver.cpp | 1 + lld/MachO/LTO.cpp | 1 + lld/MachO/Options.td | 4 ++++ lld/test/COFF/lto-stack-usage-file.ll | 15 +++++++++++++++ lld/test/ELF/lto/stack-usage-file.ll | 15 +++++++++++++++ lld/test/MachO/lto-stack-usage.ll | 16 ++++++++++++++++ lld/test/wasm/lto/stack-usage-file.ll | 13 +++++++++++++ lld/wasm/Config.h | 1 + lld/wasm/Driver.cpp | 1 + lld/wasm/LTO.cpp | 1 + lld/wasm/Options.td | 2 ++ llvm/include/llvm/LTO/Config.h | 3 +++ llvm/lib/LTO/LTOBackend.cpp | 3 +++ llvm/lib/LTO/LTOCodeGenerator.cpp | 6 ++++++ llvm/lib/LTO/ThinLTOCodeGenerator.cpp | 5 +++++ .../tools/llvm-lto2/X86/stack-usage-output.ll | 15 +++++++++++++++ llvm/tools/llvm-lto2/llvm-lto2.cpp | 5 +++++ 29 files changed, 139 insertions(+) create mode 100644 lld/test/COFF/lto-stack-usage-file.ll create mode 100644 lld/test/ELF/lto/stack-usage-file.ll create mode 100644 lld/test/MachO/lto-stack-usage.ll create mode 100644 lld/test/wasm/lto/stack-usage-file.ll create mode 100644 llvm/test/tools/llvm-lto2/X86/stack-usage-output.ll diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index d411ef1bf8763..9c8c0b35ca9a0 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -1383,6 +1383,7 @@ runThinLTOBackend(CompilerInstance &CI, ModuleSummaryIndex *CombinedIndex, Conf.RemarksFormat = CGOpts.OptRecordFormat; Conf.SplitDwarfFile = CGOpts.SplitDwarfFile; Conf.SplitDwarfOutput = CGOpts.SplitDwarfOutput; + Conf.StackUsageOutput = CGOpts.StackUsageOutput; switch (Action) { case Backend_EmitNothing: Conf.PreCodeGenModuleHook = [](size_t Task, const llvm::Module &Mod) { diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp index fb75739360328..2bbd4bbebe661 100644 --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -660,6 +660,15 @@ void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(Args.MakeArgString("-lto-stats-file=" + StatsFile.str())); } + // Set up stack usage output file for LTO. + if (Args.hasArg(options::OPT_fstack_usage)) { + SmallString<128> StackUsageFile(Output.getFilename()); + llvm::sys::path::replace_extension(StackUsageFile, "su"); + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back( + Args.MakeArgString("-lto-stack-usage-output=" + StackUsageFile)); + } + // It seems that the 'e' option is completely ignored for dynamic executables // (the default), and with static executables, the last one wins, as expected. Args.addAllArgs(CmdArgs, {options::OPT_d_Flag, options::OPT_s, options::OPT_t, diff --git a/clang/test/Driver/stack-usage.c b/clang/test/Driver/stack-usage.c index 7256707040f9c..68e5b4c4fe2c2 100644 --- a/clang/test/Driver/stack-usage.c +++ b/clang/test/Driver/stack-usage.c @@ -4,4 +4,10 @@ // RUN: %clang -target aarch64-unknown -fstack-usage %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-PRESENT // CHECK-PRESENT: "-stack-usage-file" +// RUN: %clang --target=arm64-apple-darwin -fstack-usage -flto %s -### -o foo 2>&1 | FileCheck %s --check-prefix=DARWIN-LTO +// DARWIN-LTO: "-mllvm" "-lto-stack-usage-output=foo.su" + +// RUN: %clang --target=arm64-apple-darwin -flto %s -### -o foo 2>&1 | FileCheck %s --check-prefix=DARWIN-LTO-ABSENT +// DARWIN-LTO-ABSENT-NOT: "-lto-stack-usage-output" + int foo() { return 42; } diff --git a/lld/COFF/Config.h b/lld/COFF/Config.h index 2ee60aca116d6..92d611a381392 100644 --- a/lld/COFF/Config.h +++ b/lld/COFF/Config.h @@ -272,6 +272,9 @@ struct Configuration { // Used for /lto-obj-path: llvm::StringRef ltoObjPath; + // Used for /lto-stack-usage-file: + llvm::StringRef ltoStackUsageFile; + // Used for /lto-cs-profile-generate: bool ltoCSProfileGenerate = false; diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp index b1337ea8157ab..cb5a8c4de6aa2 100644 --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -2209,6 +2209,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) { config->thinLTOObjectSuffixReplace = getOldNewOptions(ctx, args, OPT_thinlto_object_suffix_replace); config->ltoObjPath = args.getLastArgValue(OPT_lto_obj_path); + config->ltoStackUsageFile = args.getLastArgValue(OPT_lto_stack_usage_file); config->ltoCSProfileGenerate = args.hasArg(OPT_lto_cs_profile_generate); config->ltoCSProfileFile = args.getLastArgValue(OPT_lto_cs_profile_file); config->ltoSampleProfileName = args.getLastArgValue(OPT_lto_sample_profile); diff --git a/lld/COFF/LTO.cpp b/lld/COFF/LTO.cpp index e621bb263d2c9..6b5edc1e77d80 100644 --- a/lld/COFF/LTO.cpp +++ b/lld/COFF/LTO.cpp @@ -83,6 +83,7 @@ lto::Config BitcodeCompiler::createConfig() { c.RunCSIRInstr = ctx.config.ltoCSProfileGenerate; c.PGOWarnMismatch = ctx.config.ltoPGOWarnMismatch; c.SampleProfile = ctx.config.ltoSampleProfileName; + c.StackUsageOutput = std::string(ctx.config.ltoStackUsageFile); c.TimeTraceEnabled = ctx.config.timeTraceEnabled; c.TimeTraceGranularity = ctx.config.timeTraceGranularity; diff --git a/lld/COFF/Options.td b/lld/COFF/Options.td index fb762b880c2cb..b21cba85573b1 100644 --- a/lld/COFF/Options.td +++ b/lld/COFF/Options.td @@ -308,6 +308,9 @@ defm fat_lto_objects: B<"fat-lto-objects", def lto_obj_path : P< "lto-obj-path", "output native object for merged LTO unit to this path">; +def lto_stack_usage_file : P< + "lto-stack-usage-file", + "output stack usage information for LTO">; def lto_cs_profile_generate: F<"lto-cs-profile-generate">, HelpText<"Perform context sensitive PGO instrumentation">; def lto_cs_profile_file : P<"lto-cs-profile-file", diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h index 8ec5a2c04e71c..11092d87db667 100644 --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -234,6 +234,7 @@ struct Config { llvm::StringRef ltoNewPmPasses; llvm::StringRef ltoObjPath; llvm::StringRef ltoSampleProfile; + llvm::StringRef ltoStackUsageFile; llvm::StringRef mapFile; llvm::StringRef outputFile; llvm::StringRef optRemarksFilename; diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index 8647752be31fe..ebf1757eb5620 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -1469,6 +1469,7 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) { ctx.arg.ltoObjPath = args.getLastArgValue(OPT_lto_obj_path_eq); ctx.arg.ltoPartitions = args::getInteger(args, OPT_lto_partitions, 1); ctx.arg.ltoSampleProfile = args.getLastArgValue(OPT_lto_sample_profile); + ctx.arg.ltoStackUsageFile = args.getLastArgValue(OPT_lto_stack_usage_file); ctx.arg.ltoBBAddrMap = args.hasFlag(OPT_lto_basic_block_address_map, OPT_no_lto_basic_block_address_map, false); diff --git a/lld/ELF/LTO.cpp b/lld/ELF/LTO.cpp index 44a679498ed1d..2f61b92e6696f 100644 --- a/lld/ELF/LTO.cpp +++ b/lld/ELF/LTO.cpp @@ -122,6 +122,9 @@ static lto::Config createConfig(Ctx &ctx) { // Set up output file to emit statistics. c.StatsFile = std::string(ctx.arg.optStatsFilename); + // Set up output file for stack usage. + c.StackUsageOutput = std::string(ctx.arg.ltoStackUsageFile); + c.SampleProfile = std::string(ctx.arg.ltoSampleProfile); for (StringRef pluginFn : ctx.arg.passPlugins) c.PassPlugins.push_back(std::string(pluginFn)); diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td index c2111e58c12b9..c7c0615bac19e 100644 --- a/lld/ELF/Options.td +++ b/lld/ELF/Options.td @@ -689,6 +689,8 @@ def opt_remarks_with_hotness: FF<"opt-remarks-with-hotness">, HelpText<"Include hotness information in the optimization remarks file">; def opt_remarks_format: Separate<["--"], "opt-remarks-format">, HelpText<"The format used for serializing remarks (default: YAML)">; +def lto_stack_usage_file: JJ<"lto-stack-usage-file=">, + HelpText<"Stack usage output file path for LTO">; def save_temps: F<"save-temps">, HelpText<"Save intermediate LTO compilation results">; def save_temps_eq: JJ<"save-temps=">, HelpText<"Save select intermediate LTO compilation results">, Values<"resolution,preopt,promote,internalize,import,opt,precodegen,prelink,combinedindex">; diff --git a/lld/MachO/Config.h b/lld/MachO/Config.h index 814ba1016849f..cfda2c628549e 100644 --- a/lld/MachO/Config.h +++ b/lld/MachO/Config.h @@ -169,6 +169,7 @@ struct Configuration { llvm::StringRef mapFile; llvm::StringRef ltoNewPmPasses; llvm::StringRef ltoObjPath; + llvm::StringRef ltoStackUsageFile; llvm::StringRef thinLTOJobs; llvm::StringRef umbrella; uint32_t ltoo = 2; diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp index 973b3f5535cb4..f93243dc4af91 100644 --- a/lld/MachO/Driver.cpp +++ b/lld/MachO/Driver.cpp @@ -1929,6 +1929,7 @@ bool link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS, config->umbrella = arg->getValue(); } config->ltoObjPath = args.getLastArgValue(OPT_object_path_lto); + config->ltoStackUsageFile = args.getLastArgValue(OPT_stack_usage_lto); config->ltoNewPmPasses = args.getLastArgValue(OPT_lto_newpm_passes); config->thinLTOCacheDir = args.getLastArgValue(OPT_cache_path_lto); config->thinLTOCachePolicy = getLTOCachePolicy(args); diff --git a/lld/MachO/LTO.cpp b/lld/MachO/LTO.cpp index 2c360374ef3cc..22835a2fd8ea9 100644 --- a/lld/MachO/LTO.cpp +++ b/lld/MachO/LTO.cpp @@ -61,6 +61,7 @@ static lto::Config createConfig() { c.DisableVerify = config->disableVerify; c.OptLevel = config->ltoo; c.CGOptLevel = config->ltoCgo; + c.StackUsageOutput = std::string(config->ltoStackUsageFile); if (config->saveTemps) checkError(c.addSaveTemps(config->outputFile.str() + ".", /*UseInputModulePath=*/true)); diff --git a/lld/MachO/Options.td b/lld/MachO/Options.td index 5bd220b3c196a..8e409aca98db6 100644 --- a/lld/MachO/Options.td +++ b/lld/MachO/Options.td @@ -1040,6 +1040,10 @@ def object_path_lto : Separate<["-"], "object_path_lto">, MetaVarName<"<path>">, HelpText<"Retain any temporary mach-o file in <path> that would otherwise be deleted during LTO">, Group<grp_rare>; +def stack_usage_lto : Separate<["-"], "stack_usage_lto">, + MetaVarName<"<path>">, + HelpText<"Write stack usage information for LTO to <path>">, + Group<grp_rare>; def cache_path_lto : Separate<["-"], "cache_path_lto">, MetaVarName<"<path>">, HelpText<"Use <path> as a directory for the incremental LTO cache">, diff --git a/lld/test/COFF/lto-stack-usage-file.ll b/lld/test/COFF/lto-stack-usage-file.ll new file mode 100644 index 0000000000000..b9986c5b035c3 --- /dev/null +++ b/lld/test/COFF/lto-stack-usage-file.ll @@ -0,0 +1,15 @@ +; REQUIRES: x86 + +; RUN: llvm-as %s -o %t.obj +; RUN: lld-link /subsystem:console /entry:f /out:%t.exe /lto-stack-usage-file:%t.su %t.obj +; RUN: FileCheck --input-file=%t.su %s + +target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-windows-msvc19.0.24215" + +define void @f() { + %a = alloca [64 x i8] + ret void +} + +; CHECK: f {{[0-9]+}} static diff --git a/lld/test/ELF/lto/stack-usage-file.ll b/lld/test/ELF/lto/stack-usage-file.ll new file mode 100644 index 0000000000000..ac4e38900caa7 --- /dev/null +++ b/lld/test/ELF/lto/stack-usage-file.ll @@ -0,0 +1,15 @@ +; REQUIRES: x86 + +; RUN: llvm-as -o %t.bc %s +; RUN: ld.lld --lto-stack-usage-file=%t.su -m elf_x86_64 -r -o %t.o %t.bc +; RUN: FileCheck --input-file=%t.su %s + +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define void @f() { + %a = alloca [64 x i8] + ret void +} + +; CHECK: f {{[0-9]+}} static diff --git a/lld/test/MachO/lto-stack-usage.ll b/lld/test/MachO/lto-stack-usage.ll new file mode 100644 index 0000000000000..1a9d55e78e58f --- /dev/null +++ b/lld/test/MachO/lto-stack-usage.ll @@ -0,0 +1,16 @@ +; REQUIRES: x86 + +; RUN: rm -rf %t; mkdir %t +; RUN: llvm-as %s -o %t/test.o +; RUN: %lld %t/test.o -o %t/test -stack_usage_lto %t/test.su +; RUN: FileCheck --input-file=%t/test.su %s + +target triple = "x86_64-apple-macosx10.15.0" +target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + +define void @main() { + %a = alloca [64 x i8] + ret void +} + +; CHECK: main {{[0-9]+}} static diff --git a/lld/test/wasm/lto/stack-usage-file.ll b/lld/test/wasm/lto/stack-usage-file.ll new file mode 100644 index 0000000000000..4ee85edbc7189 --- /dev/null +++ b/lld/test/wasm/lto/stack-usage-file.ll @@ -0,0 +1,13 @@ +; RUN: llvm-as %s -o %t.o +; RUN: wasm-ld --entry f %t.o -o %t.wasm --lto-stack-usage-file=%t.su +; RUN: FileCheck --input-file=%t.su %s + +target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20" +target triple = "wasm32-unknown-unknown" + +define void @f() { + %a = alloca [64 x i8] + ret void +} + +; CHECK: f {{[0-9]+}} static diff --git a/lld/wasm/Config.h b/lld/wasm/Config.h index 9d903e0c799db..8d69a04e657c2 100644 --- a/lld/wasm/Config.h +++ b/lld/wasm/Config.h @@ -110,6 +110,7 @@ struct Config { llvm::StringRef entry; llvm::StringRef ltoObjPath; + llvm::StringRef ltoStackUsageFile; llvm::StringRef mapFile; llvm::StringRef outputFile; llvm::StringRef soName; diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp index d18126bef766f..5c6cc7a717d8f 100644 --- a/lld/wasm/Driver.cpp +++ b/lld/wasm/Driver.cpp @@ -573,6 +573,7 @@ static void readConfigs(opt::InputArgList &args) { error("invalid codegen optimization level for LTO: " + Twine(ltoCgo)); ctx.arg.ltoPartitions = args::getInteger(args, OPT_lto_partitions, 1); ctx.arg.ltoObjPath = args.getLastArgValue(OPT_lto_obj_path_eq); + ctx.arg.ltoStackUsageFile = args.getLastArgValue(OPT_lto_stack_usage_file_eq); ctx.arg.ltoDebugPassManager = args.hasArg(OPT_lto_debug_pass_manager); ctx.arg.mapFile = args.getLastArgValue(OPT_Map); ctx.arg.optimize = args::getInteger(args, OPT_O, 1); diff --git a/lld/wasm/LTO.cpp b/lld/wasm/LTO.cpp index 668cdf21ea3ed..020828010e6c4 100644 --- a/lld/wasm/LTO.cpp +++ b/lld/wasm/LTO.cpp @@ -56,6 +56,7 @@ static lto::Config createConfig() { c.CGOptLevel = ctx.arg.ltoCgo; c.DebugPassManager = ctx.arg.ltoDebugPassManager; c.AlwaysEmitRegularLTOObj = !ctx.arg.ltoObjPath.empty(); + c.StackUsageOutput = std::string(ctx.arg.ltoStackUsageFile); if (auto relocModel = getRelocModelFromCMModel()) c.RelocModel = *relocModel; diff --git a/lld/wasm/Options.td b/lld/wasm/Options.td index 33ecf03176d36..022d629cdfd55 100644 --- a/lld/wasm/Options.td +++ b/lld/wasm/Options.td @@ -304,6 +304,8 @@ def lto_CGO: JJ<"lto-CGO">, MetaVarName<"<cgopt-level>">, def lto_partitions: JJ<"lto-partitions=">, HelpText<"Number of LTO codegen partitions">; def lto_obj_path_eq: JJ<"lto-obj-path=">; +def lto_stack_usage_file_eq: JJ<"lto-stack-usage-file=">, + HelpText<"Stack usage output file path for LTO">; def disable_verify: F<"disable-verify">; def save_temps: F<"save-temps">, HelpText<"Save intermediate LTO compilation results">; def thinlto_cache_dir: JJ<"thinlto-cache-dir=">, diff --git a/llvm/include/llvm/LTO/Config.h b/llvm/include/llvm/LTO/Config.h index 566a87ed1a790..3417516db2464 100644 --- a/llvm/include/llvm/LTO/Config.h +++ b/llvm/include/llvm/LTO/Config.h @@ -179,6 +179,9 @@ struct Config { /// Statistics output file path. std::string StatsFile; + /// Stack usage output file path. + std::string StackUsageOutput; + /// Specific thinLTO modules to compile. std::vector<std::string> ThinLTOModulesToCompile; diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp index 43e5c3b398372..4851d5742a53b 100644 --- a/llvm/lib/LTO/LTOBackend.cpp +++ b/llvm/lib/LTO/LTOBackend.cpp @@ -448,6 +448,9 @@ static void codegen(const Config &Conf, TargetMachine *TM, EC.message()); } + if (!Conf.StackUsageOutput.empty()) + TM->Options.StackUsageOutput = Conf.StackUsageOutput; + Expected<std::unique_ptr<CachedFileStream>> StreamOrErr = AddStream(Task, Mod.getModuleIdentifier()); if (Error Err = StreamOrErr.takeError()) diff --git a/llvm/lib/LTO/LTOCodeGenerator.cpp b/llvm/lib/LTO/LTOCodeGenerator.cpp index 46be71da5a092..799454cdb362e 100644 --- a/llvm/lib/LTO/LTOCodeGenerator.cpp +++ b/llvm/lib/LTO/LTOCodeGenerator.cpp @@ -106,6 +106,11 @@ static cl::opt<std::string> LTOStatsFile("lto-stats-file", cl::desc("Save statistics to the specified file"), cl::Hidden); +cl::opt<std::string> + LTOStackUsageOutput("lto-stack-usage-output", + cl::desc("Output filename for stack usage information"), + cl::value_desc("filename"), cl::Hidden); + static cl::opt<std::string> AIXSystemAssemblerPath( "lto-aix-system-assembler", cl::desc("Path to a system assembler, picked up on AIX only"), @@ -638,6 +643,7 @@ bool LTOCodeGenerator::compileOptimized(AddStreamFn AddStream, ModuleSummaryIndex CombinedIndex(false); Config.CodeGenOnly = true; + Config.StackUsageOutput = LTOStackUsageOutput; Error Err = backend(Config, AddStream, ParallelismLevel, *MergedModule, CombinedIndex); assert(!Err && "unexpected code-generation failure"); diff --git a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp index 961dd0ee43370..fe5792131b104 100644 --- a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp +++ b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp @@ -79,6 +79,7 @@ extern cl::opt<bool> RemarksWithHotness; extern cl::opt<std::optional<uint64_t>, false, remarks::HotnessThresholdParser> RemarksHotnessThreshold; extern cl::opt<std::string> RemarksFormat; +extern cl::opt<std::string> LTOStackUsageOutput; } // Default to using all available threads in the system, but using only one @@ -960,6 +961,10 @@ void ThinLTOCodeGenerator::run() { if (llvm::timeTraceProfilerEnabled()) llvm::timeTraceProfilerEnd(); }); + + if (!LTOStackUsageOutput.empty()) + TMBuilder.Options.StackUsageOutput = LTOStackUsageOutput; + // Prepare the resulting object vector assert(ProducedBinaries.empty() && "The generator should not be reused"); if (SavedObjectsDirectoryPath.empty()) diff --git a/llvm/test/tools/llvm-lto2/X86/stack-usage-output.ll b/llvm/test/tools/llvm-lto2/X86/stack-usage-output.ll new file mode 100644 index 0000000000000..8e9f77534b41f --- /dev/null +++ b/llvm/test/tools/llvm-lto2/X86/stack-usage-output.ll @@ -0,0 +1,15 @@ +; REQUIRES: x86-registered-target + +; RUN: llvm-as < %s > %t1.bc +; RUN: llvm-lto2 run %t1.bc -o %t.o -r %t1.bc,f,px -lto-stack-usage-output=%t.su +; RUN: FileCheck --input-file=%t.su %s + +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define void @f() { + %a = alloca [64 x i8] + ret void +} + +; CHECK: f {{[0-9]+}} static diff --git a/llvm/tools/llvm-lto2/llvm-lto2.cpp b/llvm/tools/llvm-lto2/llvm-lto2.cpp index 955c1130e9f4c..1c33d1021c3c4 100644 --- a/llvm/tools/llvm-lto2/llvm-lto2.cpp +++ b/llvm/tools/llvm-lto2/llvm-lto2.cpp @@ -202,6 +202,10 @@ static cl::opt<bool> static cl::opt<std::string> StatsFile("stats-file", cl::desc("Filename to write statistics to")); +static cl::opt<std::string> + StackUsageOutputFilename("lto-stack-usage-output", + cl::desc("Filename to write stack usage info to")); + static cl::list<std::string> PassPlugins("load-pass-plugin", cl::desc("Load passes from plugin library")); @@ -390,6 +394,7 @@ static int run(int argc, char **argv) { Conf.OverrideTriple = OverrideTriple; Conf.DefaultTriple = DefaultTriple; Conf.StatsFile = StatsFile; + Conf.StackUsageOutput = StackUsageOutputFilename; Conf.PTO.LoopVectorization = Conf.OptLevel > 1; Conf.PTO.SLPVectorization = Conf.OptLevel > 1; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
