hotspot/src/share/vm/adlc/output_c.cpp
Print this page
rev 611 : Merge
@@ -1,10 +1,10 @@
#ifdef USE_PRAGMA_IDENT_SRC
#pragma ident "@(#)output_c.cpp 1.185 07/07/02 16:50:40 JVM"
#endif
/*
- * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1998-2008 Sun Microsystems, Inc. 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.
@@ -1547,10 +1547,22 @@
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");
+
+ // The order in which inputs are added to a node is very
+ // strange. Store nodes get a memory input before Expand is
+ // called and all other nodes get it afterwards so
+ // oper_input_base is wrong during expansion. This code adjusts
+ // is so that expansion will work correctly.
+ bool missing_memory_edge = node->_matrule->needs_ideal_memory_edge(_globalNames) &&
+ node->is_ideal_store() == Form::none;
+ if (missing_memory_edge) {
+ fprintf(fp," idx0--; // Adjust base because memory edge hasn't been inserted yet\n");
+ }
+
for( i = 0; i < node->num_opnds(); i++ ) {
fprintf(fp," unsigned idx%d = idx%d + num%d;\n",
i+1,i,i);
}
@@ -1601,15 +1613,18 @@
int memory_operand = new_inst->memory_operand(_globalNames);
if( memory_operand != InstructForm::NO_MEMORY_OPERAND ) {
int node_mem_op = node->memory_operand(_globalNames);
assert( node_mem_op != InstructForm::NO_MEMORY_OPERAND,
"expand rule member needs memory but top-level inst doesn't have any" );
+ if (!missing_memory_edge) {
// Copy memory edge
fprintf(fp," n%d->add_req(_in[1]);\t// Add memory edge\n", cnt);
}
+ }
// Iterate over the new instruction's operands
+ int prev_pos = -1;
for( expand_instr->reset(); (opid = expand_instr->iter()) != NULL; ) {
// Use 'parameter' at current position in list of new instruction's formals
// instead of 'opid' when looking up info internal to new_inst
const char *parameter = formal_lst->iter();
// Check for an operand which is created in the expand rule
@@ -1629,10 +1644,22 @@
else {
// Use operand name to get an index into instruction component list
// ins = (InstructForm *) _globalNames[new_id];
exp_pos = node->operand_position_format(opid);
assert(exp_pos != -1, "Bad expand rule");
+ if (prev_pos > exp_pos && expand_instruction->_matrule != NULL) {
+ // For the add_req calls below to work correctly they need
+ // to added in the same order that a match would add them.
+ // This means that they would need to be in the order of
+ // the components list instead of the formal parameters.
+ // This is a sort of hidden invariant that previously
+ // wasn't checked and could lead to incorrectly
+ // constructed nodes.
+ syntax_err(node->_linenum, "For expand in %s to work, parameter declaration order in %s must follow matchrule\n",
+ node->_ident, new_inst->_ident);
+ }
+ prev_pos = exp_pos;
new_pos = new_inst->operand_position(parameter,Component::USE);
if (new_pos != -1) {
// Copy the operand from the ExpandNode to the new node
fprintf(fp," n%d->set_opnd_array(%d, opnd_array(%d)->clone(C)); // %s\n",
@@ -2293,11 +2320,16 @@
void emit_rep_var(const char *rep_var) {
_processing_noninput = false;
// A replacement variable, originally '$'
if ( Opcode::as_opcode_type(rep_var) != Opcode::NOT_AN_OPCODE ) {
- _inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(rep_var) );
+ if (!_inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(rep_var) )) {
+ // Missing opcode
+ _AD.syntax_err( _inst._linenum,
+ "Missing $%s opcode definition in %s, used by encoding %s\n",
+ rep_var, _inst._ident, _encoding._name);
+ }
}
else {
// Lookup its position in parameter list
int param_no = _encoding.rep_var_index(rep_var);
if ( param_no == -1 ) {
@@ -2335,11 +2367,17 @@
_constant_status = LITERAL_OUTPUT;
}
else if( Opcode::as_opcode_type(inst_rep_var) != Opcode::NOT_AN_OPCODE ) {
// else check if "primary", "secondary", "tertiary"
assert( _constant_status == LITERAL_ACCESSED, "Must be processing a literal constant parameter");
- _inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(inst_rep_var) );
+ if (!_inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(inst_rep_var) )) {
+ // Missing opcode
+ _AD.syntax_err( _inst._linenum,
+ "Missing $%s opcode definition in %s\n",
+ rep_var, _inst._ident);
+
+ }
_constant_status = LITERAL_OUTPUT;
}
else if((_AD.get_registers() != NULL ) && (_AD.get_registers()->getRegDef(inst_rep_var) != NULL)) {
// Instruction provided a literal register name for this parameter
// Check that encoding specifies $$$reg to resolve.as register.
@@ -2364,10 +2402,12 @@
//(1)
// Output instruction's emit prototype
fprintf(fp,"uint %sNode::size(PhaseRegAlloc *ra_) const {\n",
inst._ident);
+ fprintf(fp, " assert(VerifyOops || MachNode::size(ra_) <= %s, \"bad fixed size\");\n", inst._size);
+
//(2)
// Print the size
fprintf(fp, " return (VerifyOops ? MachNode::size(ra_) : %s);\n", inst._size);
// (3) and (4)
@@ -3427,10 +3467,12 @@
&& mnode->base_operand(position, globals, result, name, optype) ) {
if ( strcmp(optype,"ConI") == 0 ) {
fprintf(fp, "_leaf->get_int()");
} else if ( (strcmp(optype,"ConP") == 0) ) {
fprintf(fp, "_leaf->bottom_type()->is_ptr()");
+ } else if ( (strcmp(optype,"ConN") == 0) ) {
+ fprintf(fp, "_leaf->bottom_type()->is_narrowoop()");
} else if ( (strcmp(optype,"ConF") == 0) ) {
fprintf(fp, "_leaf->getf()");
} else if ( (strcmp(optype,"ConD") == 0) ) {
fprintf(fp, "_leaf->getd()");
} else if ( (strcmp(optype,"ConL") == 0) ) {