//===- 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,
                                      (Type *)0);

  // void (sbyte*)
  ReleasePtrFunc = M.getOrInsertFunction("ReleasePointerSeqNum",
                                         Type::VoidTy, SBP, (Type *)0);
  RecordPtrFunc  = M.getOrInsertFunction("RecordPointer",
                                         Type::VoidTy, SBP, (Type *)0);

  PushOnEntryFunc = M.getOrInsertFunction("PushPointerSet", Type::VoidTy,
                                          (Type *)0);
  ReleaseOnReturnFunc = M.getOrInsertFunction("ReleasePointersPopSet",
                                              Type::VoidTy, (Type *)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;
}
