[turbofan] Improve reduction of TruncateInt64ToInt32

When TruncateInt64ToInt32 is owned by Word32Op, it can be elided
because Word32Op automatically truncate int64 to int32.

Change-Id: Ia9dd4405f2b9b28710093dbc4c0471ea58df4e12
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4100664
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Commit-Queue: Hao A Xu <hao.a.xu@intel.com>
Cr-Commit-Position: refs/heads/main@{#85272}
This commit is contained in:
Hao Xu 2023-01-12 21:39:12 +08:00 committed by V8 LUCI CQ
parent 21de2f66e7
commit c2a0acd47a
4 changed files with 54 additions and 19 deletions

View File

@ -20,6 +20,33 @@ bool IsBitcast(Node* node) {
node->opcode() == IrOpcode::kBitcastWordToTaggedSigned;
}
bool OwnedByWord32Op(Node* node) {
for (Node* const use : node->uses()) {
switch (use->opcode()) {
case IrOpcode::kWord32Equal:
case IrOpcode::kInt32LessThan:
case IrOpcode::kInt32LessThanOrEqual:
case IrOpcode::kUint32LessThan:
case IrOpcode::kUint32LessThanOrEqual:
case IrOpcode::kChangeInt32ToInt64:
#define Word32Op(Name) case IrOpcode::k##Name:
MACHINE_BINOP_32_LIST(Word32Op)
#undef Word32Op
break;
default:
return false;
}
}
return true;
}
void Replace(Node* node, Node* replacement) {
for (Edge edge : node->use_edges()) {
edge.UpdateTo(replacement);
}
node->Kill();
}
} // namespace
void BitcastElider::Enqueue(Node* node) {
@ -28,18 +55,21 @@ void BitcastElider::Enqueue(Node* node) {
to_visit_.push(node);
}
void BitcastElider::Revisit(Node* node) { to_visit_.push(node); }
void BitcastElider::VisitNode(Node* node) {
for (int i = 0; i < node->InputCount(); i++) {
Node* input = node->InputAt(i);
bool should_replace_input = false;
while (IsBitcast(input)) {
input = input->InputAt(0);
should_replace_input = true;
if (input->opcode() == IrOpcode::kTruncateInt64ToInt32 &&
OwnedByWord32Op(input)) {
Replace(input, input->InputAt(0));
Revisit(node);
} else if (is_builtin_ && IsBitcast(input)) {
Replace(input, input->InputAt(0));
Revisit(node);
} else {
Enqueue(input);
}
if (should_replace_input) {
node->ReplaceInput(i, input);
}
Enqueue(input);
}
}
@ -52,8 +82,11 @@ void BitcastElider::ProcessGraph() {
}
}
BitcastElider::BitcastElider(Zone* zone, Graph* graph)
: graph_(graph), to_visit_(zone), seen_(graph, 2) {}
BitcastElider::BitcastElider(Zone* zone, Graph* graph, bool is_builtin)
: graph_(graph),
to_visit_(zone),
seen_(graph, 2),
is_builtin_(is_builtin) {}
void BitcastElider::Reduce() { ProcessGraph(); }

View File

@ -15,16 +15,18 @@ namespace compiler {
class Graph;
// Elide all the Bitcast nodes which are required by MachineGraphVerifier. This
// avoid generating redundant move instructions in instruction selection phase.
// Elide all the Bitcast and TruncateInt64ToInt32 nodes which are required by
// MachineGraphVerifier. This avoid generating redundant move instructions in
// instruction selection phase.
class BitcastElider {
public:
BitcastElider(Zone* zone, Graph* graph);
BitcastElider(Zone* zone, Graph* graph, bool is_builtin);
~BitcastElider() = default;
void Reduce();
void Enqueue(Node* node);
void Revisit(Node* node);
void VisitNode(Node* node);
void ProcessGraph();
@ -32,6 +34,7 @@ class BitcastElider {
Graph* const graph_;
ZoneQueue<Node*> to_visit_;
NodeMarker<bool> seen_;
bool is_builtin_;
};
} // namespace compiler

View File

@ -1053,7 +1053,8 @@ Reduction MachineOperatorReducer::ReduceTruncateInt64ToInt32(Node* node) {
Int64Matcher m(node->InputAt(0));
if (m.HasResolvedValue())
return ReplaceInt32(static_cast<int32_t>(m.ResolvedValue()));
if (m.IsChangeInt32ToInt64()) return Replace(m.node()->InputAt(0));
if (m.IsChangeInt32ToInt64() || m.IsChangeUint32ToUint64())
return Replace(m.node()->InputAt(0));
// TruncateInt64ToInt32(BitcastTaggedToWordForTagAndSmiBits(Load(x))) =>
// Load(x)
// where the new Load uses Int32 rather than the tagged representation.

View File

@ -2487,8 +2487,8 @@ struct InstructionSelectionPhase {
struct BitcastElisionPhase {
DECL_PIPELINE_PHASE_CONSTANTS(BitcastElision)
void Run(PipelineData* data, Zone* temp_zone) {
BitcastElider bitcast_optimizer(temp_zone, data->graph());
void Run(PipelineData* data, Zone* temp_zone, bool is_builtin) {
BitcastElider bitcast_optimizer(temp_zone, data->graph(), is_builtin);
bitcast_optimizer.Reduce();
}
};
@ -3930,9 +3930,7 @@ bool PipelineImpl::SelectInstructions(Linkage* linkage) {
data->debug_name(), &temp_zone);
}
if (Builtins::IsBuiltinId(data->info()->builtin())) {
Run<BitcastElisionPhase>();
}
Run<BitcastElisionPhase>(Builtins::IsBuiltinId(data->info()->builtin()));
data->InitializeInstructionSequence(call_descriptor);