1d88c1a5aSDimitry Andric //===-- WebAssemblyUtilities.cpp - WebAssembly Utility Functions ----------===//
2d88c1a5aSDimitry Andric //
3d88c1a5aSDimitry Andric //                     The LLVM Compiler Infrastructure
4d88c1a5aSDimitry Andric //
5d88c1a5aSDimitry Andric // This file is distributed under the University of Illinois Open Source
6d88c1a5aSDimitry Andric // License. See LICENSE.TXT for details.
7d88c1a5aSDimitry Andric //
8d88c1a5aSDimitry Andric //===----------------------------------------------------------------------===//
9d88c1a5aSDimitry Andric ///
10d88c1a5aSDimitry Andric /// \file
114ba319b5SDimitry Andric /// This file implements several utility functions for WebAssembly.
12d88c1a5aSDimitry Andric ///
13d88c1a5aSDimitry Andric //===----------------------------------------------------------------------===//
14d88c1a5aSDimitry Andric 
15d88c1a5aSDimitry Andric #include "WebAssemblyUtilities.h"
16d88c1a5aSDimitry Andric #include "WebAssemblyMachineFunctionInfo.h"
17d88c1a5aSDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
187a7e6055SDimitry Andric #include "llvm/CodeGen/MachineLoopInfo.h"
19d88c1a5aSDimitry Andric using namespace llvm;
20d88c1a5aSDimitry Andric 
214ba319b5SDimitry Andric const char *const WebAssembly::ClangCallTerminateFn = "__clang_call_terminate";
224ba319b5SDimitry Andric const char *const WebAssembly::CxaBeginCatchFn = "__cxa_begin_catch";
234ba319b5SDimitry Andric const char *const WebAssembly::CxaRethrowFn = "__cxa_rethrow";
244ba319b5SDimitry Andric const char *const WebAssembly::StdTerminateFn = "_ZSt9terminatev";
254ba319b5SDimitry Andric const char *const WebAssembly::PersonalityWrapperFn =
264ba319b5SDimitry Andric     "_Unwind_Wasm_CallPersonality";
274ba319b5SDimitry Andric 
isArgument(const MachineInstr & MI)28d88c1a5aSDimitry Andric bool WebAssembly::isArgument(const MachineInstr &MI) {
29d88c1a5aSDimitry Andric   switch (MI.getOpcode()) {
30*b5893f02SDimitry Andric   case WebAssembly::ARGUMENT_i32:
31*b5893f02SDimitry Andric   case WebAssembly::ARGUMENT_i32_S:
32*b5893f02SDimitry Andric   case WebAssembly::ARGUMENT_i64:
33*b5893f02SDimitry Andric   case WebAssembly::ARGUMENT_i64_S:
34*b5893f02SDimitry Andric   case WebAssembly::ARGUMENT_f32:
35*b5893f02SDimitry Andric   case WebAssembly::ARGUMENT_f32_S:
36*b5893f02SDimitry Andric   case WebAssembly::ARGUMENT_f64:
37*b5893f02SDimitry Andric   case WebAssembly::ARGUMENT_f64_S:
38d88c1a5aSDimitry Andric   case WebAssembly::ARGUMENT_v16i8:
39*b5893f02SDimitry Andric   case WebAssembly::ARGUMENT_v16i8_S:
40d88c1a5aSDimitry Andric   case WebAssembly::ARGUMENT_v8i16:
41*b5893f02SDimitry Andric   case WebAssembly::ARGUMENT_v8i16_S:
42d88c1a5aSDimitry Andric   case WebAssembly::ARGUMENT_v4i32:
43*b5893f02SDimitry Andric   case WebAssembly::ARGUMENT_v4i32_S:
44*b5893f02SDimitry Andric   case WebAssembly::ARGUMENT_v2i64:
45*b5893f02SDimitry Andric   case WebAssembly::ARGUMENT_v2i64_S:
46d88c1a5aSDimitry Andric   case WebAssembly::ARGUMENT_v4f32:
47*b5893f02SDimitry Andric   case WebAssembly::ARGUMENT_v4f32_S:
48*b5893f02SDimitry Andric   case WebAssembly::ARGUMENT_v2f64:
49*b5893f02SDimitry Andric   case WebAssembly::ARGUMENT_v2f64_S:
50d88c1a5aSDimitry Andric     return true;
51d88c1a5aSDimitry Andric   default:
52d88c1a5aSDimitry Andric     return false;
53d88c1a5aSDimitry Andric   }
54d88c1a5aSDimitry Andric }
55d88c1a5aSDimitry Andric 
isCopy(const MachineInstr & MI)56d88c1a5aSDimitry Andric bool WebAssembly::isCopy(const MachineInstr &MI) {
57d88c1a5aSDimitry Andric   switch (MI.getOpcode()) {
58d88c1a5aSDimitry Andric   case WebAssembly::COPY_I32:
59*b5893f02SDimitry Andric   case WebAssembly::COPY_I32_S:
60d88c1a5aSDimitry Andric   case WebAssembly::COPY_I64:
61*b5893f02SDimitry Andric   case WebAssembly::COPY_I64_S:
62d88c1a5aSDimitry Andric   case WebAssembly::COPY_F32:
63*b5893f02SDimitry Andric   case WebAssembly::COPY_F32_S:
64d88c1a5aSDimitry Andric   case WebAssembly::COPY_F64:
65*b5893f02SDimitry Andric   case WebAssembly::COPY_F64_S:
66*b5893f02SDimitry Andric   case WebAssembly::COPY_V128:
67*b5893f02SDimitry Andric   case WebAssembly::COPY_V128_S:
68d88c1a5aSDimitry Andric     return true;
69d88c1a5aSDimitry Andric   default:
70d88c1a5aSDimitry Andric     return false;
71d88c1a5aSDimitry Andric   }
72d88c1a5aSDimitry Andric }
73d88c1a5aSDimitry Andric 
isTee(const MachineInstr & MI)74d88c1a5aSDimitry Andric bool WebAssembly::isTee(const MachineInstr &MI) {
75d88c1a5aSDimitry Andric   switch (MI.getOpcode()) {
76d88c1a5aSDimitry Andric   case WebAssembly::TEE_I32:
77*b5893f02SDimitry Andric   case WebAssembly::TEE_I32_S:
78d88c1a5aSDimitry Andric   case WebAssembly::TEE_I64:
79*b5893f02SDimitry Andric   case WebAssembly::TEE_I64_S:
80d88c1a5aSDimitry Andric   case WebAssembly::TEE_F32:
81*b5893f02SDimitry Andric   case WebAssembly::TEE_F32_S:
82d88c1a5aSDimitry Andric   case WebAssembly::TEE_F64:
83*b5893f02SDimitry Andric   case WebAssembly::TEE_F64_S:
84*b5893f02SDimitry Andric   case WebAssembly::TEE_V128:
85*b5893f02SDimitry Andric   case WebAssembly::TEE_V128_S:
86d88c1a5aSDimitry Andric     return true;
87d88c1a5aSDimitry Andric   default:
88d88c1a5aSDimitry Andric     return false;
89d88c1a5aSDimitry Andric   }
90d88c1a5aSDimitry Andric }
91d88c1a5aSDimitry Andric 
92d88c1a5aSDimitry Andric /// Test whether MI is a child of some other node in an expression tree.
isChild(const MachineInstr & MI,const WebAssemblyFunctionInfo & MFI)93d88c1a5aSDimitry Andric bool WebAssembly::isChild(const MachineInstr &MI,
94d88c1a5aSDimitry Andric                           const WebAssemblyFunctionInfo &MFI) {
95d88c1a5aSDimitry Andric   if (MI.getNumOperands() == 0)
96d88c1a5aSDimitry Andric     return false;
97d88c1a5aSDimitry Andric   const MachineOperand &MO = MI.getOperand(0);
98d88c1a5aSDimitry Andric   if (!MO.isReg() || MO.isImplicit() || !MO.isDef())
99d88c1a5aSDimitry Andric     return false;
100d88c1a5aSDimitry Andric   unsigned Reg = MO.getReg();
101d88c1a5aSDimitry Andric   return TargetRegisterInfo::isVirtualRegister(Reg) &&
102d88c1a5aSDimitry Andric          MFI.isVRegStackified(Reg);
103d88c1a5aSDimitry Andric }
1047a7e6055SDimitry Andric 
isCallDirect(const MachineInstr & MI)1054ba319b5SDimitry Andric bool WebAssembly::isCallDirect(const MachineInstr &MI) {
1064ba319b5SDimitry Andric   switch (MI.getOpcode()) {
1074ba319b5SDimitry Andric   case WebAssembly::CALL_VOID:
108*b5893f02SDimitry Andric   case WebAssembly::CALL_VOID_S:
1094ba319b5SDimitry Andric   case WebAssembly::CALL_I32:
110*b5893f02SDimitry Andric   case WebAssembly::CALL_I32_S:
1114ba319b5SDimitry Andric   case WebAssembly::CALL_I64:
112*b5893f02SDimitry Andric   case WebAssembly::CALL_I64_S:
1134ba319b5SDimitry Andric   case WebAssembly::CALL_F32:
114*b5893f02SDimitry Andric   case WebAssembly::CALL_F32_S:
1154ba319b5SDimitry Andric   case WebAssembly::CALL_F64:
116*b5893f02SDimitry Andric   case WebAssembly::CALL_F64_S:
1174ba319b5SDimitry Andric   case WebAssembly::CALL_v16i8:
118*b5893f02SDimitry Andric   case WebAssembly::CALL_v16i8_S:
1194ba319b5SDimitry Andric   case WebAssembly::CALL_v8i16:
120*b5893f02SDimitry Andric   case WebAssembly::CALL_v8i16_S:
1214ba319b5SDimitry Andric   case WebAssembly::CALL_v4i32:
122*b5893f02SDimitry Andric   case WebAssembly::CALL_v4i32_S:
123*b5893f02SDimitry Andric   case WebAssembly::CALL_v2i64:
124*b5893f02SDimitry Andric   case WebAssembly::CALL_v2i64_S:
1254ba319b5SDimitry Andric   case WebAssembly::CALL_v4f32:
126*b5893f02SDimitry Andric   case WebAssembly::CALL_v4f32_S:
127*b5893f02SDimitry Andric   case WebAssembly::CALL_v2f64:
128*b5893f02SDimitry Andric   case WebAssembly::CALL_v2f64_S:
1294ba319b5SDimitry Andric   case WebAssembly::CALL_EXCEPT_REF:
130*b5893f02SDimitry Andric   case WebAssembly::CALL_EXCEPT_REF_S:
1314ba319b5SDimitry Andric     return true;
1324ba319b5SDimitry Andric   default:
1334ba319b5SDimitry Andric     return false;
1344ba319b5SDimitry Andric   }
1354ba319b5SDimitry Andric }
1364ba319b5SDimitry Andric 
isCallIndirect(const MachineInstr & MI)1377a7e6055SDimitry Andric bool WebAssembly::isCallIndirect(const MachineInstr &MI) {
1387a7e6055SDimitry Andric   switch (MI.getOpcode()) {
1397a7e6055SDimitry Andric   case WebAssembly::CALL_INDIRECT_VOID:
140*b5893f02SDimitry Andric   case WebAssembly::CALL_INDIRECT_VOID_S:
1417a7e6055SDimitry Andric   case WebAssembly::CALL_INDIRECT_I32:
142*b5893f02SDimitry Andric   case WebAssembly::CALL_INDIRECT_I32_S:
1437a7e6055SDimitry Andric   case WebAssembly::CALL_INDIRECT_I64:
144*b5893f02SDimitry Andric   case WebAssembly::CALL_INDIRECT_I64_S:
1457a7e6055SDimitry Andric   case WebAssembly::CALL_INDIRECT_F32:
146*b5893f02SDimitry Andric   case WebAssembly::CALL_INDIRECT_F32_S:
1477a7e6055SDimitry Andric   case WebAssembly::CALL_INDIRECT_F64:
148*b5893f02SDimitry Andric   case WebAssembly::CALL_INDIRECT_F64_S:
1497a7e6055SDimitry Andric   case WebAssembly::CALL_INDIRECT_v16i8:
150*b5893f02SDimitry Andric   case WebAssembly::CALL_INDIRECT_v16i8_S:
1517a7e6055SDimitry Andric   case WebAssembly::CALL_INDIRECT_v8i16:
152*b5893f02SDimitry Andric   case WebAssembly::CALL_INDIRECT_v8i16_S:
1537a7e6055SDimitry Andric   case WebAssembly::CALL_INDIRECT_v4i32:
154*b5893f02SDimitry Andric   case WebAssembly::CALL_INDIRECT_v4i32_S:
155*b5893f02SDimitry Andric   case WebAssembly::CALL_INDIRECT_v2i64:
156*b5893f02SDimitry Andric   case WebAssembly::CALL_INDIRECT_v2i64_S:
1577a7e6055SDimitry Andric   case WebAssembly::CALL_INDIRECT_v4f32:
158*b5893f02SDimitry Andric   case WebAssembly::CALL_INDIRECT_v4f32_S:
159*b5893f02SDimitry Andric   case WebAssembly::CALL_INDIRECT_v2f64:
160*b5893f02SDimitry Andric   case WebAssembly::CALL_INDIRECT_v2f64_S:
1614ba319b5SDimitry Andric   case WebAssembly::CALL_INDIRECT_EXCEPT_REF:
162*b5893f02SDimitry Andric   case WebAssembly::CALL_INDIRECT_EXCEPT_REF_S:
1637a7e6055SDimitry Andric     return true;
1647a7e6055SDimitry Andric   default:
1657a7e6055SDimitry Andric     return false;
1667a7e6055SDimitry Andric   }
1677a7e6055SDimitry Andric }
1687a7e6055SDimitry Andric 
getCalleeOpNo(const MachineInstr & MI)1694ba319b5SDimitry Andric unsigned WebAssembly::getCalleeOpNo(const MachineInstr &MI) {
1704ba319b5SDimitry Andric   switch (MI.getOpcode()) {
1714ba319b5SDimitry Andric   case WebAssembly::CALL_VOID:
172*b5893f02SDimitry Andric   case WebAssembly::CALL_VOID_S:
1734ba319b5SDimitry Andric   case WebAssembly::CALL_INDIRECT_VOID:
174*b5893f02SDimitry Andric   case WebAssembly::CALL_INDIRECT_VOID_S:
1754ba319b5SDimitry Andric     return 0;
1764ba319b5SDimitry Andric   case WebAssembly::CALL_I32:
177*b5893f02SDimitry Andric   case WebAssembly::CALL_I32_S:
1784ba319b5SDimitry Andric   case WebAssembly::CALL_I64:
179*b5893f02SDimitry Andric   case WebAssembly::CALL_I64_S:
1804ba319b5SDimitry Andric   case WebAssembly::CALL_F32:
181*b5893f02SDimitry Andric   case WebAssembly::CALL_F32_S:
1824ba319b5SDimitry Andric   case WebAssembly::CALL_F64:
183*b5893f02SDimitry Andric   case WebAssembly::CALL_F64_S:
184*b5893f02SDimitry Andric   case WebAssembly::CALL_v16i8:
185*b5893f02SDimitry Andric   case WebAssembly::CALL_v16i8_S:
186*b5893f02SDimitry Andric   case WebAssembly::CALL_v8i16:
187*b5893f02SDimitry Andric   case WebAssembly::CALL_v8i16_S:
188*b5893f02SDimitry Andric   case WebAssembly::CALL_v4i32:
189*b5893f02SDimitry Andric   case WebAssembly::CALL_v4i32_S:
190*b5893f02SDimitry Andric   case WebAssembly::CALL_v2i64:
191*b5893f02SDimitry Andric   case WebAssembly::CALL_v2i64_S:
192*b5893f02SDimitry Andric   case WebAssembly::CALL_v4f32:
193*b5893f02SDimitry Andric   case WebAssembly::CALL_v4f32_S:
194*b5893f02SDimitry Andric   case WebAssembly::CALL_v2f64:
195*b5893f02SDimitry Andric   case WebAssembly::CALL_v2f64_S:
1964ba319b5SDimitry Andric   case WebAssembly::CALL_EXCEPT_REF:
197*b5893f02SDimitry Andric   case WebAssembly::CALL_EXCEPT_REF_S:
1984ba319b5SDimitry Andric   case WebAssembly::CALL_INDIRECT_I32:
199*b5893f02SDimitry Andric   case WebAssembly::CALL_INDIRECT_I32_S:
2004ba319b5SDimitry Andric   case WebAssembly::CALL_INDIRECT_I64:
201*b5893f02SDimitry Andric   case WebAssembly::CALL_INDIRECT_I64_S:
2024ba319b5SDimitry Andric   case WebAssembly::CALL_INDIRECT_F32:
203*b5893f02SDimitry Andric   case WebAssembly::CALL_INDIRECT_F32_S:
2044ba319b5SDimitry Andric   case WebAssembly::CALL_INDIRECT_F64:
205*b5893f02SDimitry Andric   case WebAssembly::CALL_INDIRECT_F64_S:
206*b5893f02SDimitry Andric   case WebAssembly::CALL_INDIRECT_v16i8:
207*b5893f02SDimitry Andric   case WebAssembly::CALL_INDIRECT_v16i8_S:
208*b5893f02SDimitry Andric   case WebAssembly::CALL_INDIRECT_v8i16:
209*b5893f02SDimitry Andric   case WebAssembly::CALL_INDIRECT_v8i16_S:
210*b5893f02SDimitry Andric   case WebAssembly::CALL_INDIRECT_v4i32:
211*b5893f02SDimitry Andric   case WebAssembly::CALL_INDIRECT_v4i32_S:
212*b5893f02SDimitry Andric   case WebAssembly::CALL_INDIRECT_v2i64:
213*b5893f02SDimitry Andric   case WebAssembly::CALL_INDIRECT_v2i64_S:
214*b5893f02SDimitry Andric   case WebAssembly::CALL_INDIRECT_v4f32:
215*b5893f02SDimitry Andric   case WebAssembly::CALL_INDIRECT_v4f32_S:
216*b5893f02SDimitry Andric   case WebAssembly::CALL_INDIRECT_v2f64:
217*b5893f02SDimitry Andric   case WebAssembly::CALL_INDIRECT_v2f64_S:
2184ba319b5SDimitry Andric   case WebAssembly::CALL_INDIRECT_EXCEPT_REF:
219*b5893f02SDimitry Andric   case WebAssembly::CALL_INDIRECT_EXCEPT_REF_S:
2204ba319b5SDimitry Andric     return 1;
2214ba319b5SDimitry Andric   default:
2224ba319b5SDimitry Andric     llvm_unreachable("Not a call instruction");
2234ba319b5SDimitry Andric   }
2244ba319b5SDimitry Andric }
2254ba319b5SDimitry Andric 
isMarker(const MachineInstr & MI)2264ba319b5SDimitry Andric bool WebAssembly::isMarker(const MachineInstr &MI) {
2274ba319b5SDimitry Andric   switch (MI.getOpcode()) {
2284ba319b5SDimitry Andric   case WebAssembly::BLOCK:
229*b5893f02SDimitry Andric   case WebAssembly::BLOCK_S:
2304ba319b5SDimitry Andric   case WebAssembly::END_BLOCK:
231*b5893f02SDimitry Andric   case WebAssembly::END_BLOCK_S:
2324ba319b5SDimitry Andric   case WebAssembly::LOOP:
233*b5893f02SDimitry Andric   case WebAssembly::LOOP_S:
2344ba319b5SDimitry Andric   case WebAssembly::END_LOOP:
235*b5893f02SDimitry Andric   case WebAssembly::END_LOOP_S:
2364ba319b5SDimitry Andric   case WebAssembly::TRY:
237*b5893f02SDimitry Andric   case WebAssembly::TRY_S:
2384ba319b5SDimitry Andric   case WebAssembly::END_TRY:
239*b5893f02SDimitry Andric   case WebAssembly::END_TRY_S:
2404ba319b5SDimitry Andric     return true;
2414ba319b5SDimitry Andric   default:
2424ba319b5SDimitry Andric     return false;
2434ba319b5SDimitry Andric   }
2444ba319b5SDimitry Andric }
2454ba319b5SDimitry Andric 
isThrow(const MachineInstr & MI)2464ba319b5SDimitry Andric bool WebAssembly::isThrow(const MachineInstr &MI) {
2474ba319b5SDimitry Andric   switch (MI.getOpcode()) {
2484ba319b5SDimitry Andric   case WebAssembly::THROW_I32:
249*b5893f02SDimitry Andric   case WebAssembly::THROW_I32_S:
2504ba319b5SDimitry Andric   case WebAssembly::THROW_I64:
251*b5893f02SDimitry Andric   case WebAssembly::THROW_I64_S:
2524ba319b5SDimitry Andric     return true;
2534ba319b5SDimitry Andric   default:
2544ba319b5SDimitry Andric     return false;
2554ba319b5SDimitry Andric   }
2564ba319b5SDimitry Andric }
2574ba319b5SDimitry Andric 
isRethrow(const MachineInstr & MI)2584ba319b5SDimitry Andric bool WebAssembly::isRethrow(const MachineInstr &MI) {
2594ba319b5SDimitry Andric   switch (MI.getOpcode()) {
2604ba319b5SDimitry Andric   case WebAssembly::RETHROW:
261*b5893f02SDimitry Andric   case WebAssembly::RETHROW_S:
2624ba319b5SDimitry Andric   case WebAssembly::RETHROW_TO_CALLER:
263*b5893f02SDimitry Andric   case WebAssembly::RETHROW_TO_CALLER_S:
2644ba319b5SDimitry Andric     return true;
2654ba319b5SDimitry Andric   default:
2664ba319b5SDimitry Andric     return false;
2674ba319b5SDimitry Andric   }
2684ba319b5SDimitry Andric }
2694ba319b5SDimitry Andric 
isCatch(const MachineInstr & MI)2704ba319b5SDimitry Andric bool WebAssembly::isCatch(const MachineInstr &MI) {
2714ba319b5SDimitry Andric   switch (MI.getOpcode()) {
2724ba319b5SDimitry Andric   case WebAssembly::CATCH_I32:
273*b5893f02SDimitry Andric   case WebAssembly::CATCH_I32_S:
2744ba319b5SDimitry Andric   case WebAssembly::CATCH_I64:
275*b5893f02SDimitry Andric   case WebAssembly::CATCH_I64_S:
2764ba319b5SDimitry Andric   case WebAssembly::CATCH_ALL:
277*b5893f02SDimitry Andric   case WebAssembly::CATCH_ALL_S:
2784ba319b5SDimitry Andric     return true;
2794ba319b5SDimitry Andric   default:
2804ba319b5SDimitry Andric     return false;
2814ba319b5SDimitry Andric   }
2824ba319b5SDimitry Andric }
2834ba319b5SDimitry Andric 
mayThrow(const MachineInstr & MI)2844ba319b5SDimitry Andric bool WebAssembly::mayThrow(const MachineInstr &MI) {
2854ba319b5SDimitry Andric   switch (MI.getOpcode()) {
2864ba319b5SDimitry Andric   case WebAssembly::THROW_I32:
287*b5893f02SDimitry Andric   case WebAssembly::THROW_I32_S:
2884ba319b5SDimitry Andric   case WebAssembly::THROW_I64:
289*b5893f02SDimitry Andric   case WebAssembly::THROW_I64_S:
2904ba319b5SDimitry Andric   case WebAssembly::RETHROW:
291*b5893f02SDimitry Andric   case WebAssembly::RETHROW_S:
2924ba319b5SDimitry Andric     return true;
2934ba319b5SDimitry Andric   }
2944ba319b5SDimitry Andric   if (isCallIndirect(MI))
2954ba319b5SDimitry Andric     return true;
2964ba319b5SDimitry Andric   if (!MI.isCall())
2974ba319b5SDimitry Andric     return false;
2984ba319b5SDimitry Andric 
2994ba319b5SDimitry Andric   const MachineOperand &MO = MI.getOperand(getCalleeOpNo(MI));
3004ba319b5SDimitry Andric   assert(MO.isGlobal());
3014ba319b5SDimitry Andric   const auto *F = dyn_cast<Function>(MO.getGlobal());
3024ba319b5SDimitry Andric   if (!F)
3034ba319b5SDimitry Andric     return true;
3044ba319b5SDimitry Andric   if (F->doesNotThrow())
3054ba319b5SDimitry Andric     return false;
3064ba319b5SDimitry Andric   // These functions never throw
3074ba319b5SDimitry Andric   if (F->getName() == CxaBeginCatchFn || F->getName() == PersonalityWrapperFn ||
3084ba319b5SDimitry Andric       F->getName() == ClangCallTerminateFn || F->getName() == StdTerminateFn)
3094ba319b5SDimitry Andric     return false;
3104ba319b5SDimitry Andric   return true;
3114ba319b5SDimitry Andric }
3124ba319b5SDimitry Andric 
isCatchTerminatePad(const MachineBasicBlock & MBB)3134ba319b5SDimitry Andric bool WebAssembly::isCatchTerminatePad(const MachineBasicBlock &MBB) {
3144ba319b5SDimitry Andric   if (!MBB.isEHPad())
3154ba319b5SDimitry Andric     return false;
3164ba319b5SDimitry Andric   bool SeenCatch = false;
3174ba319b5SDimitry Andric   for (auto &MI : MBB) {
3184ba319b5SDimitry Andric     if (MI.getOpcode() == WebAssembly::CATCH_I32 ||
319*b5893f02SDimitry Andric         MI.getOpcode() == WebAssembly::CATCH_I64 ||
320*b5893f02SDimitry Andric         MI.getOpcode() == WebAssembly::CATCH_I32_S ||
321*b5893f02SDimitry Andric         MI.getOpcode() == WebAssembly::CATCH_I64_S)
3224ba319b5SDimitry Andric       SeenCatch = true;
3234ba319b5SDimitry Andric     if (SeenCatch && MI.isCall()) {
3244ba319b5SDimitry Andric       const MachineOperand &CalleeOp = MI.getOperand(getCalleeOpNo(MI));
3254ba319b5SDimitry Andric       if (CalleeOp.isGlobal() &&
3264ba319b5SDimitry Andric           CalleeOp.getGlobal()->getName() == ClangCallTerminateFn)
3274ba319b5SDimitry Andric         return true;
3284ba319b5SDimitry Andric     }
3294ba319b5SDimitry Andric   }
3304ba319b5SDimitry Andric   return false;
3314ba319b5SDimitry Andric }
3324ba319b5SDimitry Andric 
isCatchAllTerminatePad(const MachineBasicBlock & MBB)3334ba319b5SDimitry Andric bool WebAssembly::isCatchAllTerminatePad(const MachineBasicBlock &MBB) {
3344ba319b5SDimitry Andric   if (!MBB.isEHPad())
3354ba319b5SDimitry Andric     return false;
3364ba319b5SDimitry Andric   bool SeenCatchAll = false;
3374ba319b5SDimitry Andric   for (auto &MI : MBB) {
338*b5893f02SDimitry Andric     if (MI.getOpcode() == WebAssembly::CATCH_ALL ||
339*b5893f02SDimitry Andric         MI.getOpcode() == WebAssembly::CATCH_ALL_S)
3404ba319b5SDimitry Andric       SeenCatchAll = true;
3414ba319b5SDimitry Andric     if (SeenCatchAll && MI.isCall()) {
3424ba319b5SDimitry Andric       const MachineOperand &CalleeOp = MI.getOperand(getCalleeOpNo(MI));
3434ba319b5SDimitry Andric       if (CalleeOp.isGlobal() &&
3444ba319b5SDimitry Andric           CalleeOp.getGlobal()->getName() == StdTerminateFn)
3454ba319b5SDimitry Andric         return true;
3464ba319b5SDimitry Andric     }
3474ba319b5SDimitry Andric   }
3484ba319b5SDimitry Andric   return false;
3497a7e6055SDimitry Andric }
350