| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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_XXX. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_XXX. |
| 6 | 6 |
| 7 #include "vm/flow_graph_compiler.h" | 7 #include "vm/flow_graph_compiler.h" |
| 8 | 8 |
| 9 #include "vm/cha.h" | 9 #include "vm/cha.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 202 return !FLAG_report_usage_count && | 202 return !FLAG_report_usage_count && |
| 203 (FLAG_optimization_counter_threshold >= 0); | 203 (FLAG_optimization_counter_threshold >= 0); |
| 204 } | 204 } |
| 205 | 205 |
| 206 | 206 |
| 207 bool FlowGraphCompiler::CanOptimizeFunction() const { | 207 bool FlowGraphCompiler::CanOptimizeFunction() const { |
| 208 return CanOptimize() && !parsed_function().function().HasBreakpoint(); | 208 return CanOptimize() && !parsed_function().function().HasBreakpoint(); |
| 209 } | 209 } |
| 210 | 210 |
| 211 | 211 |
| 212 static bool IsEmptyBlock(BlockEntryInstr* block) { |
| 213 return !block->HasParallelMove() && |
| 214 block->next()->IsGoto() && |
| 215 !block->next()->AsGoto()->HasParallelMove(); |
| 216 } |
| 217 |
| 218 |
| 219 void FlowGraphCompiler::CompactBlock(BlockEntryInstr* block) { |
| 220 BlockInfo* block_info = block_info_[block->postorder_number()]; |
| 221 |
| 222 if (block_info->is_marked()) { |
| 223 return; |
| 224 } |
| 225 block_info->mark(); |
| 226 |
| 227 if (IsEmptyBlock(block)) { |
| 228 BlockEntryInstr* target = block->next()->AsGoto()->successor(); |
| 229 CompactBlock(target); |
| 230 block_info->set_jump_label(GetJumpLabel(target)); |
| 231 } |
| 232 } |
| 233 |
| 234 |
| 235 void FlowGraphCompiler::CompactBlocks() { |
| 236 Label* fallthrough_label = NULL; |
| 237 for (intptr_t i = block_order().length() - 1; i >= 1; --i) { |
| 238 BlockEntryInstr* block = block_order()[i]; |
| 239 |
| 240 CompactBlock(block); |
| 241 |
| 242 if (!WasCompacted(block)) { |
| 243 BlockInfo* block_info = block_info_[block->postorder_number()]; |
| 244 block_info->set_fallthrough_label(fallthrough_label); |
| 245 fallthrough_label = GetJumpLabel(block); |
| 246 } |
| 247 } |
| 248 |
| 249 ASSERT(block_order()[0]->IsGraphEntry()); |
| 250 BlockInfo* block_info = block_info_[block_order()[0]->postorder_number()]; |
| 251 block_info->set_fallthrough_label(fallthrough_label); |
| 252 } |
| 253 |
| 254 |
| 212 void FlowGraphCompiler::VisitBlocks() { | 255 void FlowGraphCompiler::VisitBlocks() { |
| 256 CompactBlocks(); |
| 257 |
| 213 for (intptr_t i = 0; i < block_order().length(); ++i) { | 258 for (intptr_t i = 0; i < block_order().length(); ++i) { |
| 214 // Compile the block entry. | 259 // Compile the block entry. |
| 215 BlockEntryInstr* entry = block_order()[i]; | 260 BlockEntryInstr* entry = block_order()[i]; |
| 216 assembler()->Comment("B%"Pd"", entry->block_id()); | 261 assembler()->Comment("B%"Pd"", entry->block_id()); |
| 217 set_current_block(entry); | 262 set_current_block(entry); |
| 263 |
| 264 if (WasCompacted(entry)) { |
| 265 continue; |
| 266 } |
| 267 |
| 218 entry->PrepareEntry(this); | 268 entry->PrepareEntry(this); |
| 219 // Compile all successors until an exit, branch, or a block entry. | 269 // Compile all successors until an exit, branch, or a block entry. |
| 220 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { | 270 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { |
| 221 Instruction* instr = it.Current(); | 271 Instruction* instr = it.Current(); |
| 222 if (FLAG_code_comments) EmitComment(instr); | 272 if (FLAG_code_comments) EmitComment(instr); |
| 223 if (instr->IsParallelMove()) { | 273 if (instr->IsParallelMove()) { |
| 224 parallel_move_resolver_.EmitNativeCode(instr->AsParallelMove()); | 274 parallel_move_resolver_.EmitNativeCode(instr->AsParallelMove()); |
| 225 } else { | 275 } else { |
| 226 ASSERT(instr->locs() != NULL); | 276 ASSERT(instr->locs() != NULL); |
| 227 EmitInstructionPrologue(instr); | 277 EmitInstructionPrologue(instr); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 252 intptr_t FlowGraphCompiler::StackSize() const { | 302 intptr_t FlowGraphCompiler::StackSize() const { |
| 253 if (is_optimizing_) { | 303 if (is_optimizing_) { |
| 254 return block_order_[0]->AsGraphEntry()->spill_slot_count(); | 304 return block_order_[0]->AsGraphEntry()->spill_slot_count(); |
| 255 } else { | 305 } else { |
| 256 return parsed_function_.num_stack_locals() + | 306 return parsed_function_.num_stack_locals() + |
| 257 parsed_function_.num_copied_params(); | 307 parsed_function_.num_copied_params(); |
| 258 } | 308 } |
| 259 } | 309 } |
| 260 | 310 |
| 261 | 311 |
| 262 Label* FlowGraphCompiler::GetBlockLabel( | 312 Label* FlowGraphCompiler::GetJumpLabel( |
| 263 BlockEntryInstr* block_entry) const { | 313 BlockEntryInstr* block_entry) const { |
| 264 intptr_t block_index = block_entry->postorder_number(); | 314 const intptr_t block_index = block_entry->postorder_number(); |
| 265 return &block_info_[block_index]->label; | 315 return block_info_[block_index]->jump_label(); |
| 266 } | 316 } |
| 267 | 317 |
| 268 | 318 |
| 269 bool FlowGraphCompiler::IsNextBlock(BlockEntryInstr* block_entry) const { | 319 bool FlowGraphCompiler::WasCompacted( |
| 270 intptr_t current_index = reverse_index(current_block()->postorder_number()); | 320 BlockEntryInstr* block_entry) const { |
| 271 return (current_index < (block_order().length() - 1)) && | 321 const intptr_t block_index = block_entry->postorder_number(); |
| 272 (block_order()[current_index + 1] == block_entry); | 322 return block_info_[block_index]->WasCompacted(); |
| 273 } | 323 } |
| 274 | 324 |
| 275 | 325 |
| 326 bool FlowGraphCompiler::CanFallThroughTo(BlockEntryInstr* block_entry) const { |
| 327 const intptr_t current_index = current_block()->postorder_number(); |
| 328 Label* fallthrough_label = block_info_[current_index]->fallthrough_label(); |
| 329 return fallthrough_label == GetJumpLabel(block_entry); |
| 330 } |
| 331 |
| 332 |
| 276 void FlowGraphCompiler::AddSlowPathCode(SlowPathCode* code) { | 333 void FlowGraphCompiler::AddSlowPathCode(SlowPathCode* code) { |
| 277 slow_path_code_.Add(code); | 334 slow_path_code_.Add(code); |
| 278 } | 335 } |
| 279 | 336 |
| 280 | 337 |
| 281 void FlowGraphCompiler::GenerateDeferredCode() { | 338 void FlowGraphCompiler::GenerateDeferredCode() { |
| 282 for (intptr_t i = 0; i < slow_path_code_.length(); i++) { | 339 for (intptr_t i = 0; i < slow_path_code_.length(); i++) { |
| 283 slow_path_code_[i]->EmitNativeCode(this); | 340 slow_path_code_[i]->EmitNativeCode(this); |
| 284 } | 341 } |
| 285 for (intptr_t i = 0; i < deopt_infos_.length(); i++) { | 342 for (intptr_t i = 0; i < deopt_infos_.length(); i++) { |
| (...skipping 722 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1008 if (i != largest_ix) { | 1065 if (i != largest_ix) { |
| 1009 // Swap. | 1066 // Swap. |
| 1010 CidTarget temp = (*sorted)[i]; | 1067 CidTarget temp = (*sorted)[i]; |
| 1011 (*sorted)[i] = (*sorted)[largest_ix]; | 1068 (*sorted)[i] = (*sorted)[largest_ix]; |
| 1012 (*sorted)[largest_ix] = temp; | 1069 (*sorted)[largest_ix] = temp; |
| 1013 } | 1070 } |
| 1014 } | 1071 } |
| 1015 } | 1072 } |
| 1016 | 1073 |
| 1017 } // namespace dart | 1074 } // namespace dart |
| OLD | NEW |