• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2017, The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "GlobalAllocPass.h"
18 
19 #include "Context.h"
20 #include "RSAllocationUtils.h"
21 
22 #include "llvm/IR/GlobalVariable.h"
23 #include "llvm/IR/Module.h"
24 #include "llvm/Pass.h"
25 #include "llvm/Support/Debug.h"
26 
27 #define DEBUG_TYPE "rs2spirv-global-alloc"
28 
29 using namespace llvm;
30 
31 namespace rs2spirv {
32 
33 namespace {
collectGlobalAllocs(Module & M,SmallVectorImpl<GlobalVariable * > & GlobalAllocs)34 bool collectGlobalAllocs(Module &M,
35                          SmallVectorImpl<GlobalVariable *> &GlobalAllocs) {
36   for (auto &GV : M.globals()) {
37     if (!isRSAllocation(GV))
38       continue;
39 
40     DEBUG(GV.dump());
41     GlobalAllocs.push_back(&GV);
42   }
43 
44   return !GlobalAllocs.empty();
45 }
46 
47 //
48 // This pass would enumerate used global rs_allocations (TBD) and
49 // lowers calls to accessors of the following type:
50 //
51 //    rsGetAllocationDimX(g)
52 //
53 // to
54 //
55 //    __rsov_rsGetAllocationDimX(some uninque constant identifying g) */
56 //
57 // Note the __rsov_* variant is used as a marker for another SPIRIT
58 // transformations (see GlobalAllocSPIRITPass.cpp) to expand them into
59 // SPIR-V instructions that loads the metadata.
60 //
61 class GlobalAllocPass : public ModulePass {
62 public:
63   static char ID;
GlobalAllocPass()64   GlobalAllocPass()
65       : ModulePass(ID), Allocs(Context::getInstance().getGlobalAllocs()) {}
66 
getPassName() const67   const char *getPassName() const override { return "GlobalAllocPass"; }
68 
runOnModule(Module & M)69   bool runOnModule(Module &M) override {
70     DEBUG(dbgs() << "RS2SPIRVGlobalAllocPass\n");
71     DEBUG(M.dump());
72 
73     SmallVector<GlobalVariable *, 8> GlobalAllocs;
74     const bool CollectRes = collectGlobalAllocs(M, GlobalAllocs);
75     if (!CollectRes)
76       return false; // Module not modified.
77 
78     SmallVector<RSAllocationCallInfo, 8> Calls;
79     getRSAllocationInfo(M, Allocs);
80     getRSAllocAccesses(Allocs, Calls);
81 
82     // Lower the found accessors
83     for (auto &C : Calls) {
84       assert(C.Kind == RSAllocAccessKind::DIMX &&
85              "Unsupported type of accessor call types");
86       solidifyRSAllocAccess(M, C);
87     }
88     // Return true, as the pass modifies module.
89     DEBUG(dbgs() << "RS2SPIRVGlobalAllocPass end\n");
90     return true;
91   }
92 
93 private:
94   SmallVectorImpl<RSAllocationInfo> &Allocs;
95 };
96 
97 // A simple pass to remove all global allocations forcibly
98 class RemoveAllGlobalAllocPass : public ModulePass {
99 public:
100   static char ID;
RemoveAllGlobalAllocPass()101   RemoveAllGlobalAllocPass() : ModulePass(ID) {}
getPassName() const102   const char *getPassName() const override {
103     return "RemoveAllGlobalAllocPass";
104   }
105 
runOnModule(Module & M)106   bool runOnModule(Module &M) override {
107     DEBUG(dbgs() << "RemoveAllGlobalAllocPass\n");
108     DEBUG(M.dump());
109 
110     SmallVector<GlobalVariable *, 8> GlobalAllocs;
111     const bool CollectRes = collectGlobalAllocs(M, GlobalAllocs);
112     if (!CollectRes)
113       return false; // Module not modified.
114     // Remove global allocations
115     for (auto *G : GlobalAllocs) {
116       G->eraseFromParent();
117     }
118     DEBUG(dbgs() << "RemoveAllGlobalAllocPass end\n");
119     DEBUG(M.dump());
120     // Return true, as the pass modifies module.
121     return true;
122   }
123 };
124 
125 } // namespace
126 char GlobalAllocPass::ID = 0;
127 char RemoveAllGlobalAllocPass::ID = 0;
128 
createRemoveAllGlobalAllocPass()129 ModulePass *createRemoveAllGlobalAllocPass() {
130   return new RemoveAllGlobalAllocPass();
131 }
createGlobalAllocPass()132 ModulePass *createGlobalAllocPass() { return new GlobalAllocPass(); }
133 
134 } // namespace rs2spirv
135