File: StreamEmitter.hpp

package info (click to toggle)
intel-graphics-compiler 1.0.17791.18-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 102,312 kB
  • sloc: cpp: 935,343; lisp: 286,143; ansic: 16,196; python: 3,279; yacc: 2,487; lex: 1,642; pascal: 300; sh: 174; makefile: 27
file content (261 lines) | stat: -rw-r--r-- 10,207 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
/*========================== begin_copyright_notice ============================

Copyright (C) 2017-2021 Intel Corporation

SPDX-License-Identifier: MIT

============================= end_copyright_notice ===========================*/

/*========================== begin_copyright_notice ============================

This file is distributed under the University of Illinois Open Source License.
See LICENSE.TXT for details.

============================= end_copyright_notice ===========================*/

#pragma once

// clang-format off
#include "common/LLVMWarningsPush.hpp"
#include "llvm/Config/llvm-config.h"
#include "llvmWrapper/MC/MCContext.h"
#include "llvmWrapper/MC/MCObjectFileInfo.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/MC/MCSection.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/raw_ostream.h"
#include "common/LLVMWarningsPop.hpp"
// clang-format on

#include <string>

#include "EmitterOpts.hpp"

namespace llvm {
class MCStreamer;
class SourceMgr;
class MCAsmInfo;
} // namespace llvm

namespace IGC {
class DbgVariable;
class DwarfDebug;
class VISAVariableLocation;

/// @brief StreamEmitter provides API methods for emitting elf object.
///        It will be used to emit the debug info sections in dwarf format.
class StreamEmitter {
public:
  typedef DebugEmitterOpts Settings;
  /// @brief Constructor.
  /// @param raw_ostream instance of raw_ostream to emit all bitcode into.
  /// @param dataLayout data layout string.
  /// @param targetTriple target triple string.
  StreamEmitter(llvm::raw_pwrite_stream &, const std::string &dataLayout,
                const std::string &targetTriple,
                const Settings &EmitterOptions);

  /// @brief Destructor.
  ~StreamEmitter();
  StreamEmitter(const StreamEmitter &) = delete;
  StreamEmitter &operator=(const StreamEmitter &) = delete;

  const Settings &GetEmitterSettings() const { return StreamOptions; };

  /// @brief Get pointer size.
  /// @return pointer size in bits.
  unsigned int GetPointerSize() const;

  /// @brief Get endianness data stored in memory.
  /// @return true for Little-endian, and false for Big-endian.
  bool IsLittleEndian() const;

  /// @brief Section getter methods
  const llvm::MCSection *GetTextSection() const;
  const llvm::MCSection *GetDataSection() const;
  const llvm::MCSection *GetDwarfAbbrevSection() const;
  const llvm::MCSection *GetDwarfInfoSection() const;
  const llvm::MCSection *GetDwarfLineSection() const;
  const llvm::MCSection *GetDwarfLocSection() const;
  const llvm::MCSection *GetDwarfMacroInfoSection() const;
  const llvm::MCSection *GetDwarfRangesSection() const;
  const llvm::MCSection *GetDwarfStrSection() const;
  const llvm::MCSection *GetDwarfFrameSection() const;

  /// @brief Set the current section where code is being emitted to.
  /// @param pSection section to switch to
  /// @param pSubsection subsiction to switch to (optional)
  void SwitchSection(const llvm::MCSection *pSection,
                     const llvm::MCExpr *pSubsection = 0) const;

  /// @brief sympol getters
  /// @param pGV Global Variable
  /// @return Machine Code symbol
  llvm::MCSymbol *GetSymbol(const llvm::GlobalValue *pGV) const;

  /// @brief Return the MCSymbol corresponding to the assembler
  ///        temporary label with the specified stem and unique ID.
  /// @param name symbol name
  /// @param id symbol id
  /// @return Machine Code symbol
  llvm::MCSymbol *GetTempSymbol(llvm::StringRef name, uint64_t id) const;

  /// @brief Return an assembler temporary label with the specified stem.
  /// @param name symbol name
  /// @return Machine Code symbol
  llvm::MCSymbol *GetTempSymbol(llvm::StringRef name) const;

  /// @brief Return an assembler temporary label with the specified stem.
  /// @return Machine Code symbol
  llvm::MCSymbol *CreateTempSymbol() const;

  /// @brief Dwarf CU getter & setter
  unsigned GetDwarfCompileUnitID() const;
  void SetDwarfCompileUnitID(unsigned cuIndex) const;

  //===------------------------------------------------------------------===//
  // Dwarf Emission Helper Routines
  //===------------------------------------------------------------------===//

  /// @brief Emit the bytes in \p Data into the output.
  void EmitBytes(llvm::StringRef data, unsigned addrSpace = 0) const;

  /// @brief Emit the expression @p value into the output as a native
  ///        integer of the given @p size bytes.
  void EmitValue(const llvm::MCExpr *pValue, unsigned size,
                 unsigned addrSpace = 0) const;

  /// @brief Special case of EmitValue that avoids the client having
  ///        to pass in a MCExpr for constant integers.
  void EmitIntValue(uint64_t value, unsigned size,
                    unsigned addrSpace = 0) const;

  /// @brief Emit a byte directive and value.
  void EmitInt8(int value) const;

  /// @brief Emit a short directive and value.
  void EmitInt16(int value) const;

  /// @brief Emit a long directive and value.
  void EmitInt32(int value) const;

  /// @brief emit the specified signed leb128 value.
  void EmitSLEB128(int64_t value, const char *pDesc = 0) const;

  /// @brief emit the specified unsigned leb128 value.
  void EmitULEB128(uint64_t value, llvm::StringRef desc = "",
                   unsigned padTo = 0) const;

  /// @brief Emit a label
  void EmitLabel(llvm::MCSymbol *pLabel) const;

  /// @brief Emit something like ".long pHi-pLo" where the size in bytes
  ///        of the directive is specified by size and pHi/pLo specify the
  ///        labels.  This implicitly uses .set if it is available.
  void EmitLabelDifference(const llvm::MCSymbol *pHi, const llvm::MCSymbol *pLo,
                           unsigned size) const;

  /// @brief Emit something like ".long pHi+offset-pLo" where the size in bytes
  ///        of the directive is specified by size and pHi/pLo specify the
  ///        labels.  This implicitly uses .set if it is available.
  void EmitLabelOffsetDifference(const llvm::MCSymbol *pHi, uint64_t offset,
                                 const llvm::MCSymbol *pLo,
                                 unsigned size) const;

  /// @brief Emit something like ".long pLabel+offset" where the size in bytes
  ///        of the directive is specified by size and pLabel specifies the
  ///        label.  This implicitly uses .set if it is available.
  void EmitLabelPlusOffset(const llvm::MCSymbol *pLabel, uint64_t offset,
                           unsigned size, bool isSectionRelative = false) const;

  /// @brief Emit something like ".long pLabel" where the size in bytes of the
  ///        directive is specified by size and pLabel specifies the label.
  void EmitLabelReference(const llvm::MCSymbol *pLabel, unsigned size,
                          bool isSectionRelative = false) const;

  void EmitELFDiffSize(llvm::MCSymbol *pLabel, const llvm::MCSymbol *pHi,
                       const llvm::MCSymbol *pLo) const;

  /// @brief Special case of EmitValue that avoids the client
  ///        having to pass in a MCExpr for MCSymbols.
  void EmitSymbolValue(const llvm::MCSymbol *pSym, unsigned size,
                       unsigned addrSpace = 0) const;

  /// @brief Emit the 4-byte offset of pLabel from the start of its section.
  ///        This can be done with a special directive if the target supports
  ///        it (e.g. cygwin) or by emitting it as an offset from a label at
  ///        the start of the section.
  ///
  ///        SectionLabel is a temporary label emitted at the start of the
  ///        section that pLabel lives in.
  void EmitSectionOffset(const llvm::MCSymbol *pLabel,
                         const llvm::MCSymbol *pSectionLabel) const;

  /// @brief Emit dwarf register operation.
  void EmitDwarfRegOp(unsigned reg, unsigned offset = 0,
                      bool indirect = 0) const;

  /// @brief Associate a filename with a specified logical file number.
  ///        This implements the DWARF2 '.file 4 "foo.c"' assembler directive.
  bool EmitDwarfFileDirective(unsigned fileNo, llvm::StringRef directory,
                              llvm::StringRef filename,
                              unsigned cuID = 0) const;

  /// @brief This implements the DWARF2 '.loc fileno lineno ...' assembler
  /// directive.
  void EmitDwarfLocDirective(unsigned fileNo, unsigned line, unsigned column,
                             unsigned flags, unsigned isa,
                             unsigned discriminator,
                             llvm::StringRef fileName) const;

  /// @brief Maps given line table symbol to given ID
  void SetMCLineTableSymbol(llvm::MCSymbol *pSym, unsigned id) const;

  /// @brief Finalize the streamer, flush all written bytes.
  void Finalize() const;

  const std::string &getErrors() const { return ErrorLog; }

  void reportUsabilityIssue(llvm::StringRef Msg,
                            const llvm::Value *Ctx = nullptr);
  void verifyRegisterLocationSize(const DbgVariable &VarVal,
                                  const DwarfDebug &DD,
                                  unsigned MaxGRFSpaceInBits,
                                  uint64_t ExpectedSize);
  void verifyRegisterLocationExpr(const DbgVariable &VarVal,
                                  const DwarfDebug &DD);

private:
  class DiagnosticBuff {
    std::string Buff;
    llvm::raw_string_ostream OS;

  public:
    DiagnosticBuff() : OS(Buff) {}
    llvm::raw_string_ostream &out() { return OS; }
  };

  void verificationReport(const DbgVariable &VarVal, DiagnosticBuff &DiagBuff);
  void verificationReport(DiagnosticBuff &DiagBuff);

  /// @brief Return information about object file lowering.
  const llvm::MCObjectFileInfo &GetObjFileLowering() const;

  /// @brief Return the target triple string.
  const std::string &GetTargetTriple() const { return m_targetTriple; }

private:
  llvm::MCStreamer *m_pMCStreamer;
  llvm::MCContext *m_pContext;
  llvm::SourceMgr *m_pSrcMgr;
  llvm::MCAsmInfo *m_pAsmInfo;
  IGCLLVM::MCObjectFileInfo *m_pObjFileInfo;
  const llvm::DataLayout *m_pDataLayout;
  const std::string &m_targetTriple;
  Settings StreamOptions;
  std::string ErrorLog;

  mutable unsigned int m_setCounter;
};

} // namespace IGC