//
// The LLVM Compiler Infrastructure
//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//
//===----------------------------------------------------------------------===//
+#define DEBUG_TYPE "globalsmodref-aa"
#include "llvm/Analysis/Passes.h"
#include "llvm/Module.h"
#include "llvm/Pass.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/CallGraph.h"
-#include "llvm/Support/InstIterator.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/InstIterator.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/SCCIterator.h"
#include <set>
using namespace llvm;
+STATISTIC(NumNonAddrTakenGlobalVars,
+ "Number of global vars without address taken");
+STATISTIC(NumNonAddrTakenFunctions,"Number of functions without address taken");
+STATISTIC(NumNoMemFunctions, "Number of functions that do not access memory");
+STATISTIC(NumReadMemFunctions, "Number of functions that only read memory");
+STATISTIC(NumIndirectGlobalVars, "Number of indirect global objects");
+
namespace {
- Statistic
- NumNonAddrTakenGlobalVars("globalsmodref-aa",
- "Number of global vars without address taken");
- Statistic
- NumNonAddrTakenFunctions("globalsmodref-aa",
- "Number of functions without address taken");
- Statistic
- NumNoMemFunctions("globalsmodref-aa",
- "Number of functions that do not access memory");
- Statistic
- NumReadMemFunctions("globalsmodref-aa",
- "Number of functions that only read memory");
- Statistic
- NumIndirectGlobalVars("globalsmodref-aa",
- "Number of indirect global objects");
-
/// FunctionRecord - One instance of this structure is stored for every
/// function in the program. Later, the entries for these functions are
/// removed if the function is found to call an external function (in which
/// case we know nothing about it.
- struct FunctionRecord {
+ struct VISIBILITY_HIDDEN FunctionRecord {
/// GlobalInfo - Maintain mod/ref info for all of the globals without
/// addresses taken that are read or written (transitively) by this
/// function.
};
/// GlobalsModRef - The actual analysis pass.
- class GlobalsModRef : public ModulePass, public AliasAnalysis {
+ class VISIBILITY_HIDDEN GlobalsModRef
+ : public ModulePass, public AliasAnalysis {
/// NonAddressTakenGlobals - The globals that do not have their addresses
/// taken.
std::set<GlobalValue*> NonAddressTakenGlobals;
std::map<Function*, FunctionRecord> FunctionInfo;
public:
+ static char ID;
+ GlobalsModRef() : ModulePass((intptr_t)&ID) {}
+
bool runOnModule(Module &M) {
InitializeAliasAnalysis(this); // set up super class
AnalyzeGlobals(M); // find non-addr taken globals
bool AnalyzeIndirectGlobalMemory(GlobalValue *GV);
};
+ char GlobalsModRef::ID = 0;
RegisterPass<GlobalsModRef> X("globalsmodref-aa",
"Simple mod/ref analysis for globals");
RegisterAnalysisGroup<AliasAnalysis> Y(X);
} else {
return true;
}
- } else if (SetCondInst *SCI = dyn_cast<SetCondInst>(*UI)) {
- if (!isa<ConstantPointerNull>(SCI->getOperand(1)))
+ } else if (ICmpInst *ICI = dyn_cast<ICmpInst>(*UI)) {
+ if (!isa<ConstantPointerNull>(ICI->getOperand(1)))
return true; // Allow comparison against null.
} else if (FreeInst *F = dyn_cast<FreeInst>(*UI)) {
Writers.push_back(F->getParent()->getParent());
// Okay, easy case.
} else if (CallInst *CI = dyn_cast<CallInst>(Ptr)) {
Function *F = CI->getCalledFunction();
- if (!F || !F->isExternal()) return false; // Too hard to analyze.
+ if (!F || !F->isDeclaration()) return false; // Too hard to analyze.
if (F->getName() != "calloc") return false; // Not calloc.
} else {
return false; // Too hard to analyze.
if ((*I).size() != 1) {
AnalyzeSCC(*I);
} else if (Function *F = (*I)[0]->getFunction()) {
- if (!F->isExternal()) {
+ if (!F->isDeclaration()) {
// Nonexternal function.
AnalyzeSCC(*I);
} else {
// Okay, if we can't say anything about it, maybe some other alias
// analysis can.
ModRefBehavior MRB =
- AliasAnalysis::getModRefBehavior(Callee, CallSite());
+ AliasAnalysis::getModRefBehavior(Callee);
if (MRB != DoesNotAccessMemory) {
// FIXME: could make this more aggressive for functions that just
// read memory. We should just say they read all globals.
// Otherwise, if this is an allocation related to an indirect global, remove
// it.
AllocsForIndirectGlobals.erase(V);
+
+ AliasAnalysis::deleteValue(V);
}
void GlobalsModRef::copyValue(Value *From, Value *To) {
+ AliasAnalysis::copyValue(From, To);
}