Xu Jun 5 лет назад
Родитель
Сommit
c87f28eacd

+ 6 - 0
core/iwasm/aot/aot_loader.c

@@ -2093,8 +2093,14 @@ aot_convert_wasm_module(WASMModule *wasm_module,
     }
     }
 
 
     option.is_jit_mode = true;
     option.is_jit_mode = true;
+#if WASM_ENABLE_BULK_MEMORY != 0
+    option.enable_bulk_memory = true;
+#endif
 #if WASM_ENABLE_THREAD_MGR != 0
 #if WASM_ENABLE_THREAD_MGR != 0
     option.enable_thread_mgr = true;
     option.enable_thread_mgr = true;
+#endif
+#if WASM_ENABLE_TAIL_CALL != 0
+    option.enable_tail_call = true;
 #endif
 #endif
     comp_ctx = aot_create_comp_context(comp_data, &option);
     comp_ctx = aot_create_comp_context(comp_data, &option);
     if (!comp_ctx) {
     if (!comp_ctx) {

+ 29 - 1
core/iwasm/compilation/aot_compiler.c

@@ -240,7 +240,7 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
 
 
       case WASM_OP_CALL:
       case WASM_OP_CALL:
         read_leb_uint32(frame_ip, frame_ip_end, func_idx);
         read_leb_uint32(frame_ip, frame_ip_end, func_idx);
-        if (!aot_compile_op_call(comp_ctx, func_ctx, func_idx, &frame_ip))
+        if (!aot_compile_op_call(comp_ctx, func_ctx, func_idx, false))
           return false;
           return false;
         break;
         break;
 
 
@@ -251,6 +251,33 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
           return false;
           return false;
         break;
         break;
 
 
+#if WASM_ENABLE_TAIL_CALL != 0
+      case WASM_OP_RETURN_CALL:
+        if (!comp_ctx->enable_tail_call) {
+          aot_set_last_error("unsupported opcode");
+          return false;
+        }
+        read_leb_uint32(frame_ip, frame_ip_end, func_idx);
+        if (!aot_compile_op_call(comp_ctx, func_ctx, func_idx, true))
+          return false;
+        if (!aot_compile_op_return(comp_ctx, func_ctx, &frame_ip))
+          return false;
+        break;
+
+      case WASM_OP_RETURN_CALL_INDIRECT:
+        if (!comp_ctx->enable_tail_call) {
+          aot_set_last_error("unsupported opcode");
+          return false;
+        }
+        read_leb_uint32(frame_ip, frame_ip_end, type_idx);
+        frame_ip++; /* skip 0x00 */
+        if (!aot_compile_op_call_indirect(comp_ctx, func_ctx, type_idx))
+          return false;
+        if (!aot_compile_op_return(comp_ctx, func_ctx, &frame_ip))
+          return false;
+        break;
+#endif /* end of WASM_ENABLE_TAIL_CALL */
+
       case WASM_OP_DROP:
       case WASM_OP_DROP:
         if (!aot_compile_op_drop(comp_ctx, func_ctx, true))
         if (!aot_compile_op_drop(comp_ctx, func_ctx, true))
             return false;
             return false;
@@ -993,6 +1020,7 @@ build_atomic_rmw:
 #endif /* end of WASM_ENABLE_SHARED_MEMORY */
 #endif /* end of WASM_ENABLE_SHARED_MEMORY */
 
 
       default:
       default:
+        aot_set_last_error("unsupported opcode");
         break;
         break;
     }
     }
   }
   }

+ 6 - 2
core/iwasm/compilation/aot_emit_function.c

@@ -304,7 +304,7 @@ check_stack_boundary(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
 
 
 bool
 bool
 aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
 aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
-                    uint32 func_idx, uint8 **p_frame_ip)
+                    uint32 func_idx, bool tail_call)
 {
 {
     uint32 import_func_count = comp_ctx->comp_data->import_func_count;
     uint32 import_func_count = comp_ctx->comp_data->import_func_count;
     AOTImportFunc *import_funcs = comp_ctx->comp_data->import_funcs;
     AOTImportFunc *import_funcs = comp_ctx->comp_data->import_funcs;
@@ -476,8 +476,12 @@ aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
         /* Set calling convention for the call with the func's calling convention */
         /* Set calling convention for the call with the func's calling convention */
         LLVMSetInstructionCallConv(value_ret, LLVMGetFunctionCallConv(func));
         LLVMSetInstructionCallConv(value_ret, LLVMGetFunctionCallConv(func));
 
 
+        if (tail_call)
+            LLVMSetTailCall(value_ret, true);
+
         /* Check whether there was exception thrown when executing the function */
         /* Check whether there was exception thrown when executing the function */
-        if (!check_exception_thrown(comp_ctx, func_ctx))
+        if (!tail_call
+            && !check_exception_thrown(comp_ctx, func_ctx))
             goto fail;
             goto fail;
     }
     }
 
 

+ 1 - 1
core/iwasm/compilation/aot_emit_function.h

@@ -14,7 +14,7 @@ extern "C" {
 
 
 bool
 bool
 aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
 aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
-                    uint32 func_idx, uint8 **p_frame_ip);
+                    uint32 func_idx, bool tail_call);
 
 
 bool
 bool
 aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
 aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,

+ 3 - 0
core/iwasm/compilation/aot_llvm.c

@@ -1062,6 +1062,9 @@ aot_create_comp_context(AOTCompData *comp_data,
     if (option->enable_thread_mgr)
     if (option->enable_thread_mgr)
         comp_ctx->enable_thread_mgr = true;
         comp_ctx->enable_thread_mgr = true;
 
 
+    if (option->enable_tail_call)
+        comp_ctx->enable_tail_call = true;
+
     if (option->is_jit_mode) {
     if (option->is_jit_mode) {
         /* Create LLVM execution engine */
         /* Create LLVM execution engine */
         LLVMInitializeMCJITCompilerOptions(&jit_options, sizeof(jit_options));
         LLVMInitializeMCJITCompilerOptions(&jit_options, sizeof(jit_options));

+ 4 - 0
core/iwasm/compilation/aot_llvm.h

@@ -204,6 +204,9 @@ typedef struct AOTCompContext {
   /* Thread Manager */
   /* Thread Manager */
   bool enable_thread_mgr;
   bool enable_thread_mgr;
 
 
+  /* Tail Call */
+  bool enable_tail_call;
+
   /* Whether optimize the JITed code */
   /* Whether optimize the JITed code */
   bool optimize;
   bool optimize;
 
 
@@ -244,6 +247,7 @@ typedef struct AOTCompOption{
     char *cpu_features;
     char *cpu_features;
     bool enable_bulk_memory;
     bool enable_bulk_memory;
     bool enable_thread_mgr;
     bool enable_thread_mgr;
+    bool enable_tail_call;
     bool is_sgx_platform;
     bool is_sgx_platform;
     uint32 opt_level;
     uint32 opt_level;
     uint32 size_level;
     uint32 size_level;

+ 1 - 0
core/iwasm/include/aot_export.h

@@ -41,6 +41,7 @@ typedef struct AOTCompOption{
     char *cpu_features;
     char *cpu_features;
     bool enable_bulk_memory;
     bool enable_bulk_memory;
     bool enable_thread_mgr;
     bool enable_thread_mgr;
+    bool enable_tail_call;
     bool is_sgx_platform;
     bool is_sgx_platform;
     uint32_t opt_level;
     uint32_t opt_level;
     uint32_t size_level;
     uint32_t size_level;

+ 1 - 0
wamr-compiler/CMakeLists.txt

@@ -26,6 +26,7 @@ add_definitions(-DWASM_ENABLE_BULK_MEMORY=1)
 add_definitions(-DWASM_DISABLE_HW_BOUND_CHECK=1)
 add_definitions(-DWASM_DISABLE_HW_BOUND_CHECK=1)
 add_definitions(-DWASM_ENABLE_SHARED_MEMORY=1)
 add_definitions(-DWASM_ENABLE_SHARED_MEMORY=1)
 add_definitions(-DWASM_ENABLE_THREAD_MGR=1)
 add_definitions(-DWASM_ENABLE_THREAD_MGR=1)
+add_definitions(-DWASM_ENABLE_TAIL_CALL=1)
 
 
 # Set WAMR_BUILD_TARGET, currently values supported:
 # Set WAMR_BUILD_TARGET, currently values supported:
 # "X86_64", "AMD_64", "X86_32", "ARM_32", "MIPS_32", "XTENSA_32"
 # "X86_64", "AMD_64", "X86_32", "ARM_32", "MIPS_32", "XTENSA_32"

+ 4 - 0
wamr-compiler/main.c

@@ -41,6 +41,7 @@ print_help()
   printf("                              llvmir-opt     Optimized LLVM IR\n");
   printf("                              llvmir-opt     Optimized LLVM IR\n");
   printf("  --enable-bulk-memory      Enable the post-MVP bulk memory feature\n");
   printf("  --enable-bulk-memory      Enable the post-MVP bulk memory feature\n");
   printf("  --enable-multi-thread     Enable multi-thread feature, the dependent features bulk-memory and\n");
   printf("  --enable-multi-thread     Enable multi-thread feature, the dependent features bulk-memory and\n");
+  printf("  --enable-tail-call        Enable the post-MVP tail call feature\n");
   printf("                            thread-mgr will be enabled automatically\n");
   printf("                            thread-mgr will be enabled automatically\n");
   printf("  -v=n                      Set log verbose level (0 to 5, default is 2), larger with more log\n");
   printf("  -v=n                      Set log verbose level (0 to 5, default is 2), larger with more log\n");
   printf("Examples: wamrc -o test.aot test.wasm\n");
   printf("Examples: wamrc -o test.aot test.wasm\n");
@@ -146,6 +147,9 @@ main(int argc, char *argv[])
         option.enable_bulk_memory = true;
         option.enable_bulk_memory = true;
         option.enable_thread_mgr = true;
         option.enable_thread_mgr = true;
     }
     }
+    else if (!strcmp(argv[0], "--enable-tail-call")) {
+        option.enable_tail_call = true;
+    }
     else
     else
       return print_help();
       return print_help();
   }
   }