blob: e9d88d4818a58e986abbc432786e37912e4afe1b [file] [log] [blame]
Dan Gohman4fc4e422016-10-24 19:49:43 +00001//===-- WebAssemblyUtilities.cpp - WebAssembly Utility Functions ----------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Dan Gohman4fc4e422016-10-24 19:49:43 +00006//
7//===----------------------------------------------------------------------===//
8///
9/// \file
Adrian Prantl5f8f34e42018-05-01 15:54:18 +000010/// This file implements several utility functions for WebAssembly.
Dan Gohman4fc4e422016-10-24 19:49:43 +000011///
12//===----------------------------------------------------------------------===//
13
14#include "WebAssemblyUtilities.h"
15#include "WebAssemblyMachineFunctionInfo.h"
16#include "llvm/CodeGen/MachineInstr.h"
Dan Gohmanf52ee172017-02-27 22:38:58 +000017#include "llvm/CodeGen/MachineLoopInfo.h"
Dan Gohman4fc4e422016-10-24 19:49:43 +000018using namespace llvm;
19
Heejin Ahn817811ca2018-06-19 00:32:03 +000020const char *const WebAssembly::ClangCallTerminateFn = "__clang_call_terminate";
21const char *const WebAssembly::CxaBeginCatchFn = "__cxa_begin_catch";
22const char *const WebAssembly::CxaRethrowFn = "__cxa_rethrow";
23const char *const WebAssembly::StdTerminateFn = "_ZSt9terminatev";
24const char *const WebAssembly::PersonalityWrapperFn =
25 "_Unwind_Wasm_CallPersonality";
26
Dan Gohman4fc4e422016-10-24 19:49:43 +000027/// Test whether MI is a child of some other node in an expression tree.
28bool 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}
Dan Gohmand934cb82017-02-24 23:18:00 +000039
Heejin Ahn817811ca2018-06-19 00:32:03 +000040bool WebAssembly::mayThrow(const MachineInstr &MI) {
41 switch (MI.getOpcode()) {
Heejin Ahnd6f48782019-01-30 03:21:57 +000042 case WebAssembly::THROW:
43 case WebAssembly::THROW_S:
Heejin Ahn817811ca2018-06-19 00:32:03 +000044 case WebAssembly::RETHROW:
Wouter van Oortmerssen8a9cb242018-08-27 15:45:51 +000045 case WebAssembly::RETHROW_S:
Heejin Ahn817811ca2018-06-19 00:32:03 +000046 return true;
47 }
Wouter van Oortmerssend8ddf832019-07-12 22:08:25 +000048 if (isCallIndirect(MI.getOpcode()))
Heejin Ahn817811ca2018-06-19 00:32:03 +000049 return true;
50 if (!MI.isCall())
51 return false;
52
Wouter van Oortmerssend8ddf832019-07-12 22:08:25 +000053 const MachineOperand &MO = MI.getOperand(getCalleeOpNo(MI.getOpcode()));
Heejin Ahn817811ca2018-06-19 00:32:03 +000054 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;
Heejin Ahnc4ac74f2019-03-30 11:04:48 +000064
65 // TODO Can we exclude call instructions that are marked as 'nounwind' in the
66 // original LLVm IR? (Even when the callee may throw)
Heejin Ahn817811ca2018-06-19 00:32:03 +000067 return true;
68}