binop(NULL),
unop(NULL),
javascript(main_zone()),
- machine(main_zone()),
simplified(main_zone()),
common(main_zone()),
graph(main_zone()),
typer(main_zone()),
- source_positions(&graph),
context_node(NULL) {
typer.DecorateGraph(&graph);
Node* s = graph.NewNode(common.Start(num_parameters));
}
Isolate* isolate;
- Operator* binop;
- Operator* unop;
+ const Operator* binop;
+ const Operator* unop;
JSOperatorBuilder javascript;
MachineOperatorBuilder machine;
SimplifiedOperatorBuilder simplified;
CommonOperatorBuilder common;
Graph graph;
Typer typer;
- SourcePositionTable source_positions;
Node* context_node;
Node* Parameter(Type* t, int32_t index = 0) {
return n;
}
+ Node* UndefinedConstant() {
+ Unique<Object> unique =
+ Unique<Object>::CreateImmovable(isolate->factory()->undefined_value());
+ return graph.NewNode(common.HeapConstant(unique));
+ }
+
+ Node* HeapConstant(Handle<Object> constant) {
+ Unique<Object> unique = Unique<Object>::CreateUninitialized(constant);
+ return graph.NewNode(common.HeapConstant(unique));
+ }
+
+ Node* EmptyFrameState(Node* context) {
+ Node* parameters = graph.NewNode(common.StateValues(0));
+ Node* locals = graph.NewNode(common.StateValues(0));
+ Node* stack = graph.NewNode(common.StateValues(0));
+
+ Node* state_node =
+ graph.NewNode(common.FrameState(JS_FRAME, BailoutId(0), kIgnoreOutput),
+ parameters, locals, stack, context, UndefinedConstant());
+
+ return state_node;
+ }
+
Node* reduce(Node* node) {
- JSGraph jsgraph(&graph, &common, &typer);
- JSTypedLowering reducer(&jsgraph, &source_positions);
+ JSGraph jsgraph(&graph, &common, &javascript, &typer, &machine);
+ JSTypedLowering reducer(&jsgraph);
Reduction reduction = reducer.Reduce(node);
if (reduction.Changed()) return reduction.replacement();
return node;
CHECK_EQ(2, node->InputCount()); // should not have context, effect, etc.
}
- void CheckPureBinop(Operator* expected, Node* node) {
+ void CheckPureBinop(const Operator* expected, Node* node) {
CHECK_EQ(expected->opcode(), node->op()->opcode());
CHECK_EQ(2, node->InputCount()); // should not have context, effect, etc.
}
- Node* ReduceUnop(Operator* op, Type* input_type) {
+ Node* ReduceUnop(const Operator* op, Type* input_type) {
return reduce(Unop(op, Parameter(input_type)));
}
- Node* ReduceBinop(Operator* op, Type* left_type, Type* right_type) {
+ Node* ReduceBinop(const Operator* op, Type* left_type, Type* right_type) {
return reduce(Binop(op, Parameter(left_type, 0), Parameter(right_type, 1)));
}
- Node* Binop(Operator* op, Node* left, Node* right) {
+ Node* Binop(const Operator* op, Node* left, Node* right) {
// JS binops also require context, effect, and control
return graph.NewNode(op, left, right, context(), start(), control());
}
- Node* Unop(Operator* op, Node* input) {
+ Node* Unop(const Operator* op, Node* input) {
// JS unops also require context, effect, and control
return graph.NewNode(op, input, context(), start(), control());
}
void CheckInt32Constant(int32_t expected, Node* result) {
CHECK_EQ(IrOpcode::kInt32Constant, result->opcode());
- CHECK_EQ(expected, ValueOf<int32_t>(result->op()));
+ CHECK_EQ(expected, OpParameter<int32_t>(result));
}
void CheckNumberConstant(double expected, Node* result) {
CHECK_EQ(IrOpcode::kNumberConstant, result->opcode());
- CHECK_EQ(expected, ValueOf<double>(result->op()));
+ CHECK_EQ(expected, OpParameter<double>(result));
}
void CheckNaN(Node* result) {
CHECK_EQ(IrOpcode::kNumberConstant, result->opcode());
- double value = ValueOf<double>(result->op());
+ double value = OpParameter<double>(result);
CHECK(std::isnan(value));
}
void CheckHandle(Handle<Object> expected, Node* result) {
CHECK_EQ(IrOpcode::kHeapConstant, result->opcode());
- Handle<Object> value = ValueOf<Handle<Object> >(result->op());
+ Handle<Object> value = OpParameter<Unique<Object> >(result).handle();
CHECK_EQ(*expected, *value);
}
};
Type::OtherUnsigned32(), Type::OtherSigned32(), Type::SignedSmall(),
Type::Signed32(), Type::Unsigned32(), Type::Integral32(),
Type::MinusZero(), Type::NaN(), Type::OtherNumber(),
- Type::Number()};
+ Type::OrderedNumber(), Type::Number()};
static Type* kJSTypes[] = {Type::Undefined(), Type::Null(), Type::Boolean(),
}
+// TODO(turbofan): Lowering of StringAdd is disabled for now.
+#if 0
TEST(StringBinops) {
JSTypedLoweringTester R;
- for (size_t i = 0; i < ARRAY_SIZE(kStringTypes); ++i) {
+ for (size_t i = 0; i < arraysize(kStringTypes); ++i) {
Node* p0 = R.Parameter(kStringTypes[i], 0);
- for (size_t j = 0; j < ARRAY_SIZE(kStringTypes); ++j) {
+ for (size_t j = 0; j < arraysize(kStringTypes); ++j) {
Node* p1 = R.Parameter(kStringTypes[j], 1);
Node* add = R.Binop(R.javascript.Add(), p0, p1);
}
}
}
+#endif
TEST(AddNumber1) {
JSTypedLoweringTester R;
- for (size_t i = 0; i < ARRAY_SIZE(kNumberTypes); ++i) {
+ for (size_t i = 0; i < arraysize(kNumberTypes); ++i) {
Node* p0 = R.Parameter(kNumberTypes[i], 0);
Node* p1 = R.Parameter(kNumberTypes[i], 1);
Node* add = R.Binop(R.javascript.Add(), p0, p1);
TEST(NumberBinops) {
JSTypedLoweringTester R;
- Operator* ops[] = {
+ const Operator* ops[] = {
R.javascript.Add(), R.simplified.NumberAdd(),
R.javascript.Subtract(), R.simplified.NumberSubtract(),
R.javascript.Multiply(), R.simplified.NumberMultiply(),
R.javascript.Modulus(), R.simplified.NumberModulus(),
};
- for (size_t i = 0; i < ARRAY_SIZE(kNumberTypes); ++i) {
+ for (size_t i = 0; i < arraysize(kNumberTypes); ++i) {
Node* p0 = R.Parameter(kNumberTypes[i], 0);
- for (size_t j = 0; j < ARRAY_SIZE(kNumberTypes); ++j) {
+ for (size_t j = 0; j < arraysize(kNumberTypes); ++j) {
Node* p1 = R.Parameter(kNumberTypes[j], 1);
- for (size_t k = 0; k < ARRAY_SIZE(ops); k += 2) {
+ for (size_t k = 0; k < arraysize(ops); k += 2) {
Node* add = R.Binop(ops[k], p0, p1);
Node* r = R.reduce(add);
CHECK_EQ(old_input, new_input);
} else if (new_input->opcode() == IrOpcode::kNumberConstant) {
CHECK(NodeProperties::GetBounds(new_input).upper->Is(expected_type));
- double v = ValueOf<double>(new_input->op());
+ double v = OpParameter<double>(new_input);
double e = static_cast<double>(is_signed ? FastD2I(v) : FastD2UI(v));
CHECK_EQ(e, v);
} else {
class JSBitwiseShiftTypedLoweringTester : public JSTypedLoweringTester {
public:
static const int kNumberOps = 6;
- Operator* ops[kNumberOps];
+ const Operator* ops[kNumberOps];
bool signedness[kNumberOps];
JSBitwiseShiftTypedLoweringTester() {
}
private:
- void set(int idx, Operator* op, bool s) {
+ void set(int idx, const Operator* op, bool s) {
ops[idx] = op;
signedness[idx] = s;
}
Type::Null(), Type::Boolean(), Type::Number(),
Type::String(), Type::Object()};
- for (size_t i = 0; i < ARRAY_SIZE(types); ++i) {
+ for (size_t i = 0; i < arraysize(types); ++i) {
Node* p0 = R.Parameter(types[i], 0);
- for (size_t j = 0; j < ARRAY_SIZE(types); ++j) {
+ for (size_t j = 0; j < arraysize(types); ++j) {
Node* p1 = R.Parameter(types[j], 1);
for (int k = 0; k < R.kNumberOps; k += 2) {
class JSBitwiseTypedLoweringTester : public JSTypedLoweringTester {
public:
static const int kNumberOps = 6;
- Operator* ops[kNumberOps];
+ const Operator* ops[kNumberOps];
bool signedness[kNumberOps];
JSBitwiseTypedLoweringTester() {
}
private:
- void set(int idx, Operator* op, bool s) {
+ void set(int idx, const Operator* op, bool s) {
ops[idx] = op;
signedness[idx] = s;
}
Type::Null(), Type::Boolean(), Type::Number(),
Type::String(), Type::Object()};
- for (size_t i = 0; i < ARRAY_SIZE(types); ++i) {
+ for (size_t i = 0; i < arraysize(types); ++i) {
Node* p0 = R.Parameter(types[i], 0);
- for (size_t j = 0; j < ARRAY_SIZE(types); ++j) {
+ for (size_t j = 0; j < arraysize(types); ++j) {
Node* p1 = R.Parameter(types[j], 1);
for (int k = 0; k < R.kNumberOps; k += 2) {
TEST(JSToNumber1) {
JSTypedLoweringTester R;
- Operator* ton = R.javascript.ToNumber();
+ const Operator* ton = R.javascript.ToNumber();
- for (size_t i = 0; i < ARRAY_SIZE(kNumberTypes); i++) { // ToNumber(number)
+ for (size_t i = 0; i < arraysize(kNumberTypes); i++) { // ToNumber(number)
Node* r = R.ReduceUnop(ton, kNumberTypes[i]);
CHECK_EQ(IrOpcode::kParameter, r->opcode());
}
Type* types[] = {Type::Null(), Type::Undefined(), Type::Number()};
- for (size_t i = 0; i < ARRAY_SIZE(types); i++) {
+ for (size_t i = 0; i < arraysize(types); i++) {
Node* n = R.Parameter(types[i]);
Node* c = R.graph.NewNode(R.javascript.ToNumber(), n, R.context(),
R.start(), R.start());
TEST(JSToNumberOfConstant) {
JSTypedLoweringTester R;
- Operator* ops[] = {R.common.NumberConstant(0), R.common.NumberConstant(-1),
- R.common.NumberConstant(0.1), R.common.Int32Constant(1177),
- R.common.Float64Constant(0.99)};
+ const Operator* ops[] = {
+ R.common.NumberConstant(0), R.common.NumberConstant(-1),
+ R.common.NumberConstant(0.1), R.common.Int32Constant(1177),
+ R.common.Float64Constant(0.99)};
- for (size_t i = 0; i < ARRAY_SIZE(ops); i++) {
+ for (size_t i = 0; i < arraysize(ops); i++) {
Node* n = R.graph.NewNode(ops[i]);
Node* convert = R.Unop(R.javascript.ToNumber(), n);
Node* r = R.reduce(convert);
Type* others[] = {Type::Undefined(), Type::Null(), Type::Boolean(),
Type::String()};
- for (size_t i = 0; i < ARRAY_SIZE(others); i++) {
+ for (size_t i = 0; i < arraysize(others); i++) {
Type* t = Type::Union(Type::Number(), others[i], R.main_zone());
Node* r = R.ReduceUnop(R.javascript.ToNumber(), t);
CHECK_EQ(IrOpcode::kJSToNumber, r->opcode());
TEST(JSToBoolean) {
JSTypedLoweringTester R;
- Operator* op = R.javascript.ToBoolean();
+ const Operator* op = R.javascript.ToBoolean();
{ // ToBoolean(undefined)
Node* r = R.ReduceUnop(op, Type::Undefined());
CHECK_EQ(IrOpcode::kParameter, r->opcode());
}
- { // ToBoolean(number)
- Node* r = R.ReduceUnop(op, Type::Number());
+ { // ToBoolean(ordered-number)
+ Node* r = R.ReduceUnop(op, Type::OrderedNumber());
CHECK_EQ(IrOpcode::kBooleanNot, r->opcode());
Node* i = r->InputAt(0);
CHECK_EQ(IrOpcode::kNumberEqual, i->opcode());
- // ToBoolean(number) => BooleanNot(NumberEqual(x, #0))
+ // ToBoolean(x:ordered-number) => BooleanNot(NumberEqual(x, #0))
}
{ // ToBoolean(string)
TEST(JSToBoolean_replacement) {
JSTypedLoweringTester R;
- Type* types[] = {Type::Null(), Type::Undefined(), Type::Boolean(),
+ Type* types[] = {Type::Null(), Type::Undefined(),
+ Type::Boolean(), Type::OrderedNumber(),
Type::DetectableObject(), Type::Undetectable()};
- for (size_t i = 0; i < ARRAY_SIZE(types); i++) {
+ for (size_t i = 0; i < arraysize(types); i++) {
Node* n = R.Parameter(types[i]);
Node* c = R.graph.NewNode(R.javascript.ToBoolean(), n, R.context(),
R.start(), R.start());
if (types[i]->Is(Type::Boolean())) {
CHECK_EQ(n, r);
+ } else if (types[i]->Is(Type::OrderedNumber())) {
+ CHECK_EQ(IrOpcode::kBooleanNot, r->opcode());
} else {
CHECK_EQ(IrOpcode::kHeapConstant, r->opcode());
}
TEST(JSToString1) {
JSTypedLoweringTester R;
- for (size_t i = 0; i < ARRAY_SIZE(kStringTypes); i++) {
+ for (size_t i = 0; i < arraysize(kStringTypes); i++) {
Node* r = R.ReduceUnop(R.javascript.ToString(), kStringTypes[i]);
CHECK_EQ(IrOpcode::kParameter, r->opcode());
}
- Operator* op = R.javascript.ToString();
+ const Operator* op = R.javascript.ToString();
{ // ToString(undefined) => "undefined"
Node* r = R.ReduceUnop(op, Type::Undefined());
Type* types[] = {Type::Null(), Type::Undefined(), Type::String()};
- for (size_t i = 0; i < ARRAY_SIZE(types); i++) {
+ for (size_t i = 0; i < arraysize(types); i++) {
Node* n = R.Parameter(types[i]);
Node* c = R.graph.NewNode(R.javascript.ToString(), n, R.context(),
R.start(), R.start());
TEST(StringComparison) {
JSTypedLoweringTester R;
- Operator* ops[] = {
+ const Operator* ops[] = {
R.javascript.LessThan(), R.simplified.StringLessThan(),
R.javascript.LessThanOrEqual(), R.simplified.StringLessThanOrEqual(),
R.javascript.GreaterThan(), R.simplified.StringLessThan(),
R.javascript.GreaterThanOrEqual(), R.simplified.StringLessThanOrEqual()};
- for (size_t i = 0; i < ARRAY_SIZE(kStringTypes); i++) {
+ for (size_t i = 0; i < arraysize(kStringTypes); i++) {
Node* p0 = R.Parameter(kStringTypes[i], 0);
- for (size_t j = 0; j < ARRAY_SIZE(kStringTypes); j++) {
+ for (size_t j = 0; j < arraysize(kStringTypes); j++) {
Node* p1 = R.Parameter(kStringTypes[j], 1);
- for (size_t k = 0; k < ARRAY_SIZE(ops); k += 2) {
+ for (size_t k = 0; k < arraysize(ops); k += 2) {
Node* cmp = R.Binop(ops[k], p0, p1);
Node* r = R.reduce(cmp);
static void CheckIsConvertedToNumber(Node* val, Node* converted) {
if (NodeProperties::GetBounds(val).upper->Is(Type::Number())) {
CHECK_EQ(val, converted);
+ } else if (NodeProperties::GetBounds(val).upper->Is(Type::Boolean())) {
+ CHECK_EQ(IrOpcode::kBooleanToNumber, converted->opcode());
+ CHECK_EQ(val, converted->InputAt(0));
} else {
if (converted->opcode() == IrOpcode::kNumberConstant) return;
CHECK_EQ(IrOpcode::kJSToNumber, converted->opcode());
TEST(NumberComparison) {
JSTypedLoweringTester R;
- Operator* ops[] = {
+ const Operator* ops[] = {
R.javascript.LessThan(), R.simplified.NumberLessThan(),
R.javascript.LessThanOrEqual(), R.simplified.NumberLessThanOrEqual(),
R.javascript.GreaterThan(), R.simplified.NumberLessThan(),
R.javascript.GreaterThanOrEqual(), R.simplified.NumberLessThanOrEqual()};
- for (size_t i = 0; i < ARRAY_SIZE(kJSTypes); i++) {
+ for (size_t i = 0; i < arraysize(kJSTypes); i++) {
Type* t0 = kJSTypes[i];
- if (t0->Is(Type::String())) continue; // skip Type::String
+ // Skip Type::String and Type::Receiver which might coerce into a string.
+ if (t0->Is(Type::String()) || t0->Is(Type::Receiver())) continue;
Node* p0 = R.Parameter(t0, 0);
- for (size_t j = 0; j < ARRAY_SIZE(kJSTypes); j++) {
+ for (size_t j = 0; j < arraysize(kJSTypes); j++) {
Type* t1 = kJSTypes[j];
- if (t1->Is(Type::String())) continue; // skip Type::String
+ // Skip Type::String and Type::Receiver which might coerce into a string.
+ if (t1->Is(Type::String()) || t0->Is(Type::Receiver())) continue;
Node* p1 = R.Parameter(t1, 1);
- for (size_t k = 0; k < ARRAY_SIZE(ops); k += 2) {
+ for (size_t k = 0; k < arraysize(ops); k += 2) {
Node* cmp = R.Binop(ops[k], p0, p1);
Node* r = R.reduce(cmp);
Type* types[] = {Type::Number(), Type::String(),
Type::Union(Type::Number(), Type::String(), R.main_zone())};
- for (size_t i = 0; i < ARRAY_SIZE(types); i++) {
+ for (size_t i = 0; i < arraysize(types); i++) {
Node* p0 = R.Parameter(types[i], 0);
- for (size_t j = 0; j < ARRAY_SIZE(types); j++) {
+ for (size_t j = 0; j < arraysize(types); j++) {
Node* p1 = R.Parameter(types[j], 1);
{
Node* cmp = R.Binop(R.javascript.LessThan(), p0, p1);
TEST(ObjectComparison) {
JSTypedLoweringTester R;
- Node* p0 = R.Parameter(Type::Object(), 0);
+ Node* p0 = R.Parameter(Type::Number(), 0);
Node* p1 = R.Parameter(Type::Object(), 1);
Node* cmp = R.Binop(R.javascript.LessThan(), p0, p1);
Node* i0 = r->InputAt(0);
Node* i1 = r->InputAt(1);
- CHECK_NE(p0, i0);
+ CHECK_EQ(p0, i0);
CHECK_NE(p1, i1);
- CHECK_EQ(IrOpcode::kJSToNumber, i0->opcode());
+ CHECK_EQ(IrOpcode::kParameter, i0->opcode());
CHECK_EQ(IrOpcode::kJSToNumber, i1->opcode());
// Check effect chain is correct.
- R.CheckEffectInput(R.start(), i0);
- R.CheckEffectInput(i0, i1);
+ R.CheckEffectInput(R.start(), i1);
R.CheckEffectInput(i1, effect_use);
}
TEST(UnaryNot) {
JSTypedLoweringTester R;
- Operator* opnot = R.javascript.UnaryNot();
+ const Operator* opnot = R.javascript.UnaryNot();
- for (size_t i = 0; i < ARRAY_SIZE(kJSTypes); i++) {
- Node* r = R.ReduceUnop(opnot, kJSTypes[i]);
+ for (size_t i = 0; i < arraysize(kJSTypes); i++) {
+ Node* orig = R.Unop(opnot, R.Parameter(kJSTypes[i]));
+ Node* use = R.graph.NewNode(R.common.Return(), orig);
+ Node* r = R.reduce(orig);
// TODO(titzer): test will break if/when js-typed-lowering constant folds.
- CHECK_EQ(IrOpcode::kBooleanNot, r->opcode());
+ CHECK_EQ(IrOpcode::kBooleanNot, use->InputAt(0)->opcode());
+
+ if (r == orig && orig->opcode() == IrOpcode::kJSToBoolean) {
+ // The original node was turned into a ToBoolean.
+ CHECK_EQ(IrOpcode::kJSToBoolean, r->opcode());
+ } else {
+ CHECK_EQ(IrOpcode::kBooleanNot, r->opcode());
+ }
}
}
TEST(RemoveToNumberEffects) {
+ FLAG_turbo_deoptimization = true;
+
JSTypedLoweringTester R;
Node* effect_use = NULL;
for (int i = 0; i < 10; i++) {
Node* p0 = R.Parameter(Type::Number());
Node* ton = R.Unop(R.javascript.ToNumber(), p0);
+ Node* frame_state = R.EmptyFrameState(R.context());
effect_use = NULL;
switch (i) {
effect_use = R.graph.NewNode(R.common.EffectPhi(1), ton, R.start());
case 3:
effect_use = R.graph.NewNode(R.javascript.Add(), ton, ton, R.context(),
- ton, R.start());
+ frame_state, ton, R.start());
break;
case 4:
effect_use = R.graph.NewNode(R.javascript.Add(), p0, p0, R.context(),
- ton, R.start());
+ frame_state, ton, R.start());
break;
case 5:
effect_use = R.graph.NewNode(R.common.Return(), p0, ton, R.start());
// Helper class for testing the reduction of a single binop.
class BinopEffectsTester {
public:
- explicit BinopEffectsTester(Operator* op, Type* t0, Type* t1)
+ explicit BinopEffectsTester(const Operator* op, Type* t0, Type* t1)
: R(),
p0(R.Parameter(t0, 0)),
p1(R.Parameter(t1, 1)),
Type::Number()};
- for (size_t i = 0; i < ARRAY_SIZE(simple_number_types); ++i) {
+ for (size_t i = 0; i < arraysize(simple_number_types); ++i) {
Node* p0 = R.Parameter(simple_number_types[i], 0);
- for (size_t j = 0; j < ARRAY_SIZE(simple_number_types); ++j) {
+ for (size_t j = 0; j < arraysize(simple_number_types); ++j) {
Node* p1 = R.Parameter(simple_number_types[j], 1);
CheckEqualityReduction(&R, true, p0, p1, IrOpcode::kNumberEqual);
Type::Object(), Type::Receiver()};
Node* p0 = R.Parameter(Type::Any());
- for (size_t i = 0; i < ARRAY_SIZE(types); i++) {
+ for (size_t i = 0; i < arraysize(types); i++) {
Node* p1 = R.Parameter(types[i]);
CheckEqualityReduction(&R, true, p0, p1, IrOpcode::kReferenceEqual);
}
TEST(RemovePureNumberBinopEffects) {
JSTypedLoweringTester R;
- Operator* ops[] = {
+ const Operator* ops[] = {
R.javascript.Equal(), R.simplified.NumberEqual(),
R.javascript.Add(), R.simplified.NumberAdd(),
R.javascript.Subtract(), R.simplified.NumberSubtract(),
R.javascript.LessThanOrEqual(), R.simplified.NumberLessThanOrEqual(),
};
- for (size_t j = 0; j < ARRAY_SIZE(ops); j += 2) {
+ for (size_t j = 0; j < arraysize(ops); j += 2) {
BinopEffectsTester B(ops[j], Type::Number(), Type::Number());
CHECK_EQ(ops[j + 1]->opcode(), B.result->op()->opcode());
TEST(OrderNumberBinopEffects1) {
JSTypedLoweringTester R;
- Operator* ops[] = {
+ const Operator* ops[] = {
R.javascript.Subtract(), R.simplified.NumberSubtract(),
R.javascript.Multiply(), R.simplified.NumberMultiply(),
R.javascript.Divide(), R.simplified.NumberDivide(),
R.javascript.Modulus(), R.simplified.NumberModulus(),
};
- for (size_t j = 0; j < ARRAY_SIZE(ops); j += 2) {
+ for (size_t j = 0; j < arraysize(ops); j += 2) {
BinopEffectsTester B(ops[j], Type::Object(), Type::String());
CHECK_EQ(ops[j + 1]->opcode(), B.result->op()->opcode());
TEST(OrderNumberBinopEffects2) {
JSTypedLoweringTester R;
- Operator* ops[] = {
+ const Operator* ops[] = {
R.javascript.Add(), R.simplified.NumberAdd(),
R.javascript.Subtract(), R.simplified.NumberSubtract(),
R.javascript.Multiply(), R.simplified.NumberMultiply(),
R.javascript.Modulus(), R.simplified.NumberModulus(),
};
- for (size_t j = 0; j < ARRAY_SIZE(ops); j += 2) {
- BinopEffectsTester B(ops[j], Type::Number(), Type::Object());
+ for (size_t j = 0; j < arraysize(ops); j += 2) {
+ BinopEffectsTester B(ops[j], Type::Number(), Type::Symbol());
Node* i0 = B.CheckNoOp(0);
Node* i1 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 1, true);
B.CheckEffectOrdering(i1);
}
- for (size_t j = 0; j < ARRAY_SIZE(ops); j += 2) {
- BinopEffectsTester B(ops[j], Type::Object(), Type::Number());
+ for (size_t j = 0; j < arraysize(ops); j += 2) {
+ BinopEffectsTester B(ops[j], Type::Symbol(), Type::Number());
Node* i0 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 0, true);
Node* i1 = B.CheckNoOp(1);
TEST(OrderCompareEffects) {
JSTypedLoweringTester R;
- Operator* ops[] = {
+ const Operator* ops[] = {
R.javascript.GreaterThan(), R.simplified.NumberLessThan(),
R.javascript.GreaterThanOrEqual(), R.simplified.NumberLessThanOrEqual(),
};
- for (size_t j = 0; j < ARRAY_SIZE(ops); j += 2) {
- BinopEffectsTester B(ops[j], Type::Object(), Type::String());
+ for (size_t j = 0; j < arraysize(ops); j += 2) {
+ BinopEffectsTester B(ops[j], Type::Symbol(), Type::String());
CHECK_EQ(ops[j + 1]->opcode(), B.result->op()->opcode());
Node* i0 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 0, true);
B.CheckEffectOrdering(i1, i0);
}
- for (size_t j = 0; j < ARRAY_SIZE(ops); j += 2) {
- BinopEffectsTester B(ops[j], Type::Number(), Type::Object());
+ for (size_t j = 0; j < arraysize(ops); j += 2) {
+ BinopEffectsTester B(ops[j], Type::Number(), Type::Symbol());
Node* i0 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 0, true);
Node* i1 = B.result->InputAt(1);
B.CheckEffectOrdering(i0);
}
- for (size_t j = 0; j < ARRAY_SIZE(ops); j += 2) {
- BinopEffectsTester B(ops[j], Type::Object(), Type::Number());
+ for (size_t j = 0; j < arraysize(ops); j += 2) {
+ BinopEffectsTester B(ops[j], Type::Symbol(), Type::Number());
Node* i0 = B.result->InputAt(0);
Node* i1 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 1, true);
TEST(UnaryNotEffects) {
JSTypedLoweringTester R;
- Operator* opnot = R.javascript.UnaryNot();
+ const Operator* opnot = R.javascript.UnaryNot();
- for (size_t i = 0; i < ARRAY_SIZE(kJSTypes); i++) {
+ for (size_t i = 0; i < arraysize(kJSTypes); i++) {
Node* p0 = R.Parameter(kJSTypes[i], 0);
Node* orig = R.Unop(opnot, p0);
Node* effect_use = R.UseForEffect(orig);
Node* value_use = R.graph.NewNode(R.common.Return(), orig);
Node* r = R.reduce(orig);
// TODO(titzer): test will break if/when js-typed-lowering constant folds.
- CHECK_EQ(IrOpcode::kBooleanNot, r->opcode());
-
- CHECK_EQ(r, value_use->InputAt(0));
+ CHECK_EQ(IrOpcode::kBooleanNot, value_use->InputAt(0)->opcode());
- if (r->InputAt(0) == orig && orig->opcode() == IrOpcode::kJSToBoolean) {
+ if (r == orig && orig->opcode() == IrOpcode::kJSToBoolean) {
// The original node was turned into a ToBoolean, which has an effect.
+ CHECK_EQ(IrOpcode::kJSToBoolean, r->opcode());
R.CheckEffectInput(R.start(), orig);
R.CheckEffectInput(orig, effect_use);
} else {
// effect should have been removed from this node.
+ CHECK_EQ(IrOpcode::kBooleanNot, r->opcode());
R.CheckEffectInput(R.start(), effect_use);
}
}
JSBitwiseTypedLoweringTester R;
for (int o = 0; o < R.kNumberOps; o += 2) {
- for (size_t i = 0; i < ARRAY_SIZE(kInt32Types); i++) {
+ for (size_t i = 0; i < arraysize(kInt32Types); i++) {
Node* n0 = R.Parameter(kInt32Types[i]);
- for (size_t j = 0; j < ARRAY_SIZE(kInt32Types); j++) {
+ for (size_t j = 0; j < arraysize(kInt32Types); j++) {
Node* n1 = R.Parameter(kInt32Types[j]);
Node* one = R.graph.NewNode(R.common.NumberConstant(1));
JSBitwiseShiftTypedLoweringTester R;
for (int o = 0; o < R.kNumberOps; o += 2) {
- for (size_t i = 0; i < ARRAY_SIZE(kInt32Types); i++) {
+ for (size_t i = 0; i < arraysize(kInt32Types); i++) {
Node* n0 = R.Parameter(kInt32Types[i]);
- for (size_t j = 0; j < ARRAY_SIZE(kInt32Types); j++) {
+ for (size_t j = 0; j < arraysize(kInt32Types); j++) {
Node* n1 = R.Parameter(kInt32Types[j]);
Node* one = R.graph.NewNode(R.common.NumberConstant(1));
JSTypedLoweringTester R;
struct Entry {
- Operator* js_op;
- Operator* uint_op;
- Operator* int_op;
- Operator* num_op;
+ const Operator* js_op;
+ const Operator* uint_op;
+ const Operator* int_op;
+ const Operator* num_op;
bool commute;
};
R.machine.Int32LessThanOrEqual(), R.simplified.NumberLessThanOrEqual(),
true}};
- for (size_t o = 0; o < ARRAY_SIZE(ops); o++) {
- for (size_t i = 0; i < ARRAY_SIZE(kNumberTypes); i++) {
+ for (size_t o = 0; o < arraysize(ops); o++) {
+ for (size_t i = 0; i < arraysize(kNumberTypes); i++) {
Type* t0 = kNumberTypes[i];
Node* p0 = R.Parameter(t0, 0);
- for (size_t j = 0; j < ARRAY_SIZE(kNumberTypes); j++) {
+ for (size_t j = 0; j < arraysize(kNumberTypes); j++) {
Type* t1 = kNumberTypes[j];
Node* p1 = R.Parameter(t1, 1);
Node* cmp = R.Binop(ops[o].js_op, p0, p1);
Node* r = R.reduce(cmp);
- Operator* expected;
+ const Operator* expected;
if (t0->Is(Type::Unsigned32()) && t1->Is(Type::Unsigned32())) {
expected = ops[o].uint_op;
} else if (t0->Is(Type::Signed32()) && t1->Is(Type::Signed32())) {