[vm/compiler] Canonicalize more intermediate constants in IL.

* when building IL from Kernel use canonical double representation
instead of allocating new double objects;
* in constant propagation canonicalize immutable primitive constants
(strings, mints and doubles) before replacing instruction with its
constant value;

Change-Id: I18a99c1ec5cddf4de4ea0571352408bd34faeb38
Reviewed-on: https://dart-review.googlesource.com/50728
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Vyacheslav Egorov <vegorov@google.com>
This commit is contained in:
Vyacheslav Egorov 2018-04-12 12:48:13 +00:00 committed by commit-bot@chromium.org
parent df6055d876
commit 5909932d38
2 changed files with 15 additions and 5 deletions

View file

@ -26,6 +26,7 @@ DEFINE_FLAG(bool,
// Quick access to the current zone and isolate.
#define I (isolate())
#define Z (graph_->zone())
#define T (graph_->thread())
ConstantPropagator::ConstantPropagator(
FlowGraph* graph,
@ -1110,7 +1111,8 @@ void ConstantPropagator::VisitBinaryDoubleOp(BinaryDoubleOpInstr* instr) {
default:
UNREACHABLE();
}
const Double& result = Double::ZoneHandle(Double::NewCanonical(result_val));
const Double& result =
Double::ZoneHandle(Double::New(result_val, Heap::kOld));
SetValue(instr, result);
}
}
@ -1321,6 +1323,7 @@ void ConstantPropagator::Transform() {
// instructions, previous pointers, predecessors, etc. after eliminating
// unreachable code. We do not maintain those properties during the
// transformation.
auto& value = Object::Handle(Z);
for (BlockIterator b = graph_->reverse_postorder_iterator(); !b.Done();
b.Advance()) {
BlockEntryInstr* block = b.Current();
@ -1398,7 +1401,14 @@ void ConstantPropagator::Transform() {
THR_Print("Constant v%" Pd " = %s\n", defn->ssa_temp_index(),
defn->constant_value().ToCString());
}
ConstantInstr* constant = graph_->GetConstant(defn->constant_value());
value = defn->constant_value().raw();
if ((value.IsString() || value.IsMint() || value.IsDouble()) &&
!value.IsCanonical()) {
const char* error_str = nullptr;
value = Instance::Cast(value).CheckAndCanonicalize(T, &error_str);
ASSERT(value.IsNull() && (error_str == nullptr));
}
ConstantInstr* constant = graph_->GetConstant(value);
defn->ReplaceUsesWith(constant);
i.RemoveCurrentFromGraph();
}

View file

@ -8328,9 +8328,9 @@ Fragment StreamingFlowGraphBuilder::BuildDoubleLiteral(
TokenPosition* position) {
if (position != NULL) *position = TokenPosition::kNoSource;
Double& constant =
Double::ZoneHandle(Z, Double::New(H.DartString(ReadStringReference()),
Heap::kOld)); // read string reference.
Double& constant = Double::ZoneHandle(
Z, Double::NewCanonical(
H.DartString(ReadStringReference()))); // read string reference.
return Constant(constant);
}