[llvm-commits] [poolalloc] r40786 - in /poolalloc/branches/SVA/lib/DSA: DataStructure.cpp Info.cpp LeafRepl.cpp Local.cpp
Andrew Lenharth
alenhar2 at cs.uiuc.edu
Fri Aug 3 10:46:27 PDT 2007
Author: alenhar2
Date: Fri Aug 3 12:46:27 2007
New Revision: 40786
URL: http://llvm.org/viewvc/llvm-project?rev=40786&view=rev
Log:
kernel stat pass and cleanup
Modified:
poolalloc/branches/SVA/lib/DSA/DataStructure.cpp
poolalloc/branches/SVA/lib/DSA/Info.cpp
poolalloc/branches/SVA/lib/DSA/LeafRepl.cpp
poolalloc/branches/SVA/lib/DSA/Local.cpp
Modified: poolalloc/branches/SVA/lib/DSA/DataStructure.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/branches/SVA/lib/DSA/DataStructure.cpp?rev=40786&r1=40785&r2=40786&view=diff
==============================================================================
--- poolalloc/branches/SVA/lib/DSA/DataStructure.cpp (original)
+++ poolalloc/branches/SVA/lib/DSA/DataStructure.cpp Fri Aug 3 12:46:27 2007
@@ -1890,7 +1890,7 @@
if (Callee->getNumReferrers() == 1 && Callee->isComplete() &&
Callee->getGlobalsList().empty()) { // No useful info?
#ifndef NDEBUG
- std::cerr << "WARNING: Useless call site found.\n";
+ std::cerr << "WARNING: Useless call site found in " << CS.getCallSite().getInstruction()->getParent()->getParent()->getName() << "\n";
#endif
Calls.erase(OldIt);
++NumDeleted;
Modified: poolalloc/branches/SVA/lib/DSA/Info.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/branches/SVA/lib/DSA/Info.cpp?rev=40786&r1=40785&r2=40786&view=diff
==============================================================================
--- poolalloc/branches/SVA/lib/DSA/Info.cpp (original)
+++ poolalloc/branches/SVA/lib/DSA/Info.cpp Fri Aug 3 12:46:27 2007
@@ -2,7 +2,12 @@
#include "llvm/Function.h"
#include "llvm/BasicBlock.h"
#include "llvm/Instructions.h"
+#include "llvm/Constants.h"
#include "llvm/ADT/Statistic.h"
+#include "llvm/Support/InstVisitor.h"
+
+#include "dsa/DataStructure.h"
+#include "dsa/DSGraph.h"
using namespace llvm;
@@ -26,3 +31,156 @@
RegisterPass<CallInfo> X("call-info", "Call Info Pass");
}
+
+struct dsstat {
+ int U;
+ int I;
+ int UI;
+ int F;
+ int T;
+ void add(DSNode* N) {
+ if (!N) return;
+ if (N->isIncomplete()) ++I;
+ if (N->isUnknownNode()) ++U;
+ if (N->isIncomplete() && N->isUnknownNode()) ++UI;
+ if (N->isNodeCompletelyFolded()) ++F;
+ ++T;
+ }
+ void print(const char* name) const {
+ std::cerr << name << ", U: " << U << "\n";
+ std::cerr << name << ", I: " << I << "\n";
+ std::cerr << name << ", UI: " << UI << "\n";
+ std::cerr << name << ", F: " << F << "\n";
+ std::cerr << name << ", T: " << T << "\n";
+ }
+ void clear() {
+ U = I = UI = F = T = 0;
+ }
+ void addNorm(struct dsstat& o) {
+ if (o.U) ++U;
+ if (o.I) ++I;
+ if (o.UI) ++UI;
+ if (o.F) ++F;
+ if (o.T) ++T;
+ }
+};
+
+namespace {
+ class LDSTCount : public FunctionPass, public InstVisitor<LDSTCount> {
+ TDDataStructures* T;
+ DSGraph* G;
+
+ struct dsstat LD;
+ struct dsstat ST;
+ struct dsstat GEP;
+ struct dsstat GEPA;
+ struct dsstat ALL;
+ struct dsstat LD_F;
+ struct dsstat ST_F;
+ struct dsstat GEP_F;
+ struct dsstat GEPA_F;
+ struct dsstat ALL_F;
+ struct dsstat LD_T;
+ struct dsstat ST_T;
+ struct dsstat GEP_T;
+ struct dsstat GEPA_T;
+ struct dsstat ALL_T;
+
+
+ public:
+ void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ AU.addRequired<TDDataStructures>();
+ }
+
+ bool doInitialization(Module &M) {
+ LD.clear();
+ ST.clear();
+ GEP.clear();
+ GEPA.clear();
+ ALL.clear();
+ LD_F.clear();
+ ST_F.clear();
+ GEP_F.clear();
+ GEPA_F.clear();
+ ALL_F.clear();
+ LD_T.clear();
+ ST_T.clear();
+ GEP_T.clear();
+ GEPA_T.clear();
+ ALL_T.clear();
+ return false;
+ }
+
+ bool doFinalization (Module &M) {
+ LD.print("Loads");
+ ST.print("Stores");
+ GEP.print("GEPs");
+ GEPA.print("Array GEPs");
+ ALL.print("All");
+ LD_F.print("Loads, Fn");
+ ST_F.print("Stores, Fn");
+ GEP_F.print("GEPs, Fn");
+ GEPA_F.print("GEPs, Fn");
+ ALL_F.print("All, Fn");
+ return false;
+ }
+
+ bool runOnFunction(Function& F) {
+ T = &getAnalysis<TDDataStructures>();
+ G = &T->getDSGraph(F);
+ visit(F);
+ LD_F.addNorm(LD_T);
+ ST_F.addNorm(ST_T);
+ GEP_F.addNorm(GEP_T);
+ GEPA_F.addNorm(GEPA_T);
+ ALL_F.addNorm(ALL_T);
+ LD_T.clear();
+ ST_T.clear();
+ GEP_T.clear();
+ GEPA_T.clear();
+ ALL_T.clear();
+ return false;
+ }
+
+ bool hasAllConstantIndices(GetElementPtrInst* G) const {
+ for (unsigned i = 1, e = G->getNumOperands(); i != e; ++i) {
+ if (!isa<ConstantInt>(G->getOperand(i)))
+ return false;
+ }
+ return true;
+ }
+
+ void visitGetElementPtrInst(User& VGEP) {
+ DSNode* N = G->getNodeForValue(VGEP.getOperand(0)).getNode();
+ if (hasAllConstantIndices(cast<GetElementPtrInst>(&VGEP))) {
+ GEP.add(N);
+ GEP_T.add(N);
+ } else {
+ GEPA.add(N);
+ GEPA_T.add(N);
+ }
+ ALL.add(N);
+ ALL_T.add(N);
+ }
+
+ void visitLoadInst(LoadInst &LI) {
+ DSNode* N = G->getNodeForValue(LI.getOperand(0)).getNode();
+ LD.add(N);
+ LD_T.add(N);
+ ALL.add(N);
+ ALL_T.add(N);
+ }
+
+ void visitStoreInst(StoreInst &SI) {
+ DSNode* N = G->getNodeForValue(SI.getOperand(1)).getNode();
+ ST.add(N);
+ ST_T.add(N);
+ ALL.add(N);
+ ALL_T.add(N);
+ }
+ };
+
+ RegisterPass<LDSTCount> Y("mem-info", "DSA memory info pass");
+
+}
Modified: poolalloc/branches/SVA/lib/DSA/LeafRepl.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/branches/SVA/lib/DSA/LeafRepl.cpp?rev=40786&r1=40785&r2=40786&view=diff
==============================================================================
--- poolalloc/branches/SVA/lib/DSA/LeafRepl.cpp (original)
+++ poolalloc/branches/SVA/lib/DSA/LeafRepl.cpp Fri Aug 3 12:46:27 2007
@@ -17,6 +17,7 @@
Statistic<> IndDirSplit("CSCloner", "Number of direct and indirect splits");
Statistic<> LeafClone("CSCloner", "Number of leaves cloned");
Statistic<> ShallowClone("CSCloner", "Number of shallow functions cloned");
+ Statistic<> ConstantClone("CSCloner", "Number of functions with constant pointers cloned");
class CSCloner : public ModulePass {
@@ -68,6 +69,57 @@
return FNew;
}
+ bool isDirect(Function* F) {
+ for (Value::use_iterator ii = F->use_begin(), ee = F->use_end();
+ ii != ee; ++ii) {
+ CallInst* CI = dyn_cast<CallInst>(*ii);
+ if (CI && CI->getCalledFunction() == F)
+ return true;
+ }
+ return false;
+ }
+
+ bool isUnknown(Function* F) {
+ for (Value::use_iterator ii = F->use_begin(), ee = F->use_end();
+ ii != ee; ++ii) {
+ CallInst* CI = dyn_cast<CallInst>(*ii);
+ if (!CI || CI->getCalledFunction() != F)
+ return true;
+ }
+ return false;
+ }
+
+ bool hasPointer(Function* F) {
+ const FunctionType* FT = F->getFunctionType();
+ if (FT->isVarArg() || isa<PointerType>(FT->getReturnType()))
+ return true;
+ else
+ for (FunctionType::param_iterator pi = FT->param_begin(), pe = FT->param_end();
+ pi != pe; ++pi)
+ if (isa<PointerType>(pi->get()))
+ return true;
+ return false;
+ }
+
+ bool hasConstArgs(CallInst* CI) {
+ for (unsigned x = 1; x < CI->getNumOperands(); ++x)
+ if (isa<Constant>(CI->getOperand(x)) && isa<PointerType>(CI->getOperand(x)->getType()))
+ return true;
+ return false;
+ }
+
+ bool hasConstArgs(Function* F) {
+ for (Value::use_iterator ii = F->use_begin(), ee = F->use_end();
+ ii != ee; ++ii) {
+ CallInst* CI = dyn_cast<CallInst>(*ii);
+ if (CI && CI->getCalledFunction() == F)
+ if (hasConstArgs(CI))
+ return true;
+ }
+ return false;
+ }
+
+
public:
bool runOnModuleI(Module& M) {
@@ -79,6 +131,7 @@
std::set<Function*> TakesPointers;
std::set<Function*> Leaf;
std::set<Function*> Shallow;
+ std::set<Function*> ConstantArgs;
std::vector<std::string> IgnoreList;
IgnoreList.push_back("kmalloc");
IgnoreList.push_back("__vmalloc");
@@ -97,22 +150,14 @@
Leaf.insert(MI);
if (isLevelOne(MI) || isLevelTwo(MI))
Shallow.insert(MI);
- for (Value::use_iterator ii = MI->use_begin(), ee = MI->use_end();
- ii != ee; ++ii) {
- CallInst* CI = dyn_cast<CallInst>(*ii);
- if (CI && CI->getCalledFunction() == MI)
- DirectCalls.insert(MI);
- else
- Unknowns.insert(MI);
- const FunctionType* FT = MI->getFunctionType();
- if (FT->isVarArg() || isa<PointerType>(FT->getReturnType()))
- TakesPointers.insert(MI);
- else
- for (FunctionType::param_iterator pi = FT->param_begin(), pe = FT->param_end();
- pi != pe; ++pi)
- if (isa<PointerType>(pi->get()))
- TakesPointers.insert(MI);
- }
+ if (isDirect(MI))
+ DirectCalls.insert(MI);
+ if (isUnknown(MI))
+ Unknowns.insert(MI);
+ if (hasPointer(MI))
+ TakesPointers.insert(MI);
+ if (hasConstArgs(MI))
+ ConstantArgs.insert(MI);
}
//now think about replicating some functions
@@ -124,17 +169,32 @@
//clone a function for the indirect calls
if (DirectCalls.find(MI) != DirectCalls.end() &&
Unknowns.find(MI) != Unknowns.end()) {
- Function* FNew = clone(MI);
- ++IndDirSplit;
changed = true;
+ ++IndDirSplit;
+ Function* FNew = clone(MI);
for (Value::use_iterator ii = MI->use_begin(), ee = MI->use_end();
ii != ee; ++ii) {
CallInst* CI = dyn_cast<CallInst>(*ii);
- if (CI && CI->getCalledFunction() == MI)
+ if (CI && CI->getCalledFunction() == MI) {
CI->setOperand(0, FNew);
+ }
}
}
-
+
+ //if it takes constants in pointer parameters
+ if (ConstantArgs.find(MI) != ConstantArgs.end() && !MI->hasOneUse() && !MI->use_empty()) {
+ for (Value::use_iterator ii = MI->use_begin(), ee = MI->use_end();
+ ii != ee; ++ii) {
+ CallInst* CI = dyn_cast<CallInst>(*ii);
+ if (CI && CI->getCalledFunction() == MI && hasConstArgs(CI)) {
+ Function* FNew = clone(MI);
+ ++ConstantClone;
+ changed = true;
+ CI->setOperand(0, FNew);
+ }
+ }
+ }
+
//if it is a leaf, clone it
if (Leaf.find(MI) != Leaf.end() && !MI->hasOneUse() && !MI->use_empty()) {
for (Value::use_iterator ii = MI->use_begin(), ee = MI->use_end();
@@ -148,7 +208,7 @@
}
}
}
-
+
//if it has only level 1 loads (aka no loads of pointers), clone it
if (Shallow.find(MI) != Shallow.end() && !MI->hasOneUse() && !MI->use_empty()) {
for (Value::use_iterator ii = MI->use_begin(), ee = MI->use_end();
@@ -162,7 +222,6 @@
}
}
}
-
}
}
return changed;
Modified: poolalloc/branches/SVA/lib/DSA/Local.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/branches/SVA/lib/DSA/Local.cpp?rev=40786&r1=40785&r2=40786&view=diff
==============================================================================
--- poolalloc/branches/SVA/lib/DSA/Local.cpp (original)
+++ poolalloc/branches/SVA/lib/DSA/Local.cpp Fri Aug 3 12:46:27 2007
@@ -50,7 +50,7 @@
static cl::opt<int>
CrashAt("dsa-crashat", cl::Hidden,
cl::desc("Crash on unknowns"));
-static bool DebugUnknown = false;
+static bool DebugUnknown = true;
static int CrashCur = 0;
DSNode *DSNode::setUnknownNodeMarker() {
if (Crash && CrashCur == CrashAt) assert(0);
@@ -306,7 +306,8 @@
isa<ConstantInt>(CE->getOperand(0)) &&
(
cast<ConstantInt>(CE->getOperand(0))->equalsInt(1) ||
- cast<ConstantInt>(CE->getOperand(0))->getZExtValue() == 0xFFFFFFFF
+ (-cast<ConstantInt>(CE->getOperand(0))->getSExtValue() <= 124 &&
+ -cast<ConstantInt>(CE->getOperand(0))->getSExtValue() >= 0)
))
NH = createNode();
else
@@ -1277,7 +1278,7 @@
DSNodeHandle Ptr = getValueDest(**CS.arg_begin());
if (Ptr.isNull()) Ptr = createNode();
Ptr.getNode()->setReadMarker();
- Type* T;
+ Type* T = 0;
if (F->getName() == "llva_readiob") T = Type::SByteTy;
if (F->getName() == "llva_readioh") T = Type::ShortTy;
if (F->getName() == "llva_readiow") T = Type::IntTy;
@@ -1289,13 +1290,14 @@
DSNodeHandle Ptr = getValueDest(**CS.arg_begin());
if (Ptr.isNull()) Ptr = createNode();
Ptr.getNode()->setReadMarker();
- Type* T;
+ Type* T = 0;
if (F->getName() == "llva_writeiob") T = Type::SByteTy;
if (F->getName() == "llva_writeioh") T = Type::ShortTy;
if (F->getName() == "llva_writeiow") T = Type::IntTy;
Ptr.getNode()->mergeTypeInfo(T, Ptr.getOffset(), false);
return true;
} else if (F->getName() == "llva_atomic_compare_and_swap" ||
+ F->getName() == "llva_atomic_compare_and_swap_p" ||
F->getName() == "llva_atomic_cas_lw" ||
F->getName() == "llva_atomic_cas_h" ||
F->getName() == "llva_atomic_cas_b" ||
@@ -1568,7 +1570,15 @@
// to track the fact that the node points to SOMETHING, just something we
// don't know about. Make an "Unknown" node.
//
- if (DebugUnknown) CI.dump();
+
+ if (ConstantInt* I = dyn_cast<ConstantInt>(CI.getOperand(0)))
+ if (-I->getSExtValue() <= 124 && -I->getSExtValue() >= 0)
+ setDestTo(CI, createNode());
+
+ if (DebugUnknown) {
+ std::cerr << "In " << CI.getParent()->getParent()->getName() << " ";
+ CI.dump();
+ }
setDestTo(CI, createNode()->setUnknownNodeMarker());
}
}
@@ -1586,7 +1596,10 @@
CurNode.mergeWith(getValueDest(**I));
if (DSNode *N = CurNode.getNode()) {
- if (DebugUnknown) Inst.dump();
+ if (DebugUnknown) {
+ std::cerr << "In " << Inst.getParent()->getParent()->getName() << " ";
+ Inst.dump();
+ }
N->setUnknownNodeMarker();
}
}
@@ -1742,6 +1755,7 @@
FreeList.push_back("kfree");
FreeList.push_back("vfree");
FreeList.push_back("free_pages");
+ FreeList.push_back("kmem_cache_free");
//figure out all system call numbers
Function* lrs = M.getNamedFunction("llva_register_syscall");
More information about the llvm-commits
mailing list