1 //=== WebAssemblyRefTypeMem2Local.cpp - WebAssembly RefType Mem2Local -----===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
10 /// Assign reference type allocas to local addrspace (addrspace(1)) so that
11 /// their loads and stores can be lowered to local.gets/local.sets.
13 //===----------------------------------------------------------------------===//
15 #include "Utils/WasmAddressSpaces.h"
16 #include "Utils/WebAssemblyTypeUtilities.h"
17 #include "WebAssembly.h"
18 #include "llvm/IR/IRBuilder.h"
19 #include "llvm/IR/InstVisitor.h"
20 #include "llvm/IR/ValueHandle.h"
21 #include "llvm/Pass.h"
24 #define DEBUG_TYPE "wasm-ref-type-mem2local"
27 class WebAssemblyRefTypeMem2Local final
28 : public FunctionPass
,
29 public InstVisitor
<WebAssemblyRefTypeMem2Local
> {
30 StringRef
getPassName() const override
{
31 return "WebAssembly Reference Types Memory to Local";
34 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
36 FunctionPass::getAnalysisUsage(AU
);
39 bool runOnFunction(Function
&F
) override
;
44 WebAssemblyRefTypeMem2Local() : FunctionPass(ID
) {}
46 void visitAllocaInst(AllocaInst
&AI
);
48 } // End anonymous namespace
50 char WebAssemblyRefTypeMem2Local::ID
= 0;
51 INITIALIZE_PASS(WebAssemblyRefTypeMem2Local
, DEBUG_TYPE
,
52 "Assign reference type allocas to local address space", true,
55 FunctionPass
*llvm::createWebAssemblyRefTypeMem2Local() {
56 return new WebAssemblyRefTypeMem2Local();
59 void WebAssemblyRefTypeMem2Local::visitAllocaInst(AllocaInst
&AI
) {
60 if (WebAssembly::isWebAssemblyReferenceType(AI
.getAllocatedType())) {
62 IRBuilder
<> IRB(AI
.getContext());
63 IRB
.SetInsertPoint(&AI
);
64 auto *NewAI
= IRB
.CreateAlloca(AI
.getAllocatedType(),
65 WebAssembly::WASM_ADDRESS_SPACE_VAR
, nullptr,
66 AI
.getName() + ".var");
68 // The below is basically equivalent to AI.replaceAllUsesWith(NewAI), but we
69 // cannot use it because it requires the old and new types be the same,
70 // which is not true here because the address spaces are different.
71 if (AI
.hasValueHandle())
72 ValueHandleBase::ValueIsRAUWd(&AI
, NewAI
);
73 if (AI
.isUsedByMetadata())
74 ValueAsMetadata::handleRAUW(&AI
, NewAI
);
75 while (!AI
.materialized_use_empty()) {
76 Use
&U
= *AI
.materialized_use_begin();
84 bool WebAssemblyRefTypeMem2Local::runOnFunction(Function
&F
) {
85 LLVM_DEBUG(dbgs() << "********** WebAssembly RefType Mem2Local **********\n"
86 "********** Function: "
87 << F
.getName() << '\n');
89 if (F
.getFnAttribute("target-features")
91 .contains("+reference-types"))