| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/flow_graph_builder.h" | 5 #include "vm/flow_graph_builder.h" |
| 6 | 6 |
| 7 #include "vm/ast_printer.h" | 7 #include "vm/ast_printer.h" |
| 8 #include "vm/bit_vector.h" | 8 #include "vm/bit_vector.h" |
| 9 #include "vm/code_descriptors.h" | 9 #include "vm/code_descriptors.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 } | 48 } |
| 49 | 49 |
| 50 | 50 |
| 51 void EffectGraphVisitor::Append(const EffectGraphVisitor& other_fragment) { | 51 void EffectGraphVisitor::Append(const EffectGraphVisitor& other_fragment) { |
| 52 ASSERT(is_open()); | 52 ASSERT(is_open()); |
| 53 if (other_fragment.is_empty()) return; | 53 if (other_fragment.is_empty()) return; |
| 54 if (is_empty()) { | 54 if (is_empty()) { |
| 55 entry_ = other_fragment.entry(); | 55 entry_ = other_fragment.entry(); |
| 56 exit_ = other_fragment.exit(); | 56 exit_ = other_fragment.exit(); |
| 57 } else { | 57 } else { |
| 58 exit()->set_successor(other_fragment.entry()); | 58 exit()->set_next(other_fragment.entry()); |
| 59 exit_ = other_fragment.exit(); | 59 exit_ = other_fragment.exit(); |
| 60 } | 60 } |
| 61 temp_index_ = other_fragment.temp_index(); | 61 temp_index_ = other_fragment.temp_index(); |
| 62 } | 62 } |
| 63 | 63 |
| 64 | 64 |
| 65 UseVal* EffectGraphVisitor::Bind(Computation* computation) { | 65 UseVal* EffectGraphVisitor::Bind(Computation* computation) { |
| 66 ASSERT(is_open()); | 66 ASSERT(is_open()); |
| 67 DeallocateTempIndex(computation->InputCount()); | 67 DeallocateTempIndex(computation->InputCount()); |
| 68 BindInstr* bind_instr = new BindInstr(BindInstr::kUsed, computation); | 68 BindInstr* bind_instr = new BindInstr(BindInstr::kUsed, computation); |
| 69 bind_instr->set_temp_index(AllocateTempIndex()); | 69 bind_instr->set_temp_index(AllocateTempIndex()); |
| 70 if (is_empty()) { | 70 if (is_empty()) { |
| 71 entry_ = bind_instr; | 71 entry_ = bind_instr; |
| 72 } else { | 72 } else { |
| 73 exit()->set_successor(bind_instr); | 73 exit()->set_next(bind_instr); |
| 74 } | 74 } |
| 75 exit_ = bind_instr; | 75 exit_ = bind_instr; |
| 76 return new UseVal(bind_instr); | 76 return new UseVal(bind_instr); |
| 77 } | 77 } |
| 78 | 78 |
| 79 | 79 |
| 80 void EffectGraphVisitor::Do(Computation* computation) { | 80 void EffectGraphVisitor::Do(Computation* computation) { |
| 81 ASSERT(is_open()); | 81 ASSERT(is_open()); |
| 82 DeallocateTempIndex(computation->InputCount()); | 82 DeallocateTempIndex(computation->InputCount()); |
| 83 BindInstr* do_instr = new BindInstr(BindInstr::kUnused, computation); | 83 BindInstr* do_instr = new BindInstr(BindInstr::kUnused, computation); |
| 84 if (is_empty()) { | 84 if (is_empty()) { |
| 85 entry_ = do_instr; | 85 entry_ = do_instr; |
| 86 } else { | 86 } else { |
| 87 exit()->set_successor(do_instr); | 87 exit()->set_next(do_instr); |
| 88 } | 88 } |
| 89 exit_ = do_instr; | 89 exit_ = do_instr; |
| 90 } | 90 } |
| 91 | 91 |
| 92 | 92 |
| 93 void EffectGraphVisitor::AddInstruction(Instruction* instruction) { | 93 void EffectGraphVisitor::AddInstruction(Instruction* instruction) { |
| 94 ASSERT(is_open()); | 94 ASSERT(is_open()); |
| 95 ASSERT(!instruction->IsDefinition()); | 95 ASSERT(!instruction->IsDefinition()); |
| 96 DeallocateTempIndex(instruction->InputCount()); | 96 DeallocateTempIndex(instruction->InputCount()); |
| 97 if (instruction->IsDefinition()) { | 97 if (instruction->IsDefinition()) { |
| 98 instruction->AsDefinition()->set_temp_index(AllocateTempIndex()); | 98 instruction->AsDefinition()->set_temp_index(AllocateTempIndex()); |
| 99 } | 99 } |
| 100 if (is_empty()) { | 100 if (is_empty()) { |
| 101 entry_ = exit_ = instruction; | 101 entry_ = exit_ = instruction; |
| 102 } else { | 102 } else { |
| 103 exit()->set_successor(instruction); | 103 exit()->set_next(instruction); |
| 104 exit_ = instruction; | 104 exit_ = instruction; |
| 105 } | 105 } |
| 106 } | 106 } |
| 107 | 107 |
| 108 | 108 |
| 109 // Appends a graph fragment to a block entry instruction and returns the exit | 109 // Appends a graph fragment to a block entry instruction and returns the exit |
| 110 // of the resulting graph fragment. | 110 // of the resulting graph fragment. |
| 111 static Instruction* AppendFragment(BlockEntryInstr* entry, | 111 static Instruction* AppendFragment(BlockEntryInstr* entry, |
| 112 const EffectGraphVisitor& fragment) { | 112 const EffectGraphVisitor& fragment) { |
| 113 if (fragment.is_empty()) return entry; | 113 if (fragment.is_empty()) return entry; |
| 114 entry->set_successor(fragment.entry()); | 114 entry->set_next(fragment.entry()); |
| 115 return fragment.exit(); | 115 return fragment.exit(); |
| 116 } | 116 } |
| 117 | 117 |
| 118 | 118 |
| 119 void EffectGraphVisitor::Join(const TestGraphVisitor& test_fragment, | 119 void EffectGraphVisitor::Join(const TestGraphVisitor& test_fragment, |
| 120 const EffectGraphVisitor& true_fragment, | 120 const EffectGraphVisitor& true_fragment, |
| 121 const EffectGraphVisitor& false_fragment) { | 121 const EffectGraphVisitor& false_fragment) { |
| 122 // We have: a test graph fragment with zero, one, or two available exits; | 122 // We have: a test graph fragment with zero, one, or two available exits; |
| 123 // and a pair of effect graph fragments with zero or one available exits. | 123 // and a pair of effect graph fragments with zero or one available exits. |
| 124 // We want to append the branch and (if necessary) a join node to this | 124 // We want to append the branch and (if necessary) a join node to this |
| (...skipping 15 matching lines...) Expand all Loading... |
| 140 | 140 |
| 141 // 3. Add a join or select one (or neither) of the arms as exit. | 141 // 3. Add a join or select one (or neither) of the arms as exit. |
| 142 if (true_exit == NULL) { | 142 if (true_exit == NULL) { |
| 143 exit_ = false_exit; // May be NULL. | 143 exit_ = false_exit; // May be NULL. |
| 144 if (false_exit != NULL) temp_index_ = false_fragment.temp_index(); | 144 if (false_exit != NULL) temp_index_ = false_fragment.temp_index(); |
| 145 } else if (false_exit == NULL) { | 145 } else if (false_exit == NULL) { |
| 146 exit_ = true_exit; | 146 exit_ = true_exit; |
| 147 temp_index_ = true_fragment.temp_index(); | 147 temp_index_ = true_fragment.temp_index(); |
| 148 } else { | 148 } else { |
| 149 exit_ = new JoinEntryInstr(); | 149 exit_ = new JoinEntryInstr(); |
| 150 true_exit->set_successor(exit_); | 150 true_exit->set_next(exit_); |
| 151 false_exit->set_successor(exit_); | 151 false_exit->set_next(exit_); |
| 152 ASSERT(true_fragment.temp_index() == false_fragment.temp_index()); | 152 ASSERT(true_fragment.temp_index() == false_fragment.temp_index()); |
| 153 temp_index_ = true_fragment.temp_index(); | 153 temp_index_ = true_fragment.temp_index(); |
| 154 } | 154 } |
| 155 } | 155 } |
| 156 | 156 |
| 157 | 157 |
| 158 void EffectGraphVisitor::TieLoop(const TestGraphVisitor& test_fragment, | 158 void EffectGraphVisitor::TieLoop(const TestGraphVisitor& test_fragment, |
| 159 const EffectGraphVisitor& body_fragment) { | 159 const EffectGraphVisitor& body_fragment) { |
| 160 // We have: a test graph fragment with zero, one, or two available exits; | 160 // We have: a test graph fragment with zero, one, or two available exits; |
| 161 // and an effect graph fragment with zero or one available exits. We want | 161 // and an effect graph fragment with zero or one available exits. We want |
| 162 // to append the 'while loop' consisting of the test graph fragment as | 162 // to append the 'while loop' consisting of the test graph fragment as |
| 163 // condition and the effect graph fragment as body. | 163 // condition and the effect graph fragment as body. |
| 164 ASSERT(is_open()); | 164 ASSERT(is_open()); |
| 165 | 165 |
| 166 // 1. Connect the body to the test if it is reachable, and if so record | 166 // 1. Connect the body to the test if it is reachable, and if so record |
| 167 // its exit (if any). | 167 // its exit (if any). |
| 168 TargetEntryInstr* body_entry = new TargetEntryInstr(); | 168 TargetEntryInstr* body_entry = new TargetEntryInstr(); |
| 169 *test_fragment.true_successor_address() = body_entry; | 169 *test_fragment.true_successor_address() = body_entry; |
| 170 Instruction* body_exit = AppendFragment(body_entry, body_fragment); | 170 Instruction* body_exit = AppendFragment(body_entry, body_fragment); |
| 171 | 171 |
| 172 // 2. Connect the test to this graph, including the body if reachable and | 172 // 2. Connect the test to this graph, including the body if reachable and |
| 173 // using a fresh join node if the body is reachable and has an open exit. | 173 // using a fresh join node if the body is reachable and has an open exit. |
| 174 if (body_exit == NULL) { | 174 if (body_exit == NULL) { |
| 175 Append(test_fragment); | 175 Append(test_fragment); |
| 176 } else { | 176 } else { |
| 177 JoinEntryInstr* join = new JoinEntryInstr(); | 177 JoinEntryInstr* join = new JoinEntryInstr(); |
| 178 AddInstruction(join); | 178 AddInstruction(join); |
| 179 join->set_successor(test_fragment.entry()); | 179 join->set_next(test_fragment.entry()); |
| 180 body_exit->set_successor(join); | 180 body_exit->set_next(join); |
| 181 } | 181 } |
| 182 | 182 |
| 183 // 3. Set the exit to the graph to be the false successor of the test, a | 183 // 3. Set the exit to the graph to be the false successor of the test, a |
| 184 // fresh target node | 184 // fresh target node |
| 185 exit_ = *test_fragment.false_successor_address() = new TargetEntryInstr(); | 185 exit_ = *test_fragment.false_successor_address() = new TargetEntryInstr(); |
| 186 } | 186 } |
| 187 | 187 |
| 188 | 188 |
| 189 Computation* EffectGraphVisitor::BuildStoreLocal( | 189 Computation* EffectGraphVisitor::BuildStoreLocal( |
| 190 const LocalVariable& local, Value* value) { | 190 const LocalVariable& local, Value* value) { |
| (...skipping 773 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 964 | 964 |
| 965 // Once a test fragment has been added, this fragment is closed. | 965 // Once a test fragment has been added, this fragment is closed. |
| 966 ASSERT(!is_open()); | 966 ASSERT(!is_open()); |
| 967 | 967 |
| 968 // Connect all test cases except the last one. | 968 // Connect all test cases except the last one. |
| 969 for (intptr_t i = 0; i < (len - 1); i++) { | 969 for (intptr_t i = 0; i < (len - 1); i++) { |
| 970 ASSERT(needs_join_at_statement_entry); | 970 ASSERT(needs_join_at_statement_entry); |
| 971 *case_false_addresses[i] = case_entries[i + 1]; | 971 *case_false_addresses[i] = case_entries[i + 1]; |
| 972 TargetEntryInstr* true_target = new TargetEntryInstr(); | 972 TargetEntryInstr* true_target = new TargetEntryInstr(); |
| 973 *case_true_addresses[i] = true_target; | 973 *case_true_addresses[i] = true_target; |
| 974 true_target->set_successor(statement_start); | 974 true_target->set_next(statement_start); |
| 975 } | 975 } |
| 976 | 976 |
| 977 BlockEntryInstr* exit_instruction = NULL; | 977 BlockEntryInstr* exit_instruction = NULL; |
| 978 // Handle last (or only) case: false goes to exit or to statement if this | 978 // Handle last (or only) case: false goes to exit or to statement if this |
| 979 // node contains default. | 979 // node contains default. |
| 980 if (len > 0) { | 980 if (len > 0) { |
| 981 if (statement_start->IsTargetEntry()) { | 981 if (statement_start->IsTargetEntry()) { |
| 982 *case_true_addresses[len - 1] = statement_start->AsTargetEntry(); | 982 *case_true_addresses[len - 1] = statement_start->AsTargetEntry(); |
| 983 } else { | 983 } else { |
| 984 TargetEntryInstr* true_target = new TargetEntryInstr(); | 984 TargetEntryInstr* true_target = new TargetEntryInstr(); |
| 985 *case_true_addresses[len - 1] = true_target; | 985 *case_true_addresses[len - 1] = true_target; |
| 986 true_target->set_successor(statement_start); | 986 true_target->set_next(statement_start); |
| 987 } | 987 } |
| 988 TargetEntryInstr* false_target = new TargetEntryInstr(); | 988 TargetEntryInstr* false_target = new TargetEntryInstr(); |
| 989 *case_false_addresses[len - 1] = false_target; | 989 *case_false_addresses[len - 1] = false_target; |
| 990 if (node->contains_default()) { | 990 if (node->contains_default()) { |
| 991 // True and false go to statement start. | 991 // True and false go to statement start. |
| 992 false_target->set_successor(statement_start); | 992 false_target->set_next(statement_start); |
| 993 if (for_case_statements.is_open()) { | 993 if (for_case_statements.is_open()) { |
| 994 exit_instruction = new TargetEntryInstr(); | 994 exit_instruction = new TargetEntryInstr(); |
| 995 for_case_statements.exit()->set_successor(exit_instruction); | 995 for_case_statements.exit()->set_next(exit_instruction); |
| 996 } | 996 } |
| 997 } else { | 997 } else { |
| 998 if (for_case_statements.is_open()) { | 998 if (for_case_statements.is_open()) { |
| 999 exit_instruction = new JoinEntryInstr(); | 999 exit_instruction = new JoinEntryInstr(); |
| 1000 for_case_statements.exit()->set_successor(exit_instruction); | 1000 for_case_statements.exit()->set_next(exit_instruction); |
| 1001 } else { | 1001 } else { |
| 1002 exit_instruction = new TargetEntryInstr(); | 1002 exit_instruction = new TargetEntryInstr(); |
| 1003 } | 1003 } |
| 1004 false_target->set_successor(exit_instruction); | 1004 false_target->set_next(exit_instruction); |
| 1005 } | 1005 } |
| 1006 } else { | 1006 } else { |
| 1007 // A CaseNode without case expressions must contain default. | 1007 // A CaseNode without case expressions must contain default. |
| 1008 ASSERT(node->contains_default()); | 1008 ASSERT(node->contains_default()); |
| 1009 AddInstruction(statement_start); | 1009 AddInstruction(statement_start); |
| 1010 } | 1010 } |
| 1011 | 1011 |
| 1012 ASSERT(!is_open()); | 1012 ASSERT(!is_open()); |
| 1013 exit_ = exit_instruction; | 1013 exit_ = exit_instruction; |
| 1014 } | 1014 } |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1076 AddInstruction(body_entry_join); | 1076 AddInstruction(body_entry_join); |
| 1077 Instruction* body_exit = AppendFragment(body_entry_join, for_body); | 1077 Instruction* body_exit = AppendFragment(body_entry_join, for_body); |
| 1078 | 1078 |
| 1079 if (for_body.is_open() || (node->label()->join_for_continue() != NULL)) { | 1079 if (for_body.is_open() || (node->label()->join_for_continue() != NULL)) { |
| 1080 BlockEntryInstr* test_entry = NULL; | 1080 BlockEntryInstr* test_entry = NULL; |
| 1081 if (node->label()->join_for_continue() == NULL) { | 1081 if (node->label()->join_for_continue() == NULL) { |
| 1082 test_entry = new TargetEntryInstr(); | 1082 test_entry = new TargetEntryInstr(); |
| 1083 } else { | 1083 } else { |
| 1084 test_entry = node->label()->join_for_continue(); | 1084 test_entry = node->label()->join_for_continue(); |
| 1085 } | 1085 } |
| 1086 test_entry->set_successor(for_test.entry()); | 1086 test_entry->set_next(for_test.entry()); |
| 1087 if (body_exit != NULL) { | 1087 if (body_exit != NULL) { |
| 1088 body_exit->set_successor(test_entry); | 1088 body_exit->set_next(test_entry); |
| 1089 } | 1089 } |
| 1090 } | 1090 } |
| 1091 | 1091 |
| 1092 TargetEntryInstr* back_target_entry = new TargetEntryInstr(); | 1092 TargetEntryInstr* back_target_entry = new TargetEntryInstr(); |
| 1093 *for_test.true_successor_address() = back_target_entry; | 1093 *for_test.true_successor_address() = back_target_entry; |
| 1094 back_target_entry->set_successor(body_entry_join); | 1094 back_target_entry->set_next(body_entry_join); |
| 1095 TargetEntryInstr* loop_exit_target = new TargetEntryInstr(); | 1095 TargetEntryInstr* loop_exit_target = new TargetEntryInstr(); |
| 1096 *for_test.false_successor_address() = loop_exit_target; | 1096 *for_test.false_successor_address() = loop_exit_target; |
| 1097 if (node->label()->join_for_break() == NULL) { | 1097 if (node->label()->join_for_break() == NULL) { |
| 1098 exit_ = loop_exit_target; | 1098 exit_ = loop_exit_target; |
| 1099 } else { | 1099 } else { |
| 1100 loop_exit_target->set_successor(node->label()->join_for_break()); | 1100 loop_exit_target->set_next(node->label()->join_for_break()); |
| 1101 exit_ = node->label()->join_for_break(); | 1101 exit_ = node->label()->join_for_break(); |
| 1102 } | 1102 } |
| 1103 } | 1103 } |
| 1104 | 1104 |
| 1105 | 1105 |
| 1106 // A ForNode can contain break and continue jumps. 'break' joins to | 1106 // A ForNode can contain break and continue jumps. 'break' joins to |
| 1107 // ForNode exit, 'continue' joins at increment entry. The fragment is composed | 1107 // ForNode exit, 'continue' joins at increment entry. The fragment is composed |
| 1108 // as follows: | 1108 // as follows: |
| 1109 // a) [ initializer ] | 1109 // a) [ initializer ] |
| 1110 // b) loop-join | 1110 // b) loop-join |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1136 if ((node->label()->join_for_continue() == NULL) && for_body.is_open()) { | 1136 if ((node->label()->join_for_continue() == NULL) && for_body.is_open()) { |
| 1137 // Do not insert an extra basic block. | 1137 // Do not insert an extra basic block. |
| 1138 node->increment()->Visit(&for_increment); | 1138 node->increment()->Visit(&for_increment); |
| 1139 for_body.Append(for_increment); | 1139 for_body.Append(for_increment); |
| 1140 loop_increment_end = for_body.exit(); | 1140 loop_increment_end = for_body.exit(); |
| 1141 // 'for_body' contains at least the TargetInstruction 'body_entry'. | 1141 // 'for_body' contains at least the TargetInstruction 'body_entry'. |
| 1142 ASSERT(loop_increment_end != NULL); | 1142 ASSERT(loop_increment_end != NULL); |
| 1143 } else if (node->label()->join_for_continue() != NULL) { | 1143 } else if (node->label()->join_for_continue() != NULL) { |
| 1144 // Insert join between body and increment. | 1144 // Insert join between body and increment. |
| 1145 if (for_body.is_open()) { | 1145 if (for_body.is_open()) { |
| 1146 for_body.exit()->set_successor(node->label()->join_for_continue()); | 1146 for_body.exit()->set_next(node->label()->join_for_continue()); |
| 1147 } | 1147 } |
| 1148 for_increment.AddInstruction(node->label()->join_for_continue()); | 1148 for_increment.AddInstruction(node->label()->join_for_continue()); |
| 1149 node->increment()->Visit(&for_increment); | 1149 node->increment()->Visit(&for_increment); |
| 1150 loop_increment_end = for_increment.exit(); | 1150 loop_increment_end = for_increment.exit(); |
| 1151 ASSERT(loop_increment_end != NULL); | 1151 ASSERT(loop_increment_end != NULL); |
| 1152 } else { | 1152 } else { |
| 1153 loop_increment_end = NULL; | 1153 loop_increment_end = NULL; |
| 1154 ASSERT(!for_body.is_open() && node->label()->join_for_continue() == NULL); | 1154 ASSERT(!for_body.is_open() && node->label()->join_for_continue() == NULL); |
| 1155 } | 1155 } |
| 1156 | 1156 |
| 1157 // 'loop_increment_end' is NULL only if there is no join for continue and the | 1157 // 'loop_increment_end' is NULL only if there is no join for continue and the |
| 1158 // body is not open, i.e., no backward branch exists. | 1158 // body is not open, i.e., no backward branch exists. |
| 1159 if (loop_increment_end != NULL) { | 1159 if (loop_increment_end != NULL) { |
| 1160 JoinEntryInstr* loop_start = new JoinEntryInstr(); | 1160 JoinEntryInstr* loop_start = new JoinEntryInstr(); |
| 1161 AddInstruction(loop_start); | 1161 AddInstruction(loop_start); |
| 1162 loop_increment_end->set_successor(loop_start); | 1162 loop_increment_end->set_next(loop_start); |
| 1163 } | 1163 } |
| 1164 | 1164 |
| 1165 if (node->condition() == NULL) { | 1165 if (node->condition() == NULL) { |
| 1166 // Endless loop, no test. | 1166 // Endless loop, no test. |
| 1167 Append(for_body); | 1167 Append(for_body); |
| 1168 if (node->label()->join_for_break() == NULL) { | 1168 if (node->label()->join_for_break() == NULL) { |
| 1169 CloseFragment(); | 1169 CloseFragment(); |
| 1170 } else { | 1170 } else { |
| 1171 // Control flow of ForLoop continues into join_for_break. | 1171 // Control flow of ForLoop continues into join_for_break. |
| 1172 exit_ = node->label()->join_for_break(); | 1172 exit_ = node->label()->join_for_break(); |
| 1173 } | 1173 } |
| 1174 } else { | 1174 } else { |
| 1175 TargetEntryInstr* loop_exit = new TargetEntryInstr(); | 1175 TargetEntryInstr* loop_exit = new TargetEntryInstr(); |
| 1176 TestGraphVisitor for_test(owner(), | 1176 TestGraphVisitor for_test(owner(), |
| 1177 temp_index(), | 1177 temp_index(), |
| 1178 node->condition()->token_pos()); | 1178 node->condition()->token_pos()); |
| 1179 node->condition()->Visit(&for_test); | 1179 node->condition()->Visit(&for_test); |
| 1180 Append(for_test); | 1180 Append(for_test); |
| 1181 *for_test.true_successor_address() = body_entry; | 1181 *for_test.true_successor_address() = body_entry; |
| 1182 *for_test.false_successor_address() = loop_exit; | 1182 *for_test.false_successor_address() = loop_exit; |
| 1183 if (node->label()->join_for_break() == NULL) { | 1183 if (node->label()->join_for_break() == NULL) { |
| 1184 exit_ = loop_exit; | 1184 exit_ = loop_exit; |
| 1185 } else { | 1185 } else { |
| 1186 loop_exit->set_successor(node->label()->join_for_break()); | 1186 loop_exit->set_next(node->label()->join_for_break()); |
| 1187 exit_ = node->label()->join_for_break(); | 1187 exit_ = node->label()->join_for_break(); |
| 1188 } | 1188 } |
| 1189 } | 1189 } |
| 1190 } | 1190 } |
| 1191 | 1191 |
| 1192 | 1192 |
| 1193 void EffectGraphVisitor::VisitJumpNode(JumpNode* node) { | 1193 void EffectGraphVisitor::VisitJumpNode(JumpNode* node) { |
| 1194 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { | 1194 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { |
| 1195 EffectGraphVisitor for_effect(owner(), temp_index()); | 1195 EffectGraphVisitor for_effect(owner(), temp_index()); |
| 1196 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); | 1196 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); |
| (...skipping 1017 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2214 variable_count); | 2214 variable_count); |
| 2215 // Number blocks in reverse postorder. | 2215 // Number blocks in reverse postorder. |
| 2216 intptr_t block_count = postorder_block_entries_.length(); | 2216 intptr_t block_count = postorder_block_entries_.length(); |
| 2217 for (intptr_t i = 0; i < block_count; ++i) { | 2217 for (intptr_t i = 0; i < block_count; ++i) { |
| 2218 postorder_block_entries_[i]->set_block_id(block_count - i - 1); | 2218 postorder_block_entries_[i]->set_block_id(block_count - i - 1); |
| 2219 } | 2219 } |
| 2220 if (for_optimized && use_ssa) { | 2220 if (for_optimized && use_ssa) { |
| 2221 // Link instructions backwards for optimized compilation. | 2221 // Link instructions backwards for optimized compilation. |
| 2222 for (intptr_t i = 0; i < block_count; ++i) { | 2222 for (intptr_t i = 0; i < block_count; ++i) { |
| 2223 Instruction* prev = postorder_block_entries_[i]; | 2223 Instruction* prev = postorder_block_entries_[i]; |
| 2224 Instruction* current = prev->successor(); | 2224 Instruction* current = prev->next(); |
| 2225 while (current != NULL && !current->IsBlockEntry()) { | 2225 while (current != NULL && !current->IsBlockEntry()) { |
| 2226 current->set_previous(prev); | 2226 current->set_previous(prev); |
| 2227 prev = current; | 2227 prev = current; |
| 2228 current = current->successor(); | 2228 current = current->next(); |
| 2229 } | 2229 } |
| 2230 } | 2230 } |
| 2231 GrowableArray<BitVector*> dominance_frontier; | 2231 GrowableArray<BitVector*> dominance_frontier; |
| 2232 ComputeDominators(&preorder_block_entries_, &parent, &dominance_frontier); | 2232 ComputeDominators(&preorder_block_entries_, &parent, &dominance_frontier); |
| 2233 InsertPhis(preorder_block_entries_, | 2233 InsertPhis(preorder_block_entries_, |
| 2234 assigned_vars, | 2234 assigned_vars, |
| 2235 variable_count, | 2235 variable_count, |
| 2236 dominance_frontier); | 2236 dominance_frontier); |
| 2237 Rename(variable_count); | 2237 Rename(variable_count); |
| 2238 } | 2238 } |
| (...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2619 char* chars = reinterpret_cast<char*>( | 2619 char* chars = reinterpret_cast<char*>( |
| 2620 Isolate::Current()->current_zone()->Allocate(len)); | 2620 Isolate::Current()->current_zone()->Allocate(len)); |
| 2621 OS::SNPrint(chars, len, kFormat, function_name, reason); | 2621 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 2622 const Error& error = Error::Handle( | 2622 const Error& error = Error::Handle( |
| 2623 LanguageError::New(String::Handle(String::New(chars)))); | 2623 LanguageError::New(String::Handle(String::New(chars)))); |
| 2624 Isolate::Current()->long_jump_base()->Jump(1, error); | 2624 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 2625 } | 2625 } |
| 2626 | 2626 |
| 2627 | 2627 |
| 2628 } // namespace dart | 2628 } // namespace dart |
| OLD | NEW |