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

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: rebased 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
« no previous file with comments | « runtime/vm/compiler.cc ('k') | runtime/vm/flow_graph_allocator.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/flow_graph.cc
===================================================================
--- runtime/vm/flow_graph.cc (revision 22613)
+++ 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)
@@ -328,8 +334,20 @@
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 a try{} block.
+ // This is a safe approximation and workaround to force insertion of
+ // phis for stores that appear non-live because of the way catch-blocks
+ // are connected to the graph: They normally are dominated by the
+ // try-entry, but are direct successors of the graph entry in our flow
+ // graph.
+ // TODO(fschneider): Improve this approximation by better modeling the
+ // actual data flow to reduce the number of redundant phis.
BitVector* kill = GetKillSet(block);
- kill->Intersect(GetLiveOutSet(block));
+ if (block->InsideTryBlock()) {
+ kill->SetAll();
+ } else {
+ kill->Intersect(GetLiveOutSet(block));
+ }
assigned_vars_.Add(kill);
}
@@ -378,6 +396,17 @@
BitVector* live_in = live_in_[i];
last_loads->Clear();
+ // There is an implicit use (load-local) of every local variable at each
+ // call inside a try{} block and every call has an implicit control-flow
+ // to the catch entry. As an approximation we mark all locals as live
+ // inside try{}.
+ // TODO(fschneider): Improve this approximation, since not all local
+ // variable stores actually reach a call.
+ if (block->InsideTryBlock()) {
+ live_in->SetAll();
+ continue;
+ }
+
// Iterate backwards starting at the last instruction.
for (BackwardInstructionIterator it(block); !it.Done(); it.Advance()) {
Instruction* current = it.Current();
@@ -617,8 +646,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 +681,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 +722,26 @@
if (phi != NULL) {
(*env)[i] = phi;
phi->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp.
+ if (block_entry->InsideTryBlock()) {
+ // This is a safe approximation. Inside try{} all locals are
+ // used at every call implicitly, so we mark all phis as live
+ // from the start.
+ // TODO(fschneider): Improve this approximation to eliminate
+ // more redundant phis.
+ phi->mark_alive();
+ live_phis->Add(phi);
+ }
}
}
}
+ } else if (block_entry->IsCatchBlockEntry()) {
+ // Add real definitions for all locals and parameters.
+ 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.
« no previous file with comments | « runtime/vm/compiler.cc ('k') | runtime/vm/flow_graph_allocator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698