Mercurial > hg > graal-jvmci-8
comparison src/share/vm/adlc/output_c.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 | 650868c062a9 |
children | 1410ad6b05f1 |
comparison
equal
deleted
inserted
replaced
14427:eb178e97560c | 14428:044b28168e20 |
---|---|
2486 //(2) | 2486 //(2) |
2487 // Print the size | 2487 // Print the size |
2488 fprintf(fp, " return (VerifyOops ? MachNode::size(ra_) : %s);\n", inst._size); | 2488 fprintf(fp, " return (VerifyOops ? MachNode::size(ra_) : %s);\n", inst._size); |
2489 | 2489 |
2490 // (3) and (4) | 2490 // (3) and (4) |
2491 fprintf(fp,"}\n"); | 2491 fprintf(fp,"}\n\n"); |
2492 } | |
2493 | |
2494 // Emit late expand function. | |
2495 void ArchDesc::define_postalloc_expand(FILE *fp, InstructForm &inst) { | |
2496 InsEncode *ins_encode = inst._insencode; | |
2497 | |
2498 // Output instruction's postalloc_expand prototype. | |
2499 fprintf(fp, "void %sNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {\n", | |
2500 inst._ident); | |
2501 | |
2502 assert((_encode != NULL) && (ins_encode != NULL), "You must define an encode section."); | |
2503 | |
2504 // Output each operand's offset into the array of registers. | |
2505 inst.index_temps(fp, _globalNames); | |
2506 | |
2507 // Output variables "unsigned idx_<par_name>", Node *n_<par_name> and "MachOpnd *op_<par_name>" | |
2508 // for each parameter <par_name> specified in the encoding. | |
2509 ins_encode->reset(); | |
2510 const char *ec_name = ins_encode->encode_class_iter(); | |
2511 assert(ec_name != NULL, "late expand must specify an encoding"); | |
2512 | |
2513 EncClass *encoding = _encode->encClass(ec_name); | |
2514 if (encoding == NULL) { | |
2515 fprintf(stderr, "User did not define contents of this encode_class: %s\n", ec_name); | |
2516 abort(); | |
2517 } | |
2518 if (ins_encode->current_encoding_num_args() != encoding->num_args()) { | |
2519 globalAD->syntax_err(ins_encode->_linenum, "In %s: passing %d arguments to %s but expecting %d", | |
2520 inst._ident, ins_encode->current_encoding_num_args(), | |
2521 ec_name, encoding->num_args()); | |
2522 } | |
2523 | |
2524 fprintf(fp, " // Access to ins and operands for late expand.\n"); | |
2525 const int buflen = 2000; | |
2526 char idxbuf[buflen]; char *ib = idxbuf; sprintf(ib, ""); | |
2527 char nbuf [buflen]; char *nb = nbuf; sprintf(nb, ""); | |
2528 char opbuf [buflen]; char *ob = opbuf; sprintf(ob, ""); | |
2529 | |
2530 encoding->_parameter_type.reset(); | |
2531 encoding->_parameter_name.reset(); | |
2532 const char *type = encoding->_parameter_type.iter(); | |
2533 const char *name = encoding->_parameter_name.iter(); | |
2534 int param_no = 0; | |
2535 for (; (type != NULL) && (name != NULL); | |
2536 (type = encoding->_parameter_type.iter()), (name = encoding->_parameter_name.iter())) { | |
2537 const char* arg_name = ins_encode->rep_var_name(inst, param_no); | |
2538 int idx = inst.operand_position_format(arg_name); | |
2539 if (strcmp(arg_name, "constanttablebase") == 0) { | |
2540 ib += sprintf(ib, " unsigned idx_%-5s = mach_constant_base_node_input(); \t// %s, \t%s\n", | |
2541 name, type, arg_name); | |
2542 nb += sprintf(nb, " Node *n_%-7s = lookup(idx_%s);\n", name, name); | |
2543 // There is no operand for the constanttablebase. | |
2544 } else if (inst.is_noninput_operand(idx)) { | |
2545 globalAD->syntax_err(inst._linenum, | |
2546 "In %s: you can not pass the non-input %s to a late expand encoding.\n", | |
2547 inst._ident, arg_name); | |
2548 } else { | |
2549 ib += sprintf(ib, " unsigned idx_%-5s = idx%d; \t// %s, \t%s\n", | |
2550 name, idx, type, arg_name); | |
2551 nb += sprintf(nb, " Node *n_%-7s = lookup(idx_%s);\n", name, name); | |
2552 ob += sprintf(ob, " %sOper *op_%s = (%sOper *)opnd_array(%d);\n", type, name, type, idx); | |
2553 } | |
2554 param_no++; | |
2555 } | |
2556 assert(ib < &idxbuf[buflen-1] && nb < &nbuf[buflen-1] && ob < &opbuf[buflen-1], "buffer overflow"); | |
2557 | |
2558 fprintf(fp, "%s", idxbuf); | |
2559 fprintf(fp, " Node *n_region = lookup(0);\n"); | |
2560 fprintf(fp, "%s%s", nbuf, opbuf); | |
2561 fprintf(fp, " Compile *C = ra_->C;\n"); | |
2562 | |
2563 // Output this instruction's encodings. | |
2564 fprintf(fp, " {"); | |
2565 const char *ec_code = NULL; | |
2566 const char *ec_rep_var = NULL; | |
2567 assert(encoding == _encode->encClass(ec_name), ""); | |
2568 | |
2569 DefineEmitState pending(fp, *this, *encoding, *ins_encode, inst); | |
2570 encoding->_code.reset(); | |
2571 encoding->_rep_vars.reset(); | |
2572 // Process list of user-defined strings, | |
2573 // and occurrences of replacement variables. | |
2574 // Replacement Vars are pushed into a list and then output. | |
2575 while ((ec_code = encoding->_code.iter()) != NULL) { | |
2576 if (! encoding->_code.is_signal(ec_code)) { | |
2577 // Emit pending code. | |
2578 pending.emit(); | |
2579 pending.clear(); | |
2580 // Emit this code section. | |
2581 fprintf(fp, "%s", ec_code); | |
2582 } else { | |
2583 // A replacement variable or one of its subfields. | |
2584 // Obtain replacement variable from list. | |
2585 ec_rep_var = encoding->_rep_vars.iter(); | |
2586 pending.add_rep_var(ec_rep_var); | |
2587 } | |
2588 } | |
2589 // Emit pending code. | |
2590 pending.emit(); | |
2591 pending.clear(); | |
2592 fprintf(fp, " }\n"); | |
2593 | |
2594 fprintf(fp, "}\n\n"); | |
2595 | |
2596 ec_name = ins_encode->encode_class_iter(); | |
2597 assert(ec_name == NULL, "Late expand may only have one encoding."); | |
2492 } | 2598 } |
2493 | 2599 |
2494 // defineEmit ----------------------------------------------------------------- | 2600 // defineEmit ----------------------------------------------------------------- |
2495 void ArchDesc::defineEmit(FILE* fp, InstructForm& inst) { | 2601 void ArchDesc::defineEmit(FILE* fp, InstructForm& inst) { |
2496 InsEncode* encode = inst._insencode; | 2602 InsEncode* encode = inst._insencode; |
2839 fprintf(fp,"(PhaseRegAlloc *ra_, const Node *node, int idx) const { \n"); | 2945 fprintf(fp,"(PhaseRegAlloc *ra_, const Node *node, int idx) const { \n"); |
2840 emit_position = true; | 2946 emit_position = true; |
2841 } else if ( (strcmp(name,"disp") == 0) ) { | 2947 } else if ( (strcmp(name,"disp") == 0) ) { |
2842 fprintf(fp,"(PhaseRegAlloc *ra_, const Node *node, int idx) const { \n"); | 2948 fprintf(fp,"(PhaseRegAlloc *ra_, const Node *node, int idx) const { \n"); |
2843 } else { | 2949 } else { |
2844 fprintf(fp,"() const { \n"); | 2950 fprintf(fp, "() const {\n"); |
2845 } | 2951 } |
2846 | 2952 |
2847 // Check for hexadecimal value OR replacement variable | 2953 // Check for hexadecimal value OR replacement variable |
2848 if( *encoding == '$' ) { | 2954 if( *encoding == '$' ) { |
2849 // Replacement variable | 2955 // Replacement variable |
2889 } | 2995 } |
2890 else if( *encoding == '0' && *(encoding+1) == 'x' ) { | 2996 else if( *encoding == '0' && *(encoding+1) == 'x' ) { |
2891 // Hex value | 2997 // Hex value |
2892 fprintf(fp," return %s;\n", encoding); | 2998 fprintf(fp," return %s;\n", encoding); |
2893 } else { | 2999 } else { |
3000 globalAD->syntax_err(oper._linenum, "In operand %s: Do not support this encode constant: '%s' for %s.", | |
3001 oper._ident, encoding, name); | |
2894 assert( false, "Do not support octal or decimal encode constants"); | 3002 assert( false, "Do not support octal or decimal encode constants"); |
2895 } | 3003 } |
2896 fprintf(fp," }\n"); | 3004 fprintf(fp," }\n"); |
2897 | 3005 |
2898 if( emit_position && (position != -1) && (oper.num_edges(globals) > 0) ) { | 3006 if( emit_position && (position != -1) && (oper.num_edges(globals) > 0) ) { |
3140 _instructions.reset(); | 3248 _instructions.reset(); |
3141 for( ; (instr = (InstructForm*)_instructions.iter()) != NULL; ) { | 3249 for( ; (instr = (InstructForm*)_instructions.iter()) != NULL; ) { |
3142 // Ensure this is a machine-world instruction | 3250 // Ensure this is a machine-world instruction |
3143 if ( instr->ideal_only() ) continue; | 3251 if ( instr->ideal_only() ) continue; |
3144 | 3252 |
3145 if (instr->_insencode) defineEmit (fp, *instr); | 3253 if (instr->_insencode) { |
3254 if (instr->postalloc_expands()) { | |
3255 // Don't write this to _CPP_EXPAND_file, as the code generated calls C-code | |
3256 // from code sections in ad file that is dumped to fp. | |
3257 define_postalloc_expand(fp, *instr); | |
3258 } else { | |
3259 defineEmit(fp, *instr); | |
3260 } | |
3261 } | |
3146 if (instr->is_mach_constant()) defineEvalConstant(fp, *instr); | 3262 if (instr->is_mach_constant()) defineEvalConstant(fp, *instr); |
3147 if (instr->_size) defineSize (fp, *instr); | 3263 if (instr->_size) defineSize (fp, *instr); |
3148 | 3264 |
3149 // side-call to generate output that used to be in the header file: | 3265 // side-call to generate output that used to be in the header file: |
3150 extern void gen_inst_format(FILE *fp, FormDict &globals, InstructForm &oper, bool for_c_file); | 3266 extern void gen_inst_format(FILE *fp, FormDict &globals, InstructForm &oper, bool for_c_file); |