/
redgpu
/
clspv
Обзор
Документация
Войти
/
redgpu
/
clspv
Код
Запросы
0
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
lib/OpenCLInlinerPass.cpp
85 строк
3 KB
alan-baker
Update llvm (#563)
15 апр 2020, 00:38
Не верифицирован
15 апр 2020, 00:38
741fd1f
Код
Авторство
О чём код?
// Copyright 2017 The Clspv Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include "llvm/IR/Constants.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Module.h" #include "llvm/Pass.h" #include "llvm/Transforms/Utils/Cloning.h" #include "Builtins.h" #include "Passes.h" using namespace llvm; using namespace clspv; #define DEBUG_TYPE "openclinliner" namespace { struct OpenCLInlinerPass : public ModulePass { static char ID; OpenCLInlinerPass() : ModulePass(ID) {} bool runOnModule(Module &M) override; }; } // namespace char OpenCLInlinerPass::ID = 0; INITIALIZE_PASS(OpenCLInlinerPass, "OpenCLInliner", "OpenCL Inliner Pass", false, false) namespace clspv { ModulePass *createOpenCLInlinerPass() { return new OpenCLInlinerPass(); } } // namespace clspv bool OpenCLInlinerPass::runOnModule(Module &M) { bool changed = false; std::list<Function *> func_list; for (auto &F : M.getFunctionList()) { // process only WorkItem functions auto &func_info = Builtins::Lookup(&F); if (func_info.getType() > Builtins::kType_WorkItem_Start && func_info.getType() < Builtins::kType_WorkItem_End) { SmallVector<CallInst *, 4> Calls; // Walk the users of the function. for (User *U : F.users()) { // Find only the calls to the function. if (CallInst *CI = dyn_cast<CallInst>(U)) { // If the called function doesn't take an argument or is using a // constant argument, add the call to the list of to-be-inlined calls. if (F.arg_empty() || isa<Constant>(CI->getArgOperand(0))) { Calls.push_back(CI); } } } for (CallInst *CI : Calls) { InlineFunctionInfo info; changed |= InlineFunction(*CI, info).isSuccess(); } func_list.push_front(&F); } } if (func_list.size() != 0) { // remove dead for (auto *F : func_list) { if (F->use_empty()) { F->eraseFromParent(); } } } return changed; }