//===- TraceValues.cpp - Value Tracing for debugging ----------------------===//
// 
//                     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.
// 
//===----------------------------------------------------------------------===//
//
// Support for inserting LLVM code to print values at basic block and function
// exits.
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/Instrumentation.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Instructions.h"
#include "llvm/Module.h"
#include "llvm/Pass.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/ADT/StringExtras.h"
#include <algorithm>
#include <sstream>
using namespace llvm;

static cl::opt<bool>
DisablePtrHashing("tracedisablehashdisable", cl::Hidden,
                  cl::desc("Disable pointer hashing in the -trace or -tracem "
                           "passes"));

static cl::list<std::string>
TraceFuncNames("tracefunc", cl::desc("Only trace specific functions in the "
                                     "-trace or -tracem passes"),
	       cl::value_desc("function"), cl::Hidden);

static void TraceValuesAtBBExit(BasicBlock *BB,
                                Function *Printf, Function* HashPtrToSeqNum,
                             std::vector<Instruction*> *valuesStoredInFunction);

// We trace a particular function if no functions to trace were specified
// or if the function is in the specified list.
// 
inline static bool
TraceThisFunction(Function &F)
{
  if (TraceFuncNames.empty()) return true;

  return std::find(TraceFuncNames.begin(), TraceFuncNames.end(), F.getName())
                  != TraceFuncNames.end();
}


namespace {
  struct ExternalFuncs {
    Function *PrintfFunc, *HashPtrFunc, *ReleasePtrFunc;
    Function *RecordPtrFunc, *PushOnEntryFunc, *ReleaseOnReturnFunc;
    void doInitialization(Module &M); // Add prototypes for external functions
  };
  
  class InsertTraceCode : public FunctionPass {
  protected:
    ExternalFuncs externalFuncs;
  public:
    
    // Add a prototype for runtime functions 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'.
    //
    bool doit(Function *M);

    virtual void handleBasicBlock(BasicBlock *BB,
                                  std::vector<Instruction*> &VI) = 0;

    // runOnFunction - This method does the work.
    //
    bool runOnFunction(Function &F);

    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
      AU.setPreservesCFG();
    }
  };

  struct FunctionTracer : public InsertTraceCode {
    // Ignore basic blocks here...
    virtual void handleBasicBlock(BasicBlock *BB,
                                  std::vector<Instruction*> &VI) {}
  };

  struct BasicBlockTracer : public InsertTraceCode {
    // Trace basic blocks here...
    virtual void handleBasicBlock(BasicBlock *BB,
                                  std::vector<Instruction*> &VI) {
      TraceValuesAtBBExit(BB, externalFuncs.PrintfFunc,
                          externalFuncs.HashPtrFunc, &VI);
    }
  };

  // Register the passes...
  RegisterOpt<FunctionTracer>  X("tracem","Insert Function trace code only");
  RegisterOpt<BasicBlockTracer> Y("trace","Insert BB and Function trace code");
} // end anonymous namespace

/// Just trace functions
FunctionPass *llvm::createTraceValuesPassForFunction() {
  return new FunctionTracer();
}

/// Trace BB's and functions
FunctionPass *llvm::createTraceValuesPassForBasicBlocks() {
  return new BasicBlockTracer();
}

// Add a prototype for external functions used by the tracing code and require
// the trace library for this module.
//
void ExternalFuncs::doInitialization(Module &M) {
  M.addLibrary("trace");
  const Type *SBP = PointerType::get(Type::SByteTy);
  const FunctionType *MTy =
    FunctionType::get(Type::IntTy, std::vector<const Type*>(1, SBP), true);
  PrintfFunc = M.getOrInsertFunction("printf", MTy);

  // uint (sbyte*)
  HashPtrFunc = M.getOrInsertFunction("HashPointerToSeqNum", Type::UIntTy, SBP,
                                      0);
  
  // void (sbyte*)
  ReleasePtrFunc = M.getOrInsertFunction("ReleasePointerSeqNum", 
                                         Type::VoidTy, SBP, 0);
  RecordPtrFunc  = M.getOrInsertFunction("RecordPointer",
                                         Type::VoidTy, SBP, 0);
  
  PushOnEntryFunc = M.getOrInsertFunction("PushPointerSet", Type::VoidTy, 0);
  ReleaseOnReturnFunc = M.getOrInsertFunction("ReleasePointersPopSet",
                                              Type::VoidTy, 0);
}


// Add a prototype for external functions used by the tracing code.
//
bool InsertTraceCode::doInitialization(Module &M) {
  externalFuncs.doInitialization(M);
  return false;
}


static inline GlobalVariable *getStringRef(Module *M, const std::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, 
                                          GlobalValue::InternalLinkage, Init,
                                          "trstr");
  M->getGlobalList().push_back(GV);
  return GV;
}


// 
// Check if this instruction has any uses outside its basic block,
// or if it used by either a Call or Return instruction (ditto).
// (Values stored to memory within this BB are live at end of BB but are
// traced at the store instruction, not where they are computed.)
// 
static inline bool LiveAtBBExit(const Instruction* I) {
  const BasicBlock *BB = I->getParent();
  for (Value::use_const_iterator U = I->use_begin(); U != I->use_end(); ++U)
    if (const Instruction *UI = dyn_cast<Instruction>(*U))
      if (UI->getParent() != BB || isa<ReturnInst>(UI))
        return true;

  return false;
}


static inline bool TraceThisOpCode(unsigned opCode) {
  // Explicitly test for opCodes *not* to trace so that any new opcodes will
  // be traced by default (VoidTy's are already excluded)
  // 
  return (opCode  < Instruction::OtherOpsBegin &&
          opCode != Instruction::Alloca &&
          opCode != Instruction::PHI &&
          opCode != Instruction::Cast);
}


// Trace a value computed by an instruction if it is non-void, it is computed
// by a real computation, not just a copy (see TraceThisOpCode), and
// -- it is a load instruction: we want to check values read from memory
// -- or it is live at exit from the basic block (i.e., ignore local temps)
// 
static bool ShouldTraceValue(const Instruction *I) {
  return
    I->getType() != Type::VoidTy &&
    TraceThisOpCode(I->getOpcode()) &&
    (isa<LoadInst>(I) || LiveAtBBExit(I));
}

static std::string getPrintfCodeFor(const Value *V) {
  if (V == 0) return "";
  if (V->getType()->isFloatingPoint())
    return "%g";
  else if (V->getType() == Type::LabelTy)
    return "0x%p";
  else if (isa<PointerType>(V->getType()))
    return DisablePtrHashing ? "0x%p" : "%d";
  else if (V->getType()->isIntegral())
    return "%d";
  
  assert(0 && "Illegal value to print out...");
  return "";
}


static void InsertPrintInst(Value *V, BasicBlock *BB, Instruction *InsertBefore,
                            std::string Message,
                            Function *Printf, Function* HashPtrToSeqNum) {
  // Escape Message by replacing all % characters with %% chars.
  std::string Tmp;
  std::swap(Tmp, Message);
  std::string::iterator I = std::find(Tmp.begin(), Tmp.end(), '%');
  while (I != Tmp.end()) {
    Message.append(Tmp.begin(), I);
    Message += "%%";
    ++I; // Make sure to erase the % as well...
    Tmp.erase(Tmp.begin(), I);
    I = std::find(Tmp.begin(), Tmp.end(), '%');
  }
  Message += Tmp;
  Module *Mod = BB->getParent()->getParent();

  // Turn the marker string into a global variable...
  GlobalVariable *fmtVal = getStringRef(Mod, Message+getPrintfCodeFor(V)+"\n");

  // Turn the format string into an sbyte *
  Constant *GEP=ConstantExpr::getGetElementPtr(fmtVal,
                std::vector<Constant*>(2,Constant::getNullValue(Type::LongTy)));
  
  // Insert a call to the hash function if this is a pointer value
  if (V && isa<PointerType>(V->getType()) && !DisablePtrHashing) {
    const Type *SBP = PointerType::get(Type::SByteTy);
    if (V->getType() != SBP)     // Cast pointer to be sbyte*
      V = new CastInst(V, SBP, "Hash_cast", InsertBefore);

    std::vector<Value*> HashArgs(1, V);
    V = new CallInst(HashPtrToSeqNum, HashArgs, "ptrSeqNum", InsertBefore);
  }
  
  // Insert the first print instruction to print the string flag:
  std::vector<Value*> PrintArgs;
  PrintArgs.push_back(GEP);
  if (V) PrintArgs.push_back(V);
  new CallInst(Printf, PrintArgs, "trace", InsertBefore);
}
                            

static void InsertVerbosePrintInst(Value *V, BasicBlock *BB,
                                   Instruction *InsertBefore,
                                   const std::string &Message, Function *Printf,
                                   Function* HashPtrToSeqNum) {
  std::ostringstream OutStr;
  if (V) WriteAsOperand(OutStr, V);
  InsertPrintInst(V, BB, InsertBefore, Message+OutStr.str()+" = ",
                  Printf, HashPtrToSeqNum);
}

static void 
InsertReleaseInst(Value *V, BasicBlock *BB,
                  Instruction *InsertBefore,
                  Function* ReleasePtrFunc) {
  
  const Type *SBP = PointerType::get(Type::SByteTy);
  if (V->getType() != SBP)    // Cast pointer to be sbyte*
    V = new CastInst(V, SBP, "RPSN_cast", InsertBefore);

  std::vector<Value*> releaseArgs(1, V);
  new CallInst(ReleasePtrFunc, releaseArgs, "", InsertBefore);
}

static void 
InsertRecordInst(Value *V, BasicBlock *BB,
                 Instruction *InsertBefore,
                 Function* RecordPtrFunc) {
    const Type *SBP = PointerType::get(Type::SByteTy);
  if (V->getType() != SBP)     // Cast pointer to be sbyte*
    V = new CastInst(V, SBP, "RP_cast", InsertBefore);

  std::vector<Value*> releaseArgs(1, V);
  new CallInst(RecordPtrFunc, releaseArgs, "", InsertBefore);
}

// Look for alloca and free instructions. These are the ptrs to release.
// Release the free'd pointers immediately.  Record the alloca'd pointers
// to be released on return from the current function.
// 
static void
ReleasePtrSeqNumbers(BasicBlock *BB,
                     ExternalFuncs& externalFuncs) {
  
  for (BasicBlock::iterator II=BB->begin(), IE = BB->end(); II != IE; ++II)
    if (FreeInst *FI = dyn_cast<FreeInst>(II))
      InsertReleaseInst(FI->getOperand(0), BB, FI,externalFuncs.ReleasePtrFunc);
    else if (AllocaInst *AI = dyn_cast<AllocaInst>(II))
      InsertRecordInst(AI, BB, AI->getNext(), externalFuncs.RecordPtrFunc);
}  


// Insert print instructions at the end of basic block BB for each value
// computed in BB that is live at the end of BB,
// or that is stored to memory in BB.
// If the value is stored to memory, we load it back before printing it
// 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).
// 
static void TraceValuesAtBBExit(BasicBlock *BB,
                                Function *Printf, Function* HashPtrToSeqNum,
                            std::vector<Instruction*> *valuesStoredInFunction) {
  // Get an iterator to point to the insertion location, which is
  // just before the terminator instruction.
  // 
  TerminatorInst *InsertPos = BB->getTerminator();
  
  std::ostringstream OutStr;
  WriteAsOperand(OutStr, BB, false);
  InsertPrintInst(0, BB, InsertPos, "LEAVING BB:" + OutStr.str(),
                  Printf, HashPtrToSeqNum);

  // Insert a print instruction for each instruction preceding InsertPos.
  // The print instructions must go before InsertPos, so we use the
  // instruction *preceding* InsertPos to check when to terminate the loop.
  // 
  for (BasicBlock::iterator II = BB->begin(); &*II != InsertPos; ++II) {
    if (StoreInst *SI = dyn_cast<StoreInst>(II)) {
      // Trace the stored value and address
      InsertVerbosePrintInst(SI->getOperand(0), BB, InsertPos,
                             "  (store value) ", Printf, HashPtrToSeqNum);
      InsertVerbosePrintInst(SI->getOperand(1), BB, InsertPos,
                             "  (store addr ) ", Printf, HashPtrToSeqNum);
    }
    else if (ShouldTraceValue(II))
      InsertVerbosePrintInst(II, BB, InsertPos, "  ", Printf, HashPtrToSeqNum);
  }
}

static inline void InsertCodeToShowFunctionEntry(Function &F, Function *Printf,
                                                 Function* HashPtrToSeqNum){
  // Get an iterator to point to the insertion location
  BasicBlock &BB = F.getEntryBlock();
  Instruction *InsertPos = BB.begin();

  std::ostringstream OutStr;
  WriteAsOperand(OutStr, &F);
  InsertPrintInst(0, &BB, InsertPos, "ENTERING FUNCTION: " + OutStr.str(),
                  Printf, HashPtrToSeqNum);

  // Now print all the incoming arguments
  unsigned ArgNo = 0;
  for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I, ++ArgNo){
    InsertVerbosePrintInst(I, &BB, InsertPos,
                           "  Arg #" + utostr(ArgNo) + ": ", Printf,
                           HashPtrToSeqNum);
  }
}


static inline void InsertCodeToShowFunctionExit(BasicBlock *BB,
                                                Function *Printf,
                                                Function* HashPtrToSeqNum) {
  // Get an iterator to point to the insertion location
  ReturnInst *Ret = cast<ReturnInst>(BB->getTerminator());
  
  std::ostringstream OutStr;
  WriteAsOperand(OutStr, BB->getParent(), true);
  InsertPrintInst(0, BB, Ret, "LEAVING  FUNCTION: " + OutStr.str(),
                  Printf, HashPtrToSeqNum);
  
  // print the return value, if any
  if (BB->getParent()->getReturnType() != Type::VoidTy)
    InsertPrintInst(Ret->getReturnValue(), BB, Ret, "  Returning: ",
                    Printf, HashPtrToSeqNum);
}


bool InsertTraceCode::runOnFunction(Function &F) {
  if (!TraceThisFunction(F))
    return false;
  
  std::vector<Instruction*> valuesStoredInFunction;
  std::vector<BasicBlock*>  exitBlocks;

  // Insert code to trace values at function entry
  InsertCodeToShowFunctionEntry(F, externalFuncs.PrintfFunc,
                                externalFuncs.HashPtrFunc);
  
  // Push a pointer set for recording alloca'd pointers at entry.
  if (!DisablePtrHashing)
    new CallInst(externalFuncs.PushOnEntryFunc, std::vector<Value*>(), "",
                 F.getEntryBlock().begin());

  for (Function::iterator BB = F.begin(); BB != F.end(); ++BB) {
    if (isa<ReturnInst>(BB->getTerminator()))
      exitBlocks.push_back(BB); // record this as an exit block

    // Insert trace code if this basic block is interesting...
    handleBasicBlock(BB, valuesStoredInFunction);

    if (!DisablePtrHashing)          // release seq. numbers on free/ret
      ReleasePtrSeqNumbers(BB, externalFuncs);
  }
  
  for (unsigned i=0; i != exitBlocks.size(); ++i)
    {
      // Insert code to trace values at function exit
      InsertCodeToShowFunctionExit(exitBlocks[i], externalFuncs.PrintfFunc,
                                   externalFuncs.HashPtrFunc);
      
      // Release all recorded pointers before RETURN.  Do this LAST!
      if (!DisablePtrHashing)
        new CallInst(externalFuncs.ReleaseOnReturnFunc, std::vector<Value*>(),
                     "", exitBlocks[i]->getTerminator());
    }
  
  return true;
}
