# HG changeset patch # User goetz # Date 1384974489 28800 # Node ID 318d0622a6d7248070277b49bb564c5bd67d63b7 # Parent 018b357638aa9b94b26126468b7e9757634c83be 8028580: PPC64 (part 114/120): Support for Call nodes with constants. Summary: extends MachCall nodes so that they can issue constants to the constant table Reviewed-by: kvn diff -r 018b357638aa -r 318d0622a6d7 src/share/vm/adlc/adlparse.cpp --- a/src/share/vm/adlc/adlparse.cpp Tue Nov 19 11:53:58 2013 -0800 +++ b/src/share/vm/adlc/adlparse.cpp Wed Nov 20 11:08:09 2013 -0800 @@ -2863,7 +2863,10 @@ // Check if this instruct is a MachConstantNode. if (strcmp(rep_var, "constanttablebase") == 0) { // This instruct is a MachConstantNode. - inst.set_is_mach_constant(true); + inst.set_needs_constant_base(true); + if (strncmp("MachCall", inst.mach_base_class(_globalNames), strlen("MachCall")) != 0 ) { + inst.set_is_mach_constant(true); + } if (_curchar == '(') { parse_err(SYNERR, "constanttablebase in instruct %s cannot have an argument " @@ -2965,18 +2968,34 @@ while (_curchar != ')') { char *param = get_ident_or_literal_constant("encoding operand"); if ( param != NULL ) { - // Found a parameter: - // Check it is a local name, add it to the list, then check for more - // New: allow hex constants as parameters to an encode method. - // New: allow parenthesized expressions as parameters. - // New: allow "primary", "secondary", "tertiary" as parameters. - // New: allow user-defined register name as parameter - if ( (inst._localNames[param] == NULL) && - !ADLParser::is_literal_constant(param) && - (Opcode::as_opcode_type(param) == Opcode::NOT_AN_OPCODE) && - ((_AD._register == NULL ) || (_AD._register->getRegDef(param) == NULL)) ) { - parse_err(SYNERR, "Using non-locally defined parameter %s for encoding %s.\n", param, ec_name); - return; + + // Check if this instruct is a MachConstantNode. + if (strcmp(param, "constanttablebase") == 0) { + // This instruct is a MachConstantNode. + inst.set_needs_constant_base(true); + if (strncmp("MachCall", inst.mach_base_class(_globalNames), strlen("MachCall")) != 0 ) { + inst.set_is_mach_constant(true); + } + + if (_curchar == '(') { + parse_err(SYNERR, "constanttablebase in instruct %s cannot have an argument " + "(only constantaddress and constantoffset)", ec_name); + return; + } + } else { + // Found a parameter: + // Check it is a local name, add it to the list, then check for more + // New: allow hex constants as parameters to an encode method. + // New: allow parenthesized expressions as parameters. + // New: allow "primary", "secondary", "tertiary" as parameters. + // New: allow user-defined register name as parameter + if ( (inst._localNames[param] == NULL) && + !ADLParser::is_literal_constant(param) && + (Opcode::as_opcode_type(param) == Opcode::NOT_AN_OPCODE) && + ((_AD._register == NULL ) || (_AD._register->getRegDef(param) == NULL)) ) { + parse_err(SYNERR, "Using non-locally defined parameter %s for encoding %s.\n", param, ec_name); + return; + } } params->add_entry(param); @@ -3122,7 +3141,10 @@ // Check if this instruct is a MachConstantNode. if (strcmp(param, "constanttablebase") == 0) { // This instruct is a MachConstantNode. - inst.set_is_mach_constant(true); + inst.set_needs_constant_base(true); + if (strncmp("MachCall", inst.mach_base_class(_globalNames), strlen("MachCall")) != 0 ) { + inst.set_is_mach_constant(true); + } if (_curchar == '(') { parse_err(SYNERR, "constanttablebase in instruct %s cannot have an argument " diff -r 018b357638aa -r 318d0622a6d7 src/share/vm/adlc/formssel.cpp --- a/src/share/vm/adlc/formssel.cpp Tue Nov 19 11:53:58 2013 -0800 +++ b/src/share/vm/adlc/formssel.cpp Wed Nov 20 11:08:09 2013 -0800 @@ -32,6 +32,7 @@ _localNames(cmpstr, hashstr, Form::arena), _effects(cmpstr, hashstr, Form::arena), _is_mach_constant(false), + _needs_constant_base(false), _has_call(false) { _ftype = Form::INS; @@ -65,6 +66,7 @@ _localNames(instr->_localNames), _effects(instr->_effects), _is_mach_constant(false), + _needs_constant_base(false), _has_call(false) { _ftype = Form::INS; diff -r 018b357638aa -r 318d0622a6d7 src/share/vm/adlc/formssel.hpp --- a/src/share/vm/adlc/formssel.hpp Tue Nov 19 11:53:58 2013 -0800 +++ b/src/share/vm/adlc/formssel.hpp Wed Nov 20 11:08:09 2013 -0800 @@ -83,7 +83,8 @@ const char *_cisc_reg_mask_name; InstructForm *_short_branch_form; bool _is_short_branch; - bool _is_mach_constant; // true if Node is a MachConstantNode + bool _is_mach_constant; // True if Node is a MachConstantNode. + bool _needs_constant_base; // True if Node needs the mach_constant_base input. uint _alignment; public: @@ -262,6 +263,8 @@ bool is_mach_constant() const { return _is_mach_constant; } void set_is_mach_constant(bool x) { _is_mach_constant = x; } + bool needs_constant_base() const { return _needs_constant_base; } + void set_needs_constant_base(bool x) { _needs_constant_base = x; } InstructForm *short_branch_form() { return _short_branch_form; } bool has_short_branch_form() { return _short_branch_form != NULL; } diff -r 018b357638aa -r 318d0622a6d7 src/share/vm/adlc/output_c.cpp --- a/src/share/vm/adlc/output_c.cpp Tue Nov 19 11:53:58 2013 -0800 +++ b/src/share/vm/adlc/output_c.cpp Wed Nov 20 11:08:09 2013 -0800 @@ -1839,7 +1839,9 @@ // If the node is a MachConstantNode, insert the MachConstantBaseNode edge. // NOTE: this edge must be the last input (see MachConstantNode::mach_constant_base_node_input). - if (node->is_mach_constant()) { + // There are nodes that don't use $constantablebase, but still require that it + // is an input to the node. Example: divF_reg_immN, Repl32B_imm on x86_64. + if (node->is_mach_constant() || node->needs_constant_base()) { fprintf(fp," add_req(C->mach_constant_base_node());\n"); } @@ -1952,9 +1954,9 @@ else if ((strcmp(rep_var, "constanttablebase") == 0) || (strcmp(rep_var, "constantoffset") == 0) || (strcmp(rep_var, "constantaddress") == 0)) { - if (!_inst.is_mach_constant()) { + if (!(_inst.is_mach_constant() || _inst.needs_constant_base())) { _AD.syntax_err(_encoding._linenum, - "Replacement variable %s not allowed in instruct %s (only in MachConstantNode).\n", + "Replacement variable %s not allowed in instruct %s (only in MachConstantNode or MachCall).\n", rep_var, _encoding._name); } } @@ -3182,6 +3184,7 @@ if( instr->expands() || instr->needs_projections() || instr->has_temps() || instr->is_mach_constant() || + instr->needs_constant_base() || instr->_matrule != NULL && instr->num_opnds() != instr->num_unique_opnds() ) defineExpand(_CPP_EXPAND_file._fp, instr); @@ -3954,8 +3957,10 @@ } // Fill in the bottom_type where requested - if ( inst->captures_bottom_type(_globalNames) ) { - fprintf(fp_cpp, "%s node->_bottom_type = _leaf->bottom_type();\n", indent); + if (inst->captures_bottom_type(_globalNames)) { + if (strncmp("MachCall", inst->mach_base_class(_globalNames), strlen("MachCall"))) { + fprintf(fp_cpp, "%s node->_bottom_type = _leaf->bottom_type();\n", indent); + } } if( inst->is_ideal_if() ) { fprintf(fp_cpp, "%s node->_prob = _leaf->as_If()->_prob;\n", indent); diff -r 018b357638aa -r 318d0622a6d7 src/share/vm/adlc/output_h.cpp --- a/src/share/vm/adlc/output_h.cpp Tue Nov 19 11:53:58 2013 -0800 +++ b/src/share/vm/adlc/output_h.cpp Wed Nov 20 11:08:09 2013 -0800 @@ -1614,7 +1614,7 @@ if (strcmp (attr->_ident,"ins_cost") && strncmp(attr->_ident,"ins_field_", 10) != 0 && strcmp (attr->_ident,"ins_short_branch")) { - fprintf(fp," int %s() const { return %s; }\n", + fprintf(fp," virtual int %s() const { return %s; }\n", attr->_ident, attr->_val); } // Check value for ins_avoid_back_to_back, and if it is true (1), set the flag @@ -1655,6 +1655,11 @@ instr->ideal_Opcode(_globalNames) ); } + if (instr->needs_constant_base() && + !instr->is_mach_constant()) { // These inherit the funcion from MachConstantNode. + fprintf(fp," virtual uint mach_constant_base_node_input() const { return req()-1; }\n"); + } + // Allow machine-independent optimization, invert the sense of the IF test if( instr->is_ideal_if() ) { fprintf(fp," virtual void negate() { \n"); @@ -1823,6 +1828,7 @@ if( instr->expands() || instr->needs_projections() || instr->has_temps() || instr->is_mach_constant() || + instr->needs_constant_base() || instr->_matrule != NULL && instr->num_opnds() != instr->num_unique_opnds() ) { fprintf(fp," virtual MachNode *Expand(State *state, Node_List &proj_list, Node* mem);\n"); diff -r 018b357638aa -r 318d0622a6d7 src/share/vm/opto/machnode.cpp --- a/src/share/vm/opto/machnode.cpp Tue Nov 19 11:53:58 2013 -0800 +++ b/src/share/vm/opto/machnode.cpp Wed Nov 20 11:08:09 2013 -0800 @@ -648,10 +648,15 @@ //------------------------------Registers-------------------------------------- -const RegMask &MachCallNode::in_RegMask( uint idx ) const { +const RegMask &MachCallNode::in_RegMask(uint idx) const { // Values in the domain use the users calling convention, embodied in the // _in_rms array of RegMasks. - if (idx < tf()->domain()->cnt()) return _in_rms[idx]; + if (idx < tf()->domain()->cnt()) { + return _in_rms[idx]; + } + if (idx == mach_constant_base_node_input()) { + return MachConstantBaseNode::static_out_RegMask(); + } // Values outside the domain represent debug info return *Compile::current()->matcher()->idealreg2debugmask[in(idx)->ideal_reg()]; } @@ -678,7 +683,12 @@ const RegMask &MachCallJavaNode::in_RegMask(uint idx) const { // Values in the domain use the users calling convention, embodied in the // _in_rms array of RegMasks. - if (idx < tf()->domain()->cnt()) return _in_rms[idx]; + if (idx < tf()->domain()->cnt()) { + return _in_rms[idx]; + } + if (idx == mach_constant_base_node_input()) { + return MachConstantBaseNode::static_out_RegMask(); + } // Values outside the domain represent debug info Matcher* m = Compile::current()->matcher(); // If this call is a MethodHandle invoke we have to use a different diff -r 018b357638aa -r 318d0622a6d7 src/share/vm/opto/machnode.hpp --- a/src/share/vm/opto/machnode.hpp Tue Nov 19 11:53:58 2013 -0800 +++ b/src/share/vm/opto/machnode.hpp Wed Nov 20 11:08:09 2013 -0800 @@ -181,6 +181,9 @@ // Number of inputs which come before the first operand. // Generally at least 1, to skip the Control input virtual uint oper_input_base() const { return 1; } + // Position of constant base node in node's inputs. -1 if + // no constant base node input. + virtual uint mach_constant_base_node_input() const { return (uint)-1; } // Copy inputs and operands to new node of instruction. // Called from cisc_version() and short_branch_version(). @@ -250,6 +253,9 @@ // Return number of relocatable values contained in this instruction virtual int reloc() const { return 0; } + // Return number of words used for double constants in this instruction + virtual int ins_num_consts() const { return 0; } + // Hash and compare over operands. Used to do GVN on machine Nodes. virtual uint hash() const; virtual uint cmp( const Node &n ) const; @@ -412,7 +418,7 @@ } // Input edge of MachConstantBaseNode. - uint mach_constant_base_node_input() const { return req() - 1; } + virtual uint mach_constant_base_node_input() const { return req() - 1; } int constant_offset(); int constant_offset() const { return ((MachConstantNode*) this)->constant_offset(); } diff -r 018b357638aa -r 318d0622a6d7 src/share/vm/opto/output.cpp --- a/src/share/vm/opto/output.cpp Tue Nov 19 11:53:58 2013 -0800 +++ b/src/share/vm/opto/output.cpp Wed Nov 20 11:08:09 2013 -0800 @@ -1083,6 +1083,7 @@ assert(_frame_slots >= 0 && _frame_slots < 1000000, "sanity check"); if (has_mach_constant_base_node()) { + uint add_size = 0; // Fill the constant table. // Note: This must happen before shorten_branches. for (uint i = 0; i < _cfg->number_of_blocks(); i++) { @@ -1096,6 +1097,9 @@ if (n->is_MachConstant()) { MachConstantNode* machcon = n->as_MachConstant(); machcon->eval_constant(C); + } else if (n->is_Mach()) { + // On Power there are more nodes that issue constants. + add_size += (n->as_Mach()->ins_num_consts() * 8); } } } @@ -1103,7 +1107,7 @@ // Calculate the offsets of the constants and the size of the // constant table (including the padding to the next section). constant_table().calculate_offsets_and_size(); - const_req = constant_table().size(); + const_req = constant_table().size() + add_size; } // Initialize the space for the BufferBlob used to find and verify @@ -1374,7 +1378,7 @@ int offset = blk_starts[block_num] - current_offset; if (block_num >= i) { // Current and following block's offset are not - // finilized yet, adjust distance by the difference + // finalized yet, adjust distance by the difference // between calculated and final offsets of current block. offset -= (blk_starts[i] - blk_offset); }