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

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

Issue 1921483002: [turbofan] Wire in floating control during effect linearization phase. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix lines in the drawing (gcc, really?) Created 4 years, 8 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 | « no previous file | src/compiler/node-properties.h » ('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 ec21247bfc8c30d5b8a6efb5c794c5cd41e2c51f..1a484e0bbfb819b7d201db18c532a2b133b3b15e 100644
--- a/src/compiler/effect-control-linearizer.cc
+++ b/src/compiler/effect-control-linearizer.cc
@@ -34,8 +34,9 @@ MachineOperatorBuilder* EffectControlLinearizer::machine() const {
namespace {
-struct BlockEffectData {
+struct BlockEffectControlData {
Node* current_effect = nullptr; // New effect.
+ Node* current_control = nullptr; // New control.
};
// Effect phis that need to be updated after the first pass.
@@ -48,7 +49,7 @@ struct PendingEffectPhi {
};
void UpdateEffectPhi(Node* node, BasicBlock* block,
- ZoneVector<BlockEffectData>* block_effects) {
+ ZoneVector<BlockEffectControlData>* block_effects) {
// Update all inputs to an effect phi with the effects from the given
// block->effect map.
DCHECK_EQ(IrOpcode::kEffectPhi, node->opcode());
@@ -64,6 +65,27 @@ void UpdateEffectPhi(Node* node, BasicBlock* block,
}
}
+void UpdateBlockControl(BasicBlock* block,
+ ZoneVector<BlockEffectControlData>* block_effects) {
+ Node* control = block->NodeAt(0);
+ DCHECK(NodeProperties::IsControl(control));
+
+ // Do not rewire the end node.
+ if (control->opcode() == IrOpcode::kEnd) return;
+
+ // Update all inputs to the given control node with the correct control.
+ DCHECK_EQ(control->op()->ControlInputCount(), block->PredecessorCount());
+ for (int i = 0; i < control->op()->ControlInputCount(); i++) {
+ Node* input = NodeProperties::GetControlInput(control, i);
+ BasicBlock* predecessor = block->PredecessorAt(static_cast<size_t>(i));
+ Node* input_control =
+ (*block_effects)[predecessor->rpo_number()].current_control;
+ if (input != input_control) {
+ NodeProperties::ReplaceControlInput(control, input_control, i);
+ }
+ }
+}
+
bool HasIncomingBackEdges(BasicBlock* block) {
for (BasicBlock* pred : block->predecessors()) {
if (pred->rpo_number() >= block->rpo_number()) {
@@ -94,8 +116,9 @@ void RemoveRegionNode(Node* node) {
} // namespace
void EffectControlLinearizer::Run() {
- ZoneVector<BlockEffectData> block_effects(temp_zone());
+ ZoneVector<BlockEffectControlData> block_effects(temp_zone());
ZoneVector<PendingEffectPhi> pending_effect_phis(temp_zone());
+ ZoneVector<BasicBlock*> pending_block_controls(temp_zone());
block_effects.resize(schedule()->RpoBlockCount());
NodeVector inputs_buffer(temp_zone());
@@ -105,6 +128,16 @@ void EffectControlLinearizer::Run() {
// The control node should be the first.
Node* control = block->NodeAt(instr);
DCHECK(NodeProperties::IsControl(control));
+ // Update the control inputs.
+ if (HasIncomingBackEdges(block)) {
+ // If there are back edges, we need to update later because we have not
+ // computed the control yet. This should only happen for loops.
+ DCHECK_EQ(IrOpcode::kLoop, control->opcode());
+ pending_block_controls.push_back(block);
+ } else {
+ // If there are no back edges, we can update now.
+ UpdateBlockControl(block, &block_effects);
+ }
instr++;
// Iterate over the phis and update the effect phis.
@@ -177,8 +210,9 @@ void EffectControlLinearizer::Run() {
pending_effect_phis.push_back(PendingEffectPhi(effect, block));
} else if (control->opcode() == IrOpcode::kIfException) {
// The IfException is connected into the effect chain, so we need
- // to process it here.
- ProcessNode(control, &effect, &control);
+ // to update the effect here.
+ NodeProperties::ReplaceEffectInput(control, effect);
+ effect = control;
}
}
}
@@ -212,6 +246,7 @@ void EffectControlLinearizer::Run() {
// Store the effect for later use.
block_effects[block->rpo_number()].current_effect = effect;
+ block_effects[block->rpo_number()].current_control = control;
}
// Update the incoming edges of the effect phis that could not be processed
@@ -220,8 +255,27 @@ void EffectControlLinearizer::Run() {
UpdateEffectPhi(pending_effect_phi.effect_phi, pending_effect_phi.block,
&block_effects);
}
+ for (BasicBlock* pending_block_control : pending_block_controls) {
+ UpdateBlockControl(pending_block_control, &block_effects);
+ }
+}
+
+namespace {
+
+void TryScheduleCallIfSuccess(Node* node, Node** control) {
+ // Schedule the call's IfSuccess node if there is no exception use.
+ if (!NodeProperties::IsExceptionalCall(node)) {
+ for (Edge edge : node->use_edges()) {
+ if (NodeProperties::IsControlEdge(edge) &&
+ edge.from()->opcode() == IrOpcode::kIfSuccess) {
+ *control = edge.from();
+ }
+ }
+ }
}
+} // namespace
+
void EffectControlLinearizer::ProcessNode(Node* node, Node** effect,
Node** control) {
// If the node needs to be wired into the effect/control chain, do this
@@ -244,6 +298,16 @@ void EffectControlLinearizer::ProcessNode(Node* node, Node** effect,
}
}
+ if (node->opcode() == IrOpcode::kIfSuccess) {
+ // We always schedule IfSuccess with its call, so skip it here.
+ DCHECK_EQ(IrOpcode::kCall, node->InputAt(0)->opcode());
+ // The IfSuccess node should not belong to an exceptional call node
+ // because such IfSuccess nodes should only start a basic block (and
+ // basic block start nodes are not handled in the ProcessNode method).
+ DCHECK(!NodeProperties::IsExceptionalCall(node->InputAt(0)));
+ return;
+ }
+
// If the node takes an effect, replace with the current one.
if (node->op()->EffectInputCount() > 0) {
DCHECK_EQ(1, node->op()->EffectInputCount());
@@ -264,6 +328,18 @@ void EffectControlLinearizer::ProcessNode(Node* node, Node** effect,
DCHECK(node->op()->EffectOutputCount() == 0 ||
node->opcode() == IrOpcode::kStart);
}
+ // Rewire control inputs of control nodes, and update the current control
+ // input.
+ if (node->op()->ControlOutputCount() > 0) {
+ DCHECK_EQ(1, node->op()->ControlInputCount());
+ NodeProperties::ReplaceControlInput(node, *control);
+ *control = node;
+
+ if (node->opcode() == IrOpcode::kCall) {
+ // Schedule the call's IfSuccess node (if there is no exception use).
+ TryScheduleCallIfSuccess(node, control);
+ }
+ }
}
bool EffectControlLinearizer::TryWireInStateEffect(Node* node, Node** effect,
« no previous file with comments | « no previous file | src/compiler/node-properties.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698