Reviewers: ulan, jochen,

Message:
There remains a similar tag/untag sequence caused by the forced representation
change for BuildUncheckedMonomorphicElementAccess(). However, I can't find a
good way to remove this, as the representation is unknown at the point that the
forced change is introduced.

Description:
Remove forced type changes when they can't deopt

Hydrogen attempts to force representation changes on certain operations in order
to deoptimise on the change rather than the operation. However, these forced
changes are often unnecessary on 64-bit platforms, and cause poor code
generation, so this patch makes some of them conditional on whether it's
possible for deoptimisation to occur in the change.

On ARM64, this prevents sequences like:
                  ;;; <@46,#89> smi-tag
0x7ff282c7f050   144  lsl x4, x4, #32
                  ;;; <@48,#90> smi-untag
0x7ff282c7f054   148  asr x5, x4, #32
                  ;;; <@50,#31> mul-const-i-s
0x7ff282c7f058   152  lsl w6, w5, #3

BUG=

Please review this at https://codereview.chromium.org/303263010/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files (+34, -9 lines):
  M src/hydrogen.cc


Index: src/hydrogen.cc
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index c836dc21653129de5d7255a3c8d8b2e9c63e71c0..779b22470280bf9dba59575bd29d5fd63acff38a 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -2121,6 +2121,18 @@ HValue* HGraphBuilder::BuildStringAdd(
 }


+static bool RepresentationChangeToSmiCanDeopt(HValue* val) {
+  // A representation change to smi can deopt if the value:
+  //  - is not an int32 or smi
+  //  - is an int32, and smis are 31 bits
+  //  - is a uint32.
+  return !val->representation().IsSmiOrInteger32() ||
+         (val->representation().IsInteger32() &&
+ ((kSmiValueSize < (sizeof(int32_t) * 8)) || // NOLINT(runtime/sizeof)
+           val->CheckFlag(HValue::kUint32)));
+}
+
+
 HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess(
     HValue* checked_object,
     HValue* key,
@@ -2323,7 +2335,10 @@ HValue* HGraphBuilder::BuildAllocateElementsAndInitializeElementsHeader(
     HValue* capacity) {
   // The HForceRepresentation is to prevent possible deopt on int-smi
   // conversion after allocation but before the new object fields are set.
- capacity = AddUncasted<HForceRepresentation>(capacity, Representation::Smi());
+  if (RepresentationChangeToSmiCanDeopt(capacity)) {
+    capacity = AddUncasted<HForceRepresentation>(capacity,
+                                                 Representation::Smi());
+  }
   HValue* new_elements = BuildAllocateElements(kind, capacity);
   BuildInitializeElementsHeader(new_elements, kind, capacity);
   return new_elements;
@@ -3001,12 +3016,17 @@ HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* size_in_bytes, // These HForceRepresentations are because we store these as fields in the
   // objects we construct, and an int32-to-smi HChange could deopt. Accept
   // the deopt possibility now, before allocation occurs.
-  capacity =
-      builder()->AddUncasted<HForceRepresentation>(capacity,
-                                                   Representation::Smi());
-  length_field =
-      builder()->AddUncasted<HForceRepresentation>(length_field,
-                                                   Representation::Smi());
+  if (RepresentationChangeToSmiCanDeopt(capacity)) {
+    capacity =
+        builder()->AddUncasted<HForceRepresentation>(capacity,
+ Representation::Smi());
+  }
+  if (RepresentationChangeToSmiCanDeopt(length_field)) {
+    length_field =
+        builder()->AddUncasted<HForceRepresentation>(length_field,
+ Representation::Smi());
+  }
+
   // Allocate (dealing with failure appropriately)
   HAllocate* new_object = builder()->Add<HAllocate>(size_in_bytes,
       HType::JSArray(), NOT_TENURED, JS_ARRAY_TYPE);
@@ -8869,7 +8889,9 @@ HValue* HOptimizedGraphBuilder::BuildAllocateExternalElements(

   // The HForceRepresentation is to prevent possible deopt on int-smi
   // conversion after allocation but before the new object fields are set.
- length = AddUncasted<HForceRepresentation>(length, Representation::Smi());
+  if (RepresentationChangeToSmiCanDeopt(length)) {
+ length = AddUncasted<HForceRepresentation>(length, Representation::Smi());
+  }
   HValue* elements =
       Add<HAllocate>(
           Add<HConstant>(ExternalArray::kAlignedSize),
@@ -8926,7 +8948,10 @@ HValue* HOptimizedGraphBuilder::BuildAllocateFixedTypedArray(

   // The HForceRepresentation is to prevent possible deopt on int-smi
   // conversion after allocation but before the new object fields are set.
- length = AddUncasted<HForceRepresentation>(length, Representation::Smi());
+  if (RepresentationChangeToSmiCanDeopt(length)) {
+ length = AddUncasted<HForceRepresentation>(length, Representation::Smi());
+  }
+
   Handle<Map> fixed_typed_array_map(
       isolate()->heap()->MapForFixedTypedArray(array_type));
   HValue* elements =


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to