Mercurial > hg > graal-compiler
diff src/share/vm/adlc/adlparse.cpp @ 14428:044b28168e20
8003854: PPC64 (part 115): Introduce PostallocExpand that expands nodes after register allocation
Summary: added ability in C2 to expand mach nodes to several mach nodes after register allocation
Reviewed-by: kvn
author | goetz |
---|---|
date | Thu, 14 Nov 2013 19:24:59 -0800 |
parents | c9ccd7b85f20 |
children | 1410ad6b05f1 |
line wrap: on
line diff
--- a/src/share/vm/adlc/adlparse.cpp Thu Nov 07 11:47:11 2013 +0100 +++ b/src/share/vm/adlc/adlparse.cpp Thu Nov 14 19:24:59 2013 -0800 @@ -219,19 +219,21 @@ 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 @@ // 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 @@ } // 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 @@ 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 @@ 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 @@ 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.