Commit 62355eeb authored by Manos Koukoutos's avatar Manos Koukoutos Committed by Commit Bot

[turbofan] Add MachineRepresentation argument to LoopExitValue

LoopExitValue nodes can be used as inputs to Phis in loop optimizations.
To do this, we need to know the machine representation that needs to be
passed to the new Phi node. This CL adds a MachineRepresentation
argument to LoopExitValue nodes, as well as a helper to extract it.
Since the MachineRepresentation is not used by JS compilation, nodes
generated during JS compilation are passed kTagged as a default value.

Change-Id: I925f382d5e6988d8fad3de7a6db231e871d6ed36
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2578983
Commit-Queue: Manos Koukoutos <manoskouk@chromium.org>
Reviewed-by: 's avatarGeorg Neis (ooo until January 5) <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#71798}
parent 106a47fd
...@@ -910,27 +910,31 @@ void BytecodeGraphBuilder::Environment::PrepareForLoopExit( ...@@ -910,27 +910,31 @@ void BytecodeGraphBuilder::Environment::PrepareForLoopExit(
// live after exiting the loop. // live after exiting the loop.
for (int i = 0; i < parameter_count(); i++) { for (int i = 0; i < parameter_count(); i++) {
if (assignments.ContainsParameter(i)) { if (assignments.ContainsParameter(i)) {
Node* rename = Node* rename = graph()->NewNode(
graph()->NewNode(common()->LoopExitValue(), values_[i], loop_exit); common()->LoopExitValue(MachineRepresentation::kTagged), values_[i],
loop_exit);
values_[i] = rename; values_[i] = rename;
} }
} }
for (int i = 0; i < register_count(); i++) { for (int i = 0; i < register_count(); i++) {
if (assignments.ContainsLocal(i) && if (assignments.ContainsLocal(i) &&
(liveness == nullptr || liveness->RegisterIsLive(i))) { (liveness == nullptr || liveness->RegisterIsLive(i))) {
Node* rename = graph()->NewNode(common()->LoopExitValue(), Node* rename = graph()->NewNode(
common()->LoopExitValue(MachineRepresentation::kTagged),
values_[register_base() + i], loop_exit); values_[register_base() + i], loop_exit);
values_[register_base() + i] = rename; values_[register_base() + i] = rename;
} }
} }
if (liveness == nullptr || liveness->AccumulatorIsLive()) { if (liveness == nullptr || liveness->AccumulatorIsLive()) {
Node* rename = graph()->NewNode(common()->LoopExitValue(), Node* rename = graph()->NewNode(
common()->LoopExitValue(MachineRepresentation::kTagged),
values_[accumulator_base()], loop_exit); values_[accumulator_base()], loop_exit);
values_[accumulator_base()] = rename; values_[accumulator_base()] = rename;
} }
if (generator_state_ != nullptr) { if (generator_state_ != nullptr) {
generator_state_ = graph()->NewNode(common()->LoopExitValue(), generator_state_ = graph()->NewNode(
common()->LoopExitValue(MachineRepresentation::kTagged),
generator_state_, loop_exit); generator_state_, loop_exit);
} }
} }
......
...@@ -193,6 +193,10 @@ MachineRepresentation PhiRepresentationOf(const Operator* const op) { ...@@ -193,6 +193,10 @@ MachineRepresentation PhiRepresentationOf(const Operator* const op) {
return OpParameter<MachineRepresentation>(op); return OpParameter<MachineRepresentation>(op);
} }
MachineRepresentation LoopExitValueRepresentationOf(const Operator* const op) {
DCHECK_EQ(IrOpcode::kLoopExitValue, op->opcode());
return OpParameter<MachineRepresentation>(op);
}
int ParameterIndexOf(const Operator* const op) { int ParameterIndexOf(const Operator* const op) {
DCHECK_EQ(IrOpcode::kParameter, op->opcode()); DCHECK_EQ(IrOpcode::kParameter, op->opcode());
...@@ -466,12 +470,13 @@ IfValueParameters const& IfValueParametersOf(const Operator* op) { ...@@ -466,12 +470,13 @@ IfValueParameters const& IfValueParametersOf(const Operator* op) {
V(Throw, Operator::kKontrol, 0, 1, 1, 0, 0, 1) \ V(Throw, Operator::kKontrol, 0, 1, 1, 0, 0, 1) \
V(Terminate, Operator::kKontrol, 0, 1, 1, 0, 0, 1) \ V(Terminate, Operator::kKontrol, 0, 1, 1, 0, 0, 1) \
V(LoopExit, Operator::kKontrol, 0, 0, 2, 0, 0, 1) \ V(LoopExit, Operator::kKontrol, 0, 0, 2, 0, 0, 1) \
V(LoopExitValue, Operator::kPure, 1, 0, 1, 1, 0, 0) \
V(LoopExitEffect, Operator::kNoThrow, 0, 1, 1, 0, 1, 0) \ V(LoopExitEffect, Operator::kNoThrow, 0, 1, 1, 0, 1, 0) \
V(Checkpoint, Operator::kKontrol, 0, 1, 1, 0, 1, 0) \ V(Checkpoint, Operator::kKontrol, 0, 1, 1, 0, 1, 0) \
V(FinishRegion, Operator::kKontrol, 1, 1, 0, 1, 1, 0) \ V(FinishRegion, Operator::kKontrol, 1, 1, 0, 1, 1, 0) \
V(Retain, Operator::kKontrol, 1, 1, 0, 0, 1, 0) V(Retain, Operator::kKontrol, 1, 1, 0, 0, 1, 0)
#define CACHED_LOOP_EXIT_VALUE_LIST(V) V(kTagged)
#define CACHED_BRANCH_LIST(V) \ #define CACHED_BRANCH_LIST(V) \
V(None, CriticalSafetyCheck) \ V(None, CriticalSafetyCheck) \
V(True, CriticalSafetyCheck) \ V(True, CriticalSafetyCheck) \
...@@ -726,6 +731,19 @@ struct CommonOperatorGlobalCache final { ...@@ -726,6 +731,19 @@ struct CommonOperatorGlobalCache final {
CACHED_MERGE_LIST(CACHED_MERGE) CACHED_MERGE_LIST(CACHED_MERGE)
#undef CACHED_MERGE #undef CACHED_MERGE
template <MachineRepresentation kRep>
struct LoopExitValueOperator final : public Operator1<MachineRepresentation> {
LoopExitValueOperator()
: Operator1<MachineRepresentation>(IrOpcode::kLoopExitValue,
Operator::kPure, "LoopExitValue", 1,
0, 1, 1, 0, 0, kRep) {}
};
#define CACHED_LOOP_EXIT_VALUE(rep) \
LoopExitValueOperator<MachineRepresentation::rep> \
kLoopExitValue##rep##Operator;
CACHED_LOOP_EXIT_VALUE_LIST(CACHED_LOOP_EXIT_VALUE)
#undef CACHED_LOOP_EXIT_VALUE
template <DeoptimizeKind kKind, DeoptimizeReason kReason> template <DeoptimizeKind kKind, DeoptimizeReason kReason>
struct DeoptimizeOperator final : public Operator1<DeoptimizeParameters> { struct DeoptimizeOperator final : public Operator1<DeoptimizeParameters> {
DeoptimizeOperator() DeoptimizeOperator()
...@@ -1144,6 +1162,24 @@ const Operator* CommonOperatorBuilder::Merge(int control_input_count) { ...@@ -1144,6 +1162,24 @@ const Operator* CommonOperatorBuilder::Merge(int control_input_count) {
0, 0, control_input_count, 0, 0, 1); // counts 0, 0, control_input_count, 0, 0, 1); // counts
} }
const Operator* CommonOperatorBuilder::LoopExitValue(
MachineRepresentation rep) {
switch (rep) {
#define CACHED_LOOP_EXIT_VALUE(kRep) \
case MachineRepresentation::kRep: \
return &cache_.kLoopExitValue##kRep##Operator;
CACHED_LOOP_EXIT_VALUE_LIST(CACHED_LOOP_EXIT_VALUE)
#undef CACHED_LOOP_EXIT_VALUE
default:
// Uncached.
return zone()->New<Operator1<MachineRepresentation>>( // --
IrOpcode::kLoopExitValue, Operator::kPure, // opcode
"LoopExitValue", // name
1, 0, 1, 1, 0, 0, // counts
rep); // parameter
}
}
const Operator* CommonOperatorBuilder::Parameter(int index, const Operator* CommonOperatorBuilder::Parameter(int index,
const char* debug_name) { const char* debug_name) {
......
...@@ -167,6 +167,9 @@ V8_EXPORT_PRIVATE CallDescriptor const* CallDescriptorOf(const Operator* const) ...@@ -167,6 +167,9 @@ V8_EXPORT_PRIVATE CallDescriptor const* CallDescriptorOf(const Operator* const)
V8_EXPORT_PRIVATE size_t ProjectionIndexOf(const Operator* const) V8_EXPORT_PRIVATE size_t ProjectionIndexOf(const Operator* const)
V8_WARN_UNUSED_RESULT; V8_WARN_UNUSED_RESULT;
V8_EXPORT_PRIVATE MachineRepresentation
LoopExitValueRepresentationOf(const Operator* const) V8_WARN_UNUSED_RESULT;
V8_EXPORT_PRIVATE MachineRepresentation V8_EXPORT_PRIVATE MachineRepresentation
PhiRepresentationOf(const Operator* const) V8_WARN_UNUSED_RESULT; PhiRepresentationOf(const Operator* const) V8_WARN_UNUSED_RESULT;
...@@ -527,7 +530,7 @@ class V8_EXPORT_PRIVATE CommonOperatorBuilder final ...@@ -527,7 +530,7 @@ class V8_EXPORT_PRIVATE CommonOperatorBuilder final
const Operator* EffectPhi(int effect_input_count); const Operator* EffectPhi(int effect_input_count);
const Operator* InductionVariablePhi(int value_input_count); const Operator* InductionVariablePhi(int value_input_count);
const Operator* LoopExit(); const Operator* LoopExit();
const Operator* LoopExitValue(); const Operator* LoopExitValue(MachineRepresentation rep);
const Operator* LoopExitEffect(); const Operator* LoopExitEffect();
const Operator* Checkpoint(); const Operator* Checkpoint();
const Operator* BeginRegion(RegionObservability); const Operator* BeginRegion(RegionObservability);
......
...@@ -569,8 +569,9 @@ void GraphAssembler::MergeState(GraphAssemblerLabel<sizeof...(Vars)>* label, ...@@ -569,8 +569,9 @@ void GraphAssembler::MergeState(GraphAssemblerLabel<sizeof...(Vars)>* label,
*loop_headers_.back())); *loop_headers_.back()));
AddNode(graph()->NewNode(common()->LoopExitEffect(), effect(), control())); AddNode(graph()->NewNode(common()->LoopExitEffect(), effect(), control()));
for (size_t i = 0; i < kVarCount; i++) { for (size_t i = 0; i < kVarCount; i++) {
var_array[i] = AddNode( var_array[i] = AddNode(graph()->NewNode(
graph()->NewNode(common()->LoopExitValue(), var_array[i], control())); common()->LoopExitValue(MachineRepresentation::kTagged), var_array[i],
control()));
} }
} }
......
...@@ -289,7 +289,7 @@ PeeledIteration* LoopPeeler::Peel(LoopTree::Loop* loop) { ...@@ -289,7 +289,7 @@ PeeledIteration* LoopPeeler::Peel(LoopTree::Loop* loop) {
// Change exit marker to phi. // Change exit marker to phi.
exit->InsertInput(graph_->zone(), 1, peeling.map(exit->InputAt(0))); exit->InsertInput(graph_->zone(), 1, peeling.map(exit->InputAt(0)));
NodeProperties::ChangeOp( NodeProperties::ChangeOp(
exit, common_->Phi(MachineRepresentation::kTagged, 2)); exit, common_->Phi(LoopExitValueRepresentationOf(exit->op()), 2));
break; break;
case IrOpcode::kLoopExitEffect: case IrOpcode::kLoopExitEffect:
// Change effect exit marker to effect phi. // Change effect exit marker to effect phi.
......
...@@ -144,7 +144,9 @@ class LoopPeelingTest : public GraphTest { ...@@ -144,7 +144,9 @@ class LoopPeelingTest : public GraphTest {
c.base, c.base, w->loop); c.base, c.base, w->loop);
c.add = graph()->NewNode(machine()->Int32Add(), c.phi, c.inc); c.add = graph()->NewNode(machine()->Int32Add(), c.phi, c.inc);
c.phi->ReplaceInput(1, c.add); c.phi->ReplaceInput(1, c.add);
c.exit_marker = graph()->NewNode(common()->LoopExitValue(), c.phi, w->exit); c.exit_marker = graph()->NewNode(
common()->LoopExitValue(MachineRepresentation::kTagged), c.phi,
w->exit);
return c; return c;
} }
}; };
...@@ -372,7 +374,8 @@ TEST_F(LoopPeelingTest, TwoBackedgeLoopWithPhi) { ...@@ -372,7 +374,8 @@ TEST_F(LoopPeelingTest, TwoBackedgeLoopWithPhi) {
loop->ReplaceInput(2, b2.if_false); loop->ReplaceInput(2, b2.if_false);
Node* exit = graph()->NewNode(common()->LoopExit(), b1.if_false, loop); Node* exit = graph()->NewNode(common()->LoopExit(), b1.if_false, loop);
Node* exit_marker = graph()->NewNode(common()->LoopExitValue(), phi, exit); Node* exit_marker = graph()->NewNode(
common()->LoopExitValue(MachineRepresentation::kTagged), phi, exit);
Node* r = InsertReturn(exit_marker, start(), exit); Node* r = InsertReturn(exit_marker, start(), exit);
PeeledIteration* peeled = PeelOne(); PeeledIteration* peeled = PeelOne();
...@@ -426,7 +429,8 @@ TEST_F(LoopPeelingTest, TwoBackedgeLoopWithCounter) { ...@@ -426,7 +429,8 @@ TEST_F(LoopPeelingTest, TwoBackedgeLoopWithCounter) {
loop->ReplaceInput(2, b2.if_false); loop->ReplaceInput(2, b2.if_false);
Node* exit = graph()->NewNode(common()->LoopExit(), b1.if_false, loop); Node* exit = graph()->NewNode(common()->LoopExit(), b1.if_false, loop);
Node* exit_marker = graph()->NewNode(common()->LoopExitValue(), phi, exit); Node* exit_marker = graph()->NewNode(
common()->LoopExitValue(MachineRepresentation::kTagged), phi, exit);
Node* r = InsertReturn(exit_marker, start(), exit); Node* r = InsertReturn(exit_marker, start(), exit);
PeeledIteration* peeled = PeelOne(); PeeledIteration* peeled = PeelOne();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment