[vala/staging: 2/2] analyzer: Break cyclic references of BasicBlock



commit e4119fc93c01608e975eecf0587ede3c0d9c596d
Author: David Hewitt <davidmhewitt gmail com>
Date:   Thu Apr 5 18:09:54 2018 +0100

    analyzer: Break cyclic references of BasicBlock
    
    https://bugzilla.gnome.org/show_bug.cgi?id=794979

 vala/valabasicblock.vala   |   14 +++++++-------
 vala/valaflowanalyzer.vala |   44 ++++++++++++++++++++++++++++++++++----------
 2 files changed, 41 insertions(+), 17 deletions(-)
---
diff --git a/vala/valabasicblock.vala b/vala/valabasicblock.vala
index f1c3ea8..759bb9c 100644
--- a/vala/valabasicblock.vala
+++ b/vala/valabasicblock.vala
@@ -31,12 +31,12 @@ public class Vala.BasicBlock {
 
        // control flow graph
        private List<weak BasicBlock> predecessors = new ArrayList<weak BasicBlock> ();
-       private List<BasicBlock> successors = new ArrayList<BasicBlock> ();
+       private List<weak BasicBlock> successors = new ArrayList<weak BasicBlock> ();
 
        // dominator tree
-       public BasicBlock parent { get; private set; }
-       List<BasicBlock> children = new ArrayList<BasicBlock> ();
-       Set<BasicBlock> df = new HashSet<BasicBlock> ();
+       public weak BasicBlock parent { get; private set; }
+       List<weak BasicBlock> children = new ArrayList<weak BasicBlock> ();
+       Set<weak BasicBlock> df = new HashSet<weak BasicBlock> ();
 
        Set<PhiFunction> phi_functions = new HashSet<PhiFunction> ();
 
@@ -73,7 +73,7 @@ public class Vala.BasicBlock {
                return predecessors;
        }
 
-       public List<BasicBlock> get_successors () {
+       public List<weak BasicBlock> get_successors () {
                return successors;
        }
 
@@ -82,7 +82,7 @@ public class Vala.BasicBlock {
                block.parent = this;
        }
 
-       public List<BasicBlock> get_children () {
+       public List<weak BasicBlock> get_children () {
                return children;
        }
 
@@ -90,7 +90,7 @@ public class Vala.BasicBlock {
                df.add (block);
        }
 
-       public Set<BasicBlock> get_dominator_frontier () {
+       public Set<weak BasicBlock> get_dominator_frontier () {
                return df;
        }
 
diff --git a/vala/valaflowanalyzer.vala b/vala/valaflowanalyzer.vala
index 7f36278..ff7c03e 100644
--- a/vala/valaflowanalyzer.vala
+++ b/vala/valaflowanalyzer.vala
@@ -89,6 +89,7 @@ public class Vala.FlowAnalyzer : CodeVisitor {
        private BasicBlock current_block;
        private bool unreachable_reported;
        private List<JumpTarget> jump_stack = new ArrayList<JumpTarget> ();
+       private Set<BasicBlock> all_basic_blocks;
 
        // check_variables
        Map<Symbol, List<Variable>> var_map;
@@ -105,6 +106,7 @@ public class Vala.FlowAnalyzer : CodeVisitor {
         */
        public void analyze (CodeContext context) {
                this.context = context;
+               all_basic_blocks = new HashSet<BasicBlock> ();
 
                /* we're only interested in non-pkg source files */
                var source_files = context.get_source_files ();
@@ -114,6 +116,7 @@ public class Vala.FlowAnalyzer : CodeVisitor {
                        }
                }
 
+               all_basic_blocks = null;
                this.context = null;
        }
 
@@ -194,8 +197,11 @@ public class Vala.FlowAnalyzer : CodeVisitor {
                }
 
                m.entry_block = new BasicBlock.entry ();
+               all_basic_blocks.add (m.entry_block);
                m.return_block = new BasicBlock ();
+               all_basic_blocks.add (m.return_block);
                m.exit_block = new BasicBlock.exit ();
+               all_basic_blocks.add (m.exit_block);
 
                m.return_block.connect (m.exit_block);
 
@@ -211,6 +217,8 @@ public class Vala.FlowAnalyzer : CodeVisitor {
                }
 
                current_block = new BasicBlock ();
+               all_basic_blocks.add (current_block);
+
                m.entry_block.connect (current_block);
                current_block.add_node (m);
 
@@ -256,7 +264,7 @@ public class Vala.FlowAnalyzer : CodeVisitor {
                        return;
                }
                current.postorder_visited = true;
-               foreach (BasicBlock succ in current.get_successors ()) {
+               foreach (weak BasicBlock succ in current.get_successors ()) {
                        depth_first_traverse (succ, list);
                }
                current.postorder_number = list.size;
@@ -279,7 +287,7 @@ public class Vala.FlowAnalyzer : CodeVisitor {
                                // new immediate dominator
                                BasicBlock new_idom = null;
                                bool first = true;
-                               foreach (BasicBlock pred in block.get_predecessors ()) {
+                               foreach (weak BasicBlock pred in block.get_predecessors ()) {
                                        if (idoms[pred.postorder_number] != null) {
                                                if (first) {
                                                        new_idom = pred;
@@ -322,15 +330,15 @@ public class Vala.FlowAnalyzer : CodeVisitor {
                for (int i = block_list.size - 1; i >= 0; i--) {
                        var block = block_list[i];
 
-                       foreach (BasicBlock succ in block.get_successors ()) {
+                       foreach (weak BasicBlock succ in block.get_successors ()) {
                                // if idom(succ) != block
                                if (succ.parent != block) {
                                        block.add_dominator_frontier (succ);
                                }
                        }
 
-                       foreach (BasicBlock child in block.get_children ()) {
-                               foreach (BasicBlock child_frontier in child.get_dominator_frontier ()) {
+                       foreach (weak BasicBlock child in block.get_children ()) {
+                               foreach (weak BasicBlock child_frontier in child.get_dominator_frontier ()) {
                                        // if idom(child_frontier) != block
                                        if (child_frontier.parent != block) {
                                                block.add_dominator_frontier (child_frontier);
@@ -475,9 +483,9 @@ public class Vala.FlowAnalyzer : CodeVisitor {
                        }
                }
 
-               foreach (BasicBlock succ in block.get_successors ()) {
+               foreach (weak BasicBlock succ in block.get_successors ()) {
                        int j = 0;
-                       foreach (BasicBlock pred in succ.get_predecessors ()) {
+                       foreach (weak BasicBlock pred in succ.get_predecessors ()) {
                                if (pred == block) {
                                        break;
                                }
@@ -492,7 +500,7 @@ public class Vala.FlowAnalyzer : CodeVisitor {
                        }
                }
 
-               foreach (BasicBlock child in block.get_children ()) {
+               foreach (weak BasicBlock child in block.get_children ()) {
                        check_block_variables (child);
                }
 
@@ -620,6 +628,7 @@ public class Vala.FlowAnalyzer : CodeVisitor {
                        mark_unreachable ();
                } else {
                        current_block = new BasicBlock ();
+                       all_basic_blocks.add (current_block);
                        last_block.connect (current_block);
                }
                stmt.true_statement.accept (this);
@@ -630,6 +639,7 @@ public class Vala.FlowAnalyzer : CodeVisitor {
                        mark_unreachable ();
                } else {
                        current_block = new BasicBlock ();
+                       all_basic_blocks.add (current_block);
                        last_block.connect (current_block);
                }
                if (stmt.false_statement != null) {
@@ -641,6 +651,7 @@ public class Vala.FlowAnalyzer : CodeVisitor {
                // reachable?
                if (last_true_block != null || last_false_block != null) {
                        current_block = new BasicBlock ();
+                       all_basic_blocks.add (current_block);
                        if (last_true_block != null) {
                                last_true_block.connect (current_block);
                        }
@@ -656,6 +667,7 @@ public class Vala.FlowAnalyzer : CodeVisitor {
                }
 
                var after_switch_block = new BasicBlock ();
+               all_basic_blocks.add (after_switch_block);
                jump_stack.add (new JumpTarget.break_target (after_switch_block));
 
                // condition
@@ -668,6 +680,7 @@ public class Vala.FlowAnalyzer : CodeVisitor {
 
                foreach (SwitchSection section in stmt.get_sections ()) {
                        current_block = new BasicBlock ();
+                       all_basic_blocks.add (current_block);
                        condition_block.connect (current_block);
                        foreach (Statement section_stmt in section.get_statements ()) {
                                section_stmt.accept (this);
@@ -709,8 +722,10 @@ public class Vala.FlowAnalyzer : CodeVisitor {
                }
 
                var loop_block = new BasicBlock ();
+               all_basic_blocks.add (loop_block);
                jump_stack.add (new JumpTarget.continue_target (loop_block));
                var after_loop_block = new BasicBlock ();
+               all_basic_blocks.add (after_loop_block);
                jump_stack.add (new JumpTarget.break_target (after_loop_block));
 
                // loop block
@@ -748,8 +763,10 @@ public class Vala.FlowAnalyzer : CodeVisitor {
                handle_errors (stmt.collection);
 
                var loop_block = new BasicBlock ();
+               all_basic_blocks.add (loop_block);
                jump_stack.add (new JumpTarget.continue_target (loop_block));
                var after_loop_block = new BasicBlock ();
+               all_basic_blocks.add (after_loop_block);
                jump_stack.add (new JumpTarget.break_target (after_loop_block));
 
                // loop block
@@ -893,6 +910,7 @@ public class Vala.FlowAnalyzer : CodeVisitor {
                        // normal control flow
                        if (!always_fail) {
                                current_block = new BasicBlock ();
+                               all_basic_blocks.add (current_block);
                                last_block.connect (current_block);
                        }
                }
@@ -922,14 +940,17 @@ public class Vala.FlowAnalyzer : CodeVisitor {
 
                var before_try_block = current_block;
                var after_try_block = new BasicBlock ();
+               all_basic_blocks.add (after_try_block);
 
                BasicBlock finally_block = null;
                if (stmt.finally_body != null) {
                        finally_block = new BasicBlock ();
+                       all_basic_blocks.add (finally_block);
                        current_block = finally_block;
 
                        // trap all forbidden jumps
                        var invalid_block = new BasicBlock ();
+                       all_basic_blocks.add (invalid_block);
                        jump_stack.add (new JumpTarget.any_target (invalid_block));
 
                        stmt.finally_body.accept (this);
@@ -950,11 +971,14 @@ public class Vala.FlowAnalyzer : CodeVisitor {
                var catch_clauses = stmt.get_catch_clauses ();
                for (int i = catch_clauses.size - 1; i >= 0; i--) {
                        var catch_clause = catch_clauses[i];
+                       var error_block = new BasicBlock ();
+                       all_basic_blocks.add (error_block);
+
                        if (catch_clause.error_type != null) {
                                var error_type = (ErrorType) catch_clause.error_type;
-                               jump_stack.add (new JumpTarget.error_target (new BasicBlock (), catch_clause, 
catch_clause.error_type.data_type as ErrorDomain, error_type.error_code, null));
+                               jump_stack.add (new JumpTarget.error_target (error_block, catch_clause, 
catch_clause.error_type.data_type as ErrorDomain, error_type.error_code, null));
                        } else {
-                               jump_stack.add (new JumpTarget.error_target (new BasicBlock (), catch_clause, 
null, null, null));
+                               jump_stack.add (new JumpTarget.error_target (error_block, catch_clause, null, 
null, null));
                        }
                }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]