https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84681

            Bug ID: 84681
           Summary: tree-ter moving code too much
           Product: gcc
           Version: 8.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: amonakov at gcc dot gnu.org
  Target Milestone: ---
            Target: x86_64

The following code (derived from a hot loop in a Huffman encoder, reported by
Fabian Giesen) suffers from TER activity too much on x86-64. TER lifts
loads+zero_extends to the BB head, sinking variable-length shifts and
increasing register pressure too badly.

Not being very familiar with TER, I think it would be good to understand why
loads are lifted all the way up to BB head like that. That's probably not
supposed to happen (and may be fixable without a TER overhaul?)

unsigned long long f(unsigned char *from,
                     unsigned char *from_end,
                     unsigned long long *codes,
                     unsigned char *lens)
{
    unsigned char sym0, sym1, sym2;
    unsigned long long bits0=0, bits1=0, bits2=0;
    unsigned char count0=0, count1=0, count2=0;
    do {
    sym0 = *from++; bits0 |= codes[sym0] << count0; count0 += lens[sym0];
    sym1 = *from++; bits1 |= codes[sym1] << count1; count1 += lens[sym1];
    sym2 = *from++; bits2 |= codes[sym2] << count2; count2 += lens[sym2];
    sym0 = *from++; bits0 |= codes[sym0] << count0; count0 += lens[sym0];
    sym1 = *from++; bits1 |= codes[sym1] << count1; count1 += lens[sym1];
    sym2 = *from++; bits2 |= codes[sym2] << count2; count2 += lens[sym2];
    sym0 = *from++; bits0 |= codes[sym0] << count0; count0 += lens[sym0];
    sym1 = *from++; bits1 |= codes[sym1] << count1; count1 += lens[sym1];
    sym2 = *from++; bits2 |= codes[sym2] << count2; count2 += lens[sym2];
    sym0 = *from++; bits0 |= codes[sym0] << count0; count0 += lens[sym0];
    sym1 = *from++; bits1 |= codes[sym1] << count1; count1 += lens[sym1];
    sym2 = *from++; bits2 |= codes[sym2] << count2; count2 += lens[sym2];
    sym0 = *from++; bits0 |= codes[sym0] << count0; count0 += lens[sym0];
    sym1 = *from++; bits1 |= codes[sym1] << count1; count1 += lens[sym1];
    sym2 = *from++; bits2 |= codes[sym2] << count2; count2 += lens[sym2];
    } while(from != from_end);
    return bits0+bits1+bits2;
}

Reply via email to