Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(148)

Side by Side Diff: runtime/vm/flow_graph_builder.cc

Issue 10808035: Apply Kevin's suggestions, make branch-compare generation more robust (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/il_printer.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 } 251 }
252 252
253 253
254 // Loads context saved in 'context_variable' into the current context. 254 // Loads context saved in 'context_variable' into the current context.
255 void EffectGraphVisitor::BuildLoadContext(const LocalVariable& variable) { 255 void EffectGraphVisitor::BuildLoadContext(const LocalVariable& variable) {
256 Value* load_saved_context = Bind(BuildLoadLocal(variable)); 256 Value* load_saved_context = Bind(BuildLoadLocal(variable));
257 Do(new StoreContextComp(load_saved_context)); 257 Do(new StoreContextComp(load_saved_context));
258 } 258 }
259 259
260 260
261 // TODO(srdjan): This code is clumsy. Try to skip allocation of ComparisonComp
262 // and generate the right BranchInstr directly.
263 // Replaces instruction patterns:
264 // t0 <- Comparison(kind, t0, t1)
265 // t1 <- #true
266 // Branch if t0 === t1 goto (true, false)
267 // With:
268 // Branch if t0 kind t1 goto (true, false)
269 // Returns false if fusing is not possible, e.g:
270 // t0 <- LoadLocal
271 // t1 <- #true
272 // Branch if t0 === t1 goto (true, false)
273 static bool TryFuseBranchInstr(BranchInstr* branch) {
274 UseVal* use = branch->left()->AsUse();
275 if (use == NULL) return false;
276 BindInstr* compare_instr = use->definition()->AsBind();
277 if (compare_instr == NULL) return false;
278 ComparisonComp* compare = compare_instr->computation()->AsComparison();
279 Token::Kind kind;
280 if (compare == NULL) {
281 // Check if there is a BooleanNegate in between Comparison and Branch.
282 BooleanNegateComp* neg = compare_instr->computation()->AsBooleanNegate();
283 if (neg == NULL) return false;
284 if (compare_instr->previous() == NULL) return false;
285 compare_instr = compare_instr->previous()->AsBind();
286 ASSERT(compare_instr != NULL);
287 compare = compare_instr->computation()->AsComparison();
288 if (compare == NULL) return false;
289 // Negation can be handled only in connection with EqualityCompare.
290 if (!compare->IsEqualityCompare()) return false;
291 kind = Token::kNE;
292 } else {
293 kind = compare->kind();
294 }
295 branch->set_kind(kind);
296 branch->SetInputAt(0, compare->InputAt(0));
297 branch->SetInputAt(1, compare->InputAt(1));
298 // Remove elminated nodes.
299 branch->set_previous(compare_instr->previous());
300 compare_instr->previous()->set_next(branch);
301 return true;
302 }
303
304
305 void TestGraphVisitor::ReturnValue(Value* value) { 261 void TestGraphVisitor::ReturnValue(Value* value) {
306 if (FLAG_enable_type_checks) { 262 if (FLAG_enable_type_checks) {
307 value = Bind(new AssertBooleanComp(condition_token_pos(), 263 value = Bind(new AssertBooleanComp(condition_token_pos(),
308 owner()->try_index(), 264 owner()->try_index(),
309 value)); 265 value));
310 } 266 }
311 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); 267 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
312 Value* constant_true = Bind(new ConstantVal(bool_true)); 268 Value* constant_true = Bind(new ConstantVal(bool_true));
313 BranchInstr* branch = new BranchInstr(condition_token_pos(), 269 BranchInstr* branch = new BranchInstr(condition_token_pos(),
314 owner()->try_index(), 270 owner()->try_index(),
315 value, 271 value,
316 constant_true, 272 constant_true,
317 Token::kEQ_STRICT); 273 Token::kEQ_STRICT);
318 AddInstruction(branch); 274 AddInstruction(branch);
319 CloseFragment(); 275 CloseFragment();
320 true_successor_address_ = branch->true_successor_address(); 276 true_successor_address_ = branch->true_successor_address();
321 false_successor_address_ = branch->false_successor_address(); 277 false_successor_address_ = branch->false_successor_address();
322 TryFuseBranchInstr(branch); 278 }
279
280
281 void TestGraphVisitor::MergeBranchWithComparison(ComparisonComp* comp) {
282 ASSERT(!FLAG_enable_type_checks);
283 BranchInstr* branch = new BranchInstr(condition_token_pos(),
284 owner()->try_index(),
285 comp->left(),
286 comp->right(),
287 comp->kind());
288 AddInstruction(branch);
289 CloseFragment();
290 true_successor_address_ = branch->true_successor_address();
291 false_successor_address_ = branch->false_successor_address();
292 }
293
294
295 void TestGraphVisitor::MergeBranchWithNegate(BooleanNegateComp* comp) {
296 ASSERT(!FLAG_enable_type_checks);
297 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
298 Value* constant_true = Bind(new ConstantVal(bool_true));
299 BranchInstr* branch = new BranchInstr(condition_token_pos(),
300 owner()->try_index(),
301 comp->value(),
302 constant_true,
303 Token::kNE_STRICT);
304 AddInstruction(branch);
305 CloseFragment();
306 true_successor_address_ = branch->true_successor_address();
307 false_successor_address_ = branch->false_successor_address();
308 }
309
310
311 void TestGraphVisitor::ReturnComputation(Computation* computation) {
312 if (!FLAG_enable_type_checks) {
313 if (computation->AsComparison() != NULL) {
314 MergeBranchWithComparison(computation->AsComparison());
315 return;
316 }
317 if (computation->IsBooleanNegate()) {
318 MergeBranchWithNegate(computation->AsBooleanNegate());
319 return;
320 }
321 }
322 ReturnValue(Bind(computation));
323 } 323 }
324 324
325 325
326 void EffectGraphVisitor::Bailout(const char* reason) { 326 void EffectGraphVisitor::Bailout(const char* reason) {
327 owner()->Bailout(reason); 327 owner()->Bailout(reason);
328 } 328 }
329 329
330 330
331 // <Statement> ::= Return { value: <Expression> 331 // <Statement> ::= Return { value: <Expression>
332 // inlined_finally_list: <InlinedFinally>* } 332 // inlined_finally_list: <InlinedFinally>* }
(...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after
846 return; 846 return;
847 } 847 }
848 848
849 if ((node->kind() == Token::kEQ) || (node->kind() == Token::kNE)) { 849 if ((node->kind() == Token::kEQ) || (node->kind() == Token::kNE)) {
850 ValueGraphVisitor for_left_value(owner(), temp_index()); 850 ValueGraphVisitor for_left_value(owner(), temp_index());
851 node->left()->Visit(&for_left_value); 851 node->left()->Visit(&for_left_value);
852 Append(for_left_value); 852 Append(for_left_value);
853 ValueGraphVisitor for_right_value(owner(), temp_index()); 853 ValueGraphVisitor for_right_value(owner(), temp_index());
854 node->right()->Visit(&for_right_value); 854 node->right()->Visit(&for_right_value);
855 Append(for_right_value); 855 Append(for_right_value);
856 EqualityCompareComp* comp = new EqualityCompareComp( 856 if (FLAG_enable_type_checks) {
857 node->token_pos(), owner()->try_index(), 857 EqualityCompareComp* comp = new EqualityCompareComp(
858 for_left_value.value(), for_right_value.value()); 858 node->token_pos(), owner()->try_index(),
859 if (node->kind() == Token::kEQ) { 859 Token::kEQ, for_left_value.value(), for_right_value.value());
860 if (node->kind() == Token::kEQ) {
861 ReturnComputation(comp);
862 } else {
863 Value* eq_result = Bind(comp);
864 eq_result = Bind(new AssertBooleanComp(node->token_pos(),
865 owner()->try_index(),
866 eq_result));
867 ReturnComputation(new BooleanNegateComp(eq_result));
868 }
869 } else {
870 EqualityCompareComp* comp = new EqualityCompareComp(
871 node->token_pos(), owner()->try_index(),
872 node->kind(), for_left_value.value(), for_right_value.value());
860 ReturnComputation(comp); 873 ReturnComputation(comp);
861 } else {
862 Value* eq_result = Bind(comp);
863 if (FLAG_enable_type_checks) {
864 eq_result =
865 Bind(new AssertBooleanComp(node->token_pos(),
866 owner()->try_index(),
867 eq_result));
868 }
869 ReturnComputation(new BooleanNegateComp(eq_result));
870 } 874 }
871 return; 875 return;
872 } 876 }
873 877
874 ValueGraphVisitor for_left_value(owner(), temp_index()); 878 ValueGraphVisitor for_left_value(owner(), temp_index());
875 node->left()->Visit(&for_left_value); 879 node->left()->Visit(&for_left_value);
876 Append(for_left_value); 880 Append(for_left_value);
877 ValueGraphVisitor for_right_value(owner(), temp_index()); 881 ValueGraphVisitor for_right_value(owner(), temp_index());
878 node->right()->Visit(&for_right_value); 882 node->right()->Visit(&for_right_value);
879 Append(for_right_value); 883 Append(for_right_value);
(...skipping 1824 matching lines...) Expand 10 before | Expand all | Expand 10 after
2704 char* chars = reinterpret_cast<char*>( 2708 char* chars = reinterpret_cast<char*>(
2705 Isolate::Current()->current_zone()->Allocate(len)); 2709 Isolate::Current()->current_zone()->Allocate(len));
2706 OS::SNPrint(chars, len, kFormat, function_name, reason); 2710 OS::SNPrint(chars, len, kFormat, function_name, reason);
2707 const Error& error = Error::Handle( 2711 const Error& error = Error::Handle(
2708 LanguageError::New(String::Handle(String::New(chars)))); 2712 LanguageError::New(String::Handle(String::New(chars))));
2709 Isolate::Current()->long_jump_base()->Jump(1, error); 2713 Isolate::Current()->long_jump_base()->Jump(1, error);
2710 } 2714 }
2711 2715
2712 2716
2713 } // namespace dart 2717 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/il_printer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698