@@ -34,6 +34,186 @@ SPDX-License-Identifier: MIT
34
34
35
35
#include " Probe/Assertion.h"
36
36
37
+ //
38
+ // / GenXDebugInfo
39
+ // / -------------
40
+ // /
41
+ // / The goal of the pass is to provide debug information for each generated
42
+ // / genisa instruction (if such information is available). The debug
43
+ // / information is encoded in DWARF format.
44
+ // /
45
+ // / Ultimately, the pass gets data from 2 sources:
46
+ // /
47
+ // / 1. LLVM debug information encoded in LLVM IR itself. It captures the
48
+ // / important pieces of the source language's Abstract Syntax Tree and
49
+ // / maps it onto LLVM code.
50
+ // / LLVM framework should maintain it automatically, given that we follow
51
+ // / relatively simple rules while designing IR transformations:
52
+ // / https://llvm.org/docs/HowToUpdateDebugInfo.html
53
+ // /
54
+ // / 2. Debug information obtained from the finalizer. This information is
55
+ // / encoded in some proprietary format (blob) and contains the following:
56
+ // / a. mapping between vISA and genISA instructions
57
+ // / b. live intervals of the virtual registers, information about spilled
58
+ // / values, etc.
59
+ // / c. call frame information
60
+ // /
61
+ // / The pass feeds the above information to the DebugInfo library which in turn
62
+ // / produces the final DWARF.
63
+ // /
64
+ // / Operation of the pass
65
+ // / ^^^^^^^^^^^^^^^^^^^^^
66
+ // /
67
+ // / The pass assumes that some data is already being made available by other
68
+ // / passes/analysis.
69
+ // /
70
+ // / * FunctionGroupAnalysis:
71
+ // / provides information about the overall "structure"
72
+ // / of the program: functions, stack calls, indirect calls, subroutines and
73
+ // / relationships.
74
+ // /
75
+ // / * GenXModule:
76
+ // / 1. for each LLVM Function provides information about
77
+ // / LLVM instruction -> vISA instructions mapping. This information is
78
+ // / produced/maintained during operation of CISABuilder pass.
79
+ // / 2. for each LLVM Function provides access to a corresponding
80
+ // / *VISAKernel* object.
81
+ // /
82
+ // / * GenXVisaRegAlloc:
83
+ // / provides the mapping between LLVM values and virtual registers.
84
+ // /
85
+ // / * GenXCisaBuilder:
86
+ // / provides access to VISABuilder, which allows us to have access to
87
+ // / VISAKernel objects (some Functions from LLVM IR, like the ones
88
+ // / representing kernel spawns these) that contain:
89
+ // / a. debug information maintained by finalizer (see above)
90
+ // / b. the respected gen binaries
91
+ // /
92
+ // / Data Structures
93
+ // / ^^^^^^^^^^^^^^^
94
+ // /
95
+ // / Since data is aggregated from different sources, some extra data structures
96
+ // / are used to simplify bookkeeping.
97
+ // /
98
+ // / - *genx::di::VisaMapping*
99
+ // / provides the mapping from LLMV IR instruction to vISA instruction index,
100
+ // / that represents the first vISA instruction spawned by the LLVM IR
101
+ // / instruction. A single LLVM IR instruction can spawn several
102
+ // / vISA instructions - currently the number of spawned instructions is
103
+ // / derived implicitly (which is not always correct but works in most of the
104
+ // / cases).
105
+ // /
106
+ // / - *ProgramInfo*
107
+ // / A transient object that groups several llvm Functions that are eventually
108
+ // / get compiled into a single gen entity. A separate elf file with the
109
+ // / debug information is generated for each gen entity.
110
+ // /
111
+ // / The grouping is done as follows:
112
+ // / - We piggyback on FunctionGroup analysis. Each kernel function becomes the
113
+ // / head of the group. Different FunctionGroups always result in different
114
+ // / *ProgramInfo* objects. However, a single FunctionGroup can be split even
115
+ // / further. This can happen if we have an indirect call to some function. In
116
+ // / this case, this function shall is compiled into a separate gen object
117
+ // / (and a separate VISAKernel is produced aswell).
118
+ // /
119
+ // / The above approach does not work correctly in all cases. See
120
+ // / *KNOWN ISSUES* section.
121
+ // /
122
+ // / - *CompiledVisaWrapper*
123
+ // / For an arbitrary pair of llvm IR Function and VISAKernel objects,
124
+ // / does the following:
125
+ // / + Validates that IR Function and VISAKernel object are related (that is
126
+ // / the vISA spawned by IR Function is owned by the VISAKernel.
127
+ // / + Extracts Gen Binary.
128
+ // / + Extracts Debug Info Blob from finalizer and decodes it.
129
+ // /
130
+ // / *GenXFunction*
131
+ // / An object that loosely resembles MachineFunctoin from the LLVM Machine IR.
132
+ // / This is an object that for a given LLVM IR Function can access to:
133
+ // / - LLVM IR Function
134
+ // / - VisaMapping
135
+ // / - Subtarget
136
+ // / - CompiledVisaWrapper
137
+ // / - GenXVisaRegAlloc
138
+ // / GenXFunctoin serves as a primary method to communicate with the DebugInfo
139
+ // / library. The data these objects hold allow us to reason about the debug
140
+ // / information for any Gen construct (instruction, variable, etc).
141
+ // /
142
+ // / Examples
143
+ // / ^^^^^^^^
144
+ // /
145
+ // / Examples below use the following naming conventions:
146
+ // / K* - kernel function
147
+ // / L* - subroutine (non-inlined function)
148
+ // / S* - simple stack call
149
+ // / I* - indirectly-called function
150
+ // /
151
+ // / FunctionGroup construction peculiarities.
152
+ // /
153
+ // / When function groups are constructed, we do some peculiar transformations.
154
+ // /
155
+ // / Case_1 (FG):
156
+ // / Source Code: { K1 calls L1, K2 calls L1 }
157
+ // / IR after function groups: { G1 = {K1, L1}, G2 = { K2, L1'} },
158
+ // / where L1' is a clone of L1.
159
+ // / Case_2 (FG):
160
+ // / Source Code: { K1 calls S_1, both call L1 }.
161
+ // / IR after function groups: { G1 = {K1, L1, S1, L1' } }.
162
+ // / Case_3 (FG):
163
+ // / Source Code: { K1 calls I1 and I2 }.
164
+ // / IR after function grups { G1 = {K1}, G2 = {I1}, G3={I2} }.
165
+ // /
166
+ // / VISA/genISA construction peculiarities.
167
+ // /
168
+ // / Case 1:
169
+ // / Source code: K1, K1.
170
+ // / Compilation phase:
171
+ // / two function groups are created, K1 and K2 are heads.
172
+ // / two different VISAKernel produced.
173
+ // / DebugInfoGeneration:
174
+ // / Decoded Debug info for each VISAKernel contains:
175
+ // / one compiled object description.
176
+ // / two "*.elf" files are created.
177
+ // /
178
+ // / Case 2:
179
+ // / Source code: K1, S1. K1 calls S1.
180
+ // / Compilation phase:
181
+ // / 1 function group is created, K1 is the head.
182
+ // / 1 VISAKernel and 1 VISAFunction are created.
183
+ // / DebugInfoGeneratation:
184
+ // / Decoded debug info contains *2* compiled objects.
185
+ // / Each object has separate vISA indexes - visa instructions are
186
+ // / counted separately. Still, both are compiled into the same gen
187
+ // / object, so only one "*.elf" file is emitted.
188
+ // /
189
+ // / Case 3:
190
+ // / Source code: K1, I1. K1 calls I1
191
+ // / Compilation phase:
192
+ // / 1 function group is created, K1 is the head.
193
+ // / Somehow 2 VISAKernels are created.
194
+ // / DebugInfoGeneratation:
195
+ // / Decoded debug info contains *1* compiled objects (but we have 2
196
+ // / VISAKernel).
197
+ // / In the end, we emit two "*.elf" files.
198
+ // /
199
+ // / KNOWN ISSUES
200
+ // / ^^^^^^^^^^^^
201
+ // /
202
+ // / Note: see the "Examples" section for the description of the used naming
203
+ // / convention.
204
+ // /
205
+ // / Case 1: (debug info can't be emitted)
206
+ // / Source code: *K1*, *L1* *K1* calls *L1*.
207
+ // / Compilation phase:
208
+ // / 1 function group is created.
209
+ // / 1 VISAKernel produced.
210
+ // / DebugInfoGeneration:
211
+ // / 1 *ProgramInfo* created { K1, L1}.
212
+ // / Decoded Debug info contains 1 compiled object, that has 1 subroutines.
213
+ // /
214
+ // / Problem: way to map LLVM Function onto subroutine is not implemented.
215
+ // ===----------------------------------------------------------------------===//
216
+
37
217
#define DEBUG_TYPE " GENX_DEBUG_INFO"
38
218
39
219
using namespace llvm ;
0 commit comments