Commit 03e13f7a authored by Santiago Aboy Solanes's avatar Santiago Aboy Solanes Committed by Commit Bot

[Turbofan] Introduce LoadStackArgument to represent loading arguments from the stack.

This now makes it so TurboFan now uses full pointer loads for arguments values
located on stack.

Bug: v8:8876, v8:7703
Change-Id: Ib82d6f3b0f4c8d33669c7f86ce803381d210c019
Reviewed-on: https://chromium-review.googlesource.com/c/1480382Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Commit-Queue: Santiago Aboy Solanes <solanes@chromium.org>
Cr-Commit-Position: refs/heads/master@{#59798}
parent acf741b9
......@@ -913,6 +913,16 @@ ElementAccess AccessBuilder::ForFixedArrayElement(
return access;
}
// static
ElementAccess AccessBuilder::ForStackArgument() {
ElementAccess access = {
kUntaggedBase,
CommonFrameConstants::kFixedFrameSizeAboveFp - kSystemPointerSize,
Type::NonInternal(), MachineType::Pointer(),
WriteBarrierKind::kNoWriteBarrier};
return access;
}
// static
ElementAccess AccessBuilder::ForFixedDoubleArrayElement() {
ElementAccess access = {kTaggedBase, FixedDoubleArray::kHeaderSize,
......
......@@ -283,6 +283,9 @@ class V8_EXPORT_PRIVATE AccessBuilder final
ElementsKind kind,
LoadSensitivity load_sensitivity = LoadSensitivity::kUnsafe);
// Provides access to stack arguments
static ElementAccess ForStackArgument();
// Provides access to FixedDoubleArray elements.
static ElementAccess ForFixedDoubleArrayElement();
......
......@@ -978,6 +978,9 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node,
case IrOpcode::kLoadDataViewElement:
result = LowerLoadDataViewElement(node);
break;
case IrOpcode::kLoadStackArgument:
result = LowerLoadStackArgument(node);
break;
case IrOpcode::kStoreTypedElement:
LowerStoreTypedElement(node);
break;
......@@ -4341,6 +4344,16 @@ Node* EffectControlLinearizer::LowerLoadDataViewElement(Node* node) {
return done.PhiAt(0);
}
Node* EffectControlLinearizer::LowerLoadStackArgument(Node* node) {
Node* base = node->InputAt(0);
Node* index = node->InputAt(1);
Node* argument =
__ LoadElement(AccessBuilder::ForStackArgument(), base, index);
return __ BitcastWordToTagged(argument);
}
void EffectControlLinearizer::LowerStoreDataViewElement(Node* node) {
ExternalArrayType element_type = ExternalArrayTypeOf(node->op());
Node* buffer = node->InputAt(0);
......
......@@ -166,6 +166,7 @@ class V8_EXPORT_PRIVATE EffectControlLinearizer {
Node* LowerLoadMessage(Node* node);
Node* LowerLoadTypedElement(Node* node);
Node* LowerLoadDataViewElement(Node* node);
Node* LowerLoadStackArgument(Node* node);
void LowerStoreMessage(Node* node);
void LowerStoreTypedElement(Node* node);
void LowerStoreDataViewElement(Node* node);
......
......@@ -313,18 +313,6 @@ void EscapeAnalysisReducer::Finalize() {
NodeProperties::SetType(arguments_elements_state, Type::OtherInternal());
ReplaceWithValue(node, arguments_elements_state);
ElementAccess stack_access;
stack_access.base_is_tagged = BaseTaggedness::kUntaggedBase;
// Reduce base address by {kSystemPointerSize} such that (length - index)
// resolves to the right position.
stack_access.header_size =
CommonFrameConstants::kFixedFrameSizeAboveFp - kSystemPointerSize;
stack_access.type = Type::NonInternal();
stack_access.machine_type = MachineType::AnyTagged();
stack_access.write_barrier_kind = WriteBarrierKind::kNoWriteBarrier;
const Operator* load_stack_op =
jsgraph()->simplified()->LoadElement(stack_access);
for (Node* load : loads) {
switch (load->opcode()) {
case IrOpcode::kLoadElement: {
......@@ -338,7 +326,8 @@ void EscapeAnalysisReducer::Finalize() {
TypeCache::Get()->kArgumentsLengthType);
NodeProperties::ReplaceValueInput(load, arguments_frame, 0);
NodeProperties::ReplaceValueInput(load, offset, 1);
NodeProperties::ChangeOp(load, load_stack_op);
NodeProperties::ChangeOp(
load, jsgraph()->simplified()->LoadStackArgument());
break;
}
case IrOpcode::kLoadField: {
......
......@@ -405,6 +405,7 @@
V(LoadMessage) \
V(LoadTypedElement) \
V(LoadDataViewElement) \
V(LoadStackArgument) \
V(StoreField) \
V(StoreElement) \
V(StoreMessage) \
......
......@@ -2793,6 +2793,11 @@ class RepresentationSelector {
access.machine_type.representation());
return;
}
case IrOpcode::kLoadStackArgument: {
if (truncation.IsUnused()) return VisitUnused(node);
VisitBinop(node, UseInfo::Word(), MachineRepresentation::kTagged);
return;
}
case IrOpcode::kStoreElement: {
ElementAccess access = ElementAccessOf(node->op());
Node* value_node = node->InputAt(2);
......
......@@ -1128,6 +1128,17 @@ struct SimplifiedOperatorGlobalCache final {
};
LoadFieldByIndexOperator kLoadFieldByIndex;
struct LoadStackArgumentOperator final : public Operator {
LoadStackArgumentOperator()
: Operator( // --
IrOpcode::kLoadStackArgument, // opcode
Operator::kNoDeopt | Operator::kNoThrow |
Operator::kNoWrite, // flags
"LoadStackArgument", // name
2, 1, 1, 1, 1, 0) {} // counts
};
LoadStackArgumentOperator kLoadStackArgument;
#define SPECULATIVE_NUMBER_BINOP(Name) \
template <NumberOperationHint kHint> \
struct Name##Operator final : public Operator1<NumberOperationHint> { \
......@@ -1725,6 +1736,10 @@ const Operator* SimplifiedOperatorBuilder::StoreMessage() {
"StoreMessage", 2, 1, 1, 0, 1, 0);
}
const Operator* SimplifiedOperatorBuilder::LoadStackArgument() {
return &cache_.kLoadStackArgument;
}
const Operator* SimplifiedOperatorBuilder::TransitionAndStoreElement(
Handle<Map> double_map, Handle<Map> fast_map) {
TransitionAndStoreElementParameters parameters(double_map, fast_map);
......
......@@ -806,6 +806,9 @@ class V8_EXPORT_PRIVATE SimplifiedOperatorBuilder final
// load-element [base + index]
const Operator* LoadElement(ElementAccess const&);
// load-stack-argument [base + index]
const Operator* LoadStackArgument();
// store-element [base + index], value
const Operator* StoreElement(ElementAccess const&);
......
......@@ -2137,6 +2137,10 @@ Type Typer::Visitor::TypeLoadElement(Node* node) {
return ElementAccessOf(node->op()).type;
}
Type Typer::Visitor::TypeLoadStackArgument(Node* node) {
return Type::NonInternal();
}
Type Typer::Visitor::TypeLoadTypedElement(Node* node) {
switch (ExternalArrayTypeOf(node->op())) {
#define TYPED_ARRAY_CASE(ElemType, type, TYPE, ctype) \
......
......@@ -1548,6 +1548,7 @@ void Verifier::Visitor::Check(Node* node, const AllNodes& all) {
// CheckTypeIs(node, FieldAccessOf(node->op()).type));
break;
case IrOpcode::kLoadElement:
case IrOpcode::kLoadStackArgument:
// Object -> elementtype
// TODO(rossberg): activate once machine ops are typed.
// CheckValueInputIs(node, 0, Type::Object());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment