mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-05 03:10:41 +00:00
Make FunctionAttrs use AliasAnalysis::getModRefBehavior, now that it
knows about intrinsic functions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@118410 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
431c794ade
commit
3c97f7af9e
@ -40,7 +40,7 @@ STATISTIC(NumNoAlias, "Number of function returns marked noalias");
|
|||||||
namespace {
|
namespace {
|
||||||
struct FunctionAttrs : public CallGraphSCCPass {
|
struct FunctionAttrs : public CallGraphSCCPass {
|
||||||
static char ID; // Pass identification, replacement for typeid
|
static char ID; // Pass identification, replacement for typeid
|
||||||
FunctionAttrs() : CallGraphSCCPass(ID) {
|
FunctionAttrs() : CallGraphSCCPass(ID), AA(0) {
|
||||||
initializeFunctionAttrsPass(*PassRegistry::getPassRegistry());
|
initializeFunctionAttrsPass(*PassRegistry::getPassRegistry());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,10 +62,14 @@ namespace {
|
|||||||
|
|
||||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||||
AU.setPreservesCFG();
|
AU.setPreservesCFG();
|
||||||
|
AU.addRequired<AliasAnalysis>();
|
||||||
CallGraphSCCPass::getAnalysisUsage(AU);
|
CallGraphSCCPass::getAnalysisUsage(AU);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PointsToLocalOrConstantMemory(Value *V);
|
bool PointsToLocalOrConstantMemory(Value *V);
|
||||||
|
|
||||||
|
private:
|
||||||
|
AliasAnalysis *AA;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,26 +171,35 @@ bool FunctionAttrs::AddReadAttrs(const CallGraphSCC &SCC) {
|
|||||||
// Some instructions can be ignored even if they read or write memory.
|
// Some instructions can be ignored even if they read or write memory.
|
||||||
// Detect these now, skipping to the next instruction if one is found.
|
// Detect these now, skipping to the next instruction if one is found.
|
||||||
CallSite CS(cast<Value>(I));
|
CallSite CS(cast<Value>(I));
|
||||||
if (CS && CS.getCalledFunction()) {
|
if (CS) {
|
||||||
// Ignore calls to functions in the same SCC.
|
// Ignore calls to functions in the same SCC.
|
||||||
if (SCCNodes.count(CS.getCalledFunction()))
|
if (CS.getCalledFunction() && SCCNodes.count(CS.getCalledFunction()))
|
||||||
continue;
|
continue;
|
||||||
// Ignore intrinsics that only access local memory.
|
switch (AA->getModRefBehavior(CS)) {
|
||||||
if (unsigned id = CS.getCalledFunction()->getIntrinsicID())
|
case AliasAnalysis::DoesNotAccessMemory:
|
||||||
if (AliasAnalysis::getIntrinsicModRefBehavior(id) ==
|
// Ignore calls that don't access memory.
|
||||||
AliasAnalysis::AccessesArguments) {
|
continue;
|
||||||
// Check that all pointer arguments point to local memory.
|
case AliasAnalysis::OnlyReadsMemory:
|
||||||
for (CallSite::arg_iterator CI = CS.arg_begin(), CE = CS.arg_end();
|
// Handle calls that only read from memory.
|
||||||
CI != CE; ++CI) {
|
ReadsMemory = true;
|
||||||
Value *Arg = *CI;
|
continue;
|
||||||
if (Arg->getType()->isPointerTy() &&
|
case AliasAnalysis::AccessesArguments:
|
||||||
!PointsToLocalOrConstantMemory(Arg))
|
// Check whether all pointer arguments point to local memory, and
|
||||||
// Writes memory. Just give up.
|
// ignore calls that only access local memory.
|
||||||
return false;
|
for (CallSite::arg_iterator CI = CS.arg_begin(), CE = CS.arg_end();
|
||||||
}
|
CI != CE; ++CI) {
|
||||||
// Only reads and writes local memory.
|
Value *Arg = *CI;
|
||||||
continue;
|
if (Arg->getType()->isPointerTy() &&
|
||||||
|
!PointsToLocalOrConstantMemory(Arg))
|
||||||
|
// Writes memory. Just give up.
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
// Only reads and writes local memory.
|
||||||
|
continue;
|
||||||
|
default:
|
||||||
|
// Otherwise, be conservative.
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
|
} else if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
|
||||||
// Ignore non-volatile loads from local memory.
|
// Ignore non-volatile loads from local memory.
|
||||||
if (!LI->isVolatile() &&
|
if (!LI->isVolatile() &&
|
||||||
@ -387,6 +400,8 @@ bool FunctionAttrs::AddNoAliasAttrs(const CallGraphSCC &SCC) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool FunctionAttrs::runOnSCC(CallGraphSCC &SCC) {
|
bool FunctionAttrs::runOnSCC(CallGraphSCC &SCC) {
|
||||||
|
AA = &getAnalysis<AliasAnalysis>();
|
||||||
|
|
||||||
bool Changed = AddReadAttrs(SCC);
|
bool Changed = AddReadAttrs(SCC);
|
||||||
Changed |= AddNoCaptureAttrs(SCC);
|
Changed |= AddNoCaptureAttrs(SCC);
|
||||||
Changed |= AddNoAliasAttrs(SCC);
|
Changed |= AddNoAliasAttrs(SCC);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: opt < %s -functionattrs -S | FileCheck %s
|
; RUN: opt < %s -basicaa -functionattrs -S | FileCheck %s
|
||||||
|
|
||||||
%struct.X = type { i32*, i32* }
|
%struct.X = type { i32*, i32* }
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user