mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-20 19:14:38 +02:00
8028580: PPC64 (part 114/120): Support for Call nodes with constants
Extends MachCall nodes so that they can issue constants to the constant table Reviewed-by: kvn
This commit is contained in:
parent
86fba81619
commit
d22bde2c91
8 changed files with 85 additions and 27 deletions
|
@ -2863,7 +2863,10 @@ void ADLParser::ins_encode_parse_block_impl(InstructForm& inst, EncClass* encodi
|
||||||
// Check if this instruct is a MachConstantNode.
|
// Check if this instruct is a MachConstantNode.
|
||||||
if (strcmp(rep_var, "constanttablebase") == 0) {
|
if (strcmp(rep_var, "constanttablebase") == 0) {
|
||||||
// This instruct is a MachConstantNode.
|
// 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 == '(') {
|
if (_curchar == '(') {
|
||||||
parse_err(SYNERR, "constanttablebase in instruct %s cannot have an argument "
|
parse_err(SYNERR, "constanttablebase in instruct %s cannot have an argument "
|
||||||
|
@ -2965,18 +2968,34 @@ void ADLParser::ins_encode_parse(InstructForm& inst) {
|
||||||
while (_curchar != ')') {
|
while (_curchar != ')') {
|
||||||
char *param = get_ident_or_literal_constant("encoding operand");
|
char *param = get_ident_or_literal_constant("encoding operand");
|
||||||
if ( param != NULL ) {
|
if ( param != NULL ) {
|
||||||
// Found a parameter:
|
|
||||||
// Check it is a local name, add it to the list, then check for more
|
// Check if this instruct is a MachConstantNode.
|
||||||
// New: allow hex constants as parameters to an encode method.
|
if (strcmp(param, "constanttablebase") == 0) {
|
||||||
// New: allow parenthesized expressions as parameters.
|
// This instruct is a MachConstantNode.
|
||||||
// New: allow "primary", "secondary", "tertiary" as parameters.
|
inst.set_needs_constant_base(true);
|
||||||
// New: allow user-defined register name as parameter
|
if (strncmp("MachCall", inst.mach_base_class(_globalNames), strlen("MachCall")) != 0 ) {
|
||||||
if ( (inst._localNames[param] == NULL) &&
|
inst.set_is_mach_constant(true);
|
||||||
!ADLParser::is_literal_constant(param) &&
|
}
|
||||||
(Opcode::as_opcode_type(param) == Opcode::NOT_AN_OPCODE) &&
|
|
||||||
((_AD._register == NULL ) || (_AD._register->getRegDef(param) == NULL)) ) {
|
if (_curchar == '(') {
|
||||||
parse_err(SYNERR, "Using non-locally defined parameter %s for encoding %s.\n", param, ec_name);
|
parse_err(SYNERR, "constanttablebase in instruct %s cannot have an argument "
|
||||||
return;
|
"(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);
|
params->add_entry(param);
|
||||||
|
|
||||||
|
@ -3122,7 +3141,10 @@ void ADLParser::postalloc_expand_parse(InstructForm& inst) {
|
||||||
// Check if this instruct is a MachConstantNode.
|
// Check if this instruct is a MachConstantNode.
|
||||||
if (strcmp(param, "constanttablebase") == 0) {
|
if (strcmp(param, "constanttablebase") == 0) {
|
||||||
// This instruct is a MachConstantNode.
|
// 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 == '(') {
|
if (_curchar == '(') {
|
||||||
parse_err(SYNERR, "constanttablebase in instruct %s cannot have an argument "
|
parse_err(SYNERR, "constanttablebase in instruct %s cannot have an argument "
|
||||||
|
|
|
@ -32,6 +32,7 @@ InstructForm::InstructForm(const char *id, bool ideal_only)
|
||||||
_localNames(cmpstr, hashstr, Form::arena),
|
_localNames(cmpstr, hashstr, Form::arena),
|
||||||
_effects(cmpstr, hashstr, Form::arena),
|
_effects(cmpstr, hashstr, Form::arena),
|
||||||
_is_mach_constant(false),
|
_is_mach_constant(false),
|
||||||
|
_needs_constant_base(false),
|
||||||
_has_call(false)
|
_has_call(false)
|
||||||
{
|
{
|
||||||
_ftype = Form::INS;
|
_ftype = Form::INS;
|
||||||
|
@ -65,6 +66,7 @@ InstructForm::InstructForm(const char *id, InstructForm *instr, MatchRule *rule)
|
||||||
_localNames(instr->_localNames),
|
_localNames(instr->_localNames),
|
||||||
_effects(instr->_effects),
|
_effects(instr->_effects),
|
||||||
_is_mach_constant(false),
|
_is_mach_constant(false),
|
||||||
|
_needs_constant_base(false),
|
||||||
_has_call(false)
|
_has_call(false)
|
||||||
{
|
{
|
||||||
_ftype = Form::INS;
|
_ftype = Form::INS;
|
||||||
|
|
|
@ -83,7 +83,8 @@ private:
|
||||||
const char *_cisc_reg_mask_name;
|
const char *_cisc_reg_mask_name;
|
||||||
InstructForm *_short_branch_form;
|
InstructForm *_short_branch_form;
|
||||||
bool _is_short_branch;
|
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;
|
uint _alignment;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -262,6 +263,8 @@ public:
|
||||||
|
|
||||||
bool is_mach_constant() const { return _is_mach_constant; }
|
bool is_mach_constant() const { return _is_mach_constant; }
|
||||||
void set_is_mach_constant(bool x) { _is_mach_constant = x; }
|
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; }
|
InstructForm *short_branch_form() { return _short_branch_form; }
|
||||||
bool has_short_branch_form() { return _short_branch_form != NULL; }
|
bool has_short_branch_form() { return _short_branch_form != NULL; }
|
||||||
|
|
|
@ -1839,7 +1839,9 @@ void ArchDesc::defineExpand(FILE *fp, InstructForm *node) {
|
||||||
|
|
||||||
// If the node is a MachConstantNode, insert the MachConstantBaseNode edge.
|
// 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).
|
// 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");
|
fprintf(fp," add_req(C->mach_constant_base_node());\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1952,9 +1954,9 @@ public:
|
||||||
else if ((strcmp(rep_var, "constanttablebase") == 0) ||
|
else if ((strcmp(rep_var, "constanttablebase") == 0) ||
|
||||||
(strcmp(rep_var, "constantoffset") == 0) ||
|
(strcmp(rep_var, "constantoffset") == 0) ||
|
||||||
(strcmp(rep_var, "constantaddress") == 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,
|
_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);
|
rep_var, _encoding._name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3182,6 +3184,7 @@ void ArchDesc::defineClasses(FILE *fp) {
|
||||||
if( instr->expands() || instr->needs_projections() ||
|
if( instr->expands() || instr->needs_projections() ||
|
||||||
instr->has_temps() ||
|
instr->has_temps() ||
|
||||||
instr->is_mach_constant() ||
|
instr->is_mach_constant() ||
|
||||||
|
instr->needs_constant_base() ||
|
||||||
instr->_matrule != NULL &&
|
instr->_matrule != NULL &&
|
||||||
instr->num_opnds() != instr->num_unique_opnds() )
|
instr->num_opnds() != instr->num_unique_opnds() )
|
||||||
defineExpand(_CPP_EXPAND_file._fp, instr);
|
defineExpand(_CPP_EXPAND_file._fp, instr);
|
||||||
|
@ -3954,8 +3957,10 @@ void ArchDesc::buildMachNode(FILE *fp_cpp, InstructForm *inst, const char *inden
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill in the bottom_type where requested
|
// Fill in the bottom_type where requested
|
||||||
if ( inst->captures_bottom_type(_globalNames) ) {
|
if (inst->captures_bottom_type(_globalNames)) {
|
||||||
fprintf(fp_cpp, "%s node->_bottom_type = _leaf->bottom_type();\n", indent);
|
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() ) {
|
if( inst->is_ideal_if() ) {
|
||||||
fprintf(fp_cpp, "%s node->_prob = _leaf->as_If()->_prob;\n", indent);
|
fprintf(fp_cpp, "%s node->_prob = _leaf->as_If()->_prob;\n", indent);
|
||||||
|
|
|
@ -1614,7 +1614,7 @@ void ArchDesc::declareClasses(FILE *fp) {
|
||||||
if (strcmp (attr->_ident,"ins_cost") &&
|
if (strcmp (attr->_ident,"ins_cost") &&
|
||||||
strncmp(attr->_ident,"ins_field_", 10) != 0 &&
|
strncmp(attr->_ident,"ins_field_", 10) != 0 &&
|
||||||
strcmp (attr->_ident,"ins_short_branch")) {
|
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);
|
attr->_ident, attr->_val);
|
||||||
}
|
}
|
||||||
// Check value for ins_avoid_back_to_back, and if it is true (1), set the flag
|
// Check value for ins_avoid_back_to_back, and if it is true (1), set the flag
|
||||||
|
@ -1655,6 +1655,11 @@ void ArchDesc::declareClasses(FILE *fp) {
|
||||||
instr->ideal_Opcode(_globalNames) );
|
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
|
// Allow machine-independent optimization, invert the sense of the IF test
|
||||||
if( instr->is_ideal_if() ) {
|
if( instr->is_ideal_if() ) {
|
||||||
fprintf(fp," virtual void negate() { \n");
|
fprintf(fp," virtual void negate() { \n");
|
||||||
|
@ -1823,6 +1828,7 @@ void ArchDesc::declareClasses(FILE *fp) {
|
||||||
if( instr->expands() || instr->needs_projections() ||
|
if( instr->expands() || instr->needs_projections() ||
|
||||||
instr->has_temps() ||
|
instr->has_temps() ||
|
||||||
instr->is_mach_constant() ||
|
instr->is_mach_constant() ||
|
||||||
|
instr->needs_constant_base() ||
|
||||||
instr->_matrule != NULL &&
|
instr->_matrule != NULL &&
|
||||||
instr->num_opnds() != instr->num_unique_opnds() ) {
|
instr->num_opnds() != instr->num_unique_opnds() ) {
|
||||||
fprintf(fp," virtual MachNode *Expand(State *state, Node_List &proj_list, Node* mem);\n");
|
fprintf(fp," virtual MachNode *Expand(State *state, Node_List &proj_list, Node* mem);\n");
|
||||||
|
|
|
@ -648,10 +648,15 @@ bool MachCallNode::return_value_is_used() const {
|
||||||
|
|
||||||
|
|
||||||
//------------------------------Registers--------------------------------------
|
//------------------------------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
|
// Values in the domain use the users calling convention, embodied in the
|
||||||
// _in_rms array of RegMasks.
|
// _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
|
// Values outside the domain represent debug info
|
||||||
return *Compile::current()->matcher()->idealreg2debugmask[in(idx)->ideal_reg()];
|
return *Compile::current()->matcher()->idealreg2debugmask[in(idx)->ideal_reg()];
|
||||||
}
|
}
|
||||||
|
@ -678,7 +683,12 @@ void MachCallJavaNode::dump_spec(outputStream *st) const {
|
||||||
const RegMask &MachCallJavaNode::in_RegMask(uint idx) const {
|
const RegMask &MachCallJavaNode::in_RegMask(uint idx) const {
|
||||||
// Values in the domain use the users calling convention, embodied in the
|
// Values in the domain use the users calling convention, embodied in the
|
||||||
// _in_rms array of RegMasks.
|
// _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
|
// Values outside the domain represent debug info
|
||||||
Matcher* m = Compile::current()->matcher();
|
Matcher* m = Compile::current()->matcher();
|
||||||
// If this call is a MethodHandle invoke we have to use a different
|
// If this call is a MethodHandle invoke we have to use a different
|
||||||
|
|
|
@ -181,6 +181,9 @@ public:
|
||||||
// Number of inputs which come before the first operand.
|
// Number of inputs which come before the first operand.
|
||||||
// Generally at least 1, to skip the Control input
|
// Generally at least 1, to skip the Control input
|
||||||
virtual uint oper_input_base() const { return 1; }
|
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.
|
// Copy inputs and operands to new node of instruction.
|
||||||
// Called from cisc_version() and short_branch_version().
|
// Called from cisc_version() and short_branch_version().
|
||||||
|
@ -250,6 +253,9 @@ public:
|
||||||
// Return number of relocatable values contained in this instruction
|
// Return number of relocatable values contained in this instruction
|
||||||
virtual int reloc() const { return 0; }
|
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.
|
// Hash and compare over operands. Used to do GVN on machine Nodes.
|
||||||
virtual uint hash() const;
|
virtual uint hash() const;
|
||||||
virtual uint cmp( const Node &n ) const;
|
virtual uint cmp( const Node &n ) const;
|
||||||
|
@ -412,7 +418,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Input edge of MachConstantBaseNode.
|
// 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();
|
||||||
int constant_offset() const { return ((MachConstantNode*) this)->constant_offset(); }
|
int constant_offset() const { return ((MachConstantNode*) this)->constant_offset(); }
|
||||||
|
|
|
@ -1083,6 +1083,7 @@ CodeBuffer* Compile::init_buffer(uint* blk_starts) {
|
||||||
assert(_frame_slots >= 0 && _frame_slots < 1000000, "sanity check");
|
assert(_frame_slots >= 0 && _frame_slots < 1000000, "sanity check");
|
||||||
|
|
||||||
if (has_mach_constant_base_node()) {
|
if (has_mach_constant_base_node()) {
|
||||||
|
uint add_size = 0;
|
||||||
// Fill the constant table.
|
// Fill the constant table.
|
||||||
// Note: This must happen before shorten_branches.
|
// Note: This must happen before shorten_branches.
|
||||||
for (uint i = 0; i < _cfg->number_of_blocks(); i++) {
|
for (uint i = 0; i < _cfg->number_of_blocks(); i++) {
|
||||||
|
@ -1096,6 +1097,9 @@ CodeBuffer* Compile::init_buffer(uint* blk_starts) {
|
||||||
if (n->is_MachConstant()) {
|
if (n->is_MachConstant()) {
|
||||||
MachConstantNode* machcon = n->as_MachConstant();
|
MachConstantNode* machcon = n->as_MachConstant();
|
||||||
machcon->eval_constant(C);
|
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 @@ CodeBuffer* Compile::init_buffer(uint* blk_starts) {
|
||||||
// Calculate the offsets of the constants and the size of the
|
// Calculate the offsets of the constants and the size of the
|
||||||
// constant table (including the padding to the next section).
|
// constant table (including the padding to the next section).
|
||||||
constant_table().calculate_offsets_and_size();
|
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
|
// Initialize the space for the BufferBlob used to find and verify
|
||||||
|
@ -1374,7 +1378,7 @@ void Compile::fill_buffer(CodeBuffer* cb, uint* blk_starts) {
|
||||||
int offset = blk_starts[block_num] - current_offset;
|
int offset = blk_starts[block_num] - current_offset;
|
||||||
if (block_num >= i) {
|
if (block_num >= i) {
|
||||||
// Current and following block's offset are not
|
// 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.
|
// between calculated and final offsets of current block.
|
||||||
offset -= (blk_starts[i] - blk_offset);
|
offset -= (blk_starts[i] - blk_offset);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue