//===-- CollectorMetadata.cpp - Garbage collector metadata ----------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the CollectorMetadata and CollectorModuleMetadata
// classes.
//
//===----------------------------------------------------------------------===//

#include "llvm/CodeGen/CollectorMetadata.h"
#include "llvm/CodeGen/Collector.h"
#include "llvm/CodeGen/Collectors.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/Pass.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/Function.h"
#include "llvm/Support/Compiler.h"

using namespace llvm;

namespace {
  
  class VISIBILITY_HIDDEN Printer : public FunctionPass {
    static char ID;
    std::ostream &OS;
    
  public:
    explicit Printer(std::ostream &OS = *cerr);
    
    const char *getPassName() const;
    void getAnalysisUsage(AnalysisUsage &AU) const;
    
    bool runOnFunction(Function &F);
  };
  
  class VISIBILITY_HIDDEN Deleter : public FunctionPass {
    static char ID;
    
  public:
    Deleter();
    
    const char *getPassName() const;
    void getAnalysisUsage(AnalysisUsage &AU) const;
    
    bool runOnFunction(Function &F);
    bool doFinalization(Module &M);
  };
  
  RegisterPass<CollectorModuleMetadata>
  X("collector-metadata", "Create Garbage Collector Module Metadata");
  
}

// -----------------------------------------------------------------------------

CollectorMetadata::CollectorMetadata(const Function &F, Collector &C)
  : F(F), C(C), FrameSize(~0LL) {}

CollectorMetadata::~CollectorMetadata() {}

// -----------------------------------------------------------------------------

char CollectorModuleMetadata::ID = 0;

CollectorModuleMetadata::CollectorModuleMetadata()
  : ImmutablePass((intptr_t)&ID) {}

CollectorModuleMetadata::~CollectorModuleMetadata() {
  clear();
}

Collector *CollectorModuleMetadata::
getOrCreateCollector(const Module *M, const std::string &Name) {
  const char *Start = Name.c_str();
  
  collector_map_type::iterator NMI = NameMap.find(Start, Start + Name.size());
  if (NMI != NameMap.end())
    return NMI->getValue();
  
  for (CollectorRegistry::iterator I = CollectorRegistry::begin(),
                                   E = CollectorRegistry::end(); I != E; ++I) {
    if (strcmp(Start, I->getName()) == 0) {
      Collector *C = I->instantiate();
      C->M = M;
      C->Name = Name;
      NameMap.GetOrCreateValue(Start, Start + Name.size()).setValue(C);
      Collectors.push_back(C);
      return C;
    }
  }
  
  cerr << "unsupported collector: " << Name << "\n";
  abort();
}

CollectorMetadata &CollectorModuleMetadata::get(const Function &F) {
  assert(F.hasCollector());
  function_map_type::iterator I = Map.find(&F);
  if (I != Map.end())
    return *I->second;
    
  Collector *C = getOrCreateCollector(F.getParent(), F.getCollector());
  CollectorMetadata *MD = C->insertFunctionMetadata(F);
  Map[&F] = MD;
  return *MD;
}

void CollectorModuleMetadata::clear() {
  Map.clear();
  
  // TODO: StringMap should provide a clear method.
  while (!NameMap.empty())
    NameMap.erase(NameMap.begin());
  
  for (iterator I = begin(), E = end(); I != E; ++I)
    delete *I;
  Collectors.clear();
}

// -----------------------------------------------------------------------------

char Printer::ID = 0;

FunctionPass *llvm::createCollectorMetadataPrinter(std::ostream &OS) {
  return new Printer(OS);
}

Printer::Printer(std::ostream &OS)
  : FunctionPass(intptr_t(&ID)), OS(OS) {}

const char *Printer::getPassName() const {
  return "Print Garbage Collector Information";
}

void Printer::getAnalysisUsage(AnalysisUsage &AU) const {
  FunctionPass::getAnalysisUsage(AU);
  AU.setPreservesAll();
  AU.addRequired<CollectorModuleMetadata>();
}

static const char *DescKind(GC::PointKind Kind) {
  switch (Kind) {
    default: assert(0 && "Unknown GC point kind");
    case GC::Loop:     return "loop";
    case GC::Return:   return "return";
    case GC::PreCall:  return "pre-call";
    case GC::PostCall: return "post-call";
  }
}

bool Printer::runOnFunction(Function &F) {
  if (F.hasCollector()) {
    CollectorMetadata *FD = &getAnalysis<CollectorModuleMetadata>().get(F);
    
    OS << "GC roots for " << FD->getFunction().getNameStart() << ":\n";
    for (CollectorMetadata::roots_iterator RI = FD->roots_begin(),
                                           RE = FD->roots_end();
                                           RI != RE; ++RI)
      OS << "\t" << RI->Num << "\t" << RI->StackOffset << "[sp]\n";
    
    OS << "GC safe points for " << FD->getFunction().getNameStart() << ":\n";
    for (CollectorMetadata::iterator PI = FD->begin(),
                                     PE = FD->end(); PI != PE; ++PI) {
      
      OS << "\tlabel " << PI->Num << ": " << DescKind(PI->Kind) << ", live = {";
      
      for (CollectorMetadata::live_iterator RI = FD->live_begin(PI),
                                            RE = FD->live_end(PI);;) {
        OS << " " << RI->Num;
        if (++RI == RE)
          break;
        OS << ",";
      }
      
      OS << " }\n";
    }
  }
  
  return false;
}

// -----------------------------------------------------------------------------

char Deleter::ID = 0;

FunctionPass *llvm::createCollectorMetadataDeleter() {
  return new Deleter();
}

Deleter::Deleter() : FunctionPass(intptr_t(&ID)) {}

const char *Deleter::getPassName() const {
  return "Delete Garbage Collector Information";
}

void Deleter::getAnalysisUsage(AnalysisUsage &AU) const {
  AU.setPreservesAll();
  AU.addRequired<CollectorModuleMetadata>();
}

bool Deleter::runOnFunction(Function &MF) {
  return false;
}

bool Deleter::doFinalization(Module &M) {
  CollectorModuleMetadata *CMM = getAnalysisToUpdate<CollectorModuleMetadata>();
  assert(CMM && "Deleter didn't require CollectorModuleMetadata?!");
  CMM->clear();
  return false;
}
