#ifndef __ESCAPE__ANALYSIS__H
#define __ESCAPE__ANALYSIS__H

#include "CommonTypes.hpp"
#include "InterproceduralDefUse.hpp"

#include "llvm/Pass.h"
#include "llvm/CallGraphSCCPass.h"
#include "llvm/Support/InstVisitor.h"

#include <boost/scoped_ptr.hpp>
#include <tr1/unordered_map>
#include <vector>

namespace llvm
{
  class Argument;
  class Function;
  class Value;
  class CallGraphNode;
}

struct EscapeAnalysis : public llvm::CallGraphSCCPass,
                        public llvm::InstVisitor<EscapeAnalysis>
{
  static char ID;
  
  EscapeAnalysis(results_t * res = NULL);

  const use_set& getEscapeInstructions(const llvm::Value* V) const;

  // Visitor
  void visitCallInst(llvm::CallInst& CI);
  void visitArgument(llvm::Argument& arg);

  // CallGraphSCCPass
  virtual bool runOnSCC(const std::vector<llvm::CallGraphNode*> &SCCM);
  virtual void getAnalysisUsage(llvm::AnalysisUsage &AU) const;

  
private:
  /*!
    Marks the named argument as escaping.  Returns true if this
    is new information, false otherwise.
   */
  bool markEscape(const llvm::Argument & arg, short escapeType);
  void analyzeEscapes(llvm::Value* V);
  void runOnFunction(llvm::Function* F);
  
private:
  results_t * _res;
  use_map _escapes;
};
#endif // __ESCAPE__ANALYSIS__H
