comparison 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
comparison
equal deleted inserted replaced
14427:eb178e97560c 14428:044b28168e20
217 } 217 }
218 } 218 }
219 else if (!strcmp(ident, "encode")) { 219 else if (!strcmp(ident, "encode")) {
220 parse_err(SYNERR, "Instructions specify ins_encode, not encode\n"); 220 parse_err(SYNERR, "Instructions specify ins_encode, not encode\n");
221 } 221 }
222 else if (!strcmp(ident, "ins_encode")) ins_encode_parse(*instr); 222 else if (!strcmp(ident, "ins_encode")) ins_encode_parse(*instr);
223 else if (!strcmp(ident, "opcode")) instr->_opcode = opcode_parse(instr); 223 // Parse late expand keyword.
224 else if (!strcmp(ident, "size")) instr->_size = size_parse(instr); 224 else if (!strcmp(ident, "postalloc_expand")) postalloc_expand_parse(*instr);
225 else if (!strcmp(ident, "effect")) effect_parse(instr); 225 else if (!strcmp(ident, "opcode")) instr->_opcode = opcode_parse(instr);
226 else if (!strcmp(ident, "expand")) instr->_exprule = expand_parse(instr); 226 else if (!strcmp(ident, "size")) instr->_size = size_parse(instr);
227 else if (!strcmp(ident, "rewrite")) instr->_rewrule = rewrite_parse(); 227 else if (!strcmp(ident, "effect")) effect_parse(instr);
228 else if (!strcmp(ident, "expand")) instr->_exprule = expand_parse(instr);
229 else if (!strcmp(ident, "rewrite")) instr->_rewrule = rewrite_parse();
228 else if (!strcmp(ident, "constraint")) { 230 else if (!strcmp(ident, "constraint")) {
229 parse_err(SYNERR, "Instructions do not specify a constraint\n"); 231 parse_err(SYNERR, "Instructions do not specify a constraint\n");
230 } 232 }
231 else if (!strcmp(ident, "construct")) { 233 else if (!strcmp(ident, "construct")) {
232 parse_err(SYNERR, "Instructions do not specify a construct\n"); 234 parse_err(SYNERR, "Instructions do not specify a construct\n");
233 } 235 }
234 else if (!strcmp(ident, "format")) instr->_format = format_parse(); 236 else if (!strcmp(ident, "format")) instr->_format = format_parse();
235 else if (!strcmp(ident, "interface")) { 237 else if (!strcmp(ident, "interface")) {
236 parse_err(SYNERR, "Instructions do not specify an interface\n"); 238 parse_err(SYNERR, "Instructions do not specify an interface\n");
237 } 239 }
238 else if (!strcmp(ident, "ins_pipe")) ins_pipe_parse(*instr); 240 else if (!strcmp(ident, "ins_pipe")) ins_pipe_parse(*instr);
239 else { // Done with staticly defined parts of instruction definition 241 else { // Done with staticly defined parts of instruction definition
240 // Check identifier to see if it is the name of an attribute 242 // Check identifier to see if it is the name of an attribute
241 const Form *form = _globalNames[ident]; 243 const Form *form = _globalNames[ident];
242 AttributeForm *attr = form ? form->is_attribute() : NULL; 244 AttributeForm *attr = form ? form->is_attribute() : NULL;
243 if( attr && (attr->_atype == INS_ATTR) ) { 245 if (attr && (attr->_atype == INS_ATTR)) {
244 // Insert the new attribute into the linked list. 246 // Insert the new attribute into the linked list.
245 Attribute *temp = attr_parse(ident); 247 Attribute *temp = attr_parse(ident);
246 temp->_next = instr->_attribs; 248 temp->_next = instr->_attribs;
247 instr->_attribs = temp; 249 instr->_attribs = temp;
248 } else { 250 } else {
249 parse_err(SYNERR, "expected one of:\n predicate, match, encode, or the name of an instruction attribute at %s\n", ident); 251 parse_err(SYNERR, "expected one of:\n predicate, match, encode, or the name of"
252 " an instruction attribute at %s\n", ident);
250 } 253 }
251 } 254 }
252 skipws(); 255 skipws();
253 } while(_curchar != '%'); 256 } while(_curchar != '%');
254 next_char(); 257 next_char();
256 parse_err(SYNERR, "missing '%%}' in instruction definition\n"); 259 parse_err(SYNERR, "missing '%%}' in instruction definition\n");
257 return; 260 return;
258 } 261 }
259 // Check for "Set" form of chain rule 262 // Check for "Set" form of chain rule
260 adjust_set_rule(instr); 263 adjust_set_rule(instr);
261 if (_AD._pipeline ) { 264 if (_AD._pipeline) {
262 if( instr->expands() ) { 265 // No pipe required for late expand.
263 if( instr->_ins_pipe ) 266 if (instr->expands() || instr->postalloc_expands()) {
264 parse_err(WARN, "ins_pipe and expand rule both specified for instruction \"%s\"; ins_pipe will be unused\n", instr->_ident); 267 if (instr->_ins_pipe) {
268 parse_err(WARN, "ins_pipe and expand rule both specified for instruction \"%s\";"
269 " ins_pipe will be unused\n", instr->_ident);
270 }
265 } else { 271 } else {
266 if( !instr->_ins_pipe ) 272 if (!instr->_ins_pipe) {
267 parse_err(WARN, "No ins_pipe specified for instruction \"%s\"\n", instr->_ident); 273 parse_err(WARN, "No ins_pipe specified for instruction \"%s\"\n", instr->_ident);
274 }
268 } 275 }
269 } 276 }
270 // Add instruction to tail of instruction list 277 // Add instruction to tail of instruction list
271 _AD.addForm(instr); 278 _AD.addForm(instr);
272 279
2777 while ((param = inst._parameters.iter()) != NULL) { 2784 while ((param = inst._parameters.iter()) != NULL) {
2778 OperandForm* opForm = (OperandForm*) inst._localNames[param]; 2785 OperandForm* opForm = (OperandForm*) inst._localNames[param];
2779 encoding->add_parameter(opForm->_ident, param); 2786 encoding->add_parameter(opForm->_ident, param);
2780 } 2787 }
2781 2788
2782 // Define a MacroAssembler instance for use by the encoding. The 2789 if (!inst._is_postalloc_expand) {
2783 // name is chosen to match the __ idiom used for assembly in other 2790 // Define a MacroAssembler instance for use by the encoding. The
2784 // parts of hotspot and assumes the existence of the standard 2791 // name is chosen to match the __ idiom used for assembly in other
2785 // #define __ _masm. 2792 // parts of hotspot and assumes the existence of the standard
2786 encoding->add_code(" MacroAssembler _masm(&cbuf);\n"); 2793 // #define __ _masm.
2794 encoding->add_code(" MacroAssembler _masm(&cbuf);\n");
2795 }
2787 2796
2788 // Parse the following %{ }% block 2797 // Parse the following %{ }% block
2789 ins_encode_parse_block_impl(inst, encoding, ec_name); 2798 ins_encode_parse_block_impl(inst, encoding, ec_name);
2790 2799
2791 // Build an encoding rule which invokes the encoding rule we just 2800 // Build an encoding rule which invokes the encoding rule we just
2855 if (strcmp(rep_var, "constanttablebase") == 0) { 2864 if (strcmp(rep_var, "constanttablebase") == 0) {
2856 // This instruct is a MachConstantNode. 2865 // This instruct is a MachConstantNode.
2857 inst.set_is_mach_constant(true); 2866 inst.set_is_mach_constant(true);
2858 2867
2859 if (_curchar == '(') { 2868 if (_curchar == '(') {
2860 parse_err(SYNERR, "constanttablebase in instruct %s cannot have an argument (only constantaddress and constantoffset)", ec_name); 2869 parse_err(SYNERR, "constanttablebase in instruct %s cannot have an argument "
2870 "(only constantaddress and constantoffset)", ec_name);
2861 return; 2871 return;
2862 } 2872 }
2863 } 2873 }
2864 else if ((strcmp(rep_var, "constantaddress") == 0) || 2874 else if ((strcmp(rep_var, "constantaddress") == 0) ||
2865 (strcmp(rep_var, "constantoffset") == 0)) { 2875 (strcmp(rep_var, "constantoffset") == 0)) {
3043 return; 3053 return;
3044 } 3054 }
3045 3055
3046 // Debug Stuff 3056 // Debug Stuff
3047 if (_AD._adl_debug > 1) fprintf(stderr,"Instruction Encode: %s\n", ec_name); 3057 if (_AD._adl_debug > 1) fprintf(stderr,"Instruction Encode: %s\n", ec_name);
3058
3059 // Set encode class of this instruction.
3060 inst._insencode = encrule;
3061 }
3062
3063 //------------------------------postalloc_expand_parse---------------------------
3064 // Encode rules have the form
3065 // postalloc_expand( encode_class_name(parameter_list) );
3066 //
3067 // The "encode_class_name" must be defined in the encode section.
3068 // The parameter list contains $names that are locals.
3069 //
3070 // This is just a copy of ins_encode_parse without the loop.
3071 void ADLParser::postalloc_expand_parse(InstructForm& inst) {
3072 inst._is_postalloc_expand = true;
3073
3074 // Parse encode class name.
3075 skipws(); // Skip whitespace.
3076 if (_curchar != '(') {
3077 // Check for postalloc_expand %{ form
3078 if ((_curchar == '%') && (*(_ptr+1) == '{')) {
3079 next_char(); // Skip '%'
3080 next_char(); // Skip '{'
3081
3082 // Parse the block form of postalloc_expand
3083 ins_encode_parse_block(inst);
3084 return;
3085 }
3086
3087 parse_err(SYNERR, "missing '(' in postalloc_expand definition\n");
3088 return;
3089 }
3090 next_char(); // Move past '('.
3091 skipws();
3092
3093 InsEncode *encrule = new InsEncode(); // Encode class for instruction.
3094 encrule->_linenum = linenum();
3095 char *ec_name = NULL; // String representation of encode rule.
3096 // identifier is optional.
3097 if (_curchar != ')') {
3098 ec_name = get_ident();
3099 if (ec_name == NULL) {
3100 parse_err(SYNERR, "Invalid postalloc_expand class name after 'postalloc_expand('.\n");
3101 return;
3102 }
3103 // Check that encoding is defined in the encode section.
3104 EncClass *encode_class = _AD._encode->encClass(ec_name);
3105
3106 // Get list for encode method's parameters
3107 NameAndList *params = encrule->add_encode(ec_name);
3108
3109 // Parse the parameters to this encode method.
3110 skipws();
3111 if (_curchar == '(') {
3112 next_char(); // Move past '(' for parameters.
3113
3114 // Parse the encode method's parameters.
3115 while (_curchar != ')') {
3116 char *param = get_ident_or_literal_constant("encoding operand");
3117 if (param != NULL) {
3118 // Found a parameter:
3119
3120 // First check for constant table support.
3121
3122 // Check if this instruct is a MachConstantNode.
3123 if (strcmp(param, "constanttablebase") == 0) {
3124 // This instruct is a MachConstantNode.
3125 inst.set_is_mach_constant(true);
3126
3127 if (_curchar == '(') {
3128 parse_err(SYNERR, "constanttablebase in instruct %s cannot have an argument "
3129 "(only constantaddress and constantoffset)", ec_name);
3130 return;
3131 }
3132 }
3133 else if ((strcmp(param, "constantaddress") == 0) ||
3134 (strcmp(param, "constantoffset") == 0)) {
3135 // This instruct is a MachConstantNode.
3136 inst.set_is_mach_constant(true);
3137
3138 // If the constant keyword has an argument, parse it.
3139 if (_curchar == '(') constant_parse(inst);
3140 }
3141
3142 // Else check it is a local name, add it to the list, then check for more.
3143 // New: allow hex constants as parameters to an encode method.
3144 // New: allow parenthesized expressions as parameters.
3145 // New: allow "primary", "secondary", "tertiary" as parameters.
3146 // New: allow user-defined register name as parameter.
3147 else if ((inst._localNames[param] == NULL) &&
3148 !ADLParser::is_literal_constant(param) &&
3149 (Opcode::as_opcode_type(param) == Opcode::NOT_AN_OPCODE) &&
3150 ((_AD._register == NULL) || (_AD._register->getRegDef(param) == NULL))) {
3151 parse_err(SYNERR, "Using non-locally defined parameter %s for encoding %s.\n", param, ec_name);
3152 return;
3153 }
3154 params->add_entry(param);
3155
3156 skipws();
3157 if (_curchar == ',') {
3158 // More parameters to come.
3159 next_char(); // Move past ',' between parameters.
3160 skipws(); // Skip to next parameter.
3161 } else if (_curchar == ')') {
3162 // Done with parameter list
3163 } else {
3164 // Only ',' or ')' are valid after a parameter name.
3165 parse_err(SYNERR, "expected ',' or ')' after parameter %s.\n", ec_name);
3166 return;
3167 }
3168
3169 } else {
3170 skipws();
3171 // Did not find a parameter.
3172 if (_curchar == ',') {
3173 parse_err(SYNERR, "Expected encode parameter before ',' in postalloc_expand %s.\n", ec_name);
3174 return;
3175 }
3176 if (_curchar != ')') {
3177 parse_err(SYNERR, "Expected ')' after postalloc_expand parameters.\n");
3178 return;
3179 }
3180 }
3181 } // WHILE loop collecting parameters.
3182 next_char(); // Move past ')' at end of parameters.
3183 } // Done with parameter list for encoding.
3184
3185 // Check for ',' or ')' after encoding.
3186 skipws(); // Move to character after parameters.
3187 if (_curchar != ')') {
3188 // Only a ')' is allowed.
3189 parse_err(SYNERR, "Expected ')' after postalloc_expand %s.\n", ec_name);
3190 return;
3191 }
3192 } // Done parsing postalloc_expand method and their parameters.
3193 if (_curchar != ')') {
3194 parse_err(SYNERR, "Missing ')' at end of postalloc_expand description.\n");
3195 return;
3196 }
3197 next_char(); // Move past ')'.
3198 skipws(); // Skip leading whitespace.
3199
3200 if (_curchar != ';') {
3201 parse_err(SYNERR, "Missing ';' at end of postalloc_expand.\n");
3202 return;
3203 }
3204 next_char(); // Move past ';'.
3205 skipws(); // Be friendly to oper_parse().
3206
3207 // Debug Stuff.
3208 if (_AD._adl_debug > 1) fprintf(stderr, "Instruction postalloc_expand: %s\n", ec_name);
3048 3209
3049 // Set encode class of this instruction. 3210 // Set encode class of this instruction.
3050 inst._insencode = encrule; 3211 inst._insencode = encrule;
3051 } 3212 }
3052 3213