17d523365SDimitry Andric //===- InferFunctionAttrs.cpp - Infer implicit function attributes --------===//
27d523365SDimitry Andric //
37d523365SDimitry Andric // The LLVM Compiler Infrastructure
47d523365SDimitry Andric //
57d523365SDimitry Andric // This file is distributed under the University of Illinois Open Source
67d523365SDimitry Andric // License. See LICENSE.TXT for details.
77d523365SDimitry Andric //
87d523365SDimitry Andric //===----------------------------------------------------------------------===//
97d523365SDimitry Andric
107d523365SDimitry Andric #include "llvm/Transforms/IPO/InferFunctionAttrs.h"
11*db17bf38SDimitry Andric #include "llvm/Analysis/TargetLibraryInfo.h"
127d523365SDimitry Andric #include "llvm/IR/Function.h"
137d523365SDimitry Andric #include "llvm/IR/LLVMContext.h"
147d523365SDimitry Andric #include "llvm/IR/Module.h"
157d523365SDimitry Andric #include "llvm/Support/Debug.h"
167d523365SDimitry Andric #include "llvm/Support/raw_ostream.h"
173ca95b02SDimitry Andric #include "llvm/Transforms/Utils/BuildLibCalls.h"
187d523365SDimitry Andric using namespace llvm;
197d523365SDimitry Andric
207d523365SDimitry Andric #define DEBUG_TYPE "inferattrs"
217d523365SDimitry Andric
inferAllPrototypeAttributes(Module & M,const TargetLibraryInfo & TLI)227d523365SDimitry Andric static bool inferAllPrototypeAttributes(Module &M,
237d523365SDimitry Andric const TargetLibraryInfo &TLI) {
247d523365SDimitry Andric bool Changed = false;
257d523365SDimitry Andric
267d523365SDimitry Andric for (Function &F : M.functions())
273ca95b02SDimitry Andric // We only infer things using the prototype and the name; we don't need
283ca95b02SDimitry Andric // definitions.
293ca95b02SDimitry Andric if (F.isDeclaration() && !F.hasFnAttribute((Attribute::OptimizeNone)))
303ca95b02SDimitry Andric Changed |= inferLibFuncAttributes(F, TLI);
317d523365SDimitry Andric
327d523365SDimitry Andric return Changed;
337d523365SDimitry Andric }
347d523365SDimitry Andric
run(Module & M,ModuleAnalysisManager & AM)357d523365SDimitry Andric PreservedAnalyses InferFunctionAttrsPass::run(Module &M,
36d88c1a5aSDimitry Andric ModuleAnalysisManager &AM) {
373ca95b02SDimitry Andric auto &TLI = AM.getResult<TargetLibraryAnalysis>(M);
387d523365SDimitry Andric
397d523365SDimitry Andric if (!inferAllPrototypeAttributes(M, TLI))
407d523365SDimitry Andric // If we didn't infer anything, preserve all analyses.
417d523365SDimitry Andric return PreservedAnalyses::all();
427d523365SDimitry Andric
437d523365SDimitry Andric // Otherwise, we may have changed fundamental function attributes, so clear
447d523365SDimitry Andric // out all the passes.
457d523365SDimitry Andric return PreservedAnalyses::none();
467d523365SDimitry Andric }
477d523365SDimitry Andric
487d523365SDimitry Andric namespace {
497d523365SDimitry Andric struct InferFunctionAttrsLegacyPass : public ModulePass {
507d523365SDimitry Andric static char ID; // Pass identification, replacement for typeid
InferFunctionAttrsLegacyPass__anonb04951f20111::InferFunctionAttrsLegacyPass517d523365SDimitry Andric InferFunctionAttrsLegacyPass() : ModulePass(ID) {
527d523365SDimitry Andric initializeInferFunctionAttrsLegacyPassPass(
537d523365SDimitry Andric *PassRegistry::getPassRegistry());
547d523365SDimitry Andric }
557d523365SDimitry Andric
getAnalysisUsage__anonb04951f20111::InferFunctionAttrsLegacyPass567d523365SDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override {
577d523365SDimitry Andric AU.addRequired<TargetLibraryInfoWrapperPass>();
587d523365SDimitry Andric }
597d523365SDimitry Andric
runOnModule__anonb04951f20111::InferFunctionAttrsLegacyPass607d523365SDimitry Andric bool runOnModule(Module &M) override {
613ca95b02SDimitry Andric if (skipModule(M))
623ca95b02SDimitry Andric return false;
633ca95b02SDimitry Andric
647d523365SDimitry Andric auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
657d523365SDimitry Andric return inferAllPrototypeAttributes(M, TLI);
667d523365SDimitry Andric }
677d523365SDimitry Andric };
687d523365SDimitry Andric }
697d523365SDimitry Andric
707d523365SDimitry Andric char InferFunctionAttrsLegacyPass::ID = 0;
717d523365SDimitry Andric INITIALIZE_PASS_BEGIN(InferFunctionAttrsLegacyPass, "inferattrs",
727d523365SDimitry Andric "Infer set function attributes", false, false)
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)737d523365SDimitry Andric INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
747d523365SDimitry Andric INITIALIZE_PASS_END(InferFunctionAttrsLegacyPass, "inferattrs",
757d523365SDimitry Andric "Infer set function attributes", false, false)
767d523365SDimitry Andric
777d523365SDimitry Andric Pass *llvm::createInferFunctionAttrsLegacyPass() {
787d523365SDimitry Andric return new InferFunctionAttrsLegacyPass();
797d523365SDimitry Andric }
80