8168283: adlc: fix error expanding expanded nodes

Reviewed-by: kvn
This commit is contained in:
Goetz Lindenmaier 2016-10-19 11:08:03 +02:00
parent bedfd21b60
commit 29654f8fe5

View File

@ -1644,6 +1644,15 @@ void ArchDesc::defineExpand(FILE *fp, InstructForm *node) {
}
} // 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,10 +1731,14 @@ 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.
// 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()) {
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++) {
@ -1735,8 +1748,7 @@ void ArchDesc::defineExpand(FILE *fp, InstructForm *node) {
// 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 idx%d = idx%d + num%d;\n", i+1, i, i);
}
uint new_num_opnds = 1;
@ -1757,7 +1769,7 @@ void ArchDesc::defineExpand(FILE *fp, InstructForm *node) {
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
// 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");
@ -1766,12 +1778,16 @@ void ArchDesc::defineExpand(FILE *fp, InstructForm *node) {
new_num_opnds++;
}
}
// delete the rest of edges
// 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");
}
}