From 2b896c80ef22552f5062a57fcd4d798da9ec41f9 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Fri, 28 Apr 2023 14:56:44 +0900 Subject: [PATCH] wamrc: Add --stack-usage option (#2158) --- core/iwasm/compilation/aot_llvm.c | 6 +- core/iwasm/compilation/aot_llvm.h | 1 + core/iwasm/compilation/aot_llvm_extra2.cpp | 108 +++++++++++++++++++++ core/iwasm/compilation/aot_llvm_extra2.h | 17 ++++ core/iwasm/include/aot_export.h | 1 + wamr-compiler/main.c | 5 + 6 files changed, 136 insertions(+), 2 deletions(-) create mode 100644 core/iwasm/compilation/aot_llvm_extra2.cpp create mode 100644 core/iwasm/compilation/aot_llvm_extra2.h diff --git a/core/iwasm/compilation/aot_llvm.c b/core/iwasm/compilation/aot_llvm.c index 27550560f..dc3fe7f59 100644 --- a/core/iwasm/compilation/aot_llvm.c +++ b/core/iwasm/compilation/aot_llvm.c @@ -4,6 +4,7 @@ */ #include "aot_llvm.h" +#include "aot_llvm_extra2.h" #include "aot_compiler.h" #include "aot_emit_exception.h" #include "../aot/aot_runtime.h" @@ -2055,9 +2056,10 @@ aot_create_comp_context(AOTCompData *comp_data, aot_comp_option_t option) code_model = LLVMCodeModelSmall; /* Create the target machine */ - if (!(comp_ctx->target_machine = LLVMCreateTargetMachine( + if (!(comp_ctx->target_machine = LLVMCreateTargetMachineWithOpts( target, triple_norm, cpu, features, opt_level, - LLVMRelocStatic, code_model))) { + LLVMRelocStatic, code_model, false, + option->stack_usage_file))) { aot_set_last_error("create LLVM target machine failed."); goto fail; } diff --git a/core/iwasm/compilation/aot_llvm.h b/core/iwasm/compilation/aot_llvm.h index b982e8083..2a1564019 100644 --- a/core/iwasm/compilation/aot_llvm.h +++ b/core/iwasm/compilation/aot_llvm.h @@ -415,6 +415,7 @@ typedef struct AOTCompOption { uint32 stack_bounds_checks; char **custom_sections; uint32 custom_sections_count; + const char *stack_usage_file; } AOTCompOption, *aot_comp_option_t; bool diff --git a/core/iwasm/compilation/aot_llvm_extra2.cpp b/core/iwasm/compilation/aot_llvm_extra2.cpp new file mode 100644 index 000000000..9bd44bbff --- /dev/null +++ b/core/iwasm/compilation/aot_llvm_extra2.cpp @@ -0,0 +1,108 @@ +/* + * Copyright (c)2023 YAMAMOTO Takashi. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include +#include +#include + +#include "bh_assert.h" + +#include "aot_llvm_extra2.h" + +static llvm::Optional +convert(LLVMRelocMode reloc_mode) +{ + switch (reloc_mode) { + case LLVMRelocDefault: + return llvm::None; + case LLVMRelocStatic: + return llvm::Reloc::Static; + case LLVMRelocPIC: + return llvm::Reloc::PIC_; + case LLVMRelocDynamicNoPic: + return llvm::Reloc::DynamicNoPIC; + case LLVMRelocROPI: + return llvm::Reloc::ROPI; + case LLVMRelocRWPI: + return llvm::Reloc::RWPI; + case LLVMRelocROPI_RWPI: + return llvm::Reloc::ROPI_RWPI; + } + bh_assert(0); + return llvm::None; +} + +static llvm::CodeGenOpt::Level +convert(LLVMCodeGenOptLevel opt_level) +{ + switch (opt_level) { + case LLVMCodeGenLevelNone: + return llvm::CodeGenOpt::None; + case LLVMCodeGenLevelLess: + return llvm::CodeGenOpt::Less; + case LLVMCodeGenLevelDefault: + return llvm::CodeGenOpt::Default; + case LLVMCodeGenLevelAggressive: + return llvm::CodeGenOpt::Aggressive; + } + bh_assert(0); + return llvm::CodeGenOpt::None; +} + +static llvm::Optional +convert(LLVMCodeModel code_model, bool *jit) +{ + *jit = false; + switch (code_model) { + case LLVMCodeModelDefault: + return llvm::None; + case LLVMCodeModelJITDefault: + *jit = true; + return llvm::None; + case LLVMCodeModelTiny: + return llvm::CodeModel::Tiny; + case LLVMCodeModelSmall: + return llvm::CodeModel::Small; + case LLVMCodeModelKernel: + return llvm::CodeModel::Kernel; + case LLVMCodeModelMedium: + return llvm::CodeModel::Medium; + case LLVMCodeModelLarge: + return llvm::CodeModel::Large; + } + bh_assert(0); + return llvm::None; +} + +LLVMTargetMachineRef +LLVMCreateTargetMachineWithOpts(LLVMTargetRef ctarget, const char *triple, + const char *cpu, const char *features, + LLVMCodeGenOptLevel opt_level, + LLVMRelocMode reloc_mode, + LLVMCodeModel code_model, + bool EmitStackSizeSection, + const char *StackUsageOutput) +{ + llvm::TargetOptions opts; + + // -fstack-size-section equiv + // emit it to ".stack_sizes" section in case of ELF + // you can read it with "llvm-readobj --stack-sizes" + opts.EmitStackSizeSection = EmitStackSizeSection; + + // -fstack-usage equiv + if (StackUsageOutput != NULL) { + opts.StackUsageOutput = StackUsageOutput; + } + + auto target = reinterpret_cast(ctarget); + auto rm = convert(reloc_mode); + auto ol = convert(opt_level); + bool jit; + auto cm = convert(code_model, &jit); + auto targetmachine = target->createTargetMachine(triple, cpu, features, + opts, rm, cm, ol, jit); + return reinterpret_cast(targetmachine); +} diff --git a/core/iwasm/compilation/aot_llvm_extra2.h b/core/iwasm/compilation/aot_llvm_extra2.h new file mode 100644 index 000000000..ef99622a4 --- /dev/null +++ b/core/iwasm/compilation/aot_llvm_extra2.h @@ -0,0 +1,17 @@ +/* + * Copyright (c)2023 YAMAMOTO Takashi. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include + +LLVM_C_EXTERN_C_BEGIN +LLVMTargetMachineRef +LLVMCreateTargetMachineWithOpts(LLVMTargetRef ctarget, const char *triple, + const char *cpu, const char *features, + LLVMCodeGenOptLevel opt_level, + LLVMRelocMode reloc_mode, + LLVMCodeModel code_model, + bool EmitStackSizeSection, + const char *StackUsageOutput); +LLVM_C_EXTERN_C_END diff --git a/core/iwasm/include/aot_export.h b/core/iwasm/include/aot_export.h index 792a4baa9..e58873bfd 100644 --- a/core/iwasm/include/aot_export.h +++ b/core/iwasm/include/aot_export.h @@ -63,6 +63,7 @@ typedef struct AOTCompOption { uint32_t stack_bounds_checks; char **custom_sections; uint32_t custom_sections_count; + const char *stack_usage_file; } AOTCompOption, *aot_comp_option_t; bool diff --git a/wamr-compiler/main.c b/wamr-compiler/main.c index f185a17b7..bd8691c4b 100644 --- a/wamr-compiler/main.c +++ b/wamr-compiler/main.c @@ -42,6 +42,8 @@ print_help() printf(" if the option is set:\n"); printf(" (1) it is always enabled when `--bounds-checks` is enabled,\n"); printf(" (2) else it is enabled/disabled according to the option value\n"); + printf(" --stack-usage= Generate a stack-usage file.\n"); + printf(" Similarly to `clang -fstack-usage`.\n"); printf(" --format= Specifies the format of the output file\n"); printf(" The format supported:\n"); printf(" aot (default) AoT file\n"); @@ -204,6 +206,9 @@ main(int argc, char *argv[]) else if (!strncmp(argv[0], "--stack-bounds-checks=", 22)) { option.stack_bounds_checks = (atoi(argv[0] + 22) == 1) ? 1 : 0; } + else if (!strncmp(argv[0], "--stack-usage=", 14)) { + option.stack_usage_file = argv[0] + 14; + } else if (!strncmp(argv[0], "--format=", 9)) { if (argv[0][9] == '\0') PRINT_HELP_AND_EXIT();