1 | //===- InferFunctionAttrs.cpp - Infer implicit function attributes --------===// |
---|---|
2 | // |
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 |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "llvm/Transforms/IPO/InferFunctionAttrs.h" |
10 | #include "llvm/Analysis/TargetLibraryInfo.h" |
11 | #include "llvm/IR/Function.h" |
12 | #include "llvm/IR/Module.h" |
13 | #include "llvm/Transforms/Utils/BuildLibCalls.h" |
14 | #include "llvm/Transforms/Utils/Local.h" |
15 | using namespace llvm; |
16 | |
17 | #define DEBUG_TYPE "inferattrs" |
18 | |
19 | static bool inferAllPrototypeAttributes( |
20 | Module &M, function_ref<TargetLibraryInfo &(Function &)> GetTLI) { |
21 | bool Changed = false; |
22 | |
23 | for (Function &F : M.functions()) |
24 | // We only infer things using the prototype and the name; we don't need |
25 | // definitions. This ensures libfuncs are annotated and also allows our |
26 | // CGSCC inference to avoid needing to duplicate the inference from other |
27 | // attribute logic on all calls to declarations (as declarations aren't |
28 | // explicitly visited by CGSCC passes in the new pass manager.) |
29 | if (F.isDeclaration() && !F.hasOptNone()) { |
30 | if (!F.hasFnAttribute(Kind: Attribute::NoBuiltin)) |
31 | Changed |= inferNonMandatoryLibFuncAttrs(F, TLI: GetTLI(F)); |
32 | Changed |= inferAttributesFromOthers(F); |
33 | } |
34 | |
35 | return Changed; |
36 | } |
37 | |
38 | PreservedAnalyses InferFunctionAttrsPass::run(Module &M, |
39 | ModuleAnalysisManager &AM) { |
40 | FunctionAnalysisManager &FAM = |
41 | AM.getResult<FunctionAnalysisManagerModuleProxy>(IR&: M).getManager(); |
42 | auto GetTLI = [&FAM](Function &F) -> TargetLibraryInfo & { |
43 | return FAM.getResult<TargetLibraryAnalysis>(IR&: F); |
44 | }; |
45 | |
46 | if (!inferAllPrototypeAttributes(M, GetTLI)) |
47 | // If we didn't infer anything, preserve all analyses. |
48 | return PreservedAnalyses::all(); |
49 | |
50 | // Otherwise, we may have changed fundamental function attributes, so clear |
51 | // out all the passes. |
52 | return PreservedAnalyses::none(); |
53 | } |
54 |