Commit 14b424c3 authored by Jaroslav Sevcik's avatar Jaroslav Sevcik Committed by Commit Bot

[turbofan] Lower monomorphic loads during graph building.

We introduce an explicit LoweringResult data structure. Until this change,
the lowering result could be recovered from the node. However, lowering
monomorphic loads requires wiring different value and effect, so we need
a structure that can express such lowering result.

Bug: v8:6357
Change-Id: I92655800890b744d9203a778a1936a8dcd465ed3
Reviewed-on: https://chromium-review.googlesource.com/637304
Commit-Queue: Jaroslav Sevcik <jarin@chromium.org>
Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47992}
parent bc69f345
...@@ -476,7 +476,8 @@ BytecodeGraphBuilder::BytecodeGraphBuilder( ...@@ -476,7 +476,8 @@ BytecodeGraphBuilder::BytecodeGraphBuilder(
Zone* local_zone, Handle<SharedFunctionInfo> shared_info, Zone* local_zone, Handle<SharedFunctionInfo> shared_info,
Handle<FeedbackVector> feedback_vector, BailoutId osr_offset, Handle<FeedbackVector> feedback_vector, BailoutId osr_offset,
JSGraph* jsgraph, CallFrequency invocation_frequency, JSGraph* jsgraph, CallFrequency invocation_frequency,
SourcePositionTable* source_positions, int inlining_id, SourcePositionTable* source_positions, Handle<Context> native_context,
CompilationDependencies* dependencies, int inlining_id,
JSTypeHintLowering::Flags flags, bool stack_check) JSTypeHintLowering::Flags flags, bool stack_check)
: local_zone_(local_zone), : local_zone_(local_zone),
jsgraph_(jsgraph), jsgraph_(jsgraph),
...@@ -485,7 +486,8 @@ BytecodeGraphBuilder::BytecodeGraphBuilder( ...@@ -485,7 +486,8 @@ BytecodeGraphBuilder::BytecodeGraphBuilder(
exception_handler_table_( exception_handler_table_(
handle(HandlerTable::cast(bytecode_array()->handler_table()))), handle(HandlerTable::cast(bytecode_array()->handler_table()))),
feedback_vector_(feedback_vector), feedback_vector_(feedback_vector),
type_hint_lowering_(jsgraph, feedback_vector, flags), type_hint_lowering_(jsgraph, feedback_vector, native_context,
dependencies, flags, local_zone),
frame_state_function_info_(common()->CreateFrameStateFunctionInfo( frame_state_function_info_(common()->CreateFrameStateFunctionInfo(
FrameStateType::kInterpretedFunction, FrameStateType::kInterpretedFunction,
bytecode_array()->parameter_count(), bytecode_array()->parameter_count(),
......
...@@ -16,6 +16,9 @@ ...@@ -16,6 +16,9 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
class CompilationDependencies;
namespace compiler { namespace compiler {
class Reduction; class Reduction;
...@@ -29,7 +32,8 @@ class BytecodeGraphBuilder { ...@@ -29,7 +32,8 @@ class BytecodeGraphBuilder {
Zone* local_zone, Handle<SharedFunctionInfo> shared, Zone* local_zone, Handle<SharedFunctionInfo> shared,
Handle<FeedbackVector> feedback_vector, BailoutId osr_offset, Handle<FeedbackVector> feedback_vector, BailoutId osr_offset,
JSGraph* jsgraph, CallFrequency invocation_frequency, JSGraph* jsgraph, CallFrequency invocation_frequency,
SourcePositionTable* source_positions, SourcePositionTable* source_positions, Handle<Context> native_context,
CompilationDependencies* dependencies,
int inlining_id = SourcePosition::kNotInlined, int inlining_id = SourcePosition::kNotInlined,
JSTypeHintLowering::Flags flags = JSTypeHintLowering::kNoFlags, JSTypeHintLowering::Flags flags = JSTypeHintLowering::kNoFlags,
bool stack_check = true); bool stack_check = true);
......
...@@ -350,8 +350,7 @@ bool JSInliner::DetermineCallTarget( ...@@ -350,8 +350,7 @@ bool JSInliner::DetermineCallTarget(
// TODO(turbofan): We might want to revisit this restriction later when we // TODO(turbofan): We might want to revisit this restriction later when we
// have a need for this, and we know how to model different native contexts // have a need for this, and we know how to model different native contexts
// in the same graph in a compositional way. // in the same graph in a compositional way.
if (function->context()->native_context() != if (function->context()->native_context() != *native_context()) {
info_->context()->native_context()) {
return false; return false;
} }
...@@ -430,6 +429,10 @@ Reduction JSInliner::Reduce(Node* node) { ...@@ -430,6 +429,10 @@ Reduction JSInliner::Reduce(Node* node) {
return ReduceJSCall(node); return ReduceJSCall(node);
} }
Handle<Context> JSInliner::native_context() const {
return handle(info_->context()->native_context());
}
Reduction JSInliner::ReduceJSCall(Node* node) { Reduction JSInliner::ReduceJSCall(Node* node) {
DCHECK(IrOpcode::IsInlineeOpcode(node->opcode())); DCHECK(IrOpcode::IsInlineeOpcode(node->opcode()));
Handle<SharedFunctionInfo> shared_info; Handle<SharedFunctionInfo> shared_info;
...@@ -541,7 +544,8 @@ Reduction JSInliner::ReduceJSCall(Node* node) { ...@@ -541,7 +544,8 @@ Reduction JSInliner::ReduceJSCall(Node* node) {
} }
BytecodeGraphBuilder graph_builder( BytecodeGraphBuilder graph_builder(
zone(), shared_info, feedback_vector, BailoutId::None(), jsgraph(), zone(), shared_info, feedback_vector, BailoutId::None(), jsgraph(),
call.frequency(), source_positions_, inlining_id, flags, false); call.frequency(), source_positions_, native_context(),
info_->dependencies(), inlining_id, flags, false);
graph_builder.CreateGraph(); graph_builder.CreateGraph();
// Extract the inlinee start/end nodes. // Extract the inlinee start/end nodes.
......
...@@ -47,6 +47,7 @@ class JSInliner final : public AdvancedReducer { ...@@ -47,6 +47,7 @@ class JSInliner final : public AdvancedReducer {
SimplifiedOperatorBuilder* simplified() const; SimplifiedOperatorBuilder* simplified() const;
Graph* graph() const; Graph* graph() const;
JSGraph* jsgraph() const { return jsgraph_; } JSGraph* jsgraph() const { return jsgraph_; }
Handle<Context> native_context() const;
Zone* const local_zone_; Zone* const local_zone_;
CompilationInfo* info_; CompilationInfo* info_;
......
...@@ -5,10 +5,13 @@ ...@@ -5,10 +5,13 @@
#include "src/compiler/js-type-hint-lowering.h" #include "src/compiler/js-type-hint-lowering.h"
#include "src/compiler/access-builder.h" #include "src/compiler/access-builder.h"
#include "src/compiler/access-info.h"
#include "src/compiler/js-graph.h" #include "src/compiler/js-graph.h"
#include "src/compiler/operator-properties.h" #include "src/compiler/operator-properties.h"
#include "src/compiler/property-access-builder.h"
#include "src/compiler/simplified-operator.h" #include "src/compiler/simplified-operator.h"
#include "src/feedback-vector.h" #include "src/feedback-vector.h"
#include "src/handles-inl.h"
#include "src/type-hints.h" #include "src/type-hints.h"
namespace v8 { namespace v8 {
...@@ -209,8 +212,17 @@ class JSSpeculativeBinopBuilder final { ...@@ -209,8 +212,17 @@ class JSSpeculativeBinopBuilder final {
JSTypeHintLowering::JSTypeHintLowering(JSGraph* jsgraph, JSTypeHintLowering::JSTypeHintLowering(JSGraph* jsgraph,
Handle<FeedbackVector> feedback_vector, Handle<FeedbackVector> feedback_vector,
Flags flags) Handle<Context> native_context,
: jsgraph_(jsgraph), flags_(flags), feedback_vector_(feedback_vector) {} CompilationDependencies* dependencies,
Flags flags, Zone* local_zone)
: jsgraph_(jsgraph),
flags_(flags),
feedback_vector_(feedback_vector),
native_context_(native_context),
dependencies_(dependencies),
local_zone_(local_zone) {}
Graph* JSTypeHintLowering::graph() const { return jsgraph_->graph(); }
JSTypeHintLowering::LoweringResult JSTypeHintLowering::ReduceBinaryOperation( JSTypeHintLowering::LoweringResult JSTypeHintLowering::ReduceBinaryOperation(
const Operator* op, Node* left, Node* right, Node* effect, Node* control, const Operator* op, Node* left, Node* right, Node* effect, Node* control,
...@@ -360,7 +372,59 @@ JSTypeHintLowering::LoweringResult JSTypeHintLowering::ReduceLoadNamedOperation( ...@@ -360,7 +372,59 @@ JSTypeHintLowering::LoweringResult JSTypeHintLowering::ReduceLoadNamedOperation(
DeoptimizeReason::kInsufficientTypeFeedbackForGenericNamedAccess)) { DeoptimizeReason::kInsufficientTypeFeedbackForGenericNamedAccess)) {
return LoweringResult::Exit(node); return LoweringResult::Exit(node);
} }
return LoweringResult::NoChange();
// Try to extract maps from the feedback vector. Give up if the IC
// is megamorphic or unitialized.
MapHandles receiver_maps;
if (nexus.ExtractMaps(&receiver_maps) == 0) {
return LoweringResult::NoChange();
}
// Extract information about accesses from the maps.
NamedAccess const& p = NamedAccessOf(op);
AccessInfoFactory access_info_factory(dependencies(), native_context(),
graph()->zone());
ZoneVector<PropertyAccessInfo> access_infos(local_zone());
if (!access_info_factory.ComputePropertyAccessInfos(
receiver_maps, p.name(), AccessMode::kLoad, &access_infos)) {
return LoweringResult::NoChange();
}
// Bail out if not monomorphic.
if (access_infos.size() != 1) return LoweringResult::NoChange();
// We only lower data fields and data constants.
PropertyAccessInfo const& access_info = access_infos[0];
if (!access_info.IsDataField() && !access_info.IsDataConstant()) {
return LoweringResult::NoChange();
}
PropertyAccessBuilder access_builder(jsgraph(), dependencies());
if (!access_builder.TryBuildStringCheck(access_info.receiver_maps(),
&receiver, &effect, control) &&
!access_builder.TryBuildNumberCheck(access_info.receiver_maps(),
&receiver, &effect, control)) {
receiver = access_builder.BuildCheckHeapObject(receiver, &effect, control);
access_builder.BuildCheckMaps(receiver, &effect, control,
access_info.receiver_maps());
}
Handle<JSObject> holder;
if (access_info.holder().ToHandle(&holder)) {
access_builder.AssumePrototypesStable(native_context(),
access_info.receiver_maps(), holder);
}
Node* value = nullptr;
if (access_info.IsDataConstant()) {
value = jsgraph()->Constant(access_info.constant());
} else {
DCHECK(access_info.IsDataField());
value = access_builder.BuildLoadDataField(p.name(), access_info, receiver,
&effect, &control);
}
return LoweringResult::SideEffectFree(value, effect, control);
} }
JSTypeHintLowering::LoweringResult JSTypeHintLowering::ReduceLoadKeyedOperation( JSTypeHintLowering::LoweringResult JSTypeHintLowering::ReduceLoadKeyedOperation(
......
...@@ -14,6 +14,7 @@ namespace v8 { ...@@ -14,6 +14,7 @@ namespace v8 {
namespace internal { namespace internal {
// Forward declarations. // Forward declarations.
class CompilationDependencies;
class FeedbackNexus; class FeedbackNexus;
class FeedbackSlot; class FeedbackSlot;
...@@ -42,7 +43,9 @@ class JSTypeHintLowering { ...@@ -42,7 +43,9 @@ class JSTypeHintLowering {
typedef base::Flags<Flag> Flags; typedef base::Flags<Flag> Flags;
JSTypeHintLowering(JSGraph* jsgraph, Handle<FeedbackVector> feedback_vector, JSTypeHintLowering(JSGraph* jsgraph, Handle<FeedbackVector> feedback_vector,
Flags flags); Handle<Context> native_context,
CompilationDependencies* dependencies, Flags flags,
Zone* local_zone);
// {LoweringResult} describes the result of lowering. The following outcomes // {LoweringResult} describes the result of lowering. The following outcomes
// are possible: // are possible:
...@@ -156,11 +159,21 @@ class JSTypeHintLowering { ...@@ -156,11 +159,21 @@ class JSTypeHintLowering {
const Handle<FeedbackVector>& feedback_vector() const { const Handle<FeedbackVector>& feedback_vector() const {
return feedback_vector_; return feedback_vector_;
} }
Graph* graph() const;
Zone* local_zone() const { return local_zone_; }
Handle<Context> native_context() const { return native_context_; }
CompilationDependencies* dependencies() const { return dependencies_; }
JSGraph* jsgraph_; JSGraph* jsgraph_;
Flags const flags_; Flags const flags_;
Handle<FeedbackVector> feedback_vector_; Handle<FeedbackVector> feedback_vector_;
Handle<Context> native_context_;
CompilationDependencies* dependencies_;
Zone* local_zone_;
DISALLOW_COPY_AND_ASSIGN(JSTypeHintLowering); DISALLOW_COPY_AND_ASSIGN(JSTypeHintLowering);
}; };
......
...@@ -893,7 +893,8 @@ struct GraphBuilderPhase { ...@@ -893,7 +893,8 @@ struct GraphBuilderPhase {
temp_zone, data->info()->shared_info(), temp_zone, data->info()->shared_info(),
handle(data->info()->closure()->feedback_vector()), handle(data->info()->closure()->feedback_vector()),
data->info()->osr_offset(), data->jsgraph(), CallFrequency(1.0f), data->info()->osr_offset(), data->jsgraph(), CallFrequency(1.0f),
data->source_positions(), SourcePosition::kNotInlined, flags); data->source_positions(), data->native_context(),
data->info()->dependencies(), SourcePosition::kNotInlined, flags);
graph_builder.CreateGraph(); graph_builder.CreateGraph();
} }
}; };
......
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