Commit 8201579e authored by bmeurer's avatar bmeurer Committed by Commit bot

[turbofan] Introduce a dedicated CheckMaps simplified operator.

So far we always create explicit control flow for map checks during
JSNativeContextSpecialization, or in the monomorphic case we used a
CheckIf combined with a map comparison. In either case we cannot
currently effectively utilize the map check information during load
elimination to optimize (polymorphic) map checks and elements kind
transitions.

With the introduction of CheckMaps, we can now start optimizing map
checks in a more effective fashion. This CL doesn't change anything
in that direction yet, but merely changes the fundamental mechanism.

This also removes the stable map optimization from the Typer, where
it was always a bit odd, and puts it into the typed lowering and
the native context specialization instead.

R=epertoso@chromium.org
BUG=v8:4930,v8:5141

Review-Url: https://codereview.chromium.org/2196653002
Cr-Commit-Position: refs/heads/master@{#38166}
parent 45d6909e
...@@ -622,6 +622,9 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node, ...@@ -622,6 +622,9 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node,
case IrOpcode::kCheckBounds: case IrOpcode::kCheckBounds:
state = LowerCheckBounds(node, frame_state, *effect, *control); state = LowerCheckBounds(node, frame_state, *effect, *control);
break; break;
case IrOpcode::kCheckMaps:
state = LowerCheckMaps(node, frame_state, *effect, *control);
break;
case IrOpcode::kCheckNumber: case IrOpcode::kCheckNumber:
state = LowerCheckNumber(node, frame_state, *effect, *control); state = LowerCheckNumber(node, frame_state, *effect, *control);
break; break;
...@@ -1022,6 +1025,43 @@ EffectControlLinearizer::LowerCheckBounds(Node* node, Node* frame_state, ...@@ -1022,6 +1025,43 @@ EffectControlLinearizer::LowerCheckBounds(Node* node, Node* frame_state,
return ValueEffectControl(index, effect, control); return ValueEffectControl(index, effect, control);
} }
EffectControlLinearizer::ValueEffectControl
EffectControlLinearizer::LowerCheckMaps(Node* node, Node* frame_state,
Node* effect, Node* control) {
Node* value = node->InputAt(0);
// Load the current map of the {value}.
Node* value_map = effect = graph()->NewNode(
simplified()->LoadField(AccessBuilder::ForMap()), value, effect, control);
int const map_count = node->op()->ValueInputCount() - 1;
Node** controls = temp_zone()->NewArray<Node*>(map_count);
Node** effects = temp_zone()->NewArray<Node*>(map_count + 1);
for (int i = 0; i < map_count; ++i) {
Node* map = node->InputAt(1 + i);
Node* check = graph()->NewNode(machine()->WordEqual(), value_map, map);
if (i == map_count - 1) {
controls[i] = effects[i] = graph()->NewNode(
common()->DeoptimizeUnless(DeoptimizeReason::kWrongMap), check,
frame_state, effect, control);
} else {
control = graph()->NewNode(common()->Branch(), check, control);
controls[i] = graph()->NewNode(common()->IfTrue(), control);
control = graph()->NewNode(common()->IfFalse(), control);
effects[i] = effect;
}
}
control = graph()->NewNode(common()->Merge(map_count), map_count, controls);
effects[map_count] = control;
effect =
graph()->NewNode(common()->EffectPhi(map_count), map_count + 1, effects);
return ValueEffectControl(value, effect, control);
}
EffectControlLinearizer::ValueEffectControl EffectControlLinearizer::ValueEffectControl
EffectControlLinearizer::LowerCheckNumber(Node* node, Node* frame_state, EffectControlLinearizer::LowerCheckNumber(Node* node, Node* frame_state,
Node* effect, Node* control) { Node* effect, Node* control) {
......
...@@ -63,6 +63,8 @@ class EffectControlLinearizer { ...@@ -63,6 +63,8 @@ class EffectControlLinearizer {
Node* control); Node* control);
ValueEffectControl LowerCheckBounds(Node* node, Node* frame_state, ValueEffectControl LowerCheckBounds(Node* node, Node* frame_state,
Node* effect, Node* control); Node* effect, Node* control);
ValueEffectControl LowerCheckMaps(Node* node, Node* frame_state, Node* effect,
Node* control);
ValueEffectControl LowerCheckNumber(Node* node, Node* frame_state, ValueEffectControl LowerCheckNumber(Node* node, Node* frame_state,
Node* effect, Node* control); Node* effect, Node* control);
ValueEffectControl LowerCheckString(Node* node, Node* frame_state, ValueEffectControl LowerCheckString(Node* node, Node* frame_state,
......
...@@ -114,6 +114,13 @@ class JSNativeContextSpecialization final : public AdvancedReducer { ...@@ -114,6 +114,13 @@ class JSNativeContextSpecialization final : public AdvancedReducer {
ElementAccessInfo const& access_info, ElementAccessInfo const& access_info,
AccessMode access_mode); AccessMode access_mode);
// Construct an appropriate map check.
Node* BuildCheckMaps(Node* receiver, Node* effect, Node* control,
std::vector<Handle<Map>> const& maps);
// Construct an appropriate heap object check.
Node* BuildCheckTaggedPointer(Node* receiver, Node* effect, Node* control);
// Adds stability dependencies on all prototypes of every class in // Adds stability dependencies on all prototypes of every class in
// {receiver_type} up to (and including) the {holder}. // {receiver_type} up to (and including) the {holder}.
void AssumePrototypesStable(std::vector<Handle<Map>> const& receiver_maps, void AssumePrototypesStable(std::vector<Handle<Map>> const& receiver_maps,
......
...@@ -1889,6 +1889,54 @@ Reduction JSTypedLowering::ReduceSelect(Node* node) { ...@@ -1889,6 +1889,54 @@ Reduction JSTypedLowering::ReduceSelect(Node* node) {
return NoChange(); return NoChange();
} }
namespace {
MaybeHandle<Map> GetStableMapFromObjectType(Type* object_type) {
if (object_type->IsConstant() &&
object_type->AsConstant()->Value()->IsHeapObject()) {
Handle<Map> object_map(
Handle<HeapObject>::cast(object_type->AsConstant()->Value())->map());
if (object_map->is_stable()) return object_map;
} else if (object_type->IsClass()) {
Handle<Map> object_map = object_type->AsClass()->Map();
if (object_map->is_stable()) return object_map;
}
return MaybeHandle<Map>();
}
} // namespace
Reduction JSTypedLowering::ReduceCheckMaps(Node* node) {
// TODO(bmeurer): Find a better home for this thing!
// The CheckMaps(o, ...map...) can be eliminated if map is stable and
// either
// (a) o has type Constant(object) and map == object->map, or
// (b) o has type Class(map),
// and either
// (1) map cannot transition further, or
// (2) we can add a code dependency on the stability of map
// (to guard the Constant type information).
Node* const object = NodeProperties::GetValueInput(node, 0);
Type* const object_type = NodeProperties::GetType(object);
Node* const effect = NodeProperties::GetEffectInput(node);
Handle<Map> object_map;
if (GetStableMapFromObjectType(object_type).ToHandle(&object_map)) {
for (int i = 1; i < node->op()->ValueInputCount(); ++i) {
Node* const map = NodeProperties::GetValueInput(node, i);
Type* const map_type = NodeProperties::GetType(map);
if (map_type->IsConstant() &&
map_type->AsConstant()->Value().is_identical_to(object_map)) {
if (object_map->CanTransition()) {
DCHECK(flags() & kDeoptimizationEnabled);
dependencies()->AssumeMapStable(object_map);
}
return Replace(effect);
}
}
}
return NoChange();
}
Reduction JSTypedLowering::ReduceCheckString(Node* node) { Reduction JSTypedLowering::ReduceCheckString(Node* node) {
// TODO(bmeurer): Find a better home for this thing! // TODO(bmeurer): Find a better home for this thing!
Node* const input = NodeProperties::GetValueInput(node, 0); Node* const input = NodeProperties::GetValueInput(node, 0);
...@@ -1900,6 +1948,37 @@ Reduction JSTypedLowering::ReduceCheckString(Node* node) { ...@@ -1900,6 +1948,37 @@ Reduction JSTypedLowering::ReduceCheckString(Node* node) {
return NoChange(); return NoChange();
} }
Reduction JSTypedLowering::ReduceLoadField(Node* node) {
// TODO(bmeurer): Find a better home for this thing!
Node* const object = NodeProperties::GetValueInput(node, 0);
Type* const object_type = NodeProperties::GetType(object);
FieldAccess const& access = FieldAccessOf(node->op());
if (access.base_is_tagged == kTaggedBase &&
access.offset == HeapObject::kMapOffset) {
// We can replace LoadField[Map](o) with map if is stable and either
// (a) o has type Constant(object) and map == object->map, or
// (b) o has type Class(map),
// and either
// (1) map cannot transition further, or
// (2) deoptimization is enabled and we can add a code dependency on the
// stability of map (to guard the Constant type information).
Handle<Map> object_map;
if (GetStableMapFromObjectType(object_type).ToHandle(&object_map)) {
if (object_map->CanTransition()) {
if (flags() & kDeoptimizationEnabled) {
dependencies()->AssumeMapStable(object_map);
} else {
return NoChange();
}
}
Node* const value = jsgraph()->HeapConstant(object_map);
ReplaceWithValue(node, value);
return Replace(value);
}
}
return NoChange();
}
Reduction JSTypedLowering::ReduceNumberRoundop(Node* node) { Reduction JSTypedLowering::ReduceNumberRoundop(Node* node) {
// TODO(bmeurer): Find a better home for this thing! // TODO(bmeurer): Find a better home for this thing!
Node* const input = NodeProperties::GetValueInput(node, 0); Node* const input = NodeProperties::GetValueInput(node, 0);
...@@ -2030,6 +2109,8 @@ Reduction JSTypedLowering::Reduce(Node* node) { ...@@ -2030,6 +2109,8 @@ Reduction JSTypedLowering::Reduce(Node* node) {
return ReduceJSGeneratorRestoreRegister(node); return ReduceJSGeneratorRestoreRegister(node);
case IrOpcode::kSelect: case IrOpcode::kSelect:
return ReduceSelect(node); return ReduceSelect(node);
case IrOpcode::kCheckMaps:
return ReduceCheckMaps(node);
case IrOpcode::kCheckString: case IrOpcode::kCheckString:
return ReduceCheckString(node); return ReduceCheckString(node);
case IrOpcode::kNumberCeil: case IrOpcode::kNumberCeil:
...@@ -2037,6 +2118,8 @@ Reduction JSTypedLowering::Reduce(Node* node) { ...@@ -2037,6 +2118,8 @@ Reduction JSTypedLowering::Reduce(Node* node) {
case IrOpcode::kNumberRound: case IrOpcode::kNumberRound:
case IrOpcode::kNumberTrunc: case IrOpcode::kNumberTrunc:
return ReduceNumberRoundop(node); return ReduceNumberRoundop(node);
case IrOpcode::kLoadField:
return ReduceLoadField(node);
default: default:
break; break;
} }
......
...@@ -78,7 +78,9 @@ class JSTypedLowering final : public AdvancedReducer { ...@@ -78,7 +78,9 @@ class JSTypedLowering final : public AdvancedReducer {
Reduction ReduceJSGeneratorStore(Node* node); Reduction ReduceJSGeneratorStore(Node* node);
Reduction ReduceJSGeneratorRestoreContinuation(Node* node); Reduction ReduceJSGeneratorRestoreContinuation(Node* node);
Reduction ReduceJSGeneratorRestoreRegister(Node* node); Reduction ReduceJSGeneratorRestoreRegister(Node* node);
Reduction ReduceCheckMaps(Node* node);
Reduction ReduceCheckString(Node* node); Reduction ReduceCheckString(Node* node);
Reduction ReduceLoadField(Node* node);
Reduction ReduceNumberRoundop(Node* node); Reduction ReduceNumberRoundop(Node* node);
Reduction ReduceSelect(Node* node); Reduction ReduceSelect(Node* node);
Reduction ReduceJSSubtract(Node* node); Reduction ReduceJSSubtract(Node* node);
......
...@@ -51,6 +51,10 @@ bool MustAlias(Node* a, Node* b) { return QueryAlias(a, b) == kMustAlias; } ...@@ -51,6 +51,10 @@ bool MustAlias(Node* a, Node* b) { return QueryAlias(a, b) == kMustAlias; }
Reduction LoadElimination::Reduce(Node* node) { Reduction LoadElimination::Reduce(Node* node) {
switch (node->opcode()) { switch (node->opcode()) {
case IrOpcode::kCheckMaps:
return ReduceCheckMaps(node);
case IrOpcode::kTransitionElementsKind:
return ReduceTransitionElementsKind(node);
case IrOpcode::kLoadField: case IrOpcode::kLoadField:
return ReduceLoadField(node); return ReduceLoadField(node);
case IrOpcode::kStoreField: case IrOpcode::kStoreField:
...@@ -301,6 +305,52 @@ void LoadElimination::AbstractStateForEffectNodes::Set( ...@@ -301,6 +305,52 @@ void LoadElimination::AbstractStateForEffectNodes::Set(
info_for_node_[id] = state; info_for_node_[id] = state;
} }
Reduction LoadElimination::ReduceCheckMaps(Node* node) {
Node* const object = NodeProperties::GetValueInput(node, 0);
Node* const effect = NodeProperties::GetEffectInput(node);
AbstractState const* state = node_states_.Get(effect);
if (state == nullptr) return NoChange();
int const map_input_count = node->op()->ValueInputCount() - 1;
if (Node* const object_map = state->LookupField(object, 0)) {
for (int i = 0; i < map_input_count; ++i) {
Node* map = NodeProperties::GetValueInput(node, 1 + i);
if (map == object_map) return Replace(effect);
}
}
if (map_input_count == 1) {
Node* const map0 = NodeProperties::GetValueInput(node, 1);
state = state->AddField(object, 0, map0, zone());
}
return UpdateState(node, state);
}
Reduction LoadElimination::ReduceTransitionElementsKind(Node* node) {
Node* const object = NodeProperties::GetValueInput(node, 0);
Node* const source_map = NodeProperties::GetValueInput(node, 1);
Node* const target_map = NodeProperties::GetValueInput(node, 2);
Node* const effect = NodeProperties::GetEffectInput(node);
AbstractState const* state = node_states_.Get(effect);
if (state == nullptr) return NoChange();
if (Node* const object_map = state->LookupField(object, 0)) {
state = state->KillField(object, 0, zone());
if (source_map == object_map) {
state = state->AddField(object, 0, target_map, zone());
}
} else {
state = state->KillField(object, 0, zone());
}
ElementsTransition transition = ElementsTransitionOf(node->op());
switch (transition) {
case ElementsTransition::kFastTransition:
break;
case ElementsTransition::kSlowTransition:
// Kill the elements as well.
state = state->KillField(object, 2, zone());
break;
}
return UpdateState(node, state);
}
Reduction LoadElimination::ReduceLoadField(Node* node) { Reduction LoadElimination::ReduceLoadField(Node* node) {
FieldAccess const& access = FieldAccessOf(node->op()); FieldAccess const& access = FieldAccessOf(node->op());
Node* const object = NodeProperties::GetValueInput(node, 0); Node* const object = NodeProperties::GetValueInput(node, 0);
......
...@@ -149,6 +149,8 @@ class LoadElimination final : public AdvancedReducer { ...@@ -149,6 +149,8 @@ class LoadElimination final : public AdvancedReducer {
ZoneVector<AbstractState const*> info_for_node_; ZoneVector<AbstractState const*> info_for_node_;
}; };
Reduction ReduceCheckMaps(Node* node);
Reduction ReduceTransitionElementsKind(Node* node);
Reduction ReduceLoadField(Node* node); Reduction ReduceLoadField(Node* node);
Reduction ReduceStoreField(Node* node); Reduction ReduceStoreField(Node* node);
Reduction ReduceLoadElement(Node* node); Reduction ReduceLoadElement(Node* node);
......
...@@ -269,6 +269,7 @@ ...@@ -269,6 +269,7 @@
V(StringFromCharCode) \ V(StringFromCharCode) \
V(CheckBounds) \ V(CheckBounds) \
V(CheckIf) \ V(CheckIf) \
V(CheckMaps) \
V(CheckNumber) \ V(CheckNumber) \
V(CheckString) \ V(CheckString) \
V(CheckTaggedPointer) \ V(CheckTaggedPointer) \
......
...@@ -1469,10 +1469,7 @@ bool PipelineImpl::CreateGraph() { ...@@ -1469,10 +1469,7 @@ bool PipelineImpl::CreateGraph() {
// Type the graph and keep the Typer running on newly created nodes within // Type the graph and keep the Typer running on newly created nodes within
// this scope; the Typer is automatically unlinked from the Graph once we // this scope; the Typer is automatically unlinked from the Graph once we
// leave this scope below. // leave this scope below.
Typer typer(isolate(), data->graph(), info()->is_deoptimization_enabled() Typer typer(isolate(), data->graph());
? Typer::kDeoptimizationEnabled
: Typer::kNoFlags,
info()->dependencies());
Run<TyperPhase>(&typer); Run<TyperPhase>(&typer);
RunPrintAndVerify("Typed"); RunPrintAndVerify("Typed");
......
...@@ -2226,6 +2226,7 @@ class RepresentationSelector { ...@@ -2226,6 +2226,7 @@ class RepresentationSelector {
} }
return; return;
} }
case IrOpcode::kCheckMaps:
case IrOpcode::kTransitionElementsKind: { case IrOpcode::kTransitionElementsKind: {
VisitInputs(node); VisitInputs(node);
return SetOutput(node, MachineRepresentation::kNone); return SetOutput(node, MachineRepresentation::kNone);
......
...@@ -507,6 +507,18 @@ const Operator* SimplifiedOperatorBuilder::CheckedInt32Mul( ...@@ -507,6 +507,18 @@ const Operator* SimplifiedOperatorBuilder::CheckedInt32Mul(
return nullptr; return nullptr;
} }
const Operator* SimplifiedOperatorBuilder::CheckMaps(int map_input_count) {
// TODO(bmeurer): Cache the most important versions of this operator.
DCHECK_LT(0, map_input_count);
int const value_input_count = 1 + map_input_count;
return new (zone()) Operator1<int>( // --
IrOpcode::kCheckMaps, // opcode
Operator::kNoThrow | Operator::kNoWrite, // flags
"CheckMaps", // name
value_input_count, 1, 1, 0, 1, 0, // counts
map_input_count); // parameter
}
const Operator* SimplifiedOperatorBuilder::CheckFloat64Hole( const Operator* SimplifiedOperatorBuilder::CheckFloat64Hole(
CheckFloat64HoleMode mode) { CheckFloat64HoleMode mode) {
switch (mode) { switch (mode) {
......
...@@ -273,6 +273,7 @@ class SimplifiedOperatorBuilder final : public ZoneObject { ...@@ -273,6 +273,7 @@ class SimplifiedOperatorBuilder final : public ZoneObject {
const Operator* CheckIf(); const Operator* CheckIf();
const Operator* CheckBounds(); const Operator* CheckBounds();
const Operator* CheckMaps(int map_input_count);
const Operator* CheckNumber(); const Operator* CheckNumber();
const Operator* CheckString(); const Operator* CheckString();
const Operator* CheckTaggedPointer(); const Operator* CheckTaggedPointer();
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
#include "src/base/flags.h" #include "src/base/flags.h"
#include "src/bootstrapper.h" #include "src/bootstrapper.h"
#include "src/compilation-dependencies.h"
#include "src/compiler/common-operator.h" #include "src/compiler/common-operator.h"
#include "src/compiler/graph-reducer.h" #include "src/compiler/graph-reducer.h"
#include "src/compiler/js-operator.h" #include "src/compiler/js-operator.h"
...@@ -31,12 +30,9 @@ class Typer::Decorator final : public GraphDecorator { ...@@ -31,12 +30,9 @@ class Typer::Decorator final : public GraphDecorator {
Typer* const typer_; Typer* const typer_;
}; };
Typer::Typer(Isolate* isolate, Graph* graph, Flags flags, Typer::Typer(Isolate* isolate, Graph* graph)
CompilationDependencies* dependencies)
: isolate_(isolate), : isolate_(isolate),
graph_(graph), graph_(graph),
flags_(flags),
dependencies_(dependencies),
decorator_(nullptr), decorator_(nullptr),
cache_(TypeCache::Get()), cache_(TypeCache::Get()),
operation_typer_(isolate, zone()) { operation_typer_(isolate, zone()) {
...@@ -222,10 +218,6 @@ class Typer::Visitor : public Reducer { ...@@ -222,10 +218,6 @@ class Typer::Visitor : public Reducer {
Zone* zone() { return typer_->zone(); } Zone* zone() { return typer_->zone(); }
Isolate* isolate() { return typer_->isolate(); } Isolate* isolate() { return typer_->isolate(); }
Graph* graph() { return typer_->graph(); } Graph* graph() { return typer_->graph(); }
Typer::Flags flags() const { return typer_->flags(); }
CompilationDependencies* dependencies() const {
return typer_->dependencies();
}
void SetWeakened(NodeId node_id) { weakened_nodes_.insert(node_id); } void SetWeakened(NodeId node_id) { weakened_nodes_.insert(node_id); }
bool IsWeakened(NodeId node_id) { bool IsWeakened(NodeId node_id) {
...@@ -1897,6 +1889,11 @@ Type* Typer::Visitor::TypeCheckBounds(Node* node) { ...@@ -1897,6 +1889,11 @@ Type* Typer::Visitor::TypeCheckBounds(Node* node) {
return Type::Unsigned31(); return Type::Unsigned31();
} }
Type* Typer::Visitor::TypeCheckMaps(Node* node) {
UNREACHABLE();
return nullptr;
}
Type* Typer::Visitor::TypeCheckNumber(Node* node) { Type* Typer::Visitor::TypeCheckNumber(Node* node) {
Type* arg = Operand(node, 0); Type* arg = Operand(node, 0);
return Type::Intersect(arg, Type::Number(), zone()); return Type::Intersect(arg, Type::Number(), zone());
...@@ -1947,57 +1944,10 @@ Type* Typer::Visitor::TypeCheckTaggedHole(Node* node) { ...@@ -1947,57 +1944,10 @@ Type* Typer::Visitor::TypeCheckTaggedHole(Node* node) {
Type* Typer::Visitor::TypeAllocate(Node* node) { return Type::TaggedPointer(); } Type* Typer::Visitor::TypeAllocate(Node* node) { return Type::TaggedPointer(); }
namespace {
MaybeHandle<Map> GetStableMapFromObjectType(Type* object_type) {
if (object_type->IsConstant() &&
object_type->AsConstant()->Value()->IsHeapObject()) {
Handle<Map> object_map(
Handle<HeapObject>::cast(object_type->AsConstant()->Value())->map());
if (object_map->is_stable()) return object_map;
} else if (object_type->IsClass()) {
Handle<Map> object_map = object_type->AsClass()->Map();
if (object_map->is_stable()) return object_map;
}
return MaybeHandle<Map>();
}
} // namespace
Type* Typer::Visitor::TypeLoadField(Node* node) { Type* Typer::Visitor::TypeLoadField(Node* node) {
FieldAccess const& access = FieldAccessOf(node->op()); return FieldAccessOf(node->op()).type;
if (access.base_is_tagged == kTaggedBase &&
access.offset == HeapObject::kMapOffset) {
// The type of LoadField[Map](o) is Constant(map) if map is stable and
// either
// (a) o has type Constant(object) and map == object->map, or
// (b) o has type Class(map),
// and either
// (1) map cannot transition further, or
// (2) deoptimization is enabled and we can add a code dependency on the
// stability of map (to guard the Constant type information).
Type* const object = Operand(node, 0);
if (object->Is(Type::None())) return Type::None();
Handle<Map> object_map;
if (GetStableMapFromObjectType(object).ToHandle(&object_map)) {
if (object_map->CanTransition()) {
if (flags() & kDeoptimizationEnabled) {
dependencies()->AssumeMapStable(object_map);
} else {
return access.type;
}
}
Type* object_map_type = Type::Constant(object_map, zone());
DCHECK(object_map_type->Is(access.type));
return object_map_type;
}
}
return access.type;
} }
Type* Typer::Visitor::TypeLoadBuffer(Node* node) { Type* Typer::Visitor::TypeLoadBuffer(Node* node) {
// TODO(bmeurer): This typing is not yet correct. Since we can still access // TODO(bmeurer): This typing is not yet correct. Since we can still access
// out of bounds, the type in the general case has to include Undefined. // out of bounds, the type in the general case has to include Undefined.
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
#ifndef V8_COMPILER_TYPER_H_ #ifndef V8_COMPILER_TYPER_H_
#define V8_COMPILER_TYPER_H_ #define V8_COMPILER_TYPER_H_
#include "src/base/flags.h"
#include "src/compiler/graph.h" #include "src/compiler/graph.h"
#include "src/compiler/operation-typer.h" #include "src/compiler/operation-typer.h"
#include "src/types.h" #include "src/types.h"
...@@ -14,7 +13,6 @@ namespace v8 { ...@@ -14,7 +13,6 @@ namespace v8 {
namespace internal { namespace internal {
// Forward declarations. // Forward declarations.
class CompilationDependencies;
class TypeCache; class TypeCache;
namespace compiler { namespace compiler {
...@@ -24,15 +22,7 @@ class OperationTyper; ...@@ -24,15 +22,7 @@ class OperationTyper;
class Typer { class Typer {
public: public:
// Flags that control the mode of operation. Typer(Isolate* isolate, Graph* graph);
enum Flag {
kNoFlags = 0u,
kDeoptimizationEnabled = 1u << 0,
};
typedef base::Flags<Flag> Flags;
Typer(Isolate* isolate, Graph* graph, Flags flags = kNoFlags,
CompilationDependencies* dependencies = nullptr);
~Typer(); ~Typer();
void Run(); void Run();
...@@ -47,14 +37,10 @@ class Typer { ...@@ -47,14 +37,10 @@ class Typer {
Graph* graph() const { return graph_; } Graph* graph() const { return graph_; }
Zone* zone() const { return graph()->zone(); } Zone* zone() const { return graph()->zone(); }
Isolate* isolate() const { return isolate_; } Isolate* isolate() const { return isolate_; }
Flags flags() const { return flags_; }
CompilationDependencies* dependencies() const { return dependencies_; }
OperationTyper* operation_typer() { return &operation_typer_; } OperationTyper* operation_typer() { return &operation_typer_; }
Isolate* const isolate_; Isolate* const isolate_;
Graph* const graph_; Graph* const graph_;
Flags const flags_;
CompilationDependencies* const dependencies_;
Decorator* decorator_; Decorator* decorator_;
TypeCache const& cache_; TypeCache const& cache_;
OperationTyper operation_typer_; OperationTyper operation_typer_;
...@@ -70,8 +56,6 @@ class Typer { ...@@ -70,8 +56,6 @@ class Typer {
DISALLOW_COPY_AND_ASSIGN(Typer); DISALLOW_COPY_AND_ASSIGN(Typer);
}; };
DEFINE_OPERATORS_FOR_FLAGS(Typer::Flags)
} // namespace compiler } // namespace compiler
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
......
...@@ -972,6 +972,14 @@ void Verifier::Visitor::Check(Node* node) { ...@@ -972,6 +972,14 @@ void Verifier::Visitor::Check(Node* node) {
CheckValueInputIs(node, 1, Type::Unsigned31()); CheckValueInputIs(node, 1, Type::Unsigned31());
CheckUpperIs(node, Type::Unsigned31()); CheckUpperIs(node, Type::Unsigned31());
break; break;
case IrOpcode::kCheckMaps:
// (Any, Internal, ..., Internal) -> Any
CheckValueInputIs(node, 0, Type::Any());
for (int i = 1; i < node->op()->ValueInputCount(); ++i) {
CheckValueInputIs(node, i, Type::Internal());
}
CheckNotTyped(node);
break;
case IrOpcode::kCheckNumber: case IrOpcode::kCheckNumber:
CheckValueInputIs(node, 0, Type::Any()); CheckValueInputIs(node, 0, Type::Any());
CheckUpperIs(node, Type::Number()); CheckUpperIs(node, Type::Number());
......
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