[PATCH] Fix find_inc in the scheduler (PR target/62025)

Jakub Jelinek jakub@redhat.com
Thu Aug 14 09:34:00 GMT 2014


On Thu, Aug 14, 2014 at 05:12:49AM +0200, Bernd Schmidt wrote:
> On 08/12/2014 09:35 PM, Jakub Jelinek wrote:
> >As detailed in the PR, find_inc ignored any possible clobbers on
> >inc_insn (typically %cc/flags/etc. register) and thus we could ignore
> >all register dependencies between mem_insn and inc_insn even when
> >we could only safely ignore the mem_reg0 register dependency.
> 
> I've been trying to remember how I intended to prevent this, and there is
> indeed a mechanism: DEP_MULTIPLE, which ought to be set for any dependency
> between two insns that is found for more than one reason. find_inc does not
> try to break such dependencies, which should make it examine only cases
> where the only reason for a dependency is between the incremented register
> and the memory address. I'm pretty sure this worked at some point.

It can't have ever worked.
DEP_MULTIPLE is set only in update_dep.
But what happens here is that while
add_or_update_dep_1 is called indeed twice, with
dep->pro:
(insn 4485 4484 2569 3 (parallel [
            (set (reg:SI 10 %r10 [ D.1921 ])
                (plus:SI (plus:SI (ltu:SI (reg:CCL1 33 %cc)
                            (const_int 0 [0]))
                        (reg:SI 10 %r10 [ D.1921 ]))
                    (mem:SI (plus:SI (reg:SI 3 %r3 [orig:622 ivtmp.179 ] [622])
                            (const_int 128 [0x80])) [4 MEM[base: _1817, offset: 128B]+0 S4 A64])))
            (clobber (reg:CC 33 %cc))
        ]) pr62025.c:139 407 {*addsi3_alc}
     (expr_list:REG_DEAD (reg:CCL1 33 %cc)
        (expr_list:REG_UNUSED (reg:CC 33 %cc)
            (nil))))
dep->con:
(insn 1027 2571 2573 3 (parallel [
            (set (reg:SI 3 %r3 [orig:622 ivtmp.179 ] [622])
                (plus:SI (reg:SI 3 %r3 [orig:622 ivtmp.179 ] [622])
                    (const_int 128 [0x80])))
            (clobber (reg:CC 33 %cc))
        ]) 327 {*addsi3}
     (expr_list:REG_UNUSED (reg:CC 33 %cc)
        (nil)))
dep->type:
REG_DEP_ANTI

(once because of the %cc clobber -> %cc use, and then because of
the %r3 set -> %r3 use), update_dep isn't called at all and thus
DEP_MULTIPLE is not set.  That is because we hit the:

  if (true_dependency_cache != NULL)
    {
      switch (ask_dependency_caches (new_dep))
        {
        case DEP_PRESENT:
          return DEP_PRESENT;

path and return DEP_PRESENT immediately.  Thus, DEP_MULTIPLE is set
only if you have multiple kinds of dependencies in between pro and con,
not just multiple reasons to have the same kind of dependency.

So, to set DEP_MULTIPLE even in the case where ask_depencency_caches
returns DEP_PRESENT, you'd need to find the old dependency anyway (isn't
that going to be expensive and totally kill all the effects of
true_dependency_cache?) and set DEP_MULTIPLE on it if not already set.

	Jakub



More information about the Gcc-patches mailing list