This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG4625b848793f: [WebAssembly] Support clang -fwasm-exceptions
for bitcode (authored by aheejin).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D115893/new/
https://reviews.llvm.org/D115893
Files:
clang/test/CodeGen/WebAssembly/wasm-eh.ll
llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCAsmInfo.cpp
llvm/lib/Target/WebAssembly/Utils/WebAssemblyUtilities.cpp
llvm/lib/Target/WebAssembly/Utils/WebAssemblyUtilities.h
llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
Index: llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
@@ -14,6 +14,7 @@
#include "WebAssemblyTargetMachine.h"
#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
#include "TargetInfo/WebAssemblyTargetInfo.h"
+#include "Utils/WebAssemblyUtilities.h"
#include "WebAssembly.h"
#include "WebAssemblyMachineFunctionInfo.h"
#include "WebAssemblyTargetObjectFile.h"
@@ -24,6 +25,7 @@
#include "llvm/CodeGen/RegAllocRegistry.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/IR/Function.h"
+#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Transforms/Scalar.h"
@@ -33,28 +35,6 @@
#define DEBUG_TYPE "wasm"
-// Emscripten's asm.js-style exception handling
-cl::opt<bool>
- WasmEnableEmEH("enable-emscripten-cxx-exceptions",
- cl::desc("WebAssembly Emscripten-style exception handling"),
- cl::init(false));
-
-// Emscripten's asm.js-style setjmp/longjmp handling
-cl::opt<bool> WasmEnableEmSjLj(
- "enable-emscripten-sjlj",
- cl::desc("WebAssembly Emscripten-style setjmp/longjmp handling"),
- cl::init(false));
-
-// Exception handling using wasm EH instructions
-cl::opt<bool> WasmEnableEH("wasm-enable-eh",
- cl::desc("WebAssembly exception handling"),
- cl::init(false));
-
-// setjmp/longjmp handling using wasm EH instrutions
-cl::opt<bool> WasmEnableSjLj("wasm-enable-sjlj",
- cl::desc("WebAssembly setjmp/longjmp handling"),
- cl::init(false));
-
// A command-line option to keep implicit locals
// for the purpose of testing with lit/llc ONLY.
// This produces output which is not valid WebAssembly, and is not supported
@@ -368,7 +348,23 @@
return nullptr; // No reg alloc
}
-static void basicCheckForEHAndSjLj(const TargetMachine *TM) {
+using WebAssembly::WasmEnableEH;
+using WebAssembly::WasmEnableEmEH;
+using WebAssembly::WasmEnableEmSjLj;
+using WebAssembly::WasmEnableSjLj;
+
+static void basicCheckForEHAndSjLj(TargetMachine *TM) {
+ // Before checking, we make sure TargetOptions.ExceptionModel is the same as
+ // MCAsmInfo.ExceptionsType. Normally these have to be the same, because clang
+ // stores the exception model info in LangOptions, which is later transferred
+ // to TargetOptions and MCAsmInfo. But when clang compiles bitcode directly,
+ // clang's LangOptions is not used and thus the exception model info is not
+ // correctly transferred to TargetOptions and MCAsmInfo, so we make sure we
+ // have the correct exception model in in WebAssemblyMCAsmInfo constructor.
+ // But in this case TargetOptions is still not updated, so we make sure they
+ // are the same.
+ TM->Options.ExceptionModel = TM->getMCAsmInfo()->getExceptionHandlingType();
+
// Basic Correctness checking related to -exception-model
if (TM->Options.ExceptionModel != ExceptionHandling::None &&
TM->Options.ExceptionModel != ExceptionHandling::Wasm)
Index: llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
@@ -40,9 +40,6 @@
" instruction output for test purposes only."),
cl::init(false));
-extern cl::opt<bool> WasmEnableEmEH;
-extern cl::opt<bool> WasmEnableEmSjLj;
-
static void removeRegisterOperands(const MachineInstr *MI, MCInst &OutMI);
MCSymbol *
@@ -112,7 +109,8 @@
bool InvokeDetected = false;
auto *WasmSym = Printer.getMCSymbolForFunction(
- F, WasmEnableEmEH || WasmEnableEmSjLj, Signature.get(), InvokeDetected);
+ F, WebAssembly::WasmEnableEmEH || WebAssembly::WasmEnableEmSjLj,
+ Signature.get(), InvokeDetected);
WasmSym->setSignature(Signature.get());
Printer.addSignature(std::move(Signature));
WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION);
Index: llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
@@ -267,6 +267,7 @@
///
///===----------------------------------------------------------------------===//
+#include "Utils/WebAssemblyUtilities.h"
#include "WebAssembly.h"
#include "WebAssemblyTargetMachine.h"
#include "llvm/ADT/StringExtras.h"
@@ -285,13 +286,6 @@
#define DEBUG_TYPE "wasm-lower-em-ehsjlj"
-// Emscripten's asm.js-style exception handling
-extern cl::opt<bool> WasmEnableEmEH;
-// Emscripten's asm.js-style setjmp/longjmp handling
-extern cl::opt<bool> WasmEnableEmSjLj;
-// Wasm setjmp/longjmp handling using wasm EH instructions
-extern cl::opt<bool> WasmEnableSjLj;
-
static cl::list<std::string>
EHAllowlist("emscripten-cxx-exceptions-allowed",
cl::desc("The list of function names in which Emscripten-style "
@@ -370,8 +364,9 @@
static char ID;
WebAssemblyLowerEmscriptenEHSjLj()
- : ModulePass(ID), EnableEmEH(WasmEnableEmEH),
- EnableEmSjLj(WasmEnableEmSjLj), EnableWasmSjLj(WasmEnableSjLj) {
+ : ModulePass(ID), EnableEmEH(WebAssembly::WasmEnableEmEH),
+ EnableEmSjLj(WebAssembly::WasmEnableEmSjLj),
+ EnableWasmSjLj(WebAssembly::WasmEnableSjLj) {
assert(!(EnableEmSjLj && EnableWasmSjLj) &&
"Two SjLj modes cannot be turned on at the same time");
assert(!(EnableEmEH && EnableWasmSjLj) &&
Index: llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
@@ -51,8 +51,6 @@
#define DEBUG_TYPE "asm-printer"
extern cl::opt<bool> WasmKeepRegisters;
-extern cl::opt<bool> WasmEnableEmEH;
-extern cl::opt<bool> WasmEnableEmSjLj;
//===----------------------------------------------------------------------===//
// Helpers.
@@ -322,8 +320,9 @@
// will discard it later if it turns out not to be necessary.
auto Signature = signatureFromMVTs(Results, Params);
bool InvokeDetected = false;
- auto *Sym = getMCSymbolForFunction(&F, WasmEnableEmEH || WasmEnableEmSjLj,
- Signature.get(), InvokeDetected);
+ auto *Sym = getMCSymbolForFunction(
+ &F, WebAssembly::WasmEnableEmEH || WebAssembly::WasmEnableEmSjLj,
+ Signature.get(), InvokeDetected);
// Multiple functions can be mapped to the same invoke symbol. For
// example, two IR functions '__invoke_void_i8*' and '__invoke_void_i32'
Index: llvm/lib/Target/WebAssembly/Utils/WebAssemblyUtilities.h
===================================================================
--- llvm/lib/Target/WebAssembly/Utils/WebAssemblyUtilities.h
+++ llvm/lib/Target/WebAssembly/Utils/WebAssemblyUtilities.h
@@ -16,6 +16,7 @@
#define LLVM_LIB_TARGET_WEBASSEMBLY_UTILS_WEBASSEMBLYUTILITIES_H
#include "llvm/IR/DerivedTypes.h"
+#include "llvm/Support/CommandLine.h"
namespace llvm {
@@ -70,6 +71,12 @@
bool isChild(const MachineInstr &MI, const WebAssemblyFunctionInfo &MFI);
bool mayThrow(const MachineInstr &MI);
+// Exception handling / setjmp-longjmp handling command-line options
+extern cl::opt<bool> WasmEnableEmEH; // asm.js-style EH
+extern cl::opt<bool> WasmEnableEmSjLj; // asm.js-style SjLJ
+extern cl::opt<bool> WasmEnableEH; // EH using Wasm EH instructions
+extern cl::opt<bool> WasmEnableSjLj; // SjLj using Wasm EH instructions
+
// Exception-related function names
extern const char *const ClangCallTerminateFn;
extern const char *const CxaBeginCatchFn;
Index: llvm/lib/Target/WebAssembly/Utils/WebAssemblyUtilities.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/Utils/WebAssemblyUtilities.cpp
+++ llvm/lib/Target/WebAssembly/Utils/WebAssemblyUtilities.cpp
@@ -18,6 +18,31 @@
#include "llvm/MC/MCContext.h"
using namespace llvm;
+// Exception handling & setjmp-longjmp handling related options. These are
+// defined here to be shared between WebAssembly and its subdirectories.
+
+// Emscripten's asm.js-style exception handling
+cl::opt<bool> WebAssembly::WasmEnableEmEH(
+ "enable-emscripten-cxx-exceptions",
+ cl::desc("WebAssembly Emscripten-style exception handling"),
+ cl::init(false));
+// Emscripten's asm.js-style setjmp/longjmp handling
+cl::opt<bool> WebAssembly::WasmEnableEmSjLj(
+ "enable-emscripten-sjlj",
+ cl::desc("WebAssembly Emscripten-style setjmp/longjmp handling"),
+ cl::init(false));
+// Exception handling using wasm EH instructions
+cl::opt<bool>
+ WebAssembly::WasmEnableEH("wasm-enable-eh",
+ cl::desc("WebAssembly exception handling"),
+ cl::init(false));
+// setjmp/longjmp handling using wasm EH instrutions
+cl::opt<bool>
+ WebAssembly::WasmEnableSjLj("wasm-enable-sjlj",
+ cl::desc("WebAssembly setjmp/longjmp handling"),
+ cl::init(false));
+
+// Function names in libc++abi and libunwind
const char *const WebAssembly::CxaBeginCatchFn = "__cxa_begin_catch";
const char *const WebAssembly::CxaRethrowFn = "__cxa_rethrow";
const char *const WebAssembly::StdTerminateFn = "_ZSt9terminatev";
Index: llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCAsmInfo.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCAsmInfo.cpp
+++ llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCAsmInfo.cpp
@@ -13,6 +13,7 @@
//===----------------------------------------------------------------------===//
#include "WebAssemblyMCAsmInfo.h"
+#include "Utils/WebAssemblyUtilities.h"
#include "llvm/ADT/Triple.h"
using namespace llvm;
@@ -44,5 +45,13 @@
SupportsDebugInformation = true;
+ // When compilation is done on a cpp file by clang, the exception model info
+ // is stored in LangOptions, which is later used to set the info in
+ // TargetOptions and then MCAsmInfo in LLVMTargetMachine::initAsmInfo(). But
+ // this process does not happen when compiling bitcode directly with clang, so
+ // we make sure this info is set correctly.
+ if (WebAssembly::WasmEnableEH || WebAssembly::WasmEnableSjLj)
+ ExceptionsType = ExceptionHandling::Wasm;
+
// TODO: UseIntegratedAssembler?
}
Index: clang/test/CodeGen/WebAssembly/wasm-eh.ll
===================================================================
--- /dev/null
+++ clang/test/CodeGen/WebAssembly/wasm-eh.ll
@@ -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()
+
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits