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