Node* control = graph()->start();
switch (node->opcode()) {
case IrOpcode::kChangeBitToBool:
- return ChangeBitToBool(node->InputAt(0));
+ return ChangeBitToBool(node->InputAt(0), control);
case IrOpcode::kChangeBoolToBit:
return ChangeBoolToBit(node->InputAt(0));
- case IrOpcode::kChangeWord32ToBit:
- return ChangeWord32ToBit(node->InputAt(0));
- case IrOpcode::kChangeWord64ToBit:
- return ChangeWord64ToBit(node->InputAt(0));
case IrOpcode::kChangeFloat64ToTagged:
return ChangeFloat64ToTagged(node->InputAt(0), control);
case IrOpcode::kChangeInt32ToTagged:
}
-Reduction ChangeLowering::ChangeBitToBool(Node* value) {
+Reduction ChangeLowering::ChangeBitToBool(Node* val, Node* control) {
MachineType const type = static_cast<MachineType>(kTypeBool | kRepTagged);
- return Replace(graph()->NewNode(common()->Select(type), value,
+ return Replace(graph()->NewNode(common()->Select(type), val,
jsgraph()->TrueConstant(),
jsgraph()->FalseConstant()));
}
-Reduction ChangeLowering::ChangeBoolToBit(Node* value) {
- return Replace(graph()->NewNode(machine()->WordEqual(), value,
- jsgraph()->TrueConstant()));
-}
-
-
-Reduction ChangeLowering::ChangeWord32ToBit(Node* value) {
- return Replace(
- graph()->NewNode(machine()->Word32Equal(),
- graph()->NewNode(machine()->Word32Equal(), value,
- jsgraph()->Int32Constant(0)),
- jsgraph()->Int32Constant(0)));
-}
-
-
-Reduction ChangeLowering::ChangeWord64ToBit(Node* value) {
+Reduction ChangeLowering::ChangeBoolToBit(Node* val) {
return Replace(
- graph()->NewNode(machine()->Word32Equal(),
- graph()->NewNode(machine()->Word64Equal(), value,
- jsgraph()->Int64Constant(0)),
- jsgraph()->Int32Constant(0)));
+ graph()->NewNode(machine()->WordEqual(), val, jsgraph()->TrueConstant()));
}
class Linkage;
class MachineOperatorBuilder;
-
class ChangeLowering FINAL : public Reducer {
public:
ChangeLowering(JSGraph* jsgraph, Linkage* linkage)
Node* TestNotSmi(Node* value);
Node* Uint32LessThanOrEqual(Node* lhs, Node* rhs);
- Reduction ChangeBitToBool(Node* value);
+ Reduction ChangeBitToBool(Node* value, Node* control);
Reduction ChangeBoolToBit(Node* value);
- Reduction ChangeWord32ToBit(Node* value);
- Reduction ChangeWord64ToBit(Node* value);
Reduction ChangeFloat64ToTagged(Node* value, Node* control);
Reduction ChangeInt32ToTagged(Node* value, Node* control);
Reduction ChangeTaggedToFloat64(Node* value, Node* control);
}
-Type* JSGraph::ZeroOneRangeType() {
- if (!zero_one_range_type_.is_set()) {
- zero_one_range_type_.set(
- Type::Range(factory()->NewNumber(0), factory()->NewNumber(1), zone()));
- }
- return zero_one_range_type_.get();
-}
-
-
void JSGraph::GetCachedNodes(NodeVector* nodes) {
cache_.GetCachedNodes(nodes);
SetOncePointer<Node>* ptrs[] = {
namespace internal {
namespace compiler {
-// Forward declarations.
class Typer;
// Implements a facade on a Graph, enhancing the graph with JS-specific
// stubs and runtime functions that do not require a context.
Node* NoContextConstant() { return ZeroConstant(); }
- // Cached common types.
- Type* ZeroOneRangeType();
-
JSOperatorBuilder* javascript() { return javascript_; }
CommonOperatorBuilder* common() { return common_; }
MachineOperatorBuilder* machine() { return machine_; }
SetOncePointer<Node> one_constant_;
SetOncePointer<Node> nan_constant_;
- SetOncePointer<Type> zero_one_range_type_;
-
CommonNodeCache cache_;
Node* ImmovableHeapConstant(Handle<HeapObject> value);
JS_CONTEXT_OP_LIST(V) \
JS_OTHER_OP_LIST(V)
-// Opcodes for VirtualMachine-level operators.
+// Opcodes for VirtuaMachine-level operators.
#define SIMPLIFIED_OP_LIST(V) \
V(AnyToBoolean) \
V(BooleanNot) \
V(ChangeUint32ToTagged) \
V(ChangeFloat64ToTagged) \
V(ChangeBoolToBit) \
- V(ChangeWord32ToBit) \
- V(ChangeWord64ToBit) \
V(ChangeBitToBool) \
V(LoadField) \
V(LoadBuffer) \
: jsgraph_(jsgraph),
simplified_(simplified),
isolate_(isolate),
- bit_range_(Type::Range(isolate->factory()->NewNumber(0),
- isolate->factory()->NewNumber(1),
- jsgraph->zone())),
testing_type_errors_(false),
type_error_(false) {}
// Select the correct X -> Word32 operator.
const Operator* op;
if (output_type & kRepBit) {
- return node; // No change necessary.
+ return node; // Sloppy comparison -> word32
} else if (output_type & kRepFloat64) {
if (output_type & kTypeUint32 || use_unsigned) {
op = machine()->ChangeFloat64ToUint32();
Node* GetBitRepresentationFor(Node* node, MachineTypeUnion output_type) {
// Eagerly fold representation changes for constants.
switch (node->opcode()) {
- case IrOpcode::kInt32Constant: {
- int32_t value = OpParameter<int32_t>(node);
- if (value == 0 || value == 1) return node;
- return jsgraph()->Int32Constant(1); // value != 0
- }
- case IrOpcode::kNumberConstant: {
- double value = OpParameter<double>(node);
- if (value == 0 || std::isnan(value)) return jsgraph()->Int32Constant(0);
- return jsgraph()->Int32Constant(1); // value != +0.0, -0.0, NaN
- }
case IrOpcode::kHeapConstant: {
- Handle<Object> object = OpParameter<Unique<Object>>(node).handle();
- return jsgraph()->Int32Constant(object->BooleanValue() ? 1 : 0);
+ Handle<Object> value = OpParameter<Unique<Object> >(node).handle();
+ DCHECK(value.is_identical_to(factory()->true_value()) ||
+ value.is_identical_to(factory()->false_value()));
+ return jsgraph()->Int32Constant(
+ value.is_identical_to(factory()->true_value()) ? 1 : 0);
}
default:
break;
}
// Select the correct X -> Bit operator.
const Operator* op;
- if (output_type & rWord) {
- op = simplified()->ChangeWord32ToBit();
- } else if (output_type & kRepWord64) {
- op = simplified()->ChangeWord64ToBit();
- } else if (output_type & kRepTagged) {
- Type* upper = NodeProperties::GetBounds(node).upper;
- if (upper->Is(Type::Boolean())) {
- op = simplified()->ChangeBoolToBit();
- } else if (upper->Is(Type::Signed32())) {
- // Tagged -> Int32 -> Bit
- node = InsertChangeTaggedToInt32(node);
- op = simplified()->ChangeWord32ToBit();
- } else if (upper->Is(Type::Unsigned32())) {
- // Tagged -> Uint32 -> Bit
- node = InsertChangeTaggedToUint32(node);
- op = simplified()->ChangeWord32ToBit();
- } else {
- return TypeError(node, output_type, kRepBit);
- }
+ if (output_type & kRepTagged) {
+ op = simplified()->ChangeBoolToBit();
} else {
return TypeError(node, output_type, kRepBit);
}
- return graph()->NewNode(op, node);
+ return jsgraph()->graph()->NewNode(op, node);
}
Node* GetWord64RepresentationFor(Node* node, MachineTypeUnion output_type) {
JSGraph* jsgraph_;
SimplifiedOperatorBuilder* simplified_;
Isolate* isolate_;
- Type* bit_range_;
friend class RepresentationChangerTester; // accesses the below fields.
}
Node* InsertChangeFloat32ToFloat64(Node* node) {
- return graph()->NewNode(machine()->ChangeFloat32ToFloat64(), node);
+ return jsgraph()->graph()->NewNode(machine()->ChangeFloat32ToFloat64(),
+ node);
}
Node* InsertChangeTaggedToFloat64(Node* node) {
- return graph()->NewNode(simplified()->ChangeTaggedToFloat64(), node);
- }
-
- Node* InsertChangeTaggedToInt32(Node* node) {
- return graph()->NewNode(simplified()->ChangeTaggedToInt32(), node);
- }
-
- Node* InsertChangeTaggedToUint32(Node* node) {
- return graph()->NewNode(simplified()->ChangeTaggedToUint32(), node);
+ return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedToFloat64(),
+ node);
}
- Graph* graph() const { return jsgraph()->graph(); }
JSGraph* jsgraph() const { return jsgraph_; }
Isolate* isolate() const { return isolate_; }
- SimplifiedOperatorBuilder* simplified() const { return simplified_; }
- MachineOperatorBuilder* machine() const { return jsgraph()->machine(); }
+ Factory* factory() const { return isolate()->factory(); }
+ SimplifiedOperatorBuilder* simplified() { return simplified_; }
+ MachineOperatorBuilder* machine() { return jsgraph()->machine(); }
};
} // namespace compiler
memset(info_, 0, sizeof(NodeInfo) * count_);
Factory* f = zone->isolate()->factory();
- safe_bit_range_ =
- Type::Union(Type::Boolean(),
- Type::Range(f->NewNumber(0), f->NewNumber(1), zone), zone);
safe_int_additive_range_ =
Type::Range(f->NewNumber(-std::pow(2.0, 52.0)),
f->NewNumber(std::pow(2.0, 52.0)), zone);
} else {
return kRepFloat64;
}
- } else if (IsSafeBitOperand(node)) {
+ } else if (upper->Is(Type::Boolean())) {
// multiple uses => pick kRepBit.
return kRepBit;
} else if (upper->Is(Type::Number())) {
return BothInputsAre(node, Type::Signed32()) && !CanObserveNonInt32(use);
}
- bool IsSafeBitOperand(Node* node) {
- Type* type = NodeProperties::GetBounds(node).upper;
- return type->Is(safe_bit_range_);
- }
-
bool IsSafeIntAdditiveOperand(Node* node) {
Type* type = NodeProperties::GetBounds(node).upper;
// TODO(jarin): Unfortunately, bitset types are not subtypes of larger
// Simplified operators.
//------------------------------------------------------------------
case IrOpcode::kAnyToBoolean: {
- if (IsSafeBitOperand(node->InputAt(0))) {
- VisitUnop(node, kRepBit, kRepBit);
- if (lower()) DeferReplacement(node, node->InputAt(0));
- } else {
- VisitUnop(node, kMachAnyTagged, kTypeBool | kRepTagged);
- if (lower()) {
- // AnyToBoolean(x) => Call(ToBooleanStub, x, no-context)
- Operator::Properties properties = node->op()->properties();
- Callable callable = CodeFactory::ToBoolean(
- jsgraph_->isolate(), ToBooleanStub::RESULT_AS_ODDBALL);
- CallDescriptor::Flags flags = CallDescriptor::kPatchableCallSite;
- CallDescriptor* desc = Linkage::GetStubCallDescriptor(
- callable.descriptor(), 0, flags, properties, jsgraph_->zone());
- node->set_op(jsgraph_->common()->Call(desc));
- node->InsertInput(jsgraph_->zone(), 0,
- jsgraph_->HeapConstant(callable.code()));
- node->AppendInput(jsgraph_->zone(), jsgraph_->NoContextConstant());
- }
+ VisitUnop(node, kMachAnyTagged, kTypeBool | kRepTagged);
+ if (lower()) {
+ // AnyToBoolean(x) => Call(ToBooleanStub, x, no-context)
+ Operator::Properties properties = node->op()->properties();
+ Callable callable = CodeFactory::ToBoolean(
+ jsgraph_->isolate(), ToBooleanStub::RESULT_AS_ODDBALL);
+ CallDescriptor::Flags flags = CallDescriptor::kPatchableCallSite;
+ CallDescriptor* desc = Linkage::GetStubCallDescriptor(
+ callable.descriptor(), 0, flags, properties, jsgraph_->zone());
+ node->set_op(jsgraph_->common()->Call(desc));
+ node->InsertInput(jsgraph_->zone(), 0,
+ jsgraph_->HeapConstant(callable.code()));
+ node->AppendInput(jsgraph_->zone(), jsgraph_->NoContextConstant());
}
break;
}
Phase phase_; // current phase of algorithm
RepresentationChanger* changer_; // for inserting representation changes
ZoneQueue<Node*> queue_; // queue for traversing the graph
- Type* safe_bit_range_;
Type* safe_int_additive_range_;
NodeInfo* GetInfo(Node* node) {
if (m.IsChangeBitToBool()) return Replace(m.node()->InputAt(0));
break;
}
- case IrOpcode::kChangeWord32ToBit:
- return ReduceChangeWord32ToBit(node);
case IrOpcode::kChangeFloat64ToTagged: {
Float64Matcher m(node->InputAt(0));
if (m.HasValue()) return ReplaceNumber(m.Value());
}
-Reduction SimplifiedOperatorReducer::ReduceChangeWord32ToBit(Node* node) {
- Node* const input = NodeProperties::GetValueInput(node, 0);
- Type* const input_type = NodeProperties::GetBounds(input).upper;
- if (input_type->Is(jsgraph()->ZeroOneRangeType())) {
- // ChangeWord32ToBit(x:bit) => x
- return Replace(input);
- }
- return NoChange();
-}
-
-
Reduction SimplifiedOperatorReducer::Change(Node* node, const Operator* op,
Node* a) {
DCHECK_EQ(node->InputCount(), OperatorProperties::GetTotalInputCount(op));
// Forward declarations.
class Factory;
+class Heap;
namespace compiler {
private:
Reduction ReduceAnyToBoolean(Node* node);
- Reduction ReduceChangeWord32ToBit(Node* node);
Reduction Change(Node* node, const Operator* op, Node* a);
Reduction ReplaceFloat64(double value);
V(ChangeInt32ToTagged, Operator::kNoProperties, 1) \
V(ChangeUint32ToTagged, Operator::kNoProperties, 1) \
V(ChangeFloat64ToTagged, Operator::kNoProperties, 1) \
- V(ChangeBitToBool, Operator::kNoProperties, 1) \
V(ChangeBoolToBit, Operator::kNoProperties, 1) \
- V(ChangeWord32ToBit, Operator::kNoProperties, 1) \
- V(ChangeWord64ToBit, Operator::kNoProperties, 1) \
+ V(ChangeBitToBool, Operator::kNoProperties, 1) \
V(ObjectIsSmi, Operator::kNoProperties, 1) \
V(ObjectIsNonNegativeSmi, Operator::kNoProperties, 1)
const Operator* ChangeInt32ToTagged();
const Operator* ChangeUint32ToTagged();
const Operator* ChangeFloat64ToTagged();
- const Operator* ChangeBitToBool();
const Operator* ChangeBoolToBit();
- const Operator* ChangeWord32ToBit();
- const Operator* ChangeWord64ToBit();
+ const Operator* ChangeBitToBool();
const Operator* ObjectIsSmi();
const Operator* ObjectIsNonNegativeSmi();
}
-Bounds Typer::Visitor::TypeChangeBitToBool(Node* node) {
- Bounds arg = Operand(node, 0);
- // TODO(neis): DCHECK(arg.upper->Is(Type::Boolean()));
- return Bounds(ChangeRepresentation(arg.lower, Type::TaggedPointer(), zone()),
- ChangeRepresentation(arg.upper, Type::TaggedPointer(), zone()));
-}
-
-
Bounds Typer::Visitor::TypeChangeBoolToBit(Node* node) {
Bounds arg = Operand(node, 0);
// TODO(neis): DCHECK(arg.upper->Is(Type::Boolean()));
}
-Bounds Typer::Visitor::TypeChangeWord32ToBit(Node* node) {
- return Bounds(
- ChangeRepresentation(Type::Boolean(), Type::UntaggedBit(), zone()));
-}
-
-
-Bounds Typer::Visitor::TypeChangeWord64ToBit(Node* node) {
- return Bounds(
- ChangeRepresentation(Type::Boolean(), Type::UntaggedBit(), zone()));
+Bounds Typer::Visitor::TypeChangeBitToBool(Node* node) {
+ Bounds arg = Operand(node, 0);
+ // TODO(neis): DCHECK(arg.upper->Is(Type::Boolean()));
+ return Bounds(ChangeRepresentation(arg.lower, Type::TaggedPointer(), zone()),
+ ChangeRepresentation(arg.upper, Type::TaggedPointer(), zone()));
}
// CheckUpperIs(node, to));
break;
}
- case IrOpcode::kChangeBitToBool: {
- // Boolean /\ UntaggedInt1 -> Boolean /\ TaggedPtr
- // TODO(neis): Activate once ChangeRepresentation works in typer.
- // Type* from = Type::Intersect(Type::Boolean(), Type::UntaggedInt1());
- // Type* to = Type::Intersect(Type::Boolean(), Type::TaggedPtr());
- // CheckValueInputIs(node, 0, from));
- // CheckUpperIs(node, to));
- break;
- }
case IrOpcode::kChangeBoolToBit: {
// Boolean /\ TaggedPtr -> Boolean /\ UntaggedInt1
// TODO(neis): Activate once ChangeRepresentation works in typer.
// CheckUpperIs(node, to));
break;
}
- case IrOpcode::kChangeWord32ToBit: {
- // TODO(rossberg): Check.
- CheckValueInputIs(node, 0, Type::Integral32());
- break;
- }
- case IrOpcode::kChangeWord64ToBit: {
- // TODO(rossberg): Check.
+ case IrOpcode::kChangeBitToBool: {
+ // Boolean /\ UntaggedInt1 -> Boolean /\ TaggedPtr
+ // TODO(neis): Activate once ChangeRepresentation works in typer.
+ // Type* from = Type::Intersect(Type::Boolean(), Type::UntaggedInt1());
+ // Type* to = Type::Intersect(Type::Boolean(), Type::TaggedPtr());
+ // CheckValueInputIs(node, 0, from));
+ // CheckUpperIs(node, to));
break;
}
CHECK_EQ(expected, m.Value());
}
- Node* Parameter(Type* type, int index = 0) {
- Node* node = graph()->NewNode(common()->Parameter(index), graph()->start());
- NodeProperties::SetBounds(node, Bounds(type));
- return node;
+ Node* Parameter(int index = 0) {
+ return graph()->NewNode(common()->Parameter(index), graph()->start());
}
- Node* Parameter(int index = 0) { return Parameter(Type::Any(), index); }
-
void CheckTypeError(MachineTypeUnion from, MachineTypeUnion to) {
changer()->testing_type_errors_ = true;
changer()->type_error_ = false;
CHECK_EQ(n, c);
}
};
-
-} // namespace compiler
-} // namespace internal
-} // namespace v8
+}
+}
+} // namespace v8::internal::compiler
static const MachineType all_reps[] = {kRepBit, kRepWord32, kRepWord64,
kRepFloat32, kRepFloat64, kRepTagged};
-TEST(ToBit_constant) {
+TEST(BoolToBit_constant) {
RepresentationChangerTester r;
Node* true_node = r.jsgraph()->TrueConstant();
Node* false_bit =
r.changer()->GetRepresentationFor(false_node, kRepTagged, kRepBit);
r.CheckInt32Constant(false_bit, 0);
-
- {
- FOR_FLOAT64_INPUTS(i) {
- Node* node = r.jsgraph()->Constant(*i);
- Node* bit = r.changer()->GetRepresentationFor(node, kRepTagged, kRepBit);
- r.CheckInt32Constant(bit, DoubleToBoolean(*i) ? 1 : 0);
- }
- }
-
- {
- FOR_INT32_INPUTS(i) {
- Node* node = r.jsgraph()->Int32Constant(*i);
- Node* bit = r.changer()->GetRepresentationFor(node, kRepWord32, kRepBit);
- r.CheckInt32Constant(bit, *i == 0 ? 0 : 1);
- }
- }
}
static void CheckChange(IrOpcode::Value expected, MachineTypeUnion from,
- MachineTypeUnion to, Type* from_type = Type::Any()) {
+ MachineTypeUnion to) {
RepresentationChangerTester r;
- Node* n = r.Parameter(from_type);
+ Node* n = r.Parameter();
Node* c = r.changer()->GetRepresentationFor(n, from, to);
CHECK_NE(c, n);
static void CheckTwoChanges(IrOpcode::Value expected2,
IrOpcode::Value expected1, MachineTypeUnion from,
- MachineTypeUnion to,
- Type* from_type = Type::Any()) {
+ MachineTypeUnion to) {
RepresentationChangerTester r;
- Node* n = r.Parameter(from_type);
+ Node* n = r.Parameter();
Node* c1 = r.changer()->GetRepresentationFor(n, from, to);
CHECK_NE(c1, n);
TEST(SingleChanges) {
- CheckChange(IrOpcode::kChangeBoolToBit, kRepTagged, kRepBit, Type::Boolean());
- CheckTwoChanges(IrOpcode::kChangeTaggedToInt32, IrOpcode::kChangeWord32ToBit,
- kRepTagged, kRepBit, Type::Signed32());
- CheckTwoChanges(IrOpcode::kChangeTaggedToUint32, IrOpcode::kChangeWord32ToBit,
- kRepTagged, kRepBit, Type::Unsigned32());
- CheckChange(IrOpcode::kChangeWord32ToBit, kRepWord8, kRepBit);
- CheckChange(IrOpcode::kChangeWord32ToBit, kRepWord16, kRepBit);
- CheckChange(IrOpcode::kChangeWord32ToBit, kRepWord32, kRepBit);
- CheckChange(IrOpcode::kChangeWord64ToBit, kRepWord64, kRepBit);
+ CheckChange(IrOpcode::kChangeBoolToBit, kRepTagged, kRepBit);
CheckChange(IrOpcode::kChangeBitToBool, kRepBit, kRepTagged);
CheckChange(IrOpcode::kChangeInt32ToTagged, kRepWord32 | kTypeInt32,
TEST(TypeErrors) {
RepresentationChangerTester r;
+ // Wordish cannot be implicitly converted to/from comparison conditions.
+ r.CheckTypeError(kRepWord8, kRepBit);
+ r.CheckTypeError(kRepWord8, kRepBit | kTypeBool);
+ r.CheckTypeError(kRepWord16, kRepBit);
+ r.CheckTypeError(kRepWord16, kRepBit | kTypeBool);
+ r.CheckTypeError(kRepWord32, kRepBit);
+ r.CheckTypeError(kRepWord32, kRepBit | kTypeBool);
+ r.CheckTypeError(kRepWord64, kRepBit);
+ r.CheckTypeError(kRepWord64, kRepBit | kTypeBool);
+
// Floats cannot be implicitly converted to/from comparison conditions.
r.CheckTypeError(kRepFloat64, kRepBit);
r.CheckTypeError(kRepFloat64, kRepBit | kTypeBool);
};
-TEST(LowerAnyToBoolean_bit_bit) {
- // AnyToBoolean(x: kRepBit) used as kRepBit
- HandleAndZoneScope scope;
- Factory* f = scope.main_zone()->isolate()->factory();
- Handle<Object> zero = f->NewNumber(0);
- Handle<Object> one = f->NewNumber(1);
- Type* singleton_zero = Type::Constant(zero, scope.main_zone());
- Type* singleton_one = Type::Constant(one, scope.main_zone());
- Type* zero_one_range = Type::Range(zero, one, scope.main_zone());
- static Type* kTypes[] = {
- singleton_zero, singleton_one, zero_one_range, Type::Boolean(),
- Type::Union(Type::Boolean(), singleton_zero, scope.main_zone()),
- Type::Union(Type::Boolean(), singleton_one, scope.main_zone()),
- Type::Union(Type::Boolean(), zero_one_range, scope.main_zone())};
- for (Type* type : kTypes) {
- TestingGraph t(type);
- Node* x = t.ExampleWithTypeAndRep(type, kRepBit);
- Node* cnv = t.graph()->NewNode(t.simplified()->AnyToBoolean(), x);
- Node* use = t.Branch(cnv);
- t.Lower();
- CHECK_EQ(x, use->InputAt(0));
- }
-}
-
-
#if V8_TURBOFAN_TARGET
TEST(LowerAnyToBoolean_tagged_tagged) {
--- /dev/null
+// Copyright 2015 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.
+
+var stdlib = this;
+var buffer = new ArrayBuffer(64 * 1024);
+var foreign = {}
+
+var foo = (function Module(stdlib, foreign, heap) {
+ "use asm";
+ function foo(i) {
+ var x = i ? (i&1) : true;
+ if (x) return x;
+ return false;
+ }
+ return {foo:foo};
+})(stdlib, foreign, buffer).foo;
+
+assertEquals(1, foo(1));
})(stdlib, foreign, buffer).foo;
assertFalse(foo(1));
-assertTrue(foo(0));
Node* node = graph()->NewNode(simplified()->ChangeBoolToBit(), val);
Reduction reduction = Reduce(node);
ASSERT_TRUE(reduction.Changed());
- EXPECT_THAT(reduction.replacement(), IsWordEqual(val, IsTrueConstant()));
-}
-
-TARGET_TEST_P(ChangeLoweringCommonTest, ChangeWord32ToBit) {
- Node* val = Parameter(0);
- Node* node = graph()->NewNode(simplified()->ChangeWord32ToBit(), val);
- Reduction reduction = Reduce(node);
- ASSERT_TRUE(reduction.Changed());
- EXPECT_THAT(reduction.replacement(),
- IsWord32Equal(IsWord32Equal(val, IsInt32Constant(0)),
- IsInt32Constant(0)));
-}
-
-
-TARGET_TEST_P(ChangeLoweringCommonTest, ChangeWord64ToBit) {
- Node* val = Parameter(0);
- Node* node = graph()->NewNode(simplified()->ChangeWord64ToBit(), val);
- Reduction reduction = Reduce(node);
- ASSERT_TRUE(reduction.Changed());
- EXPECT_THAT(reduction.replacement(),
- IsWord32Equal(IsWord64Equal(val, IsInt64Constant(0)),
- IsInt32Constant(0)));
+ EXPECT_THAT(reduction.replacement(), IsWordEqual(val, IsTrueConstant()));
}
// -----------------------------------------------------------------------------
-// Unary operators
-
-
-namespace {
-
-struct UnaryOperator {
- const Operator* (SimplifiedOperatorBuilder::*constructor)();
- const char* constructor_name;
-};
-
-
-std::ostream& operator<<(std::ostream& os, const UnaryOperator& unop) {
- return os << unop.constructor_name;
-}
-
-
-static const UnaryOperator kUnaryOperators[] = {
- {&SimplifiedOperatorBuilder::AnyToBoolean, "AnyToBoolean"},
- {&SimplifiedOperatorBuilder::BooleanNot, "BooleanNot"},
- {&SimplifiedOperatorBuilder::ChangeBitToBool, "ChangeBitToBool"},
- {&SimplifiedOperatorBuilder::ChangeBoolToBit, "ChangeBoolToBit"},
- {&SimplifiedOperatorBuilder::ChangeFloat64ToTagged,
- "ChangeFloat64ToTagged"},
- {&SimplifiedOperatorBuilder::ChangeInt32ToTagged, "ChangeInt32ToTagged"},
- {&SimplifiedOperatorBuilder::ChangeTaggedToFloat64,
- "ChangeTaggedToFloat64"},
- {&SimplifiedOperatorBuilder::ChangeTaggedToInt32, "ChangeTaggedToInt32"},
- {&SimplifiedOperatorBuilder::ChangeTaggedToUint32, "ChangeTaggedToUint32"},
- {&SimplifiedOperatorBuilder::ChangeUint32ToTagged, "ChangeUint32ToTagged"}};
-
-} // namespace
-
-
-typedef SimplifiedOperatorReducerTestWithParam<UnaryOperator>
- SimplifiedUnaryOperatorTest;
-
-
-TEST_P(SimplifiedUnaryOperatorTest, Parameter) {
- const UnaryOperator& unop = GetParam();
- Reduction reduction = Reduce(graph()->NewNode(
- (simplified()->*unop.constructor)(), Parameter(Type::Any())));
- EXPECT_FALSE(reduction.Changed());
-}
-
-
-INSTANTIATE_TEST_CASE_P(SimplifiedOperatorReducerTest,
- SimplifiedUnaryOperatorTest,
- ::testing::ValuesIn(kUnaryOperators));
-
-
-// -----------------------------------------------------------------------------
// AnyToBoolean
// -----------------------------------------------------------------------------
-// ChangeWord32ToBit
-
-
-TEST_F(SimplifiedOperatorReducerTest, ChangeWord32ToBitWithBitType) {
- Handle<Object> zero = factory()->NewNumber(0);
- Handle<Object> one = factory()->NewNumber(1);
- Type* const kBitTypes[] = {
- Type::Constant(zero, zone()), Type::Constant(one, zone()),
- Type::Range(zero, zero, zone()), Type::Range(one, one, zone()),
- Type::Range(zero, one, zone())};
- TRACED_FOREACH(Type*, type, kBitTypes) {
- Node* param0 = Parameter(type, 0);
- Reduction reduction =
- Reduce(graph()->NewNode(simplified()->ChangeWord32ToBit(), param0));
- ASSERT_TRUE(reduction.Changed());
- EXPECT_EQ(param0, reduction.replacement());
- }
-}
-
-
-// -----------------------------------------------------------------------------
// ChangeFloat64ToTagged
PURE(ChangeUint32ToTagged, Operator::kNoProperties, 1),
PURE(ChangeFloat64ToTagged, Operator::kNoProperties, 1),
PURE(ChangeBoolToBit, Operator::kNoProperties, 1),
- PURE(ChangeWord32ToBit, Operator::kNoProperties, 1),
- PURE(ChangeWord64ToBit, Operator::kNoProperties, 1),
PURE(ChangeBitToBool, Operator::kNoProperties, 1),
PURE(ObjectIsSmi, Operator::kNoProperties, 1),
PURE(ObjectIsNonNegativeSmi, Operator::kNoProperties, 1)