Przeglądaj źródła

wamrc: Add --stack-usage option (#2158)

YAMAMOTO Takashi 2 lat temu
rodzic
commit
2b896c80ef

+ 4 - 2
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;
         }

+ 1 - 0
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

+ 108 - 0
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 <llvm-c/TargetMachine.h>
+#include <llvm/MC/TargetRegistry.h>
+#include <llvm/Target/TargetMachine.h>
+
+#include "bh_assert.h"
+
+#include "aot_llvm_extra2.h"
+
+static llvm::Optional<llvm::Reloc::Model>
+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<llvm::CodeModel::Model>
+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<llvm::Target *>(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<LLVMTargetMachineRef>(targetmachine);
+}

+ 17 - 0
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/TargetMachine.h>
+
+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

+ 1 - 0
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

+ 5 - 0
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=<file>      Generate a stack-usage file.\n");
+    printf("                              Similarly to `clang -fstack-usage`.\n");
     printf("  --format=<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();