diff --git a/src/compiler/backend/bitcast-elider.cc b/src/compiler/backend/bitcast-elider.cc index 263e3d691b..9a23aa5354 100644 --- a/src/compiler/backend/bitcast-elider.cc +++ b/src/compiler/backend/bitcast-elider.cc @@ -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(); } diff --git a/src/compiler/backend/bitcast-elider.h b/src/compiler/backend/bitcast-elider.h index b20d127a98..cc6b3653e6 100644 --- a/src/compiler/backend/bitcast-elider.h +++ b/src/compiler/backend/bitcast-elider.h @@ -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 to_visit_; NodeMarker seen_; + bool is_builtin_; }; } // namespace compiler diff --git a/src/compiler/machine-operator-reducer.cc b/src/compiler/machine-operator-reducer.cc index 9253c06fce..56e37fcea3 100644 --- a/src/compiler/machine-operator-reducer.cc +++ b/src/compiler/machine-operator-reducer.cc @@ -1053,7 +1053,8 @@ Reduction MachineOperatorReducer::ReduceTruncateInt64ToInt32(Node* node) { Int64Matcher m(node->InputAt(0)); if (m.HasResolvedValue()) return ReplaceInt32(static_cast(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. diff --git a/src/compiler/pipeline.cc b/src/compiler/pipeline.cc index cbc9a2eeb7..39355c85f1 100644 --- a/src/compiler/pipeline.cc +++ b/src/compiler/pipeline.cc @@ -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(); - } + Run(Builtins::IsBuiltinId(data->info()->builtin())); data->InitializeInstructionSequence(call_descriptor);