blob: 837e9576c853574f98671c058b461a5e5c15452b [file] [log] [blame]
Heejin Ahn5ef4d5f2018-05-31 22:25:54 +00001//=== WebAssemblyExceptionPrepare.cpp - WebAssembly Exception Preparation -===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9///
10/// \file
11/// \brief Does various transformations for exception handling.
12///
13//===----------------------------------------------------------------------===//
14
15#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
16#include "WebAssembly.h"
17#include "WebAssemblySubtarget.h"
18#include "llvm/CodeGen/MachineInstrBuilder.h"
19using namespace llvm;
20
21#define DEBUG_TYPE "wasm-exception-prepare"
22
23namespace {
24class WebAssemblyExceptionPrepare final : public MachineFunctionPass {
25 StringRef getPassName() const override {
26 return "WebAssembly Prepare Exception";
27 }
28
29 bool runOnMachineFunction(MachineFunction &MF) override;
30
31 bool replaceFuncletReturns(MachineFunction &MF);
32
33public:
34 static char ID; // Pass identification, replacement for typeid
35 WebAssemblyExceptionPrepare() : MachineFunctionPass(ID) {}
36};
37} // end anonymous namespace
38
39char WebAssemblyExceptionPrepare::ID = 0;
40INITIALIZE_PASS(WebAssemblyExceptionPrepare, DEBUG_TYPE,
41 "WebAssembly Exception Preparation", false, false)
42
43FunctionPass *llvm::createWebAssemblyExceptionPrepare() {
44 return new WebAssemblyExceptionPrepare();
45}
46
47bool WebAssemblyExceptionPrepare::runOnMachineFunction(MachineFunction &MF) {
48 bool Changed = false;
49 if (!MF.getFunction().hasPersonalityFn())
50 return false;
51 Changed |= replaceFuncletReturns(MF);
52 // TODO More transformations will be added
53 return Changed;
54}
55
56bool WebAssemblyExceptionPrepare::replaceFuncletReturns(MachineFunction &MF) {
57 bool Changed = false;
58 const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
59
60 for (auto &MBB : MF) {
61 auto Pos = MBB.getFirstTerminator();
62 if (Pos == MBB.end())
63 continue;
64 MachineInstr *TI = &*Pos;
65
66 switch (TI->getOpcode()) {
67 case WebAssembly::CATCHRET: {
68 // Replace a catchret with a branch
69 MachineBasicBlock *TBB = TI->getOperand(0).getMBB();
70 if (!MBB.isLayoutSuccessor(TBB))
71 BuildMI(MBB, TI, TI->getDebugLoc(), TII.get(WebAssembly::BR))
72 .addMBB(TBB);
73 TI->eraseFromParent();
74 Changed = true;
75 break;
76 }
77 case WebAssembly::CLEANUPRET: {
78 // Replace a cleanupret with a rethrow
79 BuildMI(MBB, TI, TI->getDebugLoc(), TII.get(WebAssembly::RETHROW))
80 .addImm(0);
81 TI->eraseFromParent();
82 Changed = true;
83 break;
84 }
85 }
86 }
87 return Changed;
88}