blob: cc7a47cd9a5f1ad3037cbe8c34228472dabaa151 [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//==- CFLSteensAliasAnalysis.h - Unification-based Alias Analysis -*- C++-*-==//
2//
Andrew Walbran16937d02019-10-22 13:54:20 +01003// 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
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01006//
7//===----------------------------------------------------------------------===//
8/// \file
9/// This is the interface for LLVM's unification-based alias analysis
10/// implemented with CFL graph reachability.
11///
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_ANALYSIS_CFLSTEENSALIASANALYSIS_H
15#define LLVM_ANALYSIS_CFLSTEENSALIASANALYSIS_H
16
17#include "llvm/ADT/DenseMap.h"
18#include "llvm/ADT/Optional.h"
19#include "llvm/Analysis/AliasAnalysis.h"
20#include "llvm/Analysis/CFLAliasAnalysisUtils.h"
21#include "llvm/Analysis/MemoryLocation.h"
22#include "llvm/IR/PassManager.h"
23#include "llvm/Pass.h"
24#include "llvm/Support/Casting.h"
25#include <forward_list>
26#include <memory>
27
28namespace llvm {
29
30class Function;
31class TargetLibraryInfo;
32
33namespace cflaa {
34
35struct AliasSummary;
36
37} // end namespace cflaa
38
39class CFLSteensAAResult : public AAResultBase<CFLSteensAAResult> {
40 friend AAResultBase<CFLSteensAAResult>;
41
42 class FunctionInfo;
43
44public:
45 explicit CFLSteensAAResult(const TargetLibraryInfo &TLI);
46 CFLSteensAAResult(CFLSteensAAResult &&Arg);
47 ~CFLSteensAAResult();
48
49 /// Handle invalidation events from the new pass manager.
50 ///
51 /// By definition, this result is stateless and so remains valid.
52 bool invalidate(Function &, const PreservedAnalyses &,
53 FunctionAnalysisManager::Invalidator &) {
54 return false;
55 }
56
Andrew Scullcdfcccc2018-10-05 20:58:37 +010057 /// Inserts the given Function into the cache.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010058 void scan(Function *Fn);
59
60 void evict(Function *Fn);
61
Andrew Scullcdfcccc2018-10-05 20:58:37 +010062 /// Ensures that the given function is available in the cache.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010063 /// Returns the appropriate entry from the cache.
64 const Optional<FunctionInfo> &ensureCached(Function *Fn);
65
Andrew Scullcdfcccc2018-10-05 20:58:37 +010066 /// Get the alias summary for the given function
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010067 /// Return nullptr if the summary is not found or not available
68 const cflaa::AliasSummary *getAliasSummary(Function &Fn);
69
70 AliasResult query(const MemoryLocation &LocA, const MemoryLocation &LocB);
71
Andrew Walbran3d2c1972020-04-07 12:24:26 +010072 AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
73 AAQueryInfo &AAQI) {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010074 if (LocA.Ptr == LocB.Ptr)
75 return MustAlias;
76
77 // Comparisons between global variables and other constants should be
78 // handled by BasicAA.
79 // CFLSteensAA may report NoAlias when comparing a GlobalValue and
80 // ConstantExpr, but every query needs to have at least one Value tied to a
81 // Function, and neither GlobalValues nor ConstantExprs are.
82 if (isa<Constant>(LocA.Ptr) && isa<Constant>(LocB.Ptr))
Andrew Walbran3d2c1972020-04-07 12:24:26 +010083 return AAResultBase::alias(LocA, LocB, AAQI);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010084
85 AliasResult QueryResult = query(LocA, LocB);
86 if (QueryResult == MayAlias)
Andrew Walbran3d2c1972020-04-07 12:24:26 +010087 return AAResultBase::alias(LocA, LocB, AAQI);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010088
89 return QueryResult;
90 }
91
92private:
93 const TargetLibraryInfo &TLI;
94
Andrew Scullcdfcccc2018-10-05 20:58:37 +010095 /// Cached mapping of Functions to their StratifiedSets.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010096 /// If a function's sets are currently being built, it is marked
97 /// in the cache as an Optional without a value. This way, if we
98 /// have any kind of recursion, it is discernable from a function
99 /// that simply has empty sets.
100 DenseMap<Function *, Optional<FunctionInfo>> Cache;
101 std::forward_list<cflaa::FunctionHandle<CFLSteensAAResult>> Handles;
102
103 FunctionInfo buildSetsFrom(Function *F);
104};
105
106/// Analysis pass providing a never-invalidated alias analysis result.
107///
108/// FIXME: We really should refactor CFL to use the analysis more heavily, and
109/// in particular to leverage invalidation to trigger re-computation of sets.
110class CFLSteensAA : public AnalysisInfoMixin<CFLSteensAA> {
111 friend AnalysisInfoMixin<CFLSteensAA>;
112
113 static AnalysisKey Key;
114
115public:
116 using Result = CFLSteensAAResult;
117
118 CFLSteensAAResult run(Function &F, FunctionAnalysisManager &AM);
119};
120
121/// Legacy wrapper pass to provide the CFLSteensAAResult object.
122class CFLSteensAAWrapperPass : public ImmutablePass {
123 std::unique_ptr<CFLSteensAAResult> Result;
124
125public:
126 static char ID;
127
128 CFLSteensAAWrapperPass();
129
130 CFLSteensAAResult &getResult() { return *Result; }
131 const CFLSteensAAResult &getResult() const { return *Result; }
132
133 void initializePass() override;
134 void getAnalysisUsage(AnalysisUsage &AU) const override;
135};
136
137// createCFLSteensAAWrapperPass - This pass implements a set-based approach to
138// alias analysis.
139ImmutablePass *createCFLSteensAAWrapperPass();
140
141} // end namespace llvm
142
143#endif // LLVM_ANALYSIS_CFLSTEENSALIASANALYSIS_H