1 //===- InferFunctionAttrs.cpp - Infer implicit function attributes --------===// 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 #include "llvm/Transforms/IPO/InferFunctionAttrs.h" 10 #include "llvm/Analysis/TargetLibraryInfo.h" 11 #include "llvm/IR/Function.h" 12 #include "llvm/IR/LLVMContext.h" 13 #include "llvm/IR/Module.h" 14 #include "llvm/Support/Debug.h" 15 #include "llvm/Support/raw_ostream.h" 16 #include "llvm/Transforms/Utils/BuildLibCalls.h" 17 using namespace llvm; 18 19 #define DEBUG_TYPE "inferattrs" 20 21 static bool inferAllPrototypeAttributes( 22 Module &M, function_ref<TargetLibraryInfo &(Function &)> GetTLI) { 23 bool Changed = false; 24 25 for (Function &F : M.functions()) 26 // We only infer things using the prototype and the name; we don't need 27 // definitions. 28 if (F.isDeclaration() && !F.hasOptNone()) 29 Changed |= inferLibFuncAttributes(F, GetTLI(F)); 30 31 return Changed; 32 } 33 34 PreservedAnalyses InferFunctionAttrsPass::run(Module &M, 35 ModuleAnalysisManager &AM) { 36 FunctionAnalysisManager &FAM = 37 AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager(); 38 auto GetTLI = [&FAM](Function &F) -> TargetLibraryInfo & { 39 return FAM.getResult<TargetLibraryAnalysis>(F); 40 }; 41 42 if (!inferAllPrototypeAttributes(M, GetTLI)) 43 // If we didn't infer anything, preserve all analyses. 44 return PreservedAnalyses::all(); 45 46 // Otherwise, we may have changed fundamental function attributes, so clear 47 // out all the passes. 48 return PreservedAnalyses::none(); 49 } 50 51 namespace { 52 struct InferFunctionAttrsLegacyPass : public ModulePass { 53 static char ID; // Pass identification, replacement for typeid 54 InferFunctionAttrsLegacyPass() : ModulePass(ID) { 55 initializeInferFunctionAttrsLegacyPassPass( 56 *PassRegistry::getPassRegistry()); 57 } 58 59 void getAnalysisUsage(AnalysisUsage &AU) const override { 60 AU.addRequired<TargetLibraryInfoWrapperPass>(); 61 } 62 63 bool runOnModule(Module &M) override { 64 if (skipModule(M)) 65 return false; 66 67 auto GetTLI = [this](Function &F) -> TargetLibraryInfo & { 68 return this->getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F); 69 }; 70 return inferAllPrototypeAttributes(M, GetTLI); 71 } 72 }; 73 } 74 75 char InferFunctionAttrsLegacyPass::ID = 0; 76 INITIALIZE_PASS_BEGIN(InferFunctionAttrsLegacyPass, "inferattrs", 77 "Infer set function attributes", false, false) 78 INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) 79 INITIALIZE_PASS_END(InferFunctionAttrsLegacyPass, "inferattrs", 80 "Infer set function attributes", false, false) 81 82 Pass *llvm::createInferFunctionAttrsLegacyPass() { 83 return new InferFunctionAttrsLegacyPass(); 84 } 85