[turbofan] Introduce CheckIf node (deopt without explicit frame state).
Type feedback introduced DeoptimizeIf node in representation inference (for Int32AddWithOverflow); we found the frame state for the deopt by walking the effect chain. Unfortunately, the effect chain can hit effect merges introduced by simplified lowering (e.g., in LoadBuffer) and thus fail the assertion (we refuse to go through effect phis). This CL postpones assignment of the frame state to the effect-control lninearizer, so that we can correctly propagate the frame state to the deopt point. The DeoptimizeIf node with unassigned frame state is called CheckIf. BUG= Review-Url: https://codereview.chromium.org/2050813003 Cr-Commit-Position: refs/heads/master@{#36839}
This commit is contained in:
parent
81c8ce723a
commit
f2312019af
@ -452,10 +452,13 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node,
|
||||
case IrOpcode::kStringFromCharCode:
|
||||
state = LowerStringFromCharCode(node, *effect, *control);
|
||||
break;
|
||||
case IrOpcode::kCheckIf:
|
||||
state = LowerCheckIf(node, frame_state, *effect, *control);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
NodeProperties::ReplaceUses(node, state.value);
|
||||
NodeProperties::ReplaceUses(node, state.value, state.effect, state.control);
|
||||
*effect = state.effect;
|
||||
*control = state.control;
|
||||
return true;
|
||||
@ -1273,6 +1276,16 @@ EffectControlLinearizer::LowerStringFromCharCode(Node* node, Node* effect,
|
||||
return ValueEffectControl(value, effect, control);
|
||||
}
|
||||
|
||||
EffectControlLinearizer::ValueEffectControl
|
||||
EffectControlLinearizer::LowerCheckIf(Node* node, Node* frame_state,
|
||||
Node* effect, Node* control) {
|
||||
NodeProperties::ReplaceEffectInput(node, effect);
|
||||
NodeProperties::ReplaceControlInput(node, control);
|
||||
node->InsertInput(graph()->zone(), 1, frame_state);
|
||||
NodeProperties::ChangeOp(node, common()->DeoptimizeIf());
|
||||
return ValueEffectControl(node, node, node);
|
||||
}
|
||||
|
||||
EffectControlLinearizer::ValueEffectControl
|
||||
EffectControlLinearizer::AllocateHeapNumberWithValue(Node* value, Node* effect,
|
||||
Node* control) {
|
||||
|
@ -89,6 +89,8 @@ class EffectControlLinearizer {
|
||||
Node* control);
|
||||
ValueEffectControl LowerStringFromCharCode(Node* node, Node* effect,
|
||||
Node* control);
|
||||
ValueEffectControl LowerCheckIf(Node* node, Node* frame_state, Node* effect,
|
||||
Node* control);
|
||||
ValueEffectControl AllocateHeapNumberWithValue(Node* node, Node* effect,
|
||||
Node* control);
|
||||
ValueEffectControl BuildCheckedFloat64ToInt32(Node* value, Node* frame_state,
|
||||
|
@ -215,7 +215,8 @@ void NodeProperties::ReplaceUses(Node* node, Node* value, Node* effect,
|
||||
DCHECK_NOT_NULL(exception);
|
||||
edge.UpdateTo(exception);
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
DCHECK_NOT_NULL(success);
|
||||
edge.UpdateTo(success);
|
||||
}
|
||||
} else if (IsEffectEdge(edge)) {
|
||||
DCHECK_NOT_NULL(effect);
|
||||
|
@ -216,6 +216,7 @@
|
||||
V(CheckedFloat64ToInt32) \
|
||||
V(CheckedTaggedToInt32) \
|
||||
V(CheckedTaggedToFloat64) \
|
||||
V(CheckIf) \
|
||||
V(TruncateTaggedToWord32) \
|
||||
V(TruncateTaggedToFloat64) \
|
||||
V(Allocate) \
|
||||
|
@ -1035,11 +1035,10 @@ class RepresentationSelector {
|
||||
void ChangeToInt32OverflowOp(Node* node, const Operator* op) {
|
||||
Node* effect = NodeProperties::GetEffectInput(node);
|
||||
Node* control = NodeProperties::GetControlInput(node);
|
||||
Node* frame_state = NodeProperties::FindFrameStateBefore(node);
|
||||
Node* arith = graph()->NewNode(op, node->InputAt(0), node->InputAt(1));
|
||||
Node* overflow = graph()->NewNode(common()->Projection(1), arith);
|
||||
control = effect = graph()->NewNode(common()->DeoptimizeIf(), overflow,
|
||||
frame_state, effect, control);
|
||||
control = effect =
|
||||
graph()->NewNode(simplified()->CheckIf(), overflow, effect, control);
|
||||
|
||||
Node* value = graph()->NewNode(common()->Projection(0), arith);
|
||||
ReplaceEffectControlUses(node, effect, control);
|
||||
|
@ -261,6 +261,13 @@ struct SimplifiedOperatorGlobalCache final {
|
||||
CHECKED_OP_LIST(CHECKED)
|
||||
#undef CHECKED
|
||||
|
||||
struct CheckIfOperator final : public Operator {
|
||||
CheckIfOperator()
|
||||
: Operator(IrOpcode::kCheckIf, Operator::kFoldable, "CheckIf", 1, 1, 1,
|
||||
0, 1, 1) {}
|
||||
};
|
||||
CheckIfOperator kCheckIf;
|
||||
|
||||
template <PretenureFlag kPretenure>
|
||||
struct AllocateOperator final : public Operator1<PretenureFlag> {
|
||||
AllocateOperator()
|
||||
@ -309,6 +316,10 @@ PURE_OP_LIST(GET_FROM_CACHE)
|
||||
CHECKED_OP_LIST(GET_FROM_CACHE)
|
||||
#undef GET_FROM_CACHE
|
||||
|
||||
const Operator* SimplifiedOperatorBuilder::CheckIf() {
|
||||
return &cache_.kCheckIf;
|
||||
}
|
||||
|
||||
const Operator* SimplifiedOperatorBuilder::ReferenceEqual(Type* type) {
|
||||
return new (zone()) Operator(IrOpcode::kReferenceEqual,
|
||||
Operator::kCommutative | Operator::kPure,
|
||||
|
@ -190,6 +190,8 @@ class SimplifiedOperatorBuilder final : public ZoneObject {
|
||||
const Operator* CheckedTaggedToInt32();
|
||||
const Operator* CheckedTaggedToFloat64();
|
||||
|
||||
const Operator* CheckIf();
|
||||
|
||||
const Operator* ObjectIsCallable();
|
||||
const Operator* ObjectIsNumber();
|
||||
const Operator* ObjectIsReceiver();
|
||||
|
@ -1945,6 +1945,11 @@ Type* Typer::Visitor::TypeCheckedTaggedToFloat64(Node* node) {
|
||||
return Type::Number();
|
||||
}
|
||||
|
||||
Type* Typer::Visitor::TypeCheckIf(Node* node) {
|
||||
UNREACHABLE();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Type* Typer::Visitor::TypeTruncateTaggedToWord32(Node* node) {
|
||||
Type* arg = Operand(node, 0);
|
||||
// TODO(jarin): DCHECK(arg->Is(Type::NumberOrUndefined()));
|
||||
|
@ -278,6 +278,7 @@ void Verifier::Visitor::Check(Node* node) {
|
||||
break;
|
||||
case IrOpcode::kDeoptimizeIf:
|
||||
case IrOpcode::kDeoptimizeUnless:
|
||||
case IrOpcode::kCheckIf:
|
||||
// Type is empty.
|
||||
CheckNotTyped(node);
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user