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]

[gfortran] Patch for optimized Arithmetic IF


Hi, all,

In case of equal labels, ARITHMETIC IF can be translated to a simple version.

E.g.
   IF (a) 10, 20, 20
   
   can be translated to
   
   if (a < 0) goto label_10;
   else goto label_20; 
  
   instead of the current one generated by GCC Fortran 95 frontend.

    if (a <= 0)
      {
        if (a < 0) goto label_10;
        else goto label_20;
      }
    else
      goto label_20;

This patch can lead the previous optimized code, OK to apply?

Canqun Yang
Creative Compiler Research Group.
National University of Defense Technology, China.
? .trans-stmt.c.save.swp
? arith_if.diff
? t
? trans-stmt.c.save
Index: ChangeLog
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fortran/ChangeLog,v
retrieving revision 1.509
diff -c -3 -p -r1.509 ChangeLog
*** ChangeLog	1 Aug 2005 21:13:38 -0000	1.509
--- ChangeLog	2 Aug 2005 13:51:39 -0000
***************
*** 1,3 ****
--- 1,8 ----
+ 2005-08-02  Canqun Yang  <canqun@nudt.edu.cn>
+ 
+ 	* trans-stmt.c (gfc_trans_arithmetic_if): Optimized in case of equal
+ 	labels.
+ 
  2005-07-31  Jerry DeLisle  <jvdelisle@verizon.net>
  
  	* intrinsic.texi: Add documentation for exponent, floor, and fnum and
Index: trans-stmt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fortran/trans-stmt.c,v
retrieving revision 1.40
diff -c -3 -p -r1.40 trans-stmt.c
*** trans-stmt.c	31 Jul 2005 20:36:47 -0000	1.40
--- trans-stmt.c	2 Aug 2005 13:51:40 -0000
*************** gfc_trans_if (gfc_code * code)
*** 461,466 ****
--- 461,474 ----
        }
      else // cond > 0
        goto label3;
+ 
+    An optimized version can be generated in case of equal labels.
+    E.g., if label1 is equal to label2, we can translate it to
+ 
+     if (cond <= 0)
+       goto label1;
+     else
+       goto label3;
  */
  
  tree
*************** gfc_trans_arithmetic_if (gfc_code * code
*** 482,499 ****
    /* Build something to compare with.  */
    zero = gfc_build_const (TREE_TYPE (se.expr), integer_zero_node);
  
!   /* If (cond < 0) take branch1 else take branch2.
!      First build jumps to the COND .LT. 0 and the COND .EQ. 0 cases.  */
!   branch1 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label));
!   branch2 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label2));
! 
!   tmp = build2 (LT_EXPR, boolean_type_node, se.expr, zero);
!   branch1 = build3_v (COND_EXPR, tmp, branch1, branch2);
! 
!   /* if (cond <= 0) take branch1 else take branch2.  */
!   branch2 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label3));
!   tmp = build2 (LE_EXPR, boolean_type_node, se.expr, zero);
!   branch1 = build3_v (COND_EXPR, tmp, branch1, branch2);
  
    /* Append the COND_EXPR to the evaluation of COND, and return.  */
    gfc_add_expr_to_block (&se.pre, branch1);
--- 490,520 ----
    /* Build something to compare with.  */
    zero = gfc_build_const (TREE_TYPE (se.expr), integer_zero_node);
  
!   if (code->label->value != code->label2->value)
!     {
!       /* If (cond < 0) take branch1 else take branch2.
!          First build jumps to the COND .LT. 0 and the COND .EQ. 0 cases.  */
!       branch1 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label));
!       branch2 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label2));
! 
!       if (code->label->value != code->label3->value)
!         tmp = build2 (LT_EXPR, boolean_type_node, se.expr, zero);
!       else
!         tmp = build2 (NE_EXPR, boolean_type_node, se.expr, zero);
! 
!       branch1 = build3_v (COND_EXPR, tmp, branch1, branch2);
!     }
!   else
!     branch1 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label));
! 
!   if (code->label->value != code->label3->value
!       && code->label2->value != code->label3->value)
!     {
!       /* if (cond <= 0) take branch1 else take branch2.  */
!       branch2 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label3));
!       tmp = build2 (LE_EXPR, boolean_type_node, se.expr, zero);
!       branch1 = build3_v (COND_EXPR, tmp, branch1, branch2);
!     }
  
    /* Append the COND_EXPR to the evaluation of COND, and return.  */
    gfc_add_expr_to_block (&se.pre, branch1);

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