[llvm-commits] CVS: llvm-poolalloc/lib/PoolAllocate/AccessTrace.cpp

Chris Lattner lattner at cs.uiuc.edu
Fri Apr 22 18:12:52 PDT 2005



Changes in directory llvm-poolalloc/lib/PoolAllocate:

AccessTrace.cpp added (r1.1)
---
Log message:

Add a little pass that adds instrumentation to a program to cause it to
dynamically print out the pool id/address of every pool-directed
load that it executes.


---
Diffs of the changes:  (+129 -0)

 AccessTrace.cpp |  129 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 129 insertions(+)


Index: llvm-poolalloc/lib/PoolAllocate/AccessTrace.cpp
diff -c /dev/null llvm-poolalloc/lib/PoolAllocate/AccessTrace.cpp:1.1
*** /dev/null	Fri Apr 22 20:12:49 2005
--- llvm-poolalloc/lib/PoolAllocate/AccessTrace.cpp	Fri Apr 22 20:12:39 2005
***************
*** 0 ****
--- 1,129 ----
+ //===-- PoolAccessTrace.cpp - Build trace of loads ------------------------===//
+ // 
+ //                     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 implements the -poolaccesstrace pass.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #define DEBUG_TYPE "pointercompress"
+ #include "PoolAllocate.h"
+ #include "llvm/Analysis/DataStructure/DataStructure.h"
+ #include "llvm/Analysis/DataStructure/DSGraph.h"
+ #include "llvm/Instructions.h"
+ #include "llvm/Module.h"
+ using namespace llvm;
+ 
+ namespace {
+ 
+   /// PoolAccessTrace - This transformation adds instrumentation to the program
+   /// to print a trace of pairs containing the address of each load and the pool
+   /// descriptor loaded from.
+   class PoolAccessTrace : public ModulePass {
+     PoolAllocate *PoolAlloc;
+     EquivClassGraphs *ECG;
+     Function *AccessTraceInitFn, *PoolAccessTraceFn;
+     const Type *VoidPtrTy;
+   public:
+ 
+     bool runOnModule(Module &M);
+ 
+     void getAnalysisUsage(AnalysisUsage &AU) const;
+ 
+     const DSGraph &getGraphForFunc(PA::FuncInfo *FI) const {
+       return ECG->getDSGraph(FI->F);
+     }
+ 
+   private:
+     void InitializeLibraryFunctions(Module &M);
+     void InstrumentAccess(Instruction *I, Value *Ptr, 
+                           PA::FuncInfo *FI, DSGraph &DSG);
+   };
+ 
+   RegisterOpt<PoolAccessTrace>
+   X("poolaccesstrace", "Instrument program to print trace of accesses");
+ }
+ 
+ void PoolAccessTrace::getAnalysisUsage(AnalysisUsage &AU) const {
+   // Need information about how pool allocation happened.
+   AU.addRequired<PoolAllocatePassAllPools>();
+ 
+   // Need information from DSA.
+   AU.addRequired<EquivClassGraphs>();
+ }
+ 
+ void PoolAccessTrace::InitializeLibraryFunctions(Module &M) {
+   VoidPtrTy = PointerType::get(Type::SByteTy);
+ 
+   AccessTraceInitFn = M.getOrInsertFunction("poolaccesstraceinit",
+                                             Type::VoidTy,0);
+   PoolAccessTraceFn = M.getOrInsertFunction("poolaccesstrace", Type::VoidTy,
+                                             VoidPtrTy, VoidPtrTy, 0);
+ }
+ 
+ void PoolAccessTrace::InstrumentAccess(Instruction *I, Value *Ptr, 
+                                        PA::FuncInfo *FI, DSGraph &DSG) {
+   // Don't trace loads of globals or the stack.
+   if (isa<Constant>(Ptr) || isa<AllocaInst>(Ptr)) return;
+ 
+   Value *MappedPtr = Ptr;
+   if (!FI->NewToOldValueMap.empty())
+     if ((MappedPtr = FI->MapValueToOriginal(MappedPtr)) == 0) {
+       // Value didn't exist in the orig program (pool desc?).
+       return;
+     }
+   DSNode *Node = DSG.getNodeForValue(MappedPtr).getNode();
+   if (Node == 0) return;
+ 
+   Value *PD = FI->PoolDescriptors[Node];
+   Ptr = new CastInst(Ptr, VoidPtrTy, Ptr->getName(), I);
+ 
+   if (PD)
+     PD = new CastInst(PD, VoidPtrTy, PD->getName(), I);
+   else
+     PD = Constant::getNullValue(VoidPtrTy);
+ 
+   // Insert the trace call.
+   new CallInst(PoolAccessTraceFn, Ptr, PD, "", I);
+ }
+ 
+ bool PoolAccessTrace::runOnModule(Module &M) {
+   PoolAlloc = &getAnalysis<PoolAllocatePassAllPools>();
+   ECG = &getAnalysis<EquivClassGraphs>();
+ 
+   // Create the function prototypes for runtime library.
+   InitializeLibraryFunctions(M);
+ 
+   Function *MainFunc = M.getMainFunction();
+   if (MainFunc && !MainFunc->isExternal())
+     // Insert a call to the library init function into the beginning of main.
+     new CallInst(AccessTraceInitFn, "", MainFunc->begin()->begin());
+ 
+   // Look at all of the loads in the program.
+   for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
+     if (F->isExternal()) continue;
+ 
+     PA::FuncInfo *FI = PoolAlloc->getFuncInfoOrClone(*F);
+     assert(FI && "DIDN'T FIND POOL INFO!");
+ 
+     // If this function was cloned, and this is the original function, ignore it
+     // (it's dead).  We'll deal with the cloned version later when we run into
+     // it again.
+     if (FI->Clone && &FI->F == F)
+       continue;
+ 
+     // Get the DSGraph for this function.
+     DSGraph &DSG = ECG->getDSGraph(FI->F);
+ 
+     for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
+       for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I)
+         if (LoadInst *LI = dyn_cast<LoadInst>(I))
+           InstrumentAccess(LI, LI->getOperand(0), FI, DSG);
+   }
+   return true;
+ }






More information about the llvm-commits mailing list