Răsfoiți Sursa

Fix jit target arch not set issue and custom name section typo issue (#400)

And set target machine's cpu to host cpu when creating JIT execution engine.

Signed-off-by: Wenyong Huang wenyong.huang@intel.com
Wenyong Huang 5 ani în urmă
părinte
comite
a3d374eb57

+ 21 - 2
core/iwasm/compilation/aot_llvm.c

@@ -997,6 +997,13 @@ get_target_arch_from_triple(const char *triple, char *arch_buf, uint32 buf_size)
     bh_assert(*triple == '-' || *triple == '\0');
 }
 
+LLVMBool
+WAMRCreateMCJITCompilerForModule(LLVMExecutionEngineRef *OutJIT,
+                                 LLVMModuleRef M,
+                                 struct LLVMMCJITCompilerOptions *Options,
+                                 size_t SizeOfOptions,
+                                 char **OutError);
+
 void LLVMAddPromoteMemoryToRegisterPass(LLVMPassManagerRef PM);
 
 AOTCompContext *
@@ -1007,7 +1014,8 @@ aot_create_comp_context(AOTCompData *comp_data,
     /*LLVMTypeRef elem_types[8];*/
     struct LLVMMCJITCompilerOptions jit_options;
     LLVMTargetRef target;
-    char *triple = NULL, *triple_norm, *arch, *abi, *cpu, *features, buf[128];
+    char *triple = NULL, *triple_jit = NULL, *triple_norm, *arch, *abi;
+    char *cpu = NULL, *features, buf[128];
     char *triple_norm_new = NULL, *cpu_new = NULL;
     char *err = NULL, *fp_round= "round.tonearest", *fp_exce = "fpexcept.strict";
     char triple_buf[32] = {0};
@@ -1060,7 +1068,7 @@ aot_create_comp_context(AOTCompData *comp_data,
         jit_options.OptLevel = LLVMCodeGenLevelAggressive;
         jit_options.EnableFastISel = true;
         /*jit_options.CodeModel = LLVMCodeModelSmall;*/
-        if (LLVMCreateMCJITCompilerForModule
+        if (WAMRCreateMCJITCompilerForModule
                 (&comp_ctx->exec_engine, comp_ctx->module,
                  &jit_options, sizeof(jit_options), &err) != 0) {
             if (err) {
@@ -1078,6 +1086,17 @@ aot_create_comp_context(AOTCompData *comp_data,
 #else
         comp_ctx->enable_bound_check = false;
 #endif
+
+        if (!(triple_jit =
+                LLVMGetTargetMachineTriple(comp_ctx->target_machine))) {
+            aot_set_last_error("can not get triple from the target machine");
+            goto fail;
+        }
+
+        /* Save target arch */
+        get_target_arch_from_triple(triple_jit, comp_ctx->target_arch,
+                                    sizeof(comp_ctx->target_arch));
+        LLVMDisposeMessage(triple_jit);
     }
     else {
         /* Create LLVM target machine */

+ 147 - 0
core/iwasm/compilation/aot_llvm_extra.cpp

@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#include <llvm/ADT/SmallVector.h>
+#include <llvm/ADT/Twine.h>
+#include <llvm/ADT/Triple.h>
+#include <llvm/ExecutionEngine/ExecutionEngine.h>
+#include <llvm/MC/MCSubtargetInfo.h>
+#include <llvm/Support/TargetSelect.h>
+#include <llvm/Target/TargetMachine.h>
+#include <llvm-c/Core.h>
+#include <llvm-c/ExecutionEngine.h>
+#include <llvm/ExecutionEngine/GenericValue.h>
+#include <llvm/ExecutionEngine/JITEventListener.h>
+#include <llvm/ExecutionEngine/RTDyldMemoryManager.h>
+#include <llvm/IR/DerivedTypes.h>
+#include <llvm/IR/Module.h>
+#include <llvm/Support/ErrorHandling.h>
+#include <llvm/Target/CodeGenCWrappers.h>
+#include <llvm/Target/TargetOptions.h>
+#include <cstring>
+
+using namespace llvm;
+
+extern "C" LLVMBool
+WAMRCreateMCJITCompilerForModule(LLVMExecutionEngineRef *OutJIT,
+                                 LLVMModuleRef M,
+                                 LLVMMCJITCompilerOptions *PassedOptions,
+                                 size_t SizeOfPassedOptions,
+                                 char **OutError);
+
+extern "C" bool
+aot_check_simd_compatibility(const char *arch_c_str, const char *cpu_c_str);
+
+LLVMBool
+WAMRCreateMCJITCompilerForModule(LLVMExecutionEngineRef *OutJIT,
+                                 LLVMModuleRef M,
+                                 LLVMMCJITCompilerOptions *PassedOptions,
+                                 size_t SizeOfPassedOptions,
+                                 char **OutError)
+{
+    LLVMMCJITCompilerOptions options;
+    // If the user passed a larger sized options struct, then they were compiled
+    // against a newer LLVM. Tell them that something is wrong.
+    if (SizeOfPassedOptions > sizeof(options)) {
+        *OutError = strdup(
+                "Refusing to use options struct that is larger than my own; assuming "
+                "LLVM library mismatch.");
+        return 1;
+    }
+
+    // Defend against the user having an old version of the API by ensuring that
+    // any fields they didn't see are cleared. We must defend against fields being
+    // set to the bitwise equivalent of zero, and assume that this means "do the
+    // default" as if that option hadn't been available.
+    LLVMInitializeMCJITCompilerOptions(&options, sizeof(options));
+    memcpy(&options, PassedOptions, SizeOfPassedOptions);
+
+    TargetOptions targetOptions;
+    targetOptions.EnableFastISel = options.EnableFastISel;
+    std::unique_ptr<Module> Mod(unwrap(M));
+
+    if (Mod) {
+        // Set function attribute "frame-pointer" based on
+        // NoFramePointerElim.
+        for (auto &F : *Mod) {
+            auto Attrs = F.getAttributes();
+            StringRef Value = options.NoFramePointerElim ? "all" : "none";
+            Attrs = Attrs.addAttribute(F.getContext(), AttributeList::FunctionIndex,
+                    "frame-pointer", Value);
+            F.setAttributes(Attrs);
+        }
+    }
+
+    std::string Error;
+    bool JIT;
+    char *host_cpu = LLVMGetHostCPUName();
+
+    if (!host_cpu) {
+        *OutError = NULL;
+        return false;
+    }
+
+    std::string mcpu(host_cpu);
+    LLVMDisposeMessage(host_cpu);
+
+    EngineBuilder builder(std::move(Mod));
+    builder.setEngineKind(EngineKind::JIT)
+           .setErrorStr(&Error)
+           .setMCPU(mcpu)
+           .setOptLevel((CodeGenOpt::Level)options.OptLevel)
+           .setTargetOptions(targetOptions);
+    if (Optional<CodeModel::Model> CM = unwrap(options.CodeModel, JIT))
+        builder.setCodeModel(*CM);
+    if (options.MCJMM)
+        builder.setMCJITMemoryManager(
+                std::unique_ptr<RTDyldMemoryManager>(unwrap(options.MCJMM)));
+    if (ExecutionEngine *JIT = builder.create()) {
+        *OutJIT = wrap(JIT);
+        return 0;
+    }
+    *OutError = strdup(Error.c_str());
+    return 1;
+}
+
+bool
+aot_check_simd_compatibility(const char *arch_c_str, const char *cpu_c_str)
+{
+#if WASM_ENABLE_SIMD != 0
+    if (!arch_c_str || !cpu_c_str) {
+        return false;
+    }
+
+    llvm::SmallVector<std::string, 1> targetAttributes;
+    llvm::Triple targetTriple(arch_c_str, "", "");
+    llvm::TargetMachine *targetMachine = llvm::EngineBuilder().selectTarget(
+      targetTriple, "", std::string(cpu_c_str), targetAttributes);
+    if (targetMachine == nullptr) {
+        return false;
+    }
+
+    const llvm::Triple::ArchType targetArch =
+      targetMachine->getTargetTriple().getArch();
+    const llvm::MCSubtargetInfo *subTargetInfo =
+      targetMachine->getMCSubtargetInfo();
+    if (subTargetInfo == nullptr) {
+        return false;
+    }
+
+    if (targetArch == llvm::Triple::x86_64) {
+        return subTargetInfo->checkFeatures("+sse4.1");
+    }
+    else if (targetArch == llvm::Triple::aarch64) {
+        return subTargetInfo->checkFeatures("+neon");
+    }
+    else {
+        return false;
+    }
+#else
+    (void)arch_c_str;
+    (void)cpu_c_str;
+    return true;
+#endif /* WASM_ENABLE_SIMD */
+}
+

+ 3 - 1
core/iwasm/compilation/iwasm_compl.cmake

@@ -2,7 +2,9 @@ set (IWASM_COMPL_DIR ${CMAKE_CURRENT_LIST_DIR})
 
 include_directories(${IWASM_COMPL_DIR})
 
-file (GLOB_RECURSE source_all ${IWASM_COMPL_DIR}/*.c)
+file (GLOB_RECURSE source_all
+                   ${IWASM_COMPL_DIR}/*.c
+                   ${IWASM_COMPL_DIR}/*.cpp)
 
 set (IWASM_COMPL_SOURCE ${source_all})
 

+ 1 - 1
core/iwasm/interpreter/wasm_loader.c

@@ -2394,7 +2394,7 @@ fail:
 
 #if WASM_ENABLE_CUSTOM_NAME_SECTION != 0
 static bool
-handle_name_section(const uint8 *buf, const uint8 *buf_end,Ø
+handle_name_section(const uint8 *buf, const uint8 *buf_end,
                     WASMModule *module,
                     char *error_buf, uint32 error_buf_size)
 {