[FunctionAttrs] Replace MemoryAccessKind with FMRB.

Update FunctionAttrs to use FunctionModRefBehavior instead
MemoryAccessKind.

This allows for adding support for inferring argmemonly and others,
see D121415.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D121460
This commit is contained in:
Florian Hahn 2022-03-15 19:35:54 +00:00
parent 8bd00557e3
commit 014f5bcf7a
No known key found for this signature in database
GPG Key ID: EEF712BB5E80EBBA
4 changed files with 25 additions and 45 deletions

View File

@ -15,6 +15,7 @@
#ifndef LLVM_TRANSFORMS_IPO_FUNCTIONATTRS_H
#define LLVM_TRANSFORMS_IPO_FUNCTIONATTRS_H
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/CGSCCPassManager.h"
#include "llvm/Analysis/LazyCallGraph.h"
#include "llvm/IR/ModuleSummaryIndex.h"
@ -27,17 +28,9 @@ class Function;
class Module;
class Pass;
/// The three kinds of memory access relevant to 'readonly' and
/// 'readnone' attributes.
enum MemoryAccessKind {
MAK_ReadNone = 0,
MAK_ReadOnly = 1,
MAK_MayWrite = 2,
MAK_WriteOnly = 3
};
/// Returns the memory access properties of this copy of the function.
MemoryAccessKind computeFunctionBodyMemoryAccess(Function &F, AAResults &AAR);
FunctionModRefBehavior computeFunctionBodyMemoryAccess(Function &F,
AAResults &AAR);
/// Propagate function attributes for function summaries along the index's
/// callgraph during thinlink

View File

@ -121,24 +121,16 @@ using SCCNodeSet = SmallSetVector<Function *, 8>;
/// result will be based only on AA results for the function declaration; it
/// will be assumed that some other (perhaps less optimized) version of the
/// function may be selected at link time.
static MemoryAccessKind checkFunctionMemoryAccess(Function &F, bool ThisBody,
AAResults &AAR,
const SCCNodeSet &SCCNodes) {
static FunctionModRefBehavior
checkFunctionMemoryAccess(Function &F, bool ThisBody, AAResults &AAR,
const SCCNodeSet &SCCNodes) {
FunctionModRefBehavior MRB = AAR.getModRefBehavior(&F);
if (MRB == FMRB_DoesNotAccessMemory)
// Already perfect!
return MAK_ReadNone;
return MRB;
if (!ThisBody) {
if (AliasAnalysis::onlyReadsMemory(MRB))
return MAK_ReadOnly;
if (AliasAnalysis::onlyWritesMemory(MRB))
return MAK_WriteOnly;
// Conservatively assume it reads and writes to memory.
return MAK_MayWrite;
}
if (!ThisBody)
return MRB;
// Scan the function body for instructions that may read or write memory.
bool ReadsMemory = false;
@ -232,18 +224,18 @@ static MemoryAccessKind checkFunctionMemoryAccess(Function &F, bool ThisBody,
ReadsMemory |= I.mayReadFromMemory();
}
if (WritesMemory) {
if (WritesMemory) {
if (!ReadsMemory)
return MAK_WriteOnly;
return FMRB_OnlyWritesMemory;
else
return MAK_MayWrite;
return FMRB_UnknownModRefBehavior;
}
return ReadsMemory ? MAK_ReadOnly : MAK_ReadNone;
return ReadsMemory ? FMRB_OnlyReadsMemory : FMRB_DoesNotAccessMemory;
}
MemoryAccessKind llvm::computeFunctionBodyMemoryAccess(Function &F,
AAResults &AAR) {
FunctionModRefBehavior llvm::computeFunctionBodyMemoryAccess(Function &F,
AAResults &AAR) {
return checkFunctionMemoryAccess(F, /*ThisBody=*/true, AAR, {});
}
@ -262,20 +254,14 @@ static void addMemoryAttrs(const SCCNodeSet &SCCNodes, AARGetterT &&AARGetter,
// Non-exact function definitions may not be selected at link time, and an
// alternative version that writes to memory may be selected. See the
// comment on GlobalValue::isDefinitionExact for more details.
switch (checkFunctionMemoryAccess(*F, F->hasExactDefinition(),
AAR, SCCNodes)) {
case MAK_MayWrite:
FunctionModRefBehavior FMRB =
checkFunctionMemoryAccess(*F, F->hasExactDefinition(), AAR, SCCNodes);
if (isModAndRefSet(createModRefInfo(FMRB)))
return;
case MAK_ReadOnly:
ReadsMemory = true;
break;
case MAK_WriteOnly:
WritesMemory = true;
break;
case MAK_ReadNone:
// Nothing to do!
break;
}
if (FMRB == FMRB_DoesNotAccessMemory)
continue;
ReadsMemory |= AliasAnalysis::onlyReadsMemory(FMRB);
WritesMemory |= AliasAnalysis::onlyWritesMemory(FMRB);
}
// If the SCC contains both functions that read and functions that write, then

View File

@ -311,7 +311,8 @@ void splitAndWriteThinLTOBitcode(
return;
}
if (!F->isDeclaration() &&
computeFunctionBodyMemoryAccess(*F, AARGetter(*F)) == MAK_ReadNone)
computeFunctionBodyMemoryAccess(*F, AARGetter(*F)) ==
FMRB_DoesNotAccessMemory)
EligibleVirtualFns.insert(F);
});
}

View File

@ -1740,7 +1740,7 @@ bool DevirtModule::tryVirtualConstProp(
for (VirtualCallTarget &Target : TargetsForSlot) {
if (Target.Fn->isDeclaration() ||
computeFunctionBodyMemoryAccess(*Target.Fn, AARGetter(*Target.Fn)) !=
MAK_ReadNone ||
FMRB_DoesNotAccessMemory ||
Target.Fn->arg_empty() || !Target.Fn->arg_begin()->use_empty() ||
Target.Fn->getReturnType() != RetType)
return false;