Home | History | Annotate | Download | only in IPO
      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/IR/Function.h"
     13 #include "llvm/IR/LLVMContext.h"
     14 #include "llvm/IR/Module.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(Module &M,
     23                                         const TargetLibraryInfo &TLI) {
     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.hasFnAttribute((Attribute::OptimizeNone)))
     30       Changed |= inferLibFuncAttributes(F, TLI);
     31 
     32   return Changed;
     33 }
     34 
     35 PreservedAnalyses InferFunctionAttrsPass::run(Module &M,
     36                                               ModuleAnalysisManager &AM) {
     37   auto &TLI = AM.getResult<TargetLibraryAnalysis>(M);
     38 
     39   if (!inferAllPrototypeAttributes(M, TLI))
     40     // If we didn't infer anything, preserve all analyses.
     41     return PreservedAnalyses::all();
     42 
     43   // Otherwise, we may have changed fundamental function attributes, so clear
     44   // out all the passes.
     45   return PreservedAnalyses::none();
     46 }
     47 
     48 namespace {
     49 struct InferFunctionAttrsLegacyPass : public ModulePass {
     50   static char ID; // Pass identification, replacement for typeid
     51   InferFunctionAttrsLegacyPass() : ModulePass(ID) {
     52     initializeInferFunctionAttrsLegacyPassPass(
     53         *PassRegistry::getPassRegistry());
     54   }
     55 
     56   void getAnalysisUsage(AnalysisUsage &AU) const override {
     57     AU.addRequired<TargetLibraryInfoWrapperPass>();
     58   }
     59 
     60   bool runOnModule(Module &M) override {
     61     if (skipModule(M))
     62       return false;
     63 
     64     auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
     65     return inferAllPrototypeAttributes(M, TLI);
     66   }
     67 };
     68 }
     69 
     70 char InferFunctionAttrsLegacyPass::ID = 0;
     71 INITIALIZE_PASS_BEGIN(InferFunctionAttrsLegacyPass, "inferattrs",
     72                       "Infer set function attributes", false, false)
     73 INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
     74 INITIALIZE_PASS_END(InferFunctionAttrsLegacyPass, "inferattrs",
     75                     "Infer set function attributes", false, false)
     76 
     77 Pass *llvm::createInferFunctionAttrsLegacyPass() {
     78   return new InferFunctionAttrsLegacyPass();
     79 }
     80