Print this page
rev 1839 : 6961690: load oops from constant table on SPARC
Summary: oops should be loaded from the constant table of an nmethod instead of materializing them with a long code sequence.
Reviewed-by:

Split Close
Expand all
Collapse all
          --- old/src/share/vm/adlc/output_c.cpp
          +++ new/src/share/vm/adlc/output_c.cpp
↓ open down ↓ 1488 lines elided ↑ open up ↑
1489 1489    fprintf(fp, "}\n");
1490 1490    fprintf(fp, "\n");
1491 1491  }
1492 1492  
1493 1493  // Define the Expand method for an instruction node
1494 1494  void ArchDesc::defineExpand(FILE *fp, InstructForm *node) {
1495 1495    unsigned      cnt  = 0;          // Count nodes we have expand into
1496 1496    unsigned      i;
1497 1497  
1498 1498    // Generate Expand function header
1499      -  fprintf(fp,"MachNode *%sNode::Expand(State *state, Node_List &proj_list, Node* mem) {\n", node->_ident);
1500      -  fprintf(fp,"Compile* C = Compile::current();\n");
     1499 +  fprintf(fp, "MachNode* %sNode::Expand(State* state, Node_List& proj_list, Node* mem) {\n", node->_ident);
     1500 +  fprintf(fp, "  Compile* C = Compile::current();\n");
1501 1501    // Generate expand code
1502 1502    if( node->expands() ) {
1503 1503      const char   *opid;
1504 1504      int           new_pos, exp_pos;
1505 1505      const char   *new_id   = NULL;
1506 1506      const Form   *frm      = NULL;
1507 1507      InstructForm *new_inst = NULL;
1508 1508      OperandForm  *new_oper = NULL;
1509 1509      unsigned      numo     = node->num_opnds() +
1510 1510                                  node->_exprule->_newopers.count();
↓ open down ↓ 300 lines elided ↑ open up ↑
1811 1811          }
1812 1812  
1813 1813          fprintf(fp,"  kill = ");
1814 1814          fprintf(fp,"new (C, 1) MachProjNode( %s, %d, (%s), Op_%s );\n",
1815 1815                  machNode, proj_no++, regmask, ideal_type);
1816 1816          fprintf(fp,"  proj_list.push(kill);\n");
1817 1817        }
1818 1818      }
1819 1819    }
1820 1820  
     1821 +  // If the node is a MachConstantNode, insert the MachConstantBaseNode edge.
     1822 +  // NOTE: this edge must be the last input (see MachConstantNode::mach_constant_base_node_input).
     1823 +  if (node->is_mach_constant()) {
     1824 +    fprintf(fp,"  add_req(C->mach_constant_base_node());\n");
     1825 +  }
     1826 +
1821 1827    fprintf(fp,"\n");
1822 1828    if( node->expands() ) {
1823 1829      fprintf(fp,"  return result;\n");
1824 1830    } else {
1825 1831      fprintf(fp,"  return this;\n");
1826 1832    }
1827 1833    fprintf(fp,"}\n");
1828 1834    fprintf(fp,"\n");
1829 1835  }
1830 1836  
↓ open down ↓ 86 lines elided ↑ open up ↑
1917 1923    void update_state(const char *rep_var) {
1918 1924      // A replacement variable or one of its subfields
1919 1925      // Obtain replacement variable from list
1920 1926      if ( (*rep_var) != '$' ) {
1921 1927        // A replacement variable, '$' prefix
1922 1928        // check_rep_var( rep_var );
1923 1929        if ( Opcode::as_opcode_type(rep_var) != Opcode::NOT_AN_OPCODE ) {
1924 1930          // No state needed.
1925 1931          assert( _opclass == NULL,
1926 1932                  "'primary', 'secondary' and 'tertiary' don't follow operand.");
1927      -      } else {
     1933 +      }
     1934 +      else if ((strcmp(rep_var, "constanttablebase") == 0) ||
     1935 +               (strcmp(rep_var, "constantoffset")    == 0) ||
     1936 +               (strcmp(rep_var, "constantaddress")   == 0)) {
     1937 +        if (!_inst.is_mach_constant()) {
     1938 +          _AD.syntax_err(_encoding._linenum,
     1939 +                         "Replacement variable %s not allowed in instruct %s (only in MachConstantNode).\n",
     1940 +                         rep_var, _encoding._name);
     1941 +        }
     1942 +      }
     1943 +      else {
1928 1944          // Lookup its position in parameter list
1929 1945          int   param_no  = _encoding.rep_var_index(rep_var);
1930 1946          if ( param_no == -1 ) {
1931 1947            _AD.syntax_err( _encoding._linenum,
1932 1948                            "Replacement variable %s not found in enc_class %s.\n",
1933 1949                            rep_var, _encoding._name);
1934 1950          }
1935 1951  
1936 1952          // Lookup the corresponding ins_encode parameter
1937 1953          const char *inst_rep_var = _ins_encode.rep_var_name(_inst, param_no);
↓ open down ↓ 435 lines elided ↑ open up ↑
2373 2389      _processing_noninput = false;
2374 2390      // A replacement variable, originally '$'
2375 2391      if ( Opcode::as_opcode_type(rep_var) != Opcode::NOT_AN_OPCODE ) {
2376 2392        if (!_inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(rep_var) )) {
2377 2393          // Missing opcode
2378 2394          _AD.syntax_err( _inst._linenum,
2379 2395                          "Missing $%s opcode definition in %s, used by encoding %s\n",
2380 2396                          rep_var, _inst._ident, _encoding._name);
2381 2397        }
2382 2398      }
     2399 +    else if (strcmp(rep_var, "constanttablebase") == 0) {
     2400 +      fprintf(_fp, "as_Register(ra_->get_encode(in(mach_constant_base_node_input())))");
     2401 +    }
     2402 +    else if (strcmp(rep_var, "constantoffset") == 0) {
     2403 +      fprintf(_fp, "constant_offset()");
     2404 +    }
     2405 +    else if (strcmp(rep_var, "constantaddress") == 0) {
     2406 +      fprintf(_fp, "InternalAddress(__ code()->consts()->start() + constant_offset())");
     2407 +    }
2383 2408      else {
2384 2409        // Lookup its position in parameter list
2385 2410        int   param_no  = _encoding.rep_var_index(rep_var);
2386 2411        if ( param_no == -1 ) {
2387 2412          _AD.syntax_err( _encoding._linenum,
2388 2413                          "Replacement variable %s not found in enc_class %s.\n",
2389 2414                          rep_var, _encoding._name);
2390 2415        }
2391 2416        // Lookup the corresponding ins_encode parameter
2392 2417        const char *inst_rep_var = _ins_encode.rep_var_name(_inst, param_no);
↓ open down ↓ 65 lines elided ↑ open up ↑
2458 2483    fprintf(fp, " assert(VerifyOops || MachNode::size(ra_) <= %s, \"bad fixed size\");\n", inst._size);
2459 2484  
2460 2485    //(2)
2461 2486    // Print the size
2462 2487    fprintf(fp, " return (VerifyOops ? MachNode::size(ra_) : %s);\n", inst._size);
2463 2488  
2464 2489    // (3) and (4)
2465 2490    fprintf(fp,"}\n");
2466 2491  }
2467 2492  
2468      -void ArchDesc::defineEmit(FILE *fp, InstructForm &inst) {
2469      -  InsEncode *ins_encode = inst._insencode;
     2493 +// defineEmit -----------------------------------------------------------------
     2494 +void ArchDesc::defineEmit(FILE* fp, InstructForm& inst) {
     2495 +  InsEncode* encode = inst._insencode;
2470 2496  
2471 2497    // (1)
2472 2498    // Output instruction's emit prototype
2473      -  fprintf(fp,"void  %sNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {\n",
2474      -          inst._ident);
     2499 +  fprintf(fp, "void %sNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {\n", inst._ident);
2475 2500  
2476 2501    // If user did not define an encode section,
2477 2502    // provide stub that does not generate any machine code.
2478      -  if( (_encode == NULL) || (ins_encode == NULL) ) {
     2503 +  if( (_encode == NULL) || (encode == NULL) ) {
2479 2504      fprintf(fp, "  // User did not define an encode section.\n");
2480      -    fprintf(fp,"}\n");
     2505 +    fprintf(fp, "}\n");
2481 2506      return;
2482 2507    }
2483 2508  
2484 2509    // Save current instruction's starting address (helps with relocation).
2485      -  fprintf(fp, "    cbuf.set_insts_mark();\n");
     2510 +  fprintf(fp, "  cbuf.set_insts_mark();\n");
2486 2511  
2487      -  // // // idx0 is only needed for syntactic purposes and only by "storeSSI"
2488      -  // fprintf( fp, "    unsigned idx0  = 0;\n");
     2512 +  // For MachConstantNodes which are ideal jump nodes, fill the jump table.
     2513 +  if (inst.is_mach_constant() && inst.is_ideal_jump()) {
     2514 +    fprintf(fp, "  ra_->C->constant_table().fill_jump_table(cbuf, (MachConstantNode*) this, _index2label);\n");
     2515 +  }
2489 2516  
2490 2517    // Output each operand's offset into the array of registers.
2491      -  inst.index_temps( fp, _globalNames );
     2518 +  inst.index_temps(fp, _globalNames);
2492 2519  
2493 2520    // Output this instruction's encodings
2494 2521    const char *ec_name;
2495 2522    bool        user_defined = false;
2496      -  ins_encode->reset();
2497      -  while ( (ec_name = ins_encode->encode_class_iter()) != NULL ) {
2498      -    fprintf(fp, "  {");
     2523 +  encode->reset();
     2524 +  while ((ec_name = encode->encode_class_iter()) != NULL) {
     2525 +    fprintf(fp, "  {\n");
2499 2526      // Output user-defined encoding
2500 2527      user_defined           = true;
2501 2528  
2502 2529      const char *ec_code    = NULL;
2503 2530      const char *ec_rep_var = NULL;
2504 2531      EncClass   *encoding   = _encode->encClass(ec_name);
2505 2532      if (encoding == NULL) {
2506 2533        fprintf(stderr, "User did not define contents of this encode_class: %s\n", ec_name);
2507 2534        abort();
2508 2535      }
2509 2536  
2510      -    if (ins_encode->current_encoding_num_args() != encoding->num_args()) {
2511      -      globalAD->syntax_err(ins_encode->_linenum, "In %s: passing %d arguments to %s but expecting %d",
2512      -                           inst._ident, ins_encode->current_encoding_num_args(),
     2537 +    if (encode->current_encoding_num_args() != encoding->num_args()) {
     2538 +      globalAD->syntax_err(encode->_linenum, "In %s: passing %d arguments to %s but expecting %d",
     2539 +                           inst._ident, encode->current_encoding_num_args(),
2513 2540                             ec_name, encoding->num_args());
2514 2541      }
2515 2542  
2516      -    DefineEmitState  pending(fp, *this, *encoding, *ins_encode, inst );
     2543 +    DefineEmitState pending(fp, *this, *encoding, *encode, inst);
2517 2544      encoding->_code.reset();
2518 2545      encoding->_rep_vars.reset();
2519 2546      // Process list of user-defined strings,
2520 2547      // and occurrences of replacement variables.
2521 2548      // Replacement Vars are pushed into a list and then output
2522      -    while ( (ec_code = encoding->_code.iter()) != NULL ) {
2523      -      if ( ! encoding->_code.is_signal( ec_code ) ) {
     2549 +    while ((ec_code = encoding->_code.iter()) != NULL) {
     2550 +      if (!encoding->_code.is_signal(ec_code)) {
2524 2551          // Emit pending code
2525 2552          pending.emit();
2526 2553          pending.clear();
2527 2554          // Emit this code section
2528      -        fprintf(fp,"%s", ec_code);
     2555 +        fprintf(fp, "%s", ec_code);
2529 2556        } else {
2530 2557          // A replacement variable or one of its subfields
2531 2558          // Obtain replacement variable from list
2532 2559          ec_rep_var  = encoding->_rep_vars.iter();
2533 2560          pending.add_rep_var(ec_rep_var);
2534 2561        }
2535 2562      }
2536 2563      // Emit pending code
2537 2564      pending.emit();
2538 2565      pending.clear();
2539      -    fprintf(fp, "}\n");
     2566 +    fprintf(fp, "  }\n");
2540 2567    } // end while instruction's encodings
2541 2568  
2542 2569    // Check if user stated which encoding to user
2543 2570    if ( user_defined == false ) {
2544 2571      fprintf(fp, "  // User did not define which encode class to use.\n");
2545 2572    }
2546 2573  
2547 2574    // (3) and (4)
2548      -  fprintf(fp,"}\n");
     2575 +  fprintf(fp, "}\n");
     2576 +}
     2577 +
     2578 +// defineEvalConstant ---------------------------------------------------------
     2579 +void ArchDesc::defineEvalConstant(FILE* fp, InstructForm& inst) {
     2580 +  InsEncode* encode = inst._constant;
     2581 +
     2582 +  // (1)
     2583 +  // Output instruction's emit prototype
     2584 +  fprintf(fp, "void %sNode::eval_constant(Compile* C) {\n", inst._ident);
     2585 +
     2586 +  // For ideal jump nodes, allocate a jump table.
     2587 +  if (inst.is_ideal_jump()) {
     2588 +    fprintf(fp, "  _constant = C->constant_table().allocate_jump_table(this);\n");
     2589 +  }
     2590 +
     2591 +  // If user did not define an encode section,
     2592 +  // provide stub that does not generate any machine code.
     2593 +  if ((_encode == NULL) || (encode == NULL)) {
     2594 +    fprintf(fp, "  // User did not define an encode section.\n");
     2595 +    fprintf(fp, "}\n");
     2596 +    return;
     2597 +  }
     2598 +
     2599 +  // Output this instruction's encodings
     2600 +  const char *ec_name;
     2601 +  bool        user_defined = false;
     2602 +  encode->reset();
     2603 +  while ((ec_name = encode->encode_class_iter()) != NULL) {
     2604 +    fprintf(fp, "  {\n");
     2605 +    // Output user-defined encoding
     2606 +    user_defined           = true;
     2607 +
     2608 +    const char *ec_code    = NULL;
     2609 +    const char *ec_rep_var = NULL;
     2610 +    EncClass   *encoding   = _encode->encClass(ec_name);
     2611 +    if (encoding == NULL) {
     2612 +      fprintf(stderr, "User did not define contents of this encode_class: %s\n", ec_name);
     2613 +      abort();
     2614 +    }
     2615 +
     2616 +    if (encode->current_encoding_num_args() != encoding->num_args()) {
     2617 +      globalAD->syntax_err(encode->_linenum, "In %s: passing %d arguments to %s but expecting %d",
     2618 +                           inst._ident, encode->current_encoding_num_args(),
     2619 +                           ec_name, encoding->num_args());
     2620 +    }
     2621 +
     2622 +    DefineEmitState pending(fp, *this, *encoding, *encode, inst);
     2623 +    encoding->_code.reset();
     2624 +    encoding->_rep_vars.reset();
     2625 +    // Process list of user-defined strings,
     2626 +    // and occurrences of replacement variables.
     2627 +    // Replacement Vars are pushed into a list and then output
     2628 +    while ((ec_code = encoding->_code.iter()) != NULL) {
     2629 +      if (!encoding->_code.is_signal(ec_code)) {
     2630 +        // Emit pending code
     2631 +        pending.emit();
     2632 +        pending.clear();
     2633 +        // Emit this code section
     2634 +        fprintf(fp, "%s", ec_code);
     2635 +      } else {
     2636 +        // A replacement variable or one of its subfields
     2637 +        // Obtain replacement variable from list
     2638 +        ec_rep_var  = encoding->_rep_vars.iter();
     2639 +        pending.add_rep_var(ec_rep_var);
     2640 +      }
     2641 +    }
     2642 +    // Emit pending code
     2643 +    pending.emit();
     2644 +    pending.clear();
     2645 +    fprintf(fp, "  }\n");
     2646 +  } // end while instruction's encodings
     2647 +
     2648 +  // Check if user stated which encoding to user
     2649 +  if (user_defined == false) {
     2650 +    fprintf(fp, "  // User did not define which encode class to use.\n");
     2651 +  }
     2652 +
     2653 +  // (3) and (4)
     2654 +  fprintf(fp, "}\n");
2549 2655  }
2550 2656  
2551 2657  // ---------------------------------------------------------------------------
2552 2658  //--------Utilities to build MachOper and MachNode derived Classes------------
2553 2659  // ---------------------------------------------------------------------------
2554 2660  
2555 2661  //------------------------------Utilities to build Operand Classes------------
2556 2662  static void defineIn_RegMask(FILE *fp, FormDict &globals, OperandForm &oper) {
2557 2663    uint num_edges = oper.num_edges(globals);
2558 2664    if( num_edges != 0 ) {
↓ open down ↓ 386 lines elided ↑ open up ↑
2945 3051  
2946 3052    bool used = false;
2947 3053    // Output the definitions for expand rules & peephole rules
2948 3054    _instructions.reset();
2949 3055    for( ; (instr = (InstructForm*)_instructions.iter()) != NULL; ) {
2950 3056      // Ensure this is a machine-world instruction
2951 3057      if ( instr->ideal_only() ) continue;
2952 3058      // If there are multiple defs/kills, or an explicit expand rule, build rule
2953 3059      if( instr->expands() || instr->needs_projections() ||
2954 3060          instr->has_temps() ||
     3061 +        instr->is_mach_constant() ||
2955 3062          instr->_matrule != NULL &&
2956 3063          instr->num_opnds() != instr->num_unique_opnds() )
2957 3064        defineExpand(_CPP_EXPAND_file._fp, instr);
2958 3065      // If there is an explicit peephole rule, build it
2959 3066      if ( instr->peepholes() )
2960 3067        definePeephole(_CPP_PEEPHOLE_file._fp, instr);
2961 3068  
2962 3069      // Output code to convert to the cisc version, if applicable
2963 3070      used |= instr->define_cisc_version(*this, fp);
2964 3071  
↓ open down ↓ 60 lines elided ↑ open up ↑
3025 3132    // address  ___Node::emit(address ptr, PhaseRegAlloc *ra_) const {
3026 3133    //   // ...  encoding defined by user
3027 3134    //   return ptr;
3028 3135    // }
3029 3136    //
3030 3137    _instructions.reset();
3031 3138    for( ; (instr = (InstructForm*)_instructions.iter()) != NULL; ) {
3032 3139      // Ensure this is a machine-world instruction
3033 3140      if ( instr->ideal_only() ) continue;
3034 3141  
3035      -    if (instr->_insencode) defineEmit(fp, *instr);
3036      -    if (instr->_size)      defineSize(fp, *instr);
     3142 +    if (instr->_insencode)         defineEmit        (fp, *instr);
     3143 +    if (instr->is_mach_constant()) defineEvalConstant(fp, *instr);
     3144 +    if (instr->_size)              defineSize        (fp, *instr);
3037 3145  
3038 3146      // side-call to generate output that used to be in the header file:
3039 3147      extern void gen_inst_format(FILE *fp, FormDict &globals, InstructForm &oper, bool for_c_file);
3040 3148      gen_inst_format(_CPP_FORMAT_file._fp, _globalNames, *instr, true);
3041 3149    }
3042 3150  
3043 3151    // Output the definitions for alias analysis
3044 3152    _instructions.reset();
3045 3153    for( ; (instr = (InstructForm*)_instructions.iter()) != NULL; ) {
3046 3154      // Ensure this is a machine-world instruction
↓ open down ↓ 1105 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX