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

Unified Diff: src/compiler/control-flow-optimizer.cc

Issue 2139593002: [turbofan] Move TryCloneBranch in the EffectControlLinearizer pass. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Update. Created 4 years, 5 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/effect-control-linearizer.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/control-flow-optimizer.cc
diff --git a/src/compiler/control-flow-optimizer.cc b/src/compiler/control-flow-optimizer.cc
index 3fc3bcefaca43f67292ca90827362139117f02e5..6027c8201cf6dd8c860aac21099af6cf1f6a770e 100644
--- a/src/compiler/control-flow-optimizer.cc
+++ b/src/compiler/control-flow-optimizer.cc
@@ -63,146 +63,10 @@ void ControlFlowOptimizer::VisitNode(Node* node) {
void ControlFlowOptimizer::VisitBranch(Node* node) {
DCHECK_EQ(IrOpcode::kBranch, node->opcode());
if (TryBuildSwitch(node)) return;
- if (TryCloneBranch(node)) return;
VisitNode(node);
}
-bool ControlFlowOptimizer::TryCloneBranch(Node* node) {
- DCHECK_EQ(IrOpcode::kBranch, node->opcode());
-
- // This optimization is a special case of (super)block cloning. It takes an
- // input graph as shown below and clones the Branch node for every predecessor
- // to the Merge, essentially removing the Merge completely. This avoids
- // materializing the bit for the Phi and may offer potential for further
- // branch folding optimizations (i.e. because one or more inputs to the Phi is
- // a constant). Note that there may be more Phi nodes hanging off the Merge,
- // but we can only a certain subset of them currently (actually only Phi and
- // EffectPhi nodes whose uses have either the IfTrue or IfFalse as control
- // input).
-
- // Control1 ... ControlN
- // ^ ^
- // | | Cond1 ... CondN
- // +----+ +----+ ^ ^
- // | | | |
- // | | +----+ |
- // Merge<--+ | +------------+
- // ^ \|/
- // | Phi
- // | |
- // Branch----+
- // ^
- // |
- // +-----+-----+
- // | |
- // IfTrue IfFalse
- // ^ ^
- // | |
-
- // The resulting graph (modulo the Phi and EffectPhi nodes) looks like this:
-
- // Control1 Cond1 ... ControlN CondN
- // ^ ^ ^ ^
- // \ / \ /
- // Branch ... Branch
- // ^ ^
- // | |
- // +---+---+ +---+----+
- // | | | |
- // IfTrue IfFalse ... IfTrue IfFalse
- // ^ ^ ^ ^
- // | | | |
- // +--+ +-------------+ |
- // | | +--------------+ +--+
- // | | | |
- // Merge Merge
- // ^ ^
- // | |
-
- Node* branch = node;
- Node* cond = NodeProperties::GetValueInput(branch, 0);
- if (!cond->OwnedBy(branch) || cond->opcode() != IrOpcode::kPhi) return false;
- Node* merge = NodeProperties::GetControlInput(branch);
- if (merge->opcode() != IrOpcode::kMerge ||
- NodeProperties::GetControlInput(cond) != merge) {
- return false;
- }
- // Grab the IfTrue/IfFalse projections of the Branch.
- BranchMatcher matcher(branch);
- // Check/collect other Phi/EffectPhi nodes hanging off the Merge.
- NodeVector phis(zone());
- for (Node* const use : merge->uses()) {
- if (use == branch || use == cond) continue;
- // We cannot currently deal with non-Phi/EffectPhi nodes hanging off the
- // Merge. Ideally, we would just clone the nodes (and everything that
- // depends on it to some distant join point), but that requires knowledge
- // about dominance/post-dominance.
- if (!NodeProperties::IsPhi(use)) return false;
- for (Edge edge : use->use_edges()) {
- // Right now we can only handle Phi/EffectPhi nodes whose uses are
- // directly control-dependend on either the IfTrue or the IfFalse
- // successor, because we know exactly how to update those uses.
- // TODO(turbofan): Generalize this to all Phi/EffectPhi nodes using
- // dominance/post-dominance on the sea of nodes.
- if (edge.from()->op()->ControlInputCount() != 1) return false;
- Node* control = NodeProperties::GetControlInput(edge.from());
- if (NodeProperties::IsPhi(edge.from())) {
- control = NodeProperties::GetControlInput(control, edge.index());
- }
- if (control != matcher.IfTrue() && control != matcher.IfFalse())
- return false;
- }
- phis.push_back(use);
- }
- BranchHint const hint = BranchHintOf(branch->op());
- int const input_count = merge->op()->ControlInputCount();
- DCHECK_LE(1, input_count);
- Node** const inputs = zone()->NewArray<Node*>(2 * input_count);
- Node** const merge_true_inputs = &inputs[0];
- Node** const merge_false_inputs = &inputs[input_count];
- for (int index = 0; index < input_count; ++index) {
- Node* cond1 = NodeProperties::GetValueInput(cond, index);
- Node* control1 = NodeProperties::GetControlInput(merge, index);
- Node* branch1 = graph()->NewNode(common()->Branch(hint), cond1, control1);
- merge_true_inputs[index] = graph()->NewNode(common()->IfTrue(), branch1);
- merge_false_inputs[index] = graph()->NewNode(common()->IfFalse(), branch1);
- Enqueue(branch1);
- }
- Node* const merge_true = graph()->NewNode(common()->Merge(input_count),
- input_count, merge_true_inputs);
- Node* const merge_false = graph()->NewNode(common()->Merge(input_count),
- input_count, merge_false_inputs);
- for (Node* const phi : phis) {
- for (int index = 0; index < input_count; ++index) {
- inputs[index] = phi->InputAt(index);
- }
- inputs[input_count] = merge_true;
- Node* phi_true = graph()->NewNode(phi->op(), input_count + 1, inputs);
- inputs[input_count] = merge_false;
- Node* phi_false = graph()->NewNode(phi->op(), input_count + 1, inputs);
- for (Edge edge : phi->use_edges()) {
- Node* control = NodeProperties::GetControlInput(edge.from());
- if (NodeProperties::IsPhi(edge.from())) {
- control = NodeProperties::GetControlInput(control, edge.index());
- }
- DCHECK(control == matcher.IfTrue() || control == matcher.IfFalse());
- edge.UpdateTo((control == matcher.IfTrue()) ? phi_true : phi_false);
- }
- phi->Kill();
- }
- // Fix up IfTrue and IfFalse and kill all dead nodes.
- matcher.IfFalse()->ReplaceUses(merge_false);
- matcher.IfTrue()->ReplaceUses(merge_true);
- matcher.IfFalse()->Kill();
- matcher.IfTrue()->Kill();
- branch->Kill();
- cond->Kill();
- merge->Kill();
- return true;
-}
-
-
bool ControlFlowOptimizer::TryBuildSwitch(Node* node) {
DCHECK_EQ(IrOpcode::kBranch, node->opcode());
« no previous file with comments | « no previous file | src/compiler/effect-control-linearizer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698