GCMetadata.cpp revision 5a29c9eed157af51a8d338b5a225b146881819e8
1fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen//===-- CollectorMetadata.cpp - Garbage collector metadata ----------------===//
2fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen//
3fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen//                     The LLVM Compiler Infrastructure
4fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen//
54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source
64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details.
7fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen//
8fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen//===----------------------------------------------------------------------===//
9fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen//
10fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen// This file implements the CollectorMetadata and CollectorModuleMetadata
11fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen// classes.
12fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen//
13fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen//===----------------------------------------------------------------------===//
14fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen
155a29c9eed157af51a8d338b5a225b146881819e8Gordon Henriksen#include "llvm/CodeGen/GCMetadata.h"
165a29c9eed157af51a8d338b5a225b146881819e8Gordon Henriksen#include "llvm/CodeGen/GCStrategy.h"
175a29c9eed157af51a8d338b5a225b146881819e8Gordon Henriksen#include "llvm/CodeGen/GCs.h"
18fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen#include "llvm/CodeGen/MachineFrameInfo.h"
19ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen#include "llvm/Pass.h"
20ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen#include "llvm/CodeGen/Passes.h"
21fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen#include "llvm/Function.h"
22fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen#include "llvm/Support/Compiler.h"
23fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen
24fc3282221f90c626d80292327213e2badc3de86bGordon Henriksenusing namespace llvm;
25fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen
26fc3282221f90c626d80292327213e2badc3de86bGordon Henriksennamespace {
27fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen
28ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen  class VISIBILITY_HIDDEN Printer : public FunctionPass {
29fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen    static char ID;
30fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen    std::ostream &OS;
31fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen
32fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen  public:
33ded2b0d0fb0d4fa09198e3d05da529d2c97214c3Dan Gohman    explicit Printer(std::ostream &OS = *cerr);
34fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen
35fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen    const char *getPassName() const;
36fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen    void getAnalysisUsage(AnalysisUsage &AU) const;
37fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen
38ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen    bool runOnFunction(Function &F);
39fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen  };
40fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen
41ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen  class VISIBILITY_HIDDEN Deleter : public FunctionPass {
42fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen    static char ID;
43fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen
44fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen  public:
45fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen    Deleter();
46fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen
47fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen    const char *getPassName() const;
48fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen    void getAnalysisUsage(AnalysisUsage &AU) const;
49fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen
50ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen    bool runOnFunction(Function &F);
51fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen    bool doFinalization(Module &M);
52fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen  };
53fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen
54fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen}
55fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen
56844731a7f1909f55935e3514c9e713a62d67662eDan Gohmanstatic RegisterPass<CollectorModuleMetadata>
57844731a7f1909f55935e3514c9e713a62d67662eDan GohmanX("collector-metadata", "Create Garbage Collector Module Metadata");
58844731a7f1909f55935e3514c9e713a62d67662eDan Gohman
59fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen// -----------------------------------------------------------------------------
60fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen
61ad93c4f936d220570535711262e0fff8857f798aGordon HenriksenCollectorMetadata::CollectorMetadata(const Function &F, Collector &C)
62ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen  : F(F), C(C), FrameSize(~0LL) {}
63fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen
64fc3282221f90c626d80292327213e2badc3de86bGordon HenriksenCollectorMetadata::~CollectorMetadata() {}
65fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen
66fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen// -----------------------------------------------------------------------------
67fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen
68fc3282221f90c626d80292327213e2badc3de86bGordon Henriksenchar CollectorModuleMetadata::ID = 0;
69fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen
70fc3282221f90c626d80292327213e2badc3de86bGordon HenriksenCollectorModuleMetadata::CollectorModuleMetadata()
71fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen  : ImmutablePass((intptr_t)&ID) {}
72fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen
73fc3282221f90c626d80292327213e2badc3de86bGordon HenriksenCollectorModuleMetadata::~CollectorModuleMetadata() {
74fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen  clear();
75fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen}
76fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen
77ad93c4f936d220570535711262e0fff8857f798aGordon HenriksenCollector *CollectorModuleMetadata::
78ad93c4f936d220570535711262e0fff8857f798aGordon HenriksengetOrCreateCollector(const Module *M, const std::string &Name) {
79ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen  const char *Start = Name.c_str();
80ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen
81ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen  collector_map_type::iterator NMI = NameMap.find(Start, Start + Name.size());
82ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen  if (NMI != NameMap.end())
83ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen    return NMI->getValue();
84ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen
85ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen  for (CollectorRegistry::iterator I = CollectorRegistry::begin(),
86ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen                                   E = CollectorRegistry::end(); I != E; ++I) {
87ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen    if (strcmp(Start, I->getName()) == 0) {
88ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen      Collector *C = I->instantiate();
89ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen      C->M = M;
90ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen      C->Name = Name;
91ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen      NameMap.GetOrCreateValue(Start, Start + Name.size()).setValue(C);
92ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen      Collectors.push_back(C);
93ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen      return C;
94ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen    }
95ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen  }
96ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen
97ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen  cerr << "unsupported collector: " << Name << "\n";
98ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen  abort();
99fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen}
100fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen
101ad93c4f936d220570535711262e0fff8857f798aGordon HenriksenCollectorMetadata &CollectorModuleMetadata::get(const Function &F) {
102ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen  assert(F.hasCollector());
103ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen  function_map_type::iterator I = Map.find(&F);
104ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen  if (I != Map.end())
105ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen    return *I->second;
106ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen
107ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen  Collector *C = getOrCreateCollector(F.getParent(), F.getCollector());
108ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen  CollectorMetadata *MD = C->insertFunctionMetadata(F);
109ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen  Map[&F] = MD;
110ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen  return *MD;
111fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen}
112fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen
113fc3282221f90c626d80292327213e2badc3de86bGordon Henriksenvoid CollectorModuleMetadata::clear() {
114ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen  Map.clear();
115fce6e546aab64602c41eeb83381b7617f97d0069Chris Lattner  NameMap.clear();
116ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen
117fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen  for (iterator I = begin(), E = end(); I != E; ++I)
118fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen    delete *I;
119ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen  Collectors.clear();
120fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen}
121fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen
122fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen// -----------------------------------------------------------------------------
123fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen
124fc3282221f90c626d80292327213e2badc3de86bGordon Henriksenchar Printer::ID = 0;
125fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen
126ad93c4f936d220570535711262e0fff8857f798aGordon HenriksenFunctionPass *llvm::createCollectorMetadataPrinter(std::ostream &OS) {
127fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen  return new Printer(OS);
128fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen}
129fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen
130fc3282221f90c626d80292327213e2badc3de86bGordon HenriksenPrinter::Printer(std::ostream &OS)
131ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen  : FunctionPass(intptr_t(&ID)), OS(OS) {}
132fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen
133fc3282221f90c626d80292327213e2badc3de86bGordon Henriksenconst char *Printer::getPassName() const {
134fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen  return "Print Garbage Collector Information";
135fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen}
136fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen
137fc3282221f90c626d80292327213e2badc3de86bGordon Henriksenvoid Printer::getAnalysisUsage(AnalysisUsage &AU) const {
138ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen  FunctionPass::getAnalysisUsage(AU);
139fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen  AU.setPreservesAll();
140fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen  AU.addRequired<CollectorModuleMetadata>();
141fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen}
142fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen
143fc3282221f90c626d80292327213e2badc3de86bGordon Henriksenstatic const char *DescKind(GC::PointKind Kind) {
144fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen  switch (Kind) {
145fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen    default: assert(0 && "Unknown GC point kind");
146fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen    case GC::Loop:     return "loop";
147fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen    case GC::Return:   return "return";
148fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen    case GC::PreCall:  return "pre-call";
149fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen    case GC::PostCall: return "post-call";
150fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen  }
151fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen}
152fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen
153ad93c4f936d220570535711262e0fff8857f798aGordon Henriksenbool Printer::runOnFunction(Function &F) {
154ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen  if (F.hasCollector()) {
155ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen    CollectorMetadata *FD = &getAnalysis<CollectorModuleMetadata>().get(F);
156fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen
157fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen    OS << "GC roots for " << FD->getFunction().getNameStart() << ":\n";
158fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen    for (CollectorMetadata::roots_iterator RI = FD->roots_begin(),
159fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen                                           RE = FD->roots_end();
160fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen                                           RI != RE; ++RI)
161fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen      OS << "\t" << RI->Num << "\t" << RI->StackOffset << "[sp]\n";
162fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen
163fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen    OS << "GC safe points for " << FD->getFunction().getNameStart() << ":\n";
164fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen    for (CollectorMetadata::iterator PI = FD->begin(),
165fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen                                     PE = FD->end(); PI != PE; ++PI) {
166fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen
167fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen      OS << "\tlabel " << PI->Num << ": " << DescKind(PI->Kind) << ", live = {";
168fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen
169fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen      for (CollectorMetadata::live_iterator RI = FD->live_begin(PI),
170fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen                                            RE = FD->live_end(PI);;) {
171fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen        OS << " " << RI->Num;
172fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen        if (++RI == RE)
173fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen          break;
174fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen        OS << ",";
175fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen      }
176fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen
177fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen      OS << " }\n";
178fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen    }
179fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen  }
180fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen
181fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen  return false;
182fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen}
183fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen
184fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen// -----------------------------------------------------------------------------
185fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen
186fc3282221f90c626d80292327213e2badc3de86bGordon Henriksenchar Deleter::ID = 0;
187fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen
188ad93c4f936d220570535711262e0fff8857f798aGordon HenriksenFunctionPass *llvm::createCollectorMetadataDeleter() {
189fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen  return new Deleter();
190fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen}
191fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen
192ad93c4f936d220570535711262e0fff8857f798aGordon HenriksenDeleter::Deleter() : FunctionPass(intptr_t(&ID)) {}
193fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen
194fc3282221f90c626d80292327213e2badc3de86bGordon Henriksenconst char *Deleter::getPassName() const {
195fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen  return "Delete Garbage Collector Information";
196fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen}
197fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen
198fc3282221f90c626d80292327213e2badc3de86bGordon Henriksenvoid Deleter::getAnalysisUsage(AnalysisUsage &AU) const {
199fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen  AU.setPreservesAll();
200fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen  AU.addRequired<CollectorModuleMetadata>();
201fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen}
202fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen
203ad93c4f936d220570535711262e0fff8857f798aGordon Henriksenbool Deleter::runOnFunction(Function &MF) {
204fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen  return false;
205fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen}
206fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen
207fc3282221f90c626d80292327213e2badc3de86bGordon Henriksenbool Deleter::doFinalization(Module &M) {
208ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen  CollectorModuleMetadata *CMM = getAnalysisToUpdate<CollectorModuleMetadata>();
209ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen  assert(CMM && "Deleter didn't require CollectorModuleMetadata?!");
210ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen  CMM->clear();
211fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen  return false;
212fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen}
213