File: | llvm/lib/Target/NVPTX/NVPTXLowerAlloca.cpp |
Warning: | line 74, column 20 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===-- NVPTXLowerAlloca.cpp - Make alloca to use local memory =====--===// | |||
2 | // | |||
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 | |||
6 | // | |||
7 | //===----------------------------------------------------------------------===// | |||
8 | // | |||
9 | // For all alloca instructions, and add a pair of cast to local address for | |||
10 | // each of them. For example, | |||
11 | // | |||
12 | // %A = alloca i32 | |||
13 | // store i32 0, i32* %A ; emits st.u32 | |||
14 | // | |||
15 | // will be transformed to | |||
16 | // | |||
17 | // %A = alloca i32 | |||
18 | // %Local = addrspacecast i32* %A to i32 addrspace(5)* | |||
19 | // %Generic = addrspacecast i32 addrspace(5)* %A to i32* | |||
20 | // store i32 0, i32 addrspace(5)* %Generic ; emits st.local.u32 | |||
21 | // | |||
22 | // And we will rely on NVPTXInferAddressSpaces to combine the last two | |||
23 | // instructions. | |||
24 | // | |||
25 | //===----------------------------------------------------------------------===// | |||
26 | ||||
27 | #include "NVPTX.h" | |||
28 | #include "NVPTXUtilities.h" | |||
29 | #include "MCTargetDesc/NVPTXBaseInfo.h" | |||
30 | #include "llvm/IR/Function.h" | |||
31 | #include "llvm/IR/Instructions.h" | |||
32 | #include "llvm/IR/IntrinsicInst.h" | |||
33 | #include "llvm/IR/Module.h" | |||
34 | #include "llvm/IR/Type.h" | |||
35 | #include "llvm/Pass.h" | |||
36 | ||||
37 | using namespace llvm; | |||
38 | ||||
39 | namespace llvm { | |||
40 | void initializeNVPTXLowerAllocaPass(PassRegistry &); | |||
41 | } | |||
42 | ||||
43 | namespace { | |||
44 | class NVPTXLowerAlloca : public FunctionPass { | |||
45 | bool runOnFunction(Function &F) override; | |||
46 | ||||
47 | public: | |||
48 | static char ID; // Pass identification, replacement for typeid | |||
49 | NVPTXLowerAlloca() : FunctionPass(ID) {} | |||
50 | StringRef getPassName() const override { | |||
51 | return "convert address space of alloca'ed memory to local"; | |||
52 | } | |||
53 | }; | |||
54 | } // namespace | |||
55 | ||||
56 | char NVPTXLowerAlloca::ID = 1; | |||
57 | ||||
58 | INITIALIZE_PASS(NVPTXLowerAlloca, "nvptx-lower-alloca",static void *initializeNVPTXLowerAllocaPassOnce(PassRegistry & Registry) { PassInfo *PI = new PassInfo( "Lower Alloca", "nvptx-lower-alloca" , &NVPTXLowerAlloca::ID, PassInfo::NormalCtor_t(callDefaultCtor <NVPTXLowerAlloca>), false, false); Registry.registerPass (*PI, true); return PI; } static llvm::once_flag InitializeNVPTXLowerAllocaPassFlag ; void llvm::initializeNVPTXLowerAllocaPass(PassRegistry & Registry) { llvm::call_once(InitializeNVPTXLowerAllocaPassFlag , initializeNVPTXLowerAllocaPassOnce, std::ref(Registry)); } | |||
59 | "Lower Alloca", false, false)static void *initializeNVPTXLowerAllocaPassOnce(PassRegistry & Registry) { PassInfo *PI = new PassInfo( "Lower Alloca", "nvptx-lower-alloca" , &NVPTXLowerAlloca::ID, PassInfo::NormalCtor_t(callDefaultCtor <NVPTXLowerAlloca>), false, false); Registry.registerPass (*PI, true); return PI; } static llvm::once_flag InitializeNVPTXLowerAllocaPassFlag ; void llvm::initializeNVPTXLowerAllocaPass(PassRegistry & Registry) { llvm::call_once(InitializeNVPTXLowerAllocaPassFlag , initializeNVPTXLowerAllocaPassOnce, std::ref(Registry)); } | |||
60 | ||||
61 | // ============================================================================= | |||
62 | // Main function for this pass. | |||
63 | // ============================================================================= | |||
64 | bool NVPTXLowerAlloca::runOnFunction(Function &F) { | |||
65 | if (skipFunction(F)) | |||
| ||||
66 | return false; | |||
67 | ||||
68 | bool Changed = false; | |||
69 | for (auto &BB : F) | |||
70 | for (auto &I : BB) { | |||
71 | if (auto allocaInst
| |||
72 | Changed = true; | |||
73 | auto PTy = dyn_cast<PointerType>(allocaInst->getType()); | |||
74 | auto ETy = PTy->getElementType(); | |||
| ||||
75 | auto LocalAddrTy = PointerType::get(ETy, ADDRESS_SPACE_LOCAL); | |||
76 | auto NewASCToLocal = new AddrSpaceCastInst(allocaInst, LocalAddrTy, ""); | |||
77 | auto GenericAddrTy = PointerType::get(ETy, ADDRESS_SPACE_GENERIC); | |||
78 | auto NewASCToGeneric = | |||
79 | new AddrSpaceCastInst(NewASCToLocal, GenericAddrTy, ""); | |||
80 | NewASCToLocal->insertAfter(allocaInst); | |||
81 | NewASCToGeneric->insertAfter(NewASCToLocal); | |||
82 | for (Value::use_iterator UI = allocaInst->use_begin(), | |||
83 | UE = allocaInst->use_end(); | |||
84 | UI != UE;) { | |||
85 | // Check Load, Store, GEP, and BitCast Uses on alloca and make them | |||
86 | // use the converted generic address, in order to expose non-generic | |||
87 | // addrspacecast to NVPTXInferAddressSpaces. For other types | |||
88 | // of instructions this is unnecessary and may introduce redundant | |||
89 | // address cast. | |||
90 | const auto &AllocaUse = *UI++; | |||
91 | auto LI = dyn_cast<LoadInst>(AllocaUse.getUser()); | |||
92 | if (LI && LI->getPointerOperand() == allocaInst && | |||
93 | !LI->isVolatile()) { | |||
94 | LI->setOperand(LI->getPointerOperandIndex(), NewASCToGeneric); | |||
95 | continue; | |||
96 | } | |||
97 | auto SI = dyn_cast<StoreInst>(AllocaUse.getUser()); | |||
98 | if (SI && SI->getPointerOperand() == allocaInst && | |||
99 | !SI->isVolatile()) { | |||
100 | SI->setOperand(SI->getPointerOperandIndex(), NewASCToGeneric); | |||
101 | continue; | |||
102 | } | |||
103 | auto GI = dyn_cast<GetElementPtrInst>(AllocaUse.getUser()); | |||
104 | if (GI && GI->getPointerOperand() == allocaInst) { | |||
105 | GI->setOperand(GI->getPointerOperandIndex(), NewASCToGeneric); | |||
106 | continue; | |||
107 | } | |||
108 | auto BI = dyn_cast<BitCastInst>(AllocaUse.getUser()); | |||
109 | if (BI && BI->getOperand(0) == allocaInst) { | |||
110 | BI->setOperand(0, NewASCToGeneric); | |||
111 | continue; | |||
112 | } | |||
113 | } | |||
114 | } | |||
115 | } | |||
116 | return Changed; | |||
117 | } | |||
118 | ||||
119 | FunctionPass *llvm::createNVPTXLowerAllocaPass() { | |||
120 | return new NVPTXLowerAlloca(); | |||
121 | } |