LLVM 20.0.0git
ErlangGCPrinter.cpp
Go to the documentation of this file.
1//===- ErlangGCPrinter.cpp - Erlang/OTP frametable emitter ----------------===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the compiler plugin that is used in order to emit
10// garbage collection information in a convenient layout for parsing and
11// loading in the Erlang/OTP runtime.
12//
13//===----------------------------------------------------------------------===//
14
19#include "llvm/IR/BuiltinGCs.h"
20#include "llvm/IR/DataLayout.h"
21#include "llvm/IR/Function.h"
22#include "llvm/IR/Module.h"
23#include "llvm/MC/MCContext.h"
25#include "llvm/MC/MCStreamer.h"
27
28using namespace llvm;
29
30namespace {
31
32class ErlangGCPrinter : public GCMetadataPrinter {
33public:
34 void finishAssembly(Module &M, GCModuleInfo &Info, AsmPrinter &AP) override;
35};
36
37} // end anonymous namespace
38
40 X("erlang", "erlang-compatible garbage collector");
41
42void ErlangGCPrinter::finishAssembly(Module &M, GCModuleInfo &Info,
43 AsmPrinter &AP) {
45 unsigned IntPtrSize = M.getDataLayout().getPointerSize();
46
47 // Put this in a custom .note section.
48 OS.switchSection(AP.getObjFileLowering().getContext().getELFSection(
49 ".note.gc", ELF::SHT_PROGBITS, 0));
50
51 // For each function...
52 for (GCModuleInfo::FuncInfoVec::iterator FI = Info.funcinfo_begin(),
53 IE = Info.funcinfo_end();
54 FI != IE; ++FI) {
55 GCFunctionInfo &MD = **FI;
56 if (MD.getStrategy().getName() != getStrategy().getName())
57 // this function is managed by some other GC
58 continue;
59 /** A compact GC layout. Emit this data structure:
60 *
61 * struct {
62 * int16_t PointCount;
63 * void *SafePointAddress[PointCount];
64 * int16_t StackFrameSize; (in words)
65 * int16_t StackArity;
66 * int16_t LiveCount;
67 * int16_t LiveOffsets[LiveCount];
68 * } __gcmap_<FUNCTIONNAME>;
69 **/
70
71 // Align to address width.
72 AP.emitAlignment(IntPtrSize == 4 ? Align(4) : Align(8));
73
74 // Emit PointCount.
75 OS.AddComment("safe point count");
76 AP.emitInt16(MD.size());
77
78 // And each safe point...
79 for (const GCPoint &P : MD) {
80 // Emit the address of the safe point.
81 OS.AddComment("safe point address");
82 MCSymbol *Label = P.Label;
83 AP.emitLabelPlusOffset(Label /*Hi*/, 0 /*Offset*/, 4 /*Size*/);
84 }
85
86 // Stack information never change in safe points! Only print info from the
87 // first call-site.
88 GCFunctionInfo::iterator PI = MD.begin();
89
90 // Emit the stack frame size.
91 OS.AddComment("stack frame size (in words)");
92 AP.emitInt16(MD.getFrameSize() / IntPtrSize);
93
94 // Emit stack arity, i.e. the number of stacked arguments.
95 unsigned RegisteredArgs = IntPtrSize == 4 ? 5 : 6;
96 unsigned StackArity = MD.getFunction().arg_size() > RegisteredArgs
97 ? MD.getFunction().arg_size() - RegisteredArgs
98 : 0;
99 OS.AddComment("stack arity");
100 AP.emitInt16(StackArity);
101
102 // Emit the number of live roots in the function.
103 OS.AddComment("live root count");
104 AP.emitInt16(MD.live_size(PI));
105
106 // And for each live root...
107 for (GCFunctionInfo::live_iterator LI = MD.live_begin(PI),
108 LE = MD.live_end(PI);
109 LI != LE; ++LI) {
110 // Emit live root's offset within the stack frame.
111 OS.AddComment("stack index (offset / wordsize)");
112 AP.emitInt16(LI->StackOffset / IntPtrSize);
113 }
114 }
115}
116
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
Module.h This file contains the declarations for the Module class.
#define P(N)
static StringRef getName(Value *V)
raw_pwrite_stream & OS
This class is intended to be used as a driving class for all asm writers.
Definition: AsmPrinter.h:86
const TargetLoweringObjectFile & getObjFileLowering() const
Return information about object file lowering.
Definition: AsmPrinter.cpp:383
void emitLabelPlusOffset(const MCSymbol *Label, uint64_t Offset, unsigned Size, bool IsSectionRelative=false) const
Emit something like ".long Label+Offset" where the size in bytes of the directive is specified by Siz...
void emitAlignment(Align Alignment, const GlobalObject *GV=nullptr, unsigned MaxBytesToEmit=0) const
Emit an alignment directive to the specified power of two boundary.
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
Definition: AsmPrinter.h:101
void emitInt16(int Value) const
Emit a short directive and value.
Garbage collection metadata for a single function.
Definition: GCMetadata.h:78
size_t size() const
Definition: GCMetadata.h:141
GCStrategy & getStrategy()
getStrategy - Return the GC strategy for the function.
Definition: GCMetadata.h:113
std::vector< GCRoot >::const_iterator live_iterator
Definition: GCMetadata.h:82
std::vector< GCPoint >::iterator iterator
Definition: GCMetadata.h:80
GCMetadataPrinter - Emits GC metadata as assembly code.
virtual void finishAssembly(Module &M, GCModuleInfo &Info, AsmPrinter &AP)
Called after the assembly for the module is generated by the AsmPrinter (but before target specific h...
An analysis pass which caches information about the entire Module.
Definition: GCMetadata.h:203
const std::string & getName() const
Return the name of the GC strategy.
Definition: GCStrategy.h:88
MCSectionELF * getELFSection(const Twine &Section, unsigned Type, unsigned Flags)
Definition: MCContext.h:551
MCContext & getContext() const
Streaming machine code generation interface.
Definition: MCStreamer.h:213
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
A static registration template.
Definition: Registry.h:114
@ SHT_PROGBITS
Definition: ELF.h:1089
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
void linkErlangGCPrinter()
Creates an erlang-compatible metadata printer.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
GCPoint - Metadata for a collector-safe point in machine code.
Definition: GCMetadata.h:57