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

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: 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 41279)
+++ 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,8 @@
optimized_block_order_(),
constant_null_(NULL),
constant_dead_(NULL),
+ constant_empty_context_(NULL),
+ current_context_(NULL),
block_effects_(NULL),
licm_allowed_(true),
loop_headers_(NULL),
@@ -465,10 +468,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().index() == flow_graph_->CurrentContextVar()->index()) {
Vyacheslav Egorov (Google) 2014/10/28 13:44:57 is it possible just to do store->local().Equals(f
Florian Schneider 2014/10/28 19:04:31 Done.
+ 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 +486,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().index() == flow_graph_->CurrentContextVar()->index()) {
Vyacheslav Egorov (Google) 2014/10/28 13:44:57 ditto
Florian Schneider 2014/10/28 19:04:30 Done.
+ return false;
+ }
const intptr_t index = load->local().BitIndexIn(num_non_copied_params_);
return load->is_last() && !GetLiveOutSet(block)->Contains(index);
}
@@ -722,6 +731,7 @@
// Insert phis for each variable in turn.
GrowableArray<BlockEntryInstr*> worklist;
for (intptr_t var_index = 0; var_index < variable_count(); ++var_index) {
+ bool always_live = var_index == CurrentContextEnvIndex();
Vyacheslav Egorov (Google) 2014/10/28 13:44:57 const bool is_always_alive
Florian Schneider 2014/10/28 19:04:30 Done.
// 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 +750,9 @@
if (has_already[index] < var_index) {
BlockEntryInstr* block = preorder[index];
ASSERT(block->IsJoinEntry());
- block->AsJoinEntry()->InsertPhi(var_index, variable_count());
+ block->AsJoinEntry()->InsertPhi(var_index,
Vyacheslav Egorov (Google) 2014/10/28 13:44:57 You can also make InsertPhi return the phi it crea
Florian Schneider 2014/10/28 19:04:31 Done.
+ variable_count(),
+ always_live);
has_already[index] = var_index;
if (work[index] < var_index) {
work[index] = var_index;
@@ -764,6 +776,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) {
@@ -791,7 +805,18 @@
// 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 +837,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());
@@ -872,7 +891,7 @@
// 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)) {
+ if (!live_in->Contains(i) && (i != CurrentContextEnvIndex())) {
Vyacheslav Egorov (Google) 2014/10/28 13:44:57 Should not we instead ensure that live_in->Contain
Florian Schneider 2014/10/28 19:04:31 Yes, I can change the VariableLiveness accordingly
(*env)[i] = constant_dead();
}
}

Powered by Google App Engine
This is Rietveld 408576698