1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 20:51:52 +01:00

[WebAssembly] refactored utilities to not depend on MachineInstr

Summary:
Most of these functions can work for MachineInstr and MCInst
equally now.

Reviewers: dschuff

Subscribers: MatzeB, sbc100, jgravelle-google, aheejin, sunfish, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D64643

llvm-svn: 365965
This commit is contained in:
Wouter van Oortmerssen 2019-07-12 22:08:25 +00:00
parent 63721a457e
commit a3b1095a5b
11 changed files with 254 additions and 261 deletions

View File

@ -122,9 +122,27 @@ enum TOF {
namespace llvm {
namespace WebAssembly {
/// This is used to indicate block signatures.
enum class ExprType : unsigned {
Void = 0x40,
I32 = 0x7F,
I64 = 0x7E,
F32 = 0x7D,
F64 = 0x7C,
V128 = 0x7B,
ExceptRef = 0x68,
Invalid = 0x00
};
/// Instruction opcodes emitted via means other than CodeGen.
static const unsigned Nop = 0x01;
static const unsigned End = 0x0b;
wasm::ValType toValType(const MVT &Ty);
/// Return the default p2align value for a load or store with the given opcode.
inline unsigned GetDefaultP2AlignAny(unsigned Opcode) {
switch (Opcode) {
inline unsigned GetDefaultP2AlignAny(unsigned Opc) {
switch (Opc) {
case WebAssembly::LOAD8_S_I32:
case WebAssembly::LOAD8_S_I32_S:
case WebAssembly::LOAD8_U_I32:
@ -337,31 +355,230 @@ inline unsigned GetDefaultP2AlignAny(unsigned Opcode) {
}
}
inline unsigned GetDefaultP2Align(unsigned Opcode) {
auto Align = GetDefaultP2AlignAny(Opcode);
inline unsigned GetDefaultP2Align(unsigned Opc) {
auto Align = GetDefaultP2AlignAny(Opc);
if (Align == -1U) {
llvm_unreachable("Only loads and stores have p2align values");
}
return Align;
}
/// This is used to indicate block signatures.
enum class ExprType : unsigned {
Void = 0x40,
I32 = 0x7F,
I64 = 0x7E,
F32 = 0x7D,
F64 = 0x7C,
V128 = 0x7B,
ExceptRef = 0x68,
Invalid = 0x00
};
inline bool isArgument(unsigned Opc) {
switch (Opc) {
case WebAssembly::ARGUMENT_i32:
case WebAssembly::ARGUMENT_i32_S:
case WebAssembly::ARGUMENT_i64:
case WebAssembly::ARGUMENT_i64_S:
case WebAssembly::ARGUMENT_f32:
case WebAssembly::ARGUMENT_f32_S:
case WebAssembly::ARGUMENT_f64:
case WebAssembly::ARGUMENT_f64_S:
case WebAssembly::ARGUMENT_v16i8:
case WebAssembly::ARGUMENT_v16i8_S:
case WebAssembly::ARGUMENT_v8i16:
case WebAssembly::ARGUMENT_v8i16_S:
case WebAssembly::ARGUMENT_v4i32:
case WebAssembly::ARGUMENT_v4i32_S:
case WebAssembly::ARGUMENT_v2i64:
case WebAssembly::ARGUMENT_v2i64_S:
case WebAssembly::ARGUMENT_v4f32:
case WebAssembly::ARGUMENT_v4f32_S:
case WebAssembly::ARGUMENT_v2f64:
case WebAssembly::ARGUMENT_v2f64_S:
return true;
default:
return false;
}
}
/// Instruction opcodes emitted via means other than CodeGen.
static const unsigned Nop = 0x01;
static const unsigned End = 0x0b;
inline bool isCopy(unsigned Opc) {
switch (Opc) {
case WebAssembly::COPY_I32:
case WebAssembly::COPY_I32_S:
case WebAssembly::COPY_I64:
case WebAssembly::COPY_I64_S:
case WebAssembly::COPY_F32:
case WebAssembly::COPY_F32_S:
case WebAssembly::COPY_F64:
case WebAssembly::COPY_F64_S:
case WebAssembly::COPY_V128:
case WebAssembly::COPY_V128_S:
case WebAssembly::COPY_EXCEPT_REF:
case WebAssembly::COPY_EXCEPT_REF_S:
return true;
default:
return false;
}
}
wasm::ValType toValType(const MVT &Ty);
inline bool isTee(unsigned Opc) {
switch (Opc) {
case WebAssembly::TEE_I32:
case WebAssembly::TEE_I32_S:
case WebAssembly::TEE_I64:
case WebAssembly::TEE_I64_S:
case WebAssembly::TEE_F32:
case WebAssembly::TEE_F32_S:
case WebAssembly::TEE_F64:
case WebAssembly::TEE_F64_S:
case WebAssembly::TEE_V128:
case WebAssembly::TEE_V128_S:
return true;
default:
return false;
}
}
inline bool isCallDirect(unsigned Opc) {
switch (Opc) {
case WebAssembly::CALL_VOID:
case WebAssembly::CALL_VOID_S:
case WebAssembly::CALL_i32:
case WebAssembly::CALL_i32_S:
case WebAssembly::CALL_i64:
case WebAssembly::CALL_i64_S:
case WebAssembly::CALL_f32:
case WebAssembly::CALL_f32_S:
case WebAssembly::CALL_f64:
case WebAssembly::CALL_f64_S:
case WebAssembly::CALL_v16i8:
case WebAssembly::CALL_v16i8_S:
case WebAssembly::CALL_v8i16:
case WebAssembly::CALL_v8i16_S:
case WebAssembly::CALL_v4i32:
case WebAssembly::CALL_v4i32_S:
case WebAssembly::CALL_v2i64:
case WebAssembly::CALL_v2i64_S:
case WebAssembly::CALL_v4f32:
case WebAssembly::CALL_v4f32_S:
case WebAssembly::CALL_v2f64:
case WebAssembly::CALL_v2f64_S:
case WebAssembly::CALL_ExceptRef:
case WebAssembly::CALL_ExceptRef_S:
case WebAssembly::RET_CALL:
case WebAssembly::RET_CALL_S:
return true;
default:
return false;
}
}
inline bool isCallIndirect(unsigned Opc) {
switch (Opc) {
case WebAssembly::CALL_INDIRECT_VOID:
case WebAssembly::CALL_INDIRECT_VOID_S:
case WebAssembly::CALL_INDIRECT_i32:
case WebAssembly::CALL_INDIRECT_i32_S:
case WebAssembly::CALL_INDIRECT_i64:
case WebAssembly::CALL_INDIRECT_i64_S:
case WebAssembly::CALL_INDIRECT_f32:
case WebAssembly::CALL_INDIRECT_f32_S:
case WebAssembly::CALL_INDIRECT_f64:
case WebAssembly::CALL_INDIRECT_f64_S:
case WebAssembly::CALL_INDIRECT_v16i8:
case WebAssembly::CALL_INDIRECT_v16i8_S:
case WebAssembly::CALL_INDIRECT_v8i16:
case WebAssembly::CALL_INDIRECT_v8i16_S:
case WebAssembly::CALL_INDIRECT_v4i32:
case WebAssembly::CALL_INDIRECT_v4i32_S:
case WebAssembly::CALL_INDIRECT_v2i64:
case WebAssembly::CALL_INDIRECT_v2i64_S:
case WebAssembly::CALL_INDIRECT_v4f32:
case WebAssembly::CALL_INDIRECT_v4f32_S:
case WebAssembly::CALL_INDIRECT_v2f64:
case WebAssembly::CALL_INDIRECT_v2f64_S:
case WebAssembly::CALL_INDIRECT_ExceptRef:
case WebAssembly::CALL_INDIRECT_ExceptRef_S:
case WebAssembly::RET_CALL_INDIRECT:
case WebAssembly::RET_CALL_INDIRECT_S:
return true;
default:
return false;
}
}
/// Returns the operand number of a callee, assuming the argument is a call
/// instruction.
inline unsigned getCalleeOpNo(unsigned Opc) {
switch (Opc) {
case WebAssembly::CALL_VOID:
case WebAssembly::CALL_VOID_S:
case WebAssembly::CALL_INDIRECT_VOID:
case WebAssembly::CALL_INDIRECT_VOID_S:
case WebAssembly::RET_CALL:
case WebAssembly::RET_CALL_S:
case WebAssembly::RET_CALL_INDIRECT:
case WebAssembly::RET_CALL_INDIRECT_S:
return 0;
case WebAssembly::CALL_i32:
case WebAssembly::CALL_i32_S:
case WebAssembly::CALL_i64:
case WebAssembly::CALL_i64_S:
case WebAssembly::CALL_f32:
case WebAssembly::CALL_f32_S:
case WebAssembly::CALL_f64:
case WebAssembly::CALL_f64_S:
case WebAssembly::CALL_v16i8:
case WebAssembly::CALL_v16i8_S:
case WebAssembly::CALL_v8i16:
case WebAssembly::CALL_v8i16_S:
case WebAssembly::CALL_v4i32:
case WebAssembly::CALL_v4i32_S:
case WebAssembly::CALL_v2i64:
case WebAssembly::CALL_v2i64_S:
case WebAssembly::CALL_v4f32:
case WebAssembly::CALL_v4f32_S:
case WebAssembly::CALL_v2f64:
case WebAssembly::CALL_v2f64_S:
case WebAssembly::CALL_ExceptRef:
case WebAssembly::CALL_ExceptRef_S:
case WebAssembly::CALL_INDIRECT_i32:
case WebAssembly::CALL_INDIRECT_i32_S:
case WebAssembly::CALL_INDIRECT_i64:
case WebAssembly::CALL_INDIRECT_i64_S:
case WebAssembly::CALL_INDIRECT_f32:
case WebAssembly::CALL_INDIRECT_f32_S:
case WebAssembly::CALL_INDIRECT_f64:
case WebAssembly::CALL_INDIRECT_f64_S:
case WebAssembly::CALL_INDIRECT_v16i8:
case WebAssembly::CALL_INDIRECT_v16i8_S:
case WebAssembly::CALL_INDIRECT_v8i16:
case WebAssembly::CALL_INDIRECT_v8i16_S:
case WebAssembly::CALL_INDIRECT_v4i32:
case WebAssembly::CALL_INDIRECT_v4i32_S:
case WebAssembly::CALL_INDIRECT_v2i64:
case WebAssembly::CALL_INDIRECT_v2i64_S:
case WebAssembly::CALL_INDIRECT_v4f32:
case WebAssembly::CALL_INDIRECT_v4f32_S:
case WebAssembly::CALL_INDIRECT_v2f64:
case WebAssembly::CALL_INDIRECT_v2f64_S:
case WebAssembly::CALL_INDIRECT_ExceptRef:
case WebAssembly::CALL_INDIRECT_ExceptRef_S:
return 1;
default:
llvm_unreachable("Not a call instruction");
}
}
inline bool isMarker(unsigned Opc) {
switch (Opc) {
case WebAssembly::BLOCK:
case WebAssembly::BLOCK_S:
case WebAssembly::END_BLOCK:
case WebAssembly::END_BLOCK_S:
case WebAssembly::LOOP:
case WebAssembly::LOOP_S:
case WebAssembly::END_LOOP:
case WebAssembly::END_LOOP_S:
case WebAssembly::TRY:
case WebAssembly::TRY_S:
case WebAssembly::END_TRY:
case WebAssembly::END_TRY_S:
return true;
default:
return false;
}
}
} // end namespace WebAssembly
} // end namespace llvm

View File

@ -78,7 +78,7 @@ bool WebAssemblyArgumentMove::runOnMachineFunction(MachineFunction &MF) {
// Look for the first NonArg instruction.
for (MachineInstr &MI : EntryMBB) {
if (!WebAssembly::isArgument(MI)) {
if (!WebAssembly::isArgument(MI.getOpcode())) {
InsertPt = MI;
break;
}
@ -87,7 +87,7 @@ bool WebAssemblyArgumentMove::runOnMachineFunction(MachineFunction &MF) {
// Now move any argument instructions later in the block
// to before our first NonArg instruction.
for (MachineInstr &MI : llvm::make_range(InsertPt, EntryMBB.end())) {
if (WebAssembly::isArgument(MI)) {
if (WebAssembly::isArgument(MI.getOpcode())) {
EntryMBB.insert(InsertPt, MI.removeFromParent());
Changed = true;
}

View File

@ -894,7 +894,7 @@ bool WebAssemblyCFGStackify::fixUnwindMismatches(MachineFunction &MF) {
// We wrap up the current range when we see a marker even if we haven't
// finished a BB.
if (RangeEnd && WebAssembly::isMarker(MI)) {
if (RangeEnd && WebAssembly::isMarker(MI.getOpcode())) {
NeedAppendixBlock = true;
// Record the range. nullptr here means the unwind destination is the
// caller.

View File

@ -205,7 +205,7 @@ bool WebAssemblyExplicitLocals::runOnMachineFunction(MachineFunction &MF) {
E = MF.begin()->end();
I != E;) {
MachineInstr &MI = *I++;
if (!WebAssembly::isArgument(MI))
if (!WebAssembly::isArgument(MI.getOpcode()))
break;
unsigned Reg = MI.getOperand(0).getReg();
assert(!MFI.isVRegStackified(Reg));
@ -227,7 +227,7 @@ bool WebAssemblyExplicitLocals::runOnMachineFunction(MachineFunction &MF) {
for (MachineBasicBlock &MBB : MF) {
for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E;) {
MachineInstr &MI = *I++;
assert(!WebAssembly::isArgument(MI));
assert(!WebAssembly::isArgument(MI.getOpcode()));
if (MI.isDebugInstr() || MI.isLabel())
continue;
@ -235,7 +235,7 @@ bool WebAssemblyExplicitLocals::runOnMachineFunction(MachineFunction &MF) {
// Replace tee instructions with local.tee. The difference is that tee
// instructions have two defs, while local.tee instructions have one def
// and an index of a local to write to.
if (WebAssembly::isTee(MI)) {
if (WebAssembly::isTee(MI.getOpcode())) {
assert(MFI.isVRegStackified(MI.getOperand(0).getReg()));
assert(!MFI.isVRegStackified(MI.getOperand(1).getReg()));
unsigned OldReg = MI.getOperand(2).getReg();
@ -356,7 +356,7 @@ bool WebAssemblyExplicitLocals::runOnMachineFunction(MachineFunction &MF) {
}
// Coalesce and eliminate COPY instructions.
if (WebAssembly::isCopy(MI)) {
if (WebAssembly::isCopy(MI.getOpcode())) {
MRI.replaceRegWith(MI.getOperand(1).getReg(),
MI.getOperand(0).getReg());
MI.eraseFromParent();

View File

@ -164,7 +164,8 @@ void WebAssemblyFrameLowering::emitPrologue(MachineFunction &MF,
auto &MRI = MF.getRegInfo();
auto InsertPt = MBB.begin();
while (InsertPt != MBB.end() && WebAssembly::isArgument(*InsertPt))
while (InsertPt != MBB.end() &&
WebAssembly::isArgument(InsertPt->getOpcode()))
++InsertPt;
DebugLoc DL;

View File

@ -16,7 +16,7 @@
#include "WebAssemblyAsmPrinter.h"
#include "WebAssemblyMachineFunctionInfo.h"
#include "WebAssemblyRuntimeLibcallSignatures.h"
#include "WebAssemblyUtilities.h"
#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/IR/Constants.h"
@ -221,7 +221,7 @@ void WebAssemblyMCInstLower::lower(const MachineInstr *MI,
// call_indirect instructions have a callee operand at the end which
// doesn't count as a param.
if (WebAssembly::isCallIndirect(*MI))
if (WebAssembly::isCallIndirect(MI->getOpcode()))
Params.pop_back();
auto *WasmSym = cast<MCSymbolWasm>(Sym);

View File

@ -64,7 +64,7 @@ FunctionPass *llvm::createWebAssemblyPrepareForLiveIntervals() {
// Test whether the given register has an ARGUMENT def.
static bool hasArgumentDef(unsigned Reg, const MachineRegisterInfo &MRI) {
for (const auto &Def : MRI.def_instructions(Reg))
if (WebAssembly::isArgument(Def))
if (WebAssembly::isArgument(Def.getOpcode()))
return true;
return false;
}
@ -114,7 +114,7 @@ bool WebAssemblyPrepareForLiveIntervals::runOnMachineFunction(
// liveness reflects the fact that these really are live-in values.
for (auto MII = Entry.begin(), MIE = Entry.end(); MII != MIE;) {
MachineInstr &MI = *MII++;
if (WebAssembly::isArgument(MI)) {
if (WebAssembly::isArgument(MI.getOpcode())) {
MI.removeFromParent();
Entry.insert(Entry.begin(), &MI);
}

View File

@ -72,7 +72,7 @@ bool WebAssemblyRegNumbering::runOnMachineFunction(MachineFunction &MF) {
// variables. Assign the numbers for them first.
MachineBasicBlock &EntryMBB = MF.front();
for (MachineInstr &MI : EntryMBB) {
if (!WebAssembly::isArgument(MI))
if (!WebAssembly::isArgument(MI.getOpcode()))
break;
int64_t Imm = MI.getOperand(1).getImm();

View File

@ -252,7 +252,7 @@ static void query(const MachineInstr &MI, AliasAnalysis &AA, bool &Read,
// Analyze calls.
if (MI.isCall()) {
unsigned CalleeOpNo = WebAssembly::getCalleeOpNo(MI);
unsigned CalleeOpNo = WebAssembly::getCalleeOpNo(MI.getOpcode());
queryCallee(MI, CalleeOpNo, Read, Write, Effects, StackPointer);
}
}
@ -826,7 +826,7 @@ bool WebAssemblyRegStackify::runOnMachineFunction(MachineFunction &MF) {
// Argument instructions represent live-in registers and not real
// instructions.
if (WebAssembly::isArgument(*Def))
if (WebAssembly::isArgument(Def->getOpcode()))
continue;
// Currently catch's return value register cannot be stackified, because

View File

@ -24,72 +24,6 @@ const char *const WebAssembly::StdTerminateFn = "_ZSt9terminatev";
const char *const WebAssembly::PersonalityWrapperFn =
"_Unwind_Wasm_CallPersonality";
bool WebAssembly::isArgument(const MachineInstr &MI) {
switch (MI.getOpcode()) {
case WebAssembly::ARGUMENT_i32:
case WebAssembly::ARGUMENT_i32_S:
case WebAssembly::ARGUMENT_i64:
case WebAssembly::ARGUMENT_i64_S:
case WebAssembly::ARGUMENT_f32:
case WebAssembly::ARGUMENT_f32_S:
case WebAssembly::ARGUMENT_f64:
case WebAssembly::ARGUMENT_f64_S:
case WebAssembly::ARGUMENT_v16i8:
case WebAssembly::ARGUMENT_v16i8_S:
case WebAssembly::ARGUMENT_v8i16:
case WebAssembly::ARGUMENT_v8i16_S:
case WebAssembly::ARGUMENT_v4i32:
case WebAssembly::ARGUMENT_v4i32_S:
case WebAssembly::ARGUMENT_v2i64:
case WebAssembly::ARGUMENT_v2i64_S:
case WebAssembly::ARGUMENT_v4f32:
case WebAssembly::ARGUMENT_v4f32_S:
case WebAssembly::ARGUMENT_v2f64:
case WebAssembly::ARGUMENT_v2f64_S:
return true;
default:
return false;
}
}
bool WebAssembly::isCopy(const MachineInstr &MI) {
switch (MI.getOpcode()) {
case WebAssembly::COPY_I32:
case WebAssembly::COPY_I32_S:
case WebAssembly::COPY_I64:
case WebAssembly::COPY_I64_S:
case WebAssembly::COPY_F32:
case WebAssembly::COPY_F32_S:
case WebAssembly::COPY_F64:
case WebAssembly::COPY_F64_S:
case WebAssembly::COPY_V128:
case WebAssembly::COPY_V128_S:
case WebAssembly::COPY_EXCEPT_REF:
case WebAssembly::COPY_EXCEPT_REF_S:
return true;
default:
return false;
}
}
bool WebAssembly::isTee(const MachineInstr &MI) {
switch (MI.getOpcode()) {
case WebAssembly::TEE_I32:
case WebAssembly::TEE_I32_S:
case WebAssembly::TEE_I64:
case WebAssembly::TEE_I64_S:
case WebAssembly::TEE_F32:
case WebAssembly::TEE_F32_S:
case WebAssembly::TEE_F64:
case WebAssembly::TEE_F64_S:
case WebAssembly::TEE_V128:
case WebAssembly::TEE_V128_S:
return true;
default:
return false;
}
}
/// Test whether MI is a child of some other node in an expression tree.
bool WebAssembly::isChild(const MachineInstr &MI,
const WebAssemblyFunctionInfo &MFI) {
@ -103,155 +37,6 @@ bool WebAssembly::isChild(const MachineInstr &MI,
MFI.isVRegStackified(Reg);
}
bool WebAssembly::isCallDirect(const MachineInstr &MI) {
switch (MI.getOpcode()) {
case WebAssembly::CALL_VOID:
case WebAssembly::CALL_VOID_S:
case WebAssembly::CALL_i32:
case WebAssembly::CALL_i32_S:
case WebAssembly::CALL_i64:
case WebAssembly::CALL_i64_S:
case WebAssembly::CALL_f32:
case WebAssembly::CALL_f32_S:
case WebAssembly::CALL_f64:
case WebAssembly::CALL_f64_S:
case WebAssembly::CALL_v16i8:
case WebAssembly::CALL_v16i8_S:
case WebAssembly::CALL_v8i16:
case WebAssembly::CALL_v8i16_S:
case WebAssembly::CALL_v4i32:
case WebAssembly::CALL_v4i32_S:
case WebAssembly::CALL_v2i64:
case WebAssembly::CALL_v2i64_S:
case WebAssembly::CALL_v4f32:
case WebAssembly::CALL_v4f32_S:
case WebAssembly::CALL_v2f64:
case WebAssembly::CALL_v2f64_S:
case WebAssembly::CALL_ExceptRef:
case WebAssembly::CALL_ExceptRef_S:
case WebAssembly::RET_CALL:
case WebAssembly::RET_CALL_S:
return true;
default:
return false;
}
}
bool WebAssembly::isCallIndirect(const MachineInstr &MI) {
switch (MI.getOpcode()) {
case WebAssembly::CALL_INDIRECT_VOID:
case WebAssembly::CALL_INDIRECT_VOID_S:
case WebAssembly::CALL_INDIRECT_i32:
case WebAssembly::CALL_INDIRECT_i32_S:
case WebAssembly::CALL_INDIRECT_i64:
case WebAssembly::CALL_INDIRECT_i64_S:
case WebAssembly::CALL_INDIRECT_f32:
case WebAssembly::CALL_INDIRECT_f32_S:
case WebAssembly::CALL_INDIRECT_f64:
case WebAssembly::CALL_INDIRECT_f64_S:
case WebAssembly::CALL_INDIRECT_v16i8:
case WebAssembly::CALL_INDIRECT_v16i8_S:
case WebAssembly::CALL_INDIRECT_v8i16:
case WebAssembly::CALL_INDIRECT_v8i16_S:
case WebAssembly::CALL_INDIRECT_v4i32:
case WebAssembly::CALL_INDIRECT_v4i32_S:
case WebAssembly::CALL_INDIRECT_v2i64:
case WebAssembly::CALL_INDIRECT_v2i64_S:
case WebAssembly::CALL_INDIRECT_v4f32:
case WebAssembly::CALL_INDIRECT_v4f32_S:
case WebAssembly::CALL_INDIRECT_v2f64:
case WebAssembly::CALL_INDIRECT_v2f64_S:
case WebAssembly::CALL_INDIRECT_ExceptRef:
case WebAssembly::CALL_INDIRECT_ExceptRef_S:
case WebAssembly::RET_CALL_INDIRECT:
case WebAssembly::RET_CALL_INDIRECT_S:
return true;
default:
return false;
}
}
unsigned WebAssembly::getCalleeOpNo(const MachineInstr &MI) {
switch (MI.getOpcode()) {
case WebAssembly::CALL_VOID:
case WebAssembly::CALL_VOID_S:
case WebAssembly::CALL_INDIRECT_VOID:
case WebAssembly::CALL_INDIRECT_VOID_S:
case WebAssembly::RET_CALL:
case WebAssembly::RET_CALL_S:
case WebAssembly::RET_CALL_INDIRECT:
case WebAssembly::RET_CALL_INDIRECT_S:
return 0;
case WebAssembly::CALL_i32:
case WebAssembly::CALL_i32_S:
case WebAssembly::CALL_i64:
case WebAssembly::CALL_i64_S:
case WebAssembly::CALL_f32:
case WebAssembly::CALL_f32_S:
case WebAssembly::CALL_f64:
case WebAssembly::CALL_f64_S:
case WebAssembly::CALL_v16i8:
case WebAssembly::CALL_v16i8_S:
case WebAssembly::CALL_v8i16:
case WebAssembly::CALL_v8i16_S:
case WebAssembly::CALL_v4i32:
case WebAssembly::CALL_v4i32_S:
case WebAssembly::CALL_v2i64:
case WebAssembly::CALL_v2i64_S:
case WebAssembly::CALL_v4f32:
case WebAssembly::CALL_v4f32_S:
case WebAssembly::CALL_v2f64:
case WebAssembly::CALL_v2f64_S:
case WebAssembly::CALL_ExceptRef:
case WebAssembly::CALL_ExceptRef_S:
case WebAssembly::CALL_INDIRECT_i32:
case WebAssembly::CALL_INDIRECT_i32_S:
case WebAssembly::CALL_INDIRECT_i64:
case WebAssembly::CALL_INDIRECT_i64_S:
case WebAssembly::CALL_INDIRECT_f32:
case WebAssembly::CALL_INDIRECT_f32_S:
case WebAssembly::CALL_INDIRECT_f64:
case WebAssembly::CALL_INDIRECT_f64_S:
case WebAssembly::CALL_INDIRECT_v16i8:
case WebAssembly::CALL_INDIRECT_v16i8_S:
case WebAssembly::CALL_INDIRECT_v8i16:
case WebAssembly::CALL_INDIRECT_v8i16_S:
case WebAssembly::CALL_INDIRECT_v4i32:
case WebAssembly::CALL_INDIRECT_v4i32_S:
case WebAssembly::CALL_INDIRECT_v2i64:
case WebAssembly::CALL_INDIRECT_v2i64_S:
case WebAssembly::CALL_INDIRECT_v4f32:
case WebAssembly::CALL_INDIRECT_v4f32_S:
case WebAssembly::CALL_INDIRECT_v2f64:
case WebAssembly::CALL_INDIRECT_v2f64_S:
case WebAssembly::CALL_INDIRECT_ExceptRef:
case WebAssembly::CALL_INDIRECT_ExceptRef_S:
return 1;
default:
llvm_unreachable("Not a call instruction");
}
}
bool WebAssembly::isMarker(const MachineInstr &MI) {
switch (MI.getOpcode()) {
case WebAssembly::BLOCK:
case WebAssembly::BLOCK_S:
case WebAssembly::END_BLOCK:
case WebAssembly::END_BLOCK_S:
case WebAssembly::LOOP:
case WebAssembly::LOOP_S:
case WebAssembly::END_LOOP:
case WebAssembly::END_LOOP_S:
case WebAssembly::TRY:
case WebAssembly::TRY_S:
case WebAssembly::END_TRY:
case WebAssembly::END_TRY_S:
return true;
default:
return false;
}
}
bool WebAssembly::mayThrow(const MachineInstr &MI) {
switch (MI.getOpcode()) {
case WebAssembly::THROW:
@ -260,12 +45,12 @@ bool WebAssembly::mayThrow(const MachineInstr &MI) {
case WebAssembly::RETHROW_S:
return true;
}
if (isCallIndirect(MI))
if (isCallIndirect(MI.getOpcode()))
return true;
if (!MI.isCall())
return false;
const MachineOperand &MO = MI.getOperand(getCalleeOpNo(MI));
const MachineOperand &MO = MI.getOperand(getCalleeOpNo(MI.getOpcode()));
assert(MO.isGlobal());
const auto *F = dyn_cast<Function>(MO.getGlobal());
if (!F)

View File

@ -23,19 +23,9 @@ class WebAssemblyFunctionInfo;
namespace WebAssembly {
bool isArgument(const MachineInstr &MI);
bool isCopy(const MachineInstr &MI);
bool isTee(const MachineInstr &MI);
bool isChild(const MachineInstr &MI, const WebAssemblyFunctionInfo &MFI);
bool isCallDirect(const MachineInstr &MI);
bool isCallIndirect(const MachineInstr &MI);
bool isMarker(const MachineInstr &MI);
bool mayThrow(const MachineInstr &MI);
/// Returns the operand number of a callee, assuming the argument is a call
/// instruction.
unsigned getCalleeOpNo(const MachineInstr &MI);
// Exception-related function names
extern const char *const ClangCallTerminateFn;
extern const char *const CxaBeginCatchFn;