LLVM  7.0.0svn
WebAssemblyUtilities.cpp
Go to the documentation of this file.
1 //===-- WebAssemblyUtilities.cpp - WebAssembly Utility Functions ----------===//
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 /// This file implements several utility functions for WebAssembly.
12 ///
13 //===----------------------------------------------------------------------===//
14 
15 #include "WebAssemblyUtilities.h"
19 using namespace llvm;
20 
21 const char *const WebAssembly::ClangCallTerminateFn = "__clang_call_terminate";
22 const char *const WebAssembly::CxaBeginCatchFn = "__cxa_begin_catch";
23 const char *const WebAssembly::CxaRethrowFn = "__cxa_rethrow";
24 const char *const WebAssembly::StdTerminateFn = "_ZSt9terminatev";
26  "_Unwind_Wasm_CallPersonality";
27 
29  switch (MI.getOpcode()) {
30  case WebAssembly::ARGUMENT_I32:
31  case WebAssembly::ARGUMENT_I64:
32  case WebAssembly::ARGUMENT_F32:
33  case WebAssembly::ARGUMENT_F64:
34  case WebAssembly::ARGUMENT_v16i8:
35  case WebAssembly::ARGUMENT_v8i16:
36  case WebAssembly::ARGUMENT_v4i32:
37  case WebAssembly::ARGUMENT_v4f32:
38  return true;
39  default:
40  return false;
41  }
42 }
43 
45  switch (MI.getOpcode()) {
46  case WebAssembly::COPY_I32:
47  case WebAssembly::COPY_I64:
48  case WebAssembly::COPY_F32:
49  case WebAssembly::COPY_F64:
50  return true;
51  default:
52  return false;
53  }
54 }
55 
57  switch (MI.getOpcode()) {
58  case WebAssembly::TEE_I32:
59  case WebAssembly::TEE_I64:
60  case WebAssembly::TEE_F32:
61  case WebAssembly::TEE_F64:
62  return true;
63  default:
64  return false;
65  }
66 }
67 
68 /// Test whether MI is a child of some other node in an expression tree.
70  const WebAssemblyFunctionInfo &MFI) {
71  if (MI.getNumOperands() == 0)
72  return false;
73  const MachineOperand &MO = MI.getOperand(0);
74  if (!MO.isReg() || MO.isImplicit() || !MO.isDef())
75  return false;
76  unsigned Reg = MO.getReg();
78  MFI.isVRegStackified(Reg);
79 }
80 
82  switch (MI.getOpcode()) {
83  case WebAssembly::CALL_VOID:
84  case WebAssembly::CALL_I32:
85  case WebAssembly::CALL_I64:
86  case WebAssembly::CALL_F32:
87  case WebAssembly::CALL_F64:
88  case WebAssembly::CALL_v16i8:
89  case WebAssembly::CALL_v8i16:
90  case WebAssembly::CALL_v4i32:
91  case WebAssembly::CALL_v4f32:
92  case WebAssembly::CALL_EXCEPT_REF:
93  return true;
94  default:
95  return false;
96  }
97 }
98 
100  switch (MI.getOpcode()) {
101  case WebAssembly::CALL_INDIRECT_VOID:
102  case WebAssembly::CALL_INDIRECT_I32:
103  case WebAssembly::CALL_INDIRECT_I64:
104  case WebAssembly::CALL_INDIRECT_F32:
105  case WebAssembly::CALL_INDIRECT_F64:
106  case WebAssembly::CALL_INDIRECT_v16i8:
107  case WebAssembly::CALL_INDIRECT_v8i16:
108  case WebAssembly::CALL_INDIRECT_v4i32:
109  case WebAssembly::CALL_INDIRECT_v4f32:
110  case WebAssembly::CALL_INDIRECT_EXCEPT_REF:
111  return true;
112  default:
113  return false;
114  }
115 }
116 
118  switch (MI.getOpcode()) {
119  case WebAssembly::CALL_VOID:
120  case WebAssembly::CALL_INDIRECT_VOID:
121  return 0;
122  case WebAssembly::CALL_I32:
123  case WebAssembly::CALL_I64:
124  case WebAssembly::CALL_F32:
125  case WebAssembly::CALL_F64:
126  case WebAssembly::CALL_EXCEPT_REF:
127  case WebAssembly::CALL_INDIRECT_I32:
128  case WebAssembly::CALL_INDIRECT_I64:
129  case WebAssembly::CALL_INDIRECT_F32:
130  case WebAssembly::CALL_INDIRECT_F64:
131  case WebAssembly::CALL_INDIRECT_EXCEPT_REF:
132  return 1;
133  default:
134  llvm_unreachable("Not a call instruction");
135  }
136 }
137 
139  switch (MI.getOpcode()) {
140  case WebAssembly::BLOCK:
142  case WebAssembly::LOOP:
143  case WebAssembly::END_LOOP:
144  case WebAssembly::TRY:
145  case WebAssembly::END_TRY:
146  return true;
147  default:
148  return false;
149  }
150 }
151 
153  switch (MI.getOpcode()) {
154  case WebAssembly::THROW_I32:
155  case WebAssembly::THROW_I64:
156  return true;
157  default:
158  return false;
159  }
160 }
161 
163  switch (MI.getOpcode()) {
164  case WebAssembly::RETHROW:
165  case WebAssembly::RETHROW_TO_CALLER:
166  return true;
167  default:
168  return false;
169  }
170 }
171 
173  switch (MI.getOpcode()) {
174  case WebAssembly::CATCH_I32:
175  case WebAssembly::CATCH_I64:
176  case WebAssembly::CATCH_ALL:
177  return true;
178  default:
179  return false;
180  }
181 }
182 
184  switch (MI.getOpcode()) {
185  case WebAssembly::THROW_I32:
186  case WebAssembly::THROW_I64:
187  case WebAssembly::RETHROW:
188  return true;
189  }
190  if (isCallIndirect(MI))
191  return true;
192  if (!MI.isCall())
193  return false;
194 
195  const MachineOperand &MO = MI.getOperand(getCalleeOpNo(MI));
196  assert(MO.isGlobal());
197  const auto *F = dyn_cast<Function>(MO.getGlobal());
198  if (!F)
199  return true;
200  if (F->doesNotThrow())
201  return false;
202  // These functions never throw
203  if (F->getName() == CxaBeginCatchFn || F->getName() == PersonalityWrapperFn ||
204  F->getName() == ClangCallTerminateFn || F->getName() == StdTerminateFn)
205  return false;
206  return true;
207 }
208 
210  if (!MBB.isEHPad())
211  return false;
212  bool SeenCatch = false;
213  for (auto &MI : MBB) {
214  if (MI.getOpcode() == WebAssembly::CATCH_I32 ||
215  MI.getOpcode() == WebAssembly::CATCH_I64)
216  SeenCatch = true;
217  if (SeenCatch && MI.isCall()) {
218  const MachineOperand &CalleeOp = MI.getOperand(getCalleeOpNo(MI));
219  if (CalleeOp.isGlobal() &&
220  CalleeOp.getGlobal()->getName() == ClangCallTerminateFn)
221  return true;
222  }
223  }
224  return false;
225 }
226 
228  if (!MBB.isEHPad())
229  return false;
230  bool SeenCatchAll = false;
231  for (auto &MI : MBB) {
232  if (MI.getOpcode() == WebAssembly::CATCH_ALL)
233  SeenCatchAll = true;
234  if (SeenCatchAll && MI.isCall()) {
235  const MachineOperand &CalleeOp = MI.getOperand(getCalleeOpNo(MI));
236  if (CalleeOp.isGlobal() &&
237  CalleeOp.getGlobal()->getName() == StdTerminateFn)
238  return true;
239  }
240  }
241  return false;
242 }
bool isCall(QueryType Type=AnyInBundle) const
Definition: MachineInstr.h:485
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
bool mayThrow(const MachineInstr &MI)
unsigned getReg() const
getReg - Returns the register number.
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
unsigned Reg
F(f)
unsigned getNumOperands() const
Access to explicit operands of the instruction.
Definition: MachineInstr.h:314
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:311
const char *const CxaBeginCatchFn
const char *const StdTerminateFn
bool isThrow(const MachineInstr &MI)
bool isCopy(const MachineInstr &MI)
This file contains the declaration of the WebAssembly-specific utility functions. ...
bool isCallDirect(const MachineInstr &MI)
const GlobalValue * getGlobal() const
const char *const CxaRethrowFn
bool isRethrow(const MachineInstr &MI)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool isTee(const MachineInstr &MI)
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
const char *const ClangCallTerminateFn
bool isArgument(const MachineInstr &MI)
MachineOperand class - Representation of each machine instruction operand.
bool isCatchTerminatePad(const MachineBasicBlock &MBB)
Returns if the given BB is a single BB terminate pad which starts with a &#39;catch&#39; instruction.
const char *const PersonalityWrapperFn
Representation of each machine instruction.
Definition: MachineInstr.h:60
This class is derived from MachineFunctionInfo and contains private WebAssembly-specific information ...
bool isEHPad() const
Returns true if the block is a landing pad.
unsigned getCalleeOpNo(const MachineInstr &MI)
Returns the operand number of a callee, assuming the argument is a call instruction.
StringRef getName() const
Return a constant reference to the value&#39;s name.
Definition: Value.cpp:224
bool isMarker(const MachineInstr &MI)
This file declares WebAssembly-specific per-machine-function information.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:323
bool isCatch(const MachineInstr &MI)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
IRTranslator LLVM IR MI
bool isCallIndirect(const MachineInstr &MI)
bool isChild(const MachineInstr &MI, const WebAssemblyFunctionInfo &MFI)
Test whether MI is a child of some other node in an expression tree.
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:316
bool isImplicit() const
bool isCatchAllTerminatePad(const MachineBasicBlock &MBB)
Returns if the given BB is a single BB terminate pad which starts with a &#39;catch_all&#39; insrtruction...