diff --git a/llvm/lib/Target/WebAssembly/Utils/WebAssemblyUtilities.h b/llvm/lib/Target/WebAssembly/Utils/WebAssemblyUtilities.h --- a/llvm/lib/Target/WebAssembly/Utils/WebAssemblyUtilities.h +++ b/llvm/lib/Target/WebAssembly/Utils/WebAssemblyUtilities.h @@ -15,6 +15,8 @@ #ifndef LLVM_LIB_TARGET_WEBASSEMBLY_UTILS_WEBASSEMBLYUTILITIES_H #define LLVM_LIB_TARGET_WEBASSEMBLY_UTILS_WEBASSEMBLYUTILITIES_H +#include "llvm/IR/DerivedTypes.h" + namespace llvm { class MachineBasicBlock; @@ -35,18 +37,35 @@ // linear memory: WebAssembly globals or WebAssembly locals. Loads and stores // to these pointers are lowered to global.get / global.set or local.get / // local.set, as appropriate. - WASM_ADDRESS_SPACE_WASM_VAR = 1 + WASM_ADDRESS_SPACE_VAR = 1, + // A non-integral address space for externref values + WASM_ADDRESS_SPACE_EXTERNREF = 10, + // A non-integral address space for funcref values + WASM_ADDRESS_SPACE_FUNCREF = 20, }; inline bool isDefaultAddressSpace(unsigned AS) { return AS == WASM_ADDRESS_SPACE_DEFAULT; } inline bool isWasmVarAddressSpace(unsigned AS) { - return AS == WASM_ADDRESS_SPACE_WASM_VAR; + return AS == WASM_ADDRESS_SPACE_VAR; } inline bool isValidAddressSpace(unsigned AS) { return isDefaultAddressSpace(AS) || isWasmVarAddressSpace(AS); } +inline bool isFuncrefType(const Type *Ty) { + return isa(Ty) && + Ty->getPointerAddressSpace() == + WasmAddressSpace::WASM_ADDRESS_SPACE_FUNCREF; +} +inline bool isExternrefType(const Type *Ty) { + return isa(Ty) && + Ty->getPointerAddressSpace() == + WasmAddressSpace::WASM_ADDRESS_SPACE_EXTERNREF; +} +inline bool isRefType(const Type *Ty) { + return isFuncrefType(Ty) || isExternrefType(Ty); +} bool isChild(const MachineInstr &MI, const WebAssemblyFunctionInfo &MFI); bool mayThrow(const MachineInstr &MI); diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h --- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h +++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h @@ -45,35 +45,8 @@ WebAssemblyTargetLowering(const TargetMachine &TM, const WebAssemblySubtarget &STI); - enum WasmAddressSpace : unsigned { - // WebAssembly uses the following address spaces: - // AS 0 : is the default address space for values in linear memory - DEFAULT = 0, - // AS 1 : is a non-integral address space for global variables - GLOBAL = 1, - // AS 10 : is a non-integral address space for externref values - EXTERNREF = 10, - // AS 20 : is a non-integral address space for funcref values - FUNCREF = 20, - }; - - MVT getPointerTy(const DataLayout &DL, uint32_t AS = 0) const override { - if (AS == WasmAddressSpace::EXTERNREF) - return MVT::externref; - if (AS == WasmAddressSpace::FUNCREF) - return MVT::funcref; - return TargetLowering::getPointerTy(DL, AS); - } - MVT getPointerMemTy(const DataLayout &DL, uint32_t AS = 0) const override { - if (AS == WasmAddressSpace::EXTERNREF) - return MVT::externref; - if (AS == WasmAddressSpace::FUNCREF) - return MVT::funcref; - return TargetLowering::getPointerMemTy(DL, AS); - } - - static bool isFuncrefType(const Type *Ty); - static bool isExternrefType(const Type *Ty); + MVT getPointerTy(const DataLayout &DL, uint32_t AS = 0) const override; + MVT getPointerMemTy(const DataLayout &DL, uint32_t AS = 0) const override; private: /// Keep a pointer to the WebAssemblySubtarget around so that we can make the diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp --- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp @@ -336,6 +336,24 @@ setMinimumJumpTableEntries(2); } +MVT WebAssemblyTargetLowering::getPointerTy(const DataLayout &DL, + uint32_t AS) const { + if (AS == WebAssembly::WasmAddressSpace::WASM_ADDRESS_SPACE_EXTERNREF) + return MVT::externref; + if (AS == WebAssembly::WasmAddressSpace::WASM_ADDRESS_SPACE_FUNCREF) + return MVT::funcref; + return TargetLowering::getPointerTy(DL, AS); +} + +MVT WebAssemblyTargetLowering::getPointerMemTy(const DataLayout &DL, + uint32_t AS) const { + if (AS == WebAssembly::WasmAddressSpace::WASM_ADDRESS_SPACE_EXTERNREF) + return MVT::externref; + if (AS == WebAssembly::WasmAddressSpace::WASM_ADDRESS_SPACE_FUNCREF) + return MVT::funcref; + return TargetLowering::getPointerMemTy(DL, AS); +} + TargetLowering::AtomicExpansionKind WebAssemblyTargetLowering::shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const { // We have wasm instructions for these @@ -1132,7 +1150,8 @@ // Lastly, if this is a call to a funcref we need to add an instruction // table.set to the chain and transform the call. - if (CLI.CB && isFuncrefType(CLI.CB->getCalledOperand()->getType())) { + if (CLI.CB && + WebAssembly::isFuncrefType(CLI.CB->getCalledOperand()->getType())) { // In the absence of function references proposal where a funcref call is // lowered to call_ref, using reference types we generate a table.set to set // the funcref to a special table used solely for this purpose, followed by @@ -1150,7 +1169,8 @@ WebAssemblyISD::TABLE_SET, DL, DAG.getVTList(MVT::Other), TableSetOps, MVT::funcref, // Machine Mem Operand args - MachinePointerInfo(WasmAddressSpace::FUNCREF), + MachinePointerInfo( + WebAssembly::WasmAddressSpace::WASM_ADDRESS_SPACE_FUNCREF), CLI.CB->getCalledOperand()->getPointerAlignment(DAG.getDataLayout()), MachineMemOperand::MOStore); @@ -1388,16 +1408,6 @@ return WebAssemblyFrameLowering::getLocalForStackObject(MF, FI->getIndex()); } -bool WebAssemblyTargetLowering::isFuncrefType(const Type *Ty) { - return isa(Ty) && - Ty->getPointerAddressSpace() == WasmAddressSpace::FUNCREF; -} - -bool WebAssemblyTargetLowering::isExternrefType(const Type *Ty) { - return isa(Ty) && - Ty->getPointerAddressSpace() == WasmAddressSpace::EXTERNREF; -} - SDValue WebAssemblyTargetLowering::LowerStore(SDValue Op, SelectionDAG &DAG) const { SDLoc DL(Op); diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp --- a/llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyLowerRefTypesIntPtrConv.cpp @@ -14,6 +14,7 @@ /// //===----------------------------------------------------------------------===// +#include "Utils/WebAssemblyUtilities.h" #include "WebAssembly.h" #include "WebAssemblySubtarget.h" #include "llvm/IR/InstIterator.h" @@ -29,8 +30,6 @@ return "WebAssembly Lower RefTypes Int-Ptr Conversions"; } - static bool isRefType(Type *T); - bool runOnFunction(Function &MF) override; public: @@ -47,11 +46,6 @@ return new WebAssemblyLowerRefTypesIntPtrConv(); } -bool WebAssemblyLowerRefTypesIntPtrConv::isRefType(Type *T) { - return WebAssemblyTargetLowering::isFuncrefType(T) || - WebAssemblyTargetLowering::isExternrefType(T); -} - bool WebAssemblyLowerRefTypesIntPtrConv::runOnFunction(Function &F) { LLVM_DEBUG(dbgs() << "********** Lower RefTypes IntPtr Convs **********\n" "********** Function: " @@ -68,8 +62,8 @@ for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) { PtrToIntInst *PTI = dyn_cast(&*I); IntToPtrInst *ITP = dyn_cast(&*I); - if (!(PTI && isRefType(PTI->getPointerOperand()->getType())) && - !(ITP && isRefType(ITP->getDestTy()))) + if (!(PTI && WebAssembly::isRefType(PTI->getPointerOperand()->getType())) && + !(ITP && WebAssembly::isRefType(ITP->getDestTy()))) continue; UndefValue *U = UndefValue::get(I->getType());