This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Patch: add missing if-then-else optimization


Compiling the following -O2 (ppc darwin):

int foo(int v, unsigned char *p1, unsigned char* p2) {
  int s=0;
  if ((v = p1[0]-p2[0]) < 0) v=-v;
  s+=v;
  if ((v = p1[1]-p2[1]) < 0) v=-v;
  s+=v;
  return s;
}

the first if-then is transformed into "abs", the second one is
not.  This happens because, after the first "abs" substitution
is made, the code in if_convert does not reexamine the merged
block to see if another substitution can be made.  This
patch addresses the problem.  Bootstrapped and tested on Darwin.

(Note, to get this to work I also had to change various places
that insert inline substitutions to do the insertion before
"cond_earliest", rather than before "jump".  The comments say
this is what is supposed to happen, and it seems to work.
Without this change you get breakage on this code:
   x=0;
   if (a>0) x=1;
   if (a<0) x=1;
The first if-then is transformed to x=(a>0), and if the code for
this is placed before "jump" you get
   x=0;
   test for a vs 0  [was shared]  <-cond_earliest
   x=(a>0)
   conditional branch  <-jump
The code in noce_process_if_block gets insn_b from the instruction
before cond_earliest, so it misses the second store to x and invalid
code results.)

Attachment: diffs
Description: Binary data



Index: ifcvt.c
===================================================================
RCS file: /cvs/Darwin/gcc3/gcc/ifcvt.c,v
retrieving revision 1.12
diff -u -d -b -w -c -3 -p -r1.12 ifcvt.c
cvs server: conflicting specifications of output style
*** ifcvt.c 2002/08/26 05:39:38 1.12
--- ifcvt.c 2002/09/13 17:47:15
*************** noce_try_store_flag (if_info)
*** 715,721 ****

seq = get_insns ();
end_sequence ();
! emit_insn_before_scope (seq, if_info->jump, INSN_SCOPE (if_info->insn_a));

return TRUE;
}
--- 715,722 ----

seq = get_insns ();
end_sequence ();
! emit_insn_before_scope (seq, if_info->cond_earliest,
! INSN_SCOPE (if_info->insn_a));

return TRUE;
}
*************** noce_try_store_flag_constants (if_info)
*** 850,856 ****
if (seq_contains_jump (seq))
return FALSE;

! emit_insn_before_scope (seq, if_info->jump, INSN_SCOPE (if_info->insn_a));

return TRUE;
}
--- 851,858 ----
if (seq_contains_jump (seq))
return FALSE;

! emit_insn_before_scope (seq, if_info->cond_earliest,
! INSN_SCOPE (if_info->insn_a));

return TRUE;
}
*************** noce_try_store_flag_inc (if_info)
*** 910,916 ****
if (seq_contains_jump (seq))
return FALSE;

! emit_insn_before_scope (seq, if_info->jump,
INSN_SCOPE (if_info->insn_a));

return TRUE;
--- 912,918 ----
if (seq_contains_jump (seq))
return FALSE;

! emit_insn_before_scope (seq, if_info->cond_earliest,
INSN_SCOPE (if_info->insn_a));

return TRUE;
*************** noce_try_store_flag_mask (if_info)
*** 963,969 ****
if (seq_contains_jump (seq))
return FALSE;

! emit_insn_before_scope (seq, if_info->jump,
INSN_SCOPE (if_info->insn_a));

return TRUE;
--- 965,971 ----
if (seq_contains_jump (seq))
return FALSE;

! emit_insn_before_scope (seq, if_info->cond_earliest,
INSN_SCOPE (if_info->insn_a));

return TRUE;
*************** noce_try_cmove (if_info)
*** 1059,1065 ****

seq = get_insns ();
end_sequence ();
! emit_insn_before_scope (seq, if_info->jump,
INSN_SCOPE (if_info->insn_a));
return TRUE;
}
--- 1061,1067 ----

seq = get_insns ();
end_sequence ();
! emit_insn_before_scope (seq, if_info->cond_earliest,
INSN_SCOPE (if_info->insn_a));
return TRUE;
}
*************** noce_try_cmove_arith (if_info)
*** 1222,1228 ****

tmp = get_insns ();
end_sequence ();
! emit_insn_before_scope (tmp, if_info->jump, INSN_SCOPE (if_info->insn_a));
return TRUE;

end_seq_and_fail:
--- 1224,1231 ----

tmp = get_insns ();
end_sequence ();
! emit_insn_before_scope (tmp, if_info->cond_earliest,
! INSN_SCOPE (if_info->insn_a));
return TRUE;

end_seq_and_fail:
*************** noce_try_minmax (if_info)
*** 1474,1480 ****
if (seq_contains_jump (seq))
return FALSE;

! emit_insn_before_scope (seq, if_info->jump, INSN_SCOPE (if_info->insn_a));
if_info->cond = cond;
if_info->cond_earliest = earliest;

--- 1477,1484 ----
if (seq_contains_jump (seq))
return FALSE;

! emit_insn_before_scope (seq, if_info->cond_earliest,
! INSN_SCOPE (if_info->insn_a));
if_info->cond = cond;
if_info->cond_earliest = earliest;

*************** noce_try_abs (if_info)
*** 1592,1598 ****
if (seq_contains_jump (seq))
return FALSE;

! emit_insn_before_scope (seq, if_info->jump, INSN_SCOPE (if_info->insn_a));
if_info->cond = cond;
if_info->cond_earliest = earliest;

--- 1596,1603 ----
if (seq_contains_jump (seq))
return FALSE;

! emit_insn_before_scope (seq, if_info->cond_earliest,
! INSN_SCOPE (if_info->insn_a));
if_info->cond = cond;
if_info->cond_earliest = earliest;

*************** if_convert (x_life_data_ok)
*** 3115,3122 ****

FOR_EACH_BB (bb)
{
! basic_block new_bb = find_if_header (bb, pass);
! if (new_bb)
bb = new_bb;
}

--- 3120,3127 ----

FOR_EACH_BB (bb)
{
! basic_block new_bb;
! while ((new_bb = find_if_header (bb, pass)))
bb = new_bb;
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]