提交 fd6737f7 编写于 作者: K kvn

7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()

Summary: Add TEMP edges (and KILL projections) before duplicated operands are removed in Expand() methods.
Reviewed-by: never
上级 f9145c84
......@@ -8125,6 +8125,17 @@ instruct convP2B( iRegI dst, iRegP src ) %{
%}
#endif
instruct cmpLTMask0( iRegI dst, iRegI src, immI0 zero, flagsReg ccr ) %{
match(Set dst (CmpLTMask src zero));
effect(KILL ccr);
size(4);
format %{ "SRA $src,#31,$dst\t# cmpLTMask0" %}
ins_encode %{
__ sra($src$$Register, 31, $dst$$Register);
%}
ins_pipe(ialu_reg_imm);
%}
instruct cmpLTMask_reg_reg( iRegI dst, iRegI p, iRegI q, flagsReg ccr ) %{
match(Set dst (CmpLTMask p q));
effect( KILL ccr );
......@@ -8144,19 +8155,7 @@ instruct cadd_cmpLTMask( iRegI p, iRegI q, iRegI y, iRegI tmp, flagsReg ccr ) %{
format %{ "SUBcc $p,$q,$p\t! p' = p-q\n\t"
"ADD $p,$y,$tmp\t! g3=p-q+y\n\t"
"MOVl $tmp,$p\t! p' < 0 ? p'+y : p'" %}
ins_encode( enc_cadd_cmpLTMask(p, q, y, tmp) );
ins_pipe( cadd_cmpltmask );
%}
instruct cadd_cmpLTMask2( iRegI p, iRegI q, iRegI y, iRegI tmp, flagsReg ccr ) %{
match(Set p (AddI (SubI p q) (AndI (CmpLTMask p q) y)));
effect( KILL ccr, TEMP tmp);
ins_cost(DEFAULT_COST*3);
format %{ "SUBcc $p,$q,$p\t! p' = p-q\n\t"
"ADD $p,$y,$tmp\t! g3=p-q+y\n\t"
"MOVl $tmp,$p\t! p' < 0 ? p'+y : p'" %}
"MOVlt $tmp,$p\t! p' < 0 ? p'+y : p'" %}
ins_encode( enc_cadd_cmpLTMask(p, q, y, tmp) );
ins_pipe( cadd_cmpltmask );
%}
......
......@@ -1698,61 +1698,6 @@ void ArchDesc::defineExpand(FILE *fp, InstructForm *node) {
fprintf(fp,"\n");
} // done generating expand rule
else if( node->_matrule != NULL ) {
// Remove duplicated operands and inputs which use the same name.
// Seach through match operands for the same name usage.
uint cur_num_opnds = node->num_opnds();
if( cur_num_opnds > 1 && cur_num_opnds != node->num_unique_opnds() ) {
Component *comp = NULL;
// Build mapping from num_edges to local variables
fprintf(fp," unsigned num0 = 0;\n");
for( i = 1; i < cur_num_opnds; i++ ) {
fprintf(fp," unsigned num%d = opnd_array(%d)->num_edges();\n",i,i);
}
// Build a mapping from operand index to input edges
fprintf(fp," unsigned idx0 = oper_input_base();\n");
for( i = 0; i < cur_num_opnds; i++ ) {
fprintf(fp," unsigned idx%d = idx%d + num%d;\n",
i+1,i,i);
}
uint new_num_opnds = 1;
node->_components.reset();
// Skip first unique operands.
for( i = 1; i < cur_num_opnds; i++ ) {
comp = node->_components.iter();
if( (int)i != node->unique_opnds_idx(i) ) {
break;
}
new_num_opnds++;
}
// Replace not unique operands with next unique operands.
for( ; i < cur_num_opnds; i++ ) {
comp = node->_components.iter();
int j = node->unique_opnds_idx(i);
// unique_opnds_idx(i) is unique if unique_opnds_idx(j) is not unique.
if( j != node->unique_opnds_idx(j) ) {
fprintf(fp," set_opnd_array(%d, opnd_array(%d)->clone(C)); // %s\n",
new_num_opnds, i, comp->_name);
// delete not unique edges here
fprintf(fp," for(unsigned i = 0; i < num%d; i++) {\n", i);
fprintf(fp," set_req(i + idx%d, _in[i + idx%d]);\n", new_num_opnds, i);
fprintf(fp," }\n");
fprintf(fp," num%d = num%d;\n", new_num_opnds, i);
fprintf(fp," idx%d = idx%d + num%d;\n", new_num_opnds+1, new_num_opnds, new_num_opnds);
new_num_opnds++;
}
}
// delete the rest of edges
fprintf(fp," for(int i = idx%d - 1; i >= (int)idx%d; i--) {\n", cur_num_opnds, new_num_opnds);
fprintf(fp," del_req(i);\n");
fprintf(fp," }\n");
fprintf(fp," _num_opnds = %d;\n", new_num_opnds);
assert(new_num_opnds == node->num_unique_opnds(), "what?");
}
}
// Generate projections for instruction's additional DEFs and KILLs
if( ! node->expands() && (node->needs_projections() || node->has_temps())) {
// Get string representing the MachNode that projections point at
......@@ -1786,9 +1731,12 @@ void ArchDesc::defineExpand(FILE *fp, InstructForm *node) {
fprintf(fp," def = new (C) MachTempNode(state->MachOperGenerator( %s, C ));\n",
machOperEnum(op->_ident));
fprintf(fp," add_req(def);\n");
int idx = node->operand_position_format(comp->_name);
fprintf(fp," set_opnd_array(%d, state->MachOperGenerator( %s, C ));\n",
idx, machOperEnum(op->_ident));
// The operand for TEMP is already constructed during
// this mach node construction, see buildMachNode().
//
// int idx = node->operand_position_format(comp->_name);
// fprintf(fp," set_opnd_array(%d, state->MachOperGenerator( %s, C ));\n",
// idx, machOperEnum(op->_ident));
} else {
assert(false, "can't have temps which aren't registers");
}
......@@ -1818,6 +1766,60 @@ void ArchDesc::defineExpand(FILE *fp, InstructForm *node) {
}
}
if( !node->expands() && node->_matrule != NULL ) {
// Remove duplicated operands and inputs which use the same name.
// Seach through match operands for the same name usage.
uint cur_num_opnds = node->num_opnds();
if( cur_num_opnds > 1 && cur_num_opnds != node->num_unique_opnds() ) {
Component *comp = NULL;
// Build mapping from num_edges to local variables
fprintf(fp," unsigned num0 = 0;\n");
for( i = 1; i < cur_num_opnds; i++ ) {
fprintf(fp," unsigned num%d = opnd_array(%d)->num_edges();\n",i,i);
}
// Build a mapping from operand index to input edges
fprintf(fp," unsigned idx0 = oper_input_base();\n");
for( i = 0; i < cur_num_opnds; i++ ) {
fprintf(fp," unsigned idx%d = idx%d + num%d;\n",
i+1,i,i);
}
uint new_num_opnds = 1;
node->_components.reset();
// Skip first unique operands.
for( i = 1; i < cur_num_opnds; i++ ) {
comp = node->_components.iter();
if( (int)i != node->unique_opnds_idx(i) ) {
break;
}
new_num_opnds++;
}
// Replace not unique operands with next unique operands.
for( ; i < cur_num_opnds; i++ ) {
comp = node->_components.iter();
int j = node->unique_opnds_idx(i);
// unique_opnds_idx(i) is unique if unique_opnds_idx(j) is not unique.
if( j != node->unique_opnds_idx(j) ) {
fprintf(fp," set_opnd_array(%d, opnd_array(%d)->clone(C)); // %s\n",
new_num_opnds, i, comp->_name);
// delete not unique edges here
fprintf(fp," for(unsigned i = 0; i < num%d; i++) {\n", i);
fprintf(fp," set_req(i + idx%d, _in[i + idx%d]);\n", new_num_opnds, i);
fprintf(fp," }\n");
fprintf(fp," num%d = num%d;\n", new_num_opnds, i);
fprintf(fp," idx%d = idx%d + num%d;\n", new_num_opnds+1, new_num_opnds, new_num_opnds);
new_num_opnds++;
}
}
// delete the rest of edges
fprintf(fp," for(int i = idx%d - 1; i >= (int)idx%d; i--) {\n", cur_num_opnds, new_num_opnds);
fprintf(fp," del_req(i);\n");
fprintf(fp," }\n");
fprintf(fp," _num_opnds = %d;\n", new_num_opnds);
assert(new_num_opnds == node->num_unique_opnds(), "what?");
}
}
// If the node is a MachConstantNode, insert the MachConstantBaseNode edge.
// NOTE: this edge must be the last input (see MachConstantNode::mach_constant_base_node_input).
if (node->is_mach_constant()) {
......@@ -3776,12 +3778,10 @@ void ArchDesc::buildMachNode(FILE *fp_cpp, InstructForm *inst, const char *inden
}
dont_care = true;
// For each operand not in the match rule, call MachOperGenerator
// with the enum for the opcode that needs to be built
// and the node just built, the parent of the operand.
// with the enum for the opcode that needs to be built.
ComponentList clist = inst->_components;
int index = clist.operand_position(comp->_name, comp->_usedef);
const char *opcode = machOperEnum(comp->_type);
const char *parent = "node";
fprintf(fp_cpp, "%s node->set_opnd_array(%d, ", indent, index);
fprintf(fp_cpp, "MachOperGenerator(%s, C));\n", opcode);
}
......
......@@ -743,6 +743,9 @@ void Node::add_req_batch( Node *n, uint m ) {
//------------------------------del_req----------------------------------------
// Delete the required edge and compact the edge array
void Node::del_req( uint idx ) {
assert( idx < _cnt, "oob");
assert( !VerifyHashTableKeys || _hash_lock == 0,
"remove node from hash table before modifying it");
// First remove corresponding def-use edge
Node *n = in(idx);
if (n != NULL) n->del_out((Node *)this);
......
/*
* Copyright (c) 2011, 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.
*/
/**
* @test
* @bug 7017746
* @summary Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
*
* @run main/othervm -Xbatch Test
*/
public class Test {
int i;
static int test(Test t, int a, int b) {
int j = t.i;
int x = a - b;
if (a < b) x = x + j;
return x - j;
}
public static void main(String args[]) {
Test t = new Test();
for (int n = 0; n < 1000000; n++) {
int i = test(t, 1, 2);
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册