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

Unified Diff: runtime/vm/intermediate_language.cc

Issue 11953076: Move code around in preparation for better inlining. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 11 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
« runtime/vm/flow_graph_builder.cc ('K') | « runtime/vm/intermediate_language.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/intermediate_language.cc
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index 744533dd5f3a94c32759ed41faeed6aea0185d34..c7f87b114db2ce32d8e57d52fefd61518ad38c7c 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -828,6 +828,74 @@ bool BlockEntryInstr::Dominates(BlockEntryInstr* other) const {
}
+// Helper to mutate the graph during inlining. This block should be
+// replaced with new_block as a predecessor of all of this block's
+// successors. For each successor, the predecessors will be reordered
+// to preserve block-order sorting of the predecessors as well as the
+// phis if the successor is a join.
+void BlockEntryInstr::ReplaceAsPredecessorWith(BlockEntryInstr* new_block) {
+ // Set the last instruction of the new block to that of the old block.
+ Instruction* last = last_instruction();
+ new_block->set_last_instruction(last);
+ // For each successor, update the predecessors.
+ for (intptr_t sidx = 0; sidx < last->SuccessorCount(); ++sidx) {
+ // If the successor is a target, update its predecessor.
+ TargetEntryInstr* target = last->SuccessorAt(sidx)->AsTargetEntry();
+ if (target != NULL) {
+ target->predecessor_ = new_block;
+ continue;
+ }
+ // If the successor is a join, update each predecessor and the phis.
+ JoinEntryInstr* join = last->SuccessorAt(sidx)->AsJoinEntry();
+ ASSERT(join != NULL);
+ // Find the old predecessor index.
+ intptr_t old_index = join->IndexOfPredecessor(this);
+ intptr_t pred_count = join->PredecessorCount();
+ ASSERT(old_index >= 0);
+ ASSERT(old_index < pred_count);
+ // Find the new predecessor index while reordering the predecessors.
+ intptr_t new_id = new_block->block_id();
+ intptr_t new_index = old_index;
+ if (block_id() < new_id) {
+ // Search upwards, bubbling down intermediate predecessors.
+ for (; new_index < pred_count - 1; ++new_index) {
+ if (join->predecessors_[new_index + 1]->block_id() > new_id) break;
+ join->predecessors_[new_index] = join->predecessors_[new_index + 1];
+ }
+ } else {
+ // Search downwards, bubbling up intermediate predecessors.
+ for (; new_index > 0; --new_index) {
+ if (join->predecessors_[new_index - 1]->block_id() < new_id) break;
+ join->predecessors_[new_index] = join->predecessors_[new_index - 1];
+ }
+ }
+ join->predecessors_[new_index] = new_block;
+ // If the new and old predecessor index match there is nothing to update.
+ if ((join->phis() == NULL) || (old_index == new_index)) return;
+ // Otherwise, reorder the predecessor uses in each phi.
+ for (intptr_t i = 0; i < join->phis()->length(); ++i) {
+ PhiInstr* phi = (*join->phis())[i];
+ if (phi == NULL) continue;
+ ASSERT(pred_count == phi->InputCount());
+ // Save the predecessor use.
+ Value* pred_use = phi->InputAt(old_index);
+ // Move uses between old and new.
+ intptr_t step = (old_index < new_index) ? 1 : -1;
+ for (intptr_t use_idx = old_index;
+ use_idx != new_index;
+ use_idx += step) {
+ Value* use = phi->InputAt(use_idx + step);
+ phi->SetInputAt(use_idx, use);
+ use->set_use_index(use_idx);
+ }
+ // Write the predecessor use.
+ phi->SetInputAt(new_index, pred_use);
+ pred_use->set_use_index(new_index);
+ }
+ }
+}
+
+
void JoinEntryInstr::InsertPhi(intptr_t var_index, intptr_t var_count) {
// Lazily initialize the array of phis.
// Currently, phis are stored in a sparse array that holds the phi
« runtime/vm/flow_graph_builder.cc ('K') | « runtime/vm/intermediate_language.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698