User account creation filtered due to spam.

View | Details | Raw Unified | Return to bug 3507 | Differences between
and this patch

Collapse All | Expand All

(-)gcc/cse.c (+105 lines)
Lines 3909-3914 record_jump_cond (enum rtx_code code, en Link Here
3909
3909
3910
  merge_equiv_classes (op0_elt, op1_elt);
3910
  merge_equiv_classes (op0_elt, op1_elt);
3911
}
3911
}
3912
3913
struct cse_comparison_use
3914
{
3915
  rtx cc_reg;
3916
  rtx comparison_operator;
3917
};
3918
3919
/* Callback function for use by cse_find_comparison_use().  */
3920
static int
3921
cse_find_comparison_use_1 (rtx *x, void *data)
3922
{
3923
  struct cse_comparison_use *use = data;
3924
  if (GET_RTX_CLASS (GET_CODE (*x)) == RTX_COMM_COMPARE
3925
      || GET_RTX_CLASS (GET_CODE (*x)) == RTX_COMPARE)
3926
    if (rtx_equal_p (XEXP (*x, 0), use->cc_reg))
3927
      {
3928
	use->comparison_operator = *x;
3929
	return 1;
3930
      }
3931
  return 0;
3932
}
3933
3934
/* For a register X holding a comparison result set in INSN, return the
3935
   comparison operator which is the user of X.  Return NULL_RTX if no user
3936
   is found or if there are more than one user.  */
3937
static rtx
3938
cse_find_comparison_use (rtx x, rtx insn)
3939
{
3940
  struct cse_comparison_use cmp_use;
3941
  struct df_ref **defs, *use;
3942
  struct df_link *def_use;
3943
  for (defs = DF_INSN_DEFS (insn);
3944
       *defs && DF_REF_REGNO (*defs) != REGNO (x);
3945
       defs++)
3946
    ;
3947
  def_use = *defs ? DF_REF_CHAIN (*defs) : NULL;
3948
3949
  /* Bail out if there are no uses or multiple uses.  */
3950
  if (!def_use || def_use->next)
3951
    return NULL_RTX;
3952
  use = def_use->ref;
3953
  cmp_use.cc_reg = x;
3954
  if (for_each_rtx (&DF_REF_INSN (use), cse_find_comparison_use_1, &cmp_use))
3955
    return cmp_use.comparison_operator;
3956
  return NULL_RTX;
3957
}
3912
3958
3913
/* CSE processing for one instruction.
3959
/* CSE processing for one instruction.
3914
   First simplify sources and addresses of all assignments
3960
   First simplify sources and addresses of all assignments
Lines 4256-4261 cse_insn (rtx insn, rtx libcall_insn) Link Here
4256
	 simplified result, which may not necessarily be valid.  */
4302
	 simplified result, which may not necessarily be valid.  */
4257
      src_folded = fold_rtx (src, insn);
4303
      src_folded = fold_rtx (src, insn);
4258
4304
4305
      /* If src is a comparison a op b, see if c = a - b was already computed.
4306
	 We'll try to replace a op b with a op c for unsigned comparisons.
4307
	 We'll try to replace a op b with c op 0 for signed comparisons and
4308
	 equality comparisons.  */
4309
      if (src_folded == src
4310
	  && REG_P (dest)
4311
	  && GET_CODE (src) == COMPARE)
4312
	{
4313
	  enum machine_mode op_mode = GET_MODE (XEXP (src, 0));
4314
	  rtx minus = gen_rtx_MINUS (op_mode, XEXP (src, 0), XEXP (src, 1));
4315
	  unsigned minus_hash = HASH (minus, op_mode);
4316
	  struct table_elt *minus_elt = lookup (minus, minus_hash, op_mode);
4317
	  rtx cmp = NULL_RTX, res = NULL_RTX, op0 = NULL_RTX, op1 = NULL_RTX;
4318
4319
	  /* We found it.  Now we need to find out if the comparison is
4320
	     signed or unsigned.  To do so, find the use of dest.  */
4321
	  if (minus_elt)
4322
	      cmp = cse_find_comparison_use (dest, insn);
4323
	  if (cmp)
4324
	    {
4325
	      for (minus_elt = minus_elt->first_same_value;
4326
		   minus_elt; minus_elt = minus_elt->next_same_value)
4327
		if (REG_P (minus_elt->exp))
4328
		  {
4329
		    res = minus_elt->exp;
4330
		    break;
4331
		  }
4332
	    }
4333
	  if (res)
4334
	    {
4335
	      switch (GET_CODE (cmp))
4336
		{
4337
		/* Because we found a - b already computed, we can assume it
4338
		   won't overflow, but only if signed overflow is undefined.  */
4339
		case LT: case GE: case LE: case GT:
4340
		  if (flag_trapv || flag_wrapv || !flag_strict_overflow)
4341
		    break;
4342
		  /* Fall through.  */
4343
4344
		/* The remaining cases have no problems with overflow.  */
4345
		case EQ: case NE:
4346
		  op0 = res;
4347
		  op1 = CONST0_RTX (op_mode);
4348
		  break;
4349
4350
		case LTU: case GEU: case LEU: case GTU:
4351
		  op0 = XEXP (src, 0);
4352
		  op1 = res;
4353
		  break;
4354
4355
		default:
4356
		  break;
4357
		}
4358
	    }
4359
	  if (op0 && op1)
4360
	    src_folded = gen_rtx_COMPARE (mode, op0, op1);
4361
	}
4362
4259
#if 0
4363
#if 0
4260
      /* ??? This caused bad code to be generated for the m68k port with -O2.
4364
      /* ??? This caused bad code to be generated for the m68k port with -O2.
4261
	 Suppose src is (CONST_INT -1), and that after truncation src_folded
4365
	 Suppose src is (CONST_INT -1), and that after truncation src_folded
Lines 6145-6150 cse_main (rtx f ATTRIBUTE_UNUSED, int nr Link Here
6145
  int *rc_order = XNEWVEC (int, last_basic_block);
6249
  int *rc_order = XNEWVEC (int, last_basic_block);
6146
  int i, n_blocks;
6250
  int i, n_blocks;
6147
6251
6252
  df_chain_add_problem (DF_DU_CHAIN);
6148
  df_set_flags (DF_LR_RUN_DCE);
6253
  df_set_flags (DF_LR_RUN_DCE);
6149
  df_analyze ();
6254
  df_analyze ();
6150
  df_set_flags (DF_DEFER_INSN_RESCAN);
6255
  df_set_flags (DF_DEFER_INSN_RESCAN);

Return to bug 3507