Skip to content

Commit

Permalink
[WebAssembly][NFC] Refactor WasmSymbol type setting code
Browse files Browse the repository at this point in the history
This refactors some code dealing with setting Wasm symbol types.
Some of the code dealing with types was moved from
`WebAssemblyUtilities` to  `WebAssemblyTypeUtilities`.

Reviewed By: sbc100

Differential Revision: https://reviews.llvm.org/D118121
  • Loading branch information
pmatos committed Jan 29, 2022
1 parent d8f929a commit 864767a
Show file tree
Hide file tree
Showing 10 changed files with 106 additions and 90 deletions.
38 changes: 38 additions & 0 deletions llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.cpp
Expand Up @@ -167,3 +167,41 @@ wasm::ValType WebAssembly::regClassToValType(unsigned RC) {
llvm_unreachable("unexpected type");
}
}

void WebAssembly::wasmSymbolSetType(MCSymbolWasm *Sym, const Type *GlobalVT,
const SmallVector<MVT, 1> &VTs) {
assert(!Sym->getType());

// 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;
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);
} else if (VTs.size() == 1) {
Type = 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);
} else {
Sym->setType(wasm::WASM_SYMBOL_TYPE_GLOBAL);
Sym->setGlobalType(wasm::WasmGlobalType{uint8_t(Type), /*Mutable=*/true});
}
}
43 changes: 43 additions & 0 deletions llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h
Expand Up @@ -17,6 +17,8 @@

#include "llvm/ADT/Optional.h"
#include "llvm/BinaryFormat/Wasm.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/MC/MCSymbolWasm.h"
#include "llvm/Support/MachineValueType.h"

namespace llvm {
Expand All @@ -41,6 +43,43 @@ enum class BlockType : unsigned {
Multivalue = 0xffff,
};

enum WasmAddressSpace : unsigned {
// Default address space, for pointers to linear memory (stack, heap, data).
WASM_ADDRESS_SPACE_DEFAULT = 0,
// A non-integral address space for pointers to named objects outside of
// 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_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_VAR;
}
inline bool isValidAddressSpace(unsigned AS) {
return isDefaultAddressSpace(AS) || isWasmVarAddressSpace(AS);
}
inline bool isFuncrefType(const Type *Ty) {
return isa<PointerType>(Ty) &&
Ty->getPointerAddressSpace() ==
WasmAddressSpace::WASM_ADDRESS_SPACE_FUNCREF;
}
inline bool isExternrefType(const Type *Ty) {
return isa<PointerType>(Ty) &&
Ty->getPointerAddressSpace() ==
WasmAddressSpace::WASM_ADDRESS_SPACE_EXTERNREF;
}
inline bool isRefType(const Type *Ty) {
return isFuncrefType(Ty) || isExternrefType(Ty);
}

// Convert StringRef to ValType / HealType / BlockType

Optional<wasm::ValType> parseType(StringRef Type);
Expand Down Expand Up @@ -68,6 +107,10 @@ wasm::ValType toValType(MVT Type);
// Convert a register class to a wasm ValType.
wasm::ValType regClassToValType(unsigned RC);

/// Sets a Wasm Symbol Type.
void wasmSymbolSetType(MCSymbolWasm *Sym, const Type *GlobalVT,
const SmallVector<MVT, 1> &VTs);

} // end namespace WebAssembly
} // end namespace llvm

Expand Down
38 changes: 0 additions & 38 deletions llvm/lib/Target/WebAssembly/Utils/WebAssemblyUtilities.h
Expand Up @@ -15,7 +15,6 @@
#ifndef LLVM_LIB_TARGET_WEBASSEMBLY_UTILS_WEBASSEMBLYUTILITIES_H
#define LLVM_LIB_TARGET_WEBASSEMBLY_UTILS_WEBASSEMBLYUTILITIES_H

#include "llvm/IR/DerivedTypes.h"
#include "llvm/Support/CommandLine.h"

namespace llvm {
Expand All @@ -30,43 +29,6 @@ class WebAssemblySubtarget;

namespace WebAssembly {

enum WasmAddressSpace : unsigned {
// Default address space, for pointers to linear memory (stack, heap, data).
WASM_ADDRESS_SPACE_DEFAULT = 0,
// A non-integral address space for pointers to named objects outside of
// 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_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_VAR;
}
inline bool isValidAddressSpace(unsigned AS) {
return isDefaultAddressSpace(AS) || isWasmVarAddressSpace(AS);
}
inline bool isFuncrefType(const Type *Ty) {
return isa<PointerType>(Ty) &&
Ty->getPointerAddressSpace() ==
WasmAddressSpace::WASM_ADDRESS_SPACE_FUNCREF;
}
inline bool isExternrefType(const Type *Ty) {
return isa<PointerType>(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);

Expand Down
16 changes: 5 additions & 11 deletions llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
Expand Up @@ -181,17 +181,11 @@ void WebAssemblyAsmPrinter::emitGlobalVariable(const GlobalVariable *GV) {

if (!Sym->getType()) {
const WebAssemblyTargetLowering &TLI = *Subtarget->getTargetLowering();
SmallVector<EVT, 1> VTs;
ComputeValueVTs(TLI, GV->getParent()->getDataLayout(), GV->getValueType(),
VTs);
if (VTs.size() != 1 ||
TLI.getNumRegisters(GV->getParent()->getContext(), VTs[0]) != 1)
report_fatal_error("Aggregate globals not yet implemented");
MVT VT = TLI.getRegisterType(GV->getParent()->getContext(), VTs[0]);
bool Mutable = true;
wasm::ValType Type = WebAssembly::toValType(VT);
Sym->setType(wasm::WASM_SYMBOL_TYPE_GLOBAL);
Sym->setGlobalType(wasm::WasmGlobalType{uint8_t(Type), Mutable});
SmallVector<MVT, 1> VTs;
Type *GlobalVT = GV->getValueType();
computeLegalValueVTs(TLI, GV->getParent()->getContext(),
GV->getParent()->getDataLayout(), GlobalVT, VTs);
WebAssembly::wasmSymbolSetType(Sym, GlobalVT, VTs);
}

// If the GlobalVariable refers to a table, we handle it here instead of
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
Expand Up @@ -16,6 +16,7 @@
//===----------------------------------------------------------------------===//

#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
#include "Utils/WebAssemblyTypeUtilities.h"
#include "Utils/WebAssemblyUtilities.h"
#include "WebAssembly.h"
#include "WebAssemblyMachineFunctionInfo.h"
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp
Expand Up @@ -19,7 +19,7 @@

#include "WebAssemblyFrameLowering.h"
#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
#include "Utils/WebAssemblyUtilities.h"
#include "Utils/WebAssemblyTypeUtilities.h"
#include "WebAssembly.h"
#include "WebAssemblyInstrInfo.h"
#include "WebAssemblyMachineFunctionInfo.h"
Expand Down
Expand Up @@ -14,7 +14,7 @@
///
//===----------------------------------------------------------------------===//

#include "Utils/WebAssemblyUtilities.h"
#include "Utils/WebAssemblyTypeUtilities.h"
#include "WebAssembly.h"
#include "WebAssemblySubtarget.h"
#include "llvm/IR/InstIterator.h"
Expand Down
34 changes: 1 addition & 33 deletions llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
Expand Up @@ -59,39 +59,7 @@ WebAssemblyMCInstLower::GetGlobalAddressSymbol(const MachineOperand &MO) const {
SmallVector<MVT, 1> VTs;
computeLegalValueVTs(CurrentFunc, TM, GlobalVT, VTs);

// 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;
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);
} else if (VTs.size() == 1) {
Type = WebAssembly::toValType(VTs[0]);
} else
report_fatal_error("Aggregate globals not yet implemented");

if (IsTable) {
WasmSym->setType(wasm::WASM_SYMBOL_TYPE_TABLE);
WasmSym->setTableType(Type);
} else {
WasmSym->setType(wasm::WASM_SYMBOL_TYPE_GLOBAL);
WasmSym->setGlobalType(
wasm::WasmGlobalType{uint8_t(Type), /*Mutable=*/true});
}
WebAssembly::wasmSymbolSetType(WasmSym, GlobalVT, VTs);
}
return WasmSym;
}
Expand Down
18 changes: 12 additions & 6 deletions llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.cpp
Expand Up @@ -30,22 +30,28 @@ void WebAssemblyFunctionInfo::initWARegs(MachineRegisterInfo &MRI) {
WARegs.resize(MRI.getNumVirtRegs(), Reg);
}

void llvm::computeLegalValueVTs(const Function &F, const TargetMachine &TM,
void llvm::computeLegalValueVTs(const WebAssemblyTargetLowering &TLI,
LLVMContext &Ctx, const DataLayout &DL,
Type *Ty, SmallVectorImpl<MVT> &ValueVTs) {
const DataLayout &DL(F.getParent()->getDataLayout());
const WebAssemblyTargetLowering &TLI =
*TM.getSubtarget<WebAssemblySubtarget>(F).getTargetLowering();
SmallVector<EVT, 4> VTs;
ComputeValueVTs(TLI, DL, Ty, VTs);

for (EVT VT : VTs) {
unsigned NumRegs = TLI.getNumRegisters(F.getContext(), VT);
MVT RegisterVT = TLI.getRegisterType(F.getContext(), VT);
unsigned NumRegs = TLI.getNumRegisters(Ctx, VT);
MVT RegisterVT = TLI.getRegisterType(Ctx, VT);
for (unsigned I = 0; I != NumRegs; ++I)
ValueVTs.push_back(RegisterVT);
}
}

void llvm::computeLegalValueVTs(const Function &F, const TargetMachine &TM,
Type *Ty, SmallVectorImpl<MVT> &ValueVTs) {
const DataLayout &DL(F.getParent()->getDataLayout());
const WebAssemblyTargetLowering &TLI =
*TM.getSubtarget<WebAssemblySubtarget>(F).getTargetLowering();
computeLegalValueVTs(TLI, F.getContext(), DL, Ty, ValueVTs);
}

void llvm::computeSignatureVTs(const FunctionType *Ty,
const Function *TargetFunc,
const Function &ContextFunc,
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h
Expand Up @@ -166,6 +166,10 @@ class WebAssemblyFunctionInfo final : public MachineFunctionInfo {
void setWasmEHFuncInfo(WasmEHFuncInfo *Info) { WasmEHInfo = Info; }
};

void computeLegalValueVTs(const WebAssemblyTargetLowering &TLI,
LLVMContext &Ctx, const DataLayout &DL, Type *Ty,
SmallVectorImpl<MVT> &ValueVTs);

void computeLegalValueVTs(const Function &F, const TargetMachine &TM, Type *Ty,
SmallVectorImpl<MVT> &ValueVTs);

Expand Down

0 comments on commit 864767a

Please sign in to comment.