constants, since doing so is irrelevant for aliasing
purposes. While this doesn't increase the total number
of functions marked readonly or readnone in MultiSource/
Applications (3089), it does result in 12 functions being
marked readnone rather than readonly.
Before:
readnone: 820
readonly: 2269
After:
readnone: 832
readonly: 2257
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@61469
91177308-0d34-0410-b5e6-
96231b3b80d8
#define DEBUG_TYPE "addreadattrs"
#include "llvm/Transforms/IPO.h"
#include "llvm/CallGraphSCCPass.h"
#define DEBUG_TYPE "addreadattrs"
#include "llvm/Transforms/IPO.h"
#include "llvm/CallGraphSCCPass.h"
+#include "llvm/GlobalVariable.h"
#include "llvm/Instructions.h"
#include "llvm/Analysis/CallGraph.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Instructions.h"
#include "llvm/Analysis/CallGraph.h"
#include "llvm/ADT/SmallPtrSet.h"
AU.setPreservesCFG();
CallGraphSCCPass::getAnalysisUsage(AU);
}
AU.setPreservesCFG();
CallGraphSCCPass::getAnalysisUsage(AU);
}
+
+ bool PointsToLocalMemory(Value *V);
Pass *llvm::createAddReadAttrsPass() { return new AddReadAttrs(); }
Pass *llvm::createAddReadAttrsPass() { return new AddReadAttrs(); }
+/// PointsToLocalMemory - Returns whether the given pointer value points to
+/// memory that is local to the function. Global constants are considered
+/// local to all functions.
+bool AddReadAttrs::PointsToLocalMemory(Value *V) {
+ V = V->getUnderlyingObject();
+ // An alloca instruction defines local memory.
+ if (isa<AllocaInst>(V))
+ return true;
+ // A global constant counts as local memory for our purposes.
+ if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V))
+ return GV->isConstant();
+ return false;
+}
+
bool AddReadAttrs::runOnSCC(const std::vector<CallGraphNode *> &SCC) {
SmallPtrSet<CallGraphNode *, 8> SCCNodes;
CallGraph &CG = getAnalysis<CallGraph>();
bool AddReadAttrs::runOnSCC(const std::vector<CallGraphNode *> &SCC) {
SmallPtrSet<CallGraphNode *, 8> SCCNodes;
CallGraph &CG = getAnalysis<CallGraph>();
if (SCCNodes.count(CG[CS.getCalledFunction()]))
continue;
} else if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
if (SCCNodes.count(CG[CS.getCalledFunction()]))
continue;
} else if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
- Value *Target = LI->getPointerOperand()->getUnderlyingObject();
// Ignore loads from local memory.
// Ignore loads from local memory.
- if (isa<AllocaInst>(Target))
+ if (PointsToLocalMemory(LI->getPointerOperand()))
continue;
} else if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
continue;
} else if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
- Value *Target = SI->getPointerOperand()->getUnderlyingObject();
// Ignore stores to local memory.
// Ignore stores to local memory.
- if (isa<AllocaInst>(Target))
+ if (PointsToLocalMemory(SI->getPointerOperand()))
--- /dev/null
+; RUN: llvm-as < %s | opt -addreadattrs | llvm-dis | grep readnone
+
+@s = external constant i8 ; <i8*> [#uses=1]
+
+define i8 @f() {
+ %tmp = load i8* @s ; <i8> [#uses=1]
+ ret i8 %tmp
+}