diff options
Diffstat (limited to 'llvm/lib/Target/WebAssembly')
15 files changed, 78 insertions, 112 deletions
diff --git a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmTypeCheck.cpp b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmTypeCheck.cpp index ec72c1de0503..d31715e367ec 100644 --- a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmTypeCheck.cpp +++ b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmTypeCheck.cpp @@ -87,15 +87,14 @@ bool WebAssemblyAsmTypeCheck::popType(SMLoc ErrorLoc, if (Stack.empty()) { return typeError(ErrorLoc, EVT ? StringRef("empty stack while popping ") + - WebAssembly::typeToString(EVT.getValue()) + WebAssembly::typeToString(EVT.value()) : StringRef("empty stack while popping value")); } auto PVT = Stack.pop_back_val(); - if (EVT && EVT.getValue() != PVT) { + if (EVT && EVT.value() != PVT) { return typeError( ErrorLoc, StringRef("popped ") + WebAssembly::typeToString(PVT) + - ", expected " + - WebAssembly::typeToString(EVT.getValue())); + ", expected " + WebAssembly::typeToString(EVT.value())); } return false; } diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp index f52545a65dbb..97dbc35c991b 100644 --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp @@ -26,6 +26,7 @@ using namespace llvm; #define DEBUG_TYPE "wasm-mc-target-desc" #define GET_INSTRINFO_MC_DESC +#define ENABLE_INSTR_PREDICATE_VERIFIER #include "WebAssemblyGenInstrInfo.inc" #define GET_SUBTARGETINFO_MC_DESC diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h index 75d5d0675990..b5b12200505b 100644 --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h @@ -124,6 +124,7 @@ enum TOF { // Defines symbolic names for the WebAssembly instructions. // #define GET_INSTRINFO_ENUM +#define GET_INSTRINFO_MC_HELPER_DECLS #include "WebAssemblyGenInstrInfo.inc" namespace llvm { diff --git a/llvm/lib/Target/WebAssembly/TargetInfo/WebAssemblyTargetInfo.cpp b/llvm/lib/Target/WebAssembly/TargetInfo/WebAssemblyTargetInfo.cpp index e3daf6bfa72e..ef2c77ade8cc 100644 --- a/llvm/lib/Target/WebAssembly/TargetInfo/WebAssemblyTargetInfo.cpp +++ b/llvm/lib/Target/WebAssembly/TargetInfo/WebAssemblyTargetInfo.cpp @@ -37,4 +37,5 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeWebAssemblyTargetInfo() { // which have to be in a shared location between CodeGen and MC. #define GET_INSTRMAP_INFO 1 #define GET_INSTRINFO_ENUM 1 +#define GET_INSTRINFO_MC_HELPER_DECLS #include "WebAssemblyGenInstrInfo.inc" diff --git a/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp b/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp index 0f1655718481..f380b2582c65 100644 --- a/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp +++ b/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp @@ -13,6 +13,7 @@ #include "WebAssemblyTypeUtilities.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/CodeGen/TargetRegisterInfo.h" // Get register classes enum. #define GET_REGINFO_ENUM @@ -168,6 +169,11 @@ wasm::ValType WebAssembly::regClassToValType(unsigned RC) { } } +wasm::ValType WebAssembly::regClassToValType(const TargetRegisterClass *RC) { + assert(RC != nullptr); + return regClassToValType(RC->getID()); +} + void WebAssembly::wasmSymbolSetType(MCSymbolWasm *Sym, const Type *GlobalVT, const SmallVector<MVT, 1> &VTs) { assert(!Sym->getType()); @@ -175,33 +181,28 @@ void WebAssembly::wasmSymbolSetType(MCSymbolWasm *Sym, const Type *GlobalVT, // Tables are represented as Arrays in LLVM IR therefore // they reach this point as aggregate Array types with an element type // that is a reference type. - wasm::ValType Type; + wasm::ValType ValTy; bool IsTable = false; if (GlobalVT->isArrayTy() && WebAssembly::isRefType(GlobalVT->getArrayElementType())) { - MVT VT; IsTable = true; - switch (GlobalVT->getArrayElementType()->getPointerAddressSpace()) { - case WebAssembly::WasmAddressSpace::WASM_ADDRESS_SPACE_FUNCREF: - VT = MVT::funcref; - break; - case WebAssembly::WasmAddressSpace::WASM_ADDRESS_SPACE_EXTERNREF: - VT = MVT::externref; - break; - default: - report_fatal_error("unhandled address space type"); - } - Type = WebAssembly::toValType(VT); + const Type *ElTy = GlobalVT->getArrayElementType(); + if (WebAssembly::isExternrefType(ElTy)) + ValTy = wasm::ValType::EXTERNREF; + else if (WebAssembly::isFuncrefType(ElTy)) + ValTy = wasm::ValType::FUNCREF; + else + report_fatal_error("unhandled reference type"); } else if (VTs.size() == 1) { - Type = WebAssembly::toValType(VTs[0]); + ValTy = WebAssembly::toValType(VTs[0]); } else report_fatal_error("Aggregate globals not yet implemented"); if (IsTable) { Sym->setType(wasm::WASM_SYMBOL_TYPE_TABLE); - Sym->setTableType(Type); + Sym->setTableType(ValTy); } else { Sym->setType(wasm::WASM_SYMBOL_TYPE_GLOBAL); - Sym->setGlobalType(wasm::WasmGlobalType{uint8_t(Type), /*Mutable=*/true}); + Sym->setGlobalType(wasm::WasmGlobalType{uint8_t(ValTy), /*Mutable=*/true}); } } diff --git a/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h b/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h index 8fc67d37925c..86211700c70a 100644 --- a/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h +++ b/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h @@ -22,6 +22,9 @@ #include "llvm/Support/MachineValueType.h" namespace llvm { + +class TargetRegisterClass; + namespace WebAssembly { /// Used as immediate MachineOperands for block signatures @@ -108,9 +111,12 @@ std::string signatureToString(const wasm::WasmSignature *Sig); // Convert a MVT into its corresponding wasm ValType. wasm::ValType toValType(MVT Type); -// Convert a register class to a wasm ValType. +// Convert a register class ID to a wasm ValType. wasm::ValType regClassToValType(unsigned RC); +// Convert a register class to a wasm ValType. +wasm::ValType regClassToValType(const TargetRegisterClass *RC); + /// Sets a Wasm Symbol Type. void wasmSymbolSetType(MCSymbolWasm *Sym, const Type *GlobalVT, const SmallVector<MVT, 1> &VTs); diff --git a/llvm/lib/Target/WebAssembly/Utils/WebAssemblyUtilities.cpp b/llvm/lib/Target/WebAssembly/Utils/WebAssemblyUtilities.cpp index b87c884c9e4a..277bbee83a6f 100644 --- a/llvm/lib/Target/WebAssembly/Utils/WebAssemblyUtilities.cpp +++ b/llvm/lib/Target/WebAssembly/Utils/WebAssemblyUtilities.cpp @@ -179,3 +179,25 @@ MachineInstr *WebAssembly::findCatch(MachineBasicBlock *EHPad) { return &*Pos; return nullptr; } + +unsigned WebAssembly::getCopyOpcodeForRegClass(const TargetRegisterClass *RC) { + assert(RC != nullptr); + switch (RC->getID()) { + case WebAssembly::I32RegClassID: + return WebAssembly::COPY_I32; + case WebAssembly::I64RegClassID: + return WebAssembly::COPY_I64; + case WebAssembly::F32RegClassID: + return WebAssembly::COPY_F32; + case WebAssembly::F64RegClassID: + return WebAssembly::COPY_F64; + case WebAssembly::V128RegClassID: + return WebAssembly::COPY_V128; + case WebAssembly::FUNCREFRegClassID: + return WebAssembly::COPY_FUNCREF; + case WebAssembly::EXTERNREFRegClassID: + return WebAssembly::COPY_EXTERNREF; + default: + llvm_unreachable("Unexpected register class"); + } +} diff --git a/llvm/lib/Target/WebAssembly/Utils/WebAssemblyUtilities.h b/llvm/lib/Target/WebAssembly/Utils/WebAssemblyUtilities.h index cdfc758db7ac..d0639208fda9 100644 --- a/llvm/lib/Target/WebAssembly/Utils/WebAssemblyUtilities.h +++ b/llvm/lib/Target/WebAssembly/Utils/WebAssemblyUtilities.h @@ -24,6 +24,7 @@ class MachineInstr; class MachineOperand; class MCContext; class MCSymbolWasm; +class TargetRegisterClass; class WebAssemblyFunctionInfo; class WebAssemblySubtarget; @@ -65,6 +66,9 @@ getOrCreateFuncrefCallTableSymbol(MCContext &Ctx, /// instruction found or the catch is in an invalid location. MachineInstr *findCatch(MachineBasicBlock *EHPad); +/// Returns the appropriate copy opcode for the given register class. +unsigned getCopyOpcodeForRegClass(const TargetRegisterClass *RC); + } // end namespace WebAssembly } // end namespace llvm diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp index 57d51634e849..bcb6cf1b4e1d 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp @@ -597,6 +597,8 @@ void WebAssemblyAsmPrinter::emitFunctionBodyStart() { void WebAssemblyAsmPrinter::emitInstruction(const MachineInstr *MI) { LLVM_DEBUG(dbgs() << "EmitInstruction: " << *MI << '\n'); + WebAssembly_MC::verifyInstructionPredicates(MI->getOpcode(), + Subtarget->getFeatureBits()); switch (MI->getOpcode()) { case WebAssembly::ARGUMENT_i32: diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp index 02e873a0f9a6..d2eb4b29e9fd 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp @@ -781,25 +781,6 @@ void WebAssemblyCFGStackify::removeUnnecessaryInstrs(MachineFunction &MF) { } } -// Get the appropriate copy opcode for the given register class. -static unsigned getCopyOpcode(const TargetRegisterClass *RC) { - if (RC == &WebAssembly::I32RegClass) - return WebAssembly::COPY_I32; - if (RC == &WebAssembly::I64RegClass) - return WebAssembly::COPY_I64; - if (RC == &WebAssembly::F32RegClass) - return WebAssembly::COPY_F32; - if (RC == &WebAssembly::F64RegClass) - return WebAssembly::COPY_F64; - if (RC == &WebAssembly::V128RegClass) - return WebAssembly::COPY_V128; - if (RC == &WebAssembly::FUNCREFRegClass) - return WebAssembly::COPY_FUNCREF; - if (RC == &WebAssembly::EXTERNREFRegClass) - return WebAssembly::COPY_EXTERNREF; - llvm_unreachable("Unexpected register class"); -} - // When MBB is split into MBB and Split, we should unstackify defs in MBB that // have their uses in Split. static void unstackifyVRegsUsedInSplitBB(MachineBasicBlock &MBB, @@ -851,7 +832,8 @@ static void unstackifyVRegsUsedInSplitBB(MachineBasicBlock &MBB, if (!MFI.isVRegStackified(TeeReg)) { // Now we are not using TEE anymore, so unstackify DefReg too MFI.unstackifyVReg(DefReg); - unsigned CopyOpc = getCopyOpcode(MRI.getRegClass(DefReg)); + unsigned CopyOpc = + WebAssembly::getCopyOpcodeForRegClass(MRI.getRegClass(DefReg)); BuildMI(MBB, &MI, MI.getDebugLoc(), TII.get(CopyOpc), TeeReg) .addReg(DefReg); BuildMI(MBB, &MI, MI.getDebugLoc(), TII.get(CopyOpc), Reg).addReg(DefReg); diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp index 5484c0db7775..9316826e3d92 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp @@ -66,23 +66,7 @@ void WebAssemblyInstrInfo::copyPhysReg(MachineBasicBlock &MBB, ? MRI.getRegClass(DestReg) : MRI.getTargetRegisterInfo()->getMinimalPhysRegClass(DestReg); - unsigned CopyOpcode; - if (RC == &WebAssembly::I32RegClass) - CopyOpcode = WebAssembly::COPY_I32; - else if (RC == &WebAssembly::I64RegClass) - CopyOpcode = WebAssembly::COPY_I64; - else if (RC == &WebAssembly::F32RegClass) - CopyOpcode = WebAssembly::COPY_F32; - else if (RC == &WebAssembly::F64RegClass) - CopyOpcode = WebAssembly::COPY_F64; - else if (RC == &WebAssembly::V128RegClass) - CopyOpcode = WebAssembly::COPY_V128; - else if (RC == &WebAssembly::FUNCREFRegClass) - CopyOpcode = WebAssembly::COPY_FUNCREF; - else if (RC == &WebAssembly::EXTERNREFRegClass) - CopyOpcode = WebAssembly::COPY_EXTERNREF; - else - llvm_unreachable("Unexpected register class"); + unsigned CopyOpcode = WebAssembly::getCopyOpcodeForRegClass(RC); BuildMI(MBB, I, DL, get(CopyOpcode), DestReg) .addReg(SrcReg, KillSrc ? RegState::Kill : 0); diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp index 2db4bd822349..7a1a769c6b16 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp @@ -553,7 +553,7 @@ Value *WebAssemblyLowerEmscriptenEHSjLj::wrapInvoke(CallBase *CI) { std::tie(SizeArg, NEltArg) = FnAttrs.getAllocSizeArgs(); SizeArg += 1; if (NEltArg) - NEltArg = NEltArg.getValue() + 1; + NEltArg = NEltArg.value() + 1; FnAttrs.addAllocSizeAttr(SizeArg, NEltArg); } // In case the callee has 'noreturn' attribute, We need to remove it, because diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp index 2e6027a5605c..e8b3542df12f 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp @@ -154,25 +154,6 @@ MCOperand WebAssemblyMCInstLower::lowerTypeIndexOperand( return MCOperand::createExpr(Expr); } -// Return the WebAssembly type associated with the given register class. -static wasm::ValType getType(const TargetRegisterClass *RC) { - if (RC == &WebAssembly::I32RegClass) - return wasm::ValType::I32; - if (RC == &WebAssembly::I64RegClass) - return wasm::ValType::I64; - if (RC == &WebAssembly::F32RegClass) - return wasm::ValType::F32; - if (RC == &WebAssembly::F64RegClass) - return wasm::ValType::F64; - if (RC == &WebAssembly::V128RegClass) - return wasm::ValType::V128; - if (RC == &WebAssembly::EXTERNREFRegClass) - return wasm::ValType::EXTERNREF; - if (RC == &WebAssembly::FUNCREFRegClass) - return wasm::ValType::FUNCREF; - llvm_unreachable("Unexpected register class"); -} - static void getFunctionReturns(const MachineInstr *MI, SmallVectorImpl<wasm::ValType> &Returns) { const Function &F = MI->getMF()->getFunction(); @@ -221,10 +202,12 @@ void WebAssemblyMCInstLower::lower(const MachineInstr *MI, const MachineRegisterInfo &MRI = MI->getParent()->getParent()->getRegInfo(); for (const MachineOperand &MO : MI->defs()) - Returns.push_back(getType(MRI.getRegClass(MO.getReg()))); + Returns.push_back( + WebAssembly::regClassToValType(MRI.getRegClass(MO.getReg()))); for (const MachineOperand &MO : MI->explicit_uses()) if (MO.isReg()) - Params.push_back(getType(MRI.getRegClass(MO.getReg()))); + Params.push_back( + WebAssembly::regClassToValType(MRI.getRegClass(MO.getReg()))); // call_indirect instructions have a callee operand at the end which // doesn't count as a param. diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyPeephole.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyPeephole.cpp index ba1c4b7233f2..5fcee7af9bde 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyPeephole.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyPeephole.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "MCTargetDesc/WebAssemblyMCTargetDesc.h" +#include "Utils/WebAssemblyUtilities.h" #include "WebAssembly.h" #include "WebAssemblyMachineFunctionInfo.h" #include "WebAssemblySubtarget.h" @@ -95,31 +96,7 @@ static bool maybeRewriteToFallthrough(MachineInstr &MI, MachineBasicBlock &MBB, if (!MFI.isVRegStackified(Reg)) { unsigned CopyLocalOpc; const TargetRegisterClass *RegClass = MRI.getRegClass(Reg); - switch (RegClass->getID()) { - case WebAssembly::I32RegClassID: - CopyLocalOpc = WebAssembly::COPY_I32; - break; - case WebAssembly::I64RegClassID: - CopyLocalOpc = WebAssembly::COPY_I64; - break; - case WebAssembly::F32RegClassID: - CopyLocalOpc = WebAssembly::COPY_F32; - break; - case WebAssembly::F64RegClassID: - CopyLocalOpc = WebAssembly::COPY_F64; - break; - case WebAssembly::V128RegClassID: - CopyLocalOpc = WebAssembly::COPY_V128; - break; - case WebAssembly::FUNCREFRegClassID: - CopyLocalOpc = WebAssembly::COPY_FUNCREF; - break; - case WebAssembly::EXTERNREFRegClassID: - CopyLocalOpc = WebAssembly::COPY_EXTERNREF; - break; - default: - llvm_unreachable("Unexpected register class for return operand"); - } + CopyLocalOpc = WebAssembly::getCopyOpcodeForRegClass(RegClass); Register NewReg = MRI.createVirtualRegister(RegClass); BuildMI(MBB, MI, MI.getDebugLoc(), TII.get(CopyLocalOpc), NewReg) .addReg(Reg); diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp index 388c0f9110b7..0b3e534315d5 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp @@ -21,7 +21,6 @@ #include "WebAssemblyRuntimeLibcallSignatures.h" #include "WebAssemblySubtarget.h" #include "llvm/CodeGen/RuntimeLibcalls.h" -#include "llvm/Support/ManagedStatic.h" using namespace llvm; @@ -482,10 +481,13 @@ struct RuntimeLibcallSignatureTable { } }; -ManagedStatic<RuntimeLibcallSignatureTable> RuntimeLibcallSignatures; +RuntimeLibcallSignatureTable &getRuntimeLibcallSignatures() { + static RuntimeLibcallSignatureTable RuntimeLibcallSignatures; + return RuntimeLibcallSignatures; +} // Maps libcall names to their RTLIB::Libcall number. Builds the map in a -// constructor for use with ManagedStatic +// constructor for use with a static variable struct StaticLibcallNameMap { StringMap<RTLIB::Libcall> Map; StaticLibcallNameMap() { @@ -496,7 +498,8 @@ struct StaticLibcallNameMap { }; for (const auto &NameLibcall : NameLibcalls) { if (NameLibcall.first != nullptr && - RuntimeLibcallSignatures->Table[NameLibcall.second] != unsupported) { + getRuntimeLibcallSignatures().Table[NameLibcall.second] != + unsupported) { assert(Map.find(NameLibcall.first) == Map.end() && "duplicate libcall names in name map"); Map[NameLibcall.first] = NameLibcall.second; @@ -523,7 +526,7 @@ void llvm::getLibcallSignature(const WebAssemblySubtarget &Subtarget, wasm::ValType PtrTy = Subtarget.hasAddr64() ? wasm::ValType::I64 : wasm::ValType::I32; - auto &Table = RuntimeLibcallSignatures->Table; + auto &Table = getRuntimeLibcallSignatures().Table; switch (Table[LC]) { case func: break; @@ -885,14 +888,14 @@ void llvm::getLibcallSignature(const WebAssemblySubtarget &Subtarget, } } -static ManagedStatic<StaticLibcallNameMap> LibcallNameMap; // TODO: If the RTLIB::Libcall-taking flavor of GetSignature remains unsed // other than here, just roll its logic into this version. void llvm::getLibcallSignature(const WebAssemblySubtarget &Subtarget, StringRef Name, SmallVectorImpl<wasm::ValType> &Rets, SmallVectorImpl<wasm::ValType> &Params) { - auto &Map = LibcallNameMap->Map; + static StaticLibcallNameMap LibcallNameMap; + auto &Map = LibcallNameMap.Map; auto Val = Map.find(Name); #ifndef NDEBUG if (Val == Map.end()) { |