https://bugs.freedesktop.org/show_bug.cgi?id=71944
--- Comment #6 from Vadim Girlin <pt...@yandex.ru> --- (In reply to comment #5) > I tried to look a little closer at the group of instructions where you > thought the problem was. But I can't really wrap my head around how the > scheduling works. Yes, sometimes it looks unnecessarily complicated to me, rewriting some parts of the scheduler and adding new features on top of existing code made it a bit messy. I planned to rewrite it completely to make it more clean and simple, but I suspect it won't happen in foreseeable future. > When is the data dependency checking done? Is it when one instruction is > added to a group or after the whole group is done or even later? I'm not sure about exact terminology and classification of dependencies, I said it's a data dependency but I guess problematic dependency in this case is actually called anti-dependency (write-after-read), and it's checked for the entire group in the post_scheduler::check_interferences ("interference" here means the case when two different values are allocated to the same register at some point - we should prevent it). The check is not performed per instruction because we want to take into account parallel execution and allow reading old value from GPR and writing new value to that GPR in the same group. This allows to process the groups like this: x: MOV R0.x, R0.y y: MOV R0.y, R0.x Per-instruction check would disallow any of these instructions that comes first because it has dependency with the other one that is not processed yet. The check uses register map (post_scheduler::regmap) where the mapping of GPR index/component to value is maintained. If at some point value V is stored in R0.x, then the map contains entry (R0.x => V) and we know that we can't put new value into R0.x until the entry for previous value in the map is removed. When we process first use of some value (scheduling is performed in the bottom-up order, so actually it's the last use in the program execution order), corresponding entry is added to regmap, when we process it's definition the entry is removed from the map so that new value can be placed into that register. As for the data dependencies (read-after-write), the way of releasing instructions for scheduling ensures they are not broken - before scheduling alu block (one or more consecutive alu clauses) we compute the number of uses of each value that is defined in that block, and instruction that defines the value is released for scheduling only after all uses are scheduled, so the write is always scheduled after all reads (before all reads in normal non-bottom-up order). In this particular case I think the check for anti-dependency doesn't work as expected because there are special cases - some values can be preallocated/pinned to registers before the scheduling, and probably some situations are handled incorrectly or not handled at all. There are special flags that are shown in the dumps (with sbdump option), e.g. "R23.x.6||FP@R1.x" means that value R23.x.6 (ssa-value R23.x with version 6, name contains original register used in source bytecode) has some special flags printed as "||", "F" and "P", and is stored in R1.x. Indirectly addressed GPR arrays are also allocated before the post-scheduler, and it seems there is some conflict between these preallocated registers that post-scheduler doesn't take into account. Hope this helps, because I'm not sure when/if I'll be able to look into it myself. But I'll be glad to help as I can, so let me know if you have any other questions. -- You are receiving this mail because: You are the assignee for the bug.
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev