llvm.org GIT mirror llvm / 8e38d8d
FunctionAttrs: Factor out a function for querying memory access of a specific copy of a function. NFC. This will later be used by ThinLTOBitcodeWriter to add copies of readnone functions to the regular LTO module. Differential Revision: https://reviews.llvm.org/D29695 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@295008 91177308-0d34-0410-b5e6-96231b3b80d8 Peter Collingbourne 2 years ago
2 changed file(s) with 34 addition(s) and 16 deletion(s). Raw diff Collapse all Expand all
1818 #include "llvm/IR/PassManager.h"
1919
2020 namespace llvm {
21
22 class AAResults;
23
24 /// The three kinds of memory access relevant to 'readonly' and
25 /// 'readnone' attributes.
26 enum MemoryAccessKind {
27 MAK_ReadNone = 0,
28 MAK_ReadOnly = 1,
29 MAK_MayWrite = 2
30 };
31
32 /// Returns the memory access properties of this copy of the function.
33 MemoryAccessKind computeFunctionBodyMemoryAccess(Function &F, AAResults &AAR);
2134
2235 /// Computes function attributes in post-order over the call graph.
2336 ///
6060 typedef SmallSetVector SCCNodeSet;
6161 }
6262
63 namespace {
64 /// The three kinds of memory access relevant to 'readonly' and
65 /// 'readnone' attributes.
66 enum MemoryAccessKind {
67 MAK_ReadNone = 0,
68 MAK_ReadOnly = 1,
69 MAK_MayWrite = 2
70 };
71 }
72
73 static MemoryAccessKind checkFunctionMemoryAccess(Function &F, AAResults &AAR,
63 /// Returns the memory access attribute for function F using AAR for AA results,
64 /// where SCCNodes is the current SCC.
65 ///
66 /// If ThisBody is true, this function may examine the function body and will
67 /// return a result pertaining to this copy of the function. If it is false, the
68 /// result will be based only on AA results for the function declaration; it
69 /// will be assumed that some other (perhaps less optimized) version of the
70 /// function may be selected at link time.
71 static MemoryAccessKind checkFunctionMemoryAccess(Function &F, bool ThisBody,
72 AAResults &AAR,
7473 const SCCNodeSet &SCCNodes) {
7574 FunctionModRefBehavior MRB = AAR.getModRefBehavior(&F);
7675 if (MRB == FMRB_DoesNotAccessMemory)
7776 // Already perfect!
7877 return MAK_ReadNone;
7978
80 // Non-exact function definitions may not be selected at link time, and an
81 // alternative version that writes to memory may be selected. See the comment
82 // on GlobalValue::isDefinitionExact for more details.
83 if (!F.hasExactDefinition()) {
79 if (!ThisBody) {
8480 if (AliasAnalysis::onlyReadsMemory(MRB))
8581 return MAK_ReadOnly;
8682
179175 return ReadsMemory ? MAK_ReadOnly : MAK_ReadNone;
180176 }
181177
178 MemoryAccessKind llvm::computeFunctionBodyMemoryAccess(Function &F,
179 AAResults &AAR) {
180 return checkFunctionMemoryAccess(F, /*ThisBody=*/true, AAR, {});
181 }
182
182183 /// Deduce readonly/readnone attributes for the SCC.
183184 template
184185 static bool addReadAttrs(const SCCNodeSet &SCCNodes, AARGetterT &&AARGetter) {
189190 // Call the callable parameter to look up AA results for this function.
190191 AAResults &AAR = AARGetter(*F);
191192
192 switch (checkFunctionMemoryAccess(*F, AAR, SCCNodes)) {
193 // Non-exact function definitions may not be selected at link time, and an
194 // alternative version that writes to memory may be selected. See the
195 // comment on GlobalValue::isDefinitionExact for more details.
196 switch (checkFunctionMemoryAccess(*F, F->hasExactDefinition(),
197 AAR, SCCNodes)) {
193198 case MAK_MayWrite:
194199 return false;
195200 case MAK_ReadOnly: