Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(92)

Unified Diff: src/compiler/js-typed-lowering.cc

Issue 792463003: [turbofan] Turn JSToBoolean and JSUnaryNot into pure operators. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/compiler/js-typed-lowering.cc
diff --git a/src/compiler/js-typed-lowering.cc b/src/compiler/js-typed-lowering.cc
index 770ae7bf6a4740e092f8d3dc041980e7837ea160..9de549362166853612c6b458293d0b2f122f3236 100644
--- a/src/compiler/js-typed-lowering.cc
+++ b/src/compiler/js-typed-lowering.cc
@@ -141,7 +141,7 @@ class JSBinopReduction {
node_->ReplaceUses(value);
// Note: ReplaceUses() smashes all uses, so smash it back here.
value->ReplaceInput(0, node_);
- return lowering_->ReplaceWith(value);
+ return lowering_->Replace(value);
}
return lowering_->Changed(node_);
}
@@ -504,16 +504,15 @@ Reduction JSTypedLowering::ReduceJSToNumberInput(Node* input) {
}
if (input_type->Is(Type::Undefined())) {
// JSToNumber(undefined) => #NaN
- return ReplaceWith(jsgraph()->NaNConstant());
+ return Replace(jsgraph()->NaNConstant());
}
if (input_type->Is(Type::Null())) {
// JSToNumber(null) => #0
- return ReplaceWith(jsgraph()->ZeroConstant());
+ return Replace(jsgraph()->ZeroConstant());
}
if (input_type->Is(Type::Boolean())) {
// JSToNumber(x:boolean) => BooleanToNumber(x)
- return ReplaceWith(
- graph()->NewNode(simplified()->BooleanToNumber(), input));
+ return Replace(graph()->NewNode(simplified()->BooleanToNumber(), input));
}
// TODO(turbofan): js-typed-lowering of ToNumber(x:string)
return NoChange();
@@ -584,11 +583,11 @@ Reduction JSTypedLowering::ReduceJSToStringInput(Node* input) {
return Changed(input); // JSToString(x:string) => x
}
if (input_type->Is(Type::Undefined())) {
- return ReplaceWith(jsgraph()->HeapConstant(
+ return Replace(jsgraph()->HeapConstant(
graph()->zone()->isolate()->factory()->undefined_string()));
}
if (input_type->Is(Type::Null())) {
- return ReplaceWith(jsgraph()->HeapConstant(
+ return Replace(jsgraph()->HeapConstant(
graph()->zone()->isolate()->factory()->null_string()));
}
// TODO(turbofan): js-typed-lowering of ToString(x:boolean)
@@ -610,26 +609,26 @@ Reduction JSTypedLowering::ReduceJSToBooleanInput(Node* input) {
}
if (input_type->Is(Type::Undefined())) {
// JSToBoolean(undefined) => #false
- return ReplaceWith(jsgraph()->FalseConstant());
+ return Replace(jsgraph()->FalseConstant());
}
if (input_type->Is(Type::Null())) {
// JSToBoolean(null) => #false
- return ReplaceWith(jsgraph()->FalseConstant());
+ return Replace(jsgraph()->FalseConstant());
}
if (input_type->Is(Type::DetectableReceiver())) {
// JSToBoolean(x:detectable) => #true
- return ReplaceWith(jsgraph()->TrueConstant());
+ return Replace(jsgraph()->TrueConstant());
}
if (input_type->Is(Type::Undetectable())) {
// JSToBoolean(x:undetectable) => #false
- return ReplaceWith(jsgraph()->FalseConstant());
+ return Replace(jsgraph()->FalseConstant());
}
if (input_type->Is(Type::OrderedNumber())) {
// JSToBoolean(x:ordered-number) => BooleanNot(NumberEqual(x, #0))
Node* cmp = graph()->NewNode(simplified()->NumberEqual(), input,
jsgraph()->ZeroConstant());
Node* inv = graph()->NewNode(simplified()->BooleanNot(), cmp);
- return ReplaceWith(inv);
+ return Replace(inv);
}
if (input_type->Is(Type::String())) {
// JSToBoolean(x:string) => BooleanNot(NumberEqual(x.length, #0))
@@ -639,7 +638,7 @@ Reduction JSTypedLowering::ReduceJSToBooleanInput(Node* input) {
Node* cmp = graph()->NewNode(simplified()->NumberEqual(), length,
jsgraph()->ZeroConstant());
Node* inv = graph()->NewNode(simplified()->BooleanNot(), cmp);
- return ReplaceWith(inv);
+ return Replace(inv);
}
return NoChange();
}
@@ -649,16 +648,10 @@ Reduction JSTypedLowering::ReduceJSToBoolean(Node* node) {
// Try to reduce the input first.
Node* const input = node->InputAt(0);
Reduction reduction = ReduceJSToBooleanInput(input);
- if (reduction.Changed()) {
- NodeProperties::ReplaceWithValue(node, reduction.replacement());
- return reduction;
- }
- Type* const input_type = NodeProperties::GetBounds(input).upper;
- if (input->opcode() == IrOpcode::kPhi && input_type->Is(Type::Primitive())) {
- Node* const context = node->InputAt(1);
- // JSToBoolean(phi(x1,...,xn,control):primitive)
- // => phi(JSToBoolean(x1),...,JSToBoolean(xn),control):boolean
- RelaxEffects(node);
+ if (reduction.Changed()) return reduction;
+ if (input->opcode() == IrOpcode::kPhi) {
+ // JSToBoolean(phi(x1,...,xn,control),context)
+ // => phi(JSToBoolean(x1,no-context),...,JSToBoolean(xn,no-context))
int const input_count = input->InputCount() - 1;
Node* const control = input->InputAt(input_count);
DCHECK_LE(0, input_count);
@@ -673,8 +666,14 @@ Reduction JSTypedLowering::ReduceJSToBoolean(Node* node) {
if (reduction.Changed()) {
value = reduction.replacement();
} else {
- value = graph()->NewNode(javascript()->ToBoolean(), value, context,
- graph()->start(), graph()->start());
+ // We must be very careful not to introduce cycles when pushing
+ // operations into phis. It is safe for {value}, since it appears
+ // as input to the phi that we are replacing, but it's not safe
+ // to simply reuse the context of the {node}. However, ToBoolean()
+ // does not require a context anyways, so it's safe to discard it
+ // here and pass the dummy context.
+ value = graph()->NewNode(javascript()->ToBoolean(), value,
+ jsgraph()->NoContextConstant());
}
if (i < node->InputCount()) {
node->ReplaceInput(i, value);
@@ -690,6 +689,37 @@ Reduction JSTypedLowering::ReduceJSToBoolean(Node* node) {
node->TrimInputCount(input_count + 1);
return Changed(node);
}
+ if (input->opcode() == IrOpcode::kSelect) {
+ // JSToBoolean(select(c,x1,x2),context)
+ // => select(c,JSToBoolean(x1,no-context),...,JSToBoolean(x2,no-context))
+ int const input_count = input->InputCount();
+ BranchHint const input_hint = SelectParametersOf(input->op()).hint();
+ DCHECK_EQ(3, input_count);
+ DCHECK(NodeProperties::GetBounds(node).upper->Is(Type::Boolean()));
+ DCHECK(!NodeProperties::GetBounds(input).upper->Is(Type::Boolean()));
+ node->set_op(common()->Select(kMachAnyTagged, input_hint));
+ node->InsertInput(graph()->zone(), 0, input->InputAt(0));
+ for (int i = 1; i < input_count; ++i) {
+ Node* value = input->InputAt(i);
+ // Recursively try to reduce the value first.
+ Reduction reduction = ReduceJSToBooleanInput(value);
+ if (reduction.Changed()) {
+ value = reduction.replacement();
+ } else {
+ // We must be very careful not to introduce cycles when pushing
+ // operations into selects. It is safe for {value}, since it appears
+ // as input to the select that we are replacing, but it's not safe
+ // to simply reuse the context of the {node}. However, ToBoolean()
+ // does not require a context anyways, so it's safe to discard it
+ // here and pass the dummy context.
+ value = graph()->NewNode(javascript()->ToBoolean(), value,
+ jsgraph()->NoContextConstant());
+ }
+ node->ReplaceInput(i, value);
+ }
+ DCHECK_EQ(3, node->InputCount());
+ return Changed(node);
+ }
return NoChange();
}
@@ -915,22 +945,15 @@ Reduction JSTypedLowering::Reduce(Node* node) {
return ReduceNumberBinop(node, simplified()->NumberModulus());
case IrOpcode::kJSUnaryNot: {
Reduction result = ReduceJSToBooleanInput(node->InputAt(0));
- Node* value;
if (result.Changed()) {
// JSUnaryNot(x:boolean) => BooleanNot(x)
- value =
- graph()->NewNode(simplified()->BooleanNot(), result.replacement());
- NodeProperties::ReplaceWithValue(node, value);
- return Changed(value);
+ node = result.replacement();
} else {
// JSUnaryNot(x) => BooleanNot(JSToBoolean(x))
- value = graph()->NewNode(simplified()->BooleanNot(), node);
node->set_op(javascript()->ToBoolean());
- NodeProperties::ReplaceWithValue(node, value, node);
- // Note: ReplaceUses() smashes all uses, so smash it back here.
- value->ReplaceInput(0, node);
- return Changed(node);
}
+ Node* value = graph()->NewNode(simplified()->BooleanNot(), node);
+ return Replace(value);
}
case IrOpcode::kJSToBoolean:
return ReduceJSToBoolean(node);

Powered by Google App Engine
This is Rietveld 408576698