[turbofan] Disallow typing for change/checked operators.

There are no useful typing rules for Change and Checked operators, so we
better make sure we don't run them through the Typer at all.

R=jarin@chromium.org

Review-Url: https://codereview.chromium.org/2107783004
Cr-Commit-Position: refs/heads/master@{#37382}
This commit is contained in:
bmeurer 2016-06-29 03:29:37 -07:00 committed by Commit bot
parent 67b5a501db
commit 6f920d7d59
8 changed files with 79 additions and 192 deletions

View File

@ -1847,6 +1847,15 @@ Reduction JSTypedLowering::ReduceSelect(Node* node) {
return NoChange();
}
Reduction JSTypedLowering::ReduceNumberRoundop(Node* node) {
// TODO(bmeurer): Find a better home for this thing!
Node* const input = NodeProperties::GetValueInput(node, 0);
Type* const input_type = NodeProperties::GetType(input);
if (input_type->Is(type_cache_.kIntegerOrMinusZeroOrNaN)) {
return Replace(input);
}
return NoChange();
}
Reduction JSTypedLowering::Reduce(Node* node) {
// Check if the output type is a singleton. In that case we already know the
@ -1968,6 +1977,11 @@ Reduction JSTypedLowering::Reduce(Node* node) {
return ReduceJSGeneratorRestoreRegister(node);
case IrOpcode::kSelect:
return ReduceSelect(node);
case IrOpcode::kNumberCeil:
case IrOpcode::kNumberFloor:
case IrOpcode::kNumberRound:
case IrOpcode::kNumberTrunc:
return ReduceNumberRoundop(node);
default:
break;
}

View File

@ -80,6 +80,7 @@ class JSTypedLowering final : public AdvancedReducer {
Reduction ReduceJSGeneratorStore(Node* node);
Reduction ReduceJSGeneratorRestoreContinuation(Node* node);
Reduction ReduceJSGeneratorRestoreRegister(Node* node);
Reduction ReduceNumberRoundop(Node* node);
Reduction ReduceSelect(Node* node);
Reduction ReduceJSSubtract(Node* node);
Reduction ReduceJSDivide(Node* node);

View File

@ -163,6 +163,28 @@
JS_OTHER_OP_LIST(V)
// Opcodes for VirtuaMachine-level operators.
#define SIMPLIFIED_CHANGE_OP_LIST(V) \
V(ChangeTaggedSignedToInt32) \
V(ChangeTaggedToInt32) \
V(ChangeTaggedToUint32) \
V(ChangeTaggedToFloat64) \
V(ChangeInt31ToTaggedSigned) \
V(ChangeInt32ToTagged) \
V(ChangeUint32ToTagged) \
V(ChangeFloat64ToTagged) \
V(ChangeTaggedToBit) \
V(ChangeBitToTagged) \
V(TruncateTaggedToWord32) \
V(TruncateTaggedToFloat64)
#define SIMPLIFIED_CHECKED_OP_LIST(V) \
V(CheckedInt32Add) \
V(CheckedInt32Sub) \
V(CheckedUint32ToInt32) \
V(CheckedFloat64ToInt32) \
V(CheckedTaggedToInt32) \
V(CheckedTaggedToFloat64)
#define SIMPLIFIED_COMPARE_BINOP_LIST(V) \
V(NumberEqual) \
V(NumberLessThan) \
@ -172,8 +194,7 @@
V(StringLessThan) \
V(StringLessThanOrEqual)
#define SIMPLIFIED_OP_LIST(V) \
SIMPLIFIED_COMPARE_BINOP_LIST(V) \
#define SIMPLIFIED_OTHER_OP_LIST(V) \
V(PlainPrimitiveToNumber) \
V(PlainPrimitiveToWord32) \
V(PlainPrimitiveToFloat64) \
@ -226,30 +247,12 @@
V(NumberSilenceNaN) \
V(StringFromCharCode) \
V(StringToNumber) \
V(ChangeTaggedSignedToInt32) \
V(ChangeTaggedToInt32) \
V(ChangeTaggedToUint32) \
V(ChangeTaggedToFloat64) \
V(ChangeInt31ToTaggedSigned) \
V(ChangeInt32ToTagged) \
V(ChangeUint32ToTagged) \
V(ChangeFloat64ToTagged) \
V(ChangeTaggedToBit) \
V(ChangeBitToTagged) \
V(CheckBounds) \
V(CheckNumber) \
V(CheckTaggedPointer) \
V(CheckTaggedSigned) \
V(CheckedInt32Add) \
V(CheckedInt32Sub) \
V(CheckedUint32ToInt32) \
V(CheckedFloat64ToInt32) \
V(CheckedTaggedToInt32) \
V(CheckedTaggedToFloat64) \
V(CheckFloat64Hole) \
V(CheckTaggedHole) \
V(TruncateTaggedToWord32) \
V(TruncateTaggedToFloat64) \
V(Allocate) \
V(LoadField) \
V(LoadBuffer) \
@ -264,6 +267,12 @@
V(ObjectIsString) \
V(ObjectIsUndetectable)
#define SIMPLIFIED_OP_LIST(V) \
SIMPLIFIED_CHANGE_OP_LIST(V) \
SIMPLIFIED_CHECKED_OP_LIST(V) \
SIMPLIFIED_COMPARE_BINOP_LIST(V) \
SIMPLIFIED_OTHER_OP_LIST(V)
// Opcodes for Machine-level operators.
#define MACHINE_COMPARE_BINOP_LIST(V) \
V(Word32Equal) \

View File

@ -34,9 +34,7 @@ Decision DecideObjectIsSmi(Node* const input) {
SimplifiedOperatorReducer::SimplifiedOperatorReducer(Editor* editor,
JSGraph* jsgraph)
: AdvancedReducer(editor),
jsgraph_(jsgraph),
type_cache_(TypeCache::Get()) {}
: AdvancedReducer(editor), jsgraph_(jsgraph) {}
SimplifiedOperatorReducer::~SimplifiedOperatorReducer() {}
@ -162,41 +160,17 @@ Reduction SimplifiedOperatorReducer::Reduce(Node* node) {
if (m.HasValue()) return ReplaceNumber(std::fabs(m.Value()));
break;
}
case IrOpcode::kNumberCeil:
case IrOpcode::kNumberFloor:
case IrOpcode::kNumberRound:
case IrOpcode::kNumberTrunc: {
Node* const input = NodeProperties::GetValueInput(node, 0);
Type* const input_type = NodeProperties::GetType(input);
if (input_type->Is(type_cache_.kIntegerOrMinusZeroOrNaN)) {
return Replace(input);
}
case IrOpcode::kReferenceEqual: {
HeapObjectBinopMatcher m(node);
if (m.left().node() == m.right().node()) return ReplaceBoolean(true);
break;
}
case IrOpcode::kReferenceEqual:
return ReduceReferenceEqual(node);
default:
break;
}
return NoChange();
}
Reduction SimplifiedOperatorReducer::ReduceReferenceEqual(Node* node) {
DCHECK_EQ(IrOpcode::kReferenceEqual, node->opcode());
Node* const left = NodeProperties::GetValueInput(node, 0);
Node* const right = NodeProperties::GetValueInput(node, 1);
HeapObjectMatcher match_left(left);
HeapObjectMatcher match_right(right);
if (match_left.HasValue() && match_right.HasValue()) {
if (match_left.Value().is_identical_to(match_right.Value())) {
return Replace(jsgraph()->TrueConstant());
} else {
return Replace(jsgraph()->FalseConstant());
}
}
return NoChange();
}
Reduction SimplifiedOperatorReducer::Change(Node* node, const Operator* op,
Node* a) {
DCHECK_EQ(node->InputCount(), OperatorProperties::GetTotalInputCount(op));

View File

@ -9,10 +9,6 @@
namespace v8 {
namespace internal {
// Forward declarations.
class TypeCache;
namespace compiler {
// Forward declarations.
@ -46,7 +42,6 @@ class SimplifiedOperatorReducer final : public AdvancedReducer {
SimplifiedOperatorBuilder* simplified() const;
JSGraph* const jsgraph_;
TypeCache const& type_cache_;
DISALLOW_COPY_AND_ASSIGN(SimplifiedOperatorReducer);
};

View File

@ -97,7 +97,8 @@ class Typer::Visitor : public Reducer {
DECLARE_CASE(IfException)
// VALUE_OP_LIST without JS_SIMPLE_BINOP_LIST:
COMMON_OP_LIST(DECLARE_CASE)
SIMPLIFIED_OP_LIST(DECLARE_CASE)
SIMPLIFIED_COMPARE_BINOP_LIST(DECLARE_CASE)
SIMPLIFIED_OTHER_OP_LIST(DECLARE_CASE)
MACHINE_OP_LIST(DECLARE_CASE)
MACHINE_SIMD_OP_LIST(DECLARE_CASE)
JS_SIMPLE_UNOP_LIST(DECLARE_CASE)
@ -126,6 +127,8 @@ class Typer::Visitor : public Reducer {
DECLARE_CASE(OsrLoopEntry)
DECLARE_CASE(Throw)
DECLARE_CASE(End)
SIMPLIFIED_CHANGE_OP_LIST(DECLARE_CASE)
SIMPLIFIED_CHECKED_OP_LIST(DECLARE_CASE)
#undef DECLARE_CASE
break;
}
@ -144,7 +147,8 @@ class Typer::Visitor : public Reducer {
DECLARE_CASE(IfException)
// VALUE_OP_LIST without JS_SIMPLE_BINOP_LIST:
COMMON_OP_LIST(DECLARE_CASE)
SIMPLIFIED_OP_LIST(DECLARE_CASE)
SIMPLIFIED_COMPARE_BINOP_LIST(DECLARE_CASE)
SIMPLIFIED_OTHER_OP_LIST(DECLARE_CASE)
MACHINE_OP_LIST(DECLARE_CASE)
MACHINE_SIMD_OP_LIST(DECLARE_CASE)
JS_SIMPLE_UNOP_LIST(DECLARE_CASE)
@ -173,6 +177,8 @@ class Typer::Visitor : public Reducer {
DECLARE_CASE(OsrLoopEntry)
DECLARE_CASE(Throw)
DECLARE_CASE(End)
SIMPLIFIED_CHANGE_OP_LIST(DECLARE_CASE)
SIMPLIFIED_CHECKED_OP_LIST(DECLARE_CASE)
#undef DECLARE_CASE
break;
}
@ -189,7 +195,12 @@ class Typer::Visitor : public Reducer {
#define DECLARE_METHOD(x) inline Type* Type##x(Node* node);
DECLARE_METHOD(Start)
DECLARE_METHOD(IfException)
VALUE_OP_LIST(DECLARE_METHOD)
COMMON_OP_LIST(DECLARE_METHOD)
SIMPLIFIED_COMPARE_BINOP_LIST(DECLARE_METHOD)
SIMPLIFIED_OTHER_OP_LIST(DECLARE_METHOD)
MACHINE_OP_LIST(DECLARE_METHOD)
MACHINE_SIMD_OP_LIST(DECLARE_METHOD)
JS_OP_LIST(DECLARE_METHOD)
#undef DECLARE_METHOD
Type* TypeOrNone(Node* node) {
@ -1725,98 +1736,6 @@ Type* Typer::Visitor::TypeStringToNumber(Node* node) {
return TypeUnaryOp(node, ToNumber);
}
namespace {
Type* ChangeRepresentation(Type* type, Type* rep, Zone* zone) {
return Type::Union(Type::Semantic(type, zone),
Type::Representation(rep, zone), zone);
}
} // namespace
Type* Typer::Visitor::TypeChangeTaggedSignedToInt32(Node* node) {
Type* arg = Operand(node, 0);
// TODO(jarin): DCHECK(arg->Is(Type::Signed32()));
// Many tests fail this check.
return ChangeRepresentation(arg, Type::UntaggedIntegral32(), zone());
}
Type* Typer::Visitor::TypeChangeTaggedToInt32(Node* node) {
Type* arg = Operand(node, 0);
DCHECK(arg->Is(Type::Signed32()));
return ChangeRepresentation(arg, Type::UntaggedIntegral32(), zone());
}
Type* Typer::Visitor::TypeChangeTaggedToUint32(Node* node) {
Type* arg = Operand(node, 0);
DCHECK(arg->Is(Type::Unsigned32()));
return ChangeRepresentation(arg, Type::UntaggedIntegral32(), zone());
}
Type* Typer::Visitor::TypeChangeTaggedToFloat64(Node* node) {
Type* arg = Operand(node, 0);
DCHECK(arg->Is(Type::Number()));
return ChangeRepresentation(arg, Type::UntaggedFloat64(), zone());
}
Type* Typer::Visitor::TypeTruncateTaggedToFloat64(Node* node) {
Type* arg = Operand(node, 0);
// TODO(jarin) This DCHECK does not work because of speculative feedback.
// Re-enable once we record the speculative feedback in types.
// DCHECK(arg->Is(Type::NumberOrOddball()));
return ChangeRepresentation(arg, Type::UntaggedFloat64(), zone());
}
Type* Typer::Visitor::TypeChangeInt31ToTaggedSigned(Node* node) {
Type* arg = Operand(node, 0);
// TODO(jarin): DCHECK(arg->Is(Type::Signed31()));
// Some mjsunit/asm and mjsunit/wasm tests fail this check.
// For instance, asm/int32-umod fails with Signed32/UntaggedIntegral32 in
// simplified-lowering (after propagation).
Type* rep =
arg->Is(Type::SignedSmall()) ? Type::TaggedSigned() : Type::Tagged();
return ChangeRepresentation(arg, rep, zone());
}
Type* Typer::Visitor::TypeChangeInt32ToTagged(Node* node) {
Type* arg = Operand(node, 0);
// TODO(jarin): DCHECK(arg->Is(Type::Signed32()));
// Two tests fail this check: mjsunit/asm/sqlite3/sqlite-safe-heap and
// mjsunit/wasm/embenchen/lua_binarytrees. The first one fails with Any/Any in
// simplified-lowering (after propagation).
Type* rep =
arg->Is(Type::SignedSmall()) ? Type::TaggedSigned() : Type::Tagged();
return ChangeRepresentation(arg, rep, zone());
}
Type* Typer::Visitor::TypeChangeUint32ToTagged(Node* node) {
Type* arg = Operand(node, 0);
// TODO(jarin): DCHECK(arg->Is(Type::Unsigned32()));
// This fails in benchmarks/octane/mandreel (--turbo).
return ChangeRepresentation(arg, Type::Tagged(), zone());
}
Type* Typer::Visitor::TypeChangeFloat64ToTagged(Node* node) {
Type* arg = Operand(node, 0);
// TODO(jarin): DCHECK(arg->Is(Type::Number()));
// Some (or all) mjsunit/wasm/embenchen/ tests fail this check when run with
// --turbo and --always-opt.
return ChangeRepresentation(arg, Type::Tagged(), zone());
}
Type* Typer::Visitor::TypeChangeTaggedToBit(Node* node) {
Type* arg = Operand(node, 0);
DCHECK(arg->Is(Type::Boolean()));
return ChangeRepresentation(arg, Type::UntaggedBit(), zone());
}
Type* Typer::Visitor::TypeChangeBitToTagged(Node* node) {
Type* arg = Operand(node, 0);
return ChangeRepresentation(arg, Type::TaggedPointer(), zone());
}
Type* Typer::Visitor::TypeCheckBounds(Node* node) {
// TODO(bmeurer): We could do better here based on the limit.
return Type::Unsigned31();
@ -1837,30 +1756,6 @@ Type* Typer::Visitor::TypeCheckTaggedSigned(Node* node) {
return Type::Intersect(arg, typer_->cache_.kSmi, zone());
}
Type* Typer::Visitor::TypeCheckedInt32Add(Node* node) {
return Type::Integral32();
}
Type* Typer::Visitor::TypeCheckedInt32Sub(Node* node) {
return Type::Integral32();
}
Type* Typer::Visitor::TypeCheckedUint32ToInt32(Node* node) {
return Type::Signed32();
}
Type* Typer::Visitor::TypeCheckedFloat64ToInt32(Node* node) {
return Type::Signed32();
}
Type* Typer::Visitor::TypeCheckedTaggedToInt32(Node* node) {
return Type::Signed32();
}
Type* Typer::Visitor::TypeCheckedTaggedToFloat64(Node* node) {
return Type::Number();
}
Type* Typer::Visitor::TypeCheckFloat64Hole(Node* node) {
Type* type = Operand(node, 0);
return type;
@ -1884,15 +1779,6 @@ Type* Typer::Visitor::TypeCheckTaggedHole(Node* node) {
return type;
}
Type* Typer::Visitor::TypeTruncateTaggedToWord32(Node* node) {
Type* arg = Operand(node, 0);
// TODO(jarin): DCHECK(arg->Is(Type::NumberOrUndefined()));
// Several mjsunit and cctest tests fail this check. For instance,
// mjsunit/compiler/regress-607493 fails with Any/Any in simplified-lowering
// (after propagation).
return ChangeRepresentation(arg, Type::UntaggedIntegral32(), zone());
}
Type* Typer::Visitor::TypeAllocate(Node* node) { return Type::TaggedPointer(); }

View File

@ -37,14 +37,15 @@ class SimplifiedLoweringTester : public GraphBuilderTester<ReturnType> {
SimplifiedLoweringTester(MachineType p0 = MachineType::None(),
MachineType p1 = MachineType::None())
: GraphBuilderTester<ReturnType>(p0, p1),
typer(this->isolate(), this->graph()),
typer(new Typer(this->isolate(), this->graph())),
javascript(this->zone()),
jsgraph(this->isolate(), this->graph(), this->common(), &javascript,
this->simplified(), this->machine()),
source_positions(jsgraph.graph()),
lowering(&jsgraph, this->zone(), &source_positions) {}
~SimplifiedLoweringTester() final { delete typer; }
Typer typer;
Typer* typer = nullptr;
JSOperatorBuilder javascript;
JSGraph jsgraph;
SourcePositionTable source_positions;
@ -52,13 +53,15 @@ class SimplifiedLoweringTester : public GraphBuilderTester<ReturnType> {
void LowerAllNodes() {
this->End();
typer.Run();
typer->Run();
delete typer, typer = nullptr;
lowering.LowerAllNodes();
}
void LowerAllNodesAndLowerChanges() {
this->End();
typer.Run();
typer->Run();
delete typer, typer = nullptr;
lowering.LowerAllNodes();
Schedule* schedule = Scheduler::ComputeSchedule(this->zone(), this->graph(),
@ -682,7 +685,7 @@ TEST(RunAllocate) {
// Fills in most of the nodes of the graph in order to make tests shorter.
class TestingGraph : public HandleAndZoneScope, public GraphAndBuilders {
public:
Typer typer;
Typer* typer = nullptr;
JSOperatorBuilder javascript;
JSGraph jsgraph;
Node* p0;
@ -695,7 +698,7 @@ class TestingGraph : public HandleAndZoneScope, public GraphAndBuilders {
explicit TestingGraph(Type* p0_type, Type* p1_type = Type::None(),
Type* p2_type = Type::None())
: GraphAndBuilders(main_zone()),
typer(main_isolate(), graph()),
typer(new Typer(main_isolate(), graph())),
javascript(main_zone()),
jsgraph(main_isolate(), graph(), common(), &javascript, simplified(),
machine()) {
@ -708,11 +711,12 @@ class TestingGraph : public HandleAndZoneScope, public GraphAndBuilders {
p0 = graph()->NewNode(common()->Parameter(0), start);
p1 = graph()->NewNode(common()->Parameter(1), start);
p2 = graph()->NewNode(common()->Parameter(2), start);
typer.Run();
typer->Run();
NodeProperties::SetType(p0, p0_type);
NodeProperties::SetType(p1, p1_type);
NodeProperties::SetType(p2, p2_type);
}
~TestingGraph() { delete typer; }
void CheckLoweringBinop(IrOpcode::Value expected, const Operator* op) {
Node* node = Return(graph()->NewNode(op, p0, p1));
@ -736,11 +740,14 @@ class TestingGraph : public HandleAndZoneScope, public GraphAndBuilders {
}
void Lower() {
delete typer;
SourcePositionTable table(jsgraph.graph());
SimplifiedLowering(&jsgraph, jsgraph.zone(), &table).LowerAllNodes();
typer = new Typer(main_isolate(), graph());
}
void LowerAllNodesAndLowerChanges() {
delete typer;
SourcePositionTable table(jsgraph.graph());
SimplifiedLowering(&jsgraph, jsgraph.zone(), &table).LowerAllNodes();
@ -751,6 +758,7 @@ class TestingGraph : public HandleAndZoneScope, public GraphAndBuilders {
MemoryOptimizer memory_optimizer(&jsgraph, this->zone());
memory_optimizer.Optimize();
typer = new Typer(main_isolate(), graph());
}
// Inserts the node as the return value of the graph.

View File

@ -20,10 +20,10 @@ namespace v8 {
namespace internal {
namespace compiler {
class SimplifiedOperatorReducerTest : public TypedGraphTest {
class SimplifiedOperatorReducerTest : public GraphTest {
public:
explicit SimplifiedOperatorReducerTest(int num_parameters = 1)
: TypedGraphTest(num_parameters), simplified_(zone()) {}
: GraphTest(num_parameters), simplified_(zone()) {}
~SimplifiedOperatorReducerTest() override {}
protected: