Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[spirv-ll] Fix various debug info generation issues
There were a few noted and unnoted issues with our generation of debug info from `OpLine` opcodes. * Empty line ranges could crash the translator. * `OpLine`s placed in empty basic blocks could crash the translator. * `OpLabel` opcodes placed before `OpFunction` or `OpLabel` instructions (anywhere outside of a block) wouldn't influence the line/column of those entities, as is the intention. * DISubprograms weren't attached to functions. With this commit, all of these problems are resolved. There is some refactoring here to make the code easier to work with. Firstly, we change the representation of the current line range. This improves the internal representation of the internally tracked current "open" line range (i.e., one begun with `OpLine`). We were previously using special undocumented variables to denote that the current range was closed. This is better expressed as a `std::optional`, which is set to a valid pair when the range is open and `std::nullopt` when it's closed. We also close line ranges more in adherence to the SPIR-V specification. We used to close open line ranges when starting a new basic block, or ending a function. The specification says that ranges close when they hit a *block termination instruction*: one of a certain set of opcodes that end a block or function. Note that the one such opcode we *don't* process is `OpTerminateInvocation`, but we have no support for that as it's too new (SPIR-V 1.6 and above). Secondly, we process blocks targeted by branches "on demand". Before, we used to collect branch-like instructions (`OpBranch`, `OpBranchConditional`, and `OpSwitch`) and process them once the function was complete. This was harder to intuit, harder to maintain a self-consistent builder class (the special casing was done outside of its control) and was harder to maintain coherent set of debug scopes. Now, if we process a branch instruction which forward-references a block, we create that basic block on the fly. When we come to the OpLabel for that block, we'll already have a sensible block. The only fixing up is for cosmetic reasons: we move the block to the end of the function to better maintain the layout of the SPIR-V program. This also removes the special casing for branches when closing a line range. This was necessary before because there wasn't actually a branch at the time we closed the range, so the current iterators weren't quite right and we had to pre-empty the insertion of a branch later.
- Loading branch information