]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
Convert for loops into simple loops
authorJürg Billeter <j@bitron.ch>
Sat, 6 Jun 2009 15:04:02 +0000 (17:04 +0200)
committerJürg Billeter <j@bitron.ch>
Sat, 6 Jun 2009 15:20:19 +0000 (17:20 +0200)
13 files changed:
codegen/valaccodebasemodule.vala
codegen/valaccodecontrolflowmodule.vala
codegen/valaccodegenerator.vala
codegen/valaccodemodule.vala
gee/hashmap.vala
gee/hashset.vala
vala/valabinaryexpression.vala
vala/valaconditionalexpression.vala
vala/valaexpression.vala
vala/valaflowanalyzer.vala
vala/valaforstatement.vala
vala/valamethodcall.vala
vala/valanullchecker.vala

index 9b46954fa753a379c4bb0afdcacf16bba701abfc..8073265e9ecad5f36daa63154df9db4618b19b24 100644 (file)
@@ -2232,7 +2232,7 @@ internal class Vala.CCodeBaseModule : CCodeModule {
                
                if (stop_at_loop) {
                        if (b.parent_node is Loop ||
-                           b.parent_node is ForStatement || b.parent_node is ForeachStatement ||
+                           b.parent_node is ForeachStatement ||
                            b.parent_node is SwitchStatement) {
                                return;
                        }
index 2dc23b14c4af07d9cb1366a0066c6860e5d9a721..b0c84c09514e07397917e4e5c92d721370557d3c 100644 (file)
@@ -227,32 +227,6 @@ internal class Vala.CCodeControlFlowModule : CCodeMethodModule {
                stmt.ccodenode = new CCodeWhileStatement (new CCodeConstant ("TRUE"), (CCodeStatement) stmt.body.ccodenode);
        }
 
-       public override void visit_for_statement (ForStatement stmt) {
-               stmt.accept_children (codegen);
-
-               CCodeExpression ccondition = null;
-               if (stmt.condition != null) {
-                       ccondition = (CCodeExpression) stmt.condition.ccodenode;
-               }
-
-               var cfor = new CCodeForStatement (ccondition, (CCodeStatement) stmt.body.ccodenode);
-               stmt.ccodenode = cfor;
-               
-               foreach (Expression init_expr in stmt.get_initializer ()) {
-                       cfor.add_initializer ((CCodeExpression) init_expr.ccodenode);
-                       create_temp_decl (stmt, init_expr.temp_vars);
-               }
-               
-               foreach (Expression it_expr in stmt.get_iterator ()) {
-                       cfor.add_iterator ((CCodeExpression) it_expr.ccodenode);
-                       create_temp_decl (stmt, it_expr.temp_vars);
-               }
-
-               if (stmt.condition != null) {
-                       create_temp_decl (stmt, stmt.condition.temp_vars);
-               }
-       }
-
        public override void visit_foreach_statement (ForeachStatement stmt) {
                stmt.element_variable.active = true;
                stmt.collection_variable.active = true;
index 699d59cdf9df2c9dc86de9696f25f31cedaf62f0..f66e6dc6b4cc331f4e4713a622aa4450ef5c4fba 100644 (file)
@@ -193,10 +193,6 @@ public class Vala.CCodeGenerator : CodeGenerator {
                head.visit_loop (stmt);
        }
 
-       public override void visit_for_statement (ForStatement stmt) {
-               head.visit_for_statement (stmt);
-       }
-
        public override void visit_foreach_statement (ForeachStatement stmt) {
                head.visit_foreach_statement (stmt);
        }
index 9d263e053ff0c91e87d6da14bfa864a5e760c5ca..1743d2e75cb119deb90b4250893b9fbc413b1316 100644 (file)
@@ -172,10 +172,6 @@ public abstract class Vala.CCodeModule {
                next.visit_loop (stmt);
        }
 
-       public virtual void visit_for_statement (ForStatement stmt) {
-               next.visit_for_statement (stmt);
-       }
-
        public virtual void visit_foreach_statement (ForeachStatement stmt) {
                next.visit_foreach_statement (stmt);
        }
index 67b08ba913a41e69bb8f45ba21a7e2691238d57d..c152b7b746a78bf8f53f9119954f200674214d61 100644 (file)
@@ -153,7 +153,7 @@ public class Gee.HashMap<K,V> : CollectionObject, Map<K,V> {
 
                        for (int i = 0; i < _array_size; i++) {
                                Node<K,V> node;
-                               Node<K,V> next;
+                               Node<K,V> next = null;
                                for (node = (owned) _nodes[i]; node != null; node = (owned) next) {
                                        next = (owned) node.next;
                                        uint hash_val = node.key_hash % new_array_size;
index a5a98050c02b92538010e69e1bb4dffe660b5726..712fd8d9a41247662e60bbd367ca4ae09fa72a82 100644 (file)
@@ -137,7 +137,7 @@ public class Gee.HashSet<G> : CollectionObject, Iterable<G>, Collection<G>, Set<
 
                        for (int i = 0; i < _array_size; i++) {
                                Node<G> node;
-                               Node<G> next;
+                               Node<G> next = null;
                                for (node = (owned) _nodes[i]; node != null; node = (owned) next) {
                                        next = (owned) node.next;
                                        uint hash_val = node.key_hash % new_array_size;
index cbfb132e1de4fec549de9a7fa1a095e64f573a95..54f58906af6ef6dd1714ecc6a3fb3b992a30c109 100644 (file)
@@ -151,9 +151,6 @@ public class Vala.BinaryExpression : Expression {
                // for example, expressions in method contracts
                if (analyzer.current_symbol is Block
                    && (operator == BinaryOperator.AND || operator == BinaryOperator.OR)) {
-                       var old_insert_block = analyzer.insert_block;
-                       analyzer.insert_block = prepare_condition_split (analyzer);
-
                        // convert conditional expression into if statement
                        // required for flow analysis and exception handling
 
@@ -185,7 +182,6 @@ public class Vala.BinaryExpression : Expression {
                                error = true;
                                return false;
                        }
-                       analyzer.insert_block = old_insert_block;
 
                        var ma = new MemberAccess.simple (local.name, source_reference);
                        ma.target_type = target_type;
index 191d0fc0cbcae9a1183fce07e3a1b167098a825e..f521bc8f096f509e9b4201af833fd103fcc4b630 100644 (file)
@@ -1,6 +1,6 @@
 /* valaconditionalexpression.vala
  *
- * Copyright (C) 2006-2008  Jürg Billeter
+ * Copyright (C) 2006-2009  Jürg Billeter
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -111,9 +111,6 @@ public class Vala.ConditionalExpression : Expression {
                        return false;
                }
 
-               var old_insert_block = analyzer.insert_block;
-               analyzer.insert_block = prepare_condition_split (analyzer);
-
                // convert ternary expression into if statement
                // required for flow analysis and exception handling
 
@@ -143,7 +140,6 @@ public class Vala.ConditionalExpression : Expression {
                if (!if_stmt.check (analyzer)) {
                        return false;
                }
-               analyzer.insert_block = old_insert_block;
 
                true_expression = true_local.initializer;
                false_expression = false_local.initializer;
index de3824f1bf67dae6b1e21d1137202529467e53d0..ab73c4d886cd2ebed0fe7c31aa391f45f14785e6 100644 (file)
@@ -102,16 +102,6 @@ public abstract class Vala.Expression : CodeNode {
                }
        }
 
-       public Block prepare_condition_split (SemanticAnalyzer analyzer) {
-               var for_stmt = parent_statement as ForStatement;
-
-               if (for_stmt != null) {
-                       return for_stmt.prepare_condition_split (analyzer);
-               }
-
-               return analyzer.insert_block;
-       }
-
        public void insert_statement (Block block, Statement stmt) {
                block.insert_before (parent_statement, stmt);
        }
index 5d824fa49ea8d54a03fca5406dfe54c3999d3ead..cf093e2db60b3711c0f0577fb66b5ee17e6a856b 100644 (file)
@@ -691,61 +691,6 @@ public class Vala.FlowAnalyzer : CodeVisitor {
                jump_stack.remove_at (jump_stack.size - 1);
        }
 
-       public override void visit_for_statement (ForStatement stmt) {
-               if (unreachable (stmt)) {
-                       return;
-               }
-
-               // initializer
-               foreach (Expression init_expr in stmt.get_initializer ()) {
-                       current_block.add_node (init_expr);
-                       handle_errors (init_expr);
-               }
-
-               var iterator_block = new BasicBlock ();
-               jump_stack.add (new JumpTarget.continue_target (iterator_block));
-               var after_loop_block = new BasicBlock ();
-               jump_stack.add (new JumpTarget.break_target (after_loop_block));
-
-               // condition
-               var condition_block = new BasicBlock ();
-               current_block.connect (condition_block);
-               current_block = condition_block;
-               if (stmt.condition != null) {
-                       current_block.add_node (stmt.condition);
-               }
-
-               if (stmt.condition != null) {
-                       handle_errors (stmt.condition);
-               }
-
-               // loop block
-               current_block = new BasicBlock ();
-               condition_block.connect (current_block);
-               stmt.body.accept (this);
-
-               // iterator
-               // reachable?
-               if (current_block != null || iterator_block.get_predecessors ().size > 0) {
-                       if (current_block != null) {
-                               current_block.connect (iterator_block);
-                       }
-                       current_block = iterator_block;
-                       foreach (Expression it_expr in stmt.get_iterator ()) {
-                               current_block.add_node (it_expr);
-                               handle_errors (it_expr);
-                       }
-                       current_block.connect (condition_block);
-               }
-
-               // after loop
-               condition_block.connect (after_loop_block);
-               current_block = after_loop_block;
-
-               jump_stack.remove_at (jump_stack.size - 1);
-               jump_stack.remove_at (jump_stack.size - 1);
-       }
-
        public override void visit_foreach_statement (ForeachStatement stmt) {
                if (unreachable (stmt)) {
                        return;
index bdc048a52791b84690e2b28ec27f17fc9aef3199..38e79bc251597d548dd6912923b4f15a779f8902 100644 (file)
@@ -1,6 +1,6 @@
 /* valaforstatement.vala
  *
- * Copyright (C) 2006-2008  Jürg Billeter
+ * Copyright (C) 2006-2009  Jürg Billeter
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -137,87 +137,49 @@ public class Vala.ForStatement : CodeNode, Statement {
                body.accept (visitor);
        }
 
-       public override void replace_expression (Expression old_node, Expression new_node) {
-               if (condition == old_node) {
-                       condition = new_node;
-                       return;
-               }
-
-               for (int i = 0; i < initializer.size; i++) {
-                       if (initializer[i] == old_node) {
-                               initializer[i] = new_node;
-                               return;
-                       }
-               }
-               for (int i = 0; i < iterator.size; i++) {
-                       if (iterator[i] == old_node) {
-                               iterator[i] = new_node;
-                               return;
-                       }
-               }
+       bool always_true (Expression condition) {
+               var literal = condition as BooleanLiteral;
+               return (literal != null && literal.value);
        }
 
        public override bool check (SemanticAnalyzer analyzer) {
-               if (checked) {
-                       return !error;
-               }
-
-               checked = true;
-
-               foreach (Expression init_expr in initializer) {
-                       init_expr.check (analyzer);
-               }
+               // convert to simple loop
 
-               if (condition != null) {
-                       condition.check (analyzer);
-               }
+               var block = new Block (source_reference);
 
-               foreach (Expression it_expr in iterator) {
-                       it_expr.check (analyzer);
+               // initializer
+               foreach (var init_expr in initializer) {
+                       block.add_statement (new ExpressionStatement (init_expr, init_expr.source_reference));
                }
-               
-               body.check (analyzer);
 
-               if (condition != null && condition.error) {
-                       /* if there was an error in the condition, skip this check */
-                       error = true;
-                       return false;
+               // do not generate if block if condition is always true
+               if (condition != null && !always_true (condition)) {
+                       // condition
+                       var if_condition = new UnaryExpression (UnaryOperator.LOGICAL_NEGATION, condition, condition.source_reference);
+                       var true_block = new Block (condition.source_reference);
+                       true_block.add_statement (new BreakStatement (condition.source_reference));
+                       var if_stmt = new IfStatement (if_condition, true_block, null, condition.source_reference);
+                       body.insert_statement (0, if_stmt);
                }
 
-               if (condition != null && !condition.value_type.compatible (analyzer.bool_type)) {
-                       error = true;
-                       Report.error (condition.source_reference, "Condition must be boolean");
-                       return false;
-               }
+               // iterator
+               var first_local = new LocalVariable (analyzer.bool_type.copy (), get_temp_name (), new BooleanLiteral (true, source_reference), source_reference);
+               block.add_statement (new DeclarationStatement (first_local, source_reference));
 
-               if (condition != null) {
-                       add_error_types (condition.get_error_types ());
+               var iterator_block = new Block (source_reference);
+               foreach (var it_expr in iterator) {
+                       iterator_block.add_statement (new ExpressionStatement (it_expr, it_expr.source_reference));
                }
 
-               add_error_types (body.get_error_types ());
-               foreach (Expression exp in get_initializer ()) {
-                       add_error_types (exp.get_error_types ());
-               }
-               foreach (Expression exp in get_iterator ()) {
-                       add_error_types (exp.get_error_types ());
-               }
-
-               return !error;
-       }
-
-       public Block prepare_condition_split (SemanticAnalyzer analyzer) {
-               // move condition into the loop body to allow split
-               // in multiple statements
+               var first_if = new IfStatement (new UnaryExpression (UnaryOperator.LOGICAL_NEGATION, new MemberAccess.simple (first_local.name, source_reference), source_reference), iterator_block, null, source_reference);
+               body.insert_statement (0, first_if);
+               body.insert_statement (1, new ExpressionStatement (new Assignment (new MemberAccess.simple (first_local.name, source_reference), new BooleanLiteral (false, source_reference), AssignmentOperator.SIMPLE, source_reference), source_reference));
 
-               var if_condition = new UnaryExpression (UnaryOperator.LOGICAL_NEGATION, condition, condition.source_reference);
-               var true_block = new Block (condition.source_reference);
-               true_block.add_statement (new BreakStatement (condition.source_reference));
-               var if_stmt = new IfStatement (if_condition, true_block, null, condition.source_reference);
-               body.insert_statement (0, if_stmt);
+               block.add_statement (new Loop (body, source_reference));
 
-               condition = new BooleanLiteral (true, source_reference);
-               condition.check (analyzer);
+               var parent_block = (Block) parent_node;
+               parent_block.replace_statement (this, block);
 
-               return body;
+               return block.check (analyzer);
        }
 }
index 450f187fb57072c7e2fed0fc22528941b3cd3f9e..74fb2f843213f6780503c616a4e0065d82b33506 100644 (file)
@@ -436,9 +436,6 @@ public class Vala.MethodCall : Expression {
                        if (parent_node is LocalVariable || parent_node is ExpressionStatement) {
                                // simple statements, no side effects after method call
                        } else {
-                               var old_insert_block = analyzer.insert_block;
-                               analyzer.insert_block = prepare_condition_split (analyzer);
-
                                // store parent_node as we need to replace the expression in the old parent node later on
                                var old_parent_node = parent_node;
 
@@ -464,8 +461,6 @@ public class Vala.MethodCall : Expression {
                                block.remove_local_variable (local);
                                analyzer.insert_block.add_local_variable (local);
 
-                               analyzer.insert_block = old_insert_block;
-
                                old_parent_node.replace_expression (this, temp_access);
                        }
                }
index bf9c0dcb3fa944ed7e1f2d14612eb523db55bac5..8566fb72f10e4e1fb40b242eb3d5a8ba603faf3a 100644 (file)
@@ -156,12 +156,6 @@ public class Vala.NullChecker : CodeVisitor {
                stmt.accept_children (this);
        }
 
-       public override void visit_for_statement (ForStatement stmt) {
-               stmt.accept_children (this);
-
-               check_non_null (stmt.condition);
-       }
-
        public override void visit_foreach_statement (ForeachStatement stmt) {
                stmt.accept_children (this);