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

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

Issue 9719003: Compute preorder as well as postorder basic block orderings. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 9 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
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/globals.h" // Needed here to get TARGET_ARCH_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
7 7
8 #include "vm/flow_graph_compiler.h" 8 #include "vm/flow_graph_compiler.h"
9 9
10 #include "vm/ast_printer.h" 10 #include "vm/ast_printer.h"
11 #include "vm/code_generator.h" 11 #include "vm/code_generator.h"
12 #include "vm/disassembler.h" 12 #include "vm/disassembler.h"
13 #include "vm/longjump.h" 13 #include "vm/longjump.h"
14 #include "vm/object_store.h" 14 #include "vm/object_store.h"
15 #include "vm/parser.h" 15 #include "vm/parser.h"
16 #include "vm/stub_code.h" 16 #include "vm/stub_code.h"
17 17
18 namespace dart { 18 namespace dart {
19 19
20 DECLARE_FLAG(bool, print_ast); 20 DECLARE_FLAG(bool, print_ast);
21 DECLARE_FLAG(bool, print_scopes); 21 DECLARE_FLAG(bool, print_scopes);
22 DECLARE_FLAG(bool, trace_functions); 22 DECLARE_FLAG(bool, trace_functions);
23 23
24 FlowGraphCompiler::FlowGraphCompiler( 24 FlowGraphCompiler::FlowGraphCompiler(
25 Assembler* assembler, 25 Assembler* assembler,
26 const ParsedFunction& parsed_function, 26 const ParsedFunction& parsed_function,
27 const GrowableArray<BlockEntryInstr*>* blocks) 27 const GrowableArray<BlockEntryInstr*>& block_order)
28 : assembler_(assembler), 28 : FlowGraphVisitor(block_order),
29 assembler_(assembler),
29 parsed_function_(parsed_function), 30 parsed_function_(parsed_function),
30 blocks_(blocks), 31 block_info_(block_order.length()),
31 block_info_(blocks->length()),
32 current_block_(NULL), 32 current_block_(NULL),
33 pc_descriptors_list_(new CodeGenerator::DescriptorList()) { 33 pc_descriptors_list_(new CodeGenerator::DescriptorList()) {
34 for (int i = 0; i < blocks->length(); ++i) { 34 for (int i = 0; i < block_order.length(); ++i) {
35 block_info_.Add(new BlockInfo()); 35 block_info_.Add(new BlockInfo());
36 } 36 }
37 } 37 }
38 38
39 39
40 FlowGraphCompiler::~FlowGraphCompiler() { 40 FlowGraphCompiler::~FlowGraphCompiler() {
41 // BlockInfos are zone-allocated, so their destructors are not called. 41 // BlockInfos are zone-allocated, so their destructors are not called.
42 // Verify the labels explicitly here. 42 // Verify the labels explicitly here.
43 for (int i = 0; i < block_info_.length(); ++i) { 43 for (int i = 0; i < block_info_.length(); ++i) {
44 ASSERT(!block_info_[i]->label.IsLinked()); 44 ASSERT(!block_info_[i]->label.IsLinked());
(...skipping 678 matching lines...) Expand 10 before | Expand all | Expand 10 after
723 // instantiated type arguments, reset instantiator to null. 723 // instantiated type arguments, reset instantiator to null.
724 __ movq(RAX, raw_null); // Null instantiator. 724 __ movq(RAX, raw_null); // Null instantiator.
725 __ Bind(&use_instantiator); // Use instantiator in RAX. 725 __ Bind(&use_instantiator); // Use instantiator in RAX.
726 } 726 }
727 // In the non-factory case, we rely on the allocation stub to 727 // In the non-factory case, we rely on the allocation stub to
728 // instantiate the type arguments. 728 // instantiate the type arguments.
729 // RAX: instantiator or null. 729 // RAX: instantiator or null.
730 } 730 }
731 731
732 732
733 void FlowGraphCompiler::VisitBlocks( 733 void FlowGraphCompiler::VisitBlocks() {
734 const GrowableArray<BlockEntryInstr*>& blocks) { 734 for (intptr_t i = 0; i < block_order_.length(); ++i) {
735 for (intptr_t i = blocks.length() - 1; i >= 0; --i) {
736 // Compile the block entry. 735 // Compile the block entry.
737 current_block_ = blocks[i]; 736 current_block_ = block_order_[i];
738 Instruction* instr = current_block()->Accept(this); 737 Instruction* instr = current_block()->Accept(this);
739 // Compile all successors until an exit, branch, or a block entry. 738 // Compile all successors until an exit, branch, or a block entry.
740 while ((instr != NULL) && !instr->IsBlockEntry()) { 739 while ((instr != NULL) && !instr->IsBlockEntry()) {
741 instr = instr->Accept(this); 740 instr = instr->Accept(this);
742 } 741 }
743 742
744 BlockEntryInstr* successor = 743 BlockEntryInstr* successor =
745 (instr == NULL) ? NULL : instr->AsBlockEntry(); 744 (instr == NULL) ? NULL : instr->AsBlockEntry();
746 if (successor != NULL) { 745 if (successor != NULL) {
747 // Block ended with a "goto". We can fall through if it is the 746 // Block ended with a "goto". We can fall through if it is the
748 // next block in the list. Otherwise, we need a jump. 747 // next block in the list. Otherwise, we need a jump.
749 if (i == 0 || (blocks[i - 1] != successor)) { 748 if ((i == block_order_.length() - 1) ||
750 __ jmp(&block_info_[successor->block_number()]->label); 749 (block_order_[i + 1] != successor)) {
750 __ jmp(&block_info_[successor->postorder_number()]->label);
751 } 751 }
752 } 752 }
753 } 753 }
754 } 754 }
755 755
756 756
757 void FlowGraphCompiler::VisitJoinEntry(JoinEntryInstr* instr) { 757 void FlowGraphCompiler::VisitJoinEntry(JoinEntryInstr* instr) {
758 __ Bind(&block_info_[instr->block_number()]->label); 758 __ Bind(&block_info_[instr->postorder_number()]->label);
759 } 759 }
760 760
761 761
762 void FlowGraphCompiler::VisitTargetEntry(TargetEntryInstr* instr) { 762 void FlowGraphCompiler::VisitTargetEntry(TargetEntryInstr* instr) {
763 __ Bind(&block_info_[instr->block_number()]->label); 763 __ Bind(&block_info_[instr->postorder_number()]->label);
764 } 764 }
765 765
766 766
767 void FlowGraphCompiler::VisitPickTemp(PickTempInstr* instr) { 767 void FlowGraphCompiler::VisitPickTemp(PickTempInstr* instr) {
768 // Semantics is to copy a stack-allocated temporary to the top of stack. 768 // Semantics is to copy a stack-allocated temporary to the top of stack.
769 // Destination index d is assumed the new top of stack after the 769 // Destination index d is assumed the new top of stack after the
770 // operation, so d-1 is the current top of stack and so d-s-1 is the 770 // operation, so d-1 is the current top of stack and so d-s-1 is the
771 // offset to source index s. 771 // offset to source index s.
772 intptr_t offset = instr->destination() - instr->source() - 1; 772 intptr_t offset = instr->destination() - instr->source() - 1;
773 ASSERT(offset >= 0); 773 ASSERT(offset >= 0);
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
860 GenerateCallRuntime( 860 GenerateCallRuntime(
861 instr->node_id(), instr->token_index(), kReThrowRuntimeEntry); 861 instr->node_id(), instr->token_index(), kReThrowRuntimeEntry);
862 Bailout("ReThrow Untested"); 862 Bailout("ReThrow Untested");
863 } 863 }
864 864
865 865
866 866
867 void FlowGraphCompiler::VisitBranch(BranchInstr* instr) { 867 void FlowGraphCompiler::VisitBranch(BranchInstr* instr) {
868 // Determine if the true branch is fall through (!negated) or the false 868 // Determine if the true branch is fall through (!negated) or the false
869 // branch is. They cannot both be backwards branches. 869 // branch is. They cannot both be backwards branches.
870 intptr_t index = blocks_->length() - current_block()->block_number() - 1; 870 intptr_t index = reverse_index(current_block()->postorder_number());
871 ASSERT(index > 0); 871 bool negated = (block_order_[index + 1] == instr->false_successor());
872 872 ASSERT(!negated == (block_order_[index + 1] == instr->true_successor()));
873 bool negated = ((*blocks_)[index - 1] == instr->false_successor());
874 ASSERT(!negated == ((*blocks_)[index - 1] == instr->true_successor()));
875 873
876 LoadValue(RAX, instr->value()); 874 LoadValue(RAX, instr->value());
877 __ LoadObject(RDX, Bool::ZoneHandle(Bool::True())); 875 __ LoadObject(RDX, Bool::ZoneHandle(Bool::True()));
878 __ cmpq(RAX, RDX); 876 __ cmpq(RAX, RDX);
879 if (negated) { 877 if (negated) {
880 __ j(EQUAL, &block_info_[instr->true_successor()->block_number()]->label); 878 intptr_t target_index = instr->true_successor()->postorder_number();
879 __ j(EQUAL, &block_info_[target_index]->label);
881 } else { 880 } else {
882 __ j(NOT_EQUAL, 881 intptr_t target_index = instr->false_successor()->postorder_number();
883 &block_info_[instr->false_successor()->block_number()]->label); 882 __ j(NOT_EQUAL, &block_info_[target_index]->label);
884 } 883 }
885 } 884 }
886 885
887 886
888 // Coped from CodeGenerator::CopyParameters (CodeGenerator will be deprecated). 887 // Coped from CodeGenerator::CopyParameters (CodeGenerator will be deprecated).
889 void FlowGraphCompiler::CopyParameters() { 888 void FlowGraphCompiler::CopyParameters() {
890 const Function& function = parsed_function_.function(); 889 const Function& function = parsed_function_.function();
891 LocalScope* scope = parsed_function_.node_sequence()->scope(); 890 LocalScope* scope = parsed_function_.node_sequence()->scope();
892 const int num_fixed_params = function.num_fixed_parameters(); 891 const int num_fixed_params = function.num_fixed_parameters();
893 const int num_opt_params = function.num_optional_parameters(); 892 const int num_opt_params = function.num_optional_parameters();
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
1129 if (FLAG_print_scopes) { 1128 if (FLAG_print_scopes) {
1130 // Print the function scope (again) after generating the prologue in order 1129 // Print the function scope (again) after generating the prologue in order
1131 // to see annotations such as allocation indices of locals. 1130 // to see annotations such as allocation indices of locals.
1132 if (FLAG_print_ast) { 1131 if (FLAG_print_ast) {
1133 // Second printing. 1132 // Second printing.
1134 OS::Print("Annotated "); 1133 OS::Print("Annotated ");
1135 } 1134 }
1136 AstPrinter::PrintFunctionScope(parsed_function_); 1135 AstPrinter::PrintFunctionScope(parsed_function_);
1137 } 1136 }
1138 1137
1139 VisitBlocks(*blocks_); 1138 VisitBlocks();
1140 1139
1141 __ int3(); 1140 __ int3();
1142 // Emit function patching code. This will be swapped with the first 13 bytes 1141 // Emit function patching code. This will be swapped with the first 13 bytes
1143 // at entry point. 1142 // at entry point.
1144 pc_descriptors_list_->AddDescriptor(PcDescriptors::kPatchCode, 1143 pc_descriptors_list_->AddDescriptor(PcDescriptors::kPatchCode,
1145 assembler_->CodeSize(), 1144 assembler_->CodeSize(),
1146 AstNode::kNoId, 1145 AstNode::kNoId,
1147 0, 1146 0,
1148 -1); 1147 -1);
1149 __ jmp(&StubCode::FixCallersTargetLabel()); 1148 __ jmp(&StubCode::FixCallersTargetLabel());
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1198 void FlowGraphCompiler::FinalizeExceptionHandlers(const Code& code) { 1197 void FlowGraphCompiler::FinalizeExceptionHandlers(const Code& code) {
1199 // We don't compile exception handlers yet. 1198 // We don't compile exception handlers yet.
1200 code.set_exception_handlers( 1199 code.set_exception_handlers(
1201 ExceptionHandlers::Handle(ExceptionHandlers::New(0))); 1200 ExceptionHandlers::Handle(ExceptionHandlers::New(0)));
1202 } 1201 }
1203 1202
1204 1203
1205 } // namespace dart 1204 } // namespace dart
1206 1205
1207 #endif // defined TARGET_ARCH_X64 1206 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698