1 /** 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #include "transforms/builtins.h" 17 #include "transforms/passes/check_external.h" 18 #include "transforms/transform_utils.h" 19 #include "utils.h" 20 #include "llvm_ark_interface.h" 21 #include "llvm_compiler_options.h" 22 23 namespace ark::llvmbackend::passes { 24 Create()25CheckExternal CheckExternal::Create() 26 { 27 return CheckExternal(); 28 } 29 ShouldInsert(const ark::llvmbackend::LLVMCompilerOptions * options)30bool CheckExternal::ShouldInsert(const ark::llvmbackend::LLVMCompilerOptions *options) 31 { 32 return options->inlining; 33 } 34 run(llvm::Function & function,llvm::FunctionAnalysisManager &)35llvm::PreservedAnalyses CheckExternal::run(llvm::Function &function, 36 llvm::FunctionAnalysisManager & /*analysis_manager*/) 37 { 38 bool changed = false; 39 llvm::SmallVector<llvm::CallInst *> remove; 40 for (auto &block : function) { 41 for (auto &instruction : block) { 42 auto *call = llvm::dyn_cast<llvm::CallInst>(&instruction); 43 if (call == nullptr) { 44 continue; 45 } 46 auto callee = call->getCalledFunction(); 47 if (callee == nullptr || callee->isIntrinsic()) { 48 continue; 49 } 50 // Remove calls to KeepThis here since it's a convenient place: 51 // 1) It is a function pass 52 // 2) It is after DeadArgElim 53 // 3) It is before inlining 54 if (callee == ark::llvmbackend::builtins::KeepThis(function.getParent())) { 55 remove.push_back(call); 56 continue; 57 } 58 if (call->hasFnAttr(llvm::Attribute::NoInline) && !callee->isDeclaration() && 59 !call->hasFnAttr("keep-noinline") && !ark::llvmbackend::utils::HasCallsWithDeopt(*callee)) { 60 changed = true; 61 call->removeAttributeAtIndex(llvm::AttributeList::FunctionIndex, llvm::Attribute::NoInline); 62 } 63 } 64 } 65 for (auto &inst : remove) { 66 changed = true; 67 inst->eraseFromParent(); 68 } 69 return changed ? llvm::PreservedAnalyses::none() : llvm::PreservedAnalyses::all(); 70 } 71 72 } // namespace ark::llvmbackend::passes 73