/* * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. *
*/ #include"precompiled.hpp"
#ifdef COMPILER2
#include"peephole_x86_64.hpp"
// This function transforms the shapes // mov d, s1; add d, s2 into // lea d, [s1 + s2] and // mov d, s1; shl d, s2 into // lea d, [s1 << s2] with s2 = 1, 2, 3 bool lea_coalesce_helper(Block* block, int block_index, PhaseCFG* cfg_, PhaseRegAlloc* ra_,
MachNode* (*new_root)(), uint inst0_rule, bool imm) {
MachNode* inst0 = block->get_node(block_index)->as_Mach();
assert(inst0->rule() == inst0_rule, "sanity");
if (inst0->in(1)->is_MachSpillCopy()) {
OptoReg::Name in = ra_->get_reg_first(inst0->in(1)->in(1)); if (OptoReg::is_reg(in) && OptoReg::as_VMReg(in)->is_Register()) {
inst1 = inst0->in(1)->as_Mach();
src1 = in;
}
} if (inst1 == nullptr) { returnfalse;
}
assert(dst != src1, "");
// Only coalesce if inst1 is immediately followed by inst0 // Can be improved for more general cases if (block_index < 1 || block->get_node(block_index - 1) != inst1) { returnfalse;
} int inst1_index = block_index - 1;
Node* inst2; if (imm) {
inst2 = nullptr;
} else {
inst2 = inst0->in(2); if (inst2 == inst1) {
inst2 = inst2->in(1);
}
}
// Go down the block to find the output proj node (the flag output) of inst0 int proj_index = -1;
Node* proj = nullptr; for (uint pos = block_index + 1; pos < block->number_of_nodes(); pos++) {
Node* curr = block->get_node(pos); if (curr->is_MachProj() && curr->in(0) == inst0) {
proj_index = pos;
proj = curr; break;
}
}
assert(proj != nullptr, ""); // If some node uses the flag, cannot remove if (proj->outcnt() > 0) { returnfalse;
}
MachNode* root = new_root(); // Assign register for the newly allocated node
ra_->set_oop(root, ra_->is_oop(inst0));
ra_->set_pair(root->_idx, ra_->get_reg_second(inst0), ra_->get_reg_first(inst0));
// Set input and output for the node
root->add_req(inst0->in(0));
root->add_req(inst1->in(1)); // No input for constant after matching if (!imm) {
root->add_req(inst2);
}
inst0->replace_by(root);
proj->set_req(0, inst0);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.