mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-21 03:24:38 +02:00
8003854: PPC64 (part 115): Introduce PostallocExpand that expands nodes after register allocation
Added ability in C2 to expand mach nodes to several mach nodes after register allocation Reviewed-by: kvn
This commit is contained in:
parent
d8b9e9f681
commit
12b298218d
20 changed files with 689 additions and 92 deletions
|
@ -219,19 +219,21 @@ void ADLParser::instr_parse(void) {
|
|||
else if (!strcmp(ident, "encode")) {
|
||||
parse_err(SYNERR, "Instructions specify ins_encode, not encode\n");
|
||||
}
|
||||
else if (!strcmp(ident, "ins_encode")) ins_encode_parse(*instr);
|
||||
else if (!strcmp(ident, "opcode")) instr->_opcode = opcode_parse(instr);
|
||||
else if (!strcmp(ident, "size")) instr->_size = size_parse(instr);
|
||||
else if (!strcmp(ident, "effect")) effect_parse(instr);
|
||||
else if (!strcmp(ident, "expand")) instr->_exprule = expand_parse(instr);
|
||||
else if (!strcmp(ident, "rewrite")) instr->_rewrule = rewrite_parse();
|
||||
else if (!strcmp(ident, "ins_encode")) ins_encode_parse(*instr);
|
||||
// Parse late expand keyword.
|
||||
else if (!strcmp(ident, "postalloc_expand")) postalloc_expand_parse(*instr);
|
||||
else if (!strcmp(ident, "opcode")) instr->_opcode = opcode_parse(instr);
|
||||
else if (!strcmp(ident, "size")) instr->_size = size_parse(instr);
|
||||
else if (!strcmp(ident, "effect")) effect_parse(instr);
|
||||
else if (!strcmp(ident, "expand")) instr->_exprule = expand_parse(instr);
|
||||
else if (!strcmp(ident, "rewrite")) instr->_rewrule = rewrite_parse();
|
||||
else if (!strcmp(ident, "constraint")) {
|
||||
parse_err(SYNERR, "Instructions do not specify a constraint\n");
|
||||
}
|
||||
else if (!strcmp(ident, "construct")) {
|
||||
parse_err(SYNERR, "Instructions do not specify a construct\n");
|
||||
}
|
||||
else if (!strcmp(ident, "format")) instr->_format = format_parse();
|
||||
else if (!strcmp(ident, "format")) instr->_format = format_parse();
|
||||
else if (!strcmp(ident, "interface")) {
|
||||
parse_err(SYNERR, "Instructions do not specify an interface\n");
|
||||
}
|
||||
|
@ -240,13 +242,14 @@ void ADLParser::instr_parse(void) {
|
|||
// Check identifier to see if it is the name of an attribute
|
||||
const Form *form = _globalNames[ident];
|
||||
AttributeForm *attr = form ? form->is_attribute() : NULL;
|
||||
if( attr && (attr->_atype == INS_ATTR) ) {
|
||||
if (attr && (attr->_atype == INS_ATTR)) {
|
||||
// Insert the new attribute into the linked list.
|
||||
Attribute *temp = attr_parse(ident);
|
||||
temp->_next = instr->_attribs;
|
||||
instr->_attribs = temp;
|
||||
} else {
|
||||
parse_err(SYNERR, "expected one of:\n predicate, match, encode, or the name of an instruction attribute at %s\n", ident);
|
||||
parse_err(SYNERR, "expected one of:\n predicate, match, encode, or the name of"
|
||||
" an instruction attribute at %s\n", ident);
|
||||
}
|
||||
}
|
||||
skipws();
|
||||
|
@ -258,13 +261,17 @@ void ADLParser::instr_parse(void) {
|
|||
}
|
||||
// Check for "Set" form of chain rule
|
||||
adjust_set_rule(instr);
|
||||
if (_AD._pipeline ) {
|
||||
if( instr->expands() ) {
|
||||
if( instr->_ins_pipe )
|
||||
parse_err(WARN, "ins_pipe and expand rule both specified for instruction \"%s\"; ins_pipe will be unused\n", instr->_ident);
|
||||
if (_AD._pipeline) {
|
||||
// No pipe required for late expand.
|
||||
if (instr->expands() || instr->postalloc_expands()) {
|
||||
if (instr->_ins_pipe) {
|
||||
parse_err(WARN, "ins_pipe and expand rule both specified for instruction \"%s\";"
|
||||
" ins_pipe will be unused\n", instr->_ident);
|
||||
}
|
||||
} else {
|
||||
if( !instr->_ins_pipe )
|
||||
if (!instr->_ins_pipe) {
|
||||
parse_err(WARN, "No ins_pipe specified for instruction \"%s\"\n", instr->_ident);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Add instruction to tail of instruction list
|
||||
|
@ -2779,11 +2786,13 @@ void ADLParser::ins_encode_parse_block(InstructForm& inst) {
|
|||
encoding->add_parameter(opForm->_ident, param);
|
||||
}
|
||||
|
||||
// Define a MacroAssembler instance for use by the encoding. The
|
||||
// name is chosen to match the __ idiom used for assembly in other
|
||||
// parts of hotspot and assumes the existence of the standard
|
||||
// #define __ _masm.
|
||||
encoding->add_code(" MacroAssembler _masm(&cbuf);\n");
|
||||
if (!inst._is_postalloc_expand) {
|
||||
// Define a MacroAssembler instance for use by the encoding. The
|
||||
// name is chosen to match the __ idiom used for assembly in other
|
||||
// parts of hotspot and assumes the existence of the standard
|
||||
// #define __ _masm.
|
||||
encoding->add_code(" MacroAssembler _masm(&cbuf);\n");
|
||||
}
|
||||
|
||||
// Parse the following %{ }% block
|
||||
ins_encode_parse_block_impl(inst, encoding, ec_name);
|
||||
|
@ -2857,7 +2866,8 @@ void ADLParser::ins_encode_parse_block_impl(InstructForm& inst, EncClass* encodi
|
|||
inst.set_is_mach_constant(true);
|
||||
|
||||
if (_curchar == '(') {
|
||||
parse_err(SYNERR, "constanttablebase in instruct %s cannot have an argument (only constantaddress and constantoffset)", ec_name);
|
||||
parse_err(SYNERR, "constanttablebase in instruct %s cannot have an argument "
|
||||
"(only constantaddress and constantoffset)", ec_name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -3050,6 +3060,157 @@ void ADLParser::ins_encode_parse(InstructForm& inst) {
|
|||
inst._insencode = encrule;
|
||||
}
|
||||
|
||||
//------------------------------postalloc_expand_parse---------------------------
|
||||
// Encode rules have the form
|
||||
// postalloc_expand( encode_class_name(parameter_list) );
|
||||
//
|
||||
// The "encode_class_name" must be defined in the encode section.
|
||||
// The parameter list contains $names that are locals.
|
||||
//
|
||||
// This is just a copy of ins_encode_parse without the loop.
|
||||
void ADLParser::postalloc_expand_parse(InstructForm& inst) {
|
||||
inst._is_postalloc_expand = true;
|
||||
|
||||
// Parse encode class name.
|
||||
skipws(); // Skip whitespace.
|
||||
if (_curchar != '(') {
|
||||
// Check for postalloc_expand %{ form
|
||||
if ((_curchar == '%') && (*(_ptr+1) == '{')) {
|
||||
next_char(); // Skip '%'
|
||||
next_char(); // Skip '{'
|
||||
|
||||
// Parse the block form of postalloc_expand
|
||||
ins_encode_parse_block(inst);
|
||||
return;
|
||||
}
|
||||
|
||||
parse_err(SYNERR, "missing '(' in postalloc_expand definition\n");
|
||||
return;
|
||||
}
|
||||
next_char(); // Move past '('.
|
||||
skipws();
|
||||
|
||||
InsEncode *encrule = new InsEncode(); // Encode class for instruction.
|
||||
encrule->_linenum = linenum();
|
||||
char *ec_name = NULL; // String representation of encode rule.
|
||||
// identifier is optional.
|
||||
if (_curchar != ')') {
|
||||
ec_name = get_ident();
|
||||
if (ec_name == NULL) {
|
||||
parse_err(SYNERR, "Invalid postalloc_expand class name after 'postalloc_expand('.\n");
|
||||
return;
|
||||
}
|
||||
// Check that encoding is defined in the encode section.
|
||||
EncClass *encode_class = _AD._encode->encClass(ec_name);
|
||||
|
||||
// Get list for encode method's parameters
|
||||
NameAndList *params = encrule->add_encode(ec_name);
|
||||
|
||||
// Parse the parameters to this encode method.
|
||||
skipws();
|
||||
if (_curchar == '(') {
|
||||
next_char(); // Move past '(' for parameters.
|
||||
|
||||
// Parse the encode method's parameters.
|
||||
while (_curchar != ')') {
|
||||
char *param = get_ident_or_literal_constant("encoding operand");
|
||||
if (param != NULL) {
|
||||
// Found a parameter:
|
||||
|
||||
// First check for constant table support.
|
||||
|
||||
// Check if this instruct is a MachConstantNode.
|
||||
if (strcmp(param, "constanttablebase") == 0) {
|
||||
// This instruct is a MachConstantNode.
|
||||
inst.set_is_mach_constant(true);
|
||||
|
||||
if (_curchar == '(') {
|
||||
parse_err(SYNERR, "constanttablebase in instruct %s cannot have an argument "
|
||||
"(only constantaddress and constantoffset)", ec_name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if ((strcmp(param, "constantaddress") == 0) ||
|
||||
(strcmp(param, "constantoffset") == 0)) {
|
||||
// This instruct is a MachConstantNode.
|
||||
inst.set_is_mach_constant(true);
|
||||
|
||||
// If the constant keyword has an argument, parse it.
|
||||
if (_curchar == '(') constant_parse(inst);
|
||||
}
|
||||
|
||||
// Else check it is a local name, add it to the list, then check for more.
|
||||
// New: allow hex constants as parameters to an encode method.
|
||||
// New: allow parenthesized expressions as parameters.
|
||||
// New: allow "primary", "secondary", "tertiary" as parameters.
|
||||
// New: allow user-defined register name as parameter.
|
||||
else if ((inst._localNames[param] == NULL) &&
|
||||
!ADLParser::is_literal_constant(param) &&
|
||||
(Opcode::as_opcode_type(param) == Opcode::NOT_AN_OPCODE) &&
|
||||
((_AD._register == NULL) || (_AD._register->getRegDef(param) == NULL))) {
|
||||
parse_err(SYNERR, "Using non-locally defined parameter %s for encoding %s.\n", param, ec_name);
|
||||
return;
|
||||
}
|
||||
params->add_entry(param);
|
||||
|
||||
skipws();
|
||||
if (_curchar == ',') {
|
||||
// More parameters to come.
|
||||
next_char(); // Move past ',' between parameters.
|
||||
skipws(); // Skip to next parameter.
|
||||
} else if (_curchar == ')') {
|
||||
// Done with parameter list
|
||||
} else {
|
||||
// Only ',' or ')' are valid after a parameter name.
|
||||
parse_err(SYNERR, "expected ',' or ')' after parameter %s.\n", ec_name);
|
||||
return;
|
||||
}
|
||||
|
||||
} else {
|
||||
skipws();
|
||||
// Did not find a parameter.
|
||||
if (_curchar == ',') {
|
||||
parse_err(SYNERR, "Expected encode parameter before ',' in postalloc_expand %s.\n", ec_name);
|
||||
return;
|
||||
}
|
||||
if (_curchar != ')') {
|
||||
parse_err(SYNERR, "Expected ')' after postalloc_expand parameters.\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
} // WHILE loop collecting parameters.
|
||||
next_char(); // Move past ')' at end of parameters.
|
||||
} // Done with parameter list for encoding.
|
||||
|
||||
// Check for ',' or ')' after encoding.
|
||||
skipws(); // Move to character after parameters.
|
||||
if (_curchar != ')') {
|
||||
// Only a ')' is allowed.
|
||||
parse_err(SYNERR, "Expected ')' after postalloc_expand %s.\n", ec_name);
|
||||
return;
|
||||
}
|
||||
} // Done parsing postalloc_expand method and their parameters.
|
||||
if (_curchar != ')') {
|
||||
parse_err(SYNERR, "Missing ')' at end of postalloc_expand description.\n");
|
||||
return;
|
||||
}
|
||||
next_char(); // Move past ')'.
|
||||
skipws(); // Skip leading whitespace.
|
||||
|
||||
if (_curchar != ';') {
|
||||
parse_err(SYNERR, "Missing ';' at end of postalloc_expand.\n");
|
||||
return;
|
||||
}
|
||||
next_char(); // Move past ';'.
|
||||
skipws(); // Be friendly to oper_parse().
|
||||
|
||||
// Debug Stuff.
|
||||
if (_AD._adl_debug > 1) fprintf(stderr, "Instruction postalloc_expand: %s\n", ec_name);
|
||||
|
||||
// Set encode class of this instruction.
|
||||
inst._insencode = encrule;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------constant_parse---------------------------------
|
||||
// Parse a constant expression.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue