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

Unified Diff: runtime/vm/flow_graph_compiler.cc

Issue 12412013: Add pass to remove empty blocks and recompute fall-through targets. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 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 side-by-side diff with in-line comments
Download patch
Index: runtime/vm/flow_graph_compiler.cc
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index dc6d4ab6fd05a90277b492870f6ac88258f51c90..d248a9aa863dc43d90bb50c1d56764c8fded1ccc 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -209,12 +209,62 @@ bool FlowGraphCompiler::CanOptimizeFunction() const {
}
+static bool IsEmptyBlock(BlockEntryInstr* block) {
+ return !block->HasParallelMove() &&
+ block->next()->IsGoto() &&
+ !block->next()->AsGoto()->HasParallelMove();
+}
+
+
+void FlowGraphCompiler::CompactBlock(BlockEntryInstr* block) {
+ BlockInfo* block_info = block_info_[block->postorder_number()];
+
+ if (block_info->is_marked()) {
+ return;
+ }
+ block_info->mark();
+
+ if (IsEmptyBlock(block)) {
+ BlockEntryInstr* target = block->next()->AsGoto()->successor();
+ CompactBlock(target);
+ block_info->set_jump_label(GetJumpLabel(target));
+ }
+}
+
+
+void FlowGraphCompiler::CompactBlocks() {
+ Label* fallthrough_label = NULL;
+ for (intptr_t i = block_order().length() - 1; i >= 1; --i) {
+ BlockEntryInstr* block = block_order()[i];
+
+ CompactBlock(block);
+
+ if (!WasCompacted(block)) {
+ BlockInfo* block_info = block_info_[block->postorder_number()];
+ block_info->set_fallthrough_label(fallthrough_label);
+ fallthrough_label = GetJumpLabel(block);
+ }
+ }
+
+ ASSERT(block_order()[0]->IsGraphEntry());
+ BlockInfo* block_info = block_info_[block_order()[0]->postorder_number()];
+ block_info->set_fallthrough_label(fallthrough_label);
+}
+
+
void FlowGraphCompiler::VisitBlocks() {
+ CompactBlocks();
+
for (intptr_t i = 0; i < block_order().length(); ++i) {
// Compile the block entry.
BlockEntryInstr* entry = block_order()[i];
assembler()->Comment("B%"Pd"", entry->block_id());
set_current_block(entry);
+
+ if (WasCompacted(entry)) {
+ continue;
+ }
+
entry->PrepareEntry(this);
// Compile all successors until an exit, branch, or a block entry.
for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
@@ -259,17 +309,24 @@ intptr_t FlowGraphCompiler::StackSize() const {
}
-Label* FlowGraphCompiler::GetBlockLabel(
+Label* FlowGraphCompiler::GetJumpLabel(
+ BlockEntryInstr* block_entry) const {
+ const intptr_t block_index = block_entry->postorder_number();
+ return block_info_[block_index]->jump_label();
+}
+
+
+bool FlowGraphCompiler::WasCompacted(
BlockEntryInstr* block_entry) const {
- intptr_t block_index = block_entry->postorder_number();
- return &block_info_[block_index]->label;
+ const intptr_t block_index = block_entry->postorder_number();
+ return block_info_[block_index]->WasCompacted();
}
-bool FlowGraphCompiler::IsNextBlock(BlockEntryInstr* block_entry) const {
- intptr_t current_index = reverse_index(current_block()->postorder_number());
- return (current_index < (block_order().length() - 1)) &&
- (block_order()[current_index + 1] == block_entry);
+bool FlowGraphCompiler::CanFallThroughTo(BlockEntryInstr* block_entry) const {
+ const intptr_t current_index = current_block()->postorder_number();
+ Label* fallthrough_label = block_info_[current_index]->fallthrough_label();
+ return fallthrough_label == GetJumpLabel(block_entry);
}

Powered by Google App Engine
This is Rietveld 408576698