# HG changeset patch # User goetz # Date 1476868083 -7200 # Node ID c8efadafe85ce8b91743a9fc1920e27272612ee5 # Parent 30a0176b8af348912be80e2215a65bb758e86dab 8168283: adlc: fix error expanding expanded nodes. Reviewed-by: kvn diff -r 30a0176b8af3 -r c8efadafe85c hotspot/src/share/vm/adlc/output_c.cpp --- a/hotspot/src/share/vm/adlc/output_c.cpp Mon Oct 10 17:04:42 2016 +0200 +++ b/hotspot/src/share/vm/adlc/output_c.cpp Wed Oct 19 11:08:03 2016 +0200 @@ -1644,6 +1644,15 @@ } } // done iterating over a new instruction's operands + // Fix number of operands, as we do not generate redundant ones. + // The matcher generates some redundant operands, which are removed + // in the expand function (of the node we generate here). We don't + // generate the redundant operands here, so set the correct _num_opnds. + if (expand_instruction->num_opnds() != expand_instruction->num_unique_opnds()) { + fprintf(fp, " n%d->_num_opnds = %d; // Only unique opnds generated.\n", + cnt, expand_instruction->num_unique_opnds()); + } + // Invoke Expand() for the newly created instruction. fprintf(fp," result = n%d->Expand( state, proj_list, mem );\n", cnt); assert( !new_inst->expands(), "Do not have complete support for recursive expansion"); @@ -1722,27 +1731,30 @@ 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. + // Search through match operands for the same name usage. + // The matcher generates these non-unique operands. If the node + // was constructed by an expand rule, there are no unique operands. uint cur_num_opnds = node->num_opnds(); - if( cur_num_opnds > 1 && cur_num_opnds != node->num_unique_opnds() ) { + if (cur_num_opnds > 1 && cur_num_opnds != node->num_unique_opnds()) { Component *comp = NULL; + fprintf(fp, " // Remove duplicated operands and inputs which use the same name.\n"); + fprintf(fp, " if (num_opnds() == %d) {\n", cur_num_opnds); // 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();",i,i); + fprintf(fp," unsigned num0 = 0;\n"); + for (i = 1; i < cur_num_opnds; i++) { + fprintf(fp," unsigned num%d = opnd_array(%d)->num_edges();", i, i); fprintf(fp, " \t// %s\n", node->opnd_ident(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); + 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++ ) { + for (i = 1; i < cur_num_opnds; i++) { comp = node->_components.iter(); if (i != node->unique_opnds_idx(i)) { break; @@ -1750,28 +1762,32 @@ new_num_opnds++; } // Replace not unique operands with next unique operands. - for( ; i < cur_num_opnds; i++ ) { + for ( ; i < cur_num_opnds; i++) { comp = node->_components.iter(); uint 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()); // %s\n", + if (j != node->unique_opnds_idx(j)) { + fprintf(fp," set_opnd_array(%d, opnd_array(%d)->clone()); // %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); + // 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); + // 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?"); + fprintf(fp, " } else {\n"); + fprintf(fp, " assert(_num_opnds == %d, \"There should be either %d or %d operands.\");\n", + new_num_opnds, new_num_opnds, cur_num_opnds); + fprintf(fp, " }\n"); } }