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"); _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits