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

Unified Diff: src/hydrogen-check-elimination.cc

Issue 104843002: Remove half of the checks for comparing two Obejcts (Closed) Base URL: git://github.com/v8/v8.git@master
Patch Set: addressed comments Created 7 years 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/hydrogen.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/hydrogen-check-elimination.cc
diff --git a/src/hydrogen-check-elimination.cc b/src/hydrogen-check-elimination.cc
index bbd3042fb7af6659f4107fffb7127e1298000593..ca37fa1c9d9fb3c151aa88b645b1a482b3767cc1 100644
--- a/src/hydrogen-check-elimination.cc
+++ b/src/hydrogen-check-elimination.cc
@@ -101,6 +101,10 @@ class HCheckTable : public ZoneObject {
ReduceCheckHeapObject(HCheckHeapObject::cast(instr));
break;
}
+ case HValue::kCompareObjectEqAndBranch: {
+ ReduceCompareObjectEqAndBranch(HCompareObjectEqAndBranch::cast(instr));
+ break;
+ }
default: {
// If the instruction changes maps uncontrollably, drop everything.
if (instr->CheckGVNFlag(kChangesMaps) ||
@@ -266,6 +270,50 @@ class HCheckTable : public ZoneObject {
}
}
+ void ReduceCompareObjectEqAndBranch(HCompareObjectEqAndBranch* instr) {
+ HCheckMaps* removed = NULL;
+ HValue* left = instr->left();
+ HValue* right = instr->right();
+ if (left->IsCheckMaps() && right->IsCheckMaps()) {
+ HCheckMaps* left_check = HCheckMaps::cast(left);
+ HCheckMaps* right_check = HCheckMaps::cast(right);
+ MapSet left_maps = left_check->map_set().Copy(phase_->zone());
+ MapSet right_maps = right_check->map_set().Copy(phase_->zone());
+ if (left_maps->Equals(right_maps)) {
+ // Object equality comparison guarantees one check suffices, so
+ // eliminate the other. After LICM, we could easily find the correct
+ // one (loop invariant object's map check could be hoisted out of loop).
+ removed = left->block()->block_id() > right->block()->block_id()
+ ? left_check : right_check;
+ }
+ } else if (left->IsCheckMaps() || right->IsCheckMaps()) {
+ // For the case one side map check is eliminated by previous optimization.
+ HValue* obj = left->IsCheckMaps() ? right : left;
+ HCheckMaps* check = (obj == left) ? HCheckMaps::cast(right)
+ : HCheckMaps::cast(left);
+ MapSet obj_maps = FindMaps(obj);
+ MapSet check_maps = check->map_set().Copy(phase_->zone());
+ if (obj_maps->IsSubset(check_maps)) {
+ // Obj check is more strict; the remaining check is redundant.
+ removed = check;
+ }
+ }
+
+ if (removed != NULL) {
+ // Check whether there is prior CheckHeapObject refering to the same
+ // object as the removed CheckMaps.
+ if (removed->previous()->IsCheckHeapObject()) {
+ HCheckHeapObject* cho = HCheckHeapObject::cast(removed->previous());
+ if (cho->value() == removed->ActualValue()) {
+ cho->DeleteAndReplaceWith(cho->value());
+ INC_STAT(removed_cho_);
+ }
+ }
+ removed->DeleteAndReplaceWith(removed->ActualValue());
+ INC_STAT(removed_);
+ }
+ }
+
void ReduceStoreNamedField(HStoreNamedField* instr) {
HValue* object = instr->object()->ActualValue();
if (instr->has_transition()) {
« no previous file with comments | « src/hydrogen.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698