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

Unified Diff: runtime/vm/flow_graph.cc

Issue 678763004: Make CTX allocatable by the register allocator. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: incorporated latest comments Created 6 years, 2 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 41393)
+++ runtime/vm/flow_graph.cc (working copy)
@@ -8,6 +8,7 @@
#include "vm/flow_graph_builder.h"
#include "vm/intermediate_language.h"
#include "vm/growable_array.h"
+#include "vm/object_store.h"
#include "vm/report.h"
namespace dart {
@@ -36,6 +37,7 @@
optimized_block_order_(),
constant_null_(NULL),
constant_dead_(NULL),
+ constant_empty_context_(NULL),
block_effects_(NULL),
licm_allowed_(true),
loop_headers_(NULL),
@@ -465,10 +467,13 @@
// Returns true if the value set by the given store reaches any load from the
// same local variable.
bool IsStoreAlive(BlockEntryInstr* block, StoreLocalInstr* store) {
+ if (store->local().Equals(*flow_graph_->CurrentContextVar())) {
+ return true;
+ }
+
if (store->is_dead()) {
return false;
}
-
if (store->is_last()) {
const intptr_t index = store->local().BitIndexIn(num_non_copied_params_);
return GetLiveOutSet(block)->Contains(index);
@@ -480,6 +485,9 @@
// Returns true if the given load is the last for the local and the value
// of the local will not flow into another one.
bool IsLastLoad(BlockEntryInstr* block, LoadLocalInstr* load) {
+ if (load->local().Equals(*flow_graph_->CurrentContextVar())) {
+ return false;
+ }
const intptr_t index = load->local().BitIndexIn(num_non_copied_params_);
return load->is_last() && !GetLiveOutSet(block)->Contains(index);
}
@@ -565,11 +573,13 @@
VariableLivenessAnalysis variable_liveness(this);
variable_liveness.Analyze();
+ GrowableArray<PhiInstr*> live_phis;
+
InsertPhis(preorder_,
variable_liveness.ComputeAssignedVars(),
- dominance_frontier);
+ dominance_frontier,
+ &live_phis);
- GrowableArray<PhiInstr*> live_phis;
// Rename uses to reference inserted phis where appropriate.
// Collect phis that reach a non-environment use.
@@ -702,7 +712,8 @@
void FlowGraph::InsertPhis(
const GrowableArray<BlockEntryInstr*>& preorder,
const GrowableArray<BitVector*>& assigned_vars,
- const GrowableArray<BitVector*>& dom_frontier) {
+ const GrowableArray<BitVector*>& dom_frontier,
+ GrowableArray<PhiInstr*>* live_phis) {
const intptr_t block_count = preorder.length();
// Map preorder block number to the highest variable index that has a phi
// in that block. Use it to avoid inserting multiple phis for the same
@@ -722,6 +733,7 @@
// Insert phis for each variable in turn.
GrowableArray<BlockEntryInstr*> worklist;
for (intptr_t var_index = 0; var_index < variable_count(); ++var_index) {
+ const bool always_live = var_index == CurrentContextEnvIndex();
// Add to the worklist each block containing an assignment.
for (intptr_t block_index = 0; block_index < block_count; ++block_index) {
if (assigned_vars[block_index]->Contains(var_index)) {
@@ -740,7 +752,12 @@
if (has_already[index] < var_index) {
BlockEntryInstr* block = preorder[index];
ASSERT(block->IsJoinEntry());
- block->AsJoinEntry()->InsertPhi(var_index, variable_count());
+ PhiInstr* phi = block->AsJoinEntry()->InsertPhi(var_index,
+ variable_count());
+ if (always_live) {
+ phi->mark_alive();
+ live_phis->Add(phi);
+ }
has_already[index] = var_index;
if (work[index] < var_index) {
work[index] = var_index;
@@ -764,6 +781,8 @@
// Add global constants to the initial definitions.
constant_null_ = GetConstant(Object::ZoneHandle());
constant_dead_ = GetConstant(Symbols::OptimizedOut());
+ constant_empty_context_ = GetConstant(Context::Handle(
+ isolate()->object_store()->empty_context()));
// Add parameters to the initial definitions and renaming environment.
if (inlining_parameters != NULL) {
@@ -787,11 +806,22 @@
}
}
- // Initialize all locals with #null in the renaming environment. For OSR,
- // the locals have already been handled as parameters.
+ // Initialize all locals in the renaming environment For OSR, the locals have
+ // already been handled as parameters.
if (!IsCompiledForOsr()) {
for (intptr_t i = parameter_count(); i < variable_count(); ++i) {
- env.Add(constant_null());
+ if (i == CurrentContextEnvIndex()) {
+ if (parsed_function().function().IsClosureFunction()) {
+ CurrentContextInstr* context = new CurrentContextInstr();
+ context->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp.
+ AddToInitialDefinitions(context);
+ env.Add(context);
+ } else {
+ env.Add(constant_empty_context());
+ }
+ } else {
+ env.Add(constant_null());
+ }
}
}
@@ -812,12 +842,6 @@
*env,
num_non_copied_params_,
&parsed_function_);
- // TODO(fschneider): Add predicates CanEagerlyDeoptimize and
- // CanLazilyDeoptimize to instructions to generally deal with instructions
- // that have pushed arguments and input operands.
- // Right now, closure calls are the only instructions that have both. They
- // also don't have an eager deoptimziation point, so the environment attached
- // here is only used for after the call.
if (instr->IsClosureCall()) {
deopt_env = deopt_env->DeepCopy(isolate(),
deopt_env->Length() - instr->InputCount());
@@ -846,7 +870,7 @@
if (phi != NULL) {
(*env)[i] = phi;
phi->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp.
- if (block_entry->InsideTryBlock()) {
+ if (block_entry->InsideTryBlock() && !phi->is_alive()) {
// 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.
@@ -872,7 +896,9 @@
// slots with null.
BitVector* live_in = variable_liveness->GetLiveInSet(block_entry);
for (intptr_t i = 0; i < variable_count(); i++) {
- if (!live_in->Contains(i)) {
+ // TODO(fschneider): Make sure that live_in always contains the
+ // CurrentContext variable to avoid the special case here.
+ if (!live_in->Contains(i) && (i != CurrentContextEnvIndex())) {
(*env)[i] = constant_dead();
}
}

Powered by Google App Engine
This is Rietveld 408576698