1 //===- InferFunctionAttrs.cpp - Infer implicit function attributes --------===//
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
7 //===----------------------------------------------------------------------===//
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 #include "llvm/Transforms/Utils/Local.h"
21 #define DEBUG_TYPE "inferattrs"
23 static bool inferAllPrototypeAttributes(
24 Module
&M
, function_ref
<TargetLibraryInfo
&(Function
&)> GetTLI
) {
27 for (Function
&F
: M
.functions())
28 // We only infer things using the prototype and the name; we don't need
29 // definitions. This ensures libfuncs are annotated and also allows our
30 // CGSCC inference to avoid needing to duplicate the inference from other
31 // attribute logic on all calls to declarations (as declarations aren't
32 // explicitly visited by CGSCC passes in the new pass manager.)
33 if (F
.isDeclaration() && !F
.hasOptNone()) {
34 if (!F
.hasFnAttribute(Attribute::NoBuiltin
))
35 Changed
|= inferLibFuncAttributes(F
, GetTLI(F
));
36 Changed
|= inferAttributesFromOthers(F
);
42 PreservedAnalyses
InferFunctionAttrsPass::run(Module
&M
,
43 ModuleAnalysisManager
&AM
) {
44 FunctionAnalysisManager
&FAM
=
45 AM
.getResult
<FunctionAnalysisManagerModuleProxy
>(M
).getManager();
46 auto GetTLI
= [&FAM
](Function
&F
) -> TargetLibraryInfo
& {
47 return FAM
.getResult
<TargetLibraryAnalysis
>(F
);
50 if (!inferAllPrototypeAttributes(M
, GetTLI
))
51 // If we didn't infer anything, preserve all analyses.
52 return PreservedAnalyses::all();
54 // Otherwise, we may have changed fundamental function attributes, so clear
55 // out all the passes.
56 return PreservedAnalyses::none();
60 struct InferFunctionAttrsLegacyPass
: public ModulePass
{
61 static char ID
; // Pass identification, replacement for typeid
62 InferFunctionAttrsLegacyPass() : ModulePass(ID
) {
63 initializeInferFunctionAttrsLegacyPassPass(
64 *PassRegistry::getPassRegistry());
67 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
68 AU
.addRequired
<TargetLibraryInfoWrapperPass
>();
71 bool runOnModule(Module
&M
) override
{
75 auto GetTLI
= [this](Function
&F
) -> TargetLibraryInfo
& {
76 return this->getAnalysis
<TargetLibraryInfoWrapperPass
>().getTLI(F
);
78 return inferAllPrototypeAttributes(M
, GetTLI
);
83 char InferFunctionAttrsLegacyPass::ID
= 0;
84 INITIALIZE_PASS_BEGIN(InferFunctionAttrsLegacyPass
, "inferattrs",
85 "Infer set function attributes", false, false)
86 INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass
)
87 INITIALIZE_PASS_END(InferFunctionAttrsLegacyPass
, "inferattrs",
88 "Infer set function attributes", false, false)
90 Pass
*llvm::createInferFunctionAttrsLegacyPass() {
91 return new InferFunctionAttrsLegacyPass();