LLVM  9.0.0svn
WebAssemblyUtilities.cpp
Go to the documentation of this file.
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"
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";
25  "_Unwind_Wasm_CallPersonality";
26 
28  switch (MI.getOpcode()) {
29  case WebAssembly::ARGUMENT_i32:
30  case WebAssembly::ARGUMENT_i32_S:
31  case WebAssembly::ARGUMENT_i64:
32  case WebAssembly::ARGUMENT_i64_S:
33  case WebAssembly::ARGUMENT_f32:
34  case WebAssembly::ARGUMENT_f32_S:
35  case WebAssembly::ARGUMENT_f64:
36  case WebAssembly::ARGUMENT_f64_S:
37  case WebAssembly::ARGUMENT_v16i8:
38  case WebAssembly::ARGUMENT_v16i8_S:
39  case WebAssembly::ARGUMENT_v8i16:
40  case WebAssembly::ARGUMENT_v8i16_S:
41  case WebAssembly::ARGUMENT_v4i32:
42  case WebAssembly::ARGUMENT_v4i32_S:
43  case WebAssembly::ARGUMENT_v2i64:
44  case WebAssembly::ARGUMENT_v2i64_S:
45  case WebAssembly::ARGUMENT_v4f32:
46  case WebAssembly::ARGUMENT_v4f32_S:
47  case WebAssembly::ARGUMENT_v2f64:
48  case WebAssembly::ARGUMENT_v2f64_S:
49  return true;
50  default:
51  return false;
52  }
53 }
54 
56  switch (MI.getOpcode()) {
57  case WebAssembly::COPY_I32:
58  case WebAssembly::COPY_I32_S:
59  case WebAssembly::COPY_I64:
60  case WebAssembly::COPY_I64_S:
61  case WebAssembly::COPY_F32:
62  case WebAssembly::COPY_F32_S:
63  case WebAssembly::COPY_F64:
64  case WebAssembly::COPY_F64_S:
65  case WebAssembly::COPY_V128:
66  case WebAssembly::COPY_V128_S:
67  return true;
68  default:
69  return false;
70  }
71 }
72 
74  switch (MI.getOpcode()) {
75  case WebAssembly::TEE_I32:
76  case WebAssembly::TEE_I32_S:
77  case WebAssembly::TEE_I64:
78  case WebAssembly::TEE_I64_S:
79  case WebAssembly::TEE_F32:
80  case WebAssembly::TEE_F32_S:
81  case WebAssembly::TEE_F64:
82  case WebAssembly::TEE_F64_S:
83  case WebAssembly::TEE_V128:
84  case WebAssembly::TEE_V128_S:
85  return true;
86  default:
87  return false;
88  }
89 }
90 
91 /// Test whether MI is a child of some other node in an expression tree.
93  const WebAssemblyFunctionInfo &MFI) {
94  if (MI.getNumOperands() == 0)
95  return false;
96  const MachineOperand &MO = MI.getOperand(0);
97  if (!MO.isReg() || MO.isImplicit() || !MO.isDef())
98  return false;
99  unsigned Reg = MO.getReg();
101  MFI.isVRegStackified(Reg);
102 }
103 
105  switch (MI.getOpcode()) {
106  case WebAssembly::CALL_VOID:
107  case WebAssembly::CALL_VOID_S:
108  case WebAssembly::CALL_I32:
109  case WebAssembly::CALL_I32_S:
110  case WebAssembly::CALL_I64:
111  case WebAssembly::CALL_I64_S:
112  case WebAssembly::CALL_F32:
113  case WebAssembly::CALL_F32_S:
114  case WebAssembly::CALL_F64:
115  case WebAssembly::CALL_F64_S:
116  case WebAssembly::CALL_v16i8:
117  case WebAssembly::CALL_v16i8_S:
118  case WebAssembly::CALL_v8i16:
119  case WebAssembly::CALL_v8i16_S:
120  case WebAssembly::CALL_v4i32:
121  case WebAssembly::CALL_v4i32_S:
122  case WebAssembly::CALL_v2i64:
123  case WebAssembly::CALL_v2i64_S:
124  case WebAssembly::CALL_v4f32:
125  case WebAssembly::CALL_v4f32_S:
126  case WebAssembly::CALL_v2f64:
127  case WebAssembly::CALL_v2f64_S:
128  case WebAssembly::CALL_EXCEPT_REF:
129  case WebAssembly::CALL_EXCEPT_REF_S:
130  return true;
131  default:
132  return false;
133  }
134 }
135 
137  switch (MI.getOpcode()) {
138  case WebAssembly::CALL_INDIRECT_VOID:
139  case WebAssembly::CALL_INDIRECT_VOID_S:
140  case WebAssembly::CALL_INDIRECT_I32:
141  case WebAssembly::CALL_INDIRECT_I32_S:
142  case WebAssembly::CALL_INDIRECT_I64:
143  case WebAssembly::CALL_INDIRECT_I64_S:
144  case WebAssembly::CALL_INDIRECT_F32:
145  case WebAssembly::CALL_INDIRECT_F32_S:
146  case WebAssembly::CALL_INDIRECT_F64:
147  case WebAssembly::CALL_INDIRECT_F64_S:
148  case WebAssembly::CALL_INDIRECT_v16i8:
149  case WebAssembly::CALL_INDIRECT_v16i8_S:
150  case WebAssembly::CALL_INDIRECT_v8i16:
151  case WebAssembly::CALL_INDIRECT_v8i16_S:
152  case WebAssembly::CALL_INDIRECT_v4i32:
153  case WebAssembly::CALL_INDIRECT_v4i32_S:
154  case WebAssembly::CALL_INDIRECT_v2i64:
155  case WebAssembly::CALL_INDIRECT_v2i64_S:
156  case WebAssembly::CALL_INDIRECT_v4f32:
157  case WebAssembly::CALL_INDIRECT_v4f32_S:
158  case WebAssembly::CALL_INDIRECT_v2f64:
159  case WebAssembly::CALL_INDIRECT_v2f64_S:
160  case WebAssembly::CALL_INDIRECT_EXCEPT_REF:
161  case WebAssembly::CALL_INDIRECT_EXCEPT_REF_S:
162  return true;
163  default:
164  return false;
165  }
166 }
167 
169  switch (MI.getOpcode()) {
170  case WebAssembly::CALL_VOID:
171  case WebAssembly::CALL_VOID_S:
172  case WebAssembly::CALL_INDIRECT_VOID:
173  case WebAssembly::CALL_INDIRECT_VOID_S:
174  return 0;
175  case WebAssembly::CALL_I32:
176  case WebAssembly::CALL_I32_S:
177  case WebAssembly::CALL_I64:
178  case WebAssembly::CALL_I64_S:
179  case WebAssembly::CALL_F32:
180  case WebAssembly::CALL_F32_S:
181  case WebAssembly::CALL_F64:
182  case WebAssembly::CALL_F64_S:
183  case WebAssembly::CALL_v16i8:
184  case WebAssembly::CALL_v16i8_S:
185  case WebAssembly::CALL_v8i16:
186  case WebAssembly::CALL_v8i16_S:
187  case WebAssembly::CALL_v4i32:
188  case WebAssembly::CALL_v4i32_S:
189  case WebAssembly::CALL_v2i64:
190  case WebAssembly::CALL_v2i64_S:
191  case WebAssembly::CALL_v4f32:
192  case WebAssembly::CALL_v4f32_S:
193  case WebAssembly::CALL_v2f64:
194  case WebAssembly::CALL_v2f64_S:
195  case WebAssembly::CALL_EXCEPT_REF:
196  case WebAssembly::CALL_EXCEPT_REF_S:
197  case WebAssembly::CALL_INDIRECT_I32:
198  case WebAssembly::CALL_INDIRECT_I32_S:
199  case WebAssembly::CALL_INDIRECT_I64:
200  case WebAssembly::CALL_INDIRECT_I64_S:
201  case WebAssembly::CALL_INDIRECT_F32:
202  case WebAssembly::CALL_INDIRECT_F32_S:
203  case WebAssembly::CALL_INDIRECT_F64:
204  case WebAssembly::CALL_INDIRECT_F64_S:
205  case WebAssembly::CALL_INDIRECT_v16i8:
206  case WebAssembly::CALL_INDIRECT_v16i8_S:
207  case WebAssembly::CALL_INDIRECT_v8i16:
208  case WebAssembly::CALL_INDIRECT_v8i16_S:
209  case WebAssembly::CALL_INDIRECT_v4i32:
210  case WebAssembly::CALL_INDIRECT_v4i32_S:
211  case WebAssembly::CALL_INDIRECT_v2i64:
212  case WebAssembly::CALL_INDIRECT_v2i64_S:
213  case WebAssembly::CALL_INDIRECT_v4f32:
214  case WebAssembly::CALL_INDIRECT_v4f32_S:
215  case WebAssembly::CALL_INDIRECT_v2f64:
216  case WebAssembly::CALL_INDIRECT_v2f64_S:
217  case WebAssembly::CALL_INDIRECT_EXCEPT_REF:
218  case WebAssembly::CALL_INDIRECT_EXCEPT_REF_S:
219  return 1;
220  default:
221  llvm_unreachable("Not a call instruction");
222  }
223 }
224 
226  switch (MI.getOpcode()) {
227  case WebAssembly::BLOCK:
228  case WebAssembly::BLOCK_S:
230  case WebAssembly::END_BLOCK_S:
231  case WebAssembly::LOOP:
232  case WebAssembly::LOOP_S:
233  case WebAssembly::END_LOOP:
234  case WebAssembly::END_LOOP_S:
235  case WebAssembly::TRY:
236  case WebAssembly::TRY_S:
237  case WebAssembly::END_TRY:
238  case WebAssembly::END_TRY_S:
239  return true;
240  default:
241  return false;
242  }
243 }
244 
246  switch (MI.getOpcode()) {
247  case WebAssembly::THROW:
248  case WebAssembly::THROW_S:
249  case WebAssembly::RETHROW:
250  case WebAssembly::RETHROW_S:
251  return true;
252  }
253  if (isCallIndirect(MI))
254  return true;
255  if (!MI.isCall())
256  return false;
257 
258  const MachineOperand &MO = MI.getOperand(getCalleeOpNo(MI));
259  assert(MO.isGlobal());
260  const auto *F = dyn_cast<Function>(MO.getGlobal());
261  if (!F)
262  return true;
263  if (F->doesNotThrow())
264  return false;
265  // These functions never throw
266  if (F->getName() == CxaBeginCatchFn || F->getName() == PersonalityWrapperFn ||
267  F->getName() == ClangCallTerminateFn || F->getName() == StdTerminateFn)
268  return false;
269  return true;
270 }
bool isCall(QueryType Type=AnyInBundle) const
Definition: MachineInstr.h:632
This class represents lattice values for constants.
Definition: AllocatorList.h:23
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
Retuns the total number of operands.
Definition: MachineInstr.h:411
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:408
const char *const CxaBeginCatchFn
const char *const StdTerminateFn
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
#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.
const char *const PersonalityWrapperFn
Representation of each machine instruction.
Definition: MachineInstr.h:63
This class is derived from MachineFunctionInfo and contains private WebAssembly-specific information ...
unsigned getCalleeOpNo(const MachineInstr &MI)
Returns the operand number of a callee, assuming the argument is a call instruction.
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:322
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:413
bool isImplicit() const