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

Unified Diff: runtime/vm/flow_graph_optimizer.cc

Issue 10915234: Mark phi as producing a smi value if it is dominated by SmiChecks over its operands. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Improve handling of phi-cycles. 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/flow_graph_optimizer.h ('k') | runtime/vm/intermediate_language.h » ('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 e4dce9113c85a607eab1313b2787543a6299e4cb..0403b8416396b1cf47a06f13375d3d58ae13d8b2 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -993,6 +993,142 @@ void FlowGraphOptimizer::VisitBranch(BranchInstr* instr) {
}
+// SminessPropagator ensures that CheckSmis are eliminated across phis.
+class SminessPropagator {
+ public:
+ explicit SminessPropagator(FlowGraph* flow_graph)
+ : flow_graph_(flow_graph),
+ known_smis_(new BitVector(flow_graph_->current_ssa_temp_index())),
+ rollback_checks_(10),
+ in_worklist_(NULL),
+ worklist_(0) { }
+
+ void Propagate();
+
+ private:
+ void PropagateSminessRecursive(BlockEntryInstr* block);
+ void AddToWorklist(PhiInstr* phi);
+ PhiInstr* RemoveLastFromWorklist();
+ void ProcessPhis();
+
+ FlowGraph* flow_graph_;
+
+ BitVector* known_smis_;
+ GrowableArray<intptr_t> rollback_checks_;
+
+ BitVector* in_worklist_;
+ GrowableArray<PhiInstr*> worklist_;
+};
+
+
+void SminessPropagator::AddToWorklist(PhiInstr* phi) {
+ if (in_worklist_ == NULL) {
+ in_worklist_ = new BitVector(flow_graph_->current_ssa_temp_index());
+ }
+ if (!in_worklist_->Contains(phi->ssa_temp_index())) {
+ in_worklist_->Add(phi->ssa_temp_index());
+ worklist_.Add(phi);
+ }
+}
+
+
+PhiInstr* SminessPropagator::RemoveLastFromWorklist() {
+ PhiInstr* phi = worklist_.Last();
+ worklist_.RemoveLast();
Florian Schneider 2012/09/12 17:13:11 Add ASSERT(in_worklist_->Contains(phi->ssa_temp_in
+ in_worklist_->Remove(phi->ssa_temp_index());
+ return phi;
+}
+
+
+static bool IsSmiPhi(PhiInstr* phi) {
+ for (intptr_t i = 0; i < phi->InputCount(); i++) {
+ Value* input = phi->InputAt(i);
+ if ((input->definition() != phi) &&
+ (input->ResultCid() != kSmiCid)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+
+void SminessPropagator::ProcessPhis() {
+ while (!worklist_.is_empty()) {
+ PhiInstr* phi = RemoveLastFromWorklist();
+ if (IsSmiPhi(phi)) {
Florian Schneider 2012/09/12 17:13:11 Maybe assert ASSERT(phi->GetPropagatedCid() != kS
+ phi->SetPropagatedCid(kSmiCid);
+ for (Value* use = phi->input_use_list();
+ use != NULL;
+ use = use->next_use()) {
+ if (use->definition()->IsPhi() &&
+ (use->definition()->GetPropagatedCid() != kSmiCid)) {
+ AddToWorklist(use->definition()->AsPhi());
+ }
+ }
+ }
+ }
+}
+
+
+void SminessPropagator::PropagateSminessRecursive(BlockEntryInstr* block) {
+ const intptr_t rollback_point = rollback_checks_.length();
+
+ for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
+ Instruction* instr = it.Current();
+ if (instr->IsCheckSmi()) {
+ const intptr_t value_ssa_index =
+ instr->InputAt(0)->definition()->ssa_temp_index();
+ if (!known_smis_->Contains(value_ssa_index)) {
+ known_smis_->Add(value_ssa_index);
+ rollback_checks_.Add(value_ssa_index);
+ }
+ }
+ }
+
+ for (intptr_t i = 0; i < block->dominated_blocks().length(); ++i) {
+ PropagateSminessRecursive(block->dominated_blocks()[i]);
+ }
+
+ if (block->last_instruction()->SuccessorCount() == 1 &&
+ block->last_instruction()->SuccessorAt(0)->IsJoinEntry()) {
+ JoinEntryInstr* join =
+ block->last_instruction()->SuccessorAt(0)->AsJoinEntry();
+ intptr_t pred_index = join->IndexOfPredecessor(block);
+ ASSERT(pred_index >= 0);
+ if (join->phis() != NULL) {
+ for (intptr_t i = 0; i < join->phis()->length(); ++i) {
+ PhiInstr* phi = (*join->phis())[i];
+ if (phi == NULL) continue;
+ Value* use = phi->InputAt(pred_index);
+ const intptr_t value_ssa_index = use->definition()->ssa_temp_index();
+ if (known_smis_->Contains(value_ssa_index) &&
+ (phi->GetPropagatedCid() != kSmiCid)) {
+ use->set_reaching_cid(kSmiCid);
+ AddToWorklist(phi);
+ }
+ }
+ }
+ }
+
+ for (intptr_t i = rollback_point; i < rollback_checks_.length(); i++) {
+ known_smis_->Remove(rollback_checks_[i]);
+ }
+ rollback_checks_.TruncateTo(rollback_point);
+}
+
+
+void SminessPropagator::Propagate() {
+ PropagateSminessRecursive(flow_graph_->graph_entry());
+ ProcessPhis();
+}
+
+
+void FlowGraphOptimizer::PropagateSminess() {
+ SminessPropagator propagator(flow_graph_);
+ propagator.Propagate();
+}
+
+
void FlowGraphTypePropagator::VisitBlocks() {
ASSERT(current_iterator_ == NULL);
for (intptr_t i = 0; i < block_order_.length(); ++i) {
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | runtime/vm/intermediate_language.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698