LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ErlangGCPrinter.cpp
Go to the documentation of this file.
1 //===-- ErlangGCPrinter.cpp - Erlang/OTP frametable emitter -----*- C++ -*-===//
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 compiler plugin that is used in order to emit
11 // garbage collection information in a convenient layout for parsing and
12 // loading in the Erlang/OTP runtime.
13 //
14 //===----------------------------------------------------------------------===//
15 
17 #include "llvm/CodeGen/GCs.h"
19 #include "llvm/IR/DataLayout.h"
20 #include "llvm/IR/Function.h"
21 #include "llvm/IR/Instruction.h"
22 #include "llvm/IR/IntrinsicInst.h"
23 #include "llvm/IR/Metadata.h"
24 #include "llvm/MC/MCAsmInfo.h"
25 #include "llvm/MC/MCContext.h"
26 #include "llvm/MC/MCSectionELF.h"
27 #include "llvm/MC/MCStreamer.h"
28 #include "llvm/MC/MCSymbol.h"
31 
32 using namespace llvm;
33 
34 namespace {
35 
36  class ErlangGCPrinter : public GCMetadataPrinter {
37  public:
38  void beginAssembly(AsmPrinter &AP);
39  void finishAssembly(AsmPrinter &AP);
40  };
41 
42 }
43 
45 X("erlang", "erlang-compatible garbage collector");
46 
48 
49 void ErlangGCPrinter::beginAssembly(AsmPrinter &AP) { }
50 
51 void ErlangGCPrinter::finishAssembly(AsmPrinter &AP) {
52  MCStreamer &OS = AP.OutStreamer;
53  unsigned IntPtrSize = AP.TM.getDataLayout()->getPointerSize();
54 
55  // Put this in a custom .note section.
57  .getELFSection(".note.gc", ELF::SHT_PROGBITS, 0,
59 
60  // For each function...
61  for (iterator FI = begin(), FE = end(); FI != FE; ++FI) {
62  GCFunctionInfo &MD = **FI;
63 
64  /** A compact GC layout. Emit this data structure:
65  *
66  * struct {
67  * int16_t PointCount;
68  * void *SafePointAddress[PointCount];
69  * int16_t StackFrameSize; (in words)
70  * int16_t StackArity;
71  * int16_t LiveCount;
72  * int16_t LiveOffsets[LiveCount];
73  * } __gcmap_<FUNCTIONNAME>;
74  **/
75 
76  // Align to address width.
77  AP.EmitAlignment(IntPtrSize == 4 ? 2 : 3);
78 
79  // Emit PointCount.
80  OS.AddComment("safe point count");
81  AP.EmitInt16(MD.size());
82 
83  // And each safe point...
84  for (GCFunctionInfo::iterator PI = MD.begin(), PE = MD.end(); PI != PE;
85  ++PI) {
86  // Emit the address of the safe point.
87  OS.AddComment("safe point address");
88  MCSymbol *Label = PI->Label;
89  AP.EmitLabelPlusOffset(Label/*Hi*/, 0/*Offset*/, 4/*Size*/);
90  }
91 
92  // Stack information never change in safe points! Only print info from the
93  // first call-site.
95 
96  // Emit the stack frame size.
97  OS.AddComment("stack frame size (in words)");
98  AP.EmitInt16(MD.getFrameSize() / IntPtrSize);
99 
100  // Emit stack arity, i.e. the number of stacked arguments.
101  unsigned RegisteredArgs = IntPtrSize == 4 ? 5 : 6;
102  unsigned StackArity = MD.getFunction().arg_size() > RegisteredArgs ?
103  MD.getFunction().arg_size() - RegisteredArgs : 0;
104  OS.AddComment("stack arity");
105  AP.EmitInt16(StackArity);
106 
107  // Emit the number of live roots in the function.
108  OS.AddComment("live root count");
109  AP.EmitInt16(MD.live_size(PI));
110 
111  // And for each live root...
113  LE = MD.live_end(PI);
114  LI != LE; ++LI) {
115  // Emit live root's offset within the stack frame.
116  OS.AddComment("stack index (offset / wordsize)");
117  AP.EmitInt16(LI->StackOffset / IntPtrSize);
118  }
119  }
120 }
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:181
virtual void AddComment(const Twine &T)
Definition: MCStreamer.h:207
unsigned getPointerSize(unsigned AS=0) const
Definition: DataLayout.h:261
void EmitLabelPlusOffset(const MCSymbol *Label, uint64_t Offset, unsigned Size, bool IsSectionRelative=false) const
const MCSectionELF * getELFSection(StringRef Section, unsigned Type, unsigned Flags, SectionKind Kind)
Definition: MCContext.cpp:244
static SectionKind getDataRel()
Definition: SectionKind.h:229
const_iterator begin(StringRef path)
Get begin iterator over path.
Definition: Path.cpp:173
LoopInfoBase< BlockT, LoopT > * LI
Definition: LoopInfoImpl.h:411
void linkErlangGCPrinter()
Creates an erlang-compatible metadata printer.
size_t arg_size() const
Definition: Function.cpp:248
std::vector< GCPoint >::iterator iterator
Definition: GCMetadata.h:85
void SwitchSection(const MCSection *Section, const MCExpr *Subsection=0)
Definition: MCStreamer.h:284
MCStreamer & OutStreamer
Definition: AsmPrinter.h:78
void EmitInt16(int Value) const
TargetMachine & TM
Definition: AsmPrinter.h:62
uint64_t getFrameSize() const
Definition: GCMetadata.h:139
size_t live_size(const iterator &p) const
Definition: GCMetadata.h:158
live_iterator live_begin(const iterator &p)
Definition: GCMetadata.h:156
size_t size() const
Definition: GCMetadata.h:146
virtual const DataLayout * getDataLayout() const
void EmitAlignment(unsigned NumBits, const GlobalValue *GV=0) const
const TargetLoweringObjectFile & getObjFileLowering() const
getObjFileLowering - Return information about object file lowering.
Definition: AsmPrinter.cpp:129
const Function & getFunction() const
Definition: GCMetadata.h:112
live_iterator live_end(const iterator &p)
Definition: GCMetadata.h:157
std::vector< GCRoot >::const_iterator live_iterator
Definition: GCMetadata.h:87
static RegisterPass< NVPTXAllocaHoisting > X("alloca-hoisting","Hoisting alloca instructions in non-entry ""blocks to the entry block")