public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Zack Weinberg <zack@codesourcery.com>
To: Joern Rennecke <joern.rennecke@superh.com>
Cc: bonzini@gnu.org (Paolo Bonzini),  gcc-patches@gcc.gnu.org
Subject: tree-ssa optimizer limitations (was Re: RFC: define_predicate)
Date: Mon, 02 Aug 2004 19:28:00 -0000	[thread overview]
Message-ID: <874qnlny9b.fsf@codesourcery.com> (raw)
In-Reply-To: <200408021851.i72Ip7503822@chloe.uk.w2k.superh.com> (Joern Rennecke's message of "Mon, 2 Aug 2004 19:51:07 +0100 (BST)")

Joern Rennecke <joern.rennecke@superh.com> writes:

>> if genpreds.c would put an additional switch statement before the user 
>> code.  Well, maybe in this case it is not that much more readable (maybe 
>> the opposite is true), but in many predicates the third argument to 
>> define_predicate would be superfluous, as in
>> 
>> +;; Return 1 if OP refers to a symbol.
>> +(define_predicate "symbolic_operand" "symbol_ref,const,label_ref"
>> +{
>> +  switch (GET_CODE (op))
>> +    {
>> +    case CONST:
>> +    case SYMBOL_REF:
>> +    case LABEL_REF:
>> +      return 1;
>> +
>> +    default:
>> +      break;
>> +    }
>> +  return 0;
>> +})
>> 
>> and that argument could be made optional (defaulting to "return 1;"). 
>> Does this make sense?
>
> It's very hard to optimize that switch statement away if it is not needed.
> I propose it is only inserted if you omit the third argument.

I would prefer to rely on the new optimizers to get this right (it
seems like the sort of thing that ought to be easy with SSA) but
disappointingly, they don't.  I've been revising this patch; the
current version takes input like this

;; True if OP refers to a symbol in the sdata section.
(define_predicate "sdata_symbolic_operand" 
  (match_code "symbol_ref,const")
{
  switch (GET_CODE (op))
    {
    case CONST:
      op = XEXP (op, 0);
      if (GET_CODE (op) != PLUS
	  || GET_CODE (XEXP (op, 0)) != SYMBOL_REF)
	return false;
      op = XEXP (op, 0);
      /* FALLTHRU */

    case SYMBOL_REF:
      if (CONSTANT_POOL_ADDRESS_P (op))
	return GET_MODE_SIZE (get_pool_mode (op)) <= ia64_section_threshold;
      else
	return SYMBOL_REF_LOCAL_P (op) && SYMBOL_REF_SMALL_P (op);

    default:
      abort ();
    }
})

and produces code like this

static inline bool
sdata_symbolic_operand_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
  switch (GET_CODE (op))
    {
    case CONST:
      op = XEXP (op, 0);
      if (GET_CODE (op) != PLUS
	  || GET_CODE (XEXP (op, 0)) != SYMBOL_REF)
	return false;
      op = XEXP (op, 0);
      /* FALLTHRU */

    case SYMBOL_REF:
      if (CONSTANT_POOL_ADDRESS_P (op))
	return GET_MODE_SIZE (get_pool_mode (op)) <= ia64_section_threshold;
      else
	return SYMBOL_REF_LOCAL_P (op) && SYMBOL_REF_SMALL_P (op);

    default:
      abort ();
    }
}

bool
sdata_symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
  return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST) 
          && (sdata_symbolic_operand_1 (op, mode));
}

and ... known-value propagation into control flow statements doesn't
seem to be happening *at all*.  Most disappointing.  I mean, forget
the above, we've got crap like this in the -fdump-tree-optimized
output:

<L15>:;
  if ((unsigned char)T?363 == 0) goto <L17>; else goto <L33>;

<L33>:;
  T?388 = 1;
  goto <bb 15> (<L18>);

<L17>:;
  T?388 = 0;

<L18>:;
  return T?388;

where T?363 is guaranteed to be 0 or 1 when control reaches <L15>...

tree-ssa folks, what's the missing piece here?  Complete
-fdump-tree-optimized result of above is appended.  N.B. disabling
checking has no substantial effect.

zw

sdata_symbolic_operand (op, mode)
{
  struct rtx_def * const _rtx;
  static const char __FUNCTION__[25] = "sdata_symbolic_operand_1";
  _Bool T?387;
  _Bool T?386;
  int T?385;
  int T?384;
  unsigned char T?382?383;
  signed char T?382;
  unsigned int T?381;
  _Bool T?380;
  _Bool T?379;
  int T?378;
  int T?377;
  unsigned char T?375?376;
  signed char T?375;
  unsigned int T?374;
  unsigned int T?372?373;
  int T?372;
  int iftmp?371;
  unsigned int ia64_section_threshold?370;
  unsigned int T?369;
  unsigned char T?368;
  machine_mode T?367;
  int T?366;
  <unnamed type> T?365;
  <unnamed type> T?364;
  struct rtx_def * const T?358;
  int T?363;
  <unnamed type> T?362;
  struct rtx_def * T?361;
  unsigned int T?360;
  <unnamed type> T?359;
  struct rtx_def * op;
  machine_mode mode;
  unsigned char T?395;
  _Bool T?394;
  _Bool T?393;
  _Bool T?392;
  _Bool T?391;
  <unnamed type> T?390;
  int iftmp?389;
  int T?388;
  int <D10813>;

<bb 0>:
  T?390 = op->code;
  if ((T?390 == 82 || T?390 == 72) == 0) goto <L28>; else goto <L0>;

<L28>:;
  T?388 = 0;
  goto <bb 15> (<L18>);

<L0>:;
  switch (T?390)
    {
      case 72: goto <L1>;
      case 82: goto <L5>;
      default : goto <L14>;
    }

<L1>:;
  op = op->u.fld[0].rt_rtx;
  if (op->code != 87) goto <L29>; else goto <L2>;

<L2>:;
  op = op->u.fld[0].rt_rtx;
  if (op->code != 82) goto <L30>; else goto <L5>;

<L30>:;
  T?363 = 0;
  goto <bb 13> (<L15>);

<L5>:;
  if (op->code != 82) goto <L6>; else goto <L7>;

<L6>:;
  rtl_check_failed_flag ("CONSTANT_POOL_ADDRESS_P", op, "insn-preds.c", 330, &__FUNCTION__);

<L7>:;
  if (op->unchanging != 0) goto <L8>; else goto <L9>;

<L8>:;
  T?367 = get_pool_mode (op);
  T?363 = (unsigned int)mode_size[T?367] <= ia64_section_threshold;
  goto <bb 13> (<L15>);

<L9>:;
  T?372?373 = (unsigned int)op->u.fld[1].rt_int;
  if (((int)(unsigned char)(signed char)(T?372?373 >> 1) & 1) == 0) goto <L31>; else goto <L10>;

<L31>:;
  T?363 = 0;
  goto <bb 11> (<L13>);

<L10>:;
  if (((int)(unsigned char)(signed char)(T?372?373 >> 2) & 1) == 0) goto <L12>; else goto <L32>;

<L32>:;
  T?363 = 1;
  goto <bb 11> (<L13>);

<L12>:;
  T?363 = 0;

<L13>:;
  goto <bb 13> (<L15>);

<L14>:;
  fancy_abort ("insn-preds.c", 336, &__FUNCTION__);

<L29>:;
  T?363 = 0;

<L15>:;
  if ((unsigned char)T?363 == 0) goto <L17>; else goto <L33>;

<L33>:;
  T?388 = 1;
  goto <bb 15> (<L18>);

<L17>:;
  T?388 = 0;

<L18>:;
  return T?388;

}

      parent reply	other threads:[~2004-08-02 19:19 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-07-25  2:48 RFC: define_predicate Zack Weinberg
2004-07-30  9:45 ` Mark Mitchell
2004-08-02 14:33 ` Paolo Bonzini
2004-08-02 18:50   ` Joern Rennecke
2004-08-02 19:00     ` Andrew Pinski
2004-08-02 19:19       ` Joern Rennecke
2004-08-02 19:38         ` Zack Weinberg
2004-08-03 11:49           ` Joern Rennecke
2004-08-03 12:40             ` Paolo Bonzini
2004-08-03 17:27               ` Zack Weinberg
2004-08-02 19:28     ` Zack Weinberg [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=874qnlny9b.fsf@codesourcery.com \
    --to=zack@codesourcery.com \
    --cc=bonzini@gnu.org \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=joern.rennecke@superh.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).