//===-- EmitFunctions.cpp - interface to insert instrumentation -----------===//
//
//                     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 inserts into the input module three new global constants containing
// mapping information pertinent to the Reoptimizer's runtime library:
// 1) a structure containing a pointer to each function;
// 2) an array containing a boolean which is true iff the corresponding
//    function in 1) contains a back-edge branch suitable for the Reoptimizer's
//    first-level instrumentation;
// 3) an integer containing the number of entries in 1) and 2).
//
// NOTE: This pass is used by the reoptimizer only.
//
//===----------------------------------------------------------------------===//

#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
#include "llvm/Pass.h"
#include "llvm/Support/CFG.h"
#include "llvm/Transforms/Instrumentation.h"
using namespace llvm;

namespace llvm {

namespace {
  enum Color{
    WHITE,
    GREY,
    BLACK
  };

  struct EmitFunctionTable : public ModulePass {
    bool runOnModule(Module &M);
  };

  RegisterOpt<EmitFunctionTable>
  X("emitfuncs", "Emit a function table for the reoptimizer");
}

static char doDFS(BasicBlock * node,std::map<BasicBlock *, Color > &color){
  color[node] = GREY;

  for(succ_iterator vl = succ_begin(node), ve = succ_end(node); vl != ve; ++vl){

    BasicBlock *BB = *vl;

    if(color[BB]!=GREY && color[BB]!=BLACK){
      if(!doDFS(BB, color)){
        return 0;
      }
    }

    //if has backedge
    else if(color[BB]==GREY)
      return 0;

  }

  color[node] = BLACK;
  return 1;
}

static char hasBackEdge(Function *F){
  std::map<BasicBlock *, Color > color;
  return doDFS(F->begin(), color);
}

// Per Module pass for inserting function table
bool EmitFunctionTable::runOnModule(Module &M){
  std::vector<const Type*> vType;

  std::vector<Constant *> vConsts;
  std::vector<Constant *> sBCons;

  unsigned int counter = 0;
  for(Module::iterator MI = M.begin(), ME = M.end(); MI != ME; ++MI)
    if (!MI->isExternal()) {
      vType.push_back(MI->getType());

      //std::cerr<<MI;

      vConsts.push_back(MI);
      sBCons.push_back(ConstantInt::get(Type::SByteTy, hasBackEdge(MI)));

      counter++;
    }

  StructType *sttype = StructType::get(vType);
  Constant *cstruct = ConstantStruct::get(sttype, vConsts);

  GlobalVariable *gb = new GlobalVariable(cstruct->getType(), true,
                                          GlobalValue::ExternalLinkage,
                                          cstruct, "llvmFunctionTable");
  M.getGlobalList().push_back(gb);

  Constant *constArray = ConstantArray::get(ArrayType::get(Type::SByteTy,
                                                                sBCons.size()),
                                                 sBCons);

  GlobalVariable *funcArray = new GlobalVariable(constArray->getType(), true,
                                              GlobalValue::ExternalLinkage,
                                              constArray, "llvmSimpleFunction");

  M.getGlobalList().push_back(funcArray);

  ConstantInt *cnst = ConstantSInt::get(Type::IntTy, counter);
  GlobalVariable *fnCount = new GlobalVariable(Type::IntTy, true,
                                               GlobalValue::ExternalLinkage,
                                               cnst, "llvmFunctionCount");
  M.getGlobalList().push_back(fnCount);
  return true;  // Always modifies program
}

ModulePass *createEmitFunctionTablePass () {
  return new EmitFunctionTable();
}

} // end namespace llvm
