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

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

Issue 10354019: Removing all incr-op nodes. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 7 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/opt_code_generator_ia32.h » ('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/code_descriptors.h" 8 #include "vm/code_descriptors.h"
9 #include "vm/dart_entry.h" 9 #include "vm/dart_entry.h"
10 #include "vm/flags.h" 10 #include "vm/flags.h"
(...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after
717 String::ZoneHandle(String::NewSymbol((node->kind() == Token::kSUB) 717 String::ZoneHandle(String::NewSymbol((node->kind() == Token::kSUB)
718 ? Token::Str(Token::kNEGATE) 718 ? Token::Str(Token::kNEGATE)
719 : node->Name())); 719 : node->Name()));
720 InstanceCallComp* call = new InstanceCallComp( 720 InstanceCallComp* call = new InstanceCallComp(
721 node->token_index(), owner()->try_index(), name, 721 node->token_index(), owner()->try_index(), name,
722 arguments, Array::ZoneHandle(), 1); 722 arguments, Array::ZoneHandle(), 1);
723 ReturnComputation(call); 723 ReturnComputation(call);
724 } 724 }
725 725
726 726
727 Definition* EffectGraphVisitor::BuildIncrOpFieldLoad(
728 IncrOpInstanceFieldNode* node,
729 Value** receiver) {
730 // Evaluate the receiver and duplicate it (it has two uses).
731 // t_n <- ... receiver ...
732 // t_n+1 <- Pick(t_n)
733 ValueGraphVisitor for_receiver(owner(), temp_index());
734 node->receiver()->Visit(&for_receiver);
735 Append(for_receiver);
736 ASSERT(temp_index() == for_receiver.temp_index());
737 PickTempInstr* duplicate = new PickTempInstr(temp_index() - 1);
738 AddInstruction(duplicate);
739
740 // Load the value.
741 // t_n+1 <- InstanceCall(get:name, t_n+1)
742 const String& getter_name =
743 String::ZoneHandle(Field::GetterSymbol(node->field_name()));
744 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(1);
745 arguments->Add(new UseVal(duplicate));
746 BindInstr* load =
747 new BindInstr(new InstanceCallComp(
748 node->token_index(),
749 owner()->try_index(), getter_name, arguments,
750 Array::ZoneHandle(), 1));
751 AddInstruction(load);
752
753 *receiver = for_receiver.value();
754 return load;
755 }
756
757
758 Definition* EffectGraphVisitor::BuildIncrOpIncrement(Token::Kind kind,
759 intptr_t token_index,
760 Value* original) {
761 ASSERT((kind == Token::kINCR) || (kind == Token::kDECR));
762 // Assumed that t_n-1 (where n is start_index) is the field value.
763 // t_n <- #1
764 // t_n-1 <- InstanceCall(op, t_n-1, t_n)
765 BindInstr* one =
766 new BindInstr(new ConstantVal(Smi::ZoneHandle(Smi::New(1))));
767 AddInstruction(one);
768 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2);
769 arguments->Add(original);
770 arguments->Add(new UseVal(one));
771 const String& op_name =
772 String::ZoneHandle(String::NewSymbol((kind == Token::kINCR) ? "+" : "-"));
773 BindInstr* add =
774 new BindInstr(new InstanceCallComp(
775 token_index, owner()->try_index(), op_name,
776 arguments, Array::ZoneHandle(), 2));
777 AddInstruction(add);
778 return add;
779 }
780
781
782 void EffectGraphVisitor::VisitIncrOpInstanceFieldNode(
783 IncrOpInstanceFieldNode* node) {
784 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR));
785 // In an effect context, treat postincrement as if it were preincrement
786 // because its value is not needed.
787
788 // 1. Load the value.
789 Value* receiver = NULL;
790 Definition* load = BuildIncrOpFieldLoad(node, &receiver);
791 // 2. Increment.
792 Definition* incr =
793 BuildIncrOpIncrement(node->kind(), node->token_index(), new UseVal(load));
794 // 3. Perform the store, returning the stored value.
795 InstanceSetterComp* store =
796 new InstanceSetterComp(node->token_index(),
797 owner()->try_index(),
798 node->field_name(),
799 receiver,
800 new UseVal(incr));
801 ReturnComputation(store);
802 }
803
804
805 void ValueGraphVisitor::VisitIncrOpInstanceFieldNode(
806 IncrOpInstanceFieldNode* node) {
807 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR));
808 if (node->prefix()) {
809 // Base class handles preincrement.
810 EffectGraphVisitor::VisitIncrOpInstanceFieldNode(node);
811 return;
812 }
813 // For postincrement, preallocate a temporary to preserve the original
814 // value.
815 //
816 // 1. Name a placeholder.
817 BindInstr* placeholder =
818 new BindInstr(new ConstantVal(Smi::ZoneHandle(Smi::New(0))));
819 AddInstruction(placeholder);
820 // 2. Load the value.
821 Value* receiver = NULL;
822 Definition* load = BuildIncrOpFieldLoad(node, &receiver);
823 // 3. Preserve the original value.
824 AddInstruction(new TuckTempInstr(placeholder->temp_index(),
825 load->temp_index()));
826 // 4. Increment.
827 Definition* incr =
828 BuildIncrOpIncrement(node->kind(), node->token_index(), new UseVal(load));
829 // 5. Perform the store and return the original value.
830 const String& setter_name =
831 String::ZoneHandle(Field::SetterSymbol(node->field_name()));
832 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2);
833 arguments->Add(receiver);
834 arguments->Add(new UseVal(incr));
835 InstanceCallComp* store = new InstanceCallComp(
836 node->token_index(), owner()->try_index(),
837 setter_name, arguments, Array::ZoneHandle(), 1);
838 AddInstruction(new DoInstr(store));
839 ReturnValue(new UseVal(placeholder));
840 }
841
842
843 Definition* EffectGraphVisitor::BuildIncrOpIndexedLoad(
844 IncrOpIndexedNode* node,
845 Value** receiver,
846 Value** index) {
847 // Evaluate the receiver and index.
848 // t_n <- ... receiver ...
849 // t_n+1 <- ... index ...
850 ValueGraphVisitor for_receiver(owner(), temp_index());
851 node->array()->Visit(&for_receiver);
852 Append(for_receiver);
853 ASSERT(temp_index() == for_receiver.temp_index());
854
855 ValueGraphVisitor for_index(owner(), temp_index());
856 node->index()->Visit(&for_index);
857 Append(for_index);
858 ASSERT(temp_index() == for_index.temp_index());
859
860 // Duplicate the receiver and index values, load the value.
861 // t_n+2 <- Pick(t_n)
862 // t_n+3 <- Pick(t_n+1)
863 // t_n+2 <- InstanceCall([], t_n+2, t_n+3)
864 PickTempInstr* duplicate_receiver = new PickTempInstr(temp_index() - 2);
865 AddInstruction(duplicate_receiver);
866 PickTempInstr* duplicate_index = new PickTempInstr(temp_index() - 2);
867 AddInstruction(duplicate_index);
868 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2);
869 arguments->Add(new UseVal(duplicate_receiver));
870 arguments->Add(new UseVal(duplicate_index));
871 const String& load_name =
872 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kINDEX)));
873 BindInstr* load =
874 new BindInstr(new InstanceCallComp(
875 node->token_index(),
876 owner()->try_index(), load_name, arguments,
877 Array::ZoneHandle(), 1));
878 AddInstruction(load);
879
880 *receiver = for_receiver.value();
881 *index = for_index.value();
882 return load;
883 }
884
885
886 void EffectGraphVisitor::VisitIncrOpIndexedNode(IncrOpIndexedNode* node) {
887 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR));
888 // In an effect context, treat postincrement as if it were preincrement
889 // because its value is not needed.
890
891 // 1. Load the value.
892 Value* receiver = NULL;
893 Value* index = NULL;
894 Definition* load = BuildIncrOpIndexedLoad(node, &receiver, &index);
895 // 2. Increment.
896 Definition* incr =
897 BuildIncrOpIncrement(node->kind(), node->token_index(), new UseVal(load));
898 // 3. Perform the store, returning the stored value.
899 StoreIndexedComp* store = new StoreIndexedComp(node->token_index(),
900 owner()->try_index(),
901 receiver,
902 index,
903 new UseVal(incr));
904 ReturnComputation(store);
905 }
906
907
908 void ValueGraphVisitor::VisitIncrOpIndexedNode(IncrOpIndexedNode* node) {
909 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR));
910 if (node->prefix()) {
911 // Base class handles preincrement.
912 EffectGraphVisitor::VisitIncrOpIndexedNode(node);
913 return;
914 }
915 // For postincrement, preallocate a temporary to preserve the original
916 // value.
917 //
918 // 1. Name a placeholder.
919 BindInstr* placeholder =
920 new BindInstr(new ConstantVal(Smi::ZoneHandle(Smi::New(0))));
921 AddInstruction(placeholder);
922 // 2. Load the value.
923 Value* receiver = NULL;
924 Value* index = NULL;
925 Definition* load = BuildIncrOpIndexedLoad(node, &receiver, &index);
926 // 3. Preserve the original value.
927 AddInstruction(new TuckTempInstr(placeholder->temp_index(),
928 load->temp_index()));
929 // 4. Increment.
930 Definition* incr =
931 BuildIncrOpIncrement(node->kind(), node->token_index(), new UseVal(load));
932 // 5. Perform the store and return the original value.
933 const String& store_name =
934 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kASSIGN_INDEX)));
935 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(3);
936 arguments->Add(receiver);
937 arguments->Add(index);
938 arguments->Add(new UseVal(incr));
939 InstanceCallComp* store = new InstanceCallComp(
940 node->token_index(), owner()->try_index(),
941 store_name, arguments, Array::ZoneHandle(), 1);
942 AddInstruction(new DoInstr(store));
943 ReturnValue(new UseVal(placeholder));
944 }
945
946
947 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { 727 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) {
948 TestGraphVisitor for_test(owner(), 728 TestGraphVisitor for_test(owner(),
949 temp_index(), 729 temp_index(),
950 node->condition()->token_index()); 730 node->condition()->token_index());
951 node->condition()->Visit(&for_test); 731 node->condition()->Visit(&for_test);
952 732
953 // Translate the subexpressions for their effects. 733 // Translate the subexpressions for their effects.
954 EffectGraphVisitor for_true(owner(), temp_index()); 734 EffectGraphVisitor for_true(owner(), temp_index());
955 node->true_expr()->Visit(&for_true); 735 node->true_expr()->Visit(&for_true);
956 EffectGraphVisitor for_false(owner(), temp_index()); 736 EffectGraphVisitor for_false(owner(), temp_index());
(...skipping 1697 matching lines...) Expand 10 before | Expand all | Expand 10 after
2654 reverse_index(instr->false_successor()->postorder_number())); 2434 reverse_index(instr->false_successor()->postorder_number()));
2655 } 2435 }
2656 2436
2657 2437
2658 void FlowGraphBuilder::BuildGraph() { 2438 void FlowGraphBuilder::BuildGraph() {
2659 if (FLAG_print_ast) { 2439 if (FLAG_print_ast) {
2660 // Print the function ast before IL generation. 2440 // Print the function ast before IL generation.
2661 AstPrinter::PrintFunctionNodes(parsed_function()); 2441 AstPrinter::PrintFunctionNodes(parsed_function());
2662 } 2442 }
2663 TimerScope timer(FLAG_compiler_stats, &CompilerStats::graphbuilder_timer); 2443 TimerScope timer(FLAG_compiler_stats, &CompilerStats::graphbuilder_timer);
2444 // Compilation can be nested, preserve the computation-id.
2445 Isolate* isolate = Isolate::Current();
2446 const intptr_t prev_cid = isolate->computation_id();
2447 isolate->set_computation_id(0);
2664 const Function& function = parsed_function().function(); 2448 const Function& function = parsed_function().function();
2665 EffectGraphVisitor for_effect(this, 0); 2449 EffectGraphVisitor for_effect(this, 0);
2666 for_effect.AddInstruction(new TargetEntryInstr()); 2450 for_effect.AddInstruction(new TargetEntryInstr());
2667 parsed_function().node_sequence()->Visit(&for_effect); 2451 parsed_function().node_sequence()->Visit(&for_effect);
2668 // Check that the graph is properly terminated. 2452 // Check that the graph is properly terminated.
2669 ASSERT(!for_effect.is_open()); 2453 ASSERT(!for_effect.is_open());
2670 GrowableArray<intptr_t> parent; 2454 GrowableArray<intptr_t> parent;
2671 for (intptr_t i = 0; i < catch_entries_.length(); i++) { 2455 for (intptr_t i = 0; i < catch_entries_.length(); i++) {
2672 Instruction* entry = catch_entries_[i]; 2456 Instruction* entry = catch_entries_[i];
2673 entry->DiscoverBlocks(NULL, // Entry block predecessor. 2457 entry->DiscoverBlocks(NULL, // Entry block predecessor.
2674 &preorder_block_entries_, 2458 &preorder_block_entries_,
2675 &postorder_block_entries_, 2459 &postorder_block_entries_,
2676 &parent); 2460 &parent);
2677 ComputeDominators(&preorder_block_entries_, &parent); 2461 ComputeDominators(&preorder_block_entries_, &parent);
2678 } 2462 }
2679 if (for_effect.entry() != NULL) { 2463 if (for_effect.entry() != NULL) {
2680 // Perform a depth-first traversal of the graph to build preorder and 2464 // Perform a depth-first traversal of the graph to build preorder and
2681 // postorder block orders. 2465 // postorder block orders.
2682 for_effect.entry()->DiscoverBlocks(NULL, // Entry block predecessor. 2466 for_effect.entry()->DiscoverBlocks(NULL, // Entry block predecessor.
2683 &preorder_block_entries_, 2467 &preorder_block_entries_,
2684 &postorder_block_entries_, 2468 &postorder_block_entries_,
2685 &parent); 2469 &parent);
2686 ComputeDominators(&preorder_block_entries_, &parent); 2470 ComputeDominators(&preorder_block_entries_, &parent);
2687 } 2471 }
2472 isolate->set_computation_id(prev_cid);
2688 if (FLAG_print_flow_graph) { 2473 if (FLAG_print_flow_graph) {
2689 intptr_t length = postorder_block_entries_.length(); 2474 intptr_t length = postorder_block_entries_.length();
2690 GrowableArray<BlockEntryInstr*> reverse_postorder(length); 2475 GrowableArray<BlockEntryInstr*> reverse_postorder(length);
2691 for (intptr_t i = length - 1; i >= 0; --i) { 2476 for (intptr_t i = length - 1; i >= 0; --i) {
2692 reverse_postorder.Add(postorder_block_entries_[i]); 2477 reverse_postorder.Add(postorder_block_entries_[i]);
2693 } 2478 }
2694 FlowGraphPrinter printer(function, reverse_postorder); 2479 FlowGraphPrinter printer(function, reverse_postorder);
2695 printer.VisitBlocks(); 2480 printer.VisitBlocks();
2696 } 2481 }
2697 } 2482 }
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
2791 char* chars = reinterpret_cast<char*>( 2576 char* chars = reinterpret_cast<char*>(
2792 Isolate::Current()->current_zone()->Allocate(len)); 2577 Isolate::Current()->current_zone()->Allocate(len));
2793 OS::SNPrint(chars, len, kFormat, function_name, reason); 2578 OS::SNPrint(chars, len, kFormat, function_name, reason);
2794 const Error& error = Error::Handle( 2579 const Error& error = Error::Handle(
2795 LanguageError::New(String::Handle(String::New(chars)))); 2580 LanguageError::New(String::Handle(String::New(chars))));
2796 Isolate::Current()->long_jump_base()->Jump(1, error); 2581 Isolate::Current()->long_jump_base()->Jump(1, error);
2797 } 2582 }
2798 2583
2799 2584
2800 } // namespace dart 2585 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/opt_code_generator_ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698