[turboshaft] Port operations from ECL to MachineLoweringReducer (26)
This CL ports operations from Turbofan's EffectControlLinearizer to Turboshaft's MachineLoweringReducer: - FindOrderedHashMapEntry - FindOrderedHashMapEntryForInt32Key - FindOrderedHashSetEntry - TransitionAndStoreElement - TransitionAndStoreNumberElement - TransitionAndStoreNonNumberElement Bug: v8:12783 Change-Id: Ic7c051ac879ac8b71615b173f0175c05a36e3aa4 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4414805 Commit-Queue: Nico Hartmann <nicohartmann@chromium.org> Reviewed-by: Darius Mercadier <dmercadier@chromium.org> Reviewed-by: Michael Lippautz <mlippautz@chromium.org> Cr-Commit-Position: refs/heads/main@{#87065}
This commit is contained in:

committed by
V8 LUCI CQ

parent
2d4c2f3d42
commit
03594553f1
@ -3,3 +3,4 @@
|
||||
BasedOnStyle: Google
|
||||
DerivePointerAlignment: false
|
||||
MaxEmptyLinesToKeep: 1
|
||||
IfMacros: ['IF', 'IF_NOT', 'ELSE', 'ELSE_IF']
|
||||
|
@ -1855,21 +1855,27 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node,
|
||||
LowerStoreSignedSmallElement(node);
|
||||
break;
|
||||
case IrOpcode::kFindOrderedHashMapEntry:
|
||||
if (v8_flags.turboshaft) return false;
|
||||
result = LowerFindOrderedHashMapEntry(node);
|
||||
break;
|
||||
case IrOpcode::kFindOrderedHashMapEntryForInt32Key:
|
||||
if (v8_flags.turboshaft) return false;
|
||||
result = LowerFindOrderedHashMapEntryForInt32Key(node);
|
||||
break;
|
||||
case IrOpcode::kFindOrderedHashSetEntry:
|
||||
if (v8_flags.turboshaft) return false;
|
||||
result = LowerFindOrderedHashSetEntry(node);
|
||||
break;
|
||||
case IrOpcode::kTransitionAndStoreNumberElement:
|
||||
if (v8_flags.turboshaft) return false;
|
||||
LowerTransitionAndStoreNumberElement(node);
|
||||
break;
|
||||
case IrOpcode::kTransitionAndStoreNonNumberElement:
|
||||
if (v8_flags.turboshaft) return false;
|
||||
LowerTransitionAndStoreNonNumberElement(node);
|
||||
break;
|
||||
case IrOpcode::kTransitionAndStoreElement:
|
||||
if (v8_flags.turboshaft) return false;
|
||||
LowerTransitionAndStoreElement(node);
|
||||
break;
|
||||
case IrOpcode::kRuntimeAbort:
|
||||
@ -7446,6 +7452,7 @@ Node* EffectControlLinearizer::IsElementsKindGreaterThan(
|
||||
}
|
||||
|
||||
void EffectControlLinearizer::LowerTransitionAndStoreElement(Node* node) {
|
||||
DCHECK(!v8_flags.turboshaft);
|
||||
Node* array = node->InputAt(0);
|
||||
Node* index = node->InputAt(1);
|
||||
Node* value = node->InputAt(2);
|
||||
@ -7587,6 +7594,7 @@ void EffectControlLinearizer::LowerTransitionAndStoreElement(Node* node) {
|
||||
}
|
||||
|
||||
void EffectControlLinearizer::LowerTransitionAndStoreNumberElement(Node* node) {
|
||||
DCHECK(!v8_flags.turboshaft);
|
||||
Node* array = node->InputAt(0);
|
||||
Node* index = node->InputAt(1);
|
||||
Node* value = node->InputAt(2); // This is a Float64, not tagged.
|
||||
@ -7647,6 +7655,7 @@ void EffectControlLinearizer::LowerTransitionAndStoreNumberElement(Node* node) {
|
||||
|
||||
void EffectControlLinearizer::LowerTransitionAndStoreNonNumberElement(
|
||||
Node* node) {
|
||||
DCHECK(!v8_flags.turboshaft);
|
||||
Node* array = node->InputAt(0);
|
||||
Node* index = node->InputAt(1);
|
||||
Node* value = node->InputAt(2);
|
||||
@ -8272,6 +8281,7 @@ Maybe<Node*> EffectControlLinearizer::LowerFloat64RoundTruncate(Node* node) {
|
||||
}
|
||||
|
||||
Node* EffectControlLinearizer::LowerFindOrderedHashMapEntry(Node* node) {
|
||||
DCHECK(!v8_flags.turboshaft);
|
||||
Node* table = NodeProperties::GetValueInput(node, 0);
|
||||
Node* key = NodeProperties::GetValueInput(node, 1);
|
||||
|
||||
@ -8289,6 +8299,7 @@ Node* EffectControlLinearizer::LowerFindOrderedHashMapEntry(Node* node) {
|
||||
}
|
||||
|
||||
Node* EffectControlLinearizer::LowerFindOrderedHashSetEntry(Node* node) {
|
||||
DCHECK(!v8_flags.turboshaft);
|
||||
Node* table = NodeProperties::GetValueInput(node, 0);
|
||||
Node* key = NodeProperties::GetValueInput(node, 1);
|
||||
|
||||
@ -8320,6 +8331,7 @@ Node* EffectControlLinearizer::ComputeUnseededHash(Node* value) {
|
||||
|
||||
Node* EffectControlLinearizer::LowerFindOrderedHashMapEntryForInt32Key(
|
||||
Node* node) {
|
||||
DCHECK(!v8_flags.turboshaft);
|
||||
Node* table = NodeProperties::GetValueInput(node, 0);
|
||||
Node* key = NodeProperties::GetValueInput(node, 1);
|
||||
|
||||
|
@ -636,6 +636,7 @@ class AssemblerOpInterface {
|
||||
DECL_MULTI_REP_BINOP(WordMul, WordBinop, WordRepresentation, Mul)
|
||||
DECL_SINGLE_REP_BINOP_V(Word32Mul, WordBinop, Mul, Word32)
|
||||
DECL_SINGLE_REP_BINOP_V(Word64Mul, WordBinop, Mul, Word64)
|
||||
DECL_SINGLE_REP_BINOP_V(WordPtrMul, WordBinop, Mul, WordPtr)
|
||||
|
||||
DECL_MULTI_REP_BINOP(WordBitwiseAnd, WordBinop, WordRepresentation,
|
||||
BitwiseAnd)
|
||||
@ -1874,6 +1875,18 @@ class AssemblerOpInterface {
|
||||
typename BuiltinCallDescriptor::CopyFastSmiOrObjectElements>(
|
||||
isolate, context, {object});
|
||||
}
|
||||
V<Smi> CallBuiltin_FindOrderedHashMapEntry(Isolate* isolate,
|
||||
V<Context> context,
|
||||
V<Object> table, V<Smi> key) {
|
||||
return CallBuiltin<typename BuiltinCallDescriptor::FindOrderedHashMapEntry>(
|
||||
isolate, context, {table, key});
|
||||
}
|
||||
V<Smi> CallBuiltin_FindOrderedHashSetEntry(Isolate* isolate,
|
||||
V<Context> context, V<Object> set,
|
||||
V<Smi> key) {
|
||||
return CallBuiltin<typename BuiltinCallDescriptor::FindOrderedHashSetEntry>(
|
||||
isolate, context, {set, key});
|
||||
}
|
||||
V<Object> CallBuiltin_GrowFastDoubleElements(Isolate* isolate,
|
||||
V<Context> context,
|
||||
V<Object> object, V<Smi> size) {
|
||||
@ -2570,12 +2583,22 @@ class AssemblerOpInterface {
|
||||
is_little_endian, element_type);
|
||||
}
|
||||
|
||||
void StoreSignedSmallElement(V<Object> array, V<WordPtr> index,
|
||||
V<Word32> value) {
|
||||
void TransitionAndStoreArrayElement(
|
||||
V<Object> array, V<WordPtr> index, OpIndex value,
|
||||
TransitionAndStoreArrayElementOp::Kind kind, Handle<Map> fast_map,
|
||||
Handle<Map> double_map) {
|
||||
if (V8_UNLIKELY(stack().generating_unreachable_operations())) {
|
||||
return;
|
||||
}
|
||||
stack().ReduceStoreSignedSmallElement(array, index, value);
|
||||
stack().ReduceTransitionAndStoreArrayElement(array, index, value, kind,
|
||||
fast_map, double_map);
|
||||
}
|
||||
|
||||
void StoreSignedSmallElement(V<Object> array, V<WordPtr> index,
|
||||
V<Word32> value) {
|
||||
TransitionAndStoreArrayElement(
|
||||
array, index, value,
|
||||
TransitionAndStoreArrayElementOp::Kind::kSignedSmallElement, {}, {});
|
||||
}
|
||||
|
||||
V<Word32> CompareMaps(V<HeapObject> heap_object,
|
||||
@ -2683,6 +2706,28 @@ class AssemblerOpInterface {
|
||||
stack().ReduceTransitionElementsKind(object, transition);
|
||||
}
|
||||
|
||||
OpIndex FindOrderedHashEntry(V<Object> data_structure, OpIndex key,
|
||||
FindOrderedHashEntryOp::Kind kind) {
|
||||
if (V8_UNLIKELY(stack().generating_unreachable_operations())) {
|
||||
return OpIndex::Invalid();
|
||||
}
|
||||
return stack().ReduceFindOrderedHashEntry(data_structure, key, kind);
|
||||
}
|
||||
V<Smi> FindOrderedHashMapEntry(V<Object> table, V<Smi> key) {
|
||||
return FindOrderedHashEntry(
|
||||
table, key, FindOrderedHashEntryOp::Kind::kFindOrderedHashMapEntry);
|
||||
}
|
||||
V<Smi> FindOrderedHashSetEntry(V<Object> table, V<Smi> key) {
|
||||
return FindOrderedHashEntry(
|
||||
table, key, FindOrderedHashEntryOp::Kind::kFindOrderedHashSetEntry);
|
||||
}
|
||||
V<WordPtr> FindOrderedHashMapEntryForInt32Key(V<Object> table,
|
||||
V<Word32> key) {
|
||||
return FindOrderedHashEntry(
|
||||
table, key,
|
||||
FindOrderedHashEntryOp::Kind::kFindOrderedHashMapEntryForInt32Key);
|
||||
}
|
||||
|
||||
template <typename Rep>
|
||||
V<Rep> resolve(const V<Rep>& v) {
|
||||
return v;
|
||||
@ -2769,7 +2814,8 @@ class AssemblerOpInterface {
|
||||
if (!stack().Bind(else_block)) return false;
|
||||
Block* then_block = stack().NewBlock();
|
||||
info.else_block = stack().NewBlock();
|
||||
stack().Branch(condition_builder(), then_block, info.else_block);
|
||||
stack().Branch(ConditionWithHint{condition_builder()}, then_block,
|
||||
info.else_block);
|
||||
return stack().Bind(then_block);
|
||||
}
|
||||
|
||||
|
@ -95,6 +95,21 @@ struct BuiltinCallDescriptor {
|
||||
static constexpr Operator::Properties Properties = Operator::kEliminatable;
|
||||
};
|
||||
|
||||
template <Builtin B>
|
||||
struct FindOrderedHashEntry : public Descriptor<FindOrderedHashEntry<B>> {
|
||||
static constexpr auto Function = B;
|
||||
using arguments_t = std::tuple<V<Object>, V<Smi>>;
|
||||
using result_t = V<Smi>;
|
||||
|
||||
static constexpr bool NeedsFrameState = false;
|
||||
static constexpr bool NeedsContext = true;
|
||||
static constexpr Operator::Properties Properties = Operator::kEliminatable;
|
||||
};
|
||||
using FindOrderedHashMapEntry =
|
||||
FindOrderedHashEntry<Builtin::kFindOrderedHashMapEntry>;
|
||||
using FindOrderedHashSetEntry =
|
||||
FindOrderedHashEntry<Builtin::kFindOrderedHashSetEntry>;
|
||||
|
||||
template <Builtin B>
|
||||
struct GrowFastElements : public Descriptor<GrowFastElements<B>> {
|
||||
static constexpr auto Function = B;
|
||||
|
@ -1851,6 +1851,30 @@ OpIndex GraphBuilder::Process(
|
||||
Map(node->InputAt(4)),
|
||||
ExternalArrayTypeOf(node->op()));
|
||||
return OpIndex::Invalid();
|
||||
case IrOpcode::kTransitionAndStoreElement:
|
||||
__ TransitionAndStoreArrayElement(
|
||||
Map(node->InputAt(0)), Map(node->InputAt(1)), Map(node->InputAt(2)),
|
||||
TransitionAndStoreArrayElementOp::Kind::kElement,
|
||||
FastMapParameterOf(node->op()).object(),
|
||||
DoubleMapParameterOf(node->op()).object());
|
||||
return OpIndex::Invalid();
|
||||
case IrOpcode::kTransitionAndStoreNumberElement:
|
||||
__ TransitionAndStoreArrayElement(
|
||||
Map(node->InputAt(0)), Map(node->InputAt(1)), Map(node->InputAt(2)),
|
||||
TransitionAndStoreArrayElementOp::Kind::kNumberElement, {},
|
||||
DoubleMapParameterOf(node->op()).object());
|
||||
return OpIndex::Invalid();
|
||||
case IrOpcode::kTransitionAndStoreNonNumberElement: {
|
||||
auto kind =
|
||||
ValueTypeParameterOf(node->op())
|
||||
.Is(compiler::Type::BooleanOrNullOrUndefined())
|
||||
? TransitionAndStoreArrayElementOp::Kind::kOddballElement
|
||||
: TransitionAndStoreArrayElementOp::Kind::kNonNumberElement;
|
||||
__ TransitionAndStoreArrayElement(
|
||||
Map(node->InputAt(0)), Map(node->InputAt(1)), Map(node->InputAt(2)),
|
||||
kind, FastMapParameterOf(node->op()).object(), {});
|
||||
return OpIndex::Invalid();
|
||||
}
|
||||
case IrOpcode::kStoreSignedSmallElement:
|
||||
__ StoreSignedSmallElement(Map(node->InputAt(0)), Map(node->InputAt(1)),
|
||||
Map(node->InputAt(2)));
|
||||
@ -2070,6 +2094,16 @@ OpIndex GraphBuilder::Process(
|
||||
return OpIndex::Invalid();
|
||||
}
|
||||
|
||||
case IrOpcode::kFindOrderedHashMapEntry:
|
||||
return __ FindOrderedHashMapEntry(Map(node->InputAt(0)),
|
||||
Map(node->InputAt(1)));
|
||||
case IrOpcode::kFindOrderedHashSetEntry:
|
||||
return __ FindOrderedHashSetEntry(Map(node->InputAt(0)),
|
||||
Map(node->InputAt(1)));
|
||||
case IrOpcode::kFindOrderedHashMapEntryForInt32Key:
|
||||
return __ FindOrderedHashMapEntryForInt32Key(Map(node->InputAt(0)),
|
||||
Map(node->InputAt(1)));
|
||||
|
||||
case IrOpcode::kBeginRegion:
|
||||
return OpIndex::Invalid();
|
||||
case IrOpcode::kFinishRegion:
|
||||
|
@ -2028,50 +2028,244 @@ class MachineLoweringReducer : public Next {
|
||||
return {};
|
||||
}
|
||||
|
||||
OpIndex REDUCE(StoreSignedSmallElement)(V<JSArray> array, V<WordPtr> index,
|
||||
V<Word32> value) {
|
||||
// Store a signed small in an output array.
|
||||
//
|
||||
// kind = ElementsKind(array)
|
||||
//
|
||||
// -- STORE PHASE ----------------------
|
||||
// if kind == HOLEY_DOUBLE_ELEMENTS {
|
||||
// float_value = convert int32 to float
|
||||
// Store array[index] = float_value
|
||||
// } else {
|
||||
// // kind is HOLEY_SMI_ELEMENTS or HOLEY_ELEMENTS
|
||||
// smi_value = convert int32 to smi
|
||||
// Store array[index] = smi_value
|
||||
// }
|
||||
//
|
||||
OpIndex REDUCE(TransitionAndStoreArrayElement)(
|
||||
V<JSArray> array, V<WordPtr> index, OpIndex value,
|
||||
TransitionAndStoreArrayElementOp::Kind kind, Handle<Map> fast_map,
|
||||
Handle<Map> double_map) {
|
||||
V<Map> map = __ LoadMapField(array);
|
||||
V<Word32> bitfield2 =
|
||||
__ template LoadField<Word32>(map, AccessBuilder::ForMapBitField2());
|
||||
V<Word32> kind = __ Word32ShiftRightLogical(
|
||||
V<Word32> elements_kind = __ Word32ShiftRightLogical(
|
||||
__ Word32BitwiseAnd(bitfield2, Map::Bits2::ElementsKindBits::kMask),
|
||||
Map::Bits2::ElementsKindBits::kShift);
|
||||
|
||||
V<Object> elements = __ template LoadField<Object>(
|
||||
array, AccessBuilder::ForJSObjectElements());
|
||||
IF(__ Int32LessThan(HOLEY_ELEMENTS, kind)) {
|
||||
// Our ElementsKind is HOLEY_DOUBLE_ELEMENTS.
|
||||
V<Float64> f64 = __ ChangeInt32ToFloat64(value);
|
||||
__ StoreElement(elements, AccessBuilder::ForFixedDoubleArrayElement(),
|
||||
index, f64);
|
||||
}
|
||||
ELSE {
|
||||
// Our ElementsKind is HOLEY_SMI_ELEMENTS or HOLEY_ELEMENTS.
|
||||
// In this case, we know our value is a signed small, and we can optimize
|
||||
// the ElementAccess information.
|
||||
ElementAccess access = AccessBuilder::ForFixedArrayElement();
|
||||
access.type = compiler::Type::SignedSmall();
|
||||
access.machine_type = MachineType::TaggedSigned();
|
||||
access.write_barrier_kind = kNoWriteBarrier;
|
||||
__ StoreElement(elements, access, index, __ SmiTag(value));
|
||||
}
|
||||
END_IF
|
||||
switch (kind) {
|
||||
case TransitionAndStoreArrayElementOp::Kind::kElement: {
|
||||
// Possibly transition array based on input and store.
|
||||
//
|
||||
// -- TRANSITION PHASE -----------------
|
||||
// kind = ElementsKind(array)
|
||||
// if value is not smi {
|
||||
// if kind == HOLEY_SMI_ELEMENTS {
|
||||
// if value is heap number {
|
||||
// Transition array to HOLEY_DOUBLE_ELEMENTS
|
||||
// kind = HOLEY_DOUBLE_ELEMENTS
|
||||
// } else {
|
||||
// Transition array to HOLEY_ELEMENTS
|
||||
// kind = HOLEY_ELEMENTS
|
||||
// }
|
||||
// } else if kind == HOLEY_DOUBLE_ELEMENTS {
|
||||
// if value is not heap number {
|
||||
// Transition array to HOLEY_ELEMENTS
|
||||
// kind = HOLEY_ELEMENTS
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// -- STORE PHASE ----------------------
|
||||
// [make sure {kind} is up-to-date]
|
||||
// if kind == HOLEY_DOUBLE_ELEMENTS {
|
||||
// if value is smi {
|
||||
// float_value = convert smi to float
|
||||
// Store array[index] = float_value
|
||||
// } else {
|
||||
// float_value = value
|
||||
// Store array[index] = float_value
|
||||
// }
|
||||
// } else {
|
||||
// // kind is HOLEY_SMI_ELEMENTS or HOLEY_ELEMENTS
|
||||
// Store array[index] = value
|
||||
// }
|
||||
//
|
||||
Label<Word32> do_store(this);
|
||||
// We can store a smi anywhere.
|
||||
GOTO_IF(__ ObjectIsSmi(value), do_store, elements_kind);
|
||||
|
||||
return {};
|
||||
// {value} is a HeapObject.
|
||||
IF_NOT (LIKELY(__ Int32LessThan(HOLEY_SMI_ELEMENTS, elements_kind))) {
|
||||
// Transition {array} from HOLEY_SMI_ELEMENTS to HOLEY_DOUBLE_ELEMENTS
|
||||
// or to HOLEY_ELEMENTS.
|
||||
V<Map> value_map = __ LoadMapField(value);
|
||||
IF (__ TaggedEqual(value_map,
|
||||
__ HeapConstant(factory_->heap_number_map()))) {
|
||||
// {value} is a HeapNumber.
|
||||
TransitionElementsTo(array, HOLEY_SMI_ELEMENTS,
|
||||
HOLEY_DOUBLE_ELEMENTS, double_map);
|
||||
GOTO(do_store, HOLEY_DOUBLE_ELEMENTS);
|
||||
}
|
||||
ELSE {
|
||||
TransitionElementsTo(array, HOLEY_SMI_ELEMENTS, HOLEY_ELEMENTS,
|
||||
fast_map);
|
||||
GOTO(do_store, HOLEY_ELEMENTS);
|
||||
}
|
||||
END_IF
|
||||
}
|
||||
END_IF
|
||||
|
||||
GOTO_IF_NOT(LIKELY(__ Int32LessThan(HOLEY_ELEMENTS, elements_kind)),
|
||||
do_store, elements_kind);
|
||||
|
||||
// We have double elements kind. Only a HeapNumber can be stored
|
||||
// without effecting a transition.
|
||||
V<Map> value_map = __ LoadMapField(value);
|
||||
IF_NOT (UNLIKELY(__ TaggedEqual(
|
||||
value_map, __ HeapConstant(factory_->heap_number_map())))) {
|
||||
TransitionElementsTo(array, HOLEY_DOUBLE_ELEMENTS, HOLEY_ELEMENTS,
|
||||
fast_map);
|
||||
GOTO(do_store, HOLEY_ELEMENTS);
|
||||
}
|
||||
END_IF
|
||||
|
||||
GOTO(do_store, elements_kind);
|
||||
|
||||
BIND(do_store, store_kind);
|
||||
V<Object> elements = __ template LoadField<Object>(
|
||||
array, AccessBuilder::ForJSObjectElements());
|
||||
IF (__ Int32LessThan(HOLEY_ELEMENTS, store_kind)) {
|
||||
// Our ElementsKind is HOLEY_DOUBLE_ELEMENTS.
|
||||
IF (__ ObjectIsSmi(value)) {
|
||||
V<Float64> float_value =
|
||||
__ ChangeInt32ToFloat64(__ SmiUntag(value));
|
||||
__ StoreElement(elements,
|
||||
AccessBuilder::ForFixedDoubleArrayElement(), index,
|
||||
float_value);
|
||||
}
|
||||
ELSE {
|
||||
V<Float64> float_value = __ template LoadField<Float64>(
|
||||
V<HeapObject>::Cast(value),
|
||||
AccessBuilder::ForHeapNumberValue());
|
||||
__ StoreElement(elements,
|
||||
AccessBuilder::ForFixedDoubleArrayElement(), index,
|
||||
__ Float64SilenceNaN(float_value));
|
||||
}
|
||||
END_IF
|
||||
}
|
||||
ELSE {
|
||||
// Our ElementsKind is HOLEY_SMI_ELEMENTS or HOLEY_ELEMENTS.
|
||||
__ StoreElement(elements,
|
||||
AccessBuilder::ForFixedArrayElement(HOLEY_ELEMENTS),
|
||||
index, value);
|
||||
}
|
||||
END_IF
|
||||
break;
|
||||
}
|
||||
case TransitionAndStoreArrayElementOp::Kind::kNumberElement: {
|
||||
// Possibly transition array based on input and store.
|
||||
//
|
||||
// -- TRANSITION PHASE -----------------
|
||||
// kind = ElementsKind(array)
|
||||
// if kind == HOLEY_SMI_ELEMENTS {
|
||||
// Transition array to HOLEY_DOUBLE_ELEMENTS
|
||||
// } else if kind != HOLEY_DOUBLE_ELEMENTS {
|
||||
// This is UNREACHABLE, execute a debug break.
|
||||
// }
|
||||
//
|
||||
// -- STORE PHASE ----------------------
|
||||
// Store array[index] = value (it's a float)
|
||||
//
|
||||
// {value} is a float64.
|
||||
IF_NOT (LIKELY(__ Int32LessThan(HOLEY_SMI_ELEMENTS, elements_kind))) {
|
||||
// Transition {array} from HOLEY_SMI_ELEMENTS to
|
||||
// HOLEY_DOUBLE_ELEMENTS.
|
||||
TransitionElementsTo(array, HOLEY_SMI_ELEMENTS, HOLEY_DOUBLE_ELEMENTS,
|
||||
double_map);
|
||||
}
|
||||
ELSE {
|
||||
// We expect that our input array started at HOLEY_SMI_ELEMENTS, and
|
||||
// climbs the lattice up to HOLEY_DOUBLE_ELEMENTS. Force a debug break
|
||||
// if this assumption is broken. It also would be the case that
|
||||
// loop peeling can break this assumption.
|
||||
IF_NOT (LIKELY(
|
||||
__ Word32Equal(elements_kind, HOLEY_DOUBLE_ELEMENTS))) {
|
||||
__ Unreachable();
|
||||
}
|
||||
END_IF
|
||||
}
|
||||
END_IF
|
||||
|
||||
V<Object> elements = __ template LoadField<Object>(
|
||||
array, AccessBuilder::ForJSObjectElements());
|
||||
__ StoreElement(elements, AccessBuilder::ForFixedDoubleArrayElement(),
|
||||
index, __ Float64SilenceNaN(value));
|
||||
break;
|
||||
}
|
||||
case TransitionAndStoreArrayElementOp::Kind::kOddballElement:
|
||||
case TransitionAndStoreArrayElementOp::Kind::kNonNumberElement: {
|
||||
// Possibly transition array based on input and store.
|
||||
//
|
||||
// -- TRANSITION PHASE -----------------
|
||||
// kind = ElementsKind(array)
|
||||
// if kind == HOLEY_SMI_ELEMENTS {
|
||||
// Transition array to HOLEY_ELEMENTS
|
||||
// } else if kind == HOLEY_DOUBLE_ELEMENTS {
|
||||
// Transition array to HOLEY_ELEMENTS
|
||||
// }
|
||||
//
|
||||
// -- STORE PHASE ----------------------
|
||||
// // kind is HOLEY_ELEMENTS
|
||||
// Store array[index] = value
|
||||
//
|
||||
IF_NOT (LIKELY(__ Int32LessThan(HOLEY_SMI_ELEMENTS, elements_kind))) {
|
||||
// Transition {array} from HOLEY_SMI_ELEMENTS to HOLEY_ELEMENTS.
|
||||
TransitionElementsTo(array, HOLEY_SMI_ELEMENTS, HOLEY_ELEMENTS,
|
||||
fast_map);
|
||||
}
|
||||
ELSE_IF (UNLIKELY(__ Int32LessThan(HOLEY_ELEMENTS, elements_kind))) {
|
||||
TransitionElementsTo(array, HOLEY_DOUBLE_ELEMENTS, HOLEY_ELEMENTS,
|
||||
fast_map);
|
||||
}
|
||||
END_IF
|
||||
|
||||
V<Object> elements = __ template LoadField<Object>(
|
||||
array, AccessBuilder::ForJSObjectElements());
|
||||
ElementAccess access =
|
||||
AccessBuilder::ForFixedArrayElement(HOLEY_ELEMENTS);
|
||||
if (kind == TransitionAndStoreArrayElementOp::Kind::kOddballElement) {
|
||||
access.type = compiler::Type::BooleanOrNullOrUndefined();
|
||||
access.write_barrier_kind = kNoWriteBarrier;
|
||||
}
|
||||
__ StoreElement(elements, access, index, value);
|
||||
break;
|
||||
}
|
||||
case TransitionAndStoreArrayElementOp::Kind::kSignedSmallElement: {
|
||||
// Store a signed small in an output array.
|
||||
//
|
||||
// kind = ElementsKind(array)
|
||||
//
|
||||
// -- STORE PHASE ----------------------
|
||||
// if kind == HOLEY_DOUBLE_ELEMENTS {
|
||||
// float_value = convert int32 to float
|
||||
// Store array[index] = float_value
|
||||
// } else {
|
||||
// // kind is HOLEY_SMI_ELEMENTS or HOLEY_ELEMENTS
|
||||
// smi_value = convert int32 to smi
|
||||
// Store array[index] = smi_value
|
||||
// }
|
||||
//
|
||||
V<Object> elements = __ template LoadField<Object>(
|
||||
array, AccessBuilder::ForJSObjectElements());
|
||||
IF (__ Int32LessThan(HOLEY_ELEMENTS, elements_kind)) {
|
||||
// Our ElementsKind is HOLEY_DOUBLE_ELEMENTS.
|
||||
V<Float64> f64 = __ ChangeInt32ToFloat64(value);
|
||||
__ StoreElement(elements, AccessBuilder::ForFixedDoubleArrayElement(),
|
||||
index, f64);
|
||||
}
|
||||
ELSE {
|
||||
// Our ElementsKind is HOLEY_SMI_ELEMENTS or HOLEY_ELEMENTS.
|
||||
// In this case, we know our value is a signed small, and we can
|
||||
// optimize the ElementAccess information.
|
||||
ElementAccess access = AccessBuilder::ForFixedArrayElement();
|
||||
access.type = compiler::Type::SignedSmall();
|
||||
access.machine_type = MachineType::TaggedSigned();
|
||||
access.write_barrier_kind = kNoWriteBarrier;
|
||||
__ StoreElement(elements, access, index, __ SmiTag(value));
|
||||
}
|
||||
END_IF
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return OpIndex::Invalid();
|
||||
}
|
||||
|
||||
V<Word32> REDUCE(CompareMaps)(V<HeapObject> heap_object,
|
||||
@ -2553,24 +2747,78 @@ class MachineLoweringReducer : public Next {
|
||||
return OpIndex::Invalid();
|
||||
}
|
||||
|
||||
// TODO(nicohartmann@): Remove this once ECL has been fully ported.
|
||||
// ECL: ChangeInt64ToSmi(input) ==> MLR: __ SmiTag(input)
|
||||
// ECL: ChangeInt32ToSmi(input) ==> MLR: __ SmiTag(input)
|
||||
// ECL: ChangeUint32ToSmi(input) ==> MLR: __ SmiTag(input)
|
||||
// ECL: ChangeUint64ToSmi(input) ==> MLR: __ SmiTag(input)
|
||||
// ECL: ChangeIntPtrToSmi(input) ==> MLR: __ SmiTag(input)
|
||||
// ECL: ChangeFloat64ToTagged(i, m) ==> MLR: __ ConvertFloat64ToNumber(i, m)
|
||||
// ECL: ChangeSmiToIntPtr(input)
|
||||
// ==> MLR: __ ChangeInt32ToIntPtr(__ SmiUntag(input))
|
||||
// ECL: ChangeSmiToInt32(input) ==> MLR: __ SmiUntag(input)
|
||||
// ECL: ChangeSmiToInt64(input) ==> MLR: __ ChangeInt32ToInt64(__
|
||||
// SmiUntag(input))
|
||||
// ECL: BuildCheckedHeapNumberOrOddballToFloat64 ==> MLR:
|
||||
// ConvertHeapObjectToFloat64OrDeopt
|
||||
OpIndex REDUCE(FindOrderedHashEntry)(V<Object> data_structure, OpIndex key,
|
||||
FindOrderedHashEntryOp::Kind kind) {
|
||||
switch (kind) {
|
||||
case FindOrderedHashEntryOp::Kind::kFindOrderedHashMapEntry:
|
||||
return __ CallBuiltin_FindOrderedHashMapEntry(
|
||||
isolate_, __ NoContextConstant(), data_structure, key);
|
||||
case FindOrderedHashEntryOp::Kind::kFindOrderedHashMapEntryForInt32Key: {
|
||||
// Compute the integer hash code.
|
||||
V<WordPtr> hash = __ ChangeUint32ToUintPtr(ComputeUnseededHash(key));
|
||||
|
||||
V<WordPtr> number_of_buckets =
|
||||
__ ChangeInt32ToIntPtr(__ SmiUntag(__ template LoadField<Smi>(
|
||||
data_structure,
|
||||
AccessBuilder::ForOrderedHashMapOrSetNumberOfBuckets())));
|
||||
hash = __ WordPtrBitwiseAnd(hash, __ WordPtrSub(number_of_buckets, 1));
|
||||
V<WordPtr> first_entry = __ ChangeInt32ToIntPtr(__ SmiUntag(__ Load(
|
||||
data_structure,
|
||||
__ WordPtrAdd(__ WordPtrShiftLeft(hash, kTaggedSizeLog2),
|
||||
OrderedHashMap::HashTableStartOffset()),
|
||||
LoadOp::Kind::TaggedBase(), MemoryRepresentation::TaggedSigned())));
|
||||
|
||||
Label<WordPtr> done(this);
|
||||
LoopLabel<WordPtr> loop(this);
|
||||
GOTO(loop, first_entry);
|
||||
|
||||
LOOP(loop, entry) {
|
||||
GOTO_IF(__ WordPtrEqual(entry, OrderedHashMap::kNotFound), done,
|
||||
entry);
|
||||
V<WordPtr> candidate =
|
||||
__ WordPtrAdd(__ WordPtrMul(entry, OrderedHashMap::kEntrySize),
|
||||
number_of_buckets);
|
||||
V<Object> candidate_key = __ Load(
|
||||
data_structure,
|
||||
__ WordPtrAdd(__ WordPtrShiftLeft(candidate, kTaggedSizeLog2),
|
||||
OrderedHashMap::HashTableStartOffset()),
|
||||
LoadOp::Kind::TaggedBase(), MemoryRepresentation::AnyTagged());
|
||||
|
||||
IF (LIKELY(__ ObjectIsSmi(candidate_key))) {
|
||||
GOTO_IF(__ Word32Equal(__ SmiUntag(candidate_key), key), done,
|
||||
candidate);
|
||||
}
|
||||
ELSE_IF (__ TaggedEqual(
|
||||
__ LoadMapField(candidate_key),
|
||||
__ HeapConstant(factory_->heap_number_map()))) {
|
||||
GOTO_IF(__ Float64Equal(
|
||||
__ template LoadField<Float64>(
|
||||
candidate_key, AccessBuilder::ForHeapNumberValue()),
|
||||
__ ChangeInt32ToFloat64(key)),
|
||||
done, candidate);
|
||||
}
|
||||
END_IF
|
||||
|
||||
V<WordPtr> next_entry = __ ChangeInt32ToIntPtr(__ SmiUntag(__ Load(
|
||||
data_structure,
|
||||
__ WordPtrAdd(__ WordPtrShiftLeft(entry, kTaggedSizeLog2),
|
||||
(OrderedHashMap::HashTableStartOffset() +
|
||||
OrderedHashMap::kChainOffset * kTaggedSize)),
|
||||
LoadOp::Kind::TaggedBase(),
|
||||
MemoryRepresentation::TaggedSigned())));
|
||||
GOTO(loop, next_entry);
|
||||
}
|
||||
|
||||
BIND(done, result);
|
||||
return result;
|
||||
}
|
||||
case FindOrderedHashEntryOp::Kind::kFindOrderedHashSetEntry:
|
||||
return __ CallBuiltin_FindOrderedHashSetEntry(
|
||||
isolate_, __ NoContextConstant(), data_structure, key);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
// TODO(nicohartmann@): Might move some of those helpers into the assembler
|
||||
// interface.
|
||||
// Pass {bitfield} = {digit} = OpIndex::Invalid() to construct the canonical
|
||||
// 0n BigInt.
|
||||
V<BigInt> AllocateBigInt(V<Word32> bitfield, V<Word64> digit) {
|
||||
@ -2819,6 +3067,34 @@ class MachineLoweringReducer : public Next {
|
||||
}
|
||||
}
|
||||
|
||||
V<Word32> ComputeUnseededHash(V<Word32> value) {
|
||||
// See v8::internal::ComputeUnseededHash()
|
||||
value = __ Word32Add(__ Word32BitwiseXor(value, 0xFFFFFFFF),
|
||||
__ Word32ShiftLeft(value, 15));
|
||||
value = __ Word32BitwiseXor(value, __ Word32ShiftRightLogical(value, 12));
|
||||
value = __ Word32Add(value, __ Word32ShiftLeft(value, 2));
|
||||
value = __ Word32BitwiseXor(value, __ Word32ShiftRightLogical(value, 4));
|
||||
value = __ Word32Mul(value, 2057);
|
||||
value = __ Word32BitwiseXor(value, __ Word32ShiftRightLogical(value, 16));
|
||||
value = __ Word32BitwiseAnd(value, 0x3FFFFFFF);
|
||||
return value;
|
||||
}
|
||||
|
||||
void TransitionElementsTo(V<JSArray> array, ElementsKind from,
|
||||
ElementsKind to, Handle<Map> target_map) {
|
||||
DCHECK(IsMoreGeneralElementsKindTransition(from, to));
|
||||
DCHECK(to == HOLEY_ELEMENTS || to == HOLEY_DOUBLE_ELEMENTS);
|
||||
|
||||
if (IsSimpleMapChangeTransition(from, to)) {
|
||||
__ StoreField(array, AccessBuilder::ForMap(),
|
||||
__ HeapConstant(target_map));
|
||||
} else {
|
||||
// Instance migration, call out to the runtime for {array}.
|
||||
__ CallRuntime_TransitionElementsKind(isolate_, __ NoContextConstant(),
|
||||
array, __ HeapConstant(target_map));
|
||||
}
|
||||
}
|
||||
|
||||
Factory* factory_;
|
||||
Isolate* isolate_;
|
||||
};
|
||||
|
@ -1060,6 +1060,22 @@ std::ostream& operator<<(std::ostream& os, ArgumentsLengthOp::Kind kind) {
|
||||
}
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os,
|
||||
TransitionAndStoreArrayElementOp::Kind kind) {
|
||||
switch (kind) {
|
||||
case TransitionAndStoreArrayElementOp::Kind::kElement:
|
||||
return os << "Element";
|
||||
case TransitionAndStoreArrayElementOp::Kind::kNumberElement:
|
||||
return os << "NumberElement";
|
||||
case TransitionAndStoreArrayElementOp::Kind::kOddballElement:
|
||||
return os << "OddballElement";
|
||||
case TransitionAndStoreArrayElementOp::Kind::kNonNumberElement:
|
||||
return os << "NonNumberElement";
|
||||
case TransitionAndStoreArrayElementOp::Kind::kSignedSmallElement:
|
||||
return os << "SignedSmallElement";
|
||||
}
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, SameValueOp::Mode mode) {
|
||||
switch (mode) {
|
||||
case SameValueOp::Mode::kSameValue:
|
||||
@ -1069,6 +1085,17 @@ std::ostream& operator<<(std::ostream& os, SameValueOp::Mode mode) {
|
||||
}
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, FindOrderedHashEntryOp::Kind kind) {
|
||||
switch (kind) {
|
||||
case FindOrderedHashEntryOp::Kind::kFindOrderedHashMapEntry:
|
||||
return os << "FindOrderedHashMapEntry";
|
||||
case FindOrderedHashEntryOp::Kind::kFindOrderedHashMapEntryForInt32Key:
|
||||
return os << "FindOrderedHashMapEntryForInt32Key";
|
||||
case FindOrderedHashEntryOp::Kind::kFindOrderedHashSetEntry:
|
||||
return os << "FindOrderedHashSetEntry";
|
||||
}
|
||||
}
|
||||
|
||||
std::string Operation::ToString() const {
|
||||
std::stringstream ss;
|
||||
ss << *this;
|
||||
|
@ -163,7 +163,7 @@ struct FrameStateOp;
|
||||
V(LoadStackArgument) \
|
||||
V(StoreTypedElement) \
|
||||
V(StoreDataViewElement) \
|
||||
V(StoreSignedSmallElement) \
|
||||
V(TransitionAndStoreArrayElement) \
|
||||
V(CompareMaps) \
|
||||
V(CheckMaps) \
|
||||
V(CheckedClosure) \
|
||||
@ -176,7 +176,8 @@ struct FrameStateOp;
|
||||
V(RuntimeAbort) \
|
||||
V(EnsureWritableFastElements) \
|
||||
V(MaybeGrowFastElements) \
|
||||
V(TransitionElementsKind)
|
||||
V(TransitionElementsKind) \
|
||||
V(FindOrderedHashEntry)
|
||||
|
||||
enum class Opcode : uint8_t {
|
||||
#define ENUM_CONSTANT(Name) k##Name,
|
||||
@ -3672,8 +3673,19 @@ struct StoreDataViewElementOp
|
||||
auto options() const { return std::tuple{element_type}; }
|
||||
};
|
||||
|
||||
struct StoreSignedSmallElementOp
|
||||
: FixedArityOperationT<3, StoreSignedSmallElementOp> {
|
||||
struct TransitionAndStoreArrayElementOp
|
||||
: FixedArityOperationT<3, TransitionAndStoreArrayElementOp> {
|
||||
enum class Kind : uint8_t {
|
||||
kElement,
|
||||
kNumberElement,
|
||||
kOddballElement,
|
||||
kNonNumberElement,
|
||||
kSignedSmallElement,
|
||||
};
|
||||
Kind kind;
|
||||
Handle<Map> fast_map;
|
||||
Handle<Map> double_map;
|
||||
|
||||
static constexpr OpProperties properties = OpProperties::Writing();
|
||||
base::Vector<const RegisterRepresentation> outputs_rep() const { return {}; }
|
||||
|
||||
@ -3681,18 +3693,52 @@ struct StoreSignedSmallElementOp
|
||||
OpIndex index() const { return Base::input(1); }
|
||||
OpIndex value() const { return Base::input(2); }
|
||||
|
||||
StoreSignedSmallElementOp(OpIndex array, OpIndex index, OpIndex value)
|
||||
: Base(array, index, value) {}
|
||||
TransitionAndStoreArrayElementOp(OpIndex array, OpIndex index, OpIndex value,
|
||||
Kind kind, Handle<Map> fast_map,
|
||||
Handle<Map> double_map)
|
||||
: Base(array, index, value),
|
||||
kind(kind),
|
||||
fast_map(fast_map),
|
||||
double_map(double_map) {}
|
||||
|
||||
void Validate(const Graph& graph) const {
|
||||
DCHECK(ValidOpInputRep(graph, array(), RegisterRepresentation::Tagged()));
|
||||
DCHECK(ValidOpInputRep(graph, index(),
|
||||
RegisterRepresentation::PointerSized()));
|
||||
DCHECK(ValidOpInputRep(graph, value(), RegisterRepresentation::Word32()));
|
||||
switch (kind) {
|
||||
case Kind::kElement:
|
||||
DCHECK(
|
||||
ValidOpInputRep(graph, value(), RegisterRepresentation::Tagged()));
|
||||
break;
|
||||
case Kind::kNumberElement:
|
||||
DCHECK(
|
||||
ValidOpInputRep(graph, value(), RegisterRepresentation::Float64()));
|
||||
break;
|
||||
case Kind::kOddballElement:
|
||||
case Kind::kNonNumberElement:
|
||||
DCHECK(
|
||||
ValidOpInputRep(graph, value(), RegisterRepresentation::Tagged()));
|
||||
break;
|
||||
case Kind::kSignedSmallElement:
|
||||
DCHECK(
|
||||
ValidOpInputRep(graph, value(), RegisterRepresentation::Word32()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
auto options() const { return std::tuple{}; }
|
||||
size_t hash_value() const {
|
||||
return fast_hash_combine(kind, fast_map.address(), double_map.address());
|
||||
}
|
||||
|
||||
bool operator==(const TransitionAndStoreArrayElementOp& other) const {
|
||||
return kind == other.kind && fast_map.equals(other.fast_map) &&
|
||||
double_map.equals(other.double_map);
|
||||
}
|
||||
|
||||
auto options() const { return std::tuple{kind, fast_map, double_map}; }
|
||||
};
|
||||
std::ostream& operator<<(std::ostream& os,
|
||||
TransitionAndStoreArrayElementOp::Kind kind);
|
||||
|
||||
struct CompareMapsOp : FixedArityOperationT<1, CompareMapsOp> {
|
||||
ZoneRefSet<Map> maps;
|
||||
@ -4085,6 +4131,45 @@ struct TransitionElementsKindOp
|
||||
auto options() const { return std::tuple{transition}; }
|
||||
};
|
||||
|
||||
struct FindOrderedHashEntryOp
|
||||
: FixedArityOperationT<2, FindOrderedHashEntryOp> {
|
||||
enum class Kind : uint8_t {
|
||||
kFindOrderedHashMapEntry,
|
||||
kFindOrderedHashMapEntryForInt32Key,
|
||||
kFindOrderedHashSetEntry,
|
||||
};
|
||||
Kind kind;
|
||||
|
||||
static constexpr OpProperties properties = OpProperties::AnySideEffects();
|
||||
base::Vector<const RegisterRepresentation> outputs_rep() const {
|
||||
switch (kind) {
|
||||
case Kind::kFindOrderedHashMapEntry:
|
||||
case Kind::kFindOrderedHashSetEntry:
|
||||
return RepVector<RegisterRepresentation::Tagged()>();
|
||||
case Kind::kFindOrderedHashMapEntryForInt32Key:
|
||||
return RepVector<RegisterRepresentation::PointerSized()>();
|
||||
}
|
||||
}
|
||||
|
||||
OpIndex data_structure() const { return Base::input(0); }
|
||||
OpIndex key() const { return Base::input(1); }
|
||||
|
||||
FindOrderedHashEntryOp(OpIndex data_structure, OpIndex key, Kind kind)
|
||||
: Base(data_structure, key), kind(kind) {}
|
||||
|
||||
void Validate(const Graph& graph) const {
|
||||
DCHECK(ValidOpInputRep(graph, data_structure(),
|
||||
RegisterRepresentation::Tagged()));
|
||||
DCHECK(ValidOpInputRep(graph, key(),
|
||||
kind == Kind::kFindOrderedHashMapEntryForInt32Key
|
||||
? RegisterRepresentation::Word32()
|
||||
: RegisterRepresentation::Tagged()));
|
||||
}
|
||||
|
||||
auto options() const { return std::tuple{kind}; }
|
||||
};
|
||||
std::ostream& operator<<(std::ostream& os, FindOrderedHashEntryOp::Kind kind);
|
||||
|
||||
#define OPERATION_PROPERTIES_CASE(Name) Name##Op::PropertiesIfStatic(),
|
||||
static constexpr base::Optional<OpProperties>
|
||||
kOperationPropertiesTable[kNumberOfOpcodes] = {
|
||||
|
@ -862,11 +862,11 @@ class GraphVisitor {
|
||||
MapToNewGraph(op.index()), MapToNewGraph(op.value()),
|
||||
MapToNewGraph(op.is_little_endian()), op.element_type);
|
||||
}
|
||||
OpIndex AssembleOutputGraphStoreSignedSmallElement(
|
||||
const StoreSignedSmallElementOp& op) {
|
||||
return assembler().ReduceStoreSignedSmallElement(MapToNewGraph(op.array()),
|
||||
MapToNewGraph(op.index()),
|
||||
MapToNewGraph(op.value()));
|
||||
OpIndex AssembleOutputGraphTransitionAndStoreArrayElement(
|
||||
const TransitionAndStoreArrayElementOp& op) {
|
||||
return assembler().ReduceTransitionAndStoreArrayElement(
|
||||
MapToNewGraph(op.array()), MapToNewGraph(op.index()),
|
||||
MapToNewGraph(op.value()), op.kind, op.fast_map, op.double_map);
|
||||
}
|
||||
OpIndex AssembleOutputGraphCompareMaps(const CompareMapsOp& op) {
|
||||
return assembler().ReduceCompareMaps(MapToNewGraph(op.heap_object()),
|
||||
@ -929,6 +929,11 @@ class GraphVisitor {
|
||||
return assembler().ReduceTransitionElementsKind(MapToNewGraph(op.object()),
|
||||
op.transition);
|
||||
}
|
||||
OpIndex AssembleOutputGraphFindOrderedHashEntry(
|
||||
const FindOrderedHashEntryOp& op) {
|
||||
return assembler().ReduceFindOrderedHashEntry(
|
||||
MapToNewGraph(op.data_structure()), MapToNewGraph(op.key()), op.kind);
|
||||
}
|
||||
|
||||
void CreateOldToNewMapping(OpIndex old_index, OpIndex new_index) {
|
||||
if (current_block_needs_variables_) {
|
||||
|
@ -202,6 +202,7 @@ SHOULD_HAVE_BEEN_LOWERED(DecodeExternalPointer)
|
||||
SHOULD_HAVE_BEEN_LOWERED(DoubleArrayMinMax)
|
||||
SHOULD_HAVE_BEEN_LOWERED(EnsureWritableFastElements)
|
||||
SHOULD_HAVE_BEEN_LOWERED(FastApiCall)
|
||||
SHOULD_HAVE_BEEN_LOWERED(FindOrderedHashEntry)
|
||||
SHOULD_HAVE_BEEN_LOWERED(FloatIs)
|
||||
SHOULD_HAVE_BEEN_LOWERED(Float64SameValue)
|
||||
SHOULD_HAVE_BEEN_LOWERED(LoadDataViewElement)
|
||||
@ -219,7 +220,6 @@ SHOULD_HAVE_BEEN_LOWERED(RuntimeAbort)
|
||||
SHOULD_HAVE_BEEN_LOWERED(SameValue)
|
||||
SHOULD_HAVE_BEEN_LOWERED(StoreDataViewElement)
|
||||
SHOULD_HAVE_BEEN_LOWERED(StoreMessage)
|
||||
SHOULD_HAVE_BEEN_LOWERED(StoreSignedSmallElement)
|
||||
SHOULD_HAVE_BEEN_LOWERED(StoreTypedElement)
|
||||
SHOULD_HAVE_BEEN_LOWERED(StringAt)
|
||||
SHOULD_HAVE_BEEN_LOWERED(StringComparison)
|
||||
@ -233,6 +233,7 @@ SHOULD_HAVE_BEEN_LOWERED(StringSubstring)
|
||||
SHOULD_HAVE_BEEN_LOWERED(StringToCaseIntl)
|
||||
#endif // V8_INTL_SUPPORT
|
||||
SHOULD_HAVE_BEEN_LOWERED(Tag)
|
||||
SHOULD_HAVE_BEEN_LOWERED(TransitionAndStoreArrayElement)
|
||||
SHOULD_HAVE_BEEN_LOWERED(TransitionElementsKind)
|
||||
SHOULD_HAVE_BEEN_LOWERED(TruncateObjectToPrimitive)
|
||||
SHOULD_HAVE_BEEN_LOWERED(TruncateObjectToPrimitiveOrDeopt)
|
||||
|
@ -262,7 +262,7 @@ class TypeInferenceAnalysis {
|
||||
case Opcode::kLoadStackArgument:
|
||||
case Opcode::kStoreTypedElement:
|
||||
case Opcode::kStoreDataViewElement:
|
||||
case Opcode::kStoreSignedSmallElement:
|
||||
case Opcode::kTransitionAndStoreArrayElement:
|
||||
case Opcode::kCompareMaps:
|
||||
case Opcode::kCheckMaps:
|
||||
case Opcode::kCheckedClosure:
|
||||
@ -276,6 +276,7 @@ class TypeInferenceAnalysis {
|
||||
case Opcode::kEnsureWritableFastElements:
|
||||
case Opcode::kMaybeGrowFastElements:
|
||||
case Opcode::kTransitionElementsKind:
|
||||
case Opcode::kFindOrderedHashEntry:
|
||||
// TODO(nicohartmann@): Support remaining operations. For now we
|
||||
// compute fallback types.
|
||||
if (op.outputs_rep().size() > 0) {
|
||||
|
@ -59,6 +59,8 @@ def decode(arg, encoding="utf-8"):
|
||||
# https://google.github.io/styleguide/cppguide.html#Inputs_and_Outputs.
|
||||
# whitespace/braces: Doesn't handle {}-initialization for custom types
|
||||
# well; also should be subsumed by clang-format.
|
||||
# whitespace/parens: Conflicts with clang-format rule to treat Turboshaft's
|
||||
# IF, IF_NOT, ... as IfMacros and insert a whitespace before the parenthesis.
|
||||
|
||||
LINT_RULES = """
|
||||
-build/header_guard
|
||||
@ -68,6 +70,7 @@ LINT_RULES = """
|
||||
-runtime/references
|
||||
-whitespace/braces
|
||||
-whitespace/comments
|
||||
-whitespace/parens
|
||||
""".split()
|
||||
|
||||
LINT_OUTPUT_PATTERN = re.compile(r'^.+[:(]\d+[:)]')
|
||||
|
Reference in New Issue
Block a user