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

Unified Diff: runtime/vm/flow_graph_optimizer.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_optimizer.cc
===================================================================
--- runtime/vm/flow_graph_optimizer.cc (revision 22436)
+++ runtime/vm/flow_graph_optimizer.cc (working copy)
@@ -15,6 +15,7 @@
#include "vm/parser.h"
#include "vm/resolver.h"
#include "vm/scopes.h"
+#include "vm/stack_frame.h"
#include "vm/symbols.h"
namespace dart {
@@ -457,6 +458,14 @@
InsertConversionsFor(phi);
}
}
+ CatchBlockEntryInstr* catch_entry = entry->AsCatchBlockEntry();
+ if (catch_entry != NULL) {
+ for (intptr_t i = 0;
+ i < catch_entry->initial_definitions()->length();
+ i++) {
+ InsertConversionsFor((*catch_entry->initial_definitions())[i]);
+ }
+ }
for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
Definition* def = it.Current()->AsDefinition();
if (def != NULL) {
@@ -3136,6 +3145,68 @@
}
+void FlowGraphOptimizer::AnalyzeTryCatch() {
Kevin Millikin (Google) 2013/05/08 11:42:00 Doesn't need to be in the FlowGraphOptimizer, whic
Florian Schneider 2013/05/08 17:10:55 Done.
+ // For every catch-block: Iterate over all call instructions inside the
+ // corresponding try-block and figure out for each environment value if it
+ // is the same constant at all calls. If yes, replace the initial definition
+ // at the catch-entry with this constant.
+ const GrowableArray<CatchBlockEntryInstr*>& catch_entries =
+ flow_graph_->graph_entry()->catch_entries();
+ intptr_t nncp = flow_graph_->num_non_copied_params();
Kevin Millikin (Google) 2013/05/08 11:42:00 intptr_t base = kFirstLocalSlotIndex + flow_graph_
Florian Schneider 2013/05/08 17:10:55 Done.
+ for (intptr_t catch_idx = 0;
+ catch_idx < catch_entries.length();
+ ++catch_idx) {
+ CatchBlockEntryInstr* cb = catch_entries[catch_idx];
+ CatchEntryInstr* catch_entry = cb->next()->AsCatchEntry();
+ intptr_t ex_idx =
Kevin Millikin (Google) 2013/05/08 11:42:00 intptr_t ex_idx = base - catch_entry->exception_va
Florian Schneider 2013/05/08 17:10:55 Done.
+ kFirstLocalSlotIndex - catch_entry->exception_var().index() + nncp;
+ intptr_t st_idx =
+ kFirstLocalSlotIndex - catch_entry->stacktrace_var().index() + nncp;
+ GrowableArray<Definition*>* idefs = cb->initial_definitions();
+ GrowableArray<Definition*> cdefs(idefs->length());
+ cdefs.AddArray(*idefs);
+
+ for (BlockIterator block_it = flow_graph_->reverse_postorder_iterator();
Kevin Millikin (Google) 2013/05/08 11:42:00 This is doing constant analysis with the lattice:
Florian Schneider 2013/05/08 17:10:55 Done.
+ !block_it.Done();
+ block_it.Advance()) {
+ BlockEntryInstr* block = block_it.Current();
+ if (block->try_index() == cb->catch_try_index()) {
+ for (ForwardInstructionIterator instr_it(block);
+ !instr_it.Done();
+ instr_it.Advance()) {
+ Instruction* current = instr_it.Current();
+ if (current->MayThrow()) {
+ Environment* env = current->env();
+ for (intptr_t env_idx = 0; env_idx < cdefs.length(); ++env_idx) {
+ if (cdefs[env_idx] != NULL &&
+ cdefs[env_idx]->IsParameter() &&
+ cdefs[env_idx]->AsParameter()->index() != ex_idx &&
Kevin Millikin (Google) 2013/05/08 11:42:00 The intent is that ex_idx and st_idx are not const
Florian Schneider 2013/05/08 17:10:55 Done.
+ cdefs[env_idx]->AsParameter()->index() != st_idx &&
+ env->ValueAt(env_idx)->definition()->IsConstant()) {
Kevin Millikin (Google) 2013/05/08 11:42:00 I guess you can write this as env->ValueAt(env_idx
Florian Schneider 2013/05/08 17:10:55 Done.
+ cdefs[env_idx] = env->ValueAt(env_idx)->definition();
+ }
+ if (cdefs[env_idx] != env->ValueAt(env_idx)->definition()) {
+ cdefs[env_idx] = NULL;
+ }
+ }
+ }
+ }
+ }
+ }
+ for (intptr_t j = 0; j < idefs->length(); ++j) {
+ if (cdefs[j] != NULL && cdefs[j]->IsConstant()) {
+ Definition* old = (*idefs)[j];
+ ConstantInstr* orig = cdefs[j]->AsConstant();
+ ConstantInstr* copy = new ConstantInstr(orig->value());
Kevin Millikin (Google) 2013/05/08 11:42:00 Note that all constants are pooled now. I think y
Florian Schneider 2013/05/08 17:10:55 Yes. It should and make the code much simpler here
+ copy->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index());
+ old->ReplaceUsesWith(copy);
+ (*idefs)[j] = copy;
+ }
+ }
+ }
+}
+
+
static BlockEntryInstr* FindPreHeader(BlockEntryInstr* header) {
for (intptr_t j = 0; j < header->PredecessorCount(); ++j) {
BlockEntryInstr* candidate = header->PredecessorAt(j);
@@ -4398,7 +4469,9 @@
}
ASSERT(ForwardInstructionIterator(block).Done());
- SetReachable(block->normal_entry());
+ for (intptr_t i = 0; i < block->SuccessorCount(); ++i) {
+ SetReachable(block->SuccessorAt(i));
Kevin Millikin (Google) 2013/05/08 11:42:00 Hmm, this is a poor approximation. Can you add a
Florian Schneider 2013/05/08 17:10:55 Done.
+ }
}
@@ -4418,6 +4491,10 @@
void ConstantPropagator::VisitCatchBlockEntry(CatchBlockEntryInstr* block) {
+ const GrowableArray<Definition*>& defs = *block->initial_definitions();
+ for (intptr_t i = 0; i < defs.length(); ++i) {
+ defs[i]->Accept(this);
+ }
for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
it.Current()->Accept(this);
}
@@ -5224,12 +5301,16 @@
void ConstantPropagator::VisitBranches() {
GraphEntryInstr* entry = graph_->graph_entry();
reachable_->Add(entry->preorder_number());
- // TODO(fschneider): Handle CatchEntry.
- reachable_->Add(entry->normal_entry()->preorder_number());
- block_worklist_.Add(entry->normal_entry());
+ block_worklist_.Add(entry);
while (!block_worklist_.is_empty()) {
BlockEntryInstr* block = block_worklist_.RemoveLast();
+ if (block->IsGraphEntry()) {
+ for (intptr_t i = 0; i < block->SuccessorCount(); ++i) {
+ SetReachable(block->SuccessorAt(i));
+ }
+ continue;
+ }
Instruction* last = block->last_instruction();
if (last->IsGoto()) {
SetReachable(last->AsGoto()->successor());

Powered by Google App Engine
This is Rietveld 408576698