summaryrefslogtreecommitdiff
path: root/gcc/fortran/trans-stmt.c
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/fortran/trans-stmt.c
parentee1658f34360cd994f12c0bc525b714b2efe7bb8 (diff)
downloadgcc-442c1644c7faf56f554771b307e5ed664a8ace64.tar.gz
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/fortran/trans-stmt.c')
-rw-r--r--gcc/fortran/trans-stmt.c41
1 files changed, 31 insertions, 10 deletions
diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c
index 72407ae4425..040214ed27f 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);