LLVM  14.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 
15 #include "llvm/BinaryFormat/ELF.h"
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"
24 #include "llvm/MC/MCSectionELF.h"
25 #include "llvm/MC/MCStreamer.h"
26 #include "llvm/MC/MCSymbol.h"
28 
29 using namespace llvm;
30 
31 namespace {
32 
33 class ErlangGCPrinter : public GCMetadataPrinter {
34 public:
35  void finishAssembly(Module &M, GCModuleInfo &Info, AsmPrinter &AP) override;
36 };
37 
38 } // end anonymous namespace
39 
41  X("erlang", "erlang-compatible garbage collector");
42 
43 void ErlangGCPrinter::finishAssembly(Module &M, GCModuleInfo &Info,
44  AsmPrinter &AP) {
45  MCStreamer &OS = *AP.OutStreamer;
46  unsigned IntPtrSize = M.getDataLayout().getPointerSize();
47 
48  // Put this in a custom .note section.
49  OS.SwitchSection(
51  ELF::SHT_PROGBITS, 0));
52 
53  // For each function...
54  for (GCModuleInfo::FuncInfoVec::iterator FI = Info.funcinfo_begin(),
55  IE = Info.funcinfo_end();
56  FI != IE; ++FI) {
57  GCFunctionInfo &MD = **FI;
58  if (MD.getStrategy().getName() != getStrategy().getName())
59  // this function is managed by some other GC
60  continue;
61  /** A compact GC layout. Emit this data structure:
62  *
63  * struct {
64  * int16_t PointCount;
65  * void *SafePointAddress[PointCount];
66  * int16_t StackFrameSize; (in words)
67  * int16_t StackArity;
68  * int16_t LiveCount;
69  * int16_t LiveOffsets[LiveCount];
70  * } __gcmap_<FUNCTIONNAME>;
71  **/
72 
73  // Align to address width.
74  AP.emitAlignment(IntPtrSize == 4 ? Align(4) : Align(8));
75 
76  // Emit PointCount.
77  OS.AddComment("safe point count");
78  AP.emitInt16(MD.size());
79 
80  // And each safe point...
81  for (const GCPoint &P : MD) {
82  // Emit the address of the safe point.
83  OS.AddComment("safe point address");
84  MCSymbol *Label = P.Label;
85  AP.emitLabelPlusOffset(Label /*Hi*/, 0 /*Offset*/, 4 /*Size*/);
86  }
87 
88  // Stack information never change in safe points! Only print info from the
89  // first call-site.
90  GCFunctionInfo::iterator PI = MD.begin();
91 
92  // Emit the stack frame size.
93  OS.AddComment("stack frame size (in words)");
94  AP.emitInt16(MD.getFrameSize() / IntPtrSize);
95 
96  // Emit stack arity, i.e. the number of stacked arguments.
97  unsigned RegisteredArgs = IntPtrSize == 4 ? 5 : 6;
98  unsigned StackArity = MD.getFunction().arg_size() > RegisteredArgs
99  ? MD.getFunction().arg_size() - RegisteredArgs
100  : 0;
101  OS.AddComment("stack arity");
102  AP.emitInt16(StackArity);
103 
104  // Emit the number of live roots in the function.
105  OS.AddComment("live root count");
106  AP.emitInt16(MD.live_size(PI));
107 
108  // And for each live root...
109  for (GCFunctionInfo::live_iterator LI = MD.live_begin(PI),
110  LE = MD.live_end(PI);
111  LI != LE; ++LI) {
112  // Emit live root's offset within the stack frame.
113  OS.AddComment("stack index (offset / wordsize)");
114  AP.emitInt16(LI->StackOffset / IntPtrSize);
115  }
116  }
117 }
118 
AsmPrinter.h
getName
static StringRef getName(Value *V)
Definition: ProvenanceAnalysisEvaluator.cpp:42
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
GCMetadata.h
llvm::MCSymbol
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
P
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
Definition: README-SSE.txt:411
MCSectionELF.h
llvm::GCFunctionInfo
Garbage collection metadata for a single function.
Definition: GCMetadata.h:77
llvm::GCFunctionInfo::iterator
std::vector< GCPoint >::iterator iterator
Definition: GCMetadata.h:79
llvm::GCStrategy::getName
const std::string & getName() const
Return the name of the GC strategy.
Definition: GCStrategy.h:86
Module.h
llvm::GCFunctionInfo::getStrategy
GCStrategy & getStrategy()
getStrategy - Return the GC strategy for the function.
Definition: GCMetadata.h:108
llvm::GCMetadataPrinter
GCMetadataPrinter - Emits GC metadata as assembly code.
Definition: GCMetadataPrinter.h:39
llvm::MCObjectFileInfo::getContext
MCContext & getContext() const
Definition: MCObjectFileInfo.h:235
llvm::ELF::SHT_PROGBITS
@ SHT_PROGBITS
Definition: ELF.h:910
llvm::MCStreamer
Streaming machine code generation interface.
Definition: MCStreamer.h:199
llvm::GCFunctionInfo::live_iterator
std::vector< GCRoot >::const_iterator live_iterator
Definition: GCMetadata.h:81
ELF.h
llvm::AsmPrinter::OutStreamer
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
Definition: AsmPrinter.h:97
MCContext.h
MCSymbol.h
llvm::MCContext::getELFSection
MCSectionELF * getELFSection(const Twine &Section, unsigned Type, unsigned Flags)
Definition: MCContext.h:540
llvm::AsmPrinter::emitAlignment
void emitAlignment(Align Alignment, const GlobalObject *GV=nullptr) const
Emit an alignment directive to the specified power of two boundary.
Definition: AsmPrinter.cpp:2450
llvm::AArch64CC::LE
@ LE
Definition: AArch64BaseInfo.h:268
Info
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
Align
uint64_t Align
Definition: ELFObjHandler.cpp:83
X
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
llvm::ARM_PROC::IE
@ IE
Definition: ARMBaseInfo.h:27
llvm::AsmPrinter::emitLabelPlusOffset
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...
Definition: AsmPrinter.cpp:2425
BuiltinGCs.h
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
DataLayout.h
llvm::GCFunctionInfo::size
size_t size() const
Definition: GCMetadata.h:136
TargetLoweringObjectFile.h
llvm::pdb::PDB_SymType::Label
@ Label
Function.h
llvm::AsmPrinter
This class is intended to be used as a driving class for all asm writers.
Definition: AsmPrinter.h:82
GCMetadataPrinter.h
llvm::AsmPrinter::getObjFileLowering
const TargetLoweringObjectFile & getObjFileLowering() const
Return information about object file lowering.
Definition: AsmPrinter.cpp:224
MCStreamer.h
llvm::GCPoint
GCPoint - Metadata for a collector-safe point in machine code.
Definition: GCMetadata.h:56
llvm::linkErlangGCPrinter
void linkErlangGCPrinter()
Creates an erlang-compatible metadata printer.
Definition: ErlangGCPrinter.cpp:119
llvm::Registry::Add
A static registration template.
Definition: Registry.h:114
llvm::MCStreamer::SwitchSection
virtual void SwitchSection(MCSection *Section, const MCExpr *Subsection=nullptr)
Set the current section where code is being emitted to Section.
Definition: MCStreamer.cpp:1212
llvm::GCModuleInfo
An analysis pass which caches information about the entire Module.
Definition: GCMetadata.h:152
llvm::AsmPrinter::emitInt16
void emitInt16(int Value) const
Emit a short directive and value.
Definition: AsmPrinter.cpp:2404
llvm::MCStreamer::AddComment
virtual void AddComment(const Twine &T, bool EOL=true)
Add a textual comment.
Definition: MCStreamer.h:342