GCMetadata.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. //===-- GCMetadata.cpp - Garbage collector metadata -----------------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file implements the GCFunctionInfo class and GCModuleInfo pass.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "llvm/CodeGen/GCMetadata.h"
  14. #include "llvm/CodeGen/GCStrategy.h"
  15. #include "llvm/CodeGen/MachineFrameInfo.h"
  16. #include "llvm/Pass.h"
  17. #include "llvm/CodeGen/Passes.h"
  18. #include "llvm/Function.h"
  19. #include "llvm/Support/ErrorHandling.h"
  20. #include "llvm/Support/raw_ostream.h"
  21. using namespace llvm;
  22. namespace {
  23. class Printer : public FunctionPass {
  24. static char ID;
  25. raw_ostream &OS;
  26. public:
  27. Printer() : FunctionPass(&ID), OS(errs()) {}
  28. explicit Printer(raw_ostream &OS) : FunctionPass(&ID), OS(OS) {}
  29. const char *getPassName() const;
  30. void getAnalysisUsage(AnalysisUsage &AU) const;
  31. bool runOnFunction(Function &F);
  32. };
  33. class Deleter : public FunctionPass {
  34. static char ID;
  35. public:
  36. Deleter();
  37. const char *getPassName() const;
  38. void getAnalysisUsage(AnalysisUsage &AU) const;
  39. bool runOnFunction(Function &F);
  40. bool doFinalization(Module &M);
  41. };
  42. }
  43. static RegisterPass<GCModuleInfo>
  44. X("collector-metadata", "Create Garbage Collector Module Metadata");
  45. // -----------------------------------------------------------------------------
  46. GCFunctionInfo::GCFunctionInfo(const Function &F, GCStrategy &S)
  47. : F(F), S(S), FrameSize(~0LL) {}
  48. GCFunctionInfo::~GCFunctionInfo() {}
  49. // -----------------------------------------------------------------------------
  50. char GCModuleInfo::ID = 0;
  51. GCModuleInfo::GCModuleInfo()
  52. : ImmutablePass(&ID) {}
  53. GCModuleInfo::~GCModuleInfo() {
  54. clear();
  55. }
  56. GCStrategy *GCModuleInfo::getOrCreateStrategy(const Module *M,
  57. const std::string &Name) {
  58. strategy_map_type::iterator NMI = StrategyMap.find(Name);
  59. if (NMI != StrategyMap.end())
  60. return NMI->getValue();
  61. for (GCRegistry::iterator I = GCRegistry::begin(),
  62. E = GCRegistry::end(); I != E; ++I) {
  63. if (Name == I->getName()) {
  64. GCStrategy *S = I->instantiate();
  65. S->M = M;
  66. S->Name = Name;
  67. StrategyMap.GetOrCreateValue(Name).setValue(S);
  68. StrategyList.push_back(S);
  69. return S;
  70. }
  71. }
  72. errs() << "unsupported GC: " << Name << "\n";
  73. llvm_unreachable(0);
  74. }
  75. GCFunctionInfo &GCModuleInfo::getFunctionInfo(const Function &F) {
  76. assert(!F.isDeclaration() && "Can only get GCFunctionInfo for a definition!");
  77. assert(F.hasGC());
  78. finfo_map_type::iterator I = FInfoMap.find(&F);
  79. if (I != FInfoMap.end())
  80. return *I->second;
  81. GCStrategy *S = getOrCreateStrategy(F.getParent(), F.getGC());
  82. GCFunctionInfo *GFI = S->insertFunctionInfo(F);
  83. FInfoMap[&F] = GFI;
  84. return *GFI;
  85. }
  86. void GCModuleInfo::clear() {
  87. FInfoMap.clear();
  88. StrategyMap.clear();
  89. for (iterator I = begin(), E = end(); I != E; ++I)
  90. delete *I;
  91. StrategyList.clear();
  92. }
  93. // -----------------------------------------------------------------------------
  94. char Printer::ID = 0;
  95. FunctionPass *llvm::createGCInfoPrinter(raw_ostream &OS) {
  96. return new Printer(OS);
  97. }
  98. const char *Printer::getPassName() const {
  99. return "Print Garbage Collector Information";
  100. }
  101. void Printer::getAnalysisUsage(AnalysisUsage &AU) const {
  102. FunctionPass::getAnalysisUsage(AU);
  103. AU.setPreservesAll();
  104. AU.addRequired<GCModuleInfo>();
  105. }
  106. static const char *DescKind(GC::PointKind Kind) {
  107. switch (Kind) {
  108. default: llvm_unreachable("Unknown GC point kind");
  109. case GC::Loop: return "loop";
  110. case GC::Return: return "return";
  111. case GC::PreCall: return "pre-call";
  112. case GC::PostCall: return "post-call";
  113. }
  114. }
  115. bool Printer::runOnFunction(Function &F) {
  116. if (!F.hasGC()) {
  117. GCFunctionInfo *FD = &getAnalysis<GCModuleInfo>().getFunctionInfo(F);
  118. OS << "GC roots for " << FD->getFunction().getNameStr() << ":\n";
  119. for (GCFunctionInfo::roots_iterator RI = FD->roots_begin(),
  120. RE = FD->roots_end(); RI != RE; ++RI)
  121. OS << "\t" << RI->Num << "\t" << RI->StackOffset << "[sp]\n";
  122. OS << "GC safe points for " << FD->getFunction().getNameStr() << ":\n";
  123. for (GCFunctionInfo::iterator PI = FD->begin(),
  124. PE = FD->end(); PI != PE; ++PI) {
  125. OS << "\tlabel " << PI->Num << ": " << DescKind(PI->Kind) << ", live = {";
  126. for (GCFunctionInfo::live_iterator RI = FD->live_begin(PI),
  127. RE = FD->live_end(PI);;) {
  128. OS << " " << RI->Num;
  129. if (++RI == RE)
  130. break;
  131. OS << ",";
  132. }
  133. OS << " }\n";
  134. }
  135. }
  136. return false;
  137. }
  138. // -----------------------------------------------------------------------------
  139. char Deleter::ID = 0;
  140. FunctionPass *llvm::createGCInfoDeleter() {
  141. return new Deleter();
  142. }
  143. Deleter::Deleter() : FunctionPass(&ID) {}
  144. const char *Deleter::getPassName() const {
  145. return "Delete Garbage Collector Information";
  146. }
  147. void Deleter::getAnalysisUsage(AnalysisUsage &AU) const {
  148. AU.setPreservesAll();
  149. AU.addRequired<GCModuleInfo>();
  150. }
  151. bool Deleter::runOnFunction(Function &MF) {
  152. return false;
  153. }
  154. bool Deleter::doFinalization(Module &M) {
  155. GCModuleInfo *GMI = getAnalysisIfAvailable<GCModuleInfo>();
  156. assert(GMI && "Deleter didn't require GCModuleInfo?!");
  157. GMI->clear();
  158. return false;
  159. }