# HG changeset patch # User kvn # Date 1349824171 25200 # Node ID d336b3173277febb8b26045b64d1784ddcf4d1b0 # Parent f6badecb7ea70d35c9b4d4e8da1bf1a8c9239577 8000592: Improve adlc usability Summary: several changes to adlc to improve its usability Reviewed-by: kvn Contributed-by: goetz.lindenmaier@sap.com diff -r f6badecb7ea7 -r d336b3173277 src/share/vm/adlc/adlparse.cpp --- a/src/share/vm/adlc/adlparse.cpp Tue Oct 09 12:40:05 2012 -0700 +++ b/src/share/vm/adlc/adlparse.cpp Tue Oct 09 16:09:31 2012 -0700 @@ -1392,7 +1392,7 @@ _AD.addForm(machnode); } else if (!strcmp(ident, "attributes")) { - bool vsi_seen = false, bhds_seen = false; + bool vsi_seen = false; skipws(); if ( (_curchar != '%') @@ -1436,7 +1436,6 @@ } pipeline->_branchHasDelaySlot = true; - bhds_seen = true; continue; } @@ -1639,6 +1638,12 @@ next_char(); // Skip "(" or "," ident = get_ident(); // Grab next identifier + if (_AD._adl_debug > 1) { + if (ident != NULL) { + fprintf(stderr, "resource_parse: identifier: %s\n", ident); + } + } + if (ident == NULL) { parse_err(SYNERR, "keyword identifier expected at \"%c\"\n", _curchar); return; @@ -2427,7 +2432,6 @@ int lparen = 0; // keep track of parenthesis nesting depth int rparen = 0; // position of instruction at this depth InstructForm *inst_seen = NULL; - InstructForm *child_seen = NULL; // Walk the match tree, // Record @@ -2437,7 +2441,7 @@ if (_curchar == '(') { ++lparen; next_char(); - child_seen = peep_match_child_parse(match, parent, position, rparen); + ( void ) peep_match_child_parse(match, parent, position, rparen); } // Right paren signals end of an input, may be more else if (_curchar == ')') { @@ -3154,6 +3158,9 @@ //------------------------------size_parse----------------------------------- +// Parse a 'size()' attribute which specifies the size of the +// emitted instructions in bytes. can be a C++ expression, +// e.g. a constant. char* ADLParser::size_parse(InstructForm *instr) { char* sizeOfInstr = NULL; @@ -4274,7 +4281,17 @@ || ((c >= '0') && (c <= '9')) || ((c == '_')) || ((c == ':')) || ((c == '#')) ); if (start == end) { // We popped out on the first try - parse_err(SYNERR, "identifier expected at %c\n", c); + // It can occur that `start' contains the rest of the input file. + // In this case the output should be truncated. + if (strlen(start) > 24) { + char buf[32]; + strncpy(buf, start, 20); + buf[20] = '\0'; + strcat(buf, "[...]"); + parse_err(SYNERR, "Identifier expected, but found '%s'.", buf); + } else { + parse_err(SYNERR, "Identifier expected, but found '%s'.", start); + } start = NULL; } else { diff -r f6badecb7ea7 -r d336b3173277 src/share/vm/adlc/archDesc.cpp --- a/src/share/vm/adlc/archDesc.cpp Tue Oct 09 12:40:05 2012 -0700 +++ b/src/share/vm/adlc/archDesc.cpp Tue Oct 09 16:09:31 2012 -0700 @@ -221,6 +221,7 @@ _register = NULL; _encode = NULL; _pipeline = NULL; + _frame = NULL; } ArchDesc::~ArchDesc() { @@ -648,7 +649,10 @@ // Return the textual binding for a given CPP flag name. // Return NULL if there is no binding, or it has been #undef-ed. char* ArchDesc::get_preproc_def(const char* flag) { - SourceForm* deff = (SourceForm*) _preproc_table[flag]; + // In case of syntax errors, flag may take the value NULL. + SourceForm* deff = NULL; + if (flag != NULL) + deff = (SourceForm*) _preproc_table[flag]; return (deff == NULL) ? NULL : deff->_code; } @@ -803,7 +807,9 @@ while (i++ <= 15) fputc(' ', errfile); fprintf(errfile, "%-8s:", pref); vfprintf(errfile, fmt, args); - fprintf(errfile, "\n"); } + fprintf(errfile, "\n"); + fflush(errfile); + } return 1; } @@ -855,8 +861,14 @@ // Check constraints on result's register class const char *result_class = opForm.constrained_reg_class(); - if (!result_class) opForm.dump(); - assert( result_class, "Resulting register class was not defined for operand"); + if (result_class == NULL) { + opForm.dump(); + syntax_err(opForm._linenum, + "Use of an undefined result class for operand: %s", + opForm._ident); + abort(); + } + regMask = reg_class_to_reg_mask( result_class ); return regMask; @@ -865,8 +877,14 @@ // Obtain the name of the RegMask for an InstructForm const char *ArchDesc::reg_mask(InstructForm &inForm) { const char *result = inForm.reduce_result(); - assert( result, - "Did not find result operand or RegMask for this instruction"); + + if (result == NULL) { + syntax_err(inForm._linenum, + "Did not find result operand or RegMask" + " for this instruction: %s", + inForm._ident); + abort(); + } // Instructions producing 'Universe' use RegMask::Empty if( strcmp(result,"Universe")==0 ) { @@ -875,10 +893,17 @@ // Lookup this result operand and get its register class Form *form = (Form*)_globalNames[result]; - assert( form, "Result operand must be defined"); + if (form == NULL) { + syntax_err(inForm._linenum, + "Did not find result operand for result: %s", result); + abort(); + } OperandForm *oper = form->is_operand(); - if (oper == NULL) form->dump(); - assert( oper, "Result must be an OperandForm"); + if (oper == NULL) { + syntax_err(inForm._linenum, "Form is not an OperandForm:"); + form->dump(); + abort(); + } return reg_mask( *oper ); } @@ -887,7 +912,13 @@ char *ArchDesc::stack_or_reg_mask(OperandForm &opForm) { // name of cisc_spillable version const char *reg_mask_name = reg_mask(opForm); - assert( reg_mask_name != NULL, "called with incorrect opForm"); + + if (reg_mask_name == NULL) { + syntax_err(opForm._linenum, + "Did not find reg_mask for opForm: %s", + opForm._ident); + abort(); + } const char *stack_or = "STACK_OR_"; int length = (int)strlen(stack_or) + (int)strlen(reg_mask_name) + 1; diff -r f6badecb7ea7 -r d336b3173277 src/share/vm/adlc/archDesc.hpp --- a/src/share/vm/adlc/archDesc.hpp Tue Oct 09 12:40:05 2012 -0700 +++ b/src/share/vm/adlc/archDesc.hpp Tue Oct 09 16:09:31 2012 -0700 @@ -365,13 +365,14 @@ // A derived class defines the appropriate output for a specific mapping. class OutputMap { protected: - FILE *_hpp; - FILE *_cpp; - FormDict &_globals; - ArchDesc &_AD; + FILE *_hpp; + FILE *_cpp; + FormDict &_globals; + ArchDesc &_AD; + const char *_name; public: - OutputMap (FILE *decl_file, FILE *def_file, FormDict &globals, ArchDesc &AD) - : _hpp(decl_file), _cpp(def_file), _globals(globals), _AD(AD) {}; + OutputMap (FILE *decl_file, FILE *def_file, FormDict &globals, ArchDesc &AD, const char *name) + : _hpp(decl_file), _cpp(def_file), _globals(globals), _AD(AD), _name(name) {}; // Access files used by this routine FILE *decl_file() { return _hpp; } FILE *def_file() { return _cpp; } diff -r f6badecb7ea7 -r d336b3173277 src/share/vm/adlc/dict2.cpp --- a/src/share/vm/adlc/dict2.cpp Tue Oct 09 12:40:05 2012 -0700 +++ b/src/share/vm/adlc/dict2.cpp Tue Oct 09 16:09:31 2012 -0700 @@ -33,7 +33,7 @@ // String hash tables #define MAXID 20 static char initflag = 0; // True after 1st initialization -static char shft[MAXID] = {1,2,3,4,5,6,7,1,2,3,4,5,6,7,1,2,3,4,5,6}; +static char shft[MAXID + 1] = {1,2,3,4,5,6,7,1,2,3,4,5,6,7,1,2,3,4,5,6,7}; static short xsum[MAXID]; //------------------------------bucket--------------------------------------- diff -r f6badecb7ea7 -r d336b3173277 src/share/vm/adlc/filebuff.hpp --- a/src/share/vm/adlc/filebuff.hpp Tue Oct 09 12:40:05 2012 -0700 +++ b/src/share/vm/adlc/filebuff.hpp Tue Oct 09 16:09:31 2012 -0700 @@ -31,10 +31,14 @@ using namespace std; // STRUCTURE FOR HANDLING INPUT AND OUTPUT FILES -typedef struct { + +class BufferedFile { + public: const char *_name; FILE *_fp; -} BufferedFile; + inline BufferedFile() { _name = NULL; _fp = NULL; }; + inline ~BufferedFile() {}; +}; class ArchDesc; diff -r f6badecb7ea7 -r d336b3173277 src/share/vm/adlc/forms.hpp --- a/src/share/vm/adlc/forms.hpp Tue Oct 09 12:40:05 2012 -0700 +++ b/src/share/vm/adlc/forms.hpp Tue Oct 09 16:09:31 2012 -0700 @@ -449,11 +449,11 @@ // Return number of USEs + number of DEFs int num_operands(); // Return zero-based position in list; -1 if not in list. - int operand_position(const char *name, int usedef); + int operand_position(const char *name, int usedef, Form *fm); // Find position for this name, regardless of use/def information int operand_position(const char *name); // Find position for this name when looked up for output via "format" - int operand_position_format(const char *name); + int operand_position_format(const char *name, Form *fm); // Find position for the Label when looked up for output via "format" int label_position(); // Find position for the Method when looked up for output via "format" diff -r f6badecb7ea7 -r d336b3173277 src/share/vm/adlc/formssel.cpp --- a/src/share/vm/adlc/formssel.cpp Tue Oct 09 12:40:05 2012 -0700 +++ b/src/share/vm/adlc/formssel.cpp Tue Oct 09 16:09:31 2012 -0700 @@ -567,7 +567,7 @@ if( strcmp(rc_name,"stack_slots") ) { // Check for ideal_type of RegFlags const char *type = opform->ideal_type( globals, registers ); - if( !strcmp(type,"RegFlags") ) + if( (type != NULL) && !strcmp(type, "RegFlags") ) rematerialize = true; } else rematerialize = false; // Do not rematerialize things target stk @@ -795,6 +795,20 @@ return num_opnds; } +const char *InstructForm::opnd_ident(int idx) { + return _components.at(idx)->_name; +} + +const char *InstructForm::unique_opnd_ident(int idx) { + uint i; + for (i = 1; i < num_opnds(); ++i) { + if (unique_opnds_idx(i) == idx) { + break; + } + } + return (_components.at(i) != NULL) ? _components.at(i)->_name : ""; +} + // Return count of unmatched operands. uint InstructForm::num_post_match_opnds() { uint num_post_match_opnds = _components.count(); @@ -866,6 +880,9 @@ return base; } +// This function determines the order of the MachOper in _opnds[] +// by writing the operand names into the _components list. +// // Implementation does not modify state of internal structures void InstructForm::build_components() { // Add top-level operands to the components @@ -961,11 +978,11 @@ // Return zero-based position in component list; -1 if not in list. int InstructForm::operand_position(const char *name, int usedef) { - return unique_opnds_idx(_components.operand_position(name, usedef)); + return unique_opnds_idx(_components.operand_position(name, usedef, this)); } int InstructForm::operand_position_format(const char *name) { - return unique_opnds_idx(_components.operand_position_format(name)); + return unique_opnds_idx(_components.operand_position_format(name, this)); } // Return zero-based position in component list; -1 if not in list. @@ -1225,7 +1242,7 @@ if (different) { globalAD->syntax_err(short_branch->_linenum, "Instruction %s and its short form %s have different parameters\n", _ident, short_branch->_ident); } - if (AD._short_branch_debug) { + if (AD._adl_debug > 1 || AD._short_branch_debug) { fprintf(stderr, "Instruction %s has short form %s\n", _ident, short_branch->_ident); } _short_branch_form = short_branch; @@ -1257,16 +1274,19 @@ // Find replacement variable's type const Form *form = _localNames[rep_var]; if (form == NULL) { - fprintf(stderr, "unknown replacement variable in format statement: '%s'\n", rep_var); - assert(false, "ShouldNotReachHere()"); + globalAD->syntax_err(_linenum, "Unknown replacement variable %s in format statement of %s.", + rep_var, _ident); + return; } OpClassForm *opc = form->is_opclass(); assert( opc, "replacement variable was not found in local names"); // Lookup the index position of the replacement variable int idx = operand_position_format(rep_var); if ( idx == -1 ) { - assert( strcmp(opc->_ident,"label")==0, "Unimplemented"); - assert( false, "ShouldNotReachHere()"); + globalAD->syntax_err(_linenum, "Could not find replacement variable %s in format statement of %s.\n", + rep_var, _ident); + assert(strcmp(opc->_ident, "label") == 0, "Unimplemented"); + return; } if (is_noninput_operand(idx)) { @@ -1275,7 +1295,7 @@ OperandForm* oper = form->is_operand(); if (oper != NULL && oper->is_bound_register()) { const RegDef* first = oper->get_RegClass()->find_first_elem(); - fprintf(fp, " tty->print(\"%s\");\n", first->_regname); + fprintf(fp, " st->print(\"%s\");\n", first->_regname); } else { globalAD->syntax_err(_linenum, "In %s can't find format for %s %s", _ident, opc->_ident, rep_var); } @@ -1373,26 +1393,28 @@ // idx0=0 is used to indicate that info comes from this same node, not from input edge. // idx1 starts at oper_input_base() if ( cur_num_opnds >= 1 ) { - fprintf(fp," // Start at oper_input_base() and count operands\n"); - fprintf(fp," unsigned %sidx0 = %d;\n", prefix, oper_input_base(globals)); - fprintf(fp," unsigned %sidx1 = %d;\n", prefix, oper_input_base(globals)); + fprintf(fp," // Start at oper_input_base() and count operands\n"); + fprintf(fp," unsigned %sidx0 = %d;\n", prefix, oper_input_base(globals)); + fprintf(fp," unsigned %sidx1 = %d;", prefix, oper_input_base(globals)); + fprintf(fp," \t// %s\n", unique_opnd_ident(1)); // Generate starting points for other unique operands if they exist for ( idx = 2; idx < num_unique_opnds(); ++idx ) { if( *receiver == 0 ) { - fprintf(fp," unsigned %sidx%d = %sidx%d + opnd_array(%d)->num_edges();\n", + fprintf(fp," unsigned %sidx%d = %sidx%d + opnd_array(%d)->num_edges();", prefix, idx, prefix, idx-1, idx-1 ); } else { - fprintf(fp," unsigned %sidx%d = %sidx%d + %s_opnds[%d]->num_edges();\n", + fprintf(fp," unsigned %sidx%d = %sidx%d + %s_opnds[%d]->num_edges();", prefix, idx, prefix, idx-1, receiver, idx-1 ); } + fprintf(fp," \t// %s\n", unique_opnd_ident(idx)); } } if( *receiver != 0 ) { // This value is used by generate_peepreplace when copying a node. // Don't emit it in other cases since it can hide bugs with the // use invalid idx's. - fprintf(fp," unsigned %sidx%d = %sreq(); \n", prefix, idx, receiver); + fprintf(fp," unsigned %sidx%d = %sreq(); \n", prefix, idx, receiver); } } @@ -1776,9 +1798,25 @@ return Component::INVALID; } +const char *Component::getUsedefName() { + switch (_usedef) { + case Component::INVALID: return "INVALID"; break; + case Component::USE: return "USE"; break; + case Component::USE_DEF: return "USE_DEF"; break; + case Component::USE_KILL: return "USE_KILL"; break; + case Component::KILL: return "KILL"; break; + case Component::TEMP: return "TEMP"; break; + case Component::DEF: return "DEF"; break; + case Component::CALL: return "CALL"; break; + default: assert(false, "unknown effect"); + } + return "Undefined Use/Def info"; +} + Effect::Effect(const char *name) : _name(name), _use_def(effect_lookup(name)) { _ftype = Form::EFF; } + Effect::~Effect() { } @@ -2275,7 +2313,7 @@ } int OperandForm::operand_position(const char *name, int usedef) { - return _components.operand_position(name, usedef); + return _components.operand_position(name, usedef, this); } @@ -2401,20 +2439,20 @@ if (_matrule && (_matrule->is_base_register(globals) || strcmp(ideal_type(globalAD->globalNames()), "RegFlags") == 0)) { // !!!!! !!!!! - fprintf(fp, "{ char reg_str[128];\n"); - fprintf(fp," ra->dump_register(node,reg_str);\n"); - fprintf(fp," tty->print(\"%cs\",reg_str);\n",'%'); - fprintf(fp," }\n"); + fprintf(fp," { char reg_str[128];\n"); + fprintf(fp," ra->dump_register(node,reg_str);\n"); + fprintf(fp," st->print(\"%cs\",reg_str);\n",'%'); + fprintf(fp," }\n"); } else if (_matrule && (dtype = _matrule->is_base_constant(globals)) != Form::none) { format_constant( fp, index, dtype ); } else if (ideal_to_sReg_type(_ident) != Form::none) { // Special format for Stack Slot Register - fprintf(fp, "{ char reg_str[128];\n"); - fprintf(fp," ra->dump_register(node,reg_str);\n"); - fprintf(fp," tty->print(\"%cs\",reg_str);\n",'%'); - fprintf(fp," }\n"); + fprintf(fp," { char reg_str[128];\n"); + fprintf(fp," ra->dump_register(node,reg_str);\n"); + fprintf(fp," st->print(\"%cs\",reg_str);\n",'%'); + fprintf(fp," }\n"); } else { - fprintf(fp,"tty->print(\"No format defined for %s\n\");\n", _ident); + fprintf(fp," st->print(\"No format defined for %s\n\");\n", _ident); fflush(fp); fprintf(stderr,"No format defined for %s\n", _ident); dump(); @@ -2428,37 +2466,37 @@ Form::DataType dtype; if (_matrule && (_matrule->is_base_register(globals) || strcmp(ideal_type(globalAD->globalNames()), "RegFlags") == 0)) { - fprintf(fp, "{ char reg_str[128];\n"); - fprintf(fp," ra->dump_register(node->in(idx"); - if ( index != 0 ) fprintf(fp, "+%d",index); - fprintf(fp, "),reg_str);\n"); - fprintf(fp," tty->print(\"%cs\",reg_str);\n",'%'); - fprintf(fp," }\n"); + fprintf(fp," { char reg_str[128];\n"); + fprintf(fp," ra->dump_register(node->in(idx"); + if ( index != 0 ) fprintf(fp, "+%d",index); + fprintf(fp, "),reg_str);\n"); + fprintf(fp," st->print(\"%cs\",reg_str);\n",'%'); + fprintf(fp," }\n"); } else if (_matrule && (dtype = _matrule->is_base_constant(globals)) != Form::none) { format_constant( fp, index, dtype ); } else if (ideal_to_sReg_type(_ident) != Form::none) { // Special format for Stack Slot Register - fprintf(fp, "{ char reg_str[128];\n"); - fprintf(fp," ra->dump_register(node->in(idx"); + fprintf(fp," { char reg_str[128];\n"); + fprintf(fp," ra->dump_register(node->in(idx"); if ( index != 0 ) fprintf(fp, "+%d",index); fprintf(fp, "),reg_str);\n"); - fprintf(fp," tty->print(\"%cs\",reg_str);\n",'%'); - fprintf(fp," }\n"); + fprintf(fp," st->print(\"%cs\",reg_str);\n",'%'); + fprintf(fp," }\n"); } else { - fprintf(fp,"tty->print(\"No format defined for %s\n\");\n", _ident); + fprintf(fp," st->print(\"No format defined for %s\n\");\n", _ident); assert( false,"Internal error:\n output_external_operand() attempting to output other than a Register or Constant"); } } void OperandForm::format_constant(FILE *fp, uint const_index, uint const_type) { switch(const_type) { - case Form::idealI: fprintf(fp,"st->print(\"#%%d\", _c%d);\n", const_index); break; - case Form::idealP: fprintf(fp,"_c%d->dump_on(st);\n", const_index); break; + case Form::idealI: fprintf(fp," st->print(\"#%%d\", _c%d);\n", const_index); break; + case Form::idealP: fprintf(fp," if (_c%d) _c%d->dump_on(st);\n", const_index, const_index); break; case Form::idealNKlass: - case Form::idealN: fprintf(fp,"_c%d->dump_on(st);\n", const_index); break; - case Form::idealL: fprintf(fp,"st->print(\"#%%lld\", _c%d);\n", const_index); break; - case Form::idealF: fprintf(fp,"st->print(\"#%%f\", _c%d);\n", const_index); break; - case Form::idealD: fprintf(fp,"st->print(\"#%%f\", _c%d);\n", const_index); break; + case Form::idealN: fprintf(fp," if (_c%d) _c%d->dump_on(st);\n", const_index, const_index); break; + case Form::idealL: fprintf(fp," st->print(\"#%%lld\", _c%d);\n", const_index); break; + case Form::idealF: fprintf(fp," st->print(\"#%%f\", _c%d);\n", const_index); break; + case Form::idealD: fprintf(fp," st->print(\"#%%f\", _c%d);\n", const_index); break; default: assert( false, "ShouldNotReachHere()"); } @@ -2828,17 +2866,8 @@ fprintf(fp,"Component:"); // Write to output files fprintf(fp, " name = %s", _name); fprintf(fp, ", type = %s", _type); - const char * usedef = "Undefined Use/Def info"; - switch (_usedef) { - case USE: usedef = "USE"; break; - case USE_DEF: usedef = "USE_DEF"; break; - case USE_KILL: usedef = "USE_KILL"; break; - case KILL: usedef = "KILL"; break; - case TEMP: usedef = "TEMP"; break; - case DEF: usedef = "DEF"; break; - default: assert(false, "unknown effect"); - } - fprintf(fp, ", use/def = %s\n", usedef); + assert(_usedef != 0, "unknown effect"); + fprintf(fp, ", use/def = %s\n", getUsedefName()); } @@ -2930,9 +2959,9 @@ return count; } -// Return zero-based position in list; -1 if not in list. +// Return zero-based position of operand 'name' in list; -1 if not in list. // if parameter 'usedef' is ::USE, it will match USE, USE_DEF, ... -int ComponentList::operand_position(const char *name, int usedef) { +int ComponentList::operand_position(const char *name, int usedef, Form *fm) { PreserveIter pi(this); int position = 0; int num_opnds = num_operands(); @@ -2955,10 +2984,18 @@ return position+1; } else { if( preceding_non_use && strcmp(component->_name, preceding_non_use->_name) ) { - fprintf(stderr, "the name '%s' should not precede the name '%s'\n", preceding_non_use->_name, name); + fprintf(stderr, "the name '%s(%s)' should not precede the name '%s(%s)'", + preceding_non_use->_name, preceding_non_use->getUsedefName(), + name, component->getUsedefName()); + if (fm && fm->is_instruction()) fprintf(stderr, "in form '%s'", fm->is_instruction()->_ident); + if (fm && fm->is_operand()) fprintf(stderr, "in form '%s'", fm->is_operand()->_ident); + fprintf(stderr, "\n"); } if( position >= num_opnds ) { - fprintf(stderr, "the name '%s' is too late in its name list\n", name); + fprintf(stderr, "the name '%s' is too late in its name list", name); + if (fm && fm->is_instruction()) fprintf(stderr, "in form '%s'", fm->is_instruction()->_ident); + if (fm && fm->is_operand()) fprintf(stderr, "in form '%s'", fm->is_operand()->_ident); + fprintf(stderr, "\n"); } assert(position < num_opnds, "advertised index in bounds"); return position; @@ -3004,10 +3041,10 @@ return Not_in_list; } -int ComponentList::operand_position_format(const char *name) { +int ComponentList::operand_position_format(const char *name, Form *fm) { PreserveIter pi(this); int first_position = operand_position(name); - int use_position = operand_position(name, Component::USE); + int use_position = operand_position(name, Component::USE, fm); return ((first_position < use_position) ? use_position : first_position); } @@ -3270,8 +3307,8 @@ // If we are a "Set", start from the right child. const MatchNode *const mnode = sets_result() ? - (const MatchNode *const)this->_rChild : - (const MatchNode *const)this; + (const MatchNode *)this->_rChild : + (const MatchNode *)this; // If our right child exists, it is the right reduction if ( mnode->_rChild ) { @@ -3288,8 +3325,8 @@ // If we are a "Set", start from the right child. const MatchNode *const mnode = sets_result() ? - (const MatchNode *const)this->_rChild : - (const MatchNode *const)this; + (const MatchNode *)this->_rChild : + (const MatchNode *)this; // If our left child exists, it is the left reduction if ( mnode->_lChild ) { @@ -4113,12 +4150,17 @@ output(stderr); } -void MatchRule::output(FILE *fp) { +// Write just one line. +void MatchRule::output_short(FILE *fp) { fprintf(fp,"MatchRule: ( %s",_name); if (_lChild) _lChild->output(fp); if (_rChild) _rChild->output(fp); - fprintf(fp," )\n"); - fprintf(fp," nesting depth = %d\n", _depth); + fprintf(fp," )"); +} + +void MatchRule::output(FILE *fp) { + output_short(fp); + fprintf(fp,"\n nesting depth = %d\n", _depth); if (_result) fprintf(fp," Result Type = %s", _result); fprintf(fp,"\n"); } diff -r f6badecb7ea7 -r d336b3173277 src/share/vm/adlc/formssel.hpp --- a/src/share/vm/adlc/formssel.hpp Tue Oct 09 12:40:05 2012 -0700 +++ b/src/share/vm/adlc/formssel.hpp Tue Oct 09 16:09:31 2012 -0700 @@ -76,7 +76,7 @@ private: bool _ideal_only; // Not a user-defined instruction // Members used for tracking CISC-spilling - uint _cisc_spill_operand;// Which operand may cisc-spill + int _cisc_spill_operand;// Which operand may cisc-spill void set_cisc_spill_operand(uint op_index) { _cisc_spill_operand = op_index; } bool _is_cisc_alternate; InstructForm *_cisc_spill_alternate;// cisc possible replacement @@ -103,7 +103,7 @@ RewriteRule *_rewrule; // Rewrite rule for this instruction FormatRule *_format; // Format for assembly generation Peephole *_peephole; // List of peephole rules for instruction - const char *_ins_pipe; // Instruction Scheduline description class + const char *_ins_pipe; // Instruction Scheduling description class uint *_uniq_idx; // Indexes of unique operands int _uniq_idx_length; // Length of _uniq_idx array @@ -198,6 +198,7 @@ virtual const char *cost(); // Access ins_cost attribute virtual uint num_opnds(); // Count of num_opnds for MachNode class + // Counts USE_DEF opnds twice. See also num_unique_opnds(). virtual uint num_post_match_opnds(); virtual uint num_consts(FormDict &globals) const;// Constants in match rule // Constants in match rule with specified type @@ -228,6 +229,7 @@ // Return number of relocation entries needed for this instruction. virtual uint reloc(FormDict &globals); + const char *opnd_ident(int idx); // Name of operand #idx. const char *reduce_result(); // Return the name of the operand on the right hand side of the binary match // Return NULL if there is no right hand side @@ -240,7 +242,7 @@ // Check if this instruction can cisc-spill to 'alternate' bool cisc_spills_to(ArchDesc &AD, InstructForm *alternate); InstructForm *cisc_spill_alternate() { return _cisc_spill_alternate; } - uint cisc_spill_operand() const { return _cisc_spill_operand; } + int cisc_spill_operand() const { return _cisc_spill_operand; } bool is_cisc_alternate() const { return _is_cisc_alternate; } void set_cisc_alternate(bool val) { _is_cisc_alternate = val; } const char *cisc_reg_mask_name() const { return _cisc_reg_mask_name; } @@ -277,6 +279,7 @@ return idx; } } + const char *unique_opnd_ident(int idx); // Name of operand at unique idx. // Operands which are only KILLs aren't part of the input array and // require special handling in some cases. Their position in this @@ -889,6 +892,7 @@ void dump(); // Debug printer void output(FILE *fp); // Write to output files + const char* getUsedefName(); public: // Implementation depends upon working bit intersection and union. @@ -1030,6 +1034,7 @@ void matchrule_swap_commutative_op(const char* instr_ident, int count, int& match_rules_cnt); void dump(); + void output_short(FILE *fp); void output(FILE *fp); }; diff -r f6badecb7ea7 -r d336b3173277 src/share/vm/adlc/main.cpp --- a/src/share/vm/adlc/main.cpp Tue Oct 09 12:40:05 2012 -0700 +++ b/src/share/vm/adlc/main.cpp Tue Oct 09 16:09:31 2012 -0700 @@ -341,14 +341,20 @@ static void usage(ArchDesc& AD) { printf("Architecture Description Language Compiler\n\n"); - printf("Usage: adl [-doqw] [-Dflag[=def]] [-Uflag] [-cFILENAME] [-hFILENAME] [-aDFAFILE] ADLFILE\n"); + printf("Usage: adlc [-doqwTs] [-#]* [-D[=]] [-U] [-c] [-h] [-a] [-v] \n"); printf(" d produce DFA debugging info\n"); printf(" o no output produced, syntax and semantic checking only\n"); printf(" q quiet mode, supresses all non-essential messages\n"); printf(" w suppress warning messages\n"); + printf(" T make DFA as many subroutine calls\n"); + printf(" s output which instructions are cisc-spillable\n"); + printf(" D define preprocessor symbol\n"); + printf(" U undefine preprocessor symbol\n"); printf(" c specify CPP file name (default: %s)\n", AD._CPP_file._name); printf(" h specify HPP file name (default: %s)\n", AD._HPP_file._name); printf(" a specify DFA output file name\n"); + printf(" v specify adGlobals output file name\n"); + printf(" # increment ADL debug level\n"); printf("\n"); } @@ -450,22 +456,6 @@ return fname; } -//------------------------------strip_path_and_ext------------------------------ -static char *strip_path_and_ext(char *fname) -{ - char *ep; - char *sp; - - if (fname) { - for (sp = fname; *sp; sp++) - if (*sp == '/') fname = sp+1; - ep = fname; // start at first character and look for '.' - while (ep <= (fname + strlen(fname) - 1) && *ep != '.') ep++; - if (*ep == '.') *ep = '\0'; // truncate string at '.' - } - return fname; -} - //------------------------------base_plus_suffix------------------------------- // New concatenated string static char *base_plus_suffix(const char* base, const char *suffix) @@ -477,18 +467,6 @@ return fname; } - -//------------------------------prefix_plus_base_plus_suffix------------------- -// New concatenated string -static char *prefix_plus_base_plus_suffix(const char* prefix, const char* base, const char *suffix) -{ - int len = (int)strlen(prefix) + (int)strlen(base) + (int)strlen(suffix) + 1; - - char* fname = new char[len]; - sprintf(fname,"%s%s%s",prefix,base,suffix); - return fname; -} - //------------------------------get_legal_text--------------------------------- // Get pointer to legal text at the beginning of AD file. // This code assumes that a legal text starts at the beginning of .ad files, diff -r f6badecb7ea7 -r d336b3173277 src/share/vm/adlc/output_c.cpp --- a/src/share/vm/adlc/output_c.cpp Tue Oct 09 12:40:05 2012 -0700 +++ b/src/share/vm/adlc/output_c.cpp Tue Oct 09 16:09:31 2012 -0700 @@ -518,6 +518,14 @@ int cycles = piperesource->_cycles; uint stage = pipeline->_stages.index(piperesource->_stage); + if (NameList::Not_in_list == stage) { + fprintf(stderr, + "pipeline_res_mask_initializer: " + "semantic error: " + "pipeline stage undeclared: %s\n", + piperesource->_stage); + exit(1); + } uint upper_limit = stage+cycles-1; uint lower_limit = stage-1; uint upper_idx = upper_limit >> 5; @@ -1000,7 +1008,7 @@ } fprintf(fp_cpp, "};\n\n"); fprintf(fp_cpp, "#ifndef PRODUCT\n"); - fprintf(fp_cpp, "void Bundle::dump() const {\n"); + fprintf(fp_cpp, "void Bundle::dump(outputStream *st) const {\n"); fprintf(fp_cpp, " static const char * bundle_flags[] = {\n"); fprintf(fp_cpp, " \"\",\n"); fprintf(fp_cpp, " \"use nop delay\",\n"); @@ -1019,22 +1027,22 @@ // See if the same string is in the table fprintf(fp_cpp, " bool needs_comma = false;\n\n"); fprintf(fp_cpp, " if (_flags) {\n"); - fprintf(fp_cpp, " tty->print(\"%%s\", bundle_flags[_flags]);\n"); + fprintf(fp_cpp, " st->print(\"%%s\", bundle_flags[_flags]);\n"); fprintf(fp_cpp, " needs_comma = true;\n"); fprintf(fp_cpp, " };\n"); fprintf(fp_cpp, " if (instr_count()) {\n"); - fprintf(fp_cpp, " tty->print(\"%%s%%d instr%%s\", needs_comma ? \", \" : \"\", instr_count(), instr_count() != 1 ? \"s\" : \"\");\n"); + fprintf(fp_cpp, " st->print(\"%%s%%d instr%%s\", needs_comma ? \", \" : \"\", instr_count(), instr_count() != 1 ? \"s\" : \"\");\n"); fprintf(fp_cpp, " needs_comma = true;\n"); fprintf(fp_cpp, " };\n"); fprintf(fp_cpp, " uint r = resources_used();\n"); fprintf(fp_cpp, " if (r) {\n"); - fprintf(fp_cpp, " tty->print(\"%%sresource%%s:\", needs_comma ? \", \" : \"\", (r & (r-1)) != 0 ? \"s\" : \"\");\n"); + fprintf(fp_cpp, " st->print(\"%%sresource%%s:\", needs_comma ? \", \" : \"\", (r & (r-1)) != 0 ? \"s\" : \"\");\n"); fprintf(fp_cpp, " for (uint i = 0; i < %d; i++)\n", _pipeline->_rescount); fprintf(fp_cpp, " if ((r & (1 << i)) != 0)\n"); - fprintf(fp_cpp, " tty->print(\" %%s\", resource_names[i]);\n"); + fprintf(fp_cpp, " st->print(\" %%s\", resource_names[i]);\n"); fprintf(fp_cpp, " needs_comma = true;\n"); fprintf(fp_cpp, " };\n"); - fprintf(fp_cpp, " tty->print(\"\\n\");\n"); + fprintf(fp_cpp, " st->print(\"\\n\");\n"); fprintf(fp_cpp, "}\n"); fprintf(fp_cpp, "#endif\n"); } @@ -1048,39 +1056,6 @@ node, regMask); } -// Scan the peepmatch and output a test for each instruction -static void check_peepmatch_instruction_tree(FILE *fp, PeepMatch *pmatch, PeepConstraint *pconstraint) { - int parent = -1; - int inst_position = 0; - const char* inst_name = NULL; - int input = 0; - fprintf(fp, " // Check instruction sub-tree\n"); - pmatch->reset(); - for( pmatch->next_instruction( parent, inst_position, inst_name, input ); - inst_name != NULL; - pmatch->next_instruction( parent, inst_position, inst_name, input ) ) { - // If this is not a placeholder - if( ! pmatch->is_placeholder() ) { - // Define temporaries 'inst#', based on parent and parent's input index - if( parent != -1 ) { // root was initialized - fprintf(fp, " inst%d = inst%d->in(%d);\n", - inst_position, parent, input); - } - - // When not the root - // Test we have the correct instruction by comparing the rule - if( parent != -1 ) { - fprintf(fp, " matches = matches && ( inst%d->rule() == %s_rule );", - inst_position, inst_name); - } - } else { - // Check that user did not try to constrain a placeholder - assert( ! pconstraint->constrains_instruction(inst_position), - "fatal(): Can not constrain a placeholder instruction"); - } - } -} - static void print_block_index(FILE *fp, int inst_position) { assert( inst_position >= 0, "Instruction number less than zero"); fprintf(fp, "block_index"); @@ -1242,7 +1217,7 @@ if( left_op_index != 0 ) { assert( (left_index <= 9999) && (left_op_index <= 9999), "exceed string size"); // Must have index into operands - sprintf(left_reg_index,",inst%d_idx%d", left_index, left_op_index); + sprintf(left_reg_index,",inst%d_idx%d", (int)left_index, left_op_index); } else { strcpy(left_reg_index, ""); } @@ -1255,7 +1230,7 @@ if( right_op_index != 0 ) { assert( (right_index <= 9999) && (right_op_index <= 9999), "exceed string size"); // Must have index into operands - sprintf(right_reg_index,",inst%d_idx%d", right_index, right_op_index); + sprintf(right_reg_index,",inst%d_idx%d", (int)right_index, right_op_index); } else { strcpy(right_reg_index, ""); } @@ -1645,7 +1620,7 @@ new_pos = new_inst->operand_position(parameter,Component::USE); exp_pos += node->num_opnds(); // If there is no use of the created operand, just skip it - if (new_pos != -1) { + if (new_pos != NameList::Not_in_list) { //Copy the operand from the original made above fprintf(fp," n%d->set_opnd_array(%d, op%d->clone(C)); // %s\n", cnt, new_pos, exp_pos-node->num_opnds(), opid); @@ -1789,7 +1764,8 @@ // 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); + 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"); @@ -1934,6 +1910,7 @@ } // Track necessary state when identifying a replacement variable + // @arg rep_var: The formal parameter of the encoding. void update_state(const char *rep_var) { // A replacement variable or one of its subfields // Obtain replacement variable from list @@ -1955,7 +1932,7 @@ } } else { - // Lookup its position in parameter list + // Lookup its position in (formal) parameter list of encoding int param_no = _encoding.rep_var_index(rep_var); if ( param_no == -1 ) { _AD.syntax_err( _encoding._linenum, @@ -1964,6 +1941,7 @@ } // Lookup the corresponding ins_encode parameter + // This is the argument (actual parameter) to the encoding. const char *inst_rep_var = _ins_encode.rep_var_name(_inst, param_no); if (inst_rep_var == NULL) { _AD.syntax_err( _ins_encode._linenum, @@ -2329,6 +2307,7 @@ // Add parameter for index position, if not result operand if( _operand_idx != 0 ) fprintf(_fp,",idx%d", _operand_idx); fprintf(_fp,")"); + fprintf(_fp, "/* %s */", _operand_name); } } else { assert( _reg_status == LITERAL_OUTPUT, "should have output register literal in emit_rep_var"); @@ -2368,7 +2347,7 @@ } } else { assert( _constant_status == LITERAL_OUTPUT, "should have output constant literal in emit_rep_var"); - // Cosntant literal has already been sent to output file, nothing more needed + // Constant literal has already been sent to output file, nothing more needed } } else if ( strcmp(rep_var,"$disp") == 0 ) { @@ -2387,6 +2366,8 @@ } else { printf("emit_field: %s\n",rep_var); + globalAD->syntax_err(_inst._linenum, "Unknown replacement variable %s in format statement of %s.", + rep_var, _inst._ident); assert( false, "UnImplemented()"); } } @@ -2484,14 +2465,14 @@ //(1) // Output instruction's emit prototype - fprintf(fp,"uint %sNode::size(PhaseRegAlloc *ra_) const {\n", + 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); + 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); + fprintf(fp, " return (VerifyOops ? MachNode::size(ra_) : %s);\n", inst._size); // (3) and (4) fprintf(fp,"}\n"); @@ -2579,7 +2560,7 @@ } // (3) and (4) - fprintf(fp, "}\n"); + fprintf(fp, "}\n\n"); } // defineEvalConstant --------------------------------------------------------- @@ -2727,12 +2708,12 @@ // (2) } // static void defineClone(FILE *fp, FormDict &globalNames, OperandForm &oper) { - fprintf(fp,"MachOper *%sOper::clone(Compile* C) const {\n", oper._ident); + fprintf(fp,"MachOper *%sOper::clone(Compile* C) const {\n", oper._ident); // Check for constants that need to be copied over const int num_consts = oper.num_consts(globalNames); const bool is_ideal_bool = oper.is_ideal_bool(); if( (num_consts > 0) ) { - fprintf(fp," return new (C) %sOper(", oper._ident); + fprintf(fp," return new (C) %sOper(", oper._ident); // generate parameters for constants int i = 0; fprintf(fp,"_c%d", i); @@ -2744,21 +2725,12 @@ } else { assert( num_consts == 0, "Currently support zero or one constant per operand clone function"); - fprintf(fp," return new (C) %sOper();\n", oper._ident); + fprintf(fp," return new (C) %sOper();\n", oper._ident); } // finish method fprintf(fp,"}\n"); } -static void define_hash(FILE *fp, char *operand) { - fprintf(fp,"uint %sOper::hash() const { return 5; }\n", operand); -} - -static void define_cmp(FILE *fp, char *operand) { - fprintf(fp,"uint %sOper::cmp( const MachOper &oper ) const { return opcode() == oper.opcode(); }\n", operand); -} - - // Helper functions for bug 4796752, abstracted with minimal modification // from define_oper_interface() OperandForm *rep_var_to_operand(const char *encoding, OperandForm &oper, FormDict &globals) { @@ -2852,14 +2824,14 @@ } else if ( (strcmp(name,"disp") == 0) ) { fprintf(fp,"(PhaseRegAlloc *ra_, const Node *node, int idx) const { \n"); } else { - fprintf(fp,"() const { "); + fprintf(fp,"() const { \n"); } // Check for hexadecimal value OR replacement variable if( *encoding == '$' ) { // Replacement variable const char *rep_var = encoding + 1; - fprintf(fp,"// Replacement variable: %s\n", encoding+1); + fprintf(fp," // Replacement variable: %s\n", encoding+1); // Lookup replacement variable, rep_var, in operand's component list const Component *comp = oper._components.search(rep_var); assert( comp != NULL, "Replacement variable not found in components"); @@ -2880,10 +2852,10 @@ } else if ( op->ideal_to_sReg_type(op->_ident) != Form::none ) { // StackSlot for an sReg comes either from input node or from self, when idx==0 fprintf(fp," if( idx != 0 ) {\n"); - fprintf(fp," // Access register number for input operand\n"); + fprintf(fp," // Access stack offset (register number) for input operand\n"); fprintf(fp," return ra_->reg2offset(ra_->get_reg_first(node->in(idx)));/* sReg */\n"); fprintf(fp," }\n"); - fprintf(fp," // Access register number from myself\n"); + fprintf(fp," // Access stack offset (register number) from myself\n"); fprintf(fp," return ra_->reg2offset(ra_->get_reg_first(node));/* sReg */\n"); } else if (op->_matrule && op->_matrule->is_base_constant(globals)) { // Constant @@ -2900,7 +2872,7 @@ } else if( *encoding == '0' && *(encoding+1) == 'x' ) { // Hex value - fprintf(fp,"return %s;", encoding); + fprintf(fp," return %s;\n", encoding); } else { assert( false, "Do not support octal or decimal encode constants"); } @@ -3133,8 +3105,8 @@ // Output the definition for number of relocation entries uint reloc_size = instr->reloc(_globalNames); if ( reloc_size != 0 ) { - fprintf(fp,"int %sNode::reloc() const {\n", instr->_ident); - fprintf(fp, " return %d;\n", reloc_size ); + fprintf(fp,"int %sNode::reloc() const {\n", instr->_ident); + fprintf(fp," return %d;\n", reloc_size); fprintf(fp,"}\n"); fprintf(fp,"\n"); } @@ -3241,7 +3213,7 @@ class OutputReduceOp : public OutputMap { public: OutputReduceOp(FILE *hpp, FILE *cpp, FormDict &globals, ArchDesc &AD) - : OutputMap(hpp, cpp, globals, AD) {}; + : OutputMap(hpp, cpp, globals, AD, "reduceOp") {}; void declaration() { fprintf(_hpp, "extern const int reduceOp[];\n"); } void definition() { fprintf(_cpp, "const int reduceOp[] = {\n"); } @@ -3276,7 +3248,7 @@ class OutputLeftOp : public OutputMap { public: OutputLeftOp(FILE *hpp, FILE *cpp, FormDict &globals, ArchDesc &AD) - : OutputMap(hpp, cpp, globals, AD) {}; + : OutputMap(hpp, cpp, globals, AD, "leftOp") {}; void declaration() { fprintf(_hpp, "extern const int leftOp[];\n"); } void definition() { fprintf(_cpp, "const int leftOp[] = {\n"); } @@ -3306,7 +3278,7 @@ class OutputRightOp : public OutputMap { public: OutputRightOp(FILE *hpp, FILE *cpp, FormDict &globals, ArchDesc &AD) - : OutputMap(hpp, cpp, globals, AD) {}; + : OutputMap(hpp, cpp, globals, AD, "rightOp") {}; void declaration() { fprintf(_hpp, "extern const int rightOp[];\n"); } void definition() { fprintf(_cpp, "const int rightOp[] = {\n"); } @@ -3336,11 +3308,11 @@ class OutputRuleName : public OutputMap { public: OutputRuleName(FILE *hpp, FILE *cpp, FormDict &globals, ArchDesc &AD) - : OutputMap(hpp, cpp, globals, AD) {}; + : OutputMap(hpp, cpp, globals, AD, "ruleName") {}; void declaration() { fprintf(_hpp, "extern const char *ruleName[];\n"); } void definition() { fprintf(_cpp, "const char *ruleName[] = {\n"); } - void closing() { fprintf(_cpp, " \"no trailing comma\"\n"); + void closing() { fprintf(_cpp, " \"invalid rule name\" // no trailing comma\n"); OutputMap::closing(); } void map(OpClassForm &opc) { fprintf(_cpp, " \"%s\"", _AD.machOperEnum(opc._ident) ); } @@ -3354,7 +3326,7 @@ class OutputSwallowed : public OutputMap { public: OutputSwallowed(FILE *hpp, FILE *cpp, FormDict &globals, ArchDesc &AD) - : OutputMap(hpp, cpp, globals, AD) {}; + : OutputMap(hpp, cpp, globals, AD, "swallowed") {}; void declaration() { fprintf(_hpp, "extern const bool swallowed[];\n"); } void definition() { fprintf(_cpp, "const bool swallowed[] = {\n"); } @@ -3375,7 +3347,7 @@ class OutputInstChainRule : public OutputMap { public: OutputInstChainRule(FILE *hpp, FILE *cpp, FormDict &globals, ArchDesc &AD) - : OutputMap(hpp, cpp, globals, AD) {}; + : OutputMap(hpp, cpp, globals, AD, "instruction_chain_rule") {}; void declaration() { fprintf(_hpp, "extern const bool instruction_chain_rule[];\n"); } void definition() { fprintf(_cpp, "const bool instruction_chain_rule[] = {\n"); } @@ -3416,7 +3388,7 @@ if ( op->ideal_only() ) continue; // Generate the entry for this opcode - map.map(*op); fprintf(fp_cpp, ", // %d\n", idx); + fprintf(fp_cpp, " /* %4d */", idx); map.map(*op); fprintf(fp_cpp, ",\n"); ++idx; }; fprintf(fp_cpp, " // last operand\n"); @@ -3425,7 +3397,7 @@ map.record_position(OutputMap::BEGIN_OPCLASSES, idx ); _opclass.reset(); for(; (opc = (OpClassForm*)_opclass.iter()) != NULL; ) { - map.map(*opc); fprintf(fp_cpp, ", // %d\n", idx); + fprintf(fp_cpp, " /* %4d */", idx); map.map(*opc); fprintf(fp_cpp, ",\n"); ++idx; }; fprintf(fp_cpp, " // last operand class\n"); @@ -3435,7 +3407,7 @@ _internalOpNames.reset(); char *name = NULL; for(; (name = (char *)_internalOpNames.iter()) != NULL; ) { - map.map(name); fprintf(fp_cpp, ", // %d\n", idx); + fprintf(fp_cpp, " /* %4d */", idx); map.map(name); fprintf(fp_cpp, ",\n"); ++idx; }; fprintf(fp_cpp, " // last internally defined operand\n"); @@ -3453,7 +3425,7 @@ if ( ! inst->is_simple_chain_rule(_globalNames) ) continue; if ( inst->rematerialize(_globalNames, get_registers()) ) continue; - map.map(*inst); fprintf(fp_cpp, ", // %d\n", idx); + fprintf(fp_cpp, " /* %4d */", idx); map.map(*inst); fprintf(fp_cpp, ",\n"); ++idx; }; map.record_position(OutputMap::BEGIN_REMATERIALIZE, idx ); @@ -3464,7 +3436,7 @@ if ( ! inst->is_simple_chain_rule(_globalNames) ) continue; if ( ! inst->rematerialize(_globalNames, get_registers()) ) continue; - map.map(*inst); fprintf(fp_cpp, ", // %d\n", idx); + fprintf(fp_cpp, " /* %4d */", idx); map.map(*inst); fprintf(fp_cpp, ",\n"); ++idx; }; map.record_position(OutputMap::END_INST_CHAIN_RULES, idx ); @@ -3478,7 +3450,7 @@ if ( inst->is_simple_chain_rule(_globalNames) ) continue; if ( ! inst->rematerialize(_globalNames, get_registers()) ) continue; - map.map(*inst); fprintf(fp_cpp, ", // %d\n", idx); + fprintf(fp_cpp, " /* %4d */", idx); map.map(*inst); fprintf(fp_cpp, ",\n"); ++idx; }; map.record_position(OutputMap::END_REMATERIALIZE, idx ); @@ -3489,7 +3461,7 @@ if ( inst->is_simple_chain_rule(_globalNames) ) continue; if ( inst->rematerialize(_globalNames, get_registers()) ) continue; - map.map(*inst); fprintf(fp_cpp, ", // %d\n", idx); + fprintf(fp_cpp, " /* %4d */", idx); map.map(*inst); fprintf(fp_cpp, ",\n"); ++idx; }; } @@ -3571,7 +3543,7 @@ next = _register->iter_RegDefs(); char policy = reg_save_policy(rdef->_callconv); const char *comma = (next != NULL) ? "," : " // no trailing comma"; - fprintf(fp_cpp, " '%c'%s\n", policy, comma); + fprintf(fp_cpp, " '%c'%s // %s\n", policy, comma, rdef->_regname); } fprintf(fp_cpp, "};\n\n"); @@ -3583,7 +3555,7 @@ next = _register->iter_RegDefs(); char policy = reg_save_policy(rdef->_c_conv); const char *comma = (next != NULL) ? "," : " // no trailing comma"; - fprintf(fp_cpp, " '%c'%s\n", policy, comma); + fprintf(fp_cpp, " '%c'%s // %s\n", policy, comma, rdef->_regname); } fprintf(fp_cpp, "};\n\n"); @@ -3794,7 +3766,7 @@ // For each operand not in the match rule, call MachOperGenerator // with the enum for the opcode that needs to be built. ComponentList clist = inst->_components; - int index = clist.operand_position(comp->_name, comp->_usedef); + int index = clist.operand_position(comp->_name, comp->_usedef, inst); const char *opcode = machOperEnum(comp->_type); fprintf(fp_cpp, "%s node->set_opnd_array(%d, ", indent, index); fprintf(fp_cpp, "MachOperGenerator(%s, C));\n", opcode); @@ -3989,7 +3961,7 @@ fprintf(fp_cpp, " case %s_rule:", opClass); // Start local scope - fprintf(fp_cpp, " {\n"); + fprintf(fp_cpp, " {\n"); // Generate code to construct the new MachNode buildMachNode(fp_cpp, inst, " "); // Return result and exit scope @@ -4139,6 +4111,9 @@ // Get info for the CISC_oracle and MachNode::cisc_version() void ArchDesc::identify_cisc_spill_instructions() { + if (_frame == NULL) + return; + // Find the user-defined operand for cisc-spilling if( _frame->_cisc_spilling_operand_name != NULL ) { const Form *form = _globalNames[_frame->_cisc_spilling_operand_name]; diff -r f6badecb7ea7 -r d336b3173277 src/share/vm/adlc/output_h.cpp --- a/src/share/vm/adlc/output_h.cpp Tue Oct 09 12:40:05 2012 -0700 +++ b/src/share/vm/adlc/output_h.cpp Tue Oct 09 16:09:31 2012 -0700 @@ -25,6 +25,8 @@ // output_h.cpp - Class HPP file output routines for architecture definition #include "adlc.hpp" +// The comment delimiter used in format statements after assembler instructions. +#define commentSeperator "!" // Generate the #define that describes the number of registers. static void defineRegCount(FILE *fp, RegisterForm *registers) { @@ -79,10 +81,15 @@ _register->reset_RegDefs(); int i = 0; while( (reg_def = _register->iter_RegDefs()) != NULL ) { - fprintf(fp_hpp," %s_num,\t\t// %d\n", reg_def->_regname, i++); + fprintf(fp_hpp," %s_num,", reg_def->_regname); + for (int j = 0; j < 20-(int)strlen(reg_def->_regname); j++) fprintf(fp_hpp, " "); + fprintf(fp_hpp," // enum %3d, regnum %3d, reg encode %3s\n", + i++, + reg_def->register_num(), + reg_def->register_encode()); } // Finish defining enumeration - fprintf(fp_hpp, " _last_Mach_Reg\t// %d\n", i); + fprintf(fp_hpp, " _last_Mach_Reg // %d\n", i); fprintf(fp_hpp, "};\n"); } @@ -121,13 +128,24 @@ fprintf(fp_hpp, "// in the order of occurrence in the alloc_class(es).\n"); fprintf(fp_hpp, "enum MachRegisterEncodes {\n"); + // Find max enum string length. + size_t maxlen = 0; + _register->reset_RegDefs(); + reg_def = _register->iter_RegDefs(); + while (reg_def != NULL) { + size_t len = strlen(reg_def->_regname); + if (len > maxlen) maxlen = len; + reg_def = _register->iter_RegDefs(); + } + // Output the register encoding for each register in the allocation classes _register->reset_RegDefs(); reg_def_next = _register->iter_RegDefs(); while( (reg_def = reg_def_next) != NULL ) { reg_def_next = _register->iter_RegDefs(); - fprintf(fp_hpp," %s_enc = %s%s\n", - reg_def->_regname, reg_def->register_encode(), reg_def_next == NULL? "" : "," ); + fprintf(fp_hpp," %s_enc", reg_def->_regname); + for (size_t i = strlen(reg_def->_regname); i < maxlen; i++) fprintf(fp_hpp, " "); + fprintf(fp_hpp," = %3s%s\n", reg_def->register_encode(), reg_def_next == NULL? "" : "," ); } // Finish defining enumeration fprintf(fp_hpp, "};\n"); @@ -177,14 +195,6 @@ fprintf(fp," virtual const RegMask *in_RegMask(int index) const;\n"); } -static void declare_hash(FILE *fp) { - fprintf(fp," virtual uint hash() const;\n"); -} - -static void declare_cmp(FILE *fp) { - fprintf(fp," virtual uint cmp( const MachOper &oper ) const;\n"); -} - static void declareConstStorage(FILE *fp, FormDict &globals, OperandForm *oper) { int i = 0; Component *comp; @@ -372,18 +382,19 @@ static void defineCCodeDump(OperandForm* oper, FILE *fp, int i) { assert(oper != NULL, "what"); CondInterface* cond = oper->_interface->is_CondInterface(); - fprintf(fp, " if( _c%d == BoolTest::eq ) st->print(\"%s\");\n",i,cond->_equal_format); - fprintf(fp, " else if( _c%d == BoolTest::ne ) st->print(\"%s\");\n",i,cond->_not_equal_format); - fprintf(fp, " else if( _c%d == BoolTest::le ) st->print(\"%s\");\n",i,cond->_less_equal_format); - fprintf(fp, " else if( _c%d == BoolTest::ge ) st->print(\"%s\");\n",i,cond->_greater_equal_format); - fprintf(fp, " else if( _c%d == BoolTest::lt ) st->print(\"%s\");\n",i,cond->_less_format); - fprintf(fp, " else if( _c%d == BoolTest::gt ) st->print(\"%s\");\n",i,cond->_greater_format); + fprintf(fp, " if( _c%d == BoolTest::eq ) st->print(\"%s\");\n",i,cond->_equal_format); + fprintf(fp, " else if( _c%d == BoolTest::ne ) st->print(\"%s\");\n",i,cond->_not_equal_format); + fprintf(fp, " else if( _c%d == BoolTest::le ) st->print(\"%s\");\n",i,cond->_less_equal_format); + fprintf(fp, " else if( _c%d == BoolTest::ge ) st->print(\"%s\");\n",i,cond->_greater_equal_format); + fprintf(fp, " else if( _c%d == BoolTest::lt ) st->print(\"%s\");\n",i,cond->_less_format); + fprintf(fp, " else if( _c%d == BoolTest::gt ) st->print(\"%s\");\n",i,cond->_greater_format); } // Output code that dumps constant values, increment "i" if type is constant static uint dump_spec_constant(FILE *fp, const char *ideal_type, uint i, OperandForm* oper) { if (!strcmp(ideal_type, "ConI")) { fprintf(fp," st->print(\"#%%d\", _c%d);\n", i); + fprintf(fp," st->print(\"/0x%%08x\", _c%d);\n", i); ++i; } else if (!strcmp(ideal_type, "ConP")) { @@ -400,14 +411,19 @@ } else if (!strcmp(ideal_type, "ConL")) { fprintf(fp," st->print(\"#\" INT64_FORMAT, _c%d);\n", i); + fprintf(fp," st->print(\"/\" PTR64_FORMAT, _c%d);\n", i); ++i; } else if (!strcmp(ideal_type, "ConF")) { fprintf(fp," st->print(\"#%%f\", _c%d);\n", i); + fprintf(fp," jint _c%di = JavaValue(_c%d).get_jint();\n", i, i); + fprintf(fp," st->print(\"/0x%%x/\", _c%di);\n", i); ++i; } else if (!strcmp(ideal_type, "ConD")) { fprintf(fp," st->print(\"#%%f\", _c%d);\n", i); + fprintf(fp," jlong _c%dl = JavaValue(_c%d).get_jlong();\n", i, i); + fprintf(fp," st->print(\"/\" PTR64_FORMAT, _c%dl);\n", i); ++i; } else if (!strcmp(ideal_type, "Bool")) { @@ -429,7 +445,7 @@ } // Local pointer indicates remaining part of format rule - uint idx = 0; // position of operand in match rule + int idx = 0; // position of operand in match rule // Generate internal format function, used when stored locally fprintf(fp, "\n#ifndef PRODUCT\n"); @@ -444,13 +460,12 @@ oper._format->_rep_vars.reset(); oper._format->_strings.reset(); while ( (string = oper._format->_strings.iter()) != NULL ) { - fprintf(fp," "); // Check if this is a standard string or a replacement variable if ( string != NameList::_signal ) { // Normal string // Pass through to st->print - fprintf(fp,"st->print(\"%s\");\n", string); + fprintf(fp," st->print(\"%s\");\n", string); } else { // Replacement variable const char *rep_var = oper._format->_rep_vars.iter(); @@ -473,7 +488,7 @@ } // output invocation of "$..."s format function - if ( op != NULL ) op->int_format(fp, globals, idx); + if ( op != NULL ) op->int_format(fp, globals, idx); if ( idx == -1 ) { fprintf(stderr, @@ -516,13 +531,12 @@ oper._format->_rep_vars.reset(); oper._format->_strings.reset(); while ( (string = oper._format->_strings.iter()) != NULL ) { - fprintf(fp," "); // Check if this is a standard string or a replacement variable if ( string != NameList::_signal ) { // Normal string // Pass through to st->print - fprintf(fp,"st->print(\"%s\");\n", string); + fprintf(fp," st->print(\"%s\");\n", string); } else { // Replacement variable const char *rep_var = oper._format->_rep_vars.iter(); @@ -547,7 +561,7 @@ if ( op != NULL ) op->ext_format(fp, globals, idx); // Lookup the index position of the replacement variable - idx = oper._components.operand_position_format(rep_var); + idx = oper._components.operand_position_format(rep_var, &oper); if ( idx == -1 ) { fprintf(stderr, "Using a name, %s, that isn't in match rule\n", rep_var); @@ -601,7 +615,7 @@ inst._format->_rep_vars.reset(); inst._format->_strings.reset(); while( (string = inst._format->_strings.iter()) != NULL ) { - fprintf(fp," "); + fprintf(fp," "); // Check if this is a standard string or a replacement variable if( string == NameList::_signal ) { // Replacement variable const char* rep_var = inst._format->_rep_vars.iter(); @@ -658,11 +672,12 @@ if( call_type != Form::invalid_type ) { switch( call_type ) { case Form::JAVA_DYNAMIC: - fprintf(fp," _method->print_short_name();\n"); + fprintf(fp," _method->print_short_name(st);\n"); break; case Form::JAVA_STATIC: - fprintf(fp," if( _method ) _method->print_short_name(st); else st->print(\" wrapper for: %%s\", _name);\n"); - fprintf(fp," if( !_method ) dump_trap_args(st);\n"); + fprintf(fp," if( _method ) _method->print_short_name(st);\n"); + fprintf(fp," else st->print(\" wrapper for: %%s\", _name);\n"); + fprintf(fp," if( !_method ) dump_trap_args(st);\n"); break; case Form::JAVA_COMPILED: case Form::JAVA_INTERP: @@ -670,52 +685,46 @@ case Form::JAVA_RUNTIME: case Form::JAVA_LEAF: case Form::JAVA_NATIVE: - fprintf(fp," st->print(\" %%s\", _name);"); + fprintf(fp," st->print(\" %%s\", _name);"); break; default: - assert(0,"ShouldNotReacHere"); + assert(0,"ShouldNotReachHere"); } - fprintf(fp, " st->print_cr(\"\");\n" ); - fprintf(fp, " if (_jvms) _jvms->format(ra, this, st); else st->print_cr(\" No JVM State Info\");\n" ); - fprintf(fp, " st->print(\" # \");\n" ); - fprintf(fp, " if( _jvms ) _oop_map->print_on(st);\n"); + fprintf(fp, " st->print_cr(\"\");\n" ); + fprintf(fp, " if (_jvms) _jvms->format(ra, this, st); else st->print_cr(\" No JVM State Info\");\n" ); + fprintf(fp, " st->print(\" # \");\n" ); + fprintf(fp, " if( _jvms && _oop_map ) _oop_map->print_on(st);\n"); } else if(inst.is_ideal_safepoint()) { - fprintf(fp, " st->print(\"\");\n" ); - fprintf(fp, " if (_jvms) _jvms->format(ra, this, st); else st->print_cr(\" No JVM State Info\");\n" ); - fprintf(fp, " st->print(\" # \");\n" ); - fprintf(fp, " if( _jvms ) _oop_map->print_on(st);\n"); + fprintf(fp, " st->print(\"\");\n" ); + fprintf(fp, " if (_jvms) _jvms->format(ra, this, st); else st->print_cr(\" No JVM State Info\");\n" ); + fprintf(fp, " st->print(\" # \");\n" ); + fprintf(fp, " if( _jvms && _oop_map ) _oop_map->print_on(st);\n"); } else if( inst.is_ideal_if() ) { - fprintf(fp, " st->print(\" P=%%f C=%%f\",_prob,_fcnt);\n" ); + fprintf(fp, " st->print(\" P=%%f C=%%f\",_prob,_fcnt);\n" ); } else if( inst.is_ideal_mem() ) { // Print out the field name if available to improve readability - fprintf(fp, " if (ra->C->alias_type(adr_type())->field() != NULL) {\n"); - fprintf(fp, " ciField* f = ra->C->alias_type(adr_type())->field();\n"); - fprintf(fp, " st->print(\" ! Field: \");\n"); - fprintf(fp, " if (f->is_volatile())\n"); - fprintf(fp, " st->print(\"volatile \");\n"); - fprintf(fp, " f->holder()->name()->print_symbol_on(st);\n"); - fprintf(fp, " st->print(\".\");\n"); - fprintf(fp, " f->name()->print_symbol_on(st);\n"); - fprintf(fp, " if (f->is_constant())\n"); - fprintf(fp, " st->print(\" (constant)\");\n"); - fprintf(fp, " } else\n"); + fprintf(fp, " if (ra->C->alias_type(adr_type())->field() != NULL) {\n"); + fprintf(fp, " ciField* f = ra->C->alias_type(adr_type())->field();\n"); + fprintf(fp, " st->print(\" %s Field: \");\n", commentSeperator); + fprintf(fp, " if (f->is_volatile())\n"); + fprintf(fp, " st->print(\"volatile \");\n"); + fprintf(fp, " f->holder()->name()->print_symbol_on(st);\n"); + fprintf(fp, " st->print(\".\");\n"); + fprintf(fp, " f->name()->print_symbol_on(st);\n"); + fprintf(fp, " if (f->is_constant())\n"); + fprintf(fp, " st->print(\" (constant)\");\n"); + fprintf(fp, " } else {\n"); // Make sure 'Volatile' gets printed out fprintf(fp, " if (ra->C->alias_type(adr_type())->is_volatile())\n"); fprintf(fp, " st->print(\" volatile!\");\n"); + fprintf(fp, " }\n"); } // Complete the definition of the format function - fprintf(fp, " }\n#endif\n"); -} - -static bool is_non_constant(char* x) { - // Tells whether the string (part of an operator interface) is non-constant. - // Simply detect whether there is an occurrence of a formal parameter, - // which will always begin with '$'. - return strchr(x, '$') == 0; + fprintf(fp, "}\n#endif\n"); } void ArchDesc::declare_pipe_classes(FILE *fp_hpp) { @@ -1107,7 +1116,7 @@ fprintf(fp_hpp, " static void initialize_nops(MachNode *nop_list[%d], Compile* C);\n\n", _pipeline->_nopcnt); fprintf(fp_hpp, "#ifndef PRODUCT\n"); - fprintf(fp_hpp, " void dump() const;\n"); + fprintf(fp_hpp, " void dump(outputStream *st = tty) const;\n"); fprintf(fp_hpp, "#endif\n"); fprintf(fp_hpp, "};\n\n"); @@ -1252,7 +1261,7 @@ unsigned int position = 0; const char *opret, *opname, *optype; oper->_matrule->base_operand(position,_globalNames,opret,opname,optype); - fprintf(fp," virtual const Type *type() const {"); + fprintf(fp," virtual const Type *type() const {"); const char *type = getIdealType(optype); if( type != NULL ) { Form::DataType data_type = oper->is_base_constant(_globalNames); @@ -1531,12 +1540,19 @@ fprintf(fp, " GrowableArray _index2label;\n"); } fprintf(fp,"public:\n"); - fprintf(fp," MachOper *opnd_array(uint operand_index) const { assert(operand_index < _num_opnds, \"invalid _opnd_array index\"); return _opnd_array[operand_index]; }\n"); - fprintf(fp," void set_opnd_array(uint operand_index, MachOper *operand) { assert(operand_index < _num_opnds, \"invalid _opnd_array index\"); _opnd_array[operand_index] = operand; }\n"); + fprintf(fp," MachOper *opnd_array(uint operand_index) const {\n"); + fprintf(fp," assert(operand_index < _num_opnds, \"invalid _opnd_array index\");\n"); + fprintf(fp," return _opnd_array[operand_index];\n"); + fprintf(fp," }\n"); + fprintf(fp," void set_opnd_array(uint operand_index, MachOper *operand) {\n"); + fprintf(fp," assert(operand_index < _num_opnds, \"invalid _opnd_array index\");\n"); + fprintf(fp," _opnd_array[operand_index] = operand;\n"); + fprintf(fp," }\n"); fprintf(fp,"private:\n"); if ( instr->is_ideal_jump() ) { fprintf(fp," virtual void add_case_label(int index_num, Label* blockLabel) {\n"); - fprintf(fp," _index2label.at_put_grow(index_num, blockLabel);}\n"); + fprintf(fp," _index2label.at_put_grow(index_num, blockLabel);\n"); + fprintf(fp," }\n"); } if( can_cisc_spill() && (instr->cisc_spill_alternate() != NULL) ) { fprintf(fp," const RegMask *_cisc_RegMask;\n"); @@ -1572,7 +1588,7 @@ while (attr != NULL) { if (strcmp(attr->_ident,"ins_cost") && strcmp(attr->_ident,"ins_short_branch")) { - fprintf(fp," int %s() const { return %s; }\n", + fprintf(fp," int %s() const { return %s; }\n", attr->_ident, attr->_val); } // Check value for ins_avoid_back_to_back, and if it is true (1), set the flag @@ -1656,12 +1672,12 @@ // Output the declaration for number of relocation entries if ( instr->reloc(_globalNames) != 0 ) { - fprintf(fp," virtual int reloc() const;\n"); + fprintf(fp," virtual int reloc() const;\n"); } if (instr->alignment() != 1) { - fprintf(fp," virtual int alignment_required() const { return %d; }\n", instr->alignment()); - fprintf(fp," virtual int compute_padding(int current_offset) const;\n"); + fprintf(fp," virtual int alignment_required() const { return %d; }\n", instr->alignment()); + fprintf(fp," virtual int compute_padding(int current_offset) const;\n"); } // Starting point for inputs matcher wants. @@ -1831,7 +1847,7 @@ // as is done for pointers // // Construct appropriate constant type containing the constant value. - fprintf(fp," virtual const class Type *bottom_type() const{\n"); + fprintf(fp," virtual const class Type *bottom_type() const {\n"); switch( data_type ) { case Form::idealI: fprintf(fp," return TypeInt::make(opnd_array(1)->constant());\n"); @@ -1862,7 +1878,7 @@ // !!!!! !!!!! // Provide explicit bottom type for conversions to int // On Intel the result operand is a stackSlot, untyped. - fprintf(fp," virtual const class Type *bottom_type() const{"); + fprintf(fp," virtual const class Type *bottom_type() const {"); fprintf(fp, " return TypeInt::INT;"); fprintf(fp, " };\n"); }*/ @@ -1883,7 +1899,7 @@ // BoxNode provides the address of a stack slot. // Define its bottom type to be TypeRawPtr::BOTTOM instead of TypePtr::BOTTOM // This prevent s insert_anti_dependencies from complaining. It will - // complain if it see that the pointer base is TypePtr::BOTTOM since + // complain if it sees that the pointer base is TypePtr::BOTTOM since // it doesn't understand what that might alias. fprintf(fp," const Type *bottom_type() const { return TypeRawPtr::BOTTOM; } // Box?\n"); } @@ -2046,7 +2062,7 @@ class OutputMachOperands : public OutputMap { public: OutputMachOperands(FILE *hpp, FILE *cpp, FormDict &globals, ArchDesc &AD) - : OutputMap(hpp, cpp, globals, AD) {}; + : OutputMap(hpp, cpp, globals, AD, "MachOperands") {}; void declaration() { } void definition() { fprintf(_cpp, "enum MachOperands {\n"); } @@ -2081,7 +2097,7 @@ int end_instructions; public: OutputMachOpcodes(FILE *hpp, FILE *cpp, FormDict &globals, ArchDesc &AD) - : OutputMap(hpp, cpp, globals, AD), + : OutputMap(hpp, cpp, globals, AD, "MachOpcodes"), begin_inst_chain_rule(-1), end_inst_chain_rule(-1), end_instructions(-1) {};