mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-20 11:04:34 +02:00
8000592: Improve adlc usability
Several changes to adlc to improve its usability Reviewed-by: kvn
This commit is contained in:
parent
6674423523
commit
f28ac57f94
11 changed files with 352 additions and 283 deletions
|
@ -567,7 +567,7 @@ bool InstructForm::rematerialize(FormDict &globals, RegisterForm *registers ) {
|
|||
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 @@ uint InstructForm::num_opnds() {
|
|||
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 @@ uint InstructForm::oper_input_base(FormDict &globals) {
|
|||
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 @@ void InstructForm::build_components() {
|
|||
|
||||
// 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 @@ bool InstructForm::check_branch_variant(ArchDesc &AD, InstructForm *short_branch
|
|||
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 @@ void InstructForm::rep_var_format(FILE *fp, const char *rep_var) {
|
|||
// 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 @@ void InstructForm::rep_var_format(FILE *fp, const char *rep_var) {
|
|||
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 @@ void InstructForm::index_temps(FILE *fp, FormDict &globals, const char *prefix,
|
|||
// 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 @@ static int effect_lookup(const char *name) {
|
|||
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 @@ void OperandForm::build_components() {
|
|||
}
|
||||
|
||||
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 @@ void OperandForm::int_format(FILE *fp, FormDict &globals, uint index) {
|
|||
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 @@ void OperandForm::ext_format(FILE *fp, FormDict &globals, uint index) {
|
|||
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 @@ void Component::output(FILE *fp) {
|
|||
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 @@ int ComponentList::num_operands() {
|
|||
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 @@ int ComponentList::operand_position(const char *name, int usedef) {
|
|||
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 @@ int ComponentList::operand_position(const char *name) {
|
|||
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 @@ const char *MatchNode::reduce_right(FormDict &globals) const {
|
|||
|
||||
// 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 @@ const char *MatchNode::reduce_left(FormDict &globals) const {
|
|||
|
||||
// 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 @@ void MatchRule::dump() {
|
|||
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");
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue