1 | //=== WebAssemblyLowerRefTypesIntPtrConv.cpp - |
2 | // Lower IntToPtr and PtrToInt on Reference Types ---===// |
3 | // |
4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
5 | // See https://llvm.org/LICENSE.txt for license information. |
6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
7 | // |
8 | //===----------------------------------------------------------------------===// |
9 | /// |
10 | /// \file |
11 | /// Lowers IntToPtr and PtrToInt instructions on reference types to |
12 | /// Trap instructions since they have been allowed to operate |
13 | /// on non-integral pointers. |
14 | /// |
15 | //===----------------------------------------------------------------------===// |
16 | |
17 | #include "Utils/WebAssemblyTypeUtilities.h" |
18 | #include "WebAssembly.h" |
19 | #include "WebAssemblySubtarget.h" |
20 | #include "llvm/IR/InstIterator.h" |
21 | #include "llvm/Pass.h" |
22 | #include <set> |
23 | |
24 | using namespace llvm; |
25 | |
26 | #define DEBUG_TYPE "wasm-lower-reftypes-intptr-conv" |
27 | |
28 | namespace { |
29 | class WebAssemblyLowerRefTypesIntPtrConv final : public FunctionPass { |
30 | StringRef getPassName() const override { |
31 | return "WebAssembly Lower RefTypes Int-Ptr Conversions" ; |
32 | } |
33 | |
34 | bool runOnFunction(Function &MF) override; |
35 | |
36 | public: |
37 | static char ID; // Pass identification |
38 | WebAssemblyLowerRefTypesIntPtrConv() : FunctionPass(ID) {} |
39 | }; |
40 | } // end anonymous namespace |
41 | |
42 | char WebAssemblyLowerRefTypesIntPtrConv::ID = 0; |
43 | INITIALIZE_PASS(WebAssemblyLowerRefTypesIntPtrConv, DEBUG_TYPE, |
44 | "WebAssembly Lower RefTypes Int-Ptr Conversions" , false, false) |
45 | |
46 | FunctionPass *llvm::createWebAssemblyLowerRefTypesIntPtrConv() { |
47 | return new WebAssemblyLowerRefTypesIntPtrConv(); |
48 | } |
49 | |
50 | bool WebAssemblyLowerRefTypesIntPtrConv::runOnFunction(Function &F) { |
51 | LLVM_DEBUG(dbgs() << "********** Lower RefTypes IntPtr Convs **********\n" |
52 | "********** Function: " |
53 | << F.getName() << '\n'); |
54 | |
55 | // This function will check for uses of ptrtoint and inttoptr on reference |
56 | // types and replace them with a trap instruction. |
57 | // |
58 | // We replace the instruction by a trap instruction |
59 | // and its uses by null in the case of inttoptr and 0 in the |
60 | // case of ptrtoint. |
61 | std::set<Instruction *> worklist; |
62 | |
63 | for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) { |
64 | PtrToIntInst *PTI = dyn_cast<PtrToIntInst>(Val: &*I); |
65 | IntToPtrInst *ITP = dyn_cast<IntToPtrInst>(Val: &*I); |
66 | if (!(PTI && WebAssembly::isWebAssemblyReferenceType( |
67 | Ty: PTI->getPointerOperand()->getType())) && |
68 | !(ITP && WebAssembly::isWebAssemblyReferenceType(Ty: ITP->getDestTy()))) |
69 | continue; |
70 | |
71 | UndefValue *U = UndefValue::get(T: I->getType()); |
72 | I->replaceAllUsesWith(V: U); |
73 | |
74 | Function *TrapIntrin = |
75 | Intrinsic::getDeclaration(M: F.getParent(), id: Intrinsic::debugtrap); |
76 | CallInst::Create(Func: TrapIntrin, Args: {}, NameStr: "" , InsertBefore: I->getIterator()); |
77 | |
78 | worklist.insert(x: &*I); |
79 | } |
80 | |
81 | // erase each instruction replaced by trap |
82 | for (Instruction *I : worklist) |
83 | I->eraseFromParent(); |
84 | |
85 | return !worklist.empty(); |
86 | } |
87 | |