Skip to content

Commit 46667a1

Browse files
committed
[WebAssembly] Implementation of global.get/set for reftypes in LLVM IR
Reland of 31859f8. This change implements new DAG notes GLOBAL_GET/GLOBAL_SET, and lowering methods for load and stores of reference types from IR globals. Once the lowering creates the new nodes, tablegen pattern matches those and converts them to Wasm global.get/set. Reviewed By: tlively Differential Revision: https://reviews.llvm.org/D104797
1 parent df0066a commit 46667a1

29 files changed

+403
-18
lines changed

clang/lib/Basic/Targets/WebAssembly.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,9 @@ class LLVM_LIBRARY_VISIBILITY WebAssembly32TargetInfo
150150
const TargetOptions &Opts)
151151
: WebAssemblyTargetInfo(T, Opts) {
152152
if (T.isOSEmscripten())
153-
resetDataLayout("e-m:e-p:32:32-i64:64-f128:64-n32:64-S128-ni:1");
153+
resetDataLayout("e-m:e-p:32:32-i64:64-f128:64-n32:64-S128-ni:1:10:20");
154154
else
155-
resetDataLayout("e-m:e-p:32:32-i64:64-n32:64-S128-ni:1");
155+
resetDataLayout("e-m:e-p:32:32-i64:64-n32:64-S128-ni:1:10:20");
156156
}
157157

158158
protected:
@@ -172,9 +172,9 @@ class LLVM_LIBRARY_VISIBILITY WebAssembly64TargetInfo
172172
PtrDiffType = SignedLong;
173173
IntPtrType = SignedLong;
174174
if (T.isOSEmscripten())
175-
resetDataLayout("e-m:e-p:64:64-i64:64-f128:64-n32:64-S128-ni:1");
175+
resetDataLayout("e-m:e-p:64:64-i64:64-f128:64-n32:64-S128-ni:1:10:20");
176176
else
177-
resetDataLayout("e-m:e-p:64:64-i64:64-n32:64-S128-ni:1");
177+
resetDataLayout("e-m:e-p:64:64-i64:64-n32:64-S128-ni:1:10:20");
178178
}
179179

180180
protected:

clang/test/CodeGen/target-data.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,11 +108,11 @@
108108

109109
// RUN: %clang_cc1 -triple wasm32-unknown-unknown -o - -emit-llvm %s | \
110110
// RUN: FileCheck %s -check-prefix=WEBASSEMBLY32
111-
// WEBASSEMBLY32: target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128-ni:1"
111+
// WEBASSEMBLY32: target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128-ni:1:10:20"
112112

113113
// RUN: %clang_cc1 -triple wasm64-unknown-unknown -o - -emit-llvm %s | \
114114
// RUN: FileCheck %s -check-prefix=WEBASSEMBLY64
115-
// WEBASSEMBLY64: target datalayout = "e-m:e-p:64:64-i64:64-n32:64-S128-ni:1"
115+
// WEBASSEMBLY64: target datalayout = "e-m:e-p:64:64-i64:64-n32:64-S128-ni:1:10:20"
116116

117117
// RUN: %clang_cc1 -triple lanai-unknown-unknown -o - -emit-llvm %s | \
118118
// RUN: FileCheck %s -check-prefix=LANAI

llvm/include/llvm/CodeGen/TargetLowering.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ class TargetLoweringBase {
349349
/// Return the in-memory pointer type for the given address space, defaults to
350350
/// the pointer type from the data layout. FIXME: The default needs to be
351351
/// removed once all the code is updated.
352-
MVT getPointerMemTy(const DataLayout &DL, uint32_t AS = 0) const {
352+
virtual MVT getPointerMemTy(const DataLayout &DL, uint32_t AS = 0) const {
353353
return MVT::getIntegerVT(DL.getPointerSizeInBits(AS));
354354
}
355355

llvm/include/llvm/CodeGen/ValueTypes.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,12 @@ namespace llvm {
120120
return changeExtendedTypeToInteger();
121121
}
122122

123+
/// Test if the given EVT has zero size, this will fail if called on a
124+
/// scalable type
125+
bool isZeroSized() const {
126+
return !isScalableVector() && getSizeInBits() == 0;
127+
}
128+
123129
/// Test if the given EVT is simple (as opposed to being extended).
124130
bool isSimple() const {
125131
return V.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE;
@@ -207,7 +213,9 @@ namespace llvm {
207213
}
208214

209215
/// Return true if the bit size is a multiple of 8.
210-
bool isByteSized() const { return getSizeInBits().isKnownMultipleOf(8); }
216+
bool isByteSized() const {
217+
return !isZeroSized() && getSizeInBits().isKnownMultipleOf(8);
218+
}
211219

212220
/// Return true if the size is a power-of-two number of bytes.
213221
bool isRound() const {

llvm/lib/CodeGen/CodeGenPrepare.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6465,6 +6465,10 @@ bool CodeGenPrepare::optimizeLoadExt(LoadInst *Load) {
64656465

64666466
EVT LoadResultVT = TLI->getValueType(*DL, Load->getType());
64676467
unsigned BitWidth = LoadResultVT.getSizeInBits();
6468+
// If the BitWidth is 0, do not try to optimize the type
6469+
if (BitWidth == 0)
6470+
return false;
6471+
64686472
APInt DemandBits(BitWidth, 0);
64696473
APInt WidestAndBits(BitWidth, 0);
64706474

llvm/lib/CodeGen/MachineOperand.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1180,7 +1180,7 @@ void MachineMemOperand::print(raw_ostream &OS, ModuleSlotTracker &MST,
11801180
<< "unknown-address";
11811181
}
11821182
MachineOperand::printOperandOffset(OS, getOffset());
1183-
if (getAlign() != getSize())
1183+
if (getSize() > 0 && getAlign() != getSize())
11841184
OS << ", align " << getAlign().value();
11851185
if (getAlign() != getBaseAlign())
11861186
OS << ", basealign " << getBaseAlign().value();

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23243,6 +23243,10 @@ bool DAGCombiner::parallelizeChainedStores(StoreSDNode *St) {
2324323243
if (BasePtr.getBase().isUndef())
2324423244
return false;
2324523245

23246+
// Do not handle stores to opaque types
23247+
if (St->getMemoryVT().isZeroSized())
23248+
return false;
23249+
2324623250
// BaseIndexOffset assumes that offsets are fixed-size, which
2324723251
// is not valid for scalable vectors where the offsets are
2324823252
// scaled by `vscale`, so bail out early.

llvm/lib/CodeGen/TargetLoweringBase.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1710,7 +1710,7 @@ bool TargetLoweringBase::allowsMemoryAccessForAlignment(
17101710
// For example, the ABI alignment may change based on software platform while
17111711
// this function should only be affected by hardware implementation.
17121712
Type *Ty = VT.getTypeForEVT(Context);
1713-
if (Alignment >= DL.getABITypeAlign(Ty)) {
1713+
if (VT.isZeroSized() || Alignment >= DL.getABITypeAlign(Ty)) {
17141714
// Assume that an access that meets the ABI-specified alignment is fast.
17151715
if (Fast != nullptr)
17161716
*Fast = true;

llvm/lib/CodeGen/ValueTypes.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,10 @@ Type *EVT::getTypeForEVT(LLVMContext &Context) const {
198198
case MVT::ppcf128: return Type::getPPC_FP128Ty(Context);
199199
case MVT::x86mmx: return Type::getX86_MMXTy(Context);
200200
case MVT::x86amx: return Type::getX86_AMXTy(Context);
201+
case MVT::externref:
202+
return PointerType::get(StructType::create(Context), 10);
203+
case MVT::funcref:
204+
return PointerType::get(StructType::create(Context), 20);
201205
case MVT::v1i1:
202206
return FixedVectorType::get(Type::getInt1Ty(Context), 1);
203207
case MVT::v2i1:

llvm/lib/Target/WebAssembly/Utils/WebAssemblyUtilities.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,31 @@ MCSymbolWasm *WebAssembly::getOrCreateFunctionTableSymbol(
116116
return Sym;
117117
}
118118

119+
MCSymbolWasm *WebAssembly::getOrCreateFuncrefCallTableSymbol(
120+
MCContext &Ctx, const WebAssemblySubtarget *Subtarget) {
121+
StringRef Name = "__funcref_call_table";
122+
MCSymbolWasm *Sym = cast_or_null<MCSymbolWasm>(Ctx.lookupSymbol(Name));
123+
if (Sym) {
124+
if (!Sym->isFunctionTable())
125+
Ctx.reportError(SMLoc(), "symbol is not a wasm funcref table");
126+
} else {
127+
Sym = cast<MCSymbolWasm>(Ctx.getOrCreateSymbol(Name));
128+
129+
// Setting Weak ensure only one table is left after linking when multiple
130+
// modules define the table.
131+
Sym->setWeak(true);
132+
133+
wasm::WasmLimits Limits = {0, 1, 1};
134+
wasm::WasmTableType TableType = {wasm::WASM_TYPE_FUNCREF, Limits};
135+
Sym->setType(wasm::WASM_SYMBOL_TYPE_TABLE);
136+
Sym->setTableType(TableType);
137+
}
138+
// MVP object files can't have symtab entries for tables.
139+
if (!(Subtarget && Subtarget->hasReferenceTypes()))
140+
Sym->setOmitFromLinkingSection();
141+
return Sym;
142+
}
143+
119144
// Find a catch instruction from an EH pad.
120145
MachineInstr *WebAssembly::findCatch(MachineBasicBlock *EHPad) {
121146
assert(EHPad->isEHPad());

0 commit comments

Comments
 (0)