Commit 85fde59d authored by jarin's avatar jarin Committed by Commit bot

[turbofan] Introduce CheckUnless.

Similarly to CheckIf, CheckUnless is a deoptimization without a specific
frame state. A frame state is assigned during effect-control linearization
(and CheckUnless is turned into DeoptimizeUnless).

At the moment, the new operator is only used at one place in native context
specialization, but we should use it everywhere. The advantage of
CHeckUnless is that it avoids non-truncating uses of values by frame
states. This particular change is aimed at Octane's crypto, where this
enables to turn one NumberMultiply into Int32Mul, and thus improve
the score by more than 10% (it also needs minus zero truncation and
typing to be improved, but those CLs are already in flight).

BUG=v8:4470
R=bmeurer@chromium.org

Review-Url: https://codereview.chromium.org/2080113002
Cr-Commit-Position: refs/heads/master@{#37085}
parent e03c090d
......@@ -458,6 +458,9 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node,
case IrOpcode::kCheckIf:
state = LowerCheckIf(node, frame_state, *effect, *control);
break;
case IrOpcode::kCheckUnless:
state = LowerCheckUnless(node, frame_state, *effect, *control);
break;
case IrOpcode::kCheckFloat64Hole:
state = LowerCheckFloat64Hole(node, frame_state, *effect, *control);
break;
......@@ -1331,6 +1334,17 @@ EffectControlLinearizer::LowerCheckIf(Node* node, Node* frame_state,
return ValueEffectControl(node, node, node);
}
EffectControlLinearizer::ValueEffectControl
EffectControlLinearizer::LowerCheckUnless(Node* node, Node* frame_state,
Node* effect, Node* control) {
NodeProperties::ReplaceEffectInput(node, effect);
NodeProperties::ReplaceControlInput(node, control);
DCHECK_NOT_NULL(frame_state);
node->InsertInput(graph()->zone(), 1, frame_state);
NodeProperties::ChangeOp(node, common()->DeoptimizeUnless());
return ValueEffectControl(node, node, node);
}
EffectControlLinearizer::ValueEffectControl
EffectControlLinearizer::LowerCheckFloat64Hole(Node* node, Node* frame_state,
Node* effect, Node* control) {
......
......@@ -97,6 +97,8 @@ class EffectControlLinearizer {
Node* effect, Node* control);
ValueEffectControl LowerCheckIf(Node* node, Node* frame_state, Node* effect,
Node* control);
ValueEffectControl LowerCheckUnless(Node* node, Node* frame_state,
Node* effect, Node* control);
ValueEffectControl LowerPlainPrimitiveToNumber(Node* node, Node* effect,
Node* control);
ValueEffectControl LowerPlainPrimitiveToWord32(Node* node, Node* effect,
......
......@@ -573,10 +573,9 @@ Reduction JSNativeContextSpecialization::ReduceElementAccess(
// TODO(turbofan): This is ugly as hell! We should probably introduce
// macro-ish operators for property access that encapsulate this whole
// mess.
Node* deoptimize =
graph()->NewNode(common()->DeoptimizeUnless(), check, frame_state,
effect, fallthrough_control);
this_controls.push_back(deoptimize);
Node* deoptimize = graph()->NewNode(
simplified()->CheckUnless(), check, effect, fallthrough_control);
this_controls.push_back(fallthrough_control);
this_effects.push_back(deoptimize);
fallthrough_control = nullptr;
} else {
......
......@@ -242,6 +242,7 @@
V(CheckFloat64Hole) \
V(CheckTaggedHole) \
V(CheckIf) \
V(CheckUnless) \
V(TruncateTaggedToWord32) \
V(TruncateTaggedToFloat64) \
V(Allocate) \
......
......@@ -1192,6 +1192,11 @@ class RepresentationSelector {
case IrOpcode::kHeapConstant:
return VisitLeaf(node, MachineRepresentation::kTagged);
case IrOpcode::kCheckIf:
case IrOpcode::kCheckUnless:
ProcessInput(node, 0, UseInfo::Bool());
ProcessRemainingInputs(node, 1);
return;
case IrOpcode::kDeoptimizeIf:
case IrOpcode::kDeoptimizeUnless:
ProcessInput(node, 0, UseInfo::Bool());
......
......@@ -366,6 +366,13 @@ struct SimplifiedOperatorGlobalCache final {
};
CheckIfOperator kCheckIf;
struct CheckUnlessOperator final : public Operator {
CheckUnlessOperator()
: Operator(IrOpcode::kCheckUnless, Operator::kPure, "CheckUnless", 1, 1,
1, 0, 1, 0) {}
};
CheckUnlessOperator kCheckUnless;
template <PretenureFlag kPretenure>
struct AllocateOperator final : public Operator1<PretenureFlag> {
AllocateOperator()
......@@ -442,6 +449,10 @@ const Operator* SimplifiedOperatorBuilder::CheckIf() {
return &cache_.kCheckIf;
}
const Operator* SimplifiedOperatorBuilder::CheckUnless() {
return &cache_.kCheckUnless;
}
const Operator* SimplifiedOperatorBuilder::ReferenceEqual(Type* type) {
return new (zone()) Operator(IrOpcode::kReferenceEqual,
Operator::kCommutative | Operator::kPure,
......
......@@ -245,6 +245,7 @@ class SimplifiedOperatorBuilder final : public ZoneObject {
const Operator* CheckFloat64Hole(CheckFloat64HoleMode);
const Operator* CheckTaggedHole(CheckTaggedHoleMode);
const Operator* CheckIf();
const Operator* CheckUnless();
const Operator* ObjectIsCallable();
const Operator* ObjectIsNumber();
......
......@@ -2052,6 +2052,11 @@ Type* Typer::Visitor::TypeCheckIf(Node* node) {
return nullptr;
}
Type* Typer::Visitor::TypeCheckUnless(Node* node) {
UNREACHABLE();
return nullptr;
}
Type* Typer::Visitor::TypeTruncateTaggedToWord32(Node* node) {
Type* arg = Operand(node, 0);
// TODO(jarin): DCHECK(arg->Is(Type::NumberOrUndefined()));
......
......@@ -279,6 +279,7 @@ void Verifier::Visitor::Check(Node* node) {
case IrOpcode::kDeoptimizeIf:
case IrOpcode::kDeoptimizeUnless:
case IrOpcode::kCheckIf:
case IrOpcode::kCheckUnless:
// Type is empty.
CheckNotTyped(node);
break;
......
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