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

            Bug ID: 61912
           Summary: Missed (partial) dead store elimination for structures
                    on GIMPLE
           Product: gcc
           Version: 4.10.0
            Status: UNCONFIRMED
          Severity: enhancement
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: amker at gcc dot gnu.org

For simple case like below,

typedef unsigned int wchar_t;
struct printf_info
{
  int prec;
  int width;
  wchar_t spec;
  unsigned int is_long_double:1;
  unsigned int is_short:1;
  unsigned int is_long:1;
  unsigned int alt:1;
  unsigned int space:1;
  unsigned int left:1;
  unsigned int showsign:1;
  unsigned int group:1;
  unsigned int extra:1;
  unsigned int is_char:1;
  unsigned int wide:1;
  unsigned int i18n:1;
  unsigned int __pad:4;
  unsigned short int user;
  wchar_t pad;
} info;

void bar (struct printf_info *);

void foo(int prec,
  int width,
  wchar_t spec,
  unsigned int is_long_double,
  unsigned int is_short,
  unsigned int is_long,
  unsigned int alt,
  unsigned int space,
  unsigned int left,
  unsigned int showsign,
  unsigned int group,
  wchar_t pad)
{
    struct printf_info info = {
        .prec = prec,
        .width = width,
        .spec = spec,
        .is_long_double = is_long_double,
        .is_short = is_short,
        .is_long = is_long,
        .alt = alt,
        .space = space,
        .left = left,
        .showsign = showsign,
        .group = group,
        .pad = pad,
        .extra = 0,
        .wide = sizeof (char) != 1 };

    bar (&info);
}

The dump before both gimple level DSE pass is like below,

  <bb 2>:
  info = {};
  info.prec = prec_3(D);
  info.width = width_5(D);
  info.spec = spec_7(D);
  _10 = (unsigned char) is_long_double_9(D);
  _11 = (<unnamed-unsigned:1>) _10;
  info.is_long_double = _11;
  _14 = (unsigned char) is_short_13(D);
  _15 = (<unnamed-unsigned:1>) _14;
  info.is_short = _15;
  _18 = (unsigned char) is_long_17(D);
  _19 = (<unnamed-unsigned:1>) _18;
  info.is_long = _19;
  _22 = (unsigned char) alt_21(D);
  _23 = (<unnamed-unsigned:1>) _22;
  info.alt = _23;
  _26 = (unsigned char) space_25(D);
  _27 = (<unnamed-unsigned:1>) _26;
  info.space = _27;
  _30 = (unsigned char) left_29(D);
  _31 = (<unnamed-unsigned:1>) _30;
  info.left = _31;
  _34 = (unsigned char) showsign_33(D);
  _35 = (<unnamed-unsigned:1>) _34;
  info.showsign = _35;
  _38 = (unsigned char) group_37(D);
  _39 = (<unnamed-unsigned:1>) _38;
  info.group = _39;
  info.pad = pad_41(D);
  bar (&info);
  info ={v} {CLOBBER};
  return;

Most cleanups of structure `info' are dead because fields are going to be set
again.  For now GCC just generates call to memset for the structure cleanup and
let rtl decide whether the memset call should be inlined.  If it is inlined,
RTL dse can eliminate some of the dead store.  The problem with RTL DSE is it
lacks high level information and don't see the nature of structure, especially
if the memset is inlined with vectorized instruction.

So, I wonder if it's possible to have GIMPLE DSE to eliminate the redundant
store operation.  Apparently, we may need heuristic information to decide if
the cleanup of structure should be scalarized and eliminated.  I think it
depends on how many fields are left, also how difficult to set them to ZERO
(considering the bit-fields).

Thanks.

Reply via email to