/*
* 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");
OptoReg::Name dst = ra_->get_reg_first(inst0);
MachNode* inst1 = nullptr;
OptoReg::Name src1 = OptoReg::Bad;
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) {
return false;
}
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) {
return false;
}
int inst1_index = block_index - 1;
Node* inst2;
if (imm) {
inst2 = nullptr;
} else {
inst2 = inst0->in(2);
if (inst2 == inst1) {
inst2 = inst2->in(1);
}
}
// See VM_Version::supports_fast_3op_lea()
if (!imm) {
Register rsrc1 = OptoReg::as_VMReg(src1)->as_Register();
Register rsrc2 = OptoReg::as_VMReg(ra_->get_reg_first(inst2))->as_Register();
if ((rsrc1 == rbp || rsrc1 == r13) && (rsrc2 == rbp || rsrc2 == r13)) {
return false;
}
}
// 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) {
return false;
}
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);
// Initialize the operand array
root->_opnds[0] = inst0->_opnds[0]->clone();
root->_opnds[1] = inst0->_opnds[1]->clone();
root->_opnds[2] = inst0->_opnds[2]->clone();
// Modify the block
inst0->set_removed();
inst1->set_removed();
block->remove_node(proj_index);
block->remove_node(block_index);
block->remove_node(inst1_index);
block->insert_node(root, block_index - 1);
// Modify the CFG
cfg_->map_node_to_block(inst0, nullptr);
cfg_->map_node_to_block(inst1, nullptr);
cfg_->map_node_to_block(proj, nullptr);
cfg_->map_node_to_block(root, block);
return true;
}
bool Peephole::lea_coalesce_reg(Block* block, int block_index, PhaseCFG* cfg_, PhaseRegAlloc* ra_,
MachNode* (*new_root)(), uint inst0_rule) {
return lea_coalesce_helper(block, block_index, cfg_, ra_, new_root, inst0_rule, false);
}
bool Peephole::lea_coalesce_imm(Block* block, int block_index, PhaseCFG* cfg_, PhaseRegAlloc* ra_,
MachNode* (*new_root)(), uint inst0_rule) {
return lea_coalesce_helper(block, block_index, cfg_, ra_, new_root, inst0_rule, true);
}
#endif // COMPILER2
¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.0Angebot
Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können
¤
|
Lebenszyklus
Die hierunter aufgelisteten Ziele sind für diese Firma wichtig
Ziele
Entwicklung einer Software für die statische Quellcodeanalyse
|