Fri, 15 Nov 2013 14:09:26 -0500
Merge
1.1 --- a/src/cpu/sparc/vm/sparc.ad Fri Nov 15 11:05:32 2013 -0800 1.2 +++ b/src/cpu/sparc/vm/sparc.ad Fri Nov 15 14:09:26 2013 -0500 1.3 @@ -1034,6 +1034,11 @@ 1.4 } 1.5 } 1.6 1.7 +bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 1.8 +void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 1.9 + ShouldNotReachHere(); 1.10 +} 1.11 + 1.12 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1.13 Compile* C = ra_->C; 1.14 Compile::ConstantTable& constant_table = C->constant_table(); 1.15 @@ -1884,6 +1889,9 @@ 1.16 return (VM_Version::is_T4() || VM_Version::is_sparc64()) ? ConditionalMoveLimit : 0; 1.17 } 1.18 1.19 +// Does the CPU require late expand (see block.cpp for description of late expand)? 1.20 +const bool Matcher::require_postalloc_expand = false; 1.21 + 1.22 // Should the Matcher clone shifts on addressing modes, expecting them to 1.23 // be subsumed into complex addressing expressions or compute them into 1.24 // registers? True for Intel but false for most RISCs
2.1 --- a/src/cpu/x86/vm/x86_32.ad Fri Nov 15 11:05:32 2013 -0800 2.2 +++ b/src/cpu/x86/vm/x86_32.ad Fri Nov 15 14:09:26 2013 -0500 2.3 @@ -487,6 +487,11 @@ 2.4 return 0; // absolute addressing, no offset 2.5 } 2.6 2.7 +bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 2.8 +void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 2.9 + ShouldNotReachHere(); 2.10 +} 2.11 + 2.12 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 2.13 // Empty encoding 2.14 } 2.15 @@ -1389,6 +1394,9 @@ 2.16 // No CMOVF/CMOVD with SSE/SSE2 2.17 const int Matcher::float_cmove_cost() { return (UseSSE>=1) ? ConditionalMoveLimit : 0; } 2.18 2.19 +// Does the CPU require late expand (see block.cpp for description of late expand)? 2.20 +const bool Matcher::require_postalloc_expand = false; 2.21 + 2.22 // Should the Matcher clone shifts on addressing modes, expecting them to 2.23 // be subsumed into complex addressing expressions or compute them into 2.24 // registers? True for Intel but false for most RISCs
3.1 --- a/src/cpu/x86/vm/x86_64.ad Fri Nov 15 11:05:32 2013 -0800 3.2 +++ b/src/cpu/x86/vm/x86_64.ad Fri Nov 15 14:09:26 2013 -0500 3.3 @@ -688,6 +688,11 @@ 3.4 return 0; // absolute addressing, no offset 3.5 } 3.6 3.7 +bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 3.8 +void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 3.9 + ShouldNotReachHere(); 3.10 +} 3.11 + 3.12 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 3.13 // Empty encoding 3.14 } 3.15 @@ -1542,6 +1547,9 @@ 3.16 // No CMOVF/CMOVD with SSE2 3.17 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 3.18 3.19 +// Does the CPU require late expand (see block.cpp for description of late expand)? 3.20 +const bool Matcher::require_postalloc_expand = false; 3.21 + 3.22 // Should the Matcher clone shifts on addressing modes, expecting them 3.23 // to be subsumed into complex addressing expressions or compute them 3.24 // into registers? True for Intel but false for most RISCs
4.1 --- a/src/share/vm/adlc/adlparse.cpp Fri Nov 15 11:05:32 2013 -0800 4.2 +++ b/src/share/vm/adlc/adlparse.cpp Fri Nov 15 14:09:26 2013 -0500 4.3 @@ -219,19 +219,21 @@ 4.4 else if (!strcmp(ident, "encode")) { 4.5 parse_err(SYNERR, "Instructions specify ins_encode, not encode\n"); 4.6 } 4.7 - else if (!strcmp(ident, "ins_encode")) ins_encode_parse(*instr); 4.8 - else if (!strcmp(ident, "opcode")) instr->_opcode = opcode_parse(instr); 4.9 - else if (!strcmp(ident, "size")) instr->_size = size_parse(instr); 4.10 - else if (!strcmp(ident, "effect")) effect_parse(instr); 4.11 - else if (!strcmp(ident, "expand")) instr->_exprule = expand_parse(instr); 4.12 - else if (!strcmp(ident, "rewrite")) instr->_rewrule = rewrite_parse(); 4.13 + else if (!strcmp(ident, "ins_encode")) ins_encode_parse(*instr); 4.14 + // Parse late expand keyword. 4.15 + else if (!strcmp(ident, "postalloc_expand")) postalloc_expand_parse(*instr); 4.16 + else if (!strcmp(ident, "opcode")) instr->_opcode = opcode_parse(instr); 4.17 + else if (!strcmp(ident, "size")) instr->_size = size_parse(instr); 4.18 + else if (!strcmp(ident, "effect")) effect_parse(instr); 4.19 + else if (!strcmp(ident, "expand")) instr->_exprule = expand_parse(instr); 4.20 + else if (!strcmp(ident, "rewrite")) instr->_rewrule = rewrite_parse(); 4.21 else if (!strcmp(ident, "constraint")) { 4.22 parse_err(SYNERR, "Instructions do not specify a constraint\n"); 4.23 } 4.24 else if (!strcmp(ident, "construct")) { 4.25 parse_err(SYNERR, "Instructions do not specify a construct\n"); 4.26 } 4.27 - else if (!strcmp(ident, "format")) instr->_format = format_parse(); 4.28 + else if (!strcmp(ident, "format")) instr->_format = format_parse(); 4.29 else if (!strcmp(ident, "interface")) { 4.30 parse_err(SYNERR, "Instructions do not specify an interface\n"); 4.31 } 4.32 @@ -240,13 +242,14 @@ 4.33 // Check identifier to see if it is the name of an attribute 4.34 const Form *form = _globalNames[ident]; 4.35 AttributeForm *attr = form ? form->is_attribute() : NULL; 4.36 - if( attr && (attr->_atype == INS_ATTR) ) { 4.37 + if (attr && (attr->_atype == INS_ATTR)) { 4.38 // Insert the new attribute into the linked list. 4.39 Attribute *temp = attr_parse(ident); 4.40 temp->_next = instr->_attribs; 4.41 instr->_attribs = temp; 4.42 } else { 4.43 - parse_err(SYNERR, "expected one of:\n predicate, match, encode, or the name of an instruction attribute at %s\n", ident); 4.44 + parse_err(SYNERR, "expected one of:\n predicate, match, encode, or the name of" 4.45 + " an instruction attribute at %s\n", ident); 4.46 } 4.47 } 4.48 skipws(); 4.49 @@ -258,13 +261,17 @@ 4.50 } 4.51 // Check for "Set" form of chain rule 4.52 adjust_set_rule(instr); 4.53 - if (_AD._pipeline ) { 4.54 - if( instr->expands() ) { 4.55 - if( instr->_ins_pipe ) 4.56 - parse_err(WARN, "ins_pipe and expand rule both specified for instruction \"%s\"; ins_pipe will be unused\n", instr->_ident); 4.57 + if (_AD._pipeline) { 4.58 + // No pipe required for late expand. 4.59 + if (instr->expands() || instr->postalloc_expands()) { 4.60 + if (instr->_ins_pipe) { 4.61 + parse_err(WARN, "ins_pipe and expand rule both specified for instruction \"%s\";" 4.62 + " ins_pipe will be unused\n", instr->_ident); 4.63 + } 4.64 } else { 4.65 - if( !instr->_ins_pipe ) 4.66 + if (!instr->_ins_pipe) { 4.67 parse_err(WARN, "No ins_pipe specified for instruction \"%s\"\n", instr->_ident); 4.68 + } 4.69 } 4.70 } 4.71 // Add instruction to tail of instruction list 4.72 @@ -2779,11 +2786,13 @@ 4.73 encoding->add_parameter(opForm->_ident, param); 4.74 } 4.75 4.76 - // Define a MacroAssembler instance for use by the encoding. The 4.77 - // name is chosen to match the __ idiom used for assembly in other 4.78 - // parts of hotspot and assumes the existence of the standard 4.79 - // #define __ _masm. 4.80 - encoding->add_code(" MacroAssembler _masm(&cbuf);\n"); 4.81 + if (!inst._is_postalloc_expand) { 4.82 + // Define a MacroAssembler instance for use by the encoding. The 4.83 + // name is chosen to match the __ idiom used for assembly in other 4.84 + // parts of hotspot and assumes the existence of the standard 4.85 + // #define __ _masm. 4.86 + encoding->add_code(" MacroAssembler _masm(&cbuf);\n"); 4.87 + } 4.88 4.89 // Parse the following %{ }% block 4.90 ins_encode_parse_block_impl(inst, encoding, ec_name); 4.91 @@ -2857,7 +2866,8 @@ 4.92 inst.set_is_mach_constant(true); 4.93 4.94 if (_curchar == '(') { 4.95 - parse_err(SYNERR, "constanttablebase in instruct %s cannot have an argument (only constantaddress and constantoffset)", ec_name); 4.96 + parse_err(SYNERR, "constanttablebase in instruct %s cannot have an argument " 4.97 + "(only constantaddress and constantoffset)", ec_name); 4.98 return; 4.99 } 4.100 } 4.101 @@ -3050,6 +3060,157 @@ 4.102 inst._insencode = encrule; 4.103 } 4.104 4.105 +//------------------------------postalloc_expand_parse--------------------------- 4.106 +// Encode rules have the form 4.107 +// postalloc_expand( encode_class_name(parameter_list) ); 4.108 +// 4.109 +// The "encode_class_name" must be defined in the encode section. 4.110 +// The parameter list contains $names that are locals. 4.111 +// 4.112 +// This is just a copy of ins_encode_parse without the loop. 4.113 +void ADLParser::postalloc_expand_parse(InstructForm& inst) { 4.114 + inst._is_postalloc_expand = true; 4.115 + 4.116 + // Parse encode class name. 4.117 + skipws(); // Skip whitespace. 4.118 + if (_curchar != '(') { 4.119 + // Check for postalloc_expand %{ form 4.120 + if ((_curchar == '%') && (*(_ptr+1) == '{')) { 4.121 + next_char(); // Skip '%' 4.122 + next_char(); // Skip '{' 4.123 + 4.124 + // Parse the block form of postalloc_expand 4.125 + ins_encode_parse_block(inst); 4.126 + return; 4.127 + } 4.128 + 4.129 + parse_err(SYNERR, "missing '(' in postalloc_expand definition\n"); 4.130 + return; 4.131 + } 4.132 + next_char(); // Move past '('. 4.133 + skipws(); 4.134 + 4.135 + InsEncode *encrule = new InsEncode(); // Encode class for instruction. 4.136 + encrule->_linenum = linenum(); 4.137 + char *ec_name = NULL; // String representation of encode rule. 4.138 + // identifier is optional. 4.139 + if (_curchar != ')') { 4.140 + ec_name = get_ident(); 4.141 + if (ec_name == NULL) { 4.142 + parse_err(SYNERR, "Invalid postalloc_expand class name after 'postalloc_expand('.\n"); 4.143 + return; 4.144 + } 4.145 + // Check that encoding is defined in the encode section. 4.146 + EncClass *encode_class = _AD._encode->encClass(ec_name); 4.147 + 4.148 + // Get list for encode method's parameters 4.149 + NameAndList *params = encrule->add_encode(ec_name); 4.150 + 4.151 + // Parse the parameters to this encode method. 4.152 + skipws(); 4.153 + if (_curchar == '(') { 4.154 + next_char(); // Move past '(' for parameters. 4.155 + 4.156 + // Parse the encode method's parameters. 4.157 + while (_curchar != ')') { 4.158 + char *param = get_ident_or_literal_constant("encoding operand"); 4.159 + if (param != NULL) { 4.160 + // Found a parameter: 4.161 + 4.162 + // First check for constant table support. 4.163 + 4.164 + // Check if this instruct is a MachConstantNode. 4.165 + if (strcmp(param, "constanttablebase") == 0) { 4.166 + // This instruct is a MachConstantNode. 4.167 + inst.set_is_mach_constant(true); 4.168 + 4.169 + if (_curchar == '(') { 4.170 + parse_err(SYNERR, "constanttablebase in instruct %s cannot have an argument " 4.171 + "(only constantaddress and constantoffset)", ec_name); 4.172 + return; 4.173 + } 4.174 + } 4.175 + else if ((strcmp(param, "constantaddress") == 0) || 4.176 + (strcmp(param, "constantoffset") == 0)) { 4.177 + // This instruct is a MachConstantNode. 4.178 + inst.set_is_mach_constant(true); 4.179 + 4.180 + // If the constant keyword has an argument, parse it. 4.181 + if (_curchar == '(') constant_parse(inst); 4.182 + } 4.183 + 4.184 + // Else check it is a local name, add it to the list, then check for more. 4.185 + // New: allow hex constants as parameters to an encode method. 4.186 + // New: allow parenthesized expressions as parameters. 4.187 + // New: allow "primary", "secondary", "tertiary" as parameters. 4.188 + // New: allow user-defined register name as parameter. 4.189 + else if ((inst._localNames[param] == NULL) && 4.190 + !ADLParser::is_literal_constant(param) && 4.191 + (Opcode::as_opcode_type(param) == Opcode::NOT_AN_OPCODE) && 4.192 + ((_AD._register == NULL) || (_AD._register->getRegDef(param) == NULL))) { 4.193 + parse_err(SYNERR, "Using non-locally defined parameter %s for encoding %s.\n", param, ec_name); 4.194 + return; 4.195 + } 4.196 + params->add_entry(param); 4.197 + 4.198 + skipws(); 4.199 + if (_curchar == ',') { 4.200 + // More parameters to come. 4.201 + next_char(); // Move past ',' between parameters. 4.202 + skipws(); // Skip to next parameter. 4.203 + } else if (_curchar == ')') { 4.204 + // Done with parameter list 4.205 + } else { 4.206 + // Only ',' or ')' are valid after a parameter name. 4.207 + parse_err(SYNERR, "expected ',' or ')' after parameter %s.\n", ec_name); 4.208 + return; 4.209 + } 4.210 + 4.211 + } else { 4.212 + skipws(); 4.213 + // Did not find a parameter. 4.214 + if (_curchar == ',') { 4.215 + parse_err(SYNERR, "Expected encode parameter before ',' in postalloc_expand %s.\n", ec_name); 4.216 + return; 4.217 + } 4.218 + if (_curchar != ')') { 4.219 + parse_err(SYNERR, "Expected ')' after postalloc_expand parameters.\n"); 4.220 + return; 4.221 + } 4.222 + } 4.223 + } // WHILE loop collecting parameters. 4.224 + next_char(); // Move past ')' at end of parameters. 4.225 + } // Done with parameter list for encoding. 4.226 + 4.227 + // Check for ',' or ')' after encoding. 4.228 + skipws(); // Move to character after parameters. 4.229 + if (_curchar != ')') { 4.230 + // Only a ')' is allowed. 4.231 + parse_err(SYNERR, "Expected ')' after postalloc_expand %s.\n", ec_name); 4.232 + return; 4.233 + } 4.234 + } // Done parsing postalloc_expand method and their parameters. 4.235 + if (_curchar != ')') { 4.236 + parse_err(SYNERR, "Missing ')' at end of postalloc_expand description.\n"); 4.237 + return; 4.238 + } 4.239 + next_char(); // Move past ')'. 4.240 + skipws(); // Skip leading whitespace. 4.241 + 4.242 + if (_curchar != ';') { 4.243 + parse_err(SYNERR, "Missing ';' at end of postalloc_expand.\n"); 4.244 + return; 4.245 + } 4.246 + next_char(); // Move past ';'. 4.247 + skipws(); // Be friendly to oper_parse(). 4.248 + 4.249 + // Debug Stuff. 4.250 + if (_AD._adl_debug > 1) fprintf(stderr, "Instruction postalloc_expand: %s\n", ec_name); 4.251 + 4.252 + // Set encode class of this instruction. 4.253 + inst._insencode = encrule; 4.254 +} 4.255 + 4.256 4.257 //------------------------------constant_parse--------------------------------- 4.258 // Parse a constant expression.
5.1 --- a/src/share/vm/adlc/adlparse.hpp Fri Nov 15 11:05:32 2013 -0800 5.2 +++ b/src/share/vm/adlc/adlparse.hpp Fri Nov 15 14:09:26 2013 -0500 5.3 @@ -1,5 +1,5 @@ 5.4 /* 5.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 5.6 + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 5.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5.8 * 5.9 * This code is free software; you can redistribute it and/or modify it 5.10 @@ -159,6 +159,8 @@ 5.11 void ins_encode_parse(InstructForm &inst); 5.12 void ins_encode_parse_block(InstructForm &inst); 5.13 void ins_encode_parse_block_impl(InstructForm& inst, EncClass* encoding, char* ec_name); 5.14 + // Parse instruction postalloc expand rule. 5.15 + void postalloc_expand_parse(InstructForm &inst); 5.16 5.17 void constant_parse(InstructForm& inst); 5.18 void constant_parse_expression(EncClass* encoding, char* ec_name);
6.1 --- a/src/share/vm/adlc/archDesc.hpp Fri Nov 15 11:05:32 2013 -0800 6.2 +++ b/src/share/vm/adlc/archDesc.hpp Fri Nov 15 14:09:26 2013 -0500 6.3 @@ -311,6 +311,8 @@ 6.4 void defineEvalConstant(FILE *fp, InstructForm &node); 6.5 // Generator for Emit methods for instructions 6.6 void defineEmit (FILE *fp, InstructForm &node); 6.7 + // Generator for postalloc_expand methods for instructions. 6.8 + void define_postalloc_expand(FILE *fp, InstructForm &node); 6.9 6.10 // Define a MachOper encode method 6.11 void define_oper_interface(FILE *fp, OperandForm &oper, FormDict &globals,
7.1 --- a/src/share/vm/adlc/formssel.cpp Fri Nov 15 11:05:32 2013 -0800 7.2 +++ b/src/share/vm/adlc/formssel.cpp Fri Nov 15 14:09:26 2013 -0500 7.3 @@ -36,27 +36,28 @@ 7.4 { 7.5 _ftype = Form::INS; 7.6 7.7 - _matrule = NULL; 7.8 - _insencode = NULL; 7.9 - _constant = NULL; 7.10 - _opcode = NULL; 7.11 - _size = NULL; 7.12 - _attribs = NULL; 7.13 - _predicate = NULL; 7.14 - _exprule = NULL; 7.15 - _rewrule = NULL; 7.16 - _format = NULL; 7.17 - _peephole = NULL; 7.18 - _ins_pipe = NULL; 7.19 - _uniq_idx = NULL; 7.20 - _num_uniq = 0; 7.21 - _cisc_spill_operand = Not_cisc_spillable;// Which operand may cisc-spill 7.22 + _matrule = NULL; 7.23 + _insencode = NULL; 7.24 + _constant = NULL; 7.25 + _is_postalloc_expand = false; 7.26 + _opcode = NULL; 7.27 + _size = NULL; 7.28 + _attribs = NULL; 7.29 + _predicate = NULL; 7.30 + _exprule = NULL; 7.31 + _rewrule = NULL; 7.32 + _format = NULL; 7.33 + _peephole = NULL; 7.34 + _ins_pipe = NULL; 7.35 + _uniq_idx = NULL; 7.36 + _num_uniq = 0; 7.37 + _cisc_spill_operand = Not_cisc_spillable;// Which operand may cisc-spill 7.38 _cisc_spill_alternate = NULL; // possible cisc replacement 7.39 - _cisc_reg_mask_name = NULL; 7.40 - _is_cisc_alternate = false; 7.41 - _is_short_branch = false; 7.42 - _short_branch_form = NULL; 7.43 - _alignment = 1; 7.44 + _cisc_reg_mask_name = NULL; 7.45 + _is_cisc_alternate = false; 7.46 + _is_short_branch = false; 7.47 + _short_branch_form = NULL; 7.48 + _alignment = 1; 7.49 } 7.50 7.51 InstructForm::InstructForm(const char *id, InstructForm *instr, MatchRule *rule) 7.52 @@ -68,27 +69,28 @@ 7.53 { 7.54 _ftype = Form::INS; 7.55 7.56 - _matrule = rule; 7.57 - _insencode = instr->_insencode; 7.58 - _constant = instr->_constant; 7.59 - _opcode = instr->_opcode; 7.60 - _size = instr->_size; 7.61 - _attribs = instr->_attribs; 7.62 - _predicate = instr->_predicate; 7.63 - _exprule = instr->_exprule; 7.64 - _rewrule = instr->_rewrule; 7.65 - _format = instr->_format; 7.66 - _peephole = instr->_peephole; 7.67 - _ins_pipe = instr->_ins_pipe; 7.68 - _uniq_idx = instr->_uniq_idx; 7.69 - _num_uniq = instr->_num_uniq; 7.70 - _cisc_spill_operand = Not_cisc_spillable;// Which operand may cisc-spill 7.71 - _cisc_spill_alternate = NULL; // possible cisc replacement 7.72 - _cisc_reg_mask_name = NULL; 7.73 - _is_cisc_alternate = false; 7.74 - _is_short_branch = false; 7.75 - _short_branch_form = NULL; 7.76 - _alignment = 1; 7.77 + _matrule = rule; 7.78 + _insencode = instr->_insencode; 7.79 + _constant = instr->_constant; 7.80 + _is_postalloc_expand = instr->_is_postalloc_expand; 7.81 + _opcode = instr->_opcode; 7.82 + _size = instr->_size; 7.83 + _attribs = instr->_attribs; 7.84 + _predicate = instr->_predicate; 7.85 + _exprule = instr->_exprule; 7.86 + _rewrule = instr->_rewrule; 7.87 + _format = instr->_format; 7.88 + _peephole = instr->_peephole; 7.89 + _ins_pipe = instr->_ins_pipe; 7.90 + _uniq_idx = instr->_uniq_idx; 7.91 + _num_uniq = instr->_num_uniq; 7.92 + _cisc_spill_operand = Not_cisc_spillable; // Which operand may cisc-spill 7.93 + _cisc_spill_alternate = NULL; // possible cisc replacement 7.94 + _cisc_reg_mask_name = NULL; 7.95 + _is_cisc_alternate = false; 7.96 + _is_short_branch = false; 7.97 + _short_branch_form = NULL; 7.98 + _alignment = 1; 7.99 // Copy parameters 7.100 const char *name; 7.101 instr->_parameters.reset(); 7.102 @@ -157,6 +159,11 @@ 7.103 return ( _exprule != NULL ); 7.104 } 7.105 7.106 +// This instruction has a late expand rule? 7.107 +bool InstructForm::postalloc_expands() const { 7.108 + return _is_postalloc_expand; 7.109 +} 7.110 + 7.111 // This instruction has a peephole rule? 7.112 Peephole *InstructForm::peepholes() const { 7.113 return _peephole;
8.1 --- a/src/share/vm/adlc/formssel.hpp Fri Nov 15 11:05:32 2013 -0800 8.2 +++ b/src/share/vm/adlc/formssel.hpp Fri Nov 15 14:09:26 2013 -0500 8.3 @@ -88,30 +88,31 @@ 8.4 8.5 public: 8.6 // Public Data 8.7 - const char *_ident; // Name of this instruction 8.8 - NameList _parameters; // Locally defined names 8.9 - FormDict _localNames; // Table of operands & their types 8.10 - MatchRule *_matrule; // Matching rule for this instruction 8.11 - Opcode *_opcode; // Encoding of the opcode for instruction 8.12 - char *_size; // Size of instruction 8.13 - InsEncode *_insencode; // Encoding class instruction belongs to 8.14 - InsEncode *_constant; // Encoding class constant value belongs to 8.15 - Attribute *_attribs; // List of Attribute rules 8.16 - Predicate *_predicate; // Predicate test for this instruction 8.17 - FormDict _effects; // Dictionary of effect rules 8.18 - ExpandRule *_exprule; // Expand rule for this instruction 8.19 - RewriteRule *_rewrule; // Rewrite rule for this instruction 8.20 - FormatRule *_format; // Format for assembly generation 8.21 - Peephole *_peephole; // List of peephole rules for instruction 8.22 - const char *_ins_pipe; // Instruction Scheduling description class 8.23 + const char *_ident; // Name of this instruction 8.24 + NameList _parameters; // Locally defined names 8.25 + FormDict _localNames; // Table of operands & their types 8.26 + MatchRule *_matrule; // Matching rule for this instruction 8.27 + Opcode *_opcode; // Encoding of the opcode for instruction 8.28 + char *_size; // Size of instruction 8.29 + InsEncode *_insencode; // Encoding class instruction belongs to 8.30 + InsEncode *_constant; // Encoding class constant value belongs to 8.31 + bool _is_postalloc_expand; // Indicates that encoding just does a lateExpand. 8.32 + Attribute *_attribs; // List of Attribute rules 8.33 + Predicate *_predicate; // Predicate test for this instruction 8.34 + FormDict _effects; // Dictionary of effect rules 8.35 + ExpandRule *_exprule; // Expand rule for this instruction 8.36 + RewriteRule *_rewrule; // Rewrite rule for this instruction 8.37 + FormatRule *_format; // Format for assembly generation 8.38 + Peephole *_peephole; // List of peephole rules for instruction 8.39 + const char *_ins_pipe; // Instruction Scheduling description class 8.40 8.41 - uint *_uniq_idx; // Indexes of unique operands 8.42 - uint _uniq_idx_length; // Length of _uniq_idx array 8.43 - uint _num_uniq; // Number of unique operands 8.44 - ComponentList _components; // List of Components matches MachNode's 8.45 - // operand structure 8.46 + uint *_uniq_idx; // Indexes of unique operands 8.47 + uint _uniq_idx_length; // Length of _uniq_idx array 8.48 + uint _num_uniq; // Number of unique operands 8.49 + ComponentList _components; // List of Components matches MachNode's 8.50 + // operand structure 8.51 8.52 - bool _has_call; // contain a call and caller save registers should be saved? 8.53 + bool _has_call; // contain a call and caller save registers should be saved? 8.54 8.55 // Public Methods 8.56 InstructForm(const char *id, bool ideal_only = false); 8.57 @@ -133,6 +134,8 @@ 8.58 virtual uint num_defs_or_kills(); 8.59 // This instruction has an expand rule? 8.60 virtual bool expands() const ; 8.61 + // This instruction has a late expand rule? 8.62 + virtual bool postalloc_expands() const; 8.63 // Return this instruction's first peephole rule, or NULL 8.64 virtual Peephole *peepholes() const; 8.65 // Add a peephole rule to this instruction
9.1 --- a/src/share/vm/adlc/output_c.cpp Fri Nov 15 11:05:32 2013 -0800 9.2 +++ b/src/share/vm/adlc/output_c.cpp Fri Nov 15 14:09:26 2013 -0500 9.3 @@ -2488,7 +2488,113 @@ 9.4 fprintf(fp, " return (VerifyOops ? MachNode::size(ra_) : %s);\n", inst._size); 9.5 9.6 // (3) and (4) 9.7 - fprintf(fp,"}\n"); 9.8 + fprintf(fp,"}\n\n"); 9.9 +} 9.10 + 9.11 +// Emit late expand function. 9.12 +void ArchDesc::define_postalloc_expand(FILE *fp, InstructForm &inst) { 9.13 + InsEncode *ins_encode = inst._insencode; 9.14 + 9.15 + // Output instruction's postalloc_expand prototype. 9.16 + fprintf(fp, "void %sNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {\n", 9.17 + inst._ident); 9.18 + 9.19 + assert((_encode != NULL) && (ins_encode != NULL), "You must define an encode section."); 9.20 + 9.21 + // Output each operand's offset into the array of registers. 9.22 + inst.index_temps(fp, _globalNames); 9.23 + 9.24 + // Output variables "unsigned idx_<par_name>", Node *n_<par_name> and "MachOpnd *op_<par_name>" 9.25 + // for each parameter <par_name> specified in the encoding. 9.26 + ins_encode->reset(); 9.27 + const char *ec_name = ins_encode->encode_class_iter(); 9.28 + assert(ec_name != NULL, "late expand must specify an encoding"); 9.29 + 9.30 + EncClass *encoding = _encode->encClass(ec_name); 9.31 + if (encoding == NULL) { 9.32 + fprintf(stderr, "User did not define contents of this encode_class: %s\n", ec_name); 9.33 + abort(); 9.34 + } 9.35 + if (ins_encode->current_encoding_num_args() != encoding->num_args()) { 9.36 + globalAD->syntax_err(ins_encode->_linenum, "In %s: passing %d arguments to %s but expecting %d", 9.37 + inst._ident, ins_encode->current_encoding_num_args(), 9.38 + ec_name, encoding->num_args()); 9.39 + } 9.40 + 9.41 + fprintf(fp, " // Access to ins and operands for late expand.\n"); 9.42 + const int buflen = 2000; 9.43 + char idxbuf[buflen]; char *ib = idxbuf; sprintf(ib, ""); 9.44 + char nbuf [buflen]; char *nb = nbuf; sprintf(nb, ""); 9.45 + char opbuf [buflen]; char *ob = opbuf; sprintf(ob, ""); 9.46 + 9.47 + encoding->_parameter_type.reset(); 9.48 + encoding->_parameter_name.reset(); 9.49 + const char *type = encoding->_parameter_type.iter(); 9.50 + const char *name = encoding->_parameter_name.iter(); 9.51 + int param_no = 0; 9.52 + for (; (type != NULL) && (name != NULL); 9.53 + (type = encoding->_parameter_type.iter()), (name = encoding->_parameter_name.iter())) { 9.54 + const char* arg_name = ins_encode->rep_var_name(inst, param_no); 9.55 + int idx = inst.operand_position_format(arg_name); 9.56 + if (strcmp(arg_name, "constanttablebase") == 0) { 9.57 + ib += sprintf(ib, " unsigned idx_%-5s = mach_constant_base_node_input(); \t// %s, \t%s\n", 9.58 + name, type, arg_name); 9.59 + nb += sprintf(nb, " Node *n_%-7s = lookup(idx_%s);\n", name, name); 9.60 + // There is no operand for the constanttablebase. 9.61 + } else if (inst.is_noninput_operand(idx)) { 9.62 + globalAD->syntax_err(inst._linenum, 9.63 + "In %s: you can not pass the non-input %s to a late expand encoding.\n", 9.64 + inst._ident, arg_name); 9.65 + } else { 9.66 + ib += sprintf(ib, " unsigned idx_%-5s = idx%d; \t// %s, \t%s\n", 9.67 + name, idx, type, arg_name); 9.68 + nb += sprintf(nb, " Node *n_%-7s = lookup(idx_%s);\n", name, name); 9.69 + ob += sprintf(ob, " %sOper *op_%s = (%sOper *)opnd_array(%d);\n", type, name, type, idx); 9.70 + } 9.71 + param_no++; 9.72 + } 9.73 + assert(ib < &idxbuf[buflen-1] && nb < &nbuf[buflen-1] && ob < &opbuf[buflen-1], "buffer overflow"); 9.74 + 9.75 + fprintf(fp, "%s", idxbuf); 9.76 + fprintf(fp, " Node *n_region = lookup(0);\n"); 9.77 + fprintf(fp, "%s%s", nbuf, opbuf); 9.78 + fprintf(fp, " Compile *C = ra_->C;\n"); 9.79 + 9.80 + // Output this instruction's encodings. 9.81 + fprintf(fp, " {"); 9.82 + const char *ec_code = NULL; 9.83 + const char *ec_rep_var = NULL; 9.84 + assert(encoding == _encode->encClass(ec_name), ""); 9.85 + 9.86 + DefineEmitState pending(fp, *this, *encoding, *ins_encode, inst); 9.87 + encoding->_code.reset(); 9.88 + encoding->_rep_vars.reset(); 9.89 + // Process list of user-defined strings, 9.90 + // and occurrences of replacement variables. 9.91 + // Replacement Vars are pushed into a list and then output. 9.92 + while ((ec_code = encoding->_code.iter()) != NULL) { 9.93 + if (! encoding->_code.is_signal(ec_code)) { 9.94 + // Emit pending code. 9.95 + pending.emit(); 9.96 + pending.clear(); 9.97 + // Emit this code section. 9.98 + fprintf(fp, "%s", ec_code); 9.99 + } else { 9.100 + // A replacement variable or one of its subfields. 9.101 + // Obtain replacement variable from list. 9.102 + ec_rep_var = encoding->_rep_vars.iter(); 9.103 + pending.add_rep_var(ec_rep_var); 9.104 + } 9.105 + } 9.106 + // Emit pending code. 9.107 + pending.emit(); 9.108 + pending.clear(); 9.109 + fprintf(fp, " }\n"); 9.110 + 9.111 + fprintf(fp, "}\n\n"); 9.112 + 9.113 + ec_name = ins_encode->encode_class_iter(); 9.114 + assert(ec_name == NULL, "Late expand may only have one encoding."); 9.115 } 9.116 9.117 // defineEmit ----------------------------------------------------------------- 9.118 @@ -2841,7 +2947,7 @@ 9.119 } else if ( (strcmp(name,"disp") == 0) ) { 9.120 fprintf(fp,"(PhaseRegAlloc *ra_, const Node *node, int idx) const { \n"); 9.121 } else { 9.122 - fprintf(fp,"() const { \n"); 9.123 + fprintf(fp, "() const {\n"); 9.124 } 9.125 9.126 // Check for hexadecimal value OR replacement variable 9.127 @@ -2891,6 +2997,8 @@ 9.128 // Hex value 9.129 fprintf(fp," return %s;\n", encoding); 9.130 } else { 9.131 + globalAD->syntax_err(oper._linenum, "In operand %s: Do not support this encode constant: '%s' for %s.", 9.132 + oper._ident, encoding, name); 9.133 assert( false, "Do not support octal or decimal encode constants"); 9.134 } 9.135 fprintf(fp," }\n"); 9.136 @@ -3142,7 +3250,15 @@ 9.137 // Ensure this is a machine-world instruction 9.138 if ( instr->ideal_only() ) continue; 9.139 9.140 - if (instr->_insencode) defineEmit (fp, *instr); 9.141 + if (instr->_insencode) { 9.142 + if (instr->postalloc_expands()) { 9.143 + // Don't write this to _CPP_EXPAND_file, as the code generated calls C-code 9.144 + // from code sections in ad file that is dumped to fp. 9.145 + define_postalloc_expand(fp, *instr); 9.146 + } else { 9.147 + defineEmit(fp, *instr); 9.148 + } 9.149 + } 9.150 if (instr->is_mach_constant()) defineEvalConstant(fp, *instr); 9.151 if (instr->_size) defineSize (fp, *instr); 9.152
10.1 --- a/src/share/vm/adlc/output_h.cpp Fri Nov 15 11:05:32 2013 -0800 10.2 +++ b/src/share/vm/adlc/output_h.cpp Fri Nov 15 14:09:26 2013 -0500 10.3 @@ -1633,7 +1633,12 @@ 10.4 // Output the opcode function and the encode function here using the 10.5 // encoding class information in the _insencode slot. 10.6 if ( instr->_insencode ) { 10.7 - fprintf(fp," virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const;\n"); 10.8 + if (instr->postalloc_expands()) { 10.9 + fprintf(fp," virtual bool requires_postalloc_expand() const { return true; }\n"); 10.10 + fprintf(fp," virtual void postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_);\n"); 10.11 + } else { 10.12 + fprintf(fp," virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const;\n"); 10.13 + } 10.14 } 10.15 10.16 // virtual function for getting the size of an instruction
11.1 --- a/src/share/vm/opto/block.cpp Fri Nov 15 11:05:32 2013 -0800 11.2 +++ b/src/share/vm/opto/block.cpp Fri Nov 15 14:09:26 2013 -0500 11.3 @@ -144,6 +144,10 @@ 11.4 remove_node(find_node(n)); 11.5 } 11.6 11.7 +bool Block::contains(const Node *n) const { 11.8 + return _nodes.contains(n); 11.9 +} 11.10 + 11.11 // Return empty status of a block. Empty blocks contain only the head, other 11.12 // ideal nodes, and an optional trailing goto. 11.13 int Block::is_Empty() const { 11.14 @@ -699,7 +703,7 @@ 11.15 // Fix up the final control flow for basic blocks. 11.16 void PhaseCFG::fixup_flow() { 11.17 // Fixup final control flow for the blocks. Remove jump-to-next 11.18 - // block. If neither arm of a IF follows the conditional branch, we 11.19 + // block. If neither arm of an IF follows the conditional branch, we 11.20 // have to add a second jump after the conditional. We place the 11.21 // TRUE branch target in succs[0] for both GOTOs and IFs. 11.22 for (uint i = 0; i < number_of_blocks(); i++) { 11.23 @@ -844,6 +848,228 @@ 11.24 } 11.25 11.26 11.27 +// postalloc_expand: Expand nodes after register allocation. 11.28 +// 11.29 +// postalloc_expand has to be called after register allocation, just 11.30 +// before output (i.e. scheduling). It only gets called if 11.31 +// Matcher::require_postalloc_expand is true. 11.32 +// 11.33 +// Background: 11.34 +// 11.35 +// Nodes that are expandend (one compound node requiring several 11.36 +// assembler instructions to be implemented split into two or more 11.37 +// non-compound nodes) after register allocation are not as nice as 11.38 +// the ones expanded before register allocation - they don't 11.39 +// participate in optimizations as global code motion. But after 11.40 +// register allocation we can expand nodes that use registers which 11.41 +// are not spillable or registers that are not allocated, because the 11.42 +// old compound node is simply replaced (in its location in the basic 11.43 +// block) by a new subgraph which does not contain compound nodes any 11.44 +// more. The scheduler called during output can later on process these 11.45 +// non-compound nodes. 11.46 +// 11.47 +// Implementation: 11.48 +// 11.49 +// Nodes requiring postalloc expand are specified in the ad file by using 11.50 +// a postalloc_expand statement instead of ins_encode. A postalloc_expand 11.51 +// contains a single call to an encoding, as does an ins_encode 11.52 +// statement. Instead of an emit() function a postalloc_expand() function 11.53 +// is generated that doesn't emit assembler but creates a new 11.54 +// subgraph. The code below calls this postalloc_expand function for each 11.55 +// node with the appropriate attribute. This function returns the new 11.56 +// nodes generated in an array passed in the call. The old node, 11.57 +// potential MachTemps before and potential Projs after it then get 11.58 +// disconnected and replaced by the new nodes. The instruction 11.59 +// generating the result has to be the last one in the array. In 11.60 +// general it is assumed that Projs after the node expanded are 11.61 +// kills. These kills are not required any more after expanding as 11.62 +// there are now explicitly visible def-use chains and the Projs are 11.63 +// removed. This does not hold for calls: They do not only have 11.64 +// kill-Projs but also Projs defining values. Therefore Projs after 11.65 +// the node expanded are removed for all but for calls. If a node is 11.66 +// to be reused, it must be added to the nodes list returned, and it 11.67 +// will be added again. 11.68 +// 11.69 +// Implementing the postalloc_expand function for a node in an enc_class 11.70 +// is rather tedious. It requires knowledge about many node details, as 11.71 +// the nodes and the subgraph must be hand crafted. To simplify this, 11.72 +// adlc generates some utility variables into the postalloc_expand function, 11.73 +// e.g., holding the operands as specified by the postalloc_expand encoding 11.74 +// specification, e.g.: 11.75 +// * unsigned idx_<par_name> holding the index of the node in the ins 11.76 +// * Node *n_<par_name> holding the node loaded from the ins 11.77 +// * MachOpnd *op_<par_name> holding the corresponding operand 11.78 +// 11.79 +// The ordering of operands can not be determined by looking at a 11.80 +// rule. Especially if a match rule matches several different trees, 11.81 +// several nodes are generated from one instruct specification with 11.82 +// different operand orderings. In this case the adlc generated 11.83 +// variables are the only way to access the ins and operands 11.84 +// deterministically. 11.85 +// 11.86 +// If assigning a register to a node that contains an oop, don't 11.87 +// forget to call ra_->set_oop() for the node. 11.88 +void PhaseCFG::postalloc_expand(PhaseRegAlloc* _ra) { 11.89 + GrowableArray <Node *> new_nodes(32); // Array with new nodes filled by postalloc_expand function of node. 11.90 + GrowableArray <Node *> remove(32); 11.91 + GrowableArray <Node *> succs(32); 11.92 + unsigned int max_idx = C->unique(); // Remember to distinguish new from old nodes. 11.93 + DEBUG_ONLY(bool foundNode = false); 11.94 + 11.95 + // for all blocks 11.96 + for (uint i = 0; i < number_of_blocks(); i++) { 11.97 + Block *b = _blocks[i]; 11.98 + // For all instructions in the current block. 11.99 + for (uint j = 0; j < b->number_of_nodes(); j++) { 11.100 + Node *n = b->get_node(j); 11.101 + if (n->is_Mach() && n->as_Mach()->requires_postalloc_expand()) { 11.102 +#ifdef ASSERT 11.103 + if (TracePostallocExpand) { 11.104 + if (!foundNode) { 11.105 + foundNode = true; 11.106 + tty->print("POSTALLOC EXPANDING %d %s\n", C->compile_id(), 11.107 + C->method() ? C->method()->name()->as_utf8() : C->stub_name()); 11.108 + } 11.109 + tty->print(" postalloc expanding "); n->dump(); 11.110 + if (Verbose) { 11.111 + tty->print(" with ins:\n"); 11.112 + for (uint k = 0; k < n->len(); ++k) { 11.113 + if (n->in(k)) { tty->print(" "); n->in(k)->dump(); } 11.114 + } 11.115 + } 11.116 + } 11.117 +#endif 11.118 + new_nodes.clear(); 11.119 + // Collect nodes that have to be removed from the block later on. 11.120 + uint req = n->req(); 11.121 + remove.clear(); 11.122 + for (uint k = 0; k < req; ++k) { 11.123 + if (n->in(k) && n->in(k)->is_MachTemp()) { 11.124 + remove.push(n->in(k)); // MachTemps which are inputs to the old node have to be removed. 11.125 + n->in(k)->del_req(0); 11.126 + j--; 11.127 + } 11.128 + } 11.129 + 11.130 + // Check whether we can allocate enough nodes. We set a fix limit for 11.131 + // the size of postalloc expands with this. 11.132 + uint unique_limit = C->unique() + 40; 11.133 + if (unique_limit >= _ra->node_regs_max_index()) { 11.134 + Compile::current()->record_failure("out of nodes in postalloc expand"); 11.135 + return; 11.136 + } 11.137 + 11.138 + // Emit (i.e. generate new nodes). 11.139 + n->as_Mach()->postalloc_expand(&new_nodes, _ra); 11.140 + 11.141 + assert(C->unique() < unique_limit, "You allocated too many nodes in your postalloc expand."); 11.142 + 11.143 + // Disconnect the inputs of the old node. 11.144 + // 11.145 + // We reuse MachSpillCopy nodes. If we need to expand them, there 11.146 + // are many, so reusing pays off. If reused, the node already 11.147 + // has the new ins. n must be the last node on new_nodes list. 11.148 + if (!n->is_MachSpillCopy()) { 11.149 + for (int k = req - 1; k >= 0; --k) { 11.150 + n->del_req(k); 11.151 + } 11.152 + } 11.153 + 11.154 +#ifdef ASSERT 11.155 + // Check that all nodes have proper operands. 11.156 + for (int k = 0; k < new_nodes.length(); ++k) { 11.157 + if (new_nodes.at(k)->_idx < max_idx || !new_nodes.at(k)->is_Mach()) continue; // old node, Proj ... 11.158 + MachNode *m = new_nodes.at(k)->as_Mach(); 11.159 + for (unsigned int l = 0; l < m->num_opnds(); ++l) { 11.160 + if (MachOper::notAnOper(m->_opnds[l])) { 11.161 + outputStream *os = tty; 11.162 + os->print("Node %s ", m->Name()); 11.163 + os->print("has invalid opnd %d: %p\n", l, m->_opnds[l]); 11.164 + assert(0, "Invalid operands, see inline trace in hs_err_pid file."); 11.165 + } 11.166 + } 11.167 + } 11.168 +#endif 11.169 + 11.170 + // Collect succs of old node in remove (for projections) and in succs (for 11.171 + // all other nodes) do _not_ collect projections in remove (but in succs) 11.172 + // in case the node is a call. We need the projections for calls as they are 11.173 + // associated with registes (i.e. they are defs). 11.174 + succs.clear(); 11.175 + for (DUIterator k = n->outs(); n->has_out(k); k++) { 11.176 + if (n->out(k)->is_Proj() && !n->is_MachCall() && !n->is_MachBranch()) { 11.177 + remove.push(n->out(k)); 11.178 + } else { 11.179 + succs.push(n->out(k)); 11.180 + } 11.181 + } 11.182 + // Replace old node n as input of its succs by last of the new nodes. 11.183 + for (int k = 0; k < succs.length(); ++k) { 11.184 + Node *succ = succs.at(k); 11.185 + for (uint l = 0; l < succ->req(); ++l) { 11.186 + if (succ->in(l) == n) { 11.187 + succ->set_req(l, new_nodes.at(new_nodes.length() - 1)); 11.188 + } 11.189 + } 11.190 + for (uint l = succ->req(); l < succ->len(); ++l) { 11.191 + if (succ->in(l) == n) { 11.192 + succ->set_prec(l, new_nodes.at(new_nodes.length() - 1)); 11.193 + } 11.194 + } 11.195 + } 11.196 + 11.197 + // Index of old node in block. 11.198 + uint index = b->find_node(n); 11.199 + // Insert new nodes into block and map them in nodes->blocks array 11.200 + // and remember last node in n2. 11.201 + Node *n2 = NULL; 11.202 + for (int k = 0; k < new_nodes.length(); ++k) { 11.203 + n2 = new_nodes.at(k); 11.204 + b->insert_node(n2, ++index); 11.205 + map_node_to_block(n2, b); 11.206 + } 11.207 + 11.208 + // Add old node n to remove and remove them all from block. 11.209 + remove.push(n); 11.210 + j--; 11.211 +#ifdef ASSERT 11.212 + if (TracePostallocExpand && Verbose) { 11.213 + tty->print(" removing:\n"); 11.214 + for (int k = 0; k < remove.length(); ++k) { 11.215 + tty->print(" "); remove.at(k)->dump(); 11.216 + } 11.217 + tty->print(" inserting:\n"); 11.218 + for (int k = 0; k < new_nodes.length(); ++k) { 11.219 + tty->print(" "); new_nodes.at(k)->dump(); 11.220 + } 11.221 + } 11.222 +#endif 11.223 + for (int k = 0; k < remove.length(); ++k) { 11.224 + if (b->contains(remove.at(k))) { 11.225 + b->find_remove(remove.at(k)); 11.226 + } else { 11.227 + assert(remove.at(k)->is_Proj() && (remove.at(k)->in(0)->is_MachBranch()), ""); 11.228 + } 11.229 + } 11.230 + // If anything has been inserted (n2 != NULL), continue after last node inserted. 11.231 + // This does not always work. Some postalloc expands don't insert any nodes, if they 11.232 + // do optimizations (e.g., max(x,x)). In this case we decrement j accordingly. 11.233 + j = n2 ? b->find_node(n2) : j; 11.234 + } 11.235 + } 11.236 + } 11.237 + 11.238 +#ifdef ASSERT 11.239 + if (foundNode) { 11.240 + tty->print("FINISHED %d %s\n", C->compile_id(), 11.241 + C->method() ? C->method()->name()->as_utf8() : C->stub_name()); 11.242 + tty->flush(); 11.243 + } 11.244 +#endif 11.245 +} 11.246 + 11.247 + 11.248 +//------------------------------dump------------------------------------------- 11.249 #ifndef PRODUCT 11.250 void PhaseCFG::_dump_cfg( const Node *end, VectorSet &visited ) const { 11.251 const Node *x = end->is_block_proj();
12.1 --- a/src/share/vm/opto/block.hpp Fri Nov 15 11:05:32 2013 -0800 12.2 +++ b/src/share/vm/opto/block.hpp Fri Nov 15 14:09:26 2013 -0500 12.3 @@ -313,10 +313,12 @@ 12.4 // Add an instruction to an existing block. It must go after the head 12.5 // instruction and before the end instruction. 12.6 void add_inst( Node *n ) { insert_node(n, end_idx()); } 12.7 - // Find node in block 12.8 + // Find node in block. Fails if node not in block. 12.9 uint find_node( const Node *n ) const; 12.10 // Find and remove n from block list 12.11 void find_remove( const Node *n ); 12.12 + // Check wether the node is in the block. 12.13 + bool contains (const Node *n) const; 12.14 12.15 // Return the empty status of a block 12.16 enum { not_empty, empty_with_goto, completely_empty }; 12.17 @@ -596,6 +598,9 @@ 12.18 map_node_to_block(n, b); 12.19 } 12.20 12.21 + // Check all nodes and postalloc_expand them if necessary. 12.22 + void postalloc_expand(PhaseRegAlloc* _ra); 12.23 + 12.24 #ifndef PRODUCT 12.25 bool trace_opto_pipelining() const { return _trace_opto_pipelining; } 12.26
13.1 --- a/src/share/vm/opto/c2_globals.hpp Fri Nov 15 11:05:32 2013 -0800 13.2 +++ b/src/share/vm/opto/c2_globals.hpp Fri Nov 15 14:09:26 2013 -0500 13.3 @@ -463,6 +463,9 @@ 13.4 experimental(bool, AggressiveUnboxing, false, \ 13.5 "Control optimizations for aggressive boxing elimination") \ 13.6 \ 13.7 + develop(bool, TracePostallocExpand, false, "Trace expanding nodes after" \ 13.8 + " register allocation.") \ 13.9 + \ 13.10 product(bool, DoEscapeAnalysis, true, \ 13.11 "Perform escape analysis") \ 13.12 \
14.1 --- a/src/share/vm/opto/compile.cpp Fri Nov 15 11:05:32 2013 -0800 14.2 +++ b/src/share/vm/opto/compile.cpp Fri Nov 15 14:09:26 2013 -0500 14.3 @@ -2250,6 +2250,12 @@ 14.4 peep.do_transform(); 14.5 } 14.6 14.7 + // Do late expand if CPU requires this. 14.8 + if (Matcher::require_postalloc_expand) { 14.9 + NOT_PRODUCT(TracePhase t2c("postalloc_expand", &_t_postalloc_expand, true)); 14.10 + cfg.postalloc_expand(_regalloc); 14.11 + } 14.12 + 14.13 // Convert Nodes to instruction bits in a buffer 14.14 { 14.15 // %%%% workspace merge brought two timers together for one job
15.1 --- a/src/share/vm/opto/machnode.cpp Fri Nov 15 11:05:32 2013 -0800 15.2 +++ b/src/share/vm/opto/machnode.cpp Fri Nov 15 14:09:26 2013 -0500 15.3 @@ -134,6 +134,10 @@ 15.4 ShouldNotCallThis(); 15.5 } 15.6 15.7 +//---------------------------postalloc_expand---------------------------------- 15.8 +// Expand node after register allocation. 15.9 +void MachNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {} 15.10 + 15.11 //------------------------------size------------------------------------------- 15.12 // Size of instruction in bytes 15.13 uint MachNode::size(PhaseRegAlloc *ra_) const {
16.1 --- a/src/share/vm/opto/machnode.hpp Fri Nov 15 11:05:32 2013 -0800 16.2 +++ b/src/share/vm/opto/machnode.hpp Fri Nov 15 14:09:26 2013 -0500 16.3 @@ -155,7 +155,15 @@ 16.4 virtual void ext_format(PhaseRegAlloc *,const MachNode *node,int idx, outputStream *st) const=0; 16.5 16.6 virtual void dump_spec(outputStream *st) const; // Print per-operand info 16.7 -#endif 16.8 + 16.9 + // Check whether o is a valid oper. 16.10 + static bool notAnOper(const MachOper *o) { 16.11 + if (o == NULL) return true; 16.12 + if (((intptr_t)o & 1) != 0) return true; 16.13 + if (*(address*)o == badAddress) return true; // kill by Node::destruct 16.14 + return false; 16.15 + } 16.16 +#endif // !PRODUCT 16.17 }; 16.18 16.19 //------------------------------MachNode--------------------------------------- 16.20 @@ -220,6 +228,12 @@ 16.21 16.22 // Emit bytes into cbuf 16.23 virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const; 16.24 + // Expand node after register allocation. 16.25 + // Node is replaced by several nodes in the postalloc expand phase. 16.26 + // Corresponding methods are generated for nodes if they specify 16.27 + // postalloc_expand. See block.cpp for more documentation. 16.28 + virtual bool requires_postalloc_expand() const { return false; } 16.29 + virtual void postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_); 16.30 // Size of instruction in bytes 16.31 virtual uint size(PhaseRegAlloc *ra_) const; 16.32 // Helper function that computes size by emitting code 16.33 @@ -356,6 +370,9 @@ 16.34 virtual uint ideal_reg() const { return Op_RegP; } 16.35 virtual uint oper_input_base() const { return 1; } 16.36 16.37 + virtual bool requires_postalloc_expand() const; 16.38 + virtual void postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_); 16.39 + 16.40 virtual void emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const; 16.41 virtual uint size(PhaseRegAlloc* ra_) const; 16.42 virtual bool pinned() const { return UseRDPCForConstantTableBase; }
17.1 --- a/src/share/vm/opto/matcher.hpp Fri Nov 15 11:05:32 2013 -0800 17.2 +++ b/src/share/vm/opto/matcher.hpp Fri Nov 15 14:09:26 2013 -0500 17.3 @@ -449,6 +449,10 @@ 17.4 // aligned. 17.5 static const bool misaligned_doubles_ok; 17.6 17.7 + // Does the CPU require postalloc expand (see block.cpp for description of 17.8 + // postalloc expand)? 17.9 + static const bool require_postalloc_expand; 17.10 + 17.11 // Perform a platform dependent implicit null fixup. This is needed 17.12 // on windows95 to take care of some unusual register constraints. 17.13 void pd_implicit_null_fixup(MachNode *load, uint idx);
18.1 --- a/src/share/vm/opto/node.hpp Fri Nov 15 11:05:32 2013 -0800 18.2 +++ b/src/share/vm/opto/node.hpp Fri Nov 15 14:09:26 2013 -0500 18.3 @@ -357,6 +357,8 @@ 18.4 18.5 // Reference to the i'th input Node. Error if out of bounds. 18.6 Node* in(uint i) const { assert(i < _max, err_msg_res("oob: i=%d, _max=%d", i, _max)); return _in[i]; } 18.7 + // Reference to the i'th input Node. NULL if out of bounds. 18.8 + Node* lookup(uint i) const { return ((i < _max) ? _in[i] : NULL); } 18.9 // Reference to the i'th output Node. Error if out of bounds. 18.10 // Use this accessor sparingly. We are going trying to use iterators instead. 18.11 Node* raw_out(uint i) const { assert(i < _outcnt,"oob"); return _out[i]; } 18.12 @@ -384,6 +386,10 @@ 18.13 18.14 // Set a required input edge, also updates corresponding output edge 18.15 void add_req( Node *n ); // Append a NEW required input 18.16 + void add_req( Node *n0, Node *n1 ) { 18.17 + add_req(n0); add_req(n1); } 18.18 + void add_req( Node *n0, Node *n1, Node *n2 ) { 18.19 + add_req(n0); add_req(n1); add_req(n2); } 18.20 void add_req_batch( Node* n, uint m ); // Append m NEW required inputs (all n). 18.21 void del_req( uint idx ); // Delete required edge & compact 18.22 void del_req_ordered( uint idx ); // Delete required edge & compact with preserved order 18.23 @@ -1350,7 +1356,7 @@ 18.24 public: 18.25 Node_List() : Node_Array(Thread::current()->resource_area()), _cnt(0) {} 18.26 Node_List(Arena *a) : Node_Array(a), _cnt(0) {} 18.27 - bool contains(Node* n) { 18.28 + bool contains(const Node* n) const { 18.29 for (uint e = 0; e < size(); e++) { 18.30 if (at(e) == n) return true; 18.31 }
19.1 --- a/src/share/vm/opto/phase.cpp Fri Nov 15 11:05:32 2013 -0800 19.2 +++ b/src/share/vm/opto/phase.cpp Fri Nov 15 14:09:26 2013 -0500 19.3 @@ -26,6 +26,7 @@ 19.4 #include "code/nmethod.hpp" 19.5 #include "compiler/compileBroker.hpp" 19.6 #include "opto/compile.hpp" 19.7 +#include "opto/matcher.hpp" 19.8 #include "opto/node.hpp" 19.9 #include "opto/phase.hpp" 19.10 19.11 @@ -55,6 +56,7 @@ 19.12 elapsedTimer Phase::_t_macroEliminate; 19.13 elapsedTimer Phase::_t_macroExpand; 19.14 elapsedTimer Phase::_t_peephole; 19.15 +elapsedTimer Phase::_t_postalloc_expand; 19.16 elapsedTimer Phase::_t_codeGeneration; 19.17 elapsedTimer Phase::_t_registerMethod; 19.18 elapsedTimer Phase::_t_temporaryTimer1; 19.19 @@ -144,6 +146,9 @@ 19.20 } 19.21 tty->print_cr (" blockOrdering : %3.3f sec", Phase::_t_blockOrdering.seconds()); 19.22 tty->print_cr (" peephole : %3.3f sec", Phase::_t_peephole.seconds()); 19.23 + if (Matcher::require_postalloc_expand) { 19.24 + tty->print_cr (" postalloc_expand: %3.3f sec", Phase::_t_postalloc_expand.seconds()); 19.25 + } 19.26 tty->print_cr (" codeGen : %3.3f sec", Phase::_t_codeGeneration.seconds()); 19.27 tty->print_cr (" install_code : %3.3f sec", Phase::_t_registerMethod.seconds()); 19.28 tty->print_cr (" -------------- : ----------");
20.1 --- a/src/share/vm/opto/phase.hpp Fri Nov 15 11:05:32 2013 -0800 20.2 +++ b/src/share/vm/opto/phase.hpp Fri Nov 15 14:09:26 2013 -0500 20.3 @@ -91,6 +91,7 @@ 20.4 static elapsedTimer _t_macroEliminate; 20.5 static elapsedTimer _t_macroExpand; 20.6 static elapsedTimer _t_peephole; 20.7 + static elapsedTimer _t_postalloc_expand; 20.8 static elapsedTimer _t_codeGeneration; 20.9 static elapsedTimer _t_registerMethod; 20.10 static elapsedTimer _t_temporaryTimer1;