//===- OcamlGCPrinter.cpp - Ocaml frametable emitter ----------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file implements printing the assembly code for an Ocaml frametable. // //===----------------------------------------------------------------------===// #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/Twine.h" #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/CodeGen/GCMetadata.h" #include "llvm/CodeGen/GCMetadataPrinter.h" #include "llvm/IR/BuiltinGCs.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/Function.h" #include "llvm/IR/Mangler.h" #include "llvm/IR/Module.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCDirectives.h" #include "llvm/MC/MCStreamer.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Target/TargetLoweringObjectFile.h" #include <cctype> #include <cstddef> #include <cstdint> #include <string> usingnamespacellvm; namespace { class OcamlGCMetadataPrinter : public GCMetadataPrinter { … }; } // end anonymous namespace static GCMetadataPrinterRegistry::Add<OcamlGCMetadataPrinter> Y("ocaml", "ocaml 3.10-compatible collector"); void llvm::linkOcamlGCPrinter() { … } static void EmitCamlGlobal(const Module &M, AsmPrinter &AP, const char *Id) { … } void OcamlGCMetadataPrinter::beginAssembly(Module &M, GCModuleInfo &Info, AsmPrinter &AP) { … } /// emitAssembly - Print the frametable. The ocaml frametable format is thus: /// /// extern "C" struct align(sizeof(intptr_t)) { /// uint16_t NumDescriptors; /// struct align(sizeof(intptr_t)) { /// void *ReturnAddress; /// uint16_t FrameSize; /// uint16_t NumLiveOffsets; /// uint16_t LiveOffsets[NumLiveOffsets]; /// } Descriptors[NumDescriptors]; /// } caml${module}__frametable; /// /// Note that this precludes programs from stack frames larger than 64K /// (FrameSize and LiveOffsets would overflow). FrameTablePrinter will abort if /// either condition is detected in a function which uses the GC. /// void OcamlGCMetadataPrinter::finishAssembly(Module &M, GCModuleInfo &Info, AsmPrinter &AP) { … }