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

Unified Diff: runtime/vm/flow_graph.cc

Issue 14682020: Optimize functions containing try-catch. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: addressed Srdjan's comments Created 7 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 side-by-side diff with in-line comments
Download patch
Index: runtime/vm/flow_graph.cc
===================================================================
--- runtime/vm/flow_graph.cc (revision 22436)
+++ runtime/vm/flow_graph.cc (working copy)
@@ -15,6 +15,12 @@
DECLARE_FLAG(bool, trace_optimization);
DECLARE_FLAG(bool, verify_compiler);
+#if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_MIPS)
+DEFINE_FLAG(bool, optimize_try_catch, false, "Optimization of try-catch");
+#else
+DEFINE_FLAG(bool, optimize_try_catch, true, "Optimization of try-catch");
+#endif
+
FlowGraph::FlowGraph(const FlowGraphBuilder& builder,
GraphEntryInstr* graph_entry,
intptr_t max_block_id)
@@ -327,8 +333,13 @@
const intptr_t block_count = flow_graph_->preorder().length();
for (intptr_t i = 0; i < block_count; i++) {
BlockEntryInstr* block = flow_graph_->preorder()[i];
+ // All locals are assigned inside try-catch.
Kevin Millikin (Google) 2013/05/08 11:42:00 Comment needs to say why. I don't understand why
Florian Schneider 2013/05/08 17:10:55 Done.
BitVector* kill = GetKillSet(block);
- kill->Intersect(GetLiveOutSet(block));
+ if (block->try_index() != CatchClauseNode::kInvalidTryIndex) {
+ kill->SetAll();
+ } else {
+ kill->Intersect(GetLiveOutSet(block));
+ }
assigned_vars_.Add(kill);
}
@@ -377,6 +388,12 @@
BitVector* live_in = live_in_[i];
last_loads->Clear();
+ // Inside try-catch all locals are live.
Kevin Millikin (Google) 2013/05/08 11:42:00 Again, I don't understand why. This is just for a
Florian Schneider 2013/05/08 17:10:55 Done.
+ if (block->try_index() != CatchClauseNode::kInvalidTryIndex) {
+ live_in->SetAll();
+ continue;
+ }
+
// Iterate backwards starting at the last instruction.
for (BackwardInstructionIterator it(block); !it.Done(); it.Advance()) {
Instruction* current = it.Current();
@@ -385,7 +402,7 @@
if (load != NULL) {
const intptr_t index = load->local().BitIndexIn(num_non_copied_params_);
live_in->Add(index);
- if (!last_loads->Contains(index)) {
+ if (!last_loads->Contains(index) && !load->local().always_live()) {
last_loads->Add(index);
load->mark_last();
}
@@ -393,7 +410,7 @@
}
StoreLocalInstr* store = current->AsStoreLocal();
- if (store != NULL) {
+ if (store != NULL && !store->local().always_live()) {
const intptr_t index =
store->local().BitIndexIn(num_non_copied_params_);
if (kill->Contains(index)) {
@@ -406,7 +423,9 @@
}
kill->Add(index);
}
- live_in->Remove(index);
+ if (block->try_index() == CatchClauseNode::kInvalidTryIndex) {
Kevin Millikin (Google) 2013/05/08 11:42:00 This comparison is always true. The loop is not e
Florian Schneider 2013/05/08 17:10:55 Done.
+ live_in->Remove(index);
+ }
continue;
}
}
@@ -616,8 +635,7 @@
void FlowGraph::Rename(GrowableArray<PhiInstr*>* live_phis,
VariableLivenessAnalysis* variable_liveness,
ZoneGrowableArray<Definition*>* inlining_parameters) {
- // TODO(fschneider): Support catch-entry.
- if (graph_entry_->SuccessorCount() > 1) {
+ if (!FLAG_optimize_try_catch && (graph_entry_->SuccessorCount() > 1)) {
Bailout("Catch-entry support in SSA.");
}
@@ -653,9 +671,14 @@
env.Add(constant_null());
}
- BlockEntryInstr* normal_entry = graph_entry_->SuccessorAt(0);
- ASSERT(normal_entry != NULL); // Must have entry.
- RenameRecursive(normal_entry, &env, live_phis, variable_liveness);
+ if (graph_entry_->SuccessorCount() > 1) {
+ // Functions with try-catch have a fixed area of stack slots reserved
+ // so that all local variables are stored at a known location when
+ // on entry to the catch.
+ graph_entry_->set_fixed_slot_count(
+ num_stack_locals() + num_copied_params());
+ }
+ RenameRecursive(graph_entry_, &env, live_phis, variable_liveness);
}
@@ -689,9 +712,22 @@
if (phi != NULL) {
(*env)[i] = phi;
phi->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp.
+ if (block_entry->try_index() != CatchClauseNode::kInvalidTryIndex) {
Kevin Millikin (Google) 2013/05/08 11:42:00 This comparison is repeated a lot in this change.
Florian Schneider 2013/05/08 17:10:55 Done.
+ phi->mark_alive();
+ live_phis->Add(phi);
+ }
}
}
}
+ } else if (block_entry->IsCatchBlockEntry()) {
+ // Add real definitions for all locals and parameters. The location of the
+ // parameters and locals is the same as at function entry.
Kevin Millikin (Google) 2013/05/08 11:42:00 I don't think this comment is quite correct. The
Florian Schneider 2013/05/08 17:10:55 Done.
+ for (intptr_t i = 0; i < env->length(); ++i) {
+ ParameterInstr* param = new ParameterInstr(i, block_entry);
+ param->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp.
+ (*env)[i] = param;
+ block_entry->AsCatchBlockEntry()->initial_definitions()->Add(param);
+ }
}
// Attach environment to the block entry.
@@ -750,7 +786,8 @@
index = store->local().BitIndexIn(num_non_copied_params_);
result = store->value()->definition();
- if (variable_liveness->IsStoreAlive(block_entry, store)) {
+ if (variable_liveness->IsStoreAlive(block_entry, store) ||
+ store->local().always_live()) {
Kevin Millikin (Google) 2013/05/08 11:42:00 Need to know why, also below. These are for the t
Florian Schneider 2013/05/08 17:10:55 Done. Not needed anymore.
(*env)[index] = result;
} else {
(*env)[index] = constant_null();
@@ -768,7 +805,8 @@
live_phis->Add(phi);
}
- if (variable_liveness->IsLastLoad(block_entry, load)) {
+ if (variable_liveness->IsLastLoad(block_entry, load) &&
+ !load->local().always_live()) {
Kevin Millikin (Google) 2013/05/08 11:42:00 Is this because there are implicit loads from the
Florian Schneider 2013/05/08 17:10:55 Done. Not needed anymore.
(*env)[index] = constant_null();
}
}

Powered by Google App Engine
This is Rietveld 408576698