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:
parent
63721a457e
commit
a3b1095a5b
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user