[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}
This commit is contained in:
parent
e03c090d1b
commit
85fde59d53
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user