Mercurial > hg > graal-compiler
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 |