Split ConstantVals.h into Constant.h and Constants.h
[oota-llvm.git] / lib / Transforms / Instrumentation / TraceValues.cpp
index 7948266c25cb35bdbf41dec5309eb6f9cd2c6158..7b263c76ad8b76ddb69e30d131d952d5e494b432 100644 (file)
@@ -1,48 +1,87 @@
 //===- TraceValues.cpp - Value Tracing for debugging -------------*- C++ -*--=//
 //
-// Support for inserting LLVM code to print values at basic block and method
+// Support for inserting LLVM code to print values at basic block and function
 // exits.
 //
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Transforms/Instrumentation/TraceValues.h"
 #include "llvm/GlobalVariable.h"
-#include "llvm/ConstantVals.h"
+#include "llvm/Constants.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/iMemory.h"
 #include "llvm/iTerminators.h"
 #include "llvm/iOther.h"
-#include "llvm/Method.h"
+#include "llvm/BasicBlock.h"
+#include "llvm/Function.h"
 #include "llvm/Module.h"
-#include "llvm/SymbolTable.h"
+#include "llvm/Pass.h"
 #include "llvm/Assembly/Writer.h"
 #include "Support/StringExtras.h"
 #include <sstream>
+using std::vector;
+using std::string;
+
+namespace {
+  class InsertTraceCode : public FunctionPass {
+    bool TraceBasicBlockExits, TraceFunctionExits;
+    Function *PrintfFunc;
+  public:
+    InsertTraceCode(bool traceBasicBlockExits, bool traceFunctionExits)
+      : TraceBasicBlockExits(traceBasicBlockExits), 
+        TraceFunctionExits(traceFunctionExits) {}
+    
+    // Add a prototype for printf if it is not already in the program.
+    //
+    bool doInitialization(Module *M);
+    
+    //--------------------------------------------------------------------------
+    // Function InsertCodeToTraceValues
+    // 
+    // Inserts tracing code for all live values at basic block and/or function
+    // exits as specified by `traceBasicBlockExits' and `traceFunctionExits'.
+    //
+    static bool doit(Function *M, bool traceBasicBlockExits,
+                     bool traceFunctionExits, Function *Printf);
+    
+    // runOnFunction - This method does the work.
+    //
+    bool runOnFunction(Function *F) {
+      return doit(F, TraceBasicBlockExits, TraceFunctionExits, PrintfFunc);
+    }
+  };
+} // end anonymous namespace
+
+
+Pass *createTraceValuesPassForFunction() {     // Just trace functions
+  return new InsertTraceCode(false, true);
+}
+
+Pass *createTraceValuesPassForBasicBlocks() {  // Trace BB's and functions
+  return new InsertTraceCode(true, true);
+}
+
+
 
 
 // Add a prototype for printf if it is not already in the program.
 //
-bool InsertTraceCode::doPassInitialization(Module *M) {
-  SymbolTable *ST = M->getSymbolTable();
+bool InsertTraceCode::doInitialization(Module *M) {
   const Type *SBP = PointerType::get(Type::SByteTy);
-  const MethodType *MTy =
-    MethodType::get(Type::IntTy, vector<const Type*>(1, SBP), true);
+  const FunctionType *MTy =
+    FunctionType::get(Type::IntTy, vector<const Type*>(1, SBP), true);
 
-  if (Value *Meth = ST->lookup(PointerType::get(MTy), "printf")) {
-    PrintfMeth = cast<Method>(Meth);
-    return false;
-  }
-
-  // Create a new method and add it to the module
-  PrintfMeth = new Method(MTy, false, "printf");
-  M->getMethodList().push_back(PrintfMeth);
-  return true;
+  PrintfFunc = M->getOrInsertFunction("printf", MTy);
+  return false;
 }
 
 
 static inline GlobalVariable *getStringRef(Module *M, const string &str) {
   // Create a constant internal string reference...
   Constant *Init = ConstantArray::get(str);
+
+  // Create the global variable and record it in the module
+  // The GV will be renamed to a unique name if needed.
   GlobalVariable *GV = new GlobalVariable(Init->getType(), true, true, Init,
                                           "trstr");
   M->getGlobalList().push_back(GV);
@@ -84,35 +123,24 @@ static bool ShouldTraceValue(const Instruction *I) {
 
 static string getPrintfCodeFor(const Value *V) {
   if (V == 0) return "";
-  switch (V->getType()->getPrimitiveID()) {
-  case Type::BoolTyID:
-  case Type::UByteTyID: case Type::UShortTyID:
-  case Type::UIntTyID:  case Type::ULongTyID:
-  case Type::SByteTyID: case Type::ShortTyID:
-  case Type::IntTyID:   case Type::LongTyID:
-    return "%d";
-    
-  case Type::FloatTyID: case Type::DoubleTyID:
+  if (V->getType()->isFloatingPoint())
     return "%g";
-
-  case Type::LabelTyID: case Type::PointerTyID:
-    return "%p";
+  else if (V->getType() == Type::LabelTy || isa<PointerType>(V->getType()))
+    return "0x%p";
+  else if (V->getType()->isIntegral() || V->getType() == Type::BoolTy)
+    return "%d";
     
-  default:
-    assert(0 && "Illegal value to print out...");
-    return "";
-  }
+  assert(0 && "Illegal value to print out...");
+  return "";
 }
 
 
 static void InsertPrintInst(Value *V, BasicBlock *BB, BasicBlock::iterator &BBI,
-                            string Message, Method *Printf) {
+                            string Message, Function *Printf) {
   // Escape Message by replacing all % characters with %% chars.
   unsigned Offset = 0;
   while ((Offset = Message.find('%', Offset)) != string::npos) {
-    string::iterator Offs = Message.begin()+Offset;
-    //Message.replace(Offs, Offs+1, "%%");
-    Message.replace(Offset, 2, "%%");
+    Message.replace(Offset, 1, "%%");
     Offset += 2;  // Skip over the new %'s
   }
 
@@ -139,8 +167,8 @@ static void InsertPrintInst(Value *V, BasicBlock *BB, BasicBlock::iterator &BBI,
 
 static void InsertVerbosePrintInst(Value *V, BasicBlock *BB,
                                    BasicBlock::iterator &BBI,
-                                   const string &Message, Method *Printf) {
-  ostringstream OutStr;
+                                   const string &Message, Function *Printf) {
+  std::ostringstream OutStr;
   if (V) WriteAsOperand(OutStr, V);
   InsertPrintInst(V, BB, BBI, Message+OutStr.str()+" = ", Printf);
 }
@@ -150,15 +178,15 @@ static void InsertVerbosePrintInst(Value *V, BasicBlock *BB,
 // for each value in valueVec[] that is live at the end of that basic block,
 // or that is stored to memory in this basic block.
 // If the value is stored to memory, we load it back before printing
-// We also return all such loaded values in the vector valuesStoredInMethod
-// for printing at the exit from the method.  (Note that in each invocation
-// of the method, this will only get the last value stored for each static
+// We also return all such loaded values in the vector valuesStoredInFunction
+// for printing at the exit from the function.  (Note that in each invocation
+// of the function, this will only get the last value stored for each static
 // store instruction).
 // *bb must be the block in which the value is computed;
 // this is not checked here.
 // 
-static void TraceValuesAtBBExit(BasicBlock *BB, Method *Printf,
-                                vector<Instruction*> *valuesStoredInMethod) {
+static void TraceValuesAtBBExit(BasicBlock *BB, Function *Printf,
+                                vector<Instruction*> *valuesStoredInFunction) {
   // Get an iterator to point to the insertion location, which is
   // just before the terminator instruction.
   // 
@@ -184,7 +212,7 @@ static void TraceValuesAtBBExit(BasicBlock *BB, Method *Printf,
   // Copy all of the instructions into a vector to avoid problems with Setcc
   const vector<Instruction*> Insts(BB->begin(), InsertPos);
 
-  ostringstream OutStr;
+  std::ostringstream OutStr;
   WriteAsOperand(OutStr, BB, false);
   InsertPrintInst(0, BB, InsertPos, "LEAVING BB:" + OutStr.str(), Printf);
 
@@ -194,46 +222,47 @@ static void TraceValuesAtBBExit(BasicBlock *BB, Method *Printf,
          IE = Insts.end(); II != IE; ++II) {
     Instruction *I = *II;
     if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
-      assert(valuesStoredInMethod &&
-             "Should not be printing a store instruction at method exit");
+      assert(valuesStoredInFunction &&
+             "Should not be printing a store instruction at function exit");
       LoadInst *LI = new LoadInst(SI->getPointerOperand(), SI->copyIndices(),
                                   "reload");
       InsertPos = BB->getInstList().insert(InsertPos, LI) + 1;
-      valuesStoredInMethod->push_back(LI);
+      valuesStoredInFunction->push_back(LI);
     }
     if (ShouldTraceValue(I))
       InsertVerbosePrintInst(I, BB, InsertPos, "  ", Printf);
   }
 }
 
-static inline void InsertCodeToShowMethodEntry(Method *M, Method *Printf) {
+static inline void InsertCodeToShowFunctionEntry(Function *M, Function *Printf){
   // Get an iterator to point to the insertion location
   BasicBlock *BB = M->getEntryNode();
   BasicBlock::iterator BBI = BB->begin();
 
-  ostringstream OutStr;
+  std::ostringstream OutStr;
   WriteAsOperand(OutStr, M, true);
-  InsertPrintInst(0, BB, BBI, "ENTERING METHOD: " + OutStr.str(), Printf);
+  InsertPrintInst(0, BB, BBI, "ENTERING FUNCTION: " + OutStr.str(), Printf);
 
   // Now print all the incoming arguments
-  const Method::ArgumentListType &argList = M->getArgumentList();
+  const Function::ArgumentListType &argList = M->getArgumentList();
   unsigned ArgNo = 0;
-  for (Method::ArgumentListType::const_iterator
+  for (Function::ArgumentListType::const_iterator
          I = argList.begin(), E = argList.end(); I != E; ++I, ++ArgNo) {
-    InsertVerbosePrintInst(*I, BB, BBI,
+    InsertVerbosePrintInst((Value*)*I, BB, BBI,
                            "  Arg #" + utostr(ArgNo), Printf);
   }
 }
 
 
-static inline void InsertCodeToShowMethodExit(BasicBlock *BB, Method *Printf) {
+static inline void InsertCodeToShowFunctionExit(BasicBlock *BB,
+                                                Function *Printf) {
   // Get an iterator to point to the insertion location
   BasicBlock::iterator BBI = BB->end()-1;
   ReturnInst *Ret = cast<ReturnInst>(*BBI);
   
-  ostringstream OutStr;
+  std::ostringstream OutStr;
   WriteAsOperand(OutStr, BB->getParent(), true);
-  InsertPrintInst(0, BB, BBI, "LEAVING  METHOD: " + OutStr.str(), Printf);
+  InsertPrintInst(0, BB, BBI, "LEAVING  FUNCTION: " + OutStr.str(), Printf);
   
   // print the return value, if any
   if (BB->getParent()->getReturnType() != Type::VoidTy)
@@ -241,36 +270,34 @@ static inline void InsertCodeToShowMethodExit(BasicBlock *BB, Method *Printf) {
 }
 
 
-bool InsertTraceCode::doit(Method *M, bool traceBasicBlockExits,
-                           bool traceMethodEvents, Method *Printf) {
-  if (M->isExternal() || (!traceBasicBlockExits && !traceMethodEvents))
+bool InsertTraceCode::doit(Function *M, bool traceBasicBlockExits,
+                           bool traceFunctionEvents, Function *Printf) {
+  if (!traceBasicBlockExits && !traceFunctionEvents)
     return false;
 
-  vector<Instruction*> valuesStoredInMethod;
+  vector<Instruction*> valuesStoredInFunction;
   vector<BasicBlock*>  exitBlocks;
 
-  Module *module = M->getParent();
-  if (traceMethodEvents)
-    InsertCodeToShowMethodEntry(M, Printf);
+  if (traceFunctionEvents)
+    InsertCodeToShowFunctionEntry(M, Printf);
   
-  for (Method::iterator BI = M->begin(); BI != M->end(); ++BI) {
+  for (Function::iterator BI = M->begin(); BI != M->end(); ++BI) {
     BasicBlock *BB = *BI;
     if (isa<ReturnInst>(BB->getTerminator()))
       exitBlocks.push_back(BB); // record this as an exit block
     
     if (traceBasicBlockExits)
-      TraceValuesAtBBExit(BB, Printf, &valuesStoredInMethod);
+      TraceValuesAtBBExit(BB, Printf, &valuesStoredInFunction);
   }
 
-  if (traceMethodEvents)
+  if (traceFunctionEvents)
     for (unsigned i=0; i < exitBlocks.size(); ++i) {
 #if 0
-      TraceValuesAtBBExit(valuesStoredInMethod, exitBlocks[i], module,
-                          /*indent*/ 0, /*isMethodExit*/ true,
-                          /*valuesStoredInMethod*/ NULL);
+      TraceValuesAtBBExit(valuesStoredInFunction, exitBlocks[i], module,
+                          /*indent*/ 0, /*isFunctionExit*/ true,
+                          /*valuesStoredInFunction*/ NULL);
 #endif
-      InsertCodeToShowMethodExit(exitBlocks[i], Printf);
+      InsertCodeToShowFunctionExit(exitBlocks[i], Printf);
     }
 
   return true;