LLVM  6.0.0svn
GCMetadata.cpp
Go to the documentation of this file.
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 
14 #include "llvm/ADT/STLExtras.h"
17 #include "llvm/CodeGen/Passes.h"
18 #include "llvm/IR/Function.h"
19 #include "llvm/MC/MCSymbol.h"
20 #include "llvm/Pass.h"
23 #include <algorithm>
24 #include <cassert>
25 #include <memory>
26 #include <string>
27 
28 using namespace llvm;
29 
30 namespace {
31 
32 class Printer : public FunctionPass {
33  static char ID;
34 
35  raw_ostream &OS;
36 
37 public:
38  explicit Printer(raw_ostream &OS) : FunctionPass(ID), OS(OS) {}
39 
40  StringRef getPassName() const override;
41  void getAnalysisUsage(AnalysisUsage &AU) const override;
42 
43  bool runOnFunction(Function &F) override;
44  bool doFinalization(Module &M) override;
45 };
46 
47 } // end anonymous namespace
48 
49 INITIALIZE_PASS(GCModuleInfo, "collector-metadata",
50  "Create Garbage Collector Module Metadata", false, false)
51 
52 // -----------------------------------------------------------------------------
53 
55  : F(F), S(S), FrameSize(~0LL) {}
56 
58 
59 // -----------------------------------------------------------------------------
60 
61 char GCModuleInfo::ID = 0;
62 
65 }
66 
68  assert(!F.isDeclaration() && "Can only get GCFunctionInfo for a definition!");
69  assert(F.hasGC());
70 
71  finfo_map_type::iterator I = FInfoMap.find(&F);
72  if (I != FInfoMap.end())
73  return *I->second;
74 
75  GCStrategy *S = getGCStrategy(F.getGC());
76  Functions.push_back(llvm::make_unique<GCFunctionInfo>(F, *S));
77  GCFunctionInfo *GFI = Functions.back().get();
78  FInfoMap[&F] = GFI;
79  return *GFI;
80 }
81 
83  Functions.clear();
84  FInfoMap.clear();
85  GCStrategyList.clear();
86 }
87 
88 // -----------------------------------------------------------------------------
89 
90 char Printer::ID = 0;
91 
93  return new Printer(OS);
94 }
95 
96 StringRef Printer::getPassName() const {
97  return "Print Garbage Collector Information";
98 }
99 
100 void Printer::getAnalysisUsage(AnalysisUsage &AU) const {
102  AU.setPreservesAll();
104 }
105 
106 static const char *DescKind(GC::PointKind Kind) {
107  switch (Kind) {
108  case GC::PreCall:
109  return "pre-call";
110  case GC::PostCall:
111  return "post-call";
112  }
113  llvm_unreachable("Invalid point kind");
114 }
115 
117  if (F.hasGC())
118  return false;
119 
120  GCFunctionInfo *FD = &getAnalysis<GCModuleInfo>().getFunctionInfo(F);
121 
122  OS << "GC roots for " << FD->getFunction().getName() << ":\n";
124  RE = FD->roots_end();
125  RI != RE; ++RI)
126  OS << "\t" << RI->Num << "\t" << RI->StackOffset << "[sp]\n";
127 
128  OS << "GC safe points for " << FD->getFunction().getName() << ":\n";
129  for (GCFunctionInfo::iterator PI = FD->begin(), PE = FD->end(); PI != PE;
130  ++PI) {
131 
132  OS << "\t" << PI->Label->getName() << ": " << DescKind(PI->Kind)
133  << ", live = {";
134 
135  for (GCFunctionInfo::live_iterator RI = FD->live_begin(PI),
136  RE = FD->live_end(PI);
137  ;) {
138  OS << " " << RI->Num;
139  if (++RI == RE)
140  break;
141  OS << ",";
142  }
143 
144  OS << " }\n";
145  }
146 
147  return false;
148 }
149 
150 bool Printer::doFinalization(Module &M) {
151  GCModuleInfo *GMI = getAnalysisIfAvailable<GCModuleInfo>();
152  assert(GMI && "Printer didn't require GCModuleInfo?!");
153  GMI->clear();
154  return false;
155 }
156 
158  // TODO: Arguably, just doing a linear search would be faster for small N
159  auto NMI = GCStrategyMap.find(Name);
160  if (NMI != GCStrategyMap.end())
161  return NMI->getValue();
162 
163  for (auto& Entry : GCRegistry::entries()) {
164  if (Name == Entry.getName()) {
165  std::unique_ptr<GCStrategy> S = Entry.instantiate();
166  S->Name = Name;
167  GCStrategyMap[Name] = S.get();
168  GCStrategyList.push_back(std::move(S));
169  return GCStrategyList.back().get();
170  }
171  }
172 
173  if (GCRegistry::begin() == GCRegistry::end()) {
174  // In normal operation, the registry should not be empty. There should
175  // be the builtin GCs if nothing else. The most likely scenario here is
176  // that we got here without running the initializers used by the Registry
177  // itself and it's registration mechanism.
178  const std::string error = ("unsupported GC: " + Name).str() +
179  " (did you remember to link and initialize the CodeGen library?)";
180  report_fatal_error(error);
181  } else
182  report_fatal_error(std::string("unsupported GC: ") + Name);
183 }
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:115
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:63
INITIALIZE_PASS(GCModuleInfo, "collector-metadata", "Create Garbage Collector Module Metadata", false, false) GCFunctionInfo
Definition: GCMetadata.cpp:49
#define error(X)
F(f)
static iterator_range< iterator > entries()
Definition: Registry.h:102
PointKind
PointKind - Used to indicate whether the address of the call instruction or the address after the cal...
Definition: GCStrategy.h:68
print alias Alias Set Printer
AnalysisUsage & addRequired()
GCFunctionInfo & getFunctionInfo(const Function &F)
get - Look up function metadata.
Definition: GCMetadata.cpp:67
An analysis pass which caches information about the entire Module.
Definition: GCMetadata.h:154
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
Definition: Pass.cpp:91
const std::string & getGC() const
Definition: Function.cpp:444
FunctionPass * createGCInfoPrinter(raw_ostream &OS)
Creates a pass to print GC metadata.
Definition: GCMetadata.cpp:92
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:146
static bool runOnFunction(Function &F, bool PostInlining)
roots_iterator roots_end()
Definition: GCMetadata.h:142
const Function & getFunction() const
getFunction - Return the function to which this metadata applies.
Definition: GCMetadata.h:107
Instr is the return address of a call.
Definition: GCStrategy.h:70
Represent the analysis usage information of a pass.
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:285
roots_iterator roots_begin()
roots_begin/roots_end - Iterators for all roots in the function.
Definition: GCMetadata.h:141
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
std::vector< GCRoot >::iterator roots_iterator
Definition: GCMetadata.h:82
static iterator begin()
ImmutablePass class - This class is used to provide information that does not need to be run...
Definition: Pass.h:256
live_iterator live_begin(const iterator &p)
live_begin/live_end - Iterators for live roots at a given safe point.
Definition: GCMetadata.h:146
GCStrategy * getGCStrategy(const StringRef Name)
Lookup the GCStrategy object associated with the given gc name.
Definition: GCMetadata.cpp:157
void setPreservesAll()
Set by analyses that do not transform their input at all.
iterator begin()
begin/end - Iterators for safe points.
Definition: GCMetadata.h:136
static char ID
Definition: GCMetadata.h:185
std::vector< GCPoint >::iterator iterator
Definition: GCMetadata.h:81
GCStrategy describes a garbage collector algorithm&#39;s code generation requirements, and provides overridable hooks for those needs which cannot be abstractly described.
Definition: GCStrategy.h:80
bool hasGC() const
hasGC/getGC/setGC/clearGC - The name of the garbage collection algorithm to use during code generatio...
Definition: Function.h:286
void clear()
clear - Resets the pass.
Definition: GCMetadata.cpp:82
StringRef getName() const
Return a constant reference to the value&#39;s name.
Definition: Value.cpp:220
void initializeGCModuleInfoPass(PassRegistry &)
#define I(x, y, z)
Definition: MD5.cpp:58
iterator end()
Definition: DenseMap.h:79
Instr is a call instruction.
Definition: GCStrategy.h:69
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Definition: Globals.cpp:201
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
aarch64 promote const
static iterator end()
Definition: Registry.h:100
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:44
std::vector< GCRoot >::const_iterator live_iterator
Definition: GCMetadata.h:83
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
live_iterator live_end(const iterator &p)
Definition: GCMetadata.h:147
Garbage collection metadata for a single function.
Definition: GCMetadata.h:79
static const char * DescKind(GC::PointKind Kind)
Definition: GCMetadata.cpp:106