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

Unified Diff: src/compiler/effect-control-linearizer.cc

Issue 2033143002: [turbofan] Add frame state propagation to linearizer. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@local_turbofan-checkpoint-6
Patch Set: Addressed comment. Created 4 years, 6 months 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
« no previous file with comments | « src/compiler/effect-control-linearizer.h ('k') | src/compiler/operator-properties.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/effect-control-linearizer.cc
diff --git a/src/compiler/effect-control-linearizer.cc b/src/compiler/effect-control-linearizer.cc
index cf38229777cf4cfa07988297f7c7debfcb59e512..f5c5d2d1e80ba08968caef18ba2a59ec870164eb 100644
--- a/src/compiler/effect-control-linearizer.cc
+++ b/src/compiler/effect-control-linearizer.cc
@@ -37,6 +37,7 @@ namespace {
struct BlockEffectControlData {
Node* current_effect = nullptr; // New effect.
Node* current_control = nullptr; // New control.
+ Node* current_frame_state = nullptr; // New frame state.
};
// Effect phis that need to be updated after the first pass.
@@ -222,10 +223,30 @@ void EffectControlLinearizer::Run() {
NodeProperties::ReplaceEffectInput(terminate, effect);
}
+ // The frame state at block entry is determined by the frame states leaving
+ // all predecessors. In case there is no frame state dominating this block,
+ // we can rely on a checkpoint being present before the next deoptimization.
+ // TODO(mstarzinger): Eventually we will need to go hunt for a frame state
+ // once deoptimizing nodes roam freely through the schedule.
+ Node* frame_state = nullptr;
+ if (block != schedule()->start()) {
+ // If all the predecessors have the same effect, we can use it
+ // as our current effect.
+ int rpo_number = block->PredecessorAt(0)->rpo_number();
+ frame_state = block_effects[rpo_number].current_frame_state;
+ for (size_t i = 1; i < block->PredecessorCount(); i++) {
+ int rpo_number = block->PredecessorAt(i)->rpo_number();
+ if (block_effects[rpo_number].current_frame_state != frame_state) {
+ frame_state = nullptr;
+ break;
+ }
+ }
+ }
+
// Process the ordinary instructions.
for (; instr < block->NodeCount(); instr++) {
Node* node = block->NodeAt(instr);
- ProcessNode(node, &effect, &control);
+ ProcessNode(node, &frame_state, &effect, &control);
}
switch (block->control()) {
@@ -240,13 +261,14 @@ void EffectControlLinearizer::Run() {
case BasicBlock::kReturn:
case BasicBlock::kDeoptimize:
case BasicBlock::kThrow:
- ProcessNode(block->control_input(), &effect, &control);
+ ProcessNode(block->control_input(), &frame_state, &effect, &control);
break;
}
// Store the effect for later use.
block_effects[block->rpo_number()].current_effect = effect;
block_effects[block->rpo_number()].current_control = control;
+ block_effects[block->rpo_number()].current_frame_state = frame_state;
}
// Update the incoming edges of the effect phis that could not be processed
@@ -276,14 +298,19 @@ void TryScheduleCallIfSuccess(Node* node, Node** control) {
} // namespace
-void EffectControlLinearizer::ProcessNode(Node* node, Node** effect,
- Node** control) {
+void EffectControlLinearizer::ProcessNode(Node* node, Node** frame_state,
+ Node** effect, Node** control) {
// If the node needs to be wired into the effect/control chain, do this
- // here.
- if (TryWireInStateEffect(node, effect, control)) {
+ // here. Pass current frame state for lowering to eager deoptimization.
+ if (TryWireInStateEffect(node, *frame_state, effect, control)) {
return;
}
+ // If the node has a visible effect, then there must be a checkpoint in the
+ // effect chain before we are allowed to place another eager deoptimization
+ // point. We zap the frame state to ensure this invariant is maintained.
+ if (!node->op()->HasProperty(Operator::kNoWrite)) *frame_state = nullptr;
+
// Remove the end markers of 'atomic' allocation region because the
// region should be wired-in now.
if (node->opcode() == IrOpcode::kFinishRegion ||
@@ -294,10 +321,10 @@ void EffectControlLinearizer::ProcessNode(Node* node, Node** effect,
}
// Special treatment for checkpoint nodes.
- // TODO(epertoso): Pickup the current frame state.
if (node->opcode() == IrOpcode::kCheckpoint) {
// Unlink the check point; effect uses will be updated to the incoming
- // effect that is passed.
+ // effect that is passed. The frame state is preserved for lowering.
+ *frame_state = NodeProperties::GetFrameStateInput(node, 0);
node->TrimInputCount(0);
return;
}
@@ -347,7 +374,9 @@ void EffectControlLinearizer::ProcessNode(Node* node, Node** effect,
}
}
-bool EffectControlLinearizer::TryWireInStateEffect(Node* node, Node** effect,
+bool EffectControlLinearizer::TryWireInStateEffect(Node* node,
+ Node* frame_state,
+ Node** effect,
Node** control) {
ValueEffectControl state(nullptr, nullptr, nullptr);
switch (node->opcode()) {
@@ -388,16 +417,16 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node, Node** effect,
state = LowerTruncateTaggedToFloat64(node, *effect, *control);
break;
case IrOpcode::kCheckedUint32ToInt32:
- state = LowerCheckedUint32ToInt32(node, *effect, *control);
+ state = LowerCheckedUint32ToInt32(node, frame_state, *effect, *control);
break;
case IrOpcode::kCheckedFloat64ToInt32:
- state = LowerCheckedFloat64ToInt32(node, *effect, *control);
+ state = LowerCheckedFloat64ToInt32(node, frame_state, *effect, *control);
break;
case IrOpcode::kCheckedTaggedToInt32:
- state = LowerCheckedTaggedToInt32(node, *effect, *control);
+ state = LowerCheckedTaggedToInt32(node, frame_state, *effect, *control);
break;
case IrOpcode::kCheckedTaggedToFloat64:
- state = LowerCheckedTaggedToFloat64(node, *effect, *control);
+ state = LowerCheckedTaggedToFloat64(node, frame_state, *effect, *control);
break;
case IrOpcode::kTruncateTaggedToWord32:
state = LowerTruncateTaggedToWord32(node, *effect, *control);
@@ -718,10 +747,11 @@ EffectControlLinearizer::LowerTruncateTaggedToFloat64(Node* node, Node* effect,
}
EffectControlLinearizer::ValueEffectControl
-EffectControlLinearizer::LowerCheckedUint32ToInt32(Node* node, Node* effect,
+EffectControlLinearizer::LowerCheckedUint32ToInt32(Node* node,
+ Node* frame_state,
+ Node* effect,
Node* control) {
Node* value = node->InputAt(0);
- Node* frame_state = NodeProperties::GetFrameStateInput(node, 0);
Node* max_int = jsgraph()->Int32Constant(std::numeric_limits<int32_t>::max());
Node* is_safe =
graph()->NewNode(machine()->Uint32LessThanOrEqual(), value, max_int);
@@ -774,10 +804,11 @@ EffectControlLinearizer::BuildCheckedFloat64ToInt32(Node* value,
}
EffectControlLinearizer::ValueEffectControl
-EffectControlLinearizer::LowerCheckedFloat64ToInt32(Node* node, Node* effect,
+EffectControlLinearizer::LowerCheckedFloat64ToInt32(Node* node,
+ Node* frame_state,
+ Node* effect,
Node* control) {
Node* value = node->InputAt(0);
- Node* frame_state = NodeProperties::GetFrameStateInput(node, 0);
// Make sure the lowered node does not appear in any use lists.
node->TrimInputCount(0);
@@ -786,10 +817,11 @@ EffectControlLinearizer::LowerCheckedFloat64ToInt32(Node* node, Node* effect,
}
EffectControlLinearizer::ValueEffectControl
-EffectControlLinearizer::LowerCheckedTaggedToInt32(Node* node, Node* effect,
+EffectControlLinearizer::LowerCheckedTaggedToInt32(Node* node,
+ Node* frame_state,
+ Node* effect,
Node* control) {
Node* value = node->InputAt(0);
- Node* frame_state = NodeProperties::GetFrameStateInput(node, 0);
Node* check = ObjectIsSmi(value);
Node* branch =
@@ -863,10 +895,11 @@ EffectControlLinearizer::BuildCheckedHeapNumberOrOddballToFloat64(
}
EffectControlLinearizer::ValueEffectControl
-EffectControlLinearizer::LowerCheckedTaggedToFloat64(Node* node, Node* effect,
+EffectControlLinearizer::LowerCheckedTaggedToFloat64(Node* node,
+ Node* frame_state,
+ Node* effect,
Node* control) {
Node* value = node->InputAt(0);
- Node* frame_state = NodeProperties::GetFrameStateInput(node, 0);
Node* check = ObjectIsSmi(value);
Node* branch =
« no previous file with comments | « src/compiler/effect-control-linearizer.h ('k') | src/compiler/operator-properties.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698