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

Unified Diff: src/hydrogen.cc

Issue 6881003: Prevent deopt when assigning double values to typed arrays (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fixes to make ia32 tests run Created 9 years, 8 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 | « src/conversions-inl.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/hydrogen.cc
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index f6c47f31dbe83934de00a230eb9099fc12dcacf0..cc069c894201d4fc583bb7bbcdae9e785be70ec4 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -919,7 +919,7 @@ void HRangeAnalysis::InferControlFlowRange(HTest* test, HBasicBlock* dest) {
ASSERT((test->FirstSuccessor() == dest) == (test->SecondSuccessor() != dest));
if (test->value()->IsCompare()) {
HCompare* compare = HCompare::cast(test->value());
- if (compare->GetInputRepresentation().IsInteger32()) {
+ if (compare->GetInputRepresentation().IsInteger()) {
Token::Value op = compare->token();
if (test->SecondSuccessor() == dest) {
op = Token::NegateCompareOp(op);
@@ -1505,7 +1505,7 @@ class HInferRepresentation BASE_EMBEDDED {
void HInferRepresentation::AddToWorklist(HValue* current) {
- if (current->representation().IsSpecialization()) return;
+ if (current->representation().IsTerminalSpecialization()) return;
if (!current->CheckFlag(HValue::kFlexibleRepresentation)) return;
if (in_worklist_.Contains(current->id())) return;
worklist_.Add(current);
@@ -1519,10 +1519,10 @@ void HInferRepresentation::AddToWorklist(HValue* current) {
// becomes the new representation type of the node.
void HInferRepresentation::InferBasedOnInputs(HValue* current) {
Representation r = current->representation();
- if (r.IsSpecialization()) return;
+ if (r.IsTerminalSpecialization()) return;
ASSERT(current->CheckFlag(HValue::kFlexibleRepresentation));
Representation inferred = current->InferredRepresentation();
- if (inferred.IsSpecialization()) {
+ if (!inferred.Equals(r)) {
current->ChangeRepresentation(inferred);
AddDependantsToWorklist(current);
}
@@ -1545,7 +1545,7 @@ void HInferRepresentation::AddDependantsToWorklist(HValue* current) {
// specialized.
void HInferRepresentation::InferBasedOnUses(HValue* current) {
Representation r = current->representation();
- if (r.IsSpecialization() || current->HasNoUses()) return;
+ if (r.IsTerminalSpecialization() || current->HasNoUses()) return;
ASSERT(current->CheckFlag(HValue::kFlexibleRepresentation));
Representation new_rep = TryChange(current);
if (!new_rep.IsNone()) {
@@ -1578,7 +1578,12 @@ Representation HInferRepresentation::TryChange(HValue* current) {
int tagged_count = use_count[Representation::kTagged];
int double_count = use_count[Representation::kDouble];
int int32_count = use_count[Representation::kInteger32];
- int non_tagged_count = double_count + int32_count;
+ int trunc_int32_count = use_count[Representation::kTruncatedInteger32];
+ int clamped_rounded_int8_count =
+ use_count[Representation::kClampedRoundedUInteger8];
+ int non_tagged_count = double_count + int32_count +
+ trunc_int32_count + clamped_rounded_int8_count;
+ int total_use_count = tagged_count + non_tagged_count;
// If a non-loop phi has tagged uses, don't convert it to untagged.
if (current->IsPhi() && !current->block()->IsLoopHeader()) {
@@ -1593,6 +1598,14 @@ Representation HInferRepresentation::TryChange(HValue* current) {
return Representation::Double();
} else if (int32_count > 0) {
return Representation::Integer32();
+ } else if (clamped_rounded_int8_count > 0 &&
+ clamped_rounded_int8_count == total_use_count) {
+ return Representation::ClampedRoundedUInteger8();
+ } else if (trunc_int32_count > 0 &&
+ trunc_int32_count == total_use_count) {
+ return Representation::TruncatedInteger32();
+ } else {
+ return Representation::None();
}
}
return Representation::None();
@@ -1764,18 +1777,28 @@ void HGraph::InsertRepresentationChangeForUse(HValue* value,
// information we treat constants like normal instructions and insert the
// change instructions for them.
HInstruction* new_value = NULL;
- bool is_truncating = use->CheckFlag(HValue::kTruncatingToInt32);
if (value->IsConstant()) {
HConstant* constant = HConstant::cast(value);
// Try to create a new copy of the constant with the new representation.
- new_value = is_truncating
+ new_value = to.IsTruncatedInteger32()
? constant->CopyToTruncatedInt32()
- : constant->CopyToRepresentation(to);
+ : to.IsClampedRoundedInteger8()
+ ? constant->CopyToClampedRoundedUInt8()
+ : constant->CopyToRepresentation(to);
}
if (new_value == NULL) {
+ Representation from = value->representation();
+ // Don't create changes for representation differences that
+ // won't generate code.
+ if (from.IsInteger() && (to.IsInteger32X() || to.IsTruncatedInteger32())) {
+ return;
+ }
+
new_value =
- new(zone()) HChange(value, value->representation(), to, is_truncating);
+ new(zone()) HChange(value,
+ from,
+ to);
}
new_value->InsertBefore(next);
@@ -1783,25 +1806,6 @@ void HGraph::InsertRepresentationChangeForUse(HValue* value,
}
-int CompareConversionUses(HValue* a,
- HValue* b,
- Representation a_rep,
- Representation b_rep) {
- if (a_rep.kind() > b_rep.kind()) {
- // Make sure specializations are separated in the result array.
- return 1;
- }
- // Put truncating conversions before non-truncating conversions.
- bool a_truncate = a->CheckFlag(HValue::kTruncatingToInt32);
- bool b_truncate = b->CheckFlag(HValue::kTruncatingToInt32);
- if (a_truncate != b_truncate) {
- return a_truncate ? -1 : 1;
- }
- // Sort by increasing block ID.
- return a->block()->block_id() - b->block()->block_id();
-}
-
-
void HGraph::InsertRepresentationChangesForValue(
HValue* current,
ZoneList<HValue*>* to_convert,
@@ -1814,6 +1818,7 @@ void HGraph::InsertRepresentationChangesForValue(
// us to avoid duplicate changes without searching the list.
ASSERT(to_convert->is_empty());
ASSERT(to_convert_reps->is_empty());
+ int index = 0;
for (int i = 0; i < current->uses()->length(); ++i) {
HValue* use = current->uses()->at(i);
// The occurrences index means the index within the operand array of "use"
@@ -1832,27 +1837,20 @@ void HGraph::InsertRepresentationChangesForValue(
int operand_index = use->LookupOperandIndex(occurrence_index, current);
Representation req = use->RequiredInputRepresentation(operand_index);
if (req.IsNone() || req.Equals(r)) continue;
- int index = 0;
- while (index < to_convert->length() &&
- CompareConversionUses(to_convert->at(index),
fschneider 2011/05/10 10:44:53 Thanks for cleaning this up!
- use,
- to_convert_reps->at(index),
- req) < 0) {
- ++index;
- }
- if (FLAG_trace_representation) {
- PrintF("Inserting a representation change to %s of %d for use at %d\n",
- req.Mnemonic(),
- current->id(),
- use->id());
- }
to_convert->InsertAt(index, use);
to_convert_reps->InsertAt(index, req);
+ ++index;
}
for (int i = 0; i < to_convert->length(); ++i) {
HValue* use = to_convert->at(i);
Representation r_to = to_convert_reps->at(i);
+ if (FLAG_trace_representation) {
+ PrintF("Inserting a representation change to %s of %d for use at %d\n",
+ r_to.Mnemonic(),
+ current->id(),
+ use->id());
+ }
InsertRepresentationChangeForUse(current, use, r_to);
}
@@ -1867,36 +1865,6 @@ void HGraph::InsertRepresentationChangesForValue(
void HGraph::InsertRepresentationChanges() {
HPhase phase("Insert representation changes", this);
fschneider 2011/05/10 10:44:53 Not sure that the representation computation does
-
-
- // Compute truncation flag for phis: Initially assume that all
- // int32-phis allow truncation and iteratively remove the ones that
- // are used in an operation that does not allow a truncating
- // conversion.
- // TODO(fschneider): Replace this with a worklist-based iteration.
- for (int i = 0; i < phi_list()->length(); i++) {
- HPhi* phi = phi_list()->at(i);
- if (phi->representation().IsInteger32()) {
- phi->SetFlag(HValue::kTruncatingToInt32);
- }
- }
- bool change = true;
- while (change) {
- change = false;
- for (int i = 0; i < phi_list()->length(); i++) {
- HPhi* phi = phi_list()->at(i);
- if (!phi->CheckFlag(HValue::kTruncatingToInt32)) continue;
- for (int j = 0; j < phi->uses()->length(); j++) {
- HValue* use = phi->uses()->at(j);
- if (!use->CheckFlag(HValue::kTruncatingToInt32)) {
- phi->ClearFlag(HValue::kTruncatingToInt32);
- change = true;
- break;
- }
- }
- }
- }
-
ZoneList<HValue*> value_list(4);
ZoneList<Representation> rep_list(4);
for (int i = 0; i < blocks_.length(); ++i) {
@@ -1928,7 +1896,7 @@ void HGraph::ComputeMinusZeroChecks() {
// int32-to-tagged and int32-to-double.
Representation from = change->value()->representation();
ASSERT(from.Equals(change->from()));
- if (from.IsInteger32()) {
+ if (from.IsInteger() && !change->to().IsInteger()) {
ASSERT(change->to().IsTagged() || change->to().IsDouble());
ASSERT(visited.IsEmpty());
PropagateMinusZeroChecks(change->value(), &visited);
« no previous file with comments | « src/conversions-inl.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698