case kTaggedNumber: return "number";
case kSmi: return "smi";
case kHeapNumber: return "heap-number";
+ case kFloat32x4: return "float32x4";
+ case kInt32x4: return "int32x4";
case kString: return "string";
case kBoolean: return "boolean";
case kNonPrimitive: return "non-primitive";
result = HType::Smi();
} else if (value->IsHeapNumber()) {
result = HType::HeapNumber();
+ } else if (value->IsFloat32x4()) {
+ result = HType::Float32x4();
+ } else if (value->IsInt32x4()) {
+ result = HType::Int32x4();
} else if (value->IsString()) {
result = HType::String();
} else if (value->IsBoolean()) {
}
+HType HType::TypeFromRepresentation(Representation representation) {
+ HType result = HType::Tagged();
+ if (representation.IsSmi()) {
+ result = HType::Smi();
+ } else if (representation.IsDouble()) {
+ result = HType::HeapNumber();
+ } else if (representation.IsFloat32x4()) {
+ result = HType::Float32x4();
+ } else if (representation.IsInt32x4()) {
+ result = HType::Int32x4();
+ }
+ return result;
+}
+
+
bool HValue::IsDefinedAfter(HBasicBlock* other) const {
return block()->block_id() > other->block_id();
}
if (CheckFlag(HValue::kHasNoObservableSideEffects)) {
stream->Add(" [noOSE]");
}
+ if (CheckFlag(HValue::kIsDead)) {
+ stream->Add(" [dead]");
+ }
}
value()->PrintNameTo(stream);
stream->Add(" (%p)", *map().handle());
HControlInstruction::PrintDataTo(stream);
+ if (known_successor_index() == 0) {
+ stream->Add(" [true]");
+ } else if (known_successor_index() == 1) {
+ stream->Add(" [false]");
+ }
}
*block = SecondSuccessor();
}
return true;
+ } else if (value()->representation().IsFloat32x4()) {
+ if (compares_float32x4_type()) {
+ *block = FirstSuccessor();
+ } else {
+ *block = SecondSuccessor();
+ }
+ return true;
+ } else if (value()->representation().IsInt32x4()) {
+ if (compares_int32x4_type()) {
+ *block = FirstSuccessor();
+ } else {
+ *block = SecondSuccessor();
+ }
+ return true;
}
+
*block = NULL;
return false;
}
}
-void HCheckMaps::HandleSideEffectDominator(GVNFlag side_effect,
+bool HCheckMaps::HandleSideEffectDominator(GVNFlag side_effect,
HValue* dominator) {
ASSERT(side_effect == kChangesMaps);
// TODO(mstarzinger): For now we specialize on HStoreNamedField, but once
// for which the map is known.
if (HasNoUses() && dominator->IsStoreNamedField()) {
HStoreNamedField* store = HStoreNamedField::cast(dominator);
- if (!store->has_transition() || store->object() != value()) return;
+ if (!store->has_transition() || store->object() != value()) return false;
HConstant* transition = HConstant::cast(store->transition());
if (map_set_.Contains(transition->GetUnique())) {
DeleteAndReplaceWith(NULL);
- return;
+ return true;
}
}
+ return false;
}
}
+bool HConstant::ImmortalImmovable() const {
+ if (has_int32_value_) {
+ return false;
+ }
+ if (has_double_value_) {
+ if (IsSpecialDouble()) {
+ return true;
+ }
+ return false;
+ }
+ if (has_external_reference_value_) {
+ return false;
+ }
+
+ ASSERT(!object_.handle().is_null());
+ Heap* heap = isolate()->heap();
+ ASSERT(!object_.IsKnownGlobal(heap->minus_zero_value()));
+ ASSERT(!object_.IsKnownGlobal(heap->nan_value()));
+ return
+#define IMMORTAL_IMMOVABLE_ROOT(name) \
+ object_.IsKnownGlobal(heap->name()) ||
+ IMMORTAL_IMMOVABLE_ROOT_LIST(IMMORTAL_IMMOVABLE_ROOT)
+#undef IMMORTAL_IMMOVABLE_ROOT
+#define INTERNALIZED_STRING(name, value) \
+ object_.IsKnownGlobal(heap->name()) ||
+ INTERNALIZED_STRING_LIST(INTERNALIZED_STRING)
+#undef INTERNALIZED_STRING
+#define STRING_TYPE(NAME, size, name, Name) \
+ object_.IsKnownGlobal(heap->name##_map()) ||
+ STRING_TYPE_LIST(STRING_TYPE)
+#undef STRING_TYPE
+ false;
+}
+
+
bool HConstant::EmitAtUses() {
ASSERT(IsLinked());
if (block()->graph()->has_osr() &&
void HLoadNamedField::PrintDataTo(StringStream* stream) {
object()->PrintNameTo(stream);
access_.PrintTo(stream);
+
+ if (HasDependency()) {
+ stream->Add(" ");
+ dependency()->PrintNameTo(stream);
+ }
}
}
-void HAllocate::HandleSideEffectDominator(GVNFlag side_effect,
+bool HAllocate::HandleSideEffectDominator(GVNFlag side_effect,
HValue* dominator) {
ASSERT(side_effect == kChangesNewSpacePromotion);
Zone* zone = block()->zone();
- if (!FLAG_use_allocation_folding) return;
+ if (!FLAG_use_allocation_folding) return false;
// Try to fold allocations together with their dominating allocations.
if (!dominator->IsAllocate()) {
PrintF("#%d (%s) cannot fold into #%d (%s)\n",
id(), Mnemonic(), dominator->id(), dominator->Mnemonic());
}
- return;
+ return false;
}
HAllocate* dominator_allocate = HAllocate::cast(dominator);
PrintF("#%d (%s) cannot fold into #%d (%s), dynamic allocation size\n",
id(), Mnemonic(), dominator->id(), dominator->Mnemonic());
}
- return;
+ return false;
}
dominator_allocate = GetFoldableDominator(dominator_allocate);
if (dominator_allocate == NULL) {
- return;
+ return false;
}
ASSERT((IsNewSpaceAllocation() &&
id(), Mnemonic(), dominator_allocate->id(),
dominator_allocate->Mnemonic(), new_dominator_size);
}
- return;
+ return false;
}
HInstruction* new_dominator_size_constant = HConstant::CreateAndInsertBefore(
id(), Mnemonic(), dominator_allocate->id(),
dominator_allocate->Mnemonic());
}
+ return true;
}
zone, context(), free_space_size, Representation::Smi(), store_map);
// Must force Smi representation for x64 (see comment above).
HObjectAccess access =
- HObjectAccess::ForJSObjectOffset(FreeSpace::kSizeOffset,
- Representation::Smi());
+ HObjectAccess::ForMapAndOffset(isolate()->factory()->free_space_map(),
+ FreeSpace::kSizeOffset,
+ Representation::Smi());
HStoreNamedField* store_size = HStoreNamedField::New(zone, context(),
free_space_instr, access, filler_size);
store_size->SetFlag(HValue::kHasNoObservableSideEffects);
void HAllocate::ClearNextMapWord(int offset) {
if (MustClearNextMapWord()) {
Zone* zone = block()->zone();
- HObjectAccess access = HObjectAccess::ForJSObjectOffset(offset);
+ HObjectAccess access =
+ HObjectAccess::ForObservableJSObjectOffset(offset);
HStoreNamedField* clear_next_map =
HStoreNamedField::New(zone, context(), this, access,
block()->graph()->GetConstant0());
}
-HObjectAccess HObjectAccess::ForJSObjectOffset(int offset,
+HObjectAccess HObjectAccess::ForMapAndOffset(Handle<Map> map, int offset,
Representation representation) {
ASSERT(offset >= 0);
Portion portion = kInobject;
} else if (offset == JSObject::kMapOffset) {
portion = kMaps;
}
- return HObjectAccess(portion, offset, representation);
+ bool existing_inobject_property = true;
+ if (!map.is_null()) {
+ existing_inobject_property = (offset <
+ map->instance_size() - map->unused_property_fields() * kPointerSize);
+ }
+ return HObjectAccess(portion, offset, representation, Handle<String>::null(),
+ false, existing_inobject_property);
}
HObjectAccess HObjectAccess::ForBackingStoreOffset(int offset,
Representation representation) {
ASSERT(offset >= 0);
- return HObjectAccess(kBackingStore, offset, representation);
+ return HObjectAccess(kBackingStore, offset, representation,
+ Handle<String>::null(), false, false);
}
HObjectAccess HObjectAccess::ForField(Handle<Map> map,
- LookupResult *lookup, Handle<String> name) {
- ASSERT(lookup->IsField() || lookup->IsTransitionToField(*map));
+ LookupResult* lookup,
+ Handle<String> name) {
+ ASSERT(lookup->IsField() || lookup->IsTransitionToField());
int index;
Representation representation;
if (lookup->IsField()) {
index = lookup->GetLocalFieldIndexFromMap(*map);
representation = lookup->representation();
} else {
- Map* transition = lookup->GetTransitionMapFromMap(*map);
+ Map* transition = lookup->GetTransitionTarget();
int descriptor = transition->LastAdded();
index = transition->instance_descriptors()->GetFieldIndex(descriptor) -
map->inobject_properties();
// Negative property indices are in-object properties, indexed
// from the end of the fixed part of the object.
int offset = (index * kPointerSize) + map->instance_size();
- return HObjectAccess(kInobject, offset, representation, name);
+ return HObjectAccess(kInobject, offset, representation, name, false, true);
} else {
// Non-negative property indices are in the properties array.
int offset = (index * kPointerSize) + FixedArray::kHeaderSize;
- return HObjectAccess(kBackingStore, offset, representation, name);
+ return HObjectAccess(kBackingStore, offset, representation, name,
+ false, false);
}
}
stream->Add("@%d", offset());
}
+
+HInstruction* HNullarySIMDOperation::New(
+ Zone* zone, HValue* context, BuiltinFunctionId op) {
+ return new(zone) HNullarySIMDOperation(context, op);
+}
+
+
+HInstruction* HUnarySIMDOperation::New(
+ Zone* zone, HValue* context, HValue* value, BuiltinFunctionId op,
+ Representation to) {
+ return new(zone) HUnarySIMDOperation(context, value, op, to);
+}
+
+
+HInstruction* HBinarySIMDOperation::New(
+ Zone* zone, HValue* context, HValue* left, HValue* right,
+ BuiltinFunctionId op) {
+ return new(zone) HBinarySIMDOperation(context, left, right, op);
+}
+
+
+HInstruction* HTernarySIMDOperation::New(
+ Zone* zone, HValue* context, HValue* mask, HValue* left, HValue* right,
+ BuiltinFunctionId op) {
+ return new(zone) HTernarySIMDOperation(context, mask, left, right, op);
+}
+
+
+HInstruction* HQuarternarySIMDOperation::New(
+ Zone* zone, HValue* context, HValue* x, HValue* y, HValue* z, HValue* w,
+ BuiltinFunctionId op) {
+ return new(zone) HQuarternarySIMDOperation(context, x, y, z, w, op);
+}
+
+
+const char* HNullarySIMDOperation::OpName() const {
+ switch (op()) {
+#define SIMD_NULLARY_OPERATION_CASE_ITEM(module, function, name, p4) \
+ case k##name: \
+ return #module "." #function;
+SIMD_NULLARY_OPERATIONS(SIMD_NULLARY_OPERATION_CASE_ITEM)
+#undef SIMD_NULLARY_OPERATION_CASE_ITEM
+ default:
+ UNREACHABLE();
+ return NULL;
+ }
+}
+
+
+void HNullarySIMDOperation::PrintDataTo(StringStream* stream) {
+ const char* name = OpName();
+ stream->Add("%s", name);
+}
+
+
+const char* HUnarySIMDOperation::OpName() const {
+ switch (op()) {
+#define SIMD_UNARY_OPERATION_CASE_ITEM(module, function, name, p4, p5) \
+ case k##name: \
+ return #module "." #function;
+SIMD_UNARY_OPERATIONS(SIMD_UNARY_OPERATION_CASE_ITEM)
+SIMD_UNARY_OPERATIONS_FOR_PROPERTY_ACCESS(SIMD_UNARY_OPERATION_CASE_ITEM)
+#undef SIMD_UNARY_OPERATION_CASE_ITEM
+ default:
+ UNREACHABLE();
+ return NULL;
+ }
+}
+
+
+void HUnarySIMDOperation::PrintDataTo(StringStream* stream) {
+ const char* name = OpName();
+ stream->Add("%s ", name);
+ value()->PrintNameTo(stream);
+}
+
+
+const char* HBinarySIMDOperation::OpName() const {
+ switch (op()) {
+#define SIMD_BINARY_OPERATION_CASE_ITEM(module, function, name, p4, p5, p6) \
+ case k##name: \
+ return #module "." #function;
+SIMD_BINARY_OPERATIONS(SIMD_BINARY_OPERATION_CASE_ITEM)
+#undef SIMD_BINARY_OPERATION_CASE_ITEM
+ default:
+ UNREACHABLE();
+ return NULL;
+ }
+}
+
+
+void HBinarySIMDOperation::PrintDataTo(StringStream* stream) {
+ const char* name = OpName();
+ stream->Add("%s ", name);
+ left()->PrintNameTo(stream);
+ stream->Add(" ");
+ right()->PrintNameTo(stream);
+}
+
+
+const char* HTernarySIMDOperation::OpName() const {
+ switch (op()) {
+#define SIMD_TERNARY_OPERATION_CASE_ITEM(module, function, name, p4, p5, p6, \
+ p7) \
+ case k##name: \
+ return #module "." #function;
+SIMD_TERNARY_OPERATIONS(SIMD_TERNARY_OPERATION_CASE_ITEM)
+#undef SIMD_TERNARY_OPERATION_CASE_ITEM
+ default:
+ UNREACHABLE();
+ return NULL;
+ }
+}
+
+
+void HTernarySIMDOperation::PrintDataTo(StringStream* stream) {
+ const char* name = OpName();
+ stream->Add("%s ", name);
+ first()->PrintNameTo(stream);
+ stream->Add(" ");
+ second()->PrintNameTo(stream);
+ stream->Add(" ");
+ third()->PrintNameTo(stream);
+}
+
+
+const char* HQuarternarySIMDOperation::OpName() const {
+ switch (op()) {
+#define SIMD_QUARTERNARY_OPERATION_CASE_ITEM(module, function, name, p4, p5, \
+ p6, p7, p8) \
+ case k##name: \
+ return #module "." #function;
+SIMD_QUARTERNARY_OPERATIONS(SIMD_QUARTERNARY_OPERATION_CASE_ITEM)
+#undef SIMD_QUARTERNARY_OPERATION_CASE_ITEM
+ default:
+ UNREACHABLE();
+ return NULL;
+ }
+}
+
+
+void HQuarternarySIMDOperation::PrintDataTo(StringStream* stream) {
+ const char* name = OpName();
+ stream->Add("%s ", name);
+ x()->PrintNameTo(stream);
+ stream->Add(" ");
+ y()->PrintNameTo(stream);
+ stream->Add(" ");
+ z()->PrintNameTo(stream);
+ stream->Add(" ");
+ w()->PrintNameTo(stream);
+}
+
+
} } // namespace v8::internal