[compiler] Factor MachineGraph out from JSGraph

This CL factors the parts of the JSGraph that only depend on the
machine part of JSGraph into a separate base class, MachineGraph.
This helps separate the two layers and also allows the MachineGraph
to be constructed without an Isolate, which is needed for fully
asynchronous compilation, a goal for WASM.

R=mstarzinger@chromium.org
CC=jarin@chromium.org, mvstanton@chromium.org

BUG=v8:7721

Change-Id: Ie8bc3de40159332645dcb3cadcee581e1bf9830a
Reviewed-on: https://chromium-review.googlesource.com/1043746
Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
Commit-Queue: Ben Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#52990}
This commit is contained in:
Ben L. Titzer 2018-05-04 12:02:37 +02:00 committed by Commit Bot
parent a2dbb84ccd
commit bc218a2ecd
5 changed files with 192 additions and 148 deletions

View File

@ -1657,6 +1657,8 @@ v8_source_set("v8_base") {
"src/compiler/loop-variable-optimizer.h",
"src/compiler/machine-graph-verifier.cc",
"src/compiler/machine-graph-verifier.h",
"src/compiler/machine-graph.cc",
"src/compiler/machine-graph.h",
"src/compiler/machine-operator-reducer.cc",
"src/compiler/machine-operator-reducer.h",
"src/compiler/machine-operator.cc",

View File

@ -111,17 +111,14 @@ Node* JSGraph::UndefinedConstant() {
return CACHED(kUndefinedConstant, HeapConstant(factory()->undefined_value()));
}
Node* JSGraph::TheHoleConstant() {
return CACHED(kTheHoleConstant, HeapConstant(factory()->the_hole_value()));
}
Node* JSGraph::TrueConstant() {
return CACHED(kTrueConstant, HeapConstant(factory()->true_value()));
}
Node* JSGraph::FalseConstant() {
return CACHED(kFalseConstant, HeapConstant(factory()->false_value()));
}
@ -131,7 +128,6 @@ Node* JSGraph::NullConstant() {
return CACHED(kNullConstant, HeapConstant(factory()->null_value()));
}
Node* JSGraph::ZeroConstant() {
return CACHED(kZeroConstant, NumberConstant(0.0));
}
@ -149,7 +145,6 @@ Node* JSGraph::NaNConstant() {
NumberConstant(std::numeric_limits<double>::quiet_NaN()));
}
Node* JSGraph::HeapConstant(Handle<HeapObject> value) {
Node** loc = cache_.FindHeapConstant(value);
if (*loc == nullptr) {
@ -158,7 +153,6 @@ Node* JSGraph::HeapConstant(Handle<HeapObject> value) {
return *loc;
}
Node* JSGraph::Constant(Handle<Object> value) {
// Dereference the handle to determine if a number constant or other
// canonicalized node can be used.
@ -179,7 +173,6 @@ Node* JSGraph::Constant(Handle<Object> value) {
}
}
Node* JSGraph::Constant(double value) {
if (bit_cast<int64_t>(value) == bit_cast<int64_t>(0.0)) return ZeroConstant();
if (bit_cast<int64_t>(value) == bit_cast<int64_t>(1.0)) return OneConstant();
@ -199,48 +192,6 @@ Node* JSGraph::Constant(uint32_t value) {
return NumberConstant(value);
}
Node* JSGraph::Int32Constant(int32_t value) {
Node** loc = cache_.FindInt32Constant(value);
if (*loc == nullptr) {
*loc = graph()->NewNode(common()->Int32Constant(value));
}
return *loc;
}
Node* JSGraph::Int64Constant(int64_t value) {
Node** loc = cache_.FindInt64Constant(value);
if (*loc == nullptr) {
*loc = graph()->NewNode(common()->Int64Constant(value));
}
return *loc;
}
Node* JSGraph::RelocatableInt32Constant(int32_t value, RelocInfo::Mode rmode) {
Node** loc = cache_.FindRelocatableInt32Constant(
value, static_cast<RelocInfoMode>(rmode));
if (*loc == nullptr) {
*loc = graph()->NewNode(common()->RelocatableInt32Constant(value, rmode));
}
return *loc;
}
Node* JSGraph::RelocatableInt64Constant(int64_t value, RelocInfo::Mode rmode) {
Node** loc = cache_.FindRelocatableInt64Constant(
value, static_cast<RelocInfoMode>(rmode));
if (*loc == nullptr) {
*loc = graph()->NewNode(common()->RelocatableInt64Constant(value, rmode));
}
return *loc;
}
Node* JSGraph::RelocatableIntPtrConstant(intptr_t value,
RelocInfo::Mode rmode) {
return kPointerSize == 8
? RelocatableInt64Constant(value, rmode)
: RelocatableInt32Constant(static_cast<int>(value), rmode);
}
Node* JSGraph::NumberConstant(double value) {
Node** loc = cache_.FindNumberConstant(value);
if (*loc == nullptr) {
@ -249,45 +200,6 @@ Node* JSGraph::NumberConstant(double value) {
return *loc;
}
Node* JSGraph::Float32Constant(float value) {
Node** loc = cache_.FindFloat32Constant(value);
if (*loc == nullptr) {
*loc = graph()->NewNode(common()->Float32Constant(value));
}
return *loc;
}
Node* JSGraph::Float64Constant(double value) {
Node** loc = cache_.FindFloat64Constant(value);
if (*loc == nullptr) {
*loc = graph()->NewNode(common()->Float64Constant(value));
}
return *loc;
}
Node* JSGraph::PointerConstant(intptr_t value) {
Node** loc = cache_.FindPointerConstant(value);
if (*loc == nullptr) {
*loc = graph()->NewNode(common()->PointerConstant(value));
}
return *loc;
}
Node* JSGraph::ExternalConstant(ExternalReference reference) {
Node** loc = cache_.FindExternalConstant(reference);
if (*loc == nullptr) {
*loc = graph()->NewNode(common()->ExternalConstant(reference));
}
return *loc;
}
Node* JSGraph::ExternalConstant(Runtime::FunctionId function_id) {
return ExternalConstant(ExternalReference::Create(function_id));
}
Node* JSGraph::EmptyStateValues() {
return CACHED(kEmptyStateValues, graph()->NewNode(common()->StateValues(
0, SparseInputMask::Dense())));

View File

@ -5,12 +5,10 @@
#ifndef V8_COMPILER_JS_GRAPH_H_
#define V8_COMPILER_JS_GRAPH_H_
#include "src/base/compiler-specific.h"
#include "src/compiler/common-node-cache.h"
#include "src/compiler/common-operator.h"
#include "src/compiler/graph.h"
#include "src/compiler/js-operator.h"
#include "src/compiler/machine-operator.h"
#include "src/compiler/machine-graph.h"
#include "src/compiler/node-properties.h"
#include "src/globals.h"
#include "src/isolate.h"
@ -25,18 +23,15 @@ class Typer;
// Implements a facade on a Graph, enhancing the graph with JS-specific
// notions, including various builders for operators, canonicalized global
// constants, and various helper methods.
class V8_EXPORT_PRIVATE JSGraph : public NON_EXPORTED_BASE(ZoneObject) {
class V8_EXPORT_PRIVATE JSGraph : public MachineGraph {
public:
JSGraph(Isolate* isolate, Graph* graph, CommonOperatorBuilder* common,
JSOperatorBuilder* javascript, SimplifiedOperatorBuilder* simplified,
MachineOperatorBuilder* machine)
: isolate_(isolate),
graph_(graph),
common_(common),
: MachineGraph(graph, common, machine),
isolate_(isolate),
javascript_(javascript),
simplified_(simplified),
machine_(machine),
cache_(zone()) {
simplified_(simplified) {
for (int i = 0; i < kNumCachedNodes; i++) cached_nodes_[i] = nullptr;
}
@ -88,53 +83,11 @@ class V8_EXPORT_PRIVATE JSGraph : public NON_EXPORTED_BASE(ZoneObject) {
// Creates a NumberConstant node, usually canonicalized.
Node* Constant(uint32_t value);
// Creates a Int32Constant node, usually canonicalized.
Node* Int32Constant(int32_t value);
Node* Uint32Constant(uint32_t value) {
return Int32Constant(bit_cast<int32_t>(value));
}
// Creates a HeapConstant node for either true or false.
Node* BooleanConstant(bool is_true) {
return is_true ? TrueConstant() : FalseConstant();
}
// Creates a Int64Constant node, usually canonicalized.
Node* Int64Constant(int64_t value);
Node* Uint64Constant(uint64_t value) {
return Int64Constant(bit_cast<int64_t>(value));
}
// Creates a Int32Constant/Int64Constant node, depending on the word size of
// the target machine.
// TODO(turbofan): Code using Int32Constant/Int64Constant to store pointer
// constants is probably not serializable.
Node* IntPtrConstant(intptr_t value) {
return machine()->Is32() ? Int32Constant(static_cast<int32_t>(value))
: Int64Constant(static_cast<int64_t>(value));
}
Node* RelocatableInt32Constant(int32_t value, RelocInfo::Mode rmode);
Node* RelocatableInt64Constant(int64_t value, RelocInfo::Mode rmode);
Node* RelocatableIntPtrConstant(intptr_t value, RelocInfo::Mode rmode);
// Creates a Float32Constant node, usually canonicalized.
Node* Float32Constant(float value);
// Creates a Float64Constant node, usually canonicalized.
Node* Float64Constant(double value);
// Creates a PointerConstant node (asm.js only).
Node* PointerConstant(intptr_t value);
template <typename T>
Node* PointerConstant(T* value) {
return PointerConstant(bit_cast<intptr_t>(value));
}
// Creates an ExternalConstant node, usually canonicalized.
Node* ExternalConstant(ExternalReference ref);
Node* ExternalConstant(Runtime::FunctionId function_id);
Node* SmiConstant(int32_t immediate) {
DCHECK(Smi::IsValid(immediate));
return Constant(immediate);
@ -155,12 +108,8 @@ class V8_EXPORT_PRIVATE JSGraph : public NON_EXPORTED_BASE(ZoneObject) {
// Create a control node that serves as dependency for dead nodes.
Node* Dead();
CommonOperatorBuilder* common() const { return common_; }
JSOperatorBuilder* javascript() const { return javascript_; }
SimplifiedOperatorBuilder* simplified() const { return simplified_; }
MachineOperatorBuilder* machine() const { return machine_; }
Graph* graph() const { return graph_; }
Zone* zone() const { return graph()->zone(); }
Isolate* isolate() const { return isolate_; }
Factory* factory() const { return isolate()->factory(); }
@ -200,12 +149,8 @@ class V8_EXPORT_PRIVATE JSGraph : public NON_EXPORTED_BASE(ZoneObject) {
};
Isolate* isolate_;
Graph* graph_;
CommonOperatorBuilder* common_;
JSOperatorBuilder* javascript_;
SimplifiedOperatorBuilder* simplified_;
MachineOperatorBuilder* machine_;
CommonNodeCache cache_;
Node* cached_nodes_[kNumCachedNodes];
Node* NumberConstant(double value);

View File

@ -0,0 +1,99 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/compiler/machine-graph.h"
#include "src/compiler/node-properties.h"
namespace v8 {
namespace internal {
namespace compiler {
Node* MachineGraph::Int32Constant(int32_t value) {
Node** loc = cache_.FindInt32Constant(value);
if (*loc == nullptr) {
*loc = graph()->NewNode(common()->Int32Constant(value));
}
return *loc;
}
Node* MachineGraph::Int64Constant(int64_t value) {
Node** loc = cache_.FindInt64Constant(value);
if (*loc == nullptr) {
*loc = graph()->NewNode(common()->Int64Constant(value));
}
return *loc;
}
Node* MachineGraph::IntPtrConstant(intptr_t value) {
return machine()->Is32() ? Int32Constant(static_cast<int32_t>(value))
: Int64Constant(static_cast<int64_t>(value));
}
Node* MachineGraph::RelocatableInt32Constant(int32_t value,
RelocInfo::Mode rmode) {
Node** loc = cache_.FindRelocatableInt32Constant(
value, static_cast<RelocInfoMode>(rmode));
if (*loc == nullptr) {
*loc = graph()->NewNode(common()->RelocatableInt32Constant(value, rmode));
}
return *loc;
}
Node* MachineGraph::RelocatableInt64Constant(int64_t value,
RelocInfo::Mode rmode) {
Node** loc = cache_.FindRelocatableInt64Constant(
value, static_cast<RelocInfoMode>(rmode));
if (*loc == nullptr) {
*loc = graph()->NewNode(common()->RelocatableInt64Constant(value, rmode));
}
return *loc;
}
Node* MachineGraph::RelocatableIntPtrConstant(intptr_t value,
RelocInfo::Mode rmode) {
return kPointerSize == 8
? RelocatableInt64Constant(value, rmode)
: RelocatableInt32Constant(static_cast<int>(value), rmode);
}
Node* MachineGraph::Float32Constant(float value) {
Node** loc = cache_.FindFloat32Constant(value);
if (*loc == nullptr) {
*loc = graph()->NewNode(common()->Float32Constant(value));
}
return *loc;
}
Node* MachineGraph::Float64Constant(double value) {
Node** loc = cache_.FindFloat64Constant(value);
if (*loc == nullptr) {
*loc = graph()->NewNode(common()->Float64Constant(value));
}
return *loc;
}
Node* MachineGraph::PointerConstant(intptr_t value) {
Node** loc = cache_.FindPointerConstant(value);
if (*loc == nullptr) {
*loc = graph()->NewNode(common()->PointerConstant(value));
}
return *loc;
}
Node* MachineGraph::ExternalConstant(ExternalReference reference) {
Node** loc = cache_.FindExternalConstant(reference);
if (*loc == nullptr) {
*loc = graph()->NewNode(common()->ExternalConstant(reference));
}
return *loc;
}
Node* MachineGraph::ExternalConstant(Runtime::FunctionId function_id) {
return ExternalConstant(ExternalReference::Create(function_id));
}
} // namespace compiler
} // namespace internal
} // namespace v8

View File

@ -0,0 +1,86 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_COMPILER_MACHINE_GRAPH_H_
#define V8_COMPILER_MACHINE_GRAPH_H_
#include "src/assembler.h"
#include "src/base/compiler-specific.h"
#include "src/compiler/common-node-cache.h"
#include "src/compiler/common-operator.h"
#include "src/compiler/graph.h"
#include "src/compiler/machine-operator.h"
#include "src/globals.h"
namespace v8 {
namespace internal {
namespace compiler {
// Implements a facade on a Graph, enhancing the graph with machine-specific
// notions, including a builder for common and machine operators, as well
// as caching primitive constants.
class V8_EXPORT_PRIVATE MachineGraph : public NON_EXPORTED_BASE(ZoneObject) {
public:
MachineGraph(Graph* graph, CommonOperatorBuilder* common,
MachineOperatorBuilder* machine)
: graph_(graph), common_(common), machine_(machine), cache_(zone()) {}
// Creates a Int32Constant node, usually canonicalized.
Node* Int32Constant(int32_t value);
Node* Uint32Constant(uint32_t value) {
return Int32Constant(bit_cast<int32_t>(value));
}
// Creates a Int64Constant node, usually canonicalized.
Node* Int64Constant(int64_t value);
Node* Uint64Constant(uint64_t value) {
return Int64Constant(bit_cast<int64_t>(value));
}
// Creates a Int32Constant/Int64Constant node, depending on the word size of
// the target machine.
// TODO(turbofan): Code using Int32Constant/Int64Constant to store pointer
// constants is probably not serializable.
Node* IntPtrConstant(intptr_t value);
Node* RelocatableInt32Constant(int32_t value, RelocInfo::Mode rmode);
Node* RelocatableInt64Constant(int64_t value, RelocInfo::Mode rmode);
Node* RelocatableIntPtrConstant(intptr_t value, RelocInfo::Mode rmode);
// Creates a Float32Constant node, usually canonicalized.
Node* Float32Constant(float value);
// Creates a Float64Constant node, usually canonicalized.
Node* Float64Constant(double value);
// Creates a PointerConstant node.
Node* PointerConstant(intptr_t value);
template <typename T>
Node* PointerConstant(T* value) {
return PointerConstant(bit_cast<intptr_t>(value));
}
// Creates an ExternalConstant node, usually canonicalized.
Node* ExternalConstant(ExternalReference ref);
Node* ExternalConstant(Runtime::FunctionId function_id);
CommonOperatorBuilder* common() const { return common_; }
MachineOperatorBuilder* machine() const { return machine_; }
Graph* graph() const { return graph_; }
Zone* zone() const { return graph()->zone(); }
protected:
Graph* graph_;
CommonOperatorBuilder* common_;
MachineOperatorBuilder* machine_;
CommonNodeCache cache_;
DISALLOW_COPY_AND_ASSIGN(MachineGraph);
};
} // namespace compiler
} // namespace internal
} // namespace v8
#endif // V8_COMPILER_MACHINE_GRAPH_H_