1 //===-- WebAssemblyUtilities.cpp - WebAssembly Utility Functions ----------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// 9 /// \file 10 /// This file implements several utility functions for WebAssembly. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #include "WebAssemblyUtilities.h" 15 #include "WebAssemblyMachineFunctionInfo.h" 16 #include "llvm/CodeGen/MachineInstr.h" 17 #include "llvm/CodeGen/MachineLoopInfo.h" 18 using namespace llvm; 19 20 const char *const WebAssembly::ClangCallTerminateFn = "__clang_call_terminate"; 21 const char *const WebAssembly::CxaBeginCatchFn = "__cxa_begin_catch"; 22 const char *const WebAssembly::CxaRethrowFn = "__cxa_rethrow"; 23 const char *const WebAssembly::StdTerminateFn = "_ZSt9terminatev"; 24 const char *const WebAssembly::PersonalityWrapperFn = 25 "_Unwind_Wasm_CallPersonality"; 26 27 /// Test whether MI is a child of some other node in an expression tree. 28 bool WebAssembly::isChild(const MachineInstr &MI, 29 const WebAssemblyFunctionInfo &MFI) { 30 if (MI.getNumOperands() == 0) 31 return false; 32 const MachineOperand &MO = MI.getOperand(0); 33 if (!MO.isReg() || MO.isImplicit() || !MO.isDef()) 34 return false; 35 unsigned Reg = MO.getReg(); 36 return TargetRegisterInfo::isVirtualRegister(Reg) && 37 MFI.isVRegStackified(Reg); 38 } 39 40 bool WebAssembly::mayThrow(const MachineInstr &MI) { 41 switch (MI.getOpcode()) { 42 case WebAssembly::THROW: 43 case WebAssembly::THROW_S: 44 case WebAssembly::RETHROW: 45 case WebAssembly::RETHROW_S: 46 return true; 47 } 48 if (isCallIndirect(MI.getOpcode())) 49 return true; 50 if (!MI.isCall()) 51 return false; 52 53 const MachineOperand &MO = MI.getOperand(getCalleeOpNo(MI.getOpcode())); 54 assert(MO.isGlobal()); 55 const auto *F = dyn_cast<Function>(MO.getGlobal()); 56 if (!F) 57 return true; 58 if (F->doesNotThrow()) 59 return false; 60 // These functions never throw 61 if (F->getName() == CxaBeginCatchFn || F->getName() == PersonalityWrapperFn || 62 F->getName() == ClangCallTerminateFn || F->getName() == StdTerminateFn) 63 return false; 64 65 // TODO Can we exclude call instructions that are marked as 'nounwind' in the 66 // original LLVm IR? (Even when the callee may throw) 67 return true; 68 } 69