//===- InferFunctionAttrs.cpp - Infer implicit function attributes --------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include "llvm/Transforms/IPO/InferFunctionAttrs.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/IR/Function.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/Utils/BuildLibCalls.h" using namespace llvm; #define DEBUG_TYPE "inferattrs" static bool inferAllPrototypeAttributes(Module &M, const TargetLibraryInfo &TLI) { bool Changed = false; for (Function &F : M.functions()) // We only infer things using the prototype and the name; we don't need // definitions. if (F.isDeclaration() && !F.hasFnAttribute((Attribute::OptimizeNone))) Changed |= inferLibFuncAttributes(F, TLI); return Changed; } PreservedAnalyses InferFunctionAttrsPass::run(Module &M, AnalysisManager &AM) { auto &TLI = AM.getResult(M); if (!inferAllPrototypeAttributes(M, TLI)) // If we didn't infer anything, preserve all analyses. return PreservedAnalyses::all(); // Otherwise, we may have changed fundamental function attributes, so clear // out all the passes. return PreservedAnalyses::none(); } namespace { struct InferFunctionAttrsLegacyPass : public ModulePass { static char ID; // Pass identification, replacement for typeid InferFunctionAttrsLegacyPass() : ModulePass(ID) { initializeInferFunctionAttrsLegacyPassPass( *PassRegistry::getPassRegistry()); } void getAnalysisUsage(AnalysisUsage &AU) const override { AU.addRequired(); } bool runOnModule(Module &M) override { if (skipModule(M)) return false; auto &TLI = getAnalysis().getTLI(); return inferAllPrototypeAttributes(M, TLI); } }; } char InferFunctionAttrsLegacyPass::ID = 0; INITIALIZE_PASS_BEGIN(InferFunctionAttrsLegacyPass, "inferattrs", "Infer set function attributes", false, false) INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) INITIALIZE_PASS_END(InferFunctionAttrsLegacyPass, "inferattrs", "Infer set function attributes", false, false) Pass *llvm::createInferFunctionAttrsLegacyPass() { return new InferFunctionAttrsLegacyPass(); }