From 3c97f7af9e75507f12a3977bced6b91c7e2ffb2a Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 8 Nov 2010 16:10:15 +0000 Subject: [PATCH] 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 --- lib/Transforms/IPO/FunctionAttrs.cpp | 51 ++++++++++++------- .../FunctionAttrs/2008-10-04-LocalMemory.ll | 2 +- 2 files changed, 34 insertions(+), 19 deletions(-) diff --git a/lib/Transforms/IPO/FunctionAttrs.cpp b/lib/Transforms/IPO/FunctionAttrs.cpp index d464e2ee825..062e366158a 100644 --- a/lib/Transforms/IPO/FunctionAttrs.cpp +++ b/lib/Transforms/IPO/FunctionAttrs.cpp @@ -40,7 +40,7 @@ STATISTIC(NumNoAlias, "Number of function returns marked noalias"); namespace { struct FunctionAttrs : public CallGraphSCCPass { static char ID; // Pass identification, replacement for typeid - FunctionAttrs() : CallGraphSCCPass(ID) { + FunctionAttrs() : CallGraphSCCPass(ID), AA(0) { initializeFunctionAttrsPass(*PassRegistry::getPassRegistry()); } @@ -62,10 +62,14 @@ namespace { virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); + AU.addRequired(); CallGraphSCCPass::getAnalysisUsage(AU); } 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. // Detect these now, skipping to the next instruction if one is found. CallSite CS(cast(I)); - if (CS && CS.getCalledFunction()) { + if (CS) { // Ignore calls to functions in the same SCC. - if (SCCNodes.count(CS.getCalledFunction())) + if (CS.getCalledFunction() && SCCNodes.count(CS.getCalledFunction())) continue; - // Ignore intrinsics that only access local memory. - if (unsigned id = CS.getCalledFunction()->getIntrinsicID()) - if (AliasAnalysis::getIntrinsicModRefBehavior(id) == - AliasAnalysis::AccessesArguments) { - // Check that all pointer arguments point to local memory. - for (CallSite::arg_iterator CI = CS.arg_begin(), CE = CS.arg_end(); - CI != CE; ++CI) { - Value *Arg = *CI; - if (Arg->getType()->isPointerTy() && - !PointsToLocalOrConstantMemory(Arg)) - // Writes memory. Just give up. - return false; - } - // Only reads and writes local memory. - continue; + switch (AA->getModRefBehavior(CS)) { + case AliasAnalysis::DoesNotAccessMemory: + // Ignore calls that don't access memory. + continue; + case AliasAnalysis::OnlyReadsMemory: + // Handle calls that only read from memory. + ReadsMemory = true; + continue; + case AliasAnalysis::AccessesArguments: + // Check whether all pointer arguments point to local memory, and + // ignore calls that only access local memory. + for (CallSite::arg_iterator CI = CS.arg_begin(), CE = CS.arg_end(); + CI != CE; ++CI) { + Value *Arg = *CI; + 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(I)) { // Ignore non-volatile loads from local memory. if (!LI->isVolatile() && @@ -387,6 +400,8 @@ bool FunctionAttrs::AddNoAliasAttrs(const CallGraphSCC &SCC) { } bool FunctionAttrs::runOnSCC(CallGraphSCC &SCC) { + AA = &getAnalysis(); + bool Changed = AddReadAttrs(SCC); Changed |= AddNoCaptureAttrs(SCC); Changed |= AddNoAliasAttrs(SCC); diff --git a/test/Transforms/FunctionAttrs/2008-10-04-LocalMemory.ll b/test/Transforms/FunctionAttrs/2008-10-04-LocalMemory.ll index c6c2e13e33e..faac1184b60 100644 --- a/test/Transforms/FunctionAttrs/2008-10-04-LocalMemory.ll +++ b/test/Transforms/FunctionAttrs/2008-10-04-LocalMemory.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -functionattrs -S | FileCheck %s +; RUN: opt < %s -basicaa -functionattrs -S | FileCheck %s %struct.X = type { i32*, i32* }