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