Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[WebAssembly] Support clang -fwasm-exceptions for bitcode
This supports bitcode compilation using `clang -fwasm-exceptions`. --- The current situation: Currently the backend requires two options for Wasm EH: `-wasm-enable-eh` and `-exception-model=wasm`. Wasm SjLj requires two options as well: `-wasm-enable-sjlj` and `-exception-model=wasm`. When using Wasm EH via Emscripten, you only need to pass `-fwasm-exceptions`, and these options will be added within the clang driver. This description will focus on the case of Wasm EH going forward, but Wasm SjLj's case is similar. When you pass `-fwasm-exceptions` to emcc and clang driver, the clang driver adds these options to the command line that calls the clang frontend (`clang -cc1`): `-mllvm -wasm-enable-eh` and `-exception-model=wasm`. `-wasm-enable-eh` is prefixed with `-mllvm`, so it is passed as is to the backend. But `-exception-model` is parsed and processed within the clang frontend and stored in `LangOptions` class. This info is later transferred to `TargetOptions` class, and then eventually passed to `MCAsmInfo` class. All LLVM code queries this `MCAsmInfo` to get the exception model. --- Problem: The problem is the whole `LangOptions` processing is bypassed when compiling bitcode, so the information transfer of `LangOptions` -> `TargetOptions` -> `MCAsmInfo` does not happen. They are all set to `ExceptionHandling::None`, which is the default value. --- What other targets do, and why we can't do the same: Other targets support bitcode compilation by the clang driver, but they can do that by using different triples. For example, X86 target supports multiple triples, each of which has its own subclass of `MCAsmInfo`, so it can hardcode the appropriate exception model within those subclasses' constructors. But we don't have separate triples for each exception mode: none, emscripten, and wasm. --- What this CL does: If we can figure out whether `-wasm-enable-eh` is passed to the backend, we can programatically set the exception model from the backend, rather than requiring it to be passed. So we check `WasmEnableEH` and `WasmEnableSjLj` variables, which are `cl::opt` for `-wasm-enable-eh` and `-wasm-enable-sjlj`, in `WebAssemblyMCAsmInfo` constructor, and if either of them is set, we set `MCAsmInfo.ExceptionType` to Wasm. `TargetOptions` cannot be updated there, so we make sure they are the same later. Fixes emscripten-core/emscripten#15712. Reviewed By: dschuff Differential Revision: https://reviews.llvm.org/D115893
- Loading branch information
Showing
8 changed files
with
107 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
; REQUIRES: webassembly-registered-target | ||
; RUN: %clang %s -target wasm32-unknown-unknown -fwasm-exceptions -c -S -o - | FileCheck %s | ||
|
||
; This tests whether clang driver can take -fwasm-exceptions and compile bitcode | ||
; files using Wasm EH. | ||
|
||
; CHECK-LABEL: test | ||
; CHECK: try | ||
; CHECK: call foo | ||
; CHECK: catch __cpp_exception | ||
; CHECK: end | ||
define void @test() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) { | ||
entry: | ||
invoke void @foo() | ||
to label %try.cont unwind label %catch.dispatch | ||
|
||
catch.dispatch: ; preds = %entry | ||
%0 = catchswitch within none [label %catch.start] unwind to caller | ||
|
||
catch.start: ; preds = %catch.dispatch | ||
%1 = catchpad within %0 [i8* null] | ||
%2 = call i8* @llvm.wasm.get.exception(token %1) | ||
%3 = call i32 @llvm.wasm.get.ehselector(token %1) | ||
%4 = call i8* @__cxa_begin_catch(i8* %2) #2 [ "funclet"(token %1) ] | ||
call void @__cxa_end_catch() [ "funclet"(token %1) ] | ||
catchret from %1 to label %try.cont | ||
|
||
try.cont: ; preds = %entry, %catch.start | ||
ret void | ||
} | ||
|
||
declare void @foo() | ||
declare i32 @__gxx_wasm_personality_v0(...) | ||
declare i8* @llvm.wasm.get.exception(token) | ||
declare i32 @llvm.wasm.get.ehselector(token) | ||
declare i8* @__cxa_begin_catch(i8*) | ||
declare void @__cxa_end_catch() | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters