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 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311
|
<!---======================= begin_copyright_notice ============================
Copyright (C) 2020-2021 Intel Corporation
SPDX-License-Identifier: MIT
============================= end_copyright_notice ==========================-->
# Appendix: Debug Information
Debug information in vISA is emitted as structures mapping virtual
bytecode input to machine code output. There are several mapping tables
emitted and each is described below.
Debug Information Header
========================
Debug information header format is as follows:
```
DebugFormatHeader
{
ud magic_number;
uw numCompiledObjects;
DebugInfoFormat debugInfo[numCompiledObjectsObjects];
}
```
- **magic_number**: A magic number used to identify debug information
format used. This number is equal to 0xdeadd010 currently. Changes
to debug information format will change this.
- **numCompiledObjects**: Number of objects, ie kernels and stack call
functions, having debug information in debug information stream.
- **debugInfo:** Actual debug information for each compiled object.
Compiled object refers to either a kernel or a stack call function.
Debug information format per object is as follows:
```
DebugInfoFormat
{
ub objectNameLen;
ub objectName[objectNameLen];
ud reloc_offset;
MappingTable offsetMap;
MappingTable indexMap;
VarInfoMap vars;
uw numSubs
SubroutineInfo subInfo[numSubs];
CallFrameInfo frameInfo;
}
```
- **nameLen:** Length of name of object. Must be from 0 to 255.
- **objectName:** Name of the object. Not null terminated.
- **relocOffset:** Represents offset of first instruction in binary
buffer. Value is 0 for kernels, non-zero for stack call functions.
- **offsetMap:** Mapping for vISA instruction offset to Gen
instruction offset. Base of vISA offset is first instruction of
compilated object. Offsets expressed in bytes. This table is
optional and may be absent when vISA file is not generated. When
absent, offsetMap.numElements field is set to 0.
- **indexMap:** Mapping for vISA instruction index from vISA input to
Gen instruction offset. vISA instruction index starts at 0 for first
vISA instruction and increases in unit step.
- **vars:** Table mapping virtual variables with physical assigned
storage location.
- **numSubs:** Number of sub-routines that are part of this
compilation object.
- **subInfo:** Debugging information for each included sub-routine.
- **frameInfo:** Debug information about call frame in presence of
stack call callees.
```
MappingTable
{
ud numElements;
VISAMap data[numElements];
}
```
- **numElements:** Number of entries in mapping table.
- **<data:**> Actual mapping from vISA instruction offset to Gen
instruction.
```
VISAMap
{
ud visaOffset/visaIndex;
ud genOffset;
}
```
- **visaOffset/visaIndex:** Byte offset/vISA index in vISA input.
- **genOffset:** Byte offset of corresponding Gen instruction in
compiled code. If a vISA instruction leads to several Gen
instruction, this points to first one. All Gen instructions between
current genOffset and next mapping entry's genOffset are a result of
lowering current vISA instruction. In case of scheduled code, Gen
instructions resulting from a single vISA instruction could be
scattered in generated code. In such cases, union of all such
entries need to be considered to map to a single vISA instruction.
Generated mapping is best effort and there could be some vISA
instructions absent due to optimizations.
```
VarInfoMap
{
ud numElements;
VarInfo var[numElements];
}
```
- **numElements:** Number of elements in variable mapping table.
- **var:** Actual mapping entry. Valid only when optimizations are
disabled.
```
VarInfo
{
ub nameLen;
ub varName[nameLen];
VarLiveIntervalsVISA lr;
}
```
- **nameLen:** Number of characters in name field.
- **varName:** Non null terminated string of characters.
- **lr:** Live-internal information in expressed in vISA index.
```
VarLiveIntervalsVISA/VarIntervalsGenISA
{
uw numIntervals;
IntervalVISA/GenISA intervals[numIntervals];
}
```
- **numIntervals:** Number of intervals having valid mapping.
- **intervals:** Actual live-intervals.
```
IntervalVISA/GenISA
{
uw start/ud start;
uw end/ud end;
ub virtualType;
ub physicalType;
union
{
Register
{
uw regnum;
uw subRegNum;
}
Memory
{
ud isBaseOffBEFP : 1;
d memoryOffset : 31;
}
}
}
```
- **start:** Variable is uw type for IntervalVISA and represents vISA
index where current variable becomes live, ie has a valid value.
Variable is ud type for IntervalGenISA type and represents Gen ISA
start offset in bytes. Entire variable becomes live even if only a
subset of elements are defined.
- **end:** Variable is uw type for IntervalVISA and represents vISA
index where current variable's value is no longer available.
Variable is ud type for IntervalGenISA type and represents Gen ISA
end offset in bytes. A variable is no longer live once all elements
are no longer used.
- **virtualType:** Can take one of following values:
| Value | Interpretation |
| --- | --- |
| 0 | Address vISA variable |
| 1 | Flag vISA variable |
| 2 | General vISA variable |
- **physicalType:** Can take one of following values:
| Value | Interpretation |
| --- | --- |
| 0 | Address vISA variable |
| 1 | Flag vISA variable |
| 2 | General vISA variable |
| 3 | Memory |
- **regNum:** Valid if physicalType is 0, 1, 2. Indicates physical
register number holding vISA variable.
- **subRegNum:** Valid if physicalType is 0, 1, 2. Indicates physical
sub-register number holding vISA variable. Expressed in byte units.
- **isBaseOffBEFP:** Valid if physicalType is 3. Size is 1 bit.
Bit-field set to 0 if vISA variable offset is represented based off
BE_FP (ie, back-end frame pointer). If 1, it represents absolute
offset in scratch space.
- **memoryOffset:** Bit-field with size 31 bits. Valid if physicalType
is 3. Field holding signed memory offset in byte units.
```
SubroutineInfo
{
ub nameLen;
ub name[nameLen];
ud start;
ud end;
VarLiveIntervalsGenISA retVal;
}
```
- **nameLen:** Number of characters in name field.
- **name:** Name of sub-routine. Not null terminated.
- **start:** Index of first vISA instruction in sub-routine.
- **end:** Index of last vISA instruction in sub-routine.
- **retval:** Live-interval information of variable holding return
address. This can be used to determine call site from where
control was transferred.
```
CallFrameInfo
{
uw frameSizeInBytes;
ub befpValid;
VarLiveIntervalsGenISA befp;
ub callerbefpValid;
VarLiveIntervalsGenISA callerbefp;
ub retAddrValid;
VarLiveIntervalsGenISA retAddr;
uw numCalleeSaveEntries;
PhyRegSaveInfoPerIP calleeSaveEntry[numCalleeSaveEntries];
uw numCallerSaveEntries;
PhyRegSaveInfoPerIP callerSaveEntry[numCallerSaveEntries];
}
```
- **frameSizeInBytes:** Number of bytes used by current frame.
- **befpValid:** Set to 1 if BE_FP pointer is valid. When back-end
stack is not used such as for standalone kernel, this will be 0.
- **befp:** Live-interval of BE_FP. Present only when befpValid is
set to 1. Field absent and should not be read when befpValid is 0.
- **callerbefpValid:** Indicates whether BE_FP of caller frame is
valid. Can be used to virtually unwind stack.
- **callerbefp:** Live-interval of caller's BE_FP. Valid only when
callerbefpValid is 1.
- **retAddrValid:** Set to 1 when current object is a stack call
function. It indicates that current object may return to caller
frame.
- **retAddr:** Live-interval of variable holding return address of
current frame. Valid only if retAddrValid is 1.
- **numCalleeSaveEntries:** Number of entries in callee save area
table. Useful during virtual stack unwinding.
- **calleeSaveEntry:** Caller frame's variables allocated to callee
save area will be written out to memory on current frame so current
compiled object can reuse such registers. To retrieve value of such
variables from caller frame allocated to callee save area, a
debugger would need to read memory location on current frame where
callee save physical registers are stored. This member provides
relevant mapping between callee save physical register and its
location on current frame. Callee save registers are stored in
memory before first vISA instruction in a frame and restored just
before fret vISA instruction.
- **numCallerSaveEntries:** Number of entries in caller save area
table. Useful during virtual stack unwinding.
- **callerSaveEntry:** Any caller save registers live across a stack
call site will be stored in memory of current frame before the
function call and will be restored after returning from the call.
Caller save registers will be reused by callee stack call function.
In callee stack call function, if debugger wants to virtually unwind
stack and query a caller frame variable that was allocated to a
caller save register, debugger needs to lookup this table to get the
location where the variable's value is available.
```
PhyRegSaveInfoPerIP
{
ud genIPOffset;
uw numEntries;
RegInfoMapping data[numEntries];
}
```
- **genIPOffset:** Caller/callee save entry at this Gen IP.
- **numEntries:** Number of mapping entries for caller/callee save
area.
- **<data:**> Holds mapping information for caller/callee save
registers and their storage location in memory. This is useful for
virtual stack unwinding.
```
RegInfoMapping
{
uw srcRegOff;
uw numBytes;
ub dstInReg;
Mapping dst;
}
```
- **srcRegOff:** Physical register for which this caller/callee save
entry is emitted. Physical register is expressed in byte units and
zero based off GRF file. So r0.0 is expressed as 0 and r1.0 is
expressed as 32.
- **numBytes:** Total number of bytes beginning srcRegOff for this
caller/callee save entry.
- **dstInReg:** Indicates whether physical register in srcRegOff is
stored in a register or memory.
- **dst:** Actual location where registers indicated by srcRegOff and
numBytes are stored.
|