[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:
parent
21de2f66e7
commit
c2a0acd47a
@ -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(); }
|
||||
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user