forked from OSchip/llvm-project
[WebAssembly] Remove exnref and br_on_exn
This removes `exnref` type and `br_on_exn` instruction. This is effectively NFC because most uses of these were already removed in the previous CLs. Reviewed By: dschuff, tlively Differential Revision: https://reviews.llvm.org/D94041
This commit is contained in:
parent
9e4eadeb13
commit
52e240a072
|
@ -30,8 +30,6 @@ std::string toString(ValType type) {
|
|||
return "f64";
|
||||
case ValType::V128:
|
||||
return "v128";
|
||||
case ValType::EXNREF:
|
||||
return "exnref";
|
||||
case ValType::FUNCREF:
|
||||
return "funcref";
|
||||
case ValType::EXTERNREF:
|
||||
|
|
|
@ -244,7 +244,6 @@ enum : unsigned {
|
|||
WASM_TYPE_F64 = 0x7C,
|
||||
WASM_TYPE_V128 = 0x7B,
|
||||
WASM_TYPE_FUNCREF = 0x70,
|
||||
WASM_TYPE_EXNREF = 0x68,
|
||||
WASM_TYPE_EXTERNREF = 0x6F,
|
||||
WASM_TYPE_FUNC = 0x60,
|
||||
WASM_TYPE_NORESULT = 0x40, // for blocks with no result values
|
||||
|
@ -379,7 +378,6 @@ enum class ValType {
|
|||
F32 = WASM_TYPE_F32,
|
||||
F64 = WASM_TYPE_F64,
|
||||
V128 = WASM_TYPE_V128,
|
||||
EXNREF = WASM_TYPE_EXNREF,
|
||||
FUNCREF = WASM_TYPE_FUNCREF,
|
||||
EXTERNREF = WASM_TYPE_EXTERNREF,
|
||||
};
|
||||
|
|
|
@ -193,10 +193,9 @@ def x86mmx : ValueType<64 , 157>; // X86 MMX value
|
|||
def FlagVT : ValueType<0 , 158>; // Pre-RA sched glue
|
||||
def isVoid : ValueType<0 , 159>; // Produces no value
|
||||
def untyped: ValueType<8 , 160>; // Produces an untyped value
|
||||
def exnref : ValueType<0 , 161>; // WebAssembly's exnref type
|
||||
def funcref : ValueType<0 , 162>; // WebAssembly's funcref type
|
||||
def externref : ValueType<0 , 163>; // WebAssembly's externref type
|
||||
def x86amx : ValueType<8192, 164>; // X86 AMX value
|
||||
def funcref : ValueType<0 , 161>; // WebAssembly's funcref type
|
||||
def externref : ValueType<0 , 162>; // WebAssembly's externref type
|
||||
def x86amx : ValueType<8192, 163>; // X86 AMX value
|
||||
|
||||
|
||||
def token : ValueType<0 , 248>; // TokenTy
|
||||
|
|
|
@ -244,13 +244,12 @@ namespace llvm {
|
|||
// unspecified type. The register class
|
||||
// will be determined by the opcode.
|
||||
|
||||
exnref = 161, // WebAssembly's exnref type
|
||||
funcref = 162, // WebAssembly's funcref type
|
||||
externref = 163, // WebAssembly's externref type
|
||||
x86amx = 164, // This is an X86 AMX value
|
||||
funcref = 161, // WebAssembly's funcref type
|
||||
externref = 162, // WebAssembly's externref type
|
||||
x86amx = 163, // This is an X86 AMX value
|
||||
|
||||
FIRST_VALUETYPE = 1, // This is always the beginning of the list.
|
||||
LAST_VALUETYPE = 165, // This always remains at the end of the list.
|
||||
LAST_VALUETYPE = 164, // This always remains at the end of the list.
|
||||
|
||||
// This is the current maximum for LAST_VALUETYPE.
|
||||
// MVT::MAX_ALLOWED_VALUETYPE is used for asserts and to size bit vectors
|
||||
|
@ -977,7 +976,6 @@ namespace llvm {
|
|||
case v1024f32: return TypeSize::Fixed(32768);
|
||||
case v2048i32:
|
||||
case v2048f32: return TypeSize::Fixed(65536);
|
||||
case exnref:
|
||||
case funcref:
|
||||
case externref: return TypeSize::Fixed(0); // opaque type
|
||||
}
|
||||
|
|
|
@ -18,11 +18,11 @@
|
|||
using namespace llvm;
|
||||
|
||||
void WasmException::endModule() {
|
||||
// This is the symbol used in 'throw' and 'br_on_exn' instruction to denote
|
||||
// this is a C++ exception. This symbol has to be emitted somewhere once in
|
||||
// the module. Check if the symbol has already been created, i.e., we have at
|
||||
// least one 'throw' or 'br_on_exn' instruction in the module, and emit the
|
||||
// symbol only if so.
|
||||
// This is the symbol used in 'throw' and 'catch' instruction to denote this
|
||||
// is a C++ exception. This symbol has to be emitted somewhere once in the
|
||||
// module. Check if the symbol has already been created, i.e., we have at
|
||||
// least one 'throw' or 'catch' instruction in the module, and emit the symbol
|
||||
// only if so.
|
||||
SmallString<60> NameStr;
|
||||
Mangler::getNameWithPrefix(NameStr, "__cpp_exception", Asm->getDataLayout());
|
||||
if (Asm->OutContext.lookupSymbol(NameStr)) {
|
||||
|
|
|
@ -167,7 +167,6 @@ std::string EVT::getEVTString() const {
|
|||
case MVT::x86amx: return "x86amx";
|
||||
case MVT::Metadata: return "Metadata";
|
||||
case MVT::Untyped: return "Untyped";
|
||||
case MVT::exnref: return "exnref";
|
||||
case MVT::funcref: return "funcref";
|
||||
case MVT::externref: return "externref";
|
||||
}
|
||||
|
|
|
@ -572,7 +572,6 @@ void ScalarEnumerationTraits<WasmYAML::ValueType>::enumeration(
|
|||
ECase(F64);
|
||||
ECase(V128);
|
||||
ECase(FUNCREF);
|
||||
ECase(EXNREF);
|
||||
ECase(EXTERNREF);
|
||||
ECase(FUNC);
|
||||
#undef ECase
|
||||
|
|
|
@ -340,8 +340,6 @@ public:
|
|||
Type == "i32x4" || Type == "i64x2" || Type == "f32x4" ||
|
||||
Type == "f64x2")
|
||||
return wasm::ValType::V128;
|
||||
if (Type == "exnref")
|
||||
return wasm::ValType::EXNREF;
|
||||
if (Type == "funcref")
|
||||
return wasm::ValType::FUNCREF;
|
||||
if (Type == "externref")
|
||||
|
@ -359,7 +357,6 @@ public:
|
|||
.Case("v128", WebAssembly::BlockType::V128)
|
||||
.Case("funcref", WebAssembly::BlockType::Funcref)
|
||||
.Case("externref", WebAssembly::BlockType::Externref)
|
||||
.Case("exnref", WebAssembly::BlockType::Exnref)
|
||||
.Case("void", WebAssembly::BlockType::Void)
|
||||
.Default(WebAssembly::BlockType::Invalid);
|
||||
}
|
||||
|
|
|
@ -345,8 +345,6 @@ const char *WebAssembly::anyTypeToString(unsigned Ty) {
|
|||
return "externref";
|
||||
case wasm::WASM_TYPE_FUNC:
|
||||
return "func";
|
||||
case wasm::WASM_TYPE_EXNREF:
|
||||
return "exnref";
|
||||
case wasm::WASM_TYPE_NORESULT:
|
||||
return "void";
|
||||
default:
|
||||
|
|
|
@ -151,8 +151,6 @@ wasm::ValType WebAssembly::toValType(const MVT &Ty) {
|
|||
return wasm::ValType::FUNCREF;
|
||||
case MVT::externref:
|
||||
return wasm::ValType::EXTERNREF;
|
||||
case MVT::exnref:
|
||||
return wasm::ValType::EXNREF;
|
||||
default:
|
||||
llvm_unreachable("unexpected type");
|
||||
}
|
||||
|
|
|
@ -140,7 +140,6 @@ enum class BlockType : unsigned {
|
|||
V128 = unsigned(wasm::ValType::V128),
|
||||
Externref = unsigned(wasm::ValType::EXTERNREF),
|
||||
Funcref = unsigned(wasm::ValType::FUNCREF),
|
||||
Exnref = unsigned(wasm::ValType::EXNREF),
|
||||
// Multivalue blocks (and other non-void blocks) are only emitted when the
|
||||
// blocks will never be exited and are at the ends of functions (see
|
||||
// WebAssemblyCFGStackify::fixEndsAtEndOfFunction). They also are never made
|
||||
|
@ -328,8 +327,6 @@ inline bool isArgument(unsigned Opc) {
|
|||
case WebAssembly::ARGUMENT_funcref_S:
|
||||
case WebAssembly::ARGUMENT_externref:
|
||||
case WebAssembly::ARGUMENT_externref_S:
|
||||
case WebAssembly::ARGUMENT_exnref:
|
||||
case WebAssembly::ARGUMENT_exnref_S:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
@ -352,8 +349,6 @@ inline bool isCopy(unsigned Opc) {
|
|||
case WebAssembly::COPY_FUNCREF_S:
|
||||
case WebAssembly::COPY_EXTERNREF:
|
||||
case WebAssembly::COPY_EXTERNREF_S:
|
||||
case WebAssembly::COPY_EXNREF:
|
||||
case WebAssembly::COPY_EXNREF_S:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
@ -376,8 +371,6 @@ inline bool isTee(unsigned Opc) {
|
|||
case WebAssembly::TEE_FUNCREF_S:
|
||||
case WebAssembly::TEE_EXTERNREF:
|
||||
case WebAssembly::TEE_EXTERNREF_S:
|
||||
case WebAssembly::TEE_EXNREF:
|
||||
case WebAssembly::TEE_EXNREF_S:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
|
|
@ -119,8 +119,6 @@ static char getInvokeSig(wasm::ValType VT) {
|
|||
return 'd';
|
||||
case wasm::ValType::V128:
|
||||
return 'V';
|
||||
case wasm::ValType::EXNREF:
|
||||
return 'E';
|
||||
case wasm::ValType::FUNCREF:
|
||||
return 'F';
|
||||
case wasm::ValType::EXTERNREF:
|
||||
|
@ -463,14 +461,6 @@ void WebAssemblyAsmPrinter::emitInstruction(const MachineInstr *MI) {
|
|||
// This is a compiler barrier that prevents instruction reordering during
|
||||
// backend compilation, and should not be emitted.
|
||||
break;
|
||||
case WebAssembly::EXTRACT_EXCEPTION_I32:
|
||||
case WebAssembly::EXTRACT_EXCEPTION_I32_S:
|
||||
// These are pseudo instructions that simulates popping values from stack.
|
||||
// We print these only when we have -wasm-keep-registers on for assembly
|
||||
// readability.
|
||||
if (!WasmKeepRegisters)
|
||||
break;
|
||||
LLVM_FALLTHROUGH;
|
||||
default: {
|
||||
WebAssemblyMCInstLower MCInstLowering(OutContext, *this);
|
||||
MCInst TmpInst;
|
||||
|
|
|
@ -242,20 +242,12 @@ void WebAssemblyCFGStackify::placeBlockMarker(MachineBasicBlock &MBB) {
|
|||
// which reduces overall stack height.
|
||||
MachineBasicBlock *Header = nullptr;
|
||||
bool IsBranchedTo = false;
|
||||
bool IsBrOnExn = false;
|
||||
MachineInstr *BrOnExn = nullptr;
|
||||
int MBBNumber = MBB.getNumber();
|
||||
for (MachineBasicBlock *Pred : MBB.predecessors()) {
|
||||
if (Pred->getNumber() < MBBNumber) {
|
||||
Header = Header ? MDT.findNearestCommonDominator(Header, Pred) : Pred;
|
||||
if (explicitlyBranchesTo(Pred, &MBB)) {
|
||||
if (explicitlyBranchesTo(Pred, &MBB))
|
||||
IsBranchedTo = true;
|
||||
if (Pred->getFirstTerminator()->getOpcode() == WebAssembly::BR_ON_EXN) {
|
||||
IsBrOnExn = true;
|
||||
assert(!BrOnExn && "There should be only one br_on_exn per block");
|
||||
BrOnExn = &*Pred->getFirstTerminator();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!Header)
|
||||
|
@ -340,22 +332,7 @@ void WebAssemblyCFGStackify::placeBlockMarker(MachineBasicBlock &MBB) {
|
|||
}
|
||||
|
||||
// Add the BLOCK.
|
||||
|
||||
// 'br_on_exn' extracts exnref object and pushes variable number of values
|
||||
// depending on its tag. For C++ exception, its a single i32 value, and the
|
||||
// generated code will be in the form of:
|
||||
// block i32
|
||||
// br_on_exn 0, $__cpp_exception
|
||||
// rethrow
|
||||
// end_block
|
||||
WebAssembly::BlockType ReturnType = WebAssembly::BlockType::Void;
|
||||
if (IsBrOnExn) {
|
||||
const char *TagName = BrOnExn->getOperand(1).getSymbolName();
|
||||
if (std::strcmp(TagName, "__cpp_exception") != 0)
|
||||
llvm_unreachable("Only C++ exception is supported");
|
||||
ReturnType = WebAssembly::BlockType::I32;
|
||||
}
|
||||
|
||||
auto InsertPos = getLatestInsertPos(Header, BeforeSet, AfterSet);
|
||||
MachineInstr *Begin =
|
||||
BuildMI(*Header, InsertPos, Header->findDebugLoc(InsertPos),
|
||||
|
@ -776,8 +753,6 @@ static unsigned getCopyOpcode(const TargetRegisterClass *RC) {
|
|||
return WebAssembly::COPY_FUNCREF;
|
||||
if (RC == &WebAssembly::EXTERNREFRegClass)
|
||||
return WebAssembly::COPY_EXTERNREF;
|
||||
if (RC == &WebAssembly::EXNREFRegClass)
|
||||
return WebAssembly::COPY_EXNREF;
|
||||
llvm_unreachable("Unexpected register class");
|
||||
}
|
||||
|
||||
|
|
|
@ -100,8 +100,6 @@ static unsigned getDropOpcode(const TargetRegisterClass *RC) {
|
|||
return WebAssembly::DROP_FUNCREF;
|
||||
if (RC == &WebAssembly::EXTERNREFRegClass)
|
||||
return WebAssembly::DROP_EXTERNREF;
|
||||
if (RC == &WebAssembly::EXNREFRegClass)
|
||||
return WebAssembly::DROP_EXNREF;
|
||||
llvm_unreachable("Unexpected register class");
|
||||
}
|
||||
|
||||
|
@ -117,8 +115,6 @@ static unsigned getLocalGetOpcode(const TargetRegisterClass *RC) {
|
|||
return WebAssembly::LOCAL_GET_F64;
|
||||
if (RC == &WebAssembly::V128RegClass)
|
||||
return WebAssembly::LOCAL_GET_V128;
|
||||
if (RC == &WebAssembly::EXNREFRegClass)
|
||||
return WebAssembly::LOCAL_GET_EXNREF;
|
||||
if (RC == &WebAssembly::FUNCREFRegClass)
|
||||
return WebAssembly::LOCAL_GET_FUNCREF;
|
||||
if (RC == &WebAssembly::EXTERNREFRegClass)
|
||||
|
@ -138,8 +134,6 @@ static unsigned getLocalSetOpcode(const TargetRegisterClass *RC) {
|
|||
return WebAssembly::LOCAL_SET_F64;
|
||||
if (RC == &WebAssembly::V128RegClass)
|
||||
return WebAssembly::LOCAL_SET_V128;
|
||||
if (RC == &WebAssembly::EXNREFRegClass)
|
||||
return WebAssembly::LOCAL_SET_EXNREF;
|
||||
if (RC == &WebAssembly::FUNCREFRegClass)
|
||||
return WebAssembly::LOCAL_SET_FUNCREF;
|
||||
if (RC == &WebAssembly::EXTERNREFRegClass)
|
||||
|
@ -159,8 +153,6 @@ static unsigned getLocalTeeOpcode(const TargetRegisterClass *RC) {
|
|||
return WebAssembly::LOCAL_TEE_F64;
|
||||
if (RC == &WebAssembly::V128RegClass)
|
||||
return WebAssembly::LOCAL_TEE_V128;
|
||||
if (RC == &WebAssembly::EXNREFRegClass)
|
||||
return WebAssembly::LOCAL_TEE_EXNREF;
|
||||
if (RC == &WebAssembly::FUNCREFRegClass)
|
||||
return WebAssembly::LOCAL_TEE_FUNCREF;
|
||||
if (RC == &WebAssembly::EXTERNREFRegClass)
|
||||
|
@ -180,8 +172,6 @@ static MVT typeForRegClass(const TargetRegisterClass *RC) {
|
|||
return MVT::f64;
|
||||
if (RC == &WebAssembly::V128RegClass)
|
||||
return MVT::v16i8;
|
||||
if (RC == &WebAssembly::EXNREFRegClass)
|
||||
return MVT::exnref;
|
||||
if (RC == &WebAssembly::FUNCREFRegClass)
|
||||
return MVT::funcref;
|
||||
if (RC == &WebAssembly::EXTERNREFRegClass)
|
||||
|
|
|
@ -130,7 +130,6 @@ private:
|
|||
case MVT::i64:
|
||||
case MVT::f32:
|
||||
case MVT::f64:
|
||||
case MVT::exnref:
|
||||
case MVT::funcref:
|
||||
case MVT::externref:
|
||||
return VT;
|
||||
|
@ -716,10 +715,6 @@ bool WebAssemblyFastISel::fastLowerArguments() {
|
|||
Opc = WebAssembly::ARGUMENT_externref;
|
||||
RC = &WebAssembly::EXTERNREFRegClass;
|
||||
break;
|
||||
case MVT::exnref:
|
||||
Opc = WebAssembly::ARGUMENT_exnref;
|
||||
RC = &WebAssembly::EXNREFRegClass;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -818,9 +813,6 @@ bool WebAssemblyFastISel::selectCall(const Instruction *I) {
|
|||
case MVT::v2f64:
|
||||
ResultReg = createResultReg(&WebAssembly::V128RegClass);
|
||||
break;
|
||||
case MVT::exnref:
|
||||
ResultReg = createResultReg(&WebAssembly::EXNREFRegClass);
|
||||
break;
|
||||
case MVT::funcref:
|
||||
ResultReg = createResultReg(&WebAssembly::FUNCREFRegClass);
|
||||
break;
|
||||
|
@ -943,10 +935,6 @@ bool WebAssemblyFastISel::selectSelect(const Instruction *I) {
|
|||
Opc = WebAssembly::SELECT_F64;
|
||||
RC = &WebAssembly::F64RegClass;
|
||||
break;
|
||||
case MVT::exnref:
|
||||
Opc = WebAssembly::SELECT_EXNREF;
|
||||
RC = &WebAssembly::EXNREFRegClass;
|
||||
break;
|
||||
case MVT::funcref:
|
||||
Opc = WebAssembly::SELECT_FUNCREF;
|
||||
RC = &WebAssembly::FUNCREFRegClass;
|
||||
|
@ -1358,7 +1346,6 @@ bool WebAssemblyFastISel::selectRet(const Instruction *I) {
|
|||
case MVT::v2f64:
|
||||
case MVT::funcref:
|
||||
case MVT::externref:
|
||||
case MVT::exnref:
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
|
|
|
@ -145,7 +145,7 @@ defm END_TRY : NRI<(outs), (ins), [], "end_try", 0x0b>;
|
|||
|
||||
// Catching an exception: catch / catch_all
|
||||
let hasCtrlDep = 1, hasSideEffects = 1 in {
|
||||
// TODO Currently 'catch' can only extract an i32, which is sufficient for C++
|
||||
// Currently 'catch' can only extract an i32, which is sufficient for C++
|
||||
// support, but according to the spec 'catch' can extract any number of values
|
||||
// based on the event type.
|
||||
defm CATCH : I<(outs I32:$dst), (ins event_op:$tag),
|
||||
|
@ -156,21 +156,6 @@ defm CATCH : I<(outs I32:$dst), (ins event_op:$tag),
|
|||
defm CATCH_ALL : NRI<(outs), (ins), [], "catch_all", 0x05>;
|
||||
}
|
||||
|
||||
// Querying / extracing exception: br_on_exn
|
||||
// br_on_exn queries an exnref to see if it matches the corresponding exception
|
||||
// tag index. If true it branches to the given label and pushes the
|
||||
// corresponding argument values of the exception onto the stack.
|
||||
let isBranch = 1, isTerminator = 1, hasCtrlDep = 1 in
|
||||
defm BR_ON_EXN : I<(outs), (ins bb_op:$dst, event_op:$tag, EXNREF:$exn),
|
||||
(outs), (ins bb_op:$dst, event_op:$tag), [],
|
||||
"br_on_exn \t$dst, $tag, $exn", "br_on_exn \t$dst, $tag",
|
||||
0x0a>;
|
||||
// This is a pseudo instruction that simulates popping a value from stack, which
|
||||
// has been pushed by br_on_exn
|
||||
let isCodeGenOnly = 1, hasSideEffects = 1 in
|
||||
defm EXTRACT_EXCEPTION_I32 : NRI<(outs I32:$dst), (ins), [],
|
||||
"extract_exception\t$dst">;
|
||||
|
||||
// Pseudo instructions: cleanupret / catchret
|
||||
let isTerminator = 1, hasSideEffects = 1, isBarrier = 1, hasCtrlDep = 1,
|
||||
isPseudo = 1, isEHScopeReturn = 1 in {
|
||||
|
|
|
@ -80,8 +80,6 @@ void WebAssemblyInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
|
|||
CopyOpcode = WebAssembly::COPY_FUNCREF;
|
||||
else if (RC == &WebAssembly::EXTERNREFRegClass)
|
||||
CopyOpcode = WebAssembly::COPY_EXTERNREF;
|
||||
else if (RC == &WebAssembly::EXNREFRegClass)
|
||||
CopyOpcode = WebAssembly::COPY_EXNREF;
|
||||
else
|
||||
llvm_unreachable("Unexpected register class");
|
||||
|
||||
|
@ -143,14 +141,6 @@ bool WebAssemblyInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
|
|||
else
|
||||
FBB = MI.getOperand(0).getMBB();
|
||||
break;
|
||||
case WebAssembly::BR_ON_EXN:
|
||||
if (HaveCond)
|
||||
return true;
|
||||
Cond.push_back(MachineOperand::CreateImm(true));
|
||||
Cond.push_back(MI.getOperand(2));
|
||||
TBB = MI.getOperand(0).getMBB();
|
||||
HaveCond = true;
|
||||
break;
|
||||
}
|
||||
if (MI.isBarrier())
|
||||
break;
|
||||
|
@ -196,24 +186,10 @@ unsigned WebAssemblyInstrInfo::insertBranch(
|
|||
|
||||
assert(Cond.size() == 2 && "Expected a flag and a successor block");
|
||||
|
||||
MachineFunction &MF = *MBB.getParent();
|
||||
auto &MRI = MF.getRegInfo();
|
||||
bool IsBrOnExn = Cond[1].isReg() && MRI.getRegClass(Cond[1].getReg()) ==
|
||||
&WebAssembly::EXNREFRegClass;
|
||||
|
||||
if (Cond[0].getImm()) {
|
||||
if (IsBrOnExn) {
|
||||
const char *CPPExnSymbol = MF.createExternalSymbolName("__cpp_exception");
|
||||
BuildMI(&MBB, DL, get(WebAssembly::BR_ON_EXN))
|
||||
.addMBB(TBB)
|
||||
.addExternalSymbol(CPPExnSymbol)
|
||||
.add(Cond[1]);
|
||||
} else
|
||||
BuildMI(&MBB, DL, get(WebAssembly::BR_IF)).addMBB(TBB).add(Cond[1]);
|
||||
} else {
|
||||
assert(!IsBrOnExn && "br_on_exn does not have a reversed condition");
|
||||
if (Cond[0].getImm())
|
||||
BuildMI(&MBB, DL, get(WebAssembly::BR_IF)).addMBB(TBB).add(Cond[1]);
|
||||
else
|
||||
BuildMI(&MBB, DL, get(WebAssembly::BR_UNLESS)).addMBB(TBB).add(Cond[1]);
|
||||
}
|
||||
if (!FBB)
|
||||
return 1;
|
||||
|
||||
|
@ -224,14 +200,6 @@ unsigned WebAssemblyInstrInfo::insertBranch(
|
|||
bool WebAssemblyInstrInfo::reverseBranchCondition(
|
||||
SmallVectorImpl<MachineOperand> &Cond) const {
|
||||
assert(Cond.size() == 2 && "Expected a flag and a condition expression");
|
||||
|
||||
// br_on_exn's condition cannot be reversed
|
||||
MachineFunction &MF = *Cond[1].getParent()->getParent()->getParent();
|
||||
auto &MRI = MF.getRegInfo();
|
||||
if (Cond[1].isReg() &&
|
||||
MRI.getRegClass(Cond[1].getReg()) == &WebAssembly::EXNREFRegClass)
|
||||
return true;
|
||||
|
||||
Cond.front() = MachineOperand::CreateImm(!Cond.front().getImm());
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -245,7 +245,6 @@ defm "": ARGUMENT<I32, i32>;
|
|||
defm "": ARGUMENT<I64, i64>;
|
||||
defm "": ARGUMENT<F32, f32>;
|
||||
defm "": ARGUMENT<F64, f64>;
|
||||
defm "": ARGUMENT<EXNREF, exnref>;
|
||||
defm "": ARGUMENT<FUNCREF, funcref>;
|
||||
defm "": ARGUMENT<EXTERNREF, externref>;
|
||||
|
||||
|
@ -317,7 +316,6 @@ defm "" : LOCAL<I64>;
|
|||
defm "" : LOCAL<F32>;
|
||||
defm "" : LOCAL<F64>;
|
||||
defm "" : LOCAL<V128>, Requires<[HasSIMD128]>;
|
||||
defm "" : LOCAL<EXNREF>, Requires<[HasExceptionHandling]>;
|
||||
defm "" : LOCAL<FUNCREF>, Requires<[HasReferenceTypes]>;
|
||||
defm "" : LOCAL<EXTERNREF>, Requires<[HasReferenceTypes]>;
|
||||
|
||||
|
|
|
@ -30,9 +30,8 @@ multiclass REF_I<WebAssemblyRegClass reg, ValueType vt> {
|
|||
|
||||
defm "" : REF_I<FUNCREF, funcref>;
|
||||
defm "" : REF_I<EXTERNREF, externref>;
|
||||
defm "" : REF_I<EXNREF, exnref>;
|
||||
|
||||
foreach reg = [FUNCREF, EXTERNREF, EXNREF] in {
|
||||
foreach reg = [FUNCREF, EXTERNREF] in {
|
||||
def : Pat<(select (i32 (setne I32:$cond, 0)), reg:$lhs, reg:$rhs),
|
||||
(!cast<Instruction>("SELECT_"#reg) reg:$lhs, reg:$rhs, I32:$cond)>;
|
||||
def : Pat<(select (i32 (seteq I32:$cond, 0)), reg:$lhs, reg:$rhs),
|
||||
|
|
|
@ -117,9 +117,6 @@ static bool maybeRewriteToFallthrough(MachineInstr &MI, MachineBasicBlock &MBB,
|
|||
case WebAssembly::EXTERNREFRegClassID:
|
||||
CopyLocalOpc = WebAssembly::COPY_EXTERNREF;
|
||||
break;
|
||||
case WebAssembly::EXNREFRegClassID:
|
||||
CopyLocalOpc = WebAssembly::COPY_EXNREF;
|
||||
break;
|
||||
default:
|
||||
llvm_unreachable("Unexpected register class for return operand");
|
||||
}
|
||||
|
|
|
@ -864,24 +864,6 @@ bool WebAssemblyRegStackify::runOnMachineFunction(MachineFunction &MF) {
|
|||
if (WebAssembly::isArgument(DefI->getOpcode()))
|
||||
continue;
|
||||
|
||||
// Currently catch's return value register cannot be stackified, because
|
||||
// the wasm LLVM backend currently does not support live-in values
|
||||
// entering blocks, which is a part of multi-value proposal.
|
||||
//
|
||||
// Once we support live-in values of wasm blocks, this can be:
|
||||
// catch ; push exnref value onto stack
|
||||
// block exnref -> i32
|
||||
// br_on_exn $__cpp_exception ; pop the exnref value
|
||||
// end_block
|
||||
//
|
||||
// But because we don't support it yet, the catch instruction's dst
|
||||
// register should be assigned to a local to be propagated across
|
||||
// 'block' boundary now.
|
||||
//
|
||||
// TODO: Fix this once we support the multivalue blocks
|
||||
if (DefI->getOpcode() == WebAssembly::CATCH)
|
||||
continue;
|
||||
|
||||
MachineOperand *Def = DefI->findRegisterDefOperand(Reg);
|
||||
assert(Def != nullptr);
|
||||
|
||||
|
|
|
@ -43,7 +43,6 @@ def F64_0 : WebAssemblyReg<"%f64.0">;
|
|||
|
||||
def V128_0: WebAssemblyReg<"%v128">;
|
||||
|
||||
def EXNREF_0 : WebAssemblyReg<"%exnref.0">;
|
||||
def FUNCREF_0 : WebAssemblyReg<"%funcref.0">;
|
||||
def EXTERNREF_0 : WebAssemblyReg<"%externref.0">;
|
||||
|
||||
|
@ -66,6 +65,5 @@ def F32 : WebAssemblyRegClass<[f32], 32, (add F32_0)>;
|
|||
def F64 : WebAssemblyRegClass<[f64], 64, (add F64_0)>;
|
||||
def V128 : WebAssemblyRegClass<[v4f32, v2f64, v2i64, v4i32, v16i8, v8i16], 128,
|
||||
(add V128_0)>;
|
||||
def EXNREF : WebAssemblyRegClass<[exnref], 0, (add EXNREF_0)>;
|
||||
def FUNCREF : WebAssemblyRegClass<[funcref], 0, (add FUNCREF_0)>;
|
||||
def EXTERNREF : WebAssemblyRegClass<[externref], 0, (add EXTERNREF_0)>;
|
||||
|
|
|
@ -47,13 +47,24 @@ body: |
|
|||
RETURN implicit-def $arguments
|
||||
...
|
||||
---
|
||||
name: argument_exnref
|
||||
# CHECK-LABEL: argument_exnref
|
||||
name: argument_funcref
|
||||
# CHECK-LABEL: argument_funcref
|
||||
body: |
|
||||
; CHECK-LABEL: bb.0:
|
||||
; CHECK-NEXT: %1:exnref = ARGUMENT_exnref 0
|
||||
; CHECK-NEXT: %1:funcref = ARGUMENT_funcref 0
|
||||
bb.0:
|
||||
%0:i32 = CONST_I32 0, implicit-def $arguments
|
||||
%1:exnref = ARGUMENT_exnref 0, implicit $arguments
|
||||
%1:funcref = ARGUMENT_funcref 0, implicit $arguments
|
||||
RETURN implicit-def $arguments
|
||||
...
|
||||
---
|
||||
name: argument_externref
|
||||
# CHECK-LABEL: argument_externref
|
||||
body: |
|
||||
; CHECK-LABEL: bb.0:
|
||||
; CHECK-NEXT: %1:externref = ARGUMENT_externref 0
|
||||
bb.0:
|
||||
%0:i32 = CONST_I32 0, implicit-def $arguments
|
||||
%1:externref = ARGUMENT_externref 0, implicit $arguments
|
||||
RETURN implicit-def $arguments
|
||||
...
|
||||
|
|
|
@ -56,13 +56,24 @@ body: |
|
|||
RETURN implicit-def $arguments
|
||||
...
|
||||
---
|
||||
name: copy_exnref
|
||||
# CHECK-LABEL: copy_exnref
|
||||
name: copy_funcref
|
||||
# CHECK-LABEL: copy_funcref
|
||||
body: |
|
||||
; CHECK-LABEL: bb.0:
|
||||
; CHECK-NEXT: %0:exnref = COPY_EXNREF %1:exnref
|
||||
; CHECK-NEXT: %0:funcref = COPY_FUNCREF %1:funcref
|
||||
; CHECK-NEXT: RETURN
|
||||
bb.0:
|
||||
%0:exnref = COPY %1:exnref
|
||||
%0:funcref = COPY %1:funcref
|
||||
RETURN implicit-def $arguments
|
||||
...
|
||||
---
|
||||
name: copy_externref
|
||||
# CHECK-LABEL: copy_externref
|
||||
body: |
|
||||
; CHECK-LABEL: bb.0:
|
||||
; CHECK-NEXT: %0:externref = COPY_EXTERNREF %1:externref
|
||||
; CHECK-NEXT: RETURN
|
||||
bb.0:
|
||||
%0:externref = COPY %1:externref
|
||||
RETURN implicit-def $arguments
|
||||
...
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
0x11 0x80 0x01 0x00
|
||||
|
||||
# CHECK: call 0
|
||||
# CHECK-NOT: exnref.call 0
|
||||
0x10 0x00
|
||||
|
||||
# CHECK: local.get 128
|
||||
|
@ -55,6 +54,3 @@
|
|||
# This can mean end_block/end_loop/end_if/end_function/end_try..
|
||||
# CHECK: end
|
||||
0x0B
|
||||
|
||||
# CHECK: br_on_exn 0, 0
|
||||
0x0A 0x00 0x00
|
||||
|
|
|
@ -9,7 +9,7 @@ test0:
|
|||
|
||||
test1:
|
||||
.functype test1 (i32, i64) -> (i32)
|
||||
.local i32, i64, exnref
|
||||
.local i32, i64, funcref
|
||||
local.get 3
|
||||
end_function
|
||||
|
||||
|
@ -21,6 +21,6 @@ test1:
|
|||
# CHECK-NEXT: 9: 20 02 local.get 2
|
||||
# CHECK-NEXT: b: 0b end
|
||||
# CHECK-LABEL: <test1>:
|
||||
# CHECK-NEXT: .local i32, i64, exnref
|
||||
# CHECK-NEXT: .local i32, i64, funcref
|
||||
# CHECK-NEXT: 14: 20 03 local.get 3
|
||||
# CHECK-NEXT: 16: 0b end
|
||||
|
|
|
@ -226,7 +226,6 @@ StringRef llvm::getEnumName(MVT::SimpleValueType T) {
|
|||
case MVT::iPTR: return "MVT::iPTR";
|
||||
case MVT::iPTRAny: return "MVT::iPTRAny";
|
||||
case MVT::Untyped: return "MVT::Untyped";
|
||||
case MVT::exnref: return "MVT::exnref";
|
||||
case MVT::funcref: return "MVT::funcref";
|
||||
case MVT::externref: return "MVT::externref";
|
||||
default: llvm_unreachable("ILLEGAL VALUE TYPE!");
|
||||
|
|
Loading…
Reference in New Issue