yaml::WebAssemblyFunctionInfo::WebAssemblyFunctionInfo(
const llvm::WebAssemblyFunctionInfo &MFI)
- : CFGStackified(MFI.isCFGStackified()) {}
+ : CFGStackified(MFI.isCFGStackified()) {
+ auto *EHInfo = MFI.getWasmEHFuncInfo();
+ const llvm::MachineFunction &MF = MFI.getMachineFunction();
+ // MFI.getWasmEHFuncInfo() is non-null only for functions with the
+ // personality function.
+ if (EHInfo) {
+ // SrcToUnwindDest can contain stale mappings in case BBs are removed in
+ // optimizations, in case, for example, they are unreachable. We should not
+ // include their info.
+ SmallPtrSet<const MachineBasicBlock *, 16> MBBs;
+ for (const auto &MBB : MF)
+ MBBs.insert(&MBB);
+ for (auto KV : EHInfo->SrcToUnwindDest) {
+ auto *SrcBB = KV.first.get<MachineBasicBlock *>();
+ auto *DestBB = KV.second.get<MachineBasicBlock *>();
+ if (MBBs.count(SrcBB) && MBBs.count(DestBB))
+ SrcToUnwindDest[SrcBB->getNumber()] = DestBB->getNumber();
+ }
+ }
+}
void yaml::WebAssemblyFunctionInfo::mappingImpl(yaml::IO &YamlIO) {
MappingTraits<WebAssemblyFunctionInfo>::mapping(YamlIO, *this);
void WebAssemblyFunctionInfo::initializeBaseYamlFields(
const yaml::WebAssemblyFunctionInfo &YamlMFI) {
CFGStackified = YamlMFI.CFGStackified;
+ if (WasmEHInfo) {
+ for (auto KV : YamlMFI.SrcToUnwindDest)
+ WasmEHInfo->setUnwindDest(MF.getBlockNumbered(KV.first),
+ MF.getBlockNumbered(KV.second));
+ }
}
#include "llvm/BinaryFormat/Wasm.h"
#include "llvm/CodeGen/MIRYamlMapping.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/WasmEHFuncInfo.h"
#include "llvm/MC/MCSymbolWasm.h"
namespace llvm {
/// This class is derived from MachineFunctionInfo and contains private
/// WebAssembly-specific information for each MachineFunction.
class WebAssemblyFunctionInfo final : public MachineFunctionInfo {
+ const MachineFunction &MF;
+
std::vector<MVT> Params;
std::vector<MVT> Results;
std::vector<MVT> Locals;
// Function properties.
bool CFGStackified = false;
+ // Catchpad unwind destination info for wasm EH.
+ WasmEHFuncInfo *WasmEHInfo = nullptr;
+
public:
- explicit WebAssemblyFunctionInfo(MachineFunction &MF) {}
+ explicit WebAssemblyFunctionInfo(MachineFunction &MF)
+ : MF(MF), WasmEHInfo(MF.getWasmEHFuncInfo()) {}
~WebAssemblyFunctionInfo() override;
+
+ const MachineFunction &getMachineFunction() const { return MF; }
+
void initializeBaseYamlFields(const yaml::WebAssemblyFunctionInfo &YamlMFI);
void addParam(MVT VT) { Params.push_back(VT); }
bool isCFGStackified() const { return CFGStackified; }
void setCFGStackified(bool Value = true) { CFGStackified = Value; }
+
+ WasmEHFuncInfo *getWasmEHFuncInfo() const { return WasmEHInfo; }
+ void setWasmEHFuncInfo(WasmEHFuncInfo *Info) { WasmEHInfo = Info; }
};
void computeLegalValueVTs(const Function &F, const TargetMachine &TM, Type *Ty,
namespace yaml {
+using BBNumberMap = DenseMap<int, int>;
+
struct WebAssemblyFunctionInfo final : public yaml::MachineFunctionInfo {
bool CFGStackified = false;
+ // The same as WasmEHFuncInfo's SrcToUnwindDest, but stored in the mapping of
+ // BB numbers
+ BBNumberMap SrcToUnwindDest;
WebAssemblyFunctionInfo() = default;
WebAssemblyFunctionInfo(const llvm::WebAssemblyFunctionInfo &MFI);
template <> struct MappingTraits<WebAssemblyFunctionInfo> {
static void mapping(IO &YamlIO, WebAssemblyFunctionInfo &MFI) {
YamlIO.mapOptional("isCFGStackified", MFI.CFGStackified, false);
+ YamlIO.mapOptional("wasmEHFuncInfo", MFI.SrcToUnwindDest);
+ }
+};
+
+template <> struct CustomMappingTraits<BBNumberMap> {
+ static void inputOne(IO &YamlIO, StringRef Key,
+ BBNumberMap &SrcToUnwindDest) {
+ YamlIO.mapRequired(Key.str().c_str(),
+ SrcToUnwindDest[std::atoi(Key.str().c_str())]);
+ }
+
+ static void output(IO &YamlIO, BBNumberMap &SrcToUnwindDest) {
+ for (auto KV : SrcToUnwindDest)
+ YamlIO.mapRequired(std::to_string(KV.first).c_str(), KV.second);
}
};
-# RUN: llc -mtriple=wasm32-unknown-unknown -run-pass wasm-cfg-stackify %s -o - | FileCheck %s
+# RUN: llc -mtriple=wasm32-unknown-unknown -exception-model=wasm -mattr=+exception-handling -run-pass wasm-cfg-sort -run-pass wasm-cfg-stackify %s -o - | FileCheck %s
-# CHECK-LABEL: function_property_test
+--- |
+ target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
+ target triple = "wasm32-unknown-unknown"
+
+ declare i32 @__gxx_wasm_personality_v0(...)
+ declare void @foo()
+ define void @function_property_test() {
+ ret void
+ }
+ define void @wasm_eh_info_test() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) {
+ ret void
+ }
+...
+
+# CHECK-LABEL: name: function_property_test
# CHECK: machineFunctionInfo:
# CHECK: isCFGStackified: true
name: function_property_test
bb.0:
RETURN implicit-def dead $arguments
...
+
+---
+# CHECK-LABEL: name: wasm_eh_info_test
+# CHECK: machineFunctionInfo:
+name: wasm_eh_info_test
+liveins:
+ - { reg: '$arguments' }
+# CHECK: wasmEHFuncInfo:
+# bb.2 becomes bb.1 and bb.3 becomes bb.2 after CFGSort.
+# CHECK-NEXT: 1: 2
+machineFunctionInfo:
+ wasmEHFuncInfo:
+ 2: 3
+body: |
+ bb.0:
+ successors: %bb.1, %bb.2
+ CALL @foo, implicit-def dead $arguments, implicit $sp32, implicit $sp64, implicit-def dead $arguments, implicit $sp32, implicit $sp64
+
+ bb.1:
+ RETURN implicit-def dead $arguments
+
+ bb.2 (landing-pad):
+ successors: %bb.1, %bb.3
+ %0:i32 = CATCH &__cpp_exception, implicit-def dead $arguments
+ CALL @foo, implicit-def dead $arguments, implicit $sp32, implicit $sp64, implicit-def dead $arguments, implicit $sp32, implicit $sp64
+ BR %bb.1, implicit-def $arguments
+
+ bb.3 (landing-pad):
+ CATCH_ALL implicit-def $arguments
+ RETHROW 0, implicit-def $arguments
+...