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 "RemoveNonkernelsPass.h" 18 19 #include "llvm/IR/Constants.h" 20 #include "llvm/IR/Module.h" 21 #include "llvm/Pass.h" 22 #include "llvm/Support/Debug.h" 23 #include "llvm/Support/raw_ostream.h" 24 25 #include "Context.h" 26 27 #define DEBUG_TYPE "rs2spirv-remove" 28 29 using namespace llvm; 30 31 namespace rs2spirv { 32 33 namespace { 34 35 class RemoveNonkernelsPass : public ModulePass { 36 public: 37 static char ID; RemoveNonkernelsPass()38 explicit RemoveNonkernelsPass() : ModulePass(ID) {} 39 getPassName() const40 const char *getPassName() const override { return "RemoveNonkernelsPass"; } 41 runOnModule(Module & M)42 bool runOnModule(Module &M) override { 43 DEBUG(dbgs() << "RemoveNonkernelsPass\n"); 44 DEBUG(M.dump()); 45 46 rs2spirv::Context &Ctxt = rs2spirv::Context::getInstance(); 47 48 if (Ctxt.getNumForEachKernel() == 0) { 49 DEBUG(dbgs() << "RemoveNonkernelsPass detected no kernel\n"); 50 // Returns false, since no modification is made to the Module. 51 return false; 52 } 53 54 std::vector<Function *> Functions; 55 for (auto &F : M.functions()) { 56 Functions.push_back(&F); 57 } 58 59 for (auto &F : Functions) { 60 if (F->isDeclaration()) 61 continue; 62 63 if (Ctxt.isForEachKernel(F->getName())) { 64 continue; // Skip kernels. 65 } 66 67 F->replaceAllUsesWith(UndefValue::get((Type *)F->getType())); 68 F->eraseFromParent(); 69 70 DEBUG(dbgs() << "Removed:\t" << F->getName() << '\n'); 71 } 72 73 DEBUG(M.dump()); 74 DEBUG(dbgs() << "Done removal\n"); 75 76 // Returns true, because the pass modifies the Module. 77 return true; 78 } 79 }; 80 81 } // namespace 82 83 char RemoveNonkernelsPass::ID = 0; 84 createRemoveNonkernelsPass()85ModulePass *createRemoveNonkernelsPass() { 86 return new RemoveNonkernelsPass(); 87 } 88 89 } // namespace rs2spirv 90