aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorCanqun Yang <canqun@nudt.edu.cn>2005-08-14 10:06:06 +0800
committerCanqun Yang <canqun@gcc.gnu.org>2005-08-14 10:06:06 +0800
commit442c1644c7faf56f554771b307e5ed664a8ace64 (patch)
treea144773c1a7d9d4662fa3c15aa3094a5e8083cd1 /gcc
parentee1658f34360cd994f12c0bc525b714b2efe7bb8 (diff)
downloadgcc-442c1644c7faf56f554771b307e5ed664a8ace64.zip
gcc-442c1644c7faf56f554771b307e5ed664a8ace64.tar.gz
gcc-442c1644c7faf56f554771b307e5ed664a8ace64.tar.bz2
trans-stmt.c (gfc_trans_arithmetic_if): Optimized in case of equal labels.
* trans-stmt.c (gfc_trans_arithmetic_if): Optimized in case of equal labels. From-SVN: r103074
Diffstat (limited to 'gcc')
-rw-r--r--gcc/fortran/ChangeLog5
-rw-r--r--gcc/fortran/trans-stmt.c41
2 files changed, 36 insertions, 10 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index d8b4619..158123a 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,8 @@
+2005-08-14 Canqun Yang <canqun@nudt.edu.cn>
+
+ * trans-stmt.c (gfc_trans_arithmetic_if): Optimized in case of equal
+ labels.
+
2005-09-11 Francois-Xavier Coudert <coudert@clipper.ens.fr>
Steven Bosscher <stevenb@suse.de>
diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c
index 72407ae..040214e 100644
--- a/gcc/fortran/trans-stmt.c
+++ b/gcc/fortran/trans-stmt.c
@@ -461,6 +461,14 @@ gfc_trans_if (gfc_code * code)
}
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
@@ -482,18 +490,31 @@ gfc_trans_arithmetic_if (gfc_code * code)
/* 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));
+ 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));
- tmp = build2 (LT_EXPR, boolean_type_node, se.expr, zero);
- branch1 = build3_v (COND_EXPR, tmp, branch1, branch2);
+ 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);
- /* 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);
+ 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);