On 8/11/2013, at 1:48 am, Paulo Matos <pma...@broadcom.com> wrote: > Hello, > > I am slightly unsure if the confusion is in the dependencies or it's my > confusion. > > I have tracked this strange behaviour which only occurs when we need to flush > pending instructions due to the pending list becoming too large (gcc 4.8, > haven't tried with trunk). > > I have two stores: > 85: st zr, [r12] # zr is the zero register > 90: st zr, [r18] > > While analysing dependencies for `st zr, [r12]`, we notice that pending list > is too large in sched_analyze_1 and call flush_pending_lists (deps, insn, > false, true). > > This in turn causes the last_pending_memory_flush to be set to: > (insn_list:REG_DEP_TRUE 85 (nil)) > > When insn 90 is analyzed next, it skips the flushing bit since the pending > lists had just been flushed and enters the else bit where it does: > add_dependence_list (insn, deps->last_pending_memory_flush, 1, > REG_DEP_ANTI, true); > > This adds the dependency: 90 has an anti-dependency to 85. > I think this should be a true dependency (write after write). It even says so > in the list of last_pending_memory_flush, however add_dependence_list > function ignored this and uses the dep_type passed: REG_DEP_ANTI. > > Is anti the correct dependence? Why?
Output dependency is the right type (write after write). Anti dependency is write after read, and true dependency is read after write. Dependency type plays a role for estimating costs and latencies between instructions (which affects performance), but using wrong or imprecise dependency type does not affect correctness. Dependency flush is a force-major occurrence during compilation, and developers tend not to spend too much time on coding best possible handling for these [hopefully] rare occurrences. Anti dependency is a good guess for dependency type between two memory instructions. In the above particular case it is wrong, and, I imagine, this causes a performance problem for you. You can add better handling of this situation by remembering whether last_pending_memory_flush is memory read or memory write and then use it to select correct dependency type for insn 90: output, anti or true. Let me know whether you want to pursue this and I can help with advice and patch review. Thanks, -- Maxim Kuvyrkov www.kugelworks.com