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


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

Patch: don't generate dead bytecode


Today I ran `make class-check' on libgcj.  One of the problems is a
bug in the front end (previously reported).  All the other problems
turned out to be dead byte code which was generated.  It turns out we
generate code for a statement like this:

    if (false) { do something }

This patch removes all that dead bytecode.  It does so by simply not
generating code along a dead branch.

This rebuilds libgcj and passes the test suite (including class-check)
fine.

Ok?

Tom

Index: ChangeLog
from  Tom Tromey  <tromey@redhat.com>
	* jcf-write.c (generate_bytecode_conditional): Return result
	reflects whether condition was generated.
	(generate_bytecode_return): Use return result.
	(generate_bytecode_insns): Likewise.

Index: jcf-write.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/jcf-write.c,v
retrieving revision 1.90
diff -u -r1.90 jcf-write.c
--- jcf-write.c 2001/10/08 20:35:03 1.90
+++ jcf-write.c 2001/10/09 03:59:15
@@ -297,7 +297,7 @@
 static int get_access_flags PARAMS ((tree));
 static void write_chunks PARAMS ((FILE *, struct chunk *));
 static int adjust_typed_op PARAMS ((tree, int));
-static void generate_bytecode_conditional PARAMS ((tree, struct jcf_block *,
+static int generate_bytecode_conditional PARAMS ((tree, struct jcf_block *,
 						  struct jcf_block *, int,
 						  struct jcf_partial *));
 static void generate_bytecode_return PARAMS ((tree, struct jcf_partial *));
@@ -1141,9 +1141,11 @@
    branch to TRUE_LABEL; otherwise, branch to FALSE_LABEL.
    TRUE_BRANCH_FIRST is a code geneation hint that the
    TRUE_LABEL may follow right after this. (The idea is that we
-   may be able to optimize away GOTO TRUE_LABEL; TRUE_LABEL:) */
+   may be able to optimize away GOTO TRUE_LABEL; TRUE_LABEL:)
+   Return 0 if we generated a conditional, -1 if the test is always
+   false, and 1 if the test is always true.  */
 
-static void
+static int
 generate_bytecode_conditional (exp, true_label, false_label,
 			       true_branch_first, state)
      tree exp;
@@ -1155,54 +1157,86 @@
   tree exp0, exp1, type;
   int save_SP = state->code_SP;
   enum java_opcode op, negop;
+  int result = 0;
+
   switch (TREE_CODE (exp))
     {
     case INTEGER_CST:
       emit_goto (integer_zerop (exp) ? false_label : true_label, state);
+      result = integer_zerop (exp) ? -1 : 1;
       break;
     case COND_EXPR:
       {
 	struct jcf_block *then_label = gen_jcf_label (state);
 	struct jcf_block *else_label = gen_jcf_label (state);
-	int save_SP_before, save_SP_after;
-	generate_bytecode_conditional (TREE_OPERAND (exp, 0),
-				       then_label, else_label, 1, state);
-	define_jcf_label (then_label, state);
+	int save_SP_before, save_SP_after, r2;
+	int r = generate_bytecode_conditional (TREE_OPERAND (exp, 0),
+					       then_label, else_label,
+					       1, state);
 	save_SP_before = state->code_SP;
-	generate_bytecode_conditional (TREE_OPERAND (exp, 1),
-				       true_label, false_label, 1, state);
+	if (r >= 0)
+	  {
+	    define_jcf_label (then_label, state);
+	    r2 = generate_bytecode_conditional (TREE_OPERAND (exp, 1),
+						true_label, false_label,
+						1, state);
+	    if (r > 0)
+	      result = r2;
+	  }
 	save_SP_after = state->code_SP;
 	state->code_SP = save_SP_before;
-	define_jcf_label (else_label, state);
-	generate_bytecode_conditional (TREE_OPERAND (exp, 2),
-				       true_label, false_label,
-				       true_branch_first, state);
+	if (r <= 0)
+	  {
+	    define_jcf_label (else_label, state);
+	    r2 = generate_bytecode_conditional (TREE_OPERAND (exp, 2),
+						true_label, false_label,
+						true_branch_first, state);
+	    if (r < 0)
+	      result = r2;
+	  }
 	if (state->code_SP != save_SP_after)
 	  abort ();
       }
       break;
     case TRUTH_NOT_EXPR:
-      generate_bytecode_conditional (TREE_OPERAND (exp, 0), false_label,
-				     true_label, ! true_branch_first, state);
+      result = generate_bytecode_conditional (TREE_OPERAND (exp, 0),
+					      false_label, true_label,
+					      ! true_branch_first, state);
       break;
     case TRUTH_ANDIF_EXPR:
       {
 	struct jcf_block *next_label = gen_jcf_label (state);
-	generate_bytecode_conditional (TREE_OPERAND (exp, 0),
-				       next_label, false_label, 1, state);
-	define_jcf_label (next_label, state);
-	generate_bytecode_conditional (TREE_OPERAND (exp, 1),
-				       true_label, false_label, 1, state);
+	int r, r2;
+	r = generate_bytecode_conditional (TREE_OPERAND (exp, 0),
+					   next_label, false_label, 1, state);
+	if (r >= 0)
+	  {
+	    define_jcf_label (next_label, state);
+	    r2 = generate_bytecode_conditional (TREE_OPERAND (exp, 1),
+						true_label, false_label,
+						1, state);
+	    if (r > 0)
+	      r = r2;
+	  }
+	result = r;
       }
       break;
     case TRUTH_ORIF_EXPR:
       {
+	int r, r2;
 	struct jcf_block *next_label = gen_jcf_label (state);
-	generate_bytecode_conditional (TREE_OPERAND (exp, 0),
-				       true_label, next_label, 1, state);
-	define_jcf_label (next_label, state);
-	generate_bytecode_conditional (TREE_OPERAND (exp, 1),
-				       true_label, false_label, 1, state);
+	r = generate_bytecode_conditional (TREE_OPERAND (exp, 0),
+					   true_label, next_label, 1, state);
+	if (r <= 0)
+	  {
+	    define_jcf_label (next_label, state);
+	    r2 = generate_bytecode_conditional (TREE_OPERAND (exp, 1),
+						true_label, false_label,
+						1, state);
+	    if (r < 0)
+	      r = r2;
+	  }
+	result = r;
       }
       break;
     compare_1:
@@ -1348,6 +1382,8 @@
     }
   if (save_SP != state->code_SP)
     abort ();
+
+  return result;
 }
 
 /* Call pending cleanups i.e. those for surrounding CLEANUP_POINT_EXPRs
@@ -1389,12 +1425,19 @@
 	  {
 	    struct jcf_block *then_label = gen_jcf_label (state);
 	    struct jcf_block *else_label = gen_jcf_label (state);
-	    generate_bytecode_conditional (TREE_OPERAND (exp, 0),
-					   then_label, else_label, 1, state);
-	    define_jcf_label (then_label, state);
-	    generate_bytecode_return (TREE_OPERAND (exp, 1), state);
-	    define_jcf_label (else_label, state);
-	    generate_bytecode_return (TREE_OPERAND (exp, 2), state);
+	    int r = generate_bytecode_conditional (TREE_OPERAND (exp, 0),
+						   then_label, else_label,
+						   1, state);
+	    if (r >= 0)
+	      {
+		define_jcf_label (then_label, state);
+		generate_bytecode_return (TREE_OPERAND (exp, 1), state);
+	      }
+	    if (r <= 0)
+	      {
+		define_jcf_label (else_label, state);
+		generate_bytecode_return (TREE_OPERAND (exp, 2), state);
+	      }
 	  }
 	  return;
 	default:
@@ -1617,13 +1660,19 @@
 	struct jcf_block *then_label = gen_jcf_label (state);
 	struct jcf_block *else_label = gen_jcf_label (state);
 	struct jcf_block *end_label = gen_jcf_label (state);
-	generate_bytecode_conditional (exp,
-				       then_label, else_label, 1, state);
-	define_jcf_label (then_label, state);
-	push_int_const (1, state);
-	emit_goto (end_label, state);
-	define_jcf_label (else_label, state);
-	push_int_const (0, state);
+	int r = generate_bytecode_conditional (exp, then_label, else_label,
+					       1, state);
+	if (r >= 0)
+	  {
+	    define_jcf_label (then_label, state);
+	    push_int_const (1, state);
+	    emit_goto (end_label, state);
+	  }
+	if (r <= 0)
+	  {
+	    define_jcf_label (else_label, state);
+	    push_int_const (0, state);
+	  }
 	define_jcf_label (end_label, state);
 	NOTE_PUSH (1);
       }
@@ -1633,16 +1682,24 @@
 	struct jcf_block *then_label = gen_jcf_label (state);
 	struct jcf_block *else_label = gen_jcf_label (state);
 	struct jcf_block *end_label = gen_jcf_label (state);
-	generate_bytecode_conditional (TREE_OPERAND (exp, 0),
-				       then_label, else_label, 1, state);
-	define_jcf_label (then_label, state);
-	generate_bytecode_insns (TREE_OPERAND (exp, 1), target, state);
-	if (CAN_COMPLETE_NORMALLY (TREE_OPERAND (exp, 1))
-	    /* Not all expressions have CAN_COMPLETE_NORMALLY set properly. */
-	    || TREE_CODE (TREE_TYPE (exp)) != VOID_TYPE)
-	  emit_goto (end_label, state);
-	define_jcf_label (else_label, state);
-	generate_bytecode_insns (TREE_OPERAND (exp, 2), target, state);
+	int r = generate_bytecode_conditional (TREE_OPERAND (exp, 0),
+					       then_label, else_label,
+					       1, state);
+	if (r >= 0)
+	  {
+	    define_jcf_label (then_label, state);
+	    generate_bytecode_insns (TREE_OPERAND (exp, 1), target, state);
+	    if (CAN_COMPLETE_NORMALLY (TREE_OPERAND (exp, 1))
+		/* Not all expressions have CAN_COMPLETE_NORMALLY set
+                   properly. */
+		|| TREE_CODE (TREE_TYPE (exp)) != VOID_TYPE)
+	      emit_goto (end_label, state);
+	  }
+	if (r <= 0)
+	  {
+	    define_jcf_label (else_label, state);
+	    generate_bytecode_insns (TREE_OPERAND (exp, 2), target, state);
+	  }
 	define_jcf_label (end_label, state);
 	/* COND_EXPR can be used in a binop. The stack must be adjusted. */
 	if (TREE_TYPE (exp) != void_type_node)


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