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

Unified Diff: runtime/vm/flow_graph_optimizer.cc

Issue 10972003: Fix convergence issues in range analysis. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: address comments Created 8 years, 3 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/il_printer.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/flow_graph_optimizer.cc
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index 19326527499c6b7b14c5b908fade1a467b3aba19..0b4cbef7ad22f5a22d84e071237075c5a9813053 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -23,6 +23,7 @@ DEFINE_FLAG(bool, trace_optimization, false, "Print optimization details.");
DECLARE_FLAG(bool, trace_type_check_elimination);
DEFINE_FLAG(bool, use_cha, true, "Use class hierarchy analysis.");
DEFINE_FLAG(bool, load_cse, true, "Use redundant load elimination.");
+DEFINE_FLAG(bool, trace_range_analysis, false, "Trace range analysis progress");
void FlowGraphOptimizer::ApplyICData() {
VisitBlocks();
@@ -1239,6 +1240,8 @@ class RangeAnalysis : public ValueObject {
// Propagate range information until fix-point is reached.
void InferRanges();
+ void ProcessWorklist(Definition::RangeOperator op);
+
// Walk the dominator tree, initialize ranges for smi values and place them
// to the worklist.
void InitializeRangesRecursive(BlockEntryInstr* block);
@@ -1251,14 +1254,22 @@ class RangeAnalysis : public ValueObject {
void AddToWorklist(Definition* value) {
const intptr_t index = value->ssa_temp_index();
- if (!in_inactive_worklist_->Contains(index)) {
- in_inactive_worklist_->Add(index);
- inactive_worklist_->Add(value);
+ if (!in_worklist_->Contains(index)) {
+ in_worklist_->Add(index);
+ worklist_.Add(value);
}
}
bool IsWorklistEmpty() const {
- return active_worklist_->is_empty();
+ return worklist_.is_empty();
+ }
+
+ Definition* RemoveLastFromWorklist() {
+ Definition* defn = worklist_.Last();
+ worklist_.RemoveLast();
+ ASSERT(in_worklist_->Contains(defn->ssa_temp_index()));
+ in_worklist_->Remove(defn->ssa_temp_index());
+ return defn;
}
void SwapWorklists();
@@ -1275,10 +1286,9 @@ class RangeAnalysis : public ValueObject {
// Bitvector for a quick filtering of known smi values.
BitVector* smi_definitions_;
- // Worklists using during range propagation.
- ZoneGrowableArray<Definition*>* active_worklist_;
- ZoneGrowableArray<Definition*>* inactive_worklist_;
- BitVector* in_inactive_worklist_;
+ // Worklist used during range propagation.
+ GrowableArray<Definition*> worklist_;
+ BitVector* in_worklist_;
DISALLOW_COPY_AND_ASSIGN(RangeAnalysis);
};
@@ -1533,12 +1543,11 @@ void RangeAnalysis::InsertConstraints() {
void RangeAnalysis::InitializeRangesRecursive(BlockEntryInstr* block) {
JoinEntryInstr* join = block->AsJoinEntry();
- if ((join != NULL) && (join->phis() != NULL)) {
- for (intptr_t i = 0; i < join->phis()->length(); ++i) {
- PhiInstr* phi = (*join->phis())[i];
- if (phi == NULL) continue;
+ if (join != NULL) {
+ for (PhiIterator it(join); !it.Done(); it.Advance()) {
+ PhiInstr* phi = it.Current();
if (smi_definitions_->Contains(phi->ssa_temp_index())) {
- phi->InferRange();
+ phi->InferRange(Definition::kRangeInit);
AddToWorklist(phi);
}
}
@@ -1549,7 +1558,7 @@ void RangeAnalysis::InitializeRangesRecursive(BlockEntryInstr* block) {
if ((defn != NULL) &&
(defn->ssa_temp_index() != -1) &&
smi_definitions_->Contains(defn->ssa_temp_index())) {
- defn->InferRange();
+ defn->InferRange(Definition::kRangeInit);
AddToWorklist(defn);
}
}
@@ -1561,19 +1570,36 @@ void RangeAnalysis::InitializeRangesRecursive(BlockEntryInstr* block) {
void RangeAnalysis::CreateWorklists() {
- active_worklist_ = new ZoneGrowableArray<Definition*>(10);
- inactive_worklist_ = new ZoneGrowableArray<Definition*>(10);
- in_inactive_worklist_ = new BitVector(
- flow_graph_->current_ssa_temp_index());
+ in_worklist_ = new BitVector(flow_graph_->current_ssa_temp_index());
}
-void RangeAnalysis::SwapWorklists() {
- ZoneGrowableArray<Definition*>* temp = active_worklist_;
- active_worklist_ = inactive_worklist_;
- inactive_worklist_ = temp;
- inactive_worklist_->Clear();
- in_inactive_worklist_->Clear();
+void RangeAnalysis::ProcessWorklist(Definition::RangeOperator op) {
+ // Iterate until fix point is reached.
+ while (!IsWorklistEmpty()) {
+ Definition* defn = RemoveLastFromWorklist();
+ if (FLAG_trace_range_analysis) {
+ OS::Print("infering range for v%"Pd" %s\n",
+ defn->ssa_temp_index(),
+ Range::ToCString(defn->range()));
+ }
+ if (defn->InferRange(op)) { // Update the range.
+ if (FLAG_trace_range_analysis) {
+ OS::Print(" changed to %s\n", Range::ToCString(defn->range()));
+ }
+ // Range change. Place all uses to the worklist.
+ for (Value* use = defn->input_use_list();
+ use != NULL;
+ use = use->next_use()) {
+ Definition* use_defn = use->instruction()->AsDefinition();
+ if ((use_defn != NULL) &&
+ (use_defn->ssa_temp_index() != -1) &&
+ smi_definitions_->Contains(use_defn->ssa_temp_index())) {
+ AddToWorklist(use_defn);
+ }
+ }
+ }
+ }
}
@@ -1592,31 +1618,54 @@ void RangeAnalysis::InferRanges() {
// Infer initial values of ranges.
InitializeRangesRecursive(flow_graph_->graph_entry());
- // Active worklist is empty, inactive now contains all smi values.
- SwapWorklists();
-
- // Iterate until fix point is reached.
- while (!IsWorklistEmpty()) {
- for (intptr_t i = 0; i < active_worklist_->length(); i++) {
- Definition* defn = (*active_worklist_)[i];
- if (defn->InferRange()) { // Update the range.
- // Range change. Place all uses to the worklist.
- for (Value* use = defn->input_use_list();
- use != NULL;
- use = use->next_use()) {
- Definition* use_defn = use->instruction()->AsDefinition();
- if ((use_defn != NULL) &&
- (use_defn->ssa_temp_index() != -1) &&
- smi_definitions_->Contains(use_defn->ssa_temp_index())) {
- AddToWorklist(use_defn);
- }
+ for (intptr_t i = 0; i < smi_values_.length(); i++) {
+ if (smi_values_[i]->IsPhi() &&
+ smi_values_[i]->InferRange(Definition::kRangeInit)) {
+ Definition* defn = smi_values_[i];
+ for (Value* use = defn->input_use_list();
+ use != NULL;
+ use = use->next_use()) {
+ Definition* use_defn = use->instruction()->AsDefinition();
+ if ((use_defn != NULL) &&
+ (use_defn->ssa_temp_index() != -1) &&
+ smi_definitions_->Contains(use_defn->ssa_temp_index())) {
+ AddToWorklist(use_defn);
}
}
}
+ }
+
+ if (FLAG_trace_range_analysis) {
+ OS::Print("---- after initialization -------\n");
+ FlowGraphPrinter printer(*flow_graph_);
+ printer.PrintBlocks();
+ }
+
+ if (FLAG_trace_range_analysis) {
+ OS::Print("---- widening ---------\n");
+ }
+ ProcessWorklist(Definition::kRangeWiden);
+
+ if (FLAG_trace_range_analysis) {
+ OS::Print("---- after widening -------\n");
+ FlowGraphPrinter printer(*flow_graph_);
+ printer.PrintBlocks();
+ }
+
+ if (FLAG_trace_range_analysis) {
+ OS::Print("---- narrowing ---------\n");
+ }
+ // Only phis can change under narrowing operator. Place all phis
+ // into the worklist.
+ for (intptr_t i = 0; i < smi_values_.length(); i++) {
+ if (smi_values_[i]->IsPhi()) AddToWorklist(smi_values_[i]);
+ }
+ ProcessWorklist(Definition::kRangeNarrow);
- // Active worklist has been processed. Inactive contains all values which
- // can be affected by changed ranges.
- SwapWorklists();
+ if (FLAG_trace_range_analysis) {
+ OS::Print("---- after narrowing -------\n");
+ FlowGraphPrinter printer(*flow_graph_);
+ printer.PrintBlocks();
}
}
« no previous file with comments | « runtime/vm/compiler.cc ('k') | runtime/vm/il_printer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698