src/share/vm/adlc/output_c.cpp

Print this page
rev 5661 : 8003854: PPC64 (part 115): Introduce lateExpand that expands nodes after register allocation.

*** 2486,2496 **** //(2) // Print the size fprintf(fp, " return (VerifyOops ? MachNode::size(ra_) : %s);\n", inst._size); // (3) and (4) ! fprintf(fp,"}\n"); } // defineEmit ----------------------------------------------------------------- void ArchDesc::defineEmit(FILE* fp, InstructForm& inst) { InsEncode* encode = inst._insencode; --- 2486,2602 ---- //(2) // Print the size fprintf(fp, " return (VerifyOops ? MachNode::size(ra_) : %s);\n", inst._size); // (3) and (4) ! fprintf(fp,"}\n\n"); ! } ! ! // Emit late expand function. ! void ArchDesc::defineLateExpand(FILE *fp, InstructForm &inst) { ! InsEncode *ins_encode = inst._insencode; ! ! // Output instruction's lateExpand prototype. ! fprintf(fp, "void %sNode::lateExpand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {\n", ! inst._ident); ! ! assert((_encode != NULL) && (ins_encode != NULL), "You must define an encode section."); ! ! // Output each operand's offset into the array of registers. ! inst.index_temps(fp, _globalNames); ! ! // Output variables "unsigned idx_<par_name>", Node *n_<par_name> and "MachOpnd *op_<par_name>" ! // for each parameter <par_name> specified in the encoding. ! ins_encode->reset(); ! const char *ec_name = ins_encode->encode_class_iter(); ! assert(ec_name != NULL, "late expand must specify an encoding"); ! ! EncClass *encoding = _encode->encClass(ec_name); ! if (encoding == NULL) { ! fprintf(stderr, "User did not define contents of this encode_class: %s\n", ec_name); ! abort(); ! } ! if (ins_encode->current_encoding_num_args() != encoding->num_args()) { ! globalAD->syntax_err(ins_encode->_linenum, "In %s: passing %d arguments to %s but expecting %d", ! inst._ident, ins_encode->current_encoding_num_args(), ! ec_name, encoding->num_args()); ! } ! ! fprintf(fp, " // Access to ins and operands for late expand.\n"); ! const int buflen = 2000; ! char idxbuf[buflen]; char *ib = idxbuf; sprintf(ib, ""); ! char nbuf [buflen]; char *nb = nbuf; sprintf(nb, ""); ! char opbuf [buflen]; char *ob = opbuf; sprintf(ob, ""); ! ! encoding->_parameter_type.reset(); ! encoding->_parameter_name.reset(); ! const char *type = encoding->_parameter_type.iter(); ! const char *name = encoding->_parameter_name.iter(); ! int param_no = 0; ! for (; (type != NULL) && (name != NULL); ! (type = encoding->_parameter_type.iter()), (name = encoding->_parameter_name.iter())) { ! const char* arg_name = ins_encode->rep_var_name(inst, param_no); ! int idx = inst.operand_position_format(arg_name); ! if (strcmp(arg_name, "constanttablebase") == 0) { ! ib += sprintf(ib, " unsigned idx_%-5s = mach_constant_base_node_input(); \t// %s, \t%s\n", ! name, type, arg_name); ! nb += sprintf(nb, " Node *n_%-7s = lookup(idx_%s);\n", name, name); ! // There is no operand for the constanttablebase. ! } else if (inst.is_noninput_operand(idx)) { ! globalAD->syntax_err(inst._linenum, ! "In %s: you can not pass the non-input %s to a late expand encoding.\n", ! inst._ident, arg_name); ! } else { ! ib += sprintf(ib, " unsigned idx_%-5s = idx%d; \t// %s, \t%s\n", ! name, idx, type, arg_name); ! nb += sprintf(nb, " Node *n_%-7s = lookup(idx_%s);\n", name, name); ! ob += sprintf(ob, " %sOper *op_%s = (%sOper *)opnd_array(%d);\n", type, name, type, idx); ! } ! param_no++; ! } ! assert(ib < &idxbuf[buflen-1] && nb < &nbuf[buflen-1] && ob < &opbuf[buflen-1], "buffer overflow"); ! ! fprintf(fp, "%s", idxbuf); ! fprintf(fp, " Node *n_region = lookup(0);\n"); ! fprintf(fp, "%s%s", nbuf, opbuf); ! fprintf(fp, " Compile *C = ra_->C;\n"); ! ! // Output this instruction's encodings. ! fprintf(fp, " {"); ! const char *ec_code = NULL; ! const char *ec_rep_var = NULL; ! assert(encoding == _encode->encClass(ec_name), ""); ! ! DefineEmitState pending(fp, *this, *encoding, *ins_encode, inst); ! encoding->_code.reset(); ! encoding->_rep_vars.reset(); ! // Process list of user-defined strings, ! // and occurrences of replacement variables. ! // Replacement Vars are pushed into a list and then output. ! while ((ec_code = encoding->_code.iter()) != NULL) { ! if (! encoding->_code.is_signal(ec_code)) { ! // Emit pending code. ! pending.emit(); ! pending.clear(); ! // Emit this code section. ! fprintf(fp, "%s", ec_code); ! } else { ! // A replacement variable or one of its subfields. ! // Obtain replacement variable from list. ! ec_rep_var = encoding->_rep_vars.iter(); ! pending.add_rep_var(ec_rep_var); ! } ! } ! // Emit pending code. ! pending.emit(); ! pending.clear(); ! fprintf(fp, " }\n"); ! ! fprintf(fp, "}\n\n"); ! ! ec_name = ins_encode->encode_class_iter(); ! assert(ec_name == NULL, "Late expand may only have one encoding."); } // defineEmit ----------------------------------------------------------------- void ArchDesc::defineEmit(FILE* fp, InstructForm& inst) { InsEncode* encode = inst._insencode;
*** 2839,2849 **** fprintf(fp,"(PhaseRegAlloc *ra_, const Node *node, int idx) const { \n"); emit_position = true; } else if ( (strcmp(name,"disp") == 0) ) { fprintf(fp,"(PhaseRegAlloc *ra_, const Node *node, int idx) const { \n"); } else { ! fprintf(fp,"() const { \n"); } // Check for hexadecimal value OR replacement variable if( *encoding == '$' ) { // Replacement variable --- 2945,2955 ---- fprintf(fp,"(PhaseRegAlloc *ra_, const Node *node, int idx) const { \n"); emit_position = true; } else if ( (strcmp(name,"disp") == 0) ) { fprintf(fp,"(PhaseRegAlloc *ra_, const Node *node, int idx) const { \n"); } else { ! fprintf(fp, "() const {\n"); } // Check for hexadecimal value OR replacement variable if( *encoding == '$' ) { // Replacement variable
*** 2889,2898 **** --- 2995,3006 ---- } else if( *encoding == '0' && *(encoding+1) == 'x' ) { // Hex value fprintf(fp," return %s;\n", encoding); } else { + globalAD->syntax_err(oper._linenum, "In operand %s: Do not support this encode constant: '%s' for %s.", + oper._ident, encoding, name); assert( false, "Do not support octal or decimal encode constants"); } fprintf(fp," }\n"); if( emit_position && (position != -1) && (oper.num_edges(globals) > 0) ) {
*** 3140,3150 **** _instructions.reset(); for( ; (instr = (InstructForm*)_instructions.iter()) != NULL; ) { // Ensure this is a machine-world instruction if ( instr->ideal_only() ) continue; ! if (instr->_insencode) defineEmit (fp, *instr); if (instr->is_mach_constant()) defineEvalConstant(fp, *instr); if (instr->_size) defineSize (fp, *instr); // side-call to generate output that used to be in the header file: extern void gen_inst_format(FILE *fp, FormDict &globals, InstructForm &oper, bool for_c_file); --- 3248,3266 ---- _instructions.reset(); for( ; (instr = (InstructForm*)_instructions.iter()) != NULL; ) { // Ensure this is a machine-world instruction if ( instr->ideal_only() ) continue; ! if (instr->_insencode) { ! if (instr->lateExpands()) { ! // Don't write this to _CPP_EXPAND_file, as the code generated calls C-code ! // from code sections in ad file that is dumped to fp. ! defineLateExpand(fp, *instr); ! } else { ! defineEmit(fp, *instr); ! } ! } if (instr->is_mach_constant()) defineEvalConstant(fp, *instr); if (instr->_size) defineSize (fp, *instr); // side-call to generate output that used to be in the header file: extern void gen_inst_format(FILE *fp, FormDict &globals, InstructForm &oper, bool for_c_file);