1//===- OcamlGCPrinter.cpp - Ocaml frametable emitter ----------------------===// 
  3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 
  4// See https://llvm.org/LICENSE.txt for license information. 
  5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 
  7//===----------------------------------------------------------------------===// 
  9// This file implements printing the assembly code for an Ocaml frametable. 
  11//===----------------------------------------------------------------------===// 
  40 void beginAssembly(
Module &M, GCModuleInfo &
Info, AsmPrinter &AP) 
override;
 
  41 void finishAssembly(
Module &M, GCModuleInfo &
Info, AsmPrinter &AP) 
override;
 
  44} 
// end anonymous namespace 
  46static GCMetadataPrinterRegistry::Add<OcamlGCMetadataPrinter>
 
  47  Y(
"ocaml", 
"ocaml 3.10-compatible collector");
 
  52 const std::string &MId = M.getModuleIdentifier();
 
  56 size_t Letter = SymName.size();
 
  57 SymName.append(MId.begin(), 
llvm::find(MId, 
'.'));
 
  61 // Capitalize the first letter of the module name. 
  62 SymName[Letter] = toupper(SymName[Letter]);
 
 
  82/// emitAssembly - Print the frametable. The ocaml frametable format is thus: 
  84/// extern "C" struct align(sizeof(intptr_t)) { 
  85/// uint16_t NumDescriptors; 
  86/// struct align(sizeof(intptr_t)) { 
  87/// void *ReturnAddress; 
  88/// uint16_t FrameSize; 
  89/// uint16_t NumLiveOffsets; 
  90/// uint16_t LiveOffsets[NumLiveOffsets]; 
  91/// } Descriptors[NumDescriptors]; 
  92/// } caml${module}__frametable; 
  94/// Note that this precludes programs from stack frames larger than 64K 
  95/// (FrameSize and LiveOffsets would overflow). FrameTablePrinter will abort if 
  96/// either condition is detected in a function which uses the GC. 
  98void OcamlGCMetadataPrinter::finishAssembly(
Module &M, GCModuleInfo &
Info,
 
  100 unsigned IntPtrSize = 
M.getDataLayout().getPointerSize();
 
  108 // FIXME: Why does ocaml emit this?? 
  114 int NumDescriptors = 0;
 
  115 for (std::unique_ptr<GCFunctionInfo> &FI :
 
  117 if (FI->getStrategy().getName() != getStrategy().
getName())
 
  118 // this function is managed by some other GC 
  120 NumDescriptors += FI->size();
 
  123 if (NumDescriptors >= 1 << 16) {
 
  130 for (std::unique_ptr<GCFunctionInfo> &FI :
 
  132 if (FI->getStrategy().getName() != getStrategy().
getName())
 
  133 // this function is managed by some other GC 
  136 uint64_t FrameSize = FI->getFrameSize();
 
  137 if (FrameSize >= 1 << 16) {
 
  140 "' is too large for the ocaml GC! " 
  145 Twine(
reinterpret_cast<uintptr_t
>(FI.get())) + 
")");
 
  149 Twine(FI->getFunction().getName()));
 
  154 size_t LiveCount = FI->live_size(J);
 
  155 if (LiveCount >= 1 << 16) {
 
  158 "' is too large for the ocaml GC! " 
  160 Twine(LiveCount) + 
" >= 65536.");
 
  163 AP.
OutStreamer->emitSymbolValue(J->Label, IntPtrSize);
 
  168 KE = FI->live_end(J);
 
  170 if (
K->StackOffset >= 1 << 16) {
 
  173 "GC root stack offset is outside of fixed stack frame and out " 
  174 "of range for ocaml GC!");
 
Analysis containing CSE Info
 
Module.h This file contains the declarations for the Module class.
 
Machine Check Debug Module
 
static void EmitCamlGlobal(const Module &M, AsmPrinter &AP, const char *Id)
 
static StringRef getName(Value *V)
 
This file defines the SmallString class.
 
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
 
This class is intended to be used as a driving class for all asm writers.
 
const TargetLoweringObjectFile & getObjFileLowering() const
Return information about object file lowering.
 
void emitAlignment(Align Alignment, const GlobalObject *GV=nullptr, unsigned MaxBytesToEmit=0) const
Emit an alignment directive to the specified power of two boundary.
 
MCContext & OutContext
This is the context for the output file that we are streaming.
 
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
 
void emitInt16(int Value) const
Emit a short directive and value.
 
std::vector< GCRoot >::const_iterator live_iterator
 
std::vector< GCPoint >::iterator iterator
 
An analysis pass which caches information about the entire Module.
 
LLVM_ABI MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
 
MCSection * getTextSection() const
 
MCSection * getDataSection() const
 
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
 
LLVM_ABI void getNameWithPrefix(raw_ostream &OS, const GlobalValue *GV, bool CannotUsePrivateLabel) const
Print the appropriate prefix and the specified global variable's name.
 
A Module instance is used to store all the information related to an LLVM module.
 
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
 
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
 
This is an optimization pass for GlobalISel generic memory operations.
 
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
 
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
 
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
 
LLVM_ABI void linkOcamlGCPrinter()
Creates an ocaml-compatible metadata printer.
 
@ MCSA_Global
.type _foo, @gnu_unique_object