| 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 |