Mon, 12 Aug 2019 18:30:40 +0300
8223147: JFR Backport
8199712: Flight Recorder
8203346: JFR: Inconsistent signature of jfr_add_string_constant
8195817: JFR.stop should require name of recording
8195818: JFR.start should increase autogenerated name by one
8195819: Remove recording=x from jcmd JFR.check output
8203921: JFR thread sampling is missing fixes from JDK-8194552
8203929: Limit amount of data for JFR.dump
8203664: JFR start failure after AppCDS archive created with JFR StartFlightRecording
8003209: JFR events for network utilization
8207392: [PPC64] Implement JFR profiling
8202835: jfr/event/os/TestSystemProcess.java fails on missing events
Summary: Backport JFR from JDK11. Initial integration
Reviewed-by: neugens
duke@435 | 1 | /* |
mikael@6198 | 2 | * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. |
duke@435 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
duke@435 | 4 | * |
duke@435 | 5 | * This code is free software; you can redistribute it and/or modify it |
duke@435 | 6 | * under the terms of the GNU General Public License version 2 only, as |
duke@435 | 7 | * published by the Free Software Foundation. |
duke@435 | 8 | * |
duke@435 | 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
duke@435 | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
duke@435 | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
duke@435 | 12 | * version 2 for more details (a copy is included in the LICENSE file that |
duke@435 | 13 | * accompanied this code). |
duke@435 | 14 | * |
duke@435 | 15 | * You should have received a copy of the GNU General Public License version |
duke@435 | 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
duke@435 | 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
duke@435 | 18 | * |
trims@1907 | 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
trims@1907 | 20 | * or visit www.oracle.com if you need additional information or have any |
trims@1907 | 21 | * questions. |
duke@435 | 22 | * |
duke@435 | 23 | */ |
duke@435 | 24 | |
stefank@2314 | 25 | #ifndef SHARE_VM_ADLC_FORMSSEL_HPP |
stefank@2314 | 26 | #define SHARE_VM_ADLC_FORMSSEL_HPP |
stefank@2314 | 27 | |
duke@435 | 28 | // FORMSSEL.HPP - ADL Parser Instruction Selection Forms Classes |
duke@435 | 29 | |
duke@435 | 30 | // Class List |
duke@435 | 31 | class Form; |
duke@435 | 32 | class InstructForm; |
duke@435 | 33 | class MachNodeForm; |
duke@435 | 34 | class OperandForm; |
duke@435 | 35 | class OpClassForm; |
duke@435 | 36 | class AttributeForm; |
duke@435 | 37 | class RegisterForm; |
duke@435 | 38 | class PipelineForm; |
duke@435 | 39 | class SourceForm; |
duke@435 | 40 | class EncodeForm; |
duke@435 | 41 | class Component; |
duke@435 | 42 | class Constraint; |
duke@435 | 43 | class Predicate; |
duke@435 | 44 | class MatchRule; |
duke@435 | 45 | class Attribute; |
duke@435 | 46 | class Effect; |
duke@435 | 47 | class ExpandRule; |
duke@435 | 48 | class RewriteRule; |
duke@435 | 49 | class ConstructRule; |
duke@435 | 50 | class FormatRule; |
duke@435 | 51 | class Peephole; |
duke@435 | 52 | class EncClass; |
duke@435 | 53 | class Interface; |
duke@435 | 54 | class RegInterface; |
duke@435 | 55 | class ConstInterface; |
duke@435 | 56 | class MemInterface; |
duke@435 | 57 | class CondInterface; |
duke@435 | 58 | class Opcode; |
duke@435 | 59 | class InsEncode; |
duke@435 | 60 | class RegDef; |
duke@435 | 61 | class RegClass; |
zmajo@7853 | 62 | class CodeSnippetRegClass; |
zmajo@7853 | 63 | class ConditionalRegClass; |
duke@435 | 64 | class AllocClass; |
duke@435 | 65 | class ResourceForm; |
duke@435 | 66 | class PipeDesc; |
duke@435 | 67 | class PipeClass; |
duke@435 | 68 | class PeepMatch; |
duke@435 | 69 | class PeepConstraint; |
duke@435 | 70 | class PeepReplace; |
duke@435 | 71 | class MatchList; |
duke@435 | 72 | |
duke@435 | 73 | class ArchDesc; |
duke@435 | 74 | |
duke@435 | 75 | //==============================Instructions=================================== |
duke@435 | 76 | //------------------------------InstructForm----------------------------------- |
duke@435 | 77 | class InstructForm : public Form { |
duke@435 | 78 | private: |
twisti@2350 | 79 | bool _ideal_only; // Not a user-defined instruction |
duke@435 | 80 | // Members used for tracking CISC-spilling |
kvn@4161 | 81 | int _cisc_spill_operand;// Which operand may cisc-spill |
duke@435 | 82 | void set_cisc_spill_operand(uint op_index) { _cisc_spill_operand = op_index; } |
twisti@2350 | 83 | bool _is_cisc_alternate; |
duke@435 | 84 | InstructForm *_cisc_spill_alternate;// cisc possible replacement |
duke@435 | 85 | const char *_cisc_reg_mask_name; |
duke@435 | 86 | InstructForm *_short_branch_form; |
duke@435 | 87 | bool _is_short_branch; |
goetz@6484 | 88 | bool _is_mach_constant; // True if Node is a MachConstantNode. |
goetz@6484 | 89 | bool _needs_constant_base; // True if Node needs the mach_constant_base input. |
duke@435 | 90 | uint _alignment; |
duke@435 | 91 | |
duke@435 | 92 | public: |
duke@435 | 93 | // Public Data |
goetz@6478 | 94 | const char *_ident; // Name of this instruction |
goetz@6478 | 95 | NameList _parameters; // Locally defined names |
goetz@6478 | 96 | FormDict _localNames; // Table of operands & their types |
goetz@6478 | 97 | MatchRule *_matrule; // Matching rule for this instruction |
goetz@6478 | 98 | Opcode *_opcode; // Encoding of the opcode for instruction |
goetz@6478 | 99 | char *_size; // Size of instruction |
goetz@6478 | 100 | InsEncode *_insencode; // Encoding class instruction belongs to |
goetz@6478 | 101 | InsEncode *_constant; // Encoding class constant value belongs to |
goetz@6478 | 102 | bool _is_postalloc_expand; // Indicates that encoding just does a lateExpand. |
goetz@6478 | 103 | Attribute *_attribs; // List of Attribute rules |
goetz@6478 | 104 | Predicate *_predicate; // Predicate test for this instruction |
goetz@6478 | 105 | FormDict _effects; // Dictionary of effect rules |
goetz@6478 | 106 | ExpandRule *_exprule; // Expand rule for this instruction |
goetz@6478 | 107 | RewriteRule *_rewrule; // Rewrite rule for this instruction |
goetz@6478 | 108 | FormatRule *_format; // Format for assembly generation |
goetz@6478 | 109 | Peephole *_peephole; // List of peephole rules for instruction |
goetz@6478 | 110 | const char *_ins_pipe; // Instruction Scheduling description class |
duke@435 | 111 | |
goetz@6478 | 112 | uint *_uniq_idx; // Indexes of unique operands |
goetz@6478 | 113 | uint _uniq_idx_length; // Length of _uniq_idx array |
goetz@6478 | 114 | uint _num_uniq; // Number of unique operands |
goetz@6478 | 115 | ComponentList _components; // List of Components matches MachNode's |
goetz@6478 | 116 | // operand structure |
duke@435 | 117 | |
goetz@6478 | 118 | bool _has_call; // contain a call and caller save registers should be saved? |
roland@3316 | 119 | |
duke@435 | 120 | // Public Methods |
duke@435 | 121 | InstructForm(const char *id, bool ideal_only = false); |
duke@435 | 122 | InstructForm(const char *id, InstructForm *instr, MatchRule *rule); |
duke@435 | 123 | ~InstructForm(); |
duke@435 | 124 | |
duke@435 | 125 | // Dynamic type check |
duke@435 | 126 | virtual InstructForm *is_instruction() const; |
duke@435 | 127 | |
duke@435 | 128 | virtual bool ideal_only() const; |
duke@435 | 129 | |
duke@435 | 130 | // This instruction sets a result |
duke@435 | 131 | virtual bool sets_result() const; |
duke@435 | 132 | // This instruction needs projections for additional DEFs or KILLs |
duke@435 | 133 | virtual bool needs_projections(); |
duke@435 | 134 | // This instruction needs extra nodes for temporary inputs |
duke@435 | 135 | virtual bool has_temps(); |
duke@435 | 136 | // This instruction defines or kills more than one object |
duke@435 | 137 | virtual uint num_defs_or_kills(); |
duke@435 | 138 | // This instruction has an expand rule? |
duke@435 | 139 | virtual bool expands() const ; |
goetz@6478 | 140 | // This instruction has a late expand rule? |
goetz@6478 | 141 | virtual bool postalloc_expands() const; |
duke@435 | 142 | // Return this instruction's first peephole rule, or NULL |
duke@435 | 143 | virtual Peephole *peepholes() const; |
duke@435 | 144 | // Add a peephole rule to this instruction |
duke@435 | 145 | virtual void append_peephole(Peephole *peep); |
duke@435 | 146 | |
duke@435 | 147 | virtual bool is_pinned(FormDict &globals); // should be pinned inside block |
duke@435 | 148 | virtual bool is_projection(FormDict &globals); // node requires projection |
duke@435 | 149 | virtual bool is_parm(FormDict &globals); // node matches ideal 'Parm' |
duke@435 | 150 | // ideal opcode enumeration |
duke@435 | 151 | virtual const char *ideal_Opcode(FormDict &globals) const; |
duke@435 | 152 | virtual int is_expensive() const; // node matches ideal 'CosD' |
duke@435 | 153 | virtual int is_empty_encoding() const; // _size=0 and/or _insencode empty |
duke@435 | 154 | virtual int is_tls_instruction() const; // tlsLoadP rule or ideal ThreadLocal |
duke@435 | 155 | virtual int is_ideal_copy() const; // node matches ideal 'Copy*' |
adlertz@5288 | 156 | virtual bool is_ideal_negD() const; // node matches ideal 'NegD' |
duke@435 | 157 | virtual bool is_ideal_if() const; // node matches ideal 'If' |
duke@435 | 158 | virtual bool is_ideal_fastlock() const; // node matches 'FastLock' |
duke@435 | 159 | virtual bool is_ideal_membar() const; // node matches ideal 'MemBarXXX' |
duke@435 | 160 | virtual bool is_ideal_loadPC() const; // node matches ideal 'LoadPC' |
duke@435 | 161 | virtual bool is_ideal_box() const; // node matches ideal 'Box' |
duke@435 | 162 | virtual bool is_ideal_goto() const; // node matches ideal 'Goto' |
duke@435 | 163 | virtual bool is_ideal_branch() const; // "" 'If' | 'Goto' | 'LoopEnd' | 'Jump' |
duke@435 | 164 | virtual bool is_ideal_jump() const; // node matches ideal 'Jump' |
duke@435 | 165 | virtual bool is_ideal_return() const; // node matches ideal 'Return' |
duke@435 | 166 | virtual bool is_ideal_halt() const; // node matches ideal 'Halt' |
duke@435 | 167 | virtual bool is_ideal_safepoint() const; // node matches 'SafePoint' |
duke@435 | 168 | virtual bool is_ideal_nop() const; // node matches 'Nop' |
duke@435 | 169 | virtual bool is_ideal_control() const; // control node |
kvn@3882 | 170 | virtual bool is_vector() const; // vector instruction |
duke@435 | 171 | |
duke@435 | 172 | virtual Form::CallType is_ideal_call() const; // matches ideal 'Call' |
duke@435 | 173 | virtual Form::DataType is_ideal_load() const; // node matches ideal 'LoadXNode' |
never@1290 | 174 | // Should antidep checks be disabled for this Instruct |
never@1290 | 175 | // See definition of MatchRule::skip_antidep_check |
never@1290 | 176 | bool skip_antidep_check() const; |
duke@435 | 177 | virtual Form::DataType is_ideal_store() const;// node matches ideal 'StoreXNode' |
duke@435 | 178 | bool is_ideal_mem() const { return is_ideal_load() != Form::none || is_ideal_store() != Form::none; } |
duke@435 | 179 | virtual uint two_address(FormDict &globals); // output reg must match input reg |
duke@435 | 180 | // when chaining a constant to an instruction, return 'true' and set opType |
duke@435 | 181 | virtual Form::DataType is_chain_of_constant(FormDict &globals); |
duke@435 | 182 | virtual Form::DataType is_chain_of_constant(FormDict &globals, const char * &opType); |
duke@435 | 183 | virtual Form::DataType is_chain_of_constant(FormDict &globals, const char * &opType, const char * &result_type); |
duke@435 | 184 | |
duke@435 | 185 | // Check if a simple chain rule |
duke@435 | 186 | virtual bool is_simple_chain_rule(FormDict &globals) const; |
duke@435 | 187 | |
duke@435 | 188 | // check for structural rematerialization |
duke@435 | 189 | virtual bool rematerialize(FormDict &globals, RegisterForm *registers); |
duke@435 | 190 | |
duke@435 | 191 | // loads from memory, so must check for anti-dependence |
duke@435 | 192 | virtual bool needs_anti_dependence_check(FormDict &globals) const; |
duke@435 | 193 | virtual int memory_operand(FormDict &globals) const; |
duke@435 | 194 | bool is_wide_memory_kill(FormDict &globals) const; |
duke@435 | 195 | |
duke@435 | 196 | enum memory_operand_type { |
duke@435 | 197 | NO_MEMORY_OPERAND = -1, |
duke@435 | 198 | MANY_MEMORY_OPERANDS = 999999 |
duke@435 | 199 | }; |
duke@435 | 200 | |
duke@435 | 201 | |
duke@435 | 202 | // This instruction captures the machine-independent bottom_type |
duke@435 | 203 | // Expected use is for pointer vs oop determination for LoadP |
never@1896 | 204 | virtual bool captures_bottom_type(FormDict& globals) const; |
duke@435 | 205 | |
duke@435 | 206 | virtual const char *cost(); // Access ins_cost attribute |
duke@435 | 207 | virtual uint num_opnds(); // Count of num_opnds for MachNode class |
kvn@4161 | 208 | // Counts USE_DEF opnds twice. See also num_unique_opnds(). |
duke@435 | 209 | virtual uint num_post_match_opnds(); |
duke@435 | 210 | virtual uint num_consts(FormDict &globals) const;// Constants in match rule |
duke@435 | 211 | // Constants in match rule with specified type |
duke@435 | 212 | virtual uint num_consts(FormDict &globals, Form::DataType type) const; |
duke@435 | 213 | |
duke@435 | 214 | // Return the register class associated with 'leaf'. |
duke@435 | 215 | virtual const char *out_reg_class(FormDict &globals); |
duke@435 | 216 | |
duke@435 | 217 | // number of ideal node inputs to skip |
duke@435 | 218 | virtual uint oper_input_base(FormDict &globals); |
duke@435 | 219 | |
duke@435 | 220 | // Does this instruction need a base-oop edge? |
duke@435 | 221 | int needs_base_oop_edge(FormDict &globals) const; |
duke@435 | 222 | |
duke@435 | 223 | // Build instruction predicates. If the user uses the same operand name |
duke@435 | 224 | // twice, we need to check that the operands are pointer-eequivalent in |
duke@435 | 225 | // the DFA during the labeling process. |
duke@435 | 226 | Predicate *build_predicate(); |
duke@435 | 227 | |
duke@435 | 228 | virtual void build_components(); // top-level operands |
duke@435 | 229 | // Return zero-based position in component list; -1 if not in list. |
duke@435 | 230 | virtual int operand_position(const char *name, int usedef); |
duke@435 | 231 | virtual int operand_position_format(const char *name); |
duke@435 | 232 | |
duke@435 | 233 | // Return zero-based position in component list; -1 if not in list. |
duke@435 | 234 | virtual int label_position(); |
duke@435 | 235 | virtual int method_position(); |
duke@435 | 236 | // Return number of relocation entries needed for this instruction. |
duke@435 | 237 | virtual uint reloc(FormDict &globals); |
duke@435 | 238 | |
kvn@4161 | 239 | const char *opnd_ident(int idx); // Name of operand #idx. |
duke@435 | 240 | const char *reduce_result(); |
duke@435 | 241 | // Return the name of the operand on the right hand side of the binary match |
duke@435 | 242 | // Return NULL if there is no right hand side |
duke@435 | 243 | const char *reduce_right(FormDict &globals) const; |
duke@435 | 244 | const char *reduce_left(FormDict &globals) const; |
duke@435 | 245 | |
duke@435 | 246 | // Base class for this instruction, MachNode except for calls |
never@1896 | 247 | virtual const char *mach_base_class(FormDict &globals) const; |
duke@435 | 248 | |
duke@435 | 249 | // Check if this instruction can cisc-spill to 'alternate' |
duke@435 | 250 | bool cisc_spills_to(ArchDesc &AD, InstructForm *alternate); |
duke@435 | 251 | InstructForm *cisc_spill_alternate() { return _cisc_spill_alternate; } |
kvn@4161 | 252 | int cisc_spill_operand() const { return _cisc_spill_operand; } |
duke@435 | 253 | bool is_cisc_alternate() const { return _is_cisc_alternate; } |
duke@435 | 254 | void set_cisc_alternate(bool val) { _is_cisc_alternate = val; } |
duke@435 | 255 | const char *cisc_reg_mask_name() const { return _cisc_reg_mask_name; } |
duke@435 | 256 | void set_cisc_reg_mask_name(const char *rm_name) { _cisc_reg_mask_name = rm_name; } |
duke@435 | 257 | // Output cisc-method prototypes and method bodies |
duke@435 | 258 | void declare_cisc_version(ArchDesc &AD, FILE *fp_cpp); |
duke@435 | 259 | bool define_cisc_version (ArchDesc &AD, FILE *fp_cpp); |
duke@435 | 260 | |
duke@435 | 261 | bool check_branch_variant(ArchDesc &AD, InstructForm *short_branch); |
duke@435 | 262 | |
duke@435 | 263 | bool is_short_branch() { return _is_short_branch; } |
duke@435 | 264 | void set_short_branch(bool val) { _is_short_branch = val; } |
duke@435 | 265 | |
twisti@2350 | 266 | bool is_mach_constant() const { return _is_mach_constant; } |
twisti@2350 | 267 | void set_is_mach_constant(bool x) { _is_mach_constant = x; } |
goetz@6484 | 268 | bool needs_constant_base() const { return _needs_constant_base; } |
goetz@6484 | 269 | void set_needs_constant_base(bool x) { _needs_constant_base = x; } |
twisti@2350 | 270 | |
duke@435 | 271 | InstructForm *short_branch_form() { return _short_branch_form; } |
duke@435 | 272 | bool has_short_branch_form() { return _short_branch_form != NULL; } |
duke@435 | 273 | // Output short branch prototypes and method bodies |
duke@435 | 274 | void declare_short_branch_methods(FILE *fp_cpp); |
never@1896 | 275 | bool define_short_branch_methods(ArchDesc &AD, FILE *fp_cpp); |
duke@435 | 276 | |
duke@435 | 277 | uint alignment() { return _alignment; } |
duke@435 | 278 | void set_alignment(uint val) { _alignment = val; } |
duke@435 | 279 | |
duke@435 | 280 | // Seach through operands to determine operands unique positions. |
duke@435 | 281 | void set_unique_opnds(); |
duke@435 | 282 | uint num_unique_opnds() { return _num_uniq; } |
duke@435 | 283 | uint unique_opnds_idx(int idx) { |
twisti@5221 | 284 | if (_uniq_idx != NULL && idx > 0) { |
twisti@5221 | 285 | assert((uint)idx < _uniq_idx_length, "out of bounds"); |
twisti@5221 | 286 | return _uniq_idx[idx]; |
twisti@5221 | 287 | } else { |
twisti@5221 | 288 | return idx; |
twisti@5221 | 289 | } |
never@1034 | 290 | } |
twisti@5221 | 291 | const char *unique_opnd_ident(uint idx); // Name of operand at unique idx. |
duke@435 | 292 | |
duke@435 | 293 | // Operands which are only KILLs aren't part of the input array and |
duke@435 | 294 | // require special handling in some cases. Their position in this |
duke@435 | 295 | // operand list is higher than the number of unique operands. |
duke@435 | 296 | bool is_noninput_operand(uint idx) { |
duke@435 | 297 | return (idx >= num_unique_opnds()); |
duke@435 | 298 | } |
duke@435 | 299 | |
duke@435 | 300 | // --------------------------- FILE *output_routines |
duke@435 | 301 | // |
duke@435 | 302 | // Generate the format call for the replacement variable |
duke@435 | 303 | void rep_var_format(FILE *fp, const char *rep_var); |
twisti@1040 | 304 | // Generate index values needed for determining the operand position |
duke@435 | 305 | void index_temps (FILE *fp, FormDict &globals, const char *prefix = "", const char *receiver = ""); |
duke@435 | 306 | // --------------------------- |
duke@435 | 307 | |
duke@435 | 308 | virtual bool verify(); // Check consistency after parsing |
duke@435 | 309 | |
duke@435 | 310 | virtual void dump(); // Debug printer |
duke@435 | 311 | virtual void output(FILE *fp); // Write to output files |
duke@435 | 312 | }; |
duke@435 | 313 | |
duke@435 | 314 | //------------------------------EncodeForm------------------------------------- |
duke@435 | 315 | class EncodeForm : public Form { |
duke@435 | 316 | private: |
duke@435 | 317 | |
duke@435 | 318 | public: |
duke@435 | 319 | // Public Data |
duke@435 | 320 | NameList _eclasses; // List of encode class names |
duke@435 | 321 | Dict _encClass; // Map encode class names to EncClass objects |
duke@435 | 322 | |
duke@435 | 323 | // Public Methods |
duke@435 | 324 | EncodeForm(); |
duke@435 | 325 | ~EncodeForm(); |
duke@435 | 326 | |
duke@435 | 327 | EncClass *add_EncClass(const char *className); |
duke@435 | 328 | EncClass *encClass(const char *className); |
duke@435 | 329 | |
duke@435 | 330 | const char *encClassPrototype(const char *className); |
duke@435 | 331 | const char *encClassBody(const char *className); |
duke@435 | 332 | |
duke@435 | 333 | void dump(); // Debug printer |
duke@435 | 334 | void output(FILE *fp); // Write info to output files |
duke@435 | 335 | }; |
duke@435 | 336 | |
duke@435 | 337 | //------------------------------EncClass--------------------------------------- |
duke@435 | 338 | class EncClass : public Form { |
duke@435 | 339 | public: |
duke@435 | 340 | // NameList for parameter type and name |
duke@435 | 341 | NameList _parameter_type; |
duke@435 | 342 | NameList _parameter_name; |
duke@435 | 343 | |
duke@435 | 344 | // Breakdown the encoding into strings separated by $replacement_variables |
duke@435 | 345 | // There is an entry in _strings, perhaps NULL, that precedes each _rep_vars |
duke@435 | 346 | NameList _code; // Strings passed through to tty->print |
duke@435 | 347 | NameList _rep_vars; // replacement variables |
duke@435 | 348 | |
duke@435 | 349 | NameList _parameters; // Locally defined names |
duke@435 | 350 | FormDict _localNames; // Table of components & their types |
duke@435 | 351 | |
duke@435 | 352 | public: |
duke@435 | 353 | // Public Data |
duke@435 | 354 | const char *_name; // encoding class name |
duke@435 | 355 | |
duke@435 | 356 | // Public Methods |
duke@435 | 357 | EncClass(const char *name); |
duke@435 | 358 | ~EncClass(); |
duke@435 | 359 | |
duke@435 | 360 | // --------------------------- Parameters |
duke@435 | 361 | // Add a parameter <type,name> pair |
duke@435 | 362 | void add_parameter(const char *parameter_type, const char *parameter_name); |
duke@435 | 363 | // Verify operand types in parameter list |
duke@435 | 364 | bool check_parameter_types(FormDict &globals); |
duke@435 | 365 | // Obtain the zero-based index corresponding to a replacement variable |
duke@435 | 366 | int rep_var_index(const char *rep_var); |
duke@435 | 367 | int num_args() { return _parameter_name.count(); } |
duke@435 | 368 | |
duke@435 | 369 | // --------------------------- Code Block |
duke@435 | 370 | // Add code |
twisti@1040 | 371 | void add_code(const char *string_preceding_replacement_var); |
duke@435 | 372 | // Add a replacement variable or one of its subfields |
duke@435 | 373 | // Subfields are stored with a leading '$' |
duke@435 | 374 | void add_rep_var(char *replacement_var); |
duke@435 | 375 | |
duke@435 | 376 | bool verify(); |
duke@435 | 377 | void dump(); |
duke@435 | 378 | void output(FILE *fp); |
duke@435 | 379 | }; |
duke@435 | 380 | |
duke@435 | 381 | //------------------------------MachNode--------------------------------------- |
duke@435 | 382 | class MachNodeForm: public Form { |
duke@435 | 383 | private: |
duke@435 | 384 | |
duke@435 | 385 | public: |
duke@435 | 386 | char *_ident; // Name of this instruction |
duke@435 | 387 | const char *_machnode_pipe; // Instruction Scheduline description class |
duke@435 | 388 | |
duke@435 | 389 | // Public Methods |
duke@435 | 390 | MachNodeForm(char *id); |
duke@435 | 391 | ~MachNodeForm(); |
duke@435 | 392 | |
duke@435 | 393 | virtual MachNodeForm *is_machnode() const; |
duke@435 | 394 | |
duke@435 | 395 | void dump(); // Debug printer |
duke@435 | 396 | void output(FILE *fp); // Write info to output files |
duke@435 | 397 | }; |
duke@435 | 398 | |
duke@435 | 399 | //------------------------------Opcode----------------------------------------- |
duke@435 | 400 | class Opcode : public Form { |
duke@435 | 401 | private: |
duke@435 | 402 | |
duke@435 | 403 | public: |
duke@435 | 404 | // Public Data |
duke@435 | 405 | // Strings representing instruction opcodes, user defines placement in emit |
duke@435 | 406 | char *_primary; |
duke@435 | 407 | char *_secondary; |
duke@435 | 408 | char *_tertiary; |
duke@435 | 409 | |
duke@435 | 410 | enum opcode_type { |
duke@435 | 411 | NOT_AN_OPCODE = -1, |
duke@435 | 412 | PRIMARY = 1, |
duke@435 | 413 | SECONDARY = 2, |
duke@435 | 414 | TERTIARY = 3 |
duke@435 | 415 | }; |
duke@435 | 416 | |
duke@435 | 417 | // Public Methods |
duke@435 | 418 | Opcode(char *primary, char *secondary, char *tertiary); |
duke@435 | 419 | ~Opcode(); |
duke@435 | 420 | |
duke@435 | 421 | static Opcode::opcode_type as_opcode_type(const char *designator); |
duke@435 | 422 | |
duke@435 | 423 | void dump(); |
duke@435 | 424 | void output(FILE *fp); |
duke@435 | 425 | |
duke@435 | 426 | // --------------------------- FILE *output_routines |
never@850 | 427 | bool print_opcode(FILE *fp, Opcode::opcode_type desired_opcode); |
duke@435 | 428 | }; |
duke@435 | 429 | |
duke@435 | 430 | //------------------------------InsEncode-------------------------------------- |
duke@435 | 431 | class InsEncode : public Form { |
duke@435 | 432 | private: |
duke@435 | 433 | // Public Data (access directly only for reads) |
duke@435 | 434 | // The encodings can only have the values predefined by the ADLC: |
duke@435 | 435 | // blank, RegReg, RegMem, MemReg, ... |
duke@435 | 436 | NameList _encoding; |
duke@435 | 437 | // NameList _parameter; |
duke@435 | 438 | // The parameters for each encoding are preceeded by a NameList::_signal |
duke@435 | 439 | // and follow the parameters for the previous encoding. |
duke@435 | 440 | |
duke@435 | 441 | // char *_encode; // Type of instruction encoding |
duke@435 | 442 | |
duke@435 | 443 | public: |
duke@435 | 444 | // Public Methods |
duke@435 | 445 | InsEncode(); |
duke@435 | 446 | ~InsEncode(); |
duke@435 | 447 | |
duke@435 | 448 | // Add "encode class name" and its parameters |
duke@435 | 449 | NameAndList *add_encode(char *encode_method_name); |
duke@435 | 450 | // Parameters are added to the returned "NameAndList" by the parser |
duke@435 | 451 | |
duke@435 | 452 | // Access the list of encodings |
duke@435 | 453 | void reset(); |
duke@435 | 454 | const char *encode_class_iter(); |
duke@435 | 455 | |
duke@435 | 456 | // Returns the number of arguments to the current encoding in the iteration |
duke@435 | 457 | int current_encoding_num_args() { |
duke@435 | 458 | return ((NameAndList*)_encoding.current())->count(); |
duke@435 | 459 | } |
duke@435 | 460 | |
duke@435 | 461 | // --------------------------- Parameters |
duke@435 | 462 | // The following call depends upon position within encode_class_iteration |
duke@435 | 463 | // |
duke@435 | 464 | // Obtain parameter name from zero based index |
duke@435 | 465 | const char *rep_var_name(InstructForm &inst, uint param_no); |
duke@435 | 466 | // --------------------------- |
duke@435 | 467 | |
duke@435 | 468 | void dump(); |
duke@435 | 469 | void output(FILE *fp); |
duke@435 | 470 | }; |
duke@435 | 471 | |
duke@435 | 472 | //------------------------------Effect----------------------------------------- |
duke@435 | 473 | class Effect : public Form { |
duke@435 | 474 | private: |
duke@435 | 475 | |
duke@435 | 476 | public: |
duke@435 | 477 | // Public Data |
duke@435 | 478 | const char *_name; // Pre-defined name for effect |
duke@435 | 479 | int _use_def; // Enumeration value of effect |
duke@435 | 480 | |
duke@435 | 481 | // Public Methods |
duke@435 | 482 | Effect(const char *name); // Constructor |
duke@435 | 483 | ~Effect(); // Destructor |
duke@435 | 484 | |
duke@435 | 485 | // Dynamic type check |
duke@435 | 486 | virtual Effect *is_effect() const; |
duke@435 | 487 | |
duke@435 | 488 | // Return 'true' if this use def info equals the parameter |
duke@435 | 489 | bool is(int use_def_kill_enum) const; |
duke@435 | 490 | // Return 'true' if this use def info is a superset of parameter |
duke@435 | 491 | bool isa(int use_def_kill_enum) const; |
duke@435 | 492 | |
duke@435 | 493 | void dump(); // Debug printer |
duke@435 | 494 | void output(FILE *fp); // Write info to output files |
duke@435 | 495 | }; |
duke@435 | 496 | |
duke@435 | 497 | //------------------------------ExpandRule------------------------------------- |
duke@435 | 498 | class ExpandRule : public Form { |
duke@435 | 499 | private: |
duke@435 | 500 | NameList _expand_instrs; // ordered list of instructions and operands |
duke@435 | 501 | |
duke@435 | 502 | public: |
duke@435 | 503 | // Public Data |
duke@435 | 504 | NameList _newopers; // List of newly created operands |
duke@435 | 505 | Dict _newopconst; // Map new operands to their constructors |
duke@435 | 506 | |
duke@435 | 507 | void add_instruction(NameAndList *instruction_name_and_operand_list); |
duke@435 | 508 | void reset_instructions(); |
duke@435 | 509 | NameAndList *iter_instructions(); |
duke@435 | 510 | |
duke@435 | 511 | // Public Methods |
duke@435 | 512 | ExpandRule(); // Constructor |
duke@435 | 513 | ~ExpandRule(); // Destructor |
duke@435 | 514 | |
duke@435 | 515 | void dump(); // Debug printer |
duke@435 | 516 | void output(FILE *fp); // Write info to output files |
duke@435 | 517 | }; |
duke@435 | 518 | |
duke@435 | 519 | //------------------------------RewriteRule------------------------------------ |
duke@435 | 520 | class RewriteRule : public Form { |
duke@435 | 521 | private: |
duke@435 | 522 | |
duke@435 | 523 | public: |
duke@435 | 524 | // Public Data |
duke@435 | 525 | SourceForm *_condition; // Rewrite condition code |
duke@435 | 526 | InstructForm *_instrs; // List of instructions to expand to |
duke@435 | 527 | OperandForm *_opers; // List of operands generated by expand |
duke@435 | 528 | char *_tempParams; // Hold string until parser is finished. |
duke@435 | 529 | char *_tempBlock; // Hold string until parser is finished. |
duke@435 | 530 | |
duke@435 | 531 | // Public Methods |
duke@435 | 532 | RewriteRule(char* params, char* block) ; |
duke@435 | 533 | ~RewriteRule(); // Destructor |
duke@435 | 534 | void dump(); // Debug printer |
duke@435 | 535 | void output(FILE *fp); // Write info to output files |
duke@435 | 536 | }; |
duke@435 | 537 | |
duke@435 | 538 | |
duke@435 | 539 | //==============================Operands======================================= |
duke@435 | 540 | //------------------------------OpClassForm------------------------------------ |
duke@435 | 541 | class OpClassForm : public Form { |
duke@435 | 542 | public: |
duke@435 | 543 | // Public Data |
duke@435 | 544 | const char *_ident; // Name of this operand |
duke@435 | 545 | NameList _oplst; // List of operand forms included in class |
duke@435 | 546 | |
duke@435 | 547 | // Public Methods |
duke@435 | 548 | OpClassForm(const char *id); |
duke@435 | 549 | ~OpClassForm(); |
duke@435 | 550 | |
duke@435 | 551 | // dynamic type check |
duke@435 | 552 | virtual OpClassForm *is_opclass() const; |
duke@435 | 553 | virtual Form::InterfaceType interface_type(FormDict &globals) const; |
duke@435 | 554 | virtual bool stack_slots_only(FormDict &globals) const; |
duke@435 | 555 | |
duke@435 | 556 | virtual bool is_cisc_mem(FormDict &globals) const; |
duke@435 | 557 | |
duke@435 | 558 | |
duke@435 | 559 | // Min and Max opcodes of operands in this operand class |
duke@435 | 560 | int _minCode; |
duke@435 | 561 | int _maxCode; |
duke@435 | 562 | |
duke@435 | 563 | virtual bool ideal_only() const; |
duke@435 | 564 | virtual void dump(); // Debug printer |
duke@435 | 565 | virtual void output(FILE *fp); // Write to output files |
duke@435 | 566 | }; |
duke@435 | 567 | |
duke@435 | 568 | //------------------------------OperandForm------------------------------------ |
duke@435 | 569 | class OperandForm : public OpClassForm { |
duke@435 | 570 | private: |
duke@435 | 571 | bool _ideal_only; // Not a user-defined instruction |
duke@435 | 572 | |
duke@435 | 573 | public: |
duke@435 | 574 | // Public Data |
duke@435 | 575 | NameList _parameters; // Locally defined names |
duke@435 | 576 | FormDict _localNames; // Table of components & their types |
duke@435 | 577 | MatchRule *_matrule; // Matching rule for this operand |
duke@435 | 578 | Interface *_interface; // Encoding interface for this operand |
duke@435 | 579 | Attribute *_attribs; // List of Attribute rules |
duke@435 | 580 | Predicate *_predicate; // Predicate test for this operand |
duke@435 | 581 | Constraint *_constraint; // Constraint Rule for this operand |
duke@435 | 582 | ConstructRule *_construct; // Construction of operand data after matching |
duke@435 | 583 | FormatRule *_format; // Format for assembly generation |
duke@435 | 584 | NameList _classes; // List of opclasses which contain this oper |
duke@435 | 585 | |
duke@435 | 586 | ComponentList _components; // |
duke@435 | 587 | |
duke@435 | 588 | // Public Methods |
duke@435 | 589 | OperandForm(const char *id); |
duke@435 | 590 | OperandForm(const char *id, bool ideal_only); |
duke@435 | 591 | ~OperandForm(); |
duke@435 | 592 | |
duke@435 | 593 | // Dynamic type check |
duke@435 | 594 | virtual OperandForm *is_operand() const; |
duke@435 | 595 | |
duke@435 | 596 | virtual bool ideal_only() const; |
duke@435 | 597 | virtual Form::InterfaceType interface_type(FormDict &globals) const; |
duke@435 | 598 | virtual bool stack_slots_only(FormDict &globals) const; |
duke@435 | 599 | |
duke@435 | 600 | virtual const char *cost(); // Access ins_cost attribute |
duke@435 | 601 | virtual uint num_leaves() const;// Leaves in complex operand |
duke@435 | 602 | // Constants in operands' match rules |
duke@435 | 603 | virtual uint num_consts(FormDict &globals) const; |
duke@435 | 604 | // Constants in operand's match rule with specified type |
duke@435 | 605 | virtual uint num_consts(FormDict &globals, Form::DataType type) const; |
duke@435 | 606 | // Pointer Constants in operands' match rules |
duke@435 | 607 | virtual uint num_const_ptrs(FormDict &globals) const; |
duke@435 | 608 | // The number of input edges in the machine world == num_leaves - num_consts |
duke@435 | 609 | virtual uint num_edges(FormDict &globals) const; |
duke@435 | 610 | |
duke@435 | 611 | // Check if this operand is usable for cisc-spilling |
duke@435 | 612 | virtual bool is_cisc_reg(FormDict &globals) const; |
duke@435 | 613 | |
duke@435 | 614 | // node matches ideal 'Bool', grab condition codes from the ideal world |
duke@435 | 615 | virtual bool is_ideal_bool() const; |
duke@435 | 616 | |
duke@435 | 617 | // Has an integer constant suitable for spill offsets |
duke@435 | 618 | bool has_conI(FormDict &globals) const { |
duke@435 | 619 | return (num_consts(globals,idealI) == 1) && !is_ideal_bool(); } |
duke@435 | 620 | bool has_conL(FormDict &globals) const { |
duke@435 | 621 | return (num_consts(globals,idealL) == 1) && !is_ideal_bool(); } |
duke@435 | 622 | |
duke@435 | 623 | // Node is user-defined operand for an sRegX |
duke@435 | 624 | virtual Form::DataType is_user_name_for_sReg() const; |
duke@435 | 625 | |
duke@435 | 626 | // Return ideal type, if there is a single ideal type for this operand |
duke@435 | 627 | virtual const char *ideal_type(FormDict &globals, RegisterForm *registers = NULL) const; |
duke@435 | 628 | // If there is a single ideal type for this interface field, return it. |
duke@435 | 629 | virtual const char *interface_ideal_type(FormDict &globals, |
duke@435 | 630 | const char *field_name) const; |
duke@435 | 631 | |
duke@435 | 632 | // Return true if this operand represents a bound register class |
duke@435 | 633 | bool is_bound_register() const; |
duke@435 | 634 | |
duke@435 | 635 | // Return the Register class for this operand. Returns NULL if |
duke@435 | 636 | // operand isn't a register form. |
duke@435 | 637 | RegClass* get_RegClass() const; |
duke@435 | 638 | |
duke@435 | 639 | virtual bool is_interface_field(const char *field_name, |
duke@435 | 640 | const char * &value) const; |
duke@435 | 641 | |
duke@435 | 642 | // If this operand has a single ideal type, return its type |
duke@435 | 643 | virtual Form::DataType simple_type(FormDict &globals) const; |
duke@435 | 644 | // If this operand is an ideal constant, return its type |
duke@435 | 645 | virtual Form::DataType is_base_constant(FormDict &globals) const; |
duke@435 | 646 | |
duke@435 | 647 | // "true" if this operand is a simple type that is swallowed |
duke@435 | 648 | virtual bool swallowed(FormDict &globals) const; |
duke@435 | 649 | |
duke@435 | 650 | // Return register class name if a constraint specifies the register class. |
duke@435 | 651 | virtual const char *constrained_reg_class() const; |
duke@435 | 652 | // Return the register class associated with 'leaf'. |
duke@435 | 653 | virtual const char *in_reg_class(uint leaf, FormDict &globals); |
duke@435 | 654 | |
duke@435 | 655 | // Build component list from MatchRule and operand's parameter list |
duke@435 | 656 | virtual void build_components(); // top-level operands |
duke@435 | 657 | |
duke@435 | 658 | // Return zero-based position in component list; -1 if not in list. |
duke@435 | 659 | virtual int operand_position(const char *name, int usedef); |
duke@435 | 660 | |
duke@435 | 661 | // Return zero-based position in component list; -1 if not in list. |
duke@435 | 662 | virtual int constant_position(FormDict &globals, const Component *comp); |
duke@435 | 663 | virtual int constant_position(FormDict &globals, const char *local_name); |
duke@435 | 664 | // Return the operand form corresponding to the given index, else NULL. |
duke@435 | 665 | virtual OperandForm *constant_operand(FormDict &globals, uint const_index); |
duke@435 | 666 | |
duke@435 | 667 | // Return zero-based position in component list; -1 if not in list. |
duke@435 | 668 | virtual int register_position(FormDict &globals, const char *regname); |
duke@435 | 669 | |
duke@435 | 670 | const char *reduce_result() const; |
duke@435 | 671 | // Return the name of the operand on the right hand side of the binary match |
duke@435 | 672 | // Return NULL if there is no right hand side |
duke@435 | 673 | const char *reduce_right(FormDict &globals) const; |
duke@435 | 674 | const char *reduce_left(FormDict &globals) const; |
duke@435 | 675 | |
duke@435 | 676 | |
duke@435 | 677 | // --------------------------- FILE *output_routines |
duke@435 | 678 | // |
duke@435 | 679 | // Output code for disp_is_oop, if true. |
duke@435 | 680 | void disp_is_oop(FILE *fp, FormDict &globals); |
duke@435 | 681 | // Generate code for internal and external format methods |
duke@435 | 682 | void int_format(FILE *fp, FormDict &globals, uint index); |
duke@435 | 683 | void ext_format(FILE *fp, FormDict &globals, uint index); |
duke@435 | 684 | void format_constant(FILE *fp, uint con_index, uint con_type); |
duke@435 | 685 | // Output code to access the value of the index'th constant |
duke@435 | 686 | void access_constant(FILE *fp, FormDict &globals, |
duke@435 | 687 | uint con_index); |
duke@435 | 688 | // --------------------------- |
duke@435 | 689 | |
duke@435 | 690 | |
duke@435 | 691 | virtual void dump(); // Debug printer |
duke@435 | 692 | virtual void output(FILE *fp); // Write to output files |
duke@435 | 693 | }; |
duke@435 | 694 | |
duke@435 | 695 | //------------------------------Constraint------------------------------------- |
duke@435 | 696 | class Constraint : public Form { |
duke@435 | 697 | private: |
duke@435 | 698 | |
duke@435 | 699 | public: |
duke@435 | 700 | const char *_func; // Constraint function |
duke@435 | 701 | const char *_arg; // function's argument |
duke@435 | 702 | |
duke@435 | 703 | // Public Methods |
duke@435 | 704 | Constraint(const char *func, const char *arg); // Constructor |
duke@435 | 705 | ~Constraint(); |
duke@435 | 706 | |
duke@435 | 707 | bool stack_slots_only() const; |
duke@435 | 708 | |
duke@435 | 709 | void dump(); // Debug printer |
duke@435 | 710 | void output(FILE *fp); // Write info to output files |
duke@435 | 711 | }; |
duke@435 | 712 | |
duke@435 | 713 | //------------------------------Predicate-------------------------------------- |
duke@435 | 714 | class Predicate : public Form { |
duke@435 | 715 | private: |
duke@435 | 716 | |
duke@435 | 717 | public: |
duke@435 | 718 | // Public Data |
duke@435 | 719 | char *_pred; // C++ source string for predicate |
duke@435 | 720 | |
duke@435 | 721 | // Public Methods |
duke@435 | 722 | Predicate(char *pr); |
duke@435 | 723 | ~Predicate(); |
duke@435 | 724 | |
duke@435 | 725 | void dump(); |
duke@435 | 726 | void output(FILE *fp); |
duke@435 | 727 | }; |
duke@435 | 728 | |
duke@435 | 729 | //------------------------------Interface-------------------------------------- |
duke@435 | 730 | class Interface : public Form { |
duke@435 | 731 | private: |
duke@435 | 732 | |
duke@435 | 733 | public: |
duke@435 | 734 | // Public Data |
duke@435 | 735 | const char *_name; // String representing the interface name |
duke@435 | 736 | |
duke@435 | 737 | // Public Methods |
duke@435 | 738 | Interface(const char *name); |
duke@435 | 739 | ~Interface(); |
duke@435 | 740 | |
duke@435 | 741 | virtual Form::InterfaceType interface_type(FormDict &globals) const; |
duke@435 | 742 | |
duke@435 | 743 | RegInterface *is_RegInterface(); |
duke@435 | 744 | MemInterface *is_MemInterface(); |
duke@435 | 745 | ConstInterface *is_ConstInterface(); |
duke@435 | 746 | CondInterface *is_CondInterface(); |
duke@435 | 747 | |
duke@435 | 748 | |
duke@435 | 749 | void dump(); |
duke@435 | 750 | void output(FILE *fp); |
duke@435 | 751 | }; |
duke@435 | 752 | |
duke@435 | 753 | //------------------------------RegInterface----------------------------------- |
duke@435 | 754 | class RegInterface : public Interface { |
duke@435 | 755 | private: |
duke@435 | 756 | |
duke@435 | 757 | public: |
duke@435 | 758 | // Public Methods |
duke@435 | 759 | RegInterface(); |
duke@435 | 760 | ~RegInterface(); |
duke@435 | 761 | |
duke@435 | 762 | void dump(); |
duke@435 | 763 | void output(FILE *fp); |
duke@435 | 764 | }; |
duke@435 | 765 | |
duke@435 | 766 | //------------------------------ConstInterface--------------------------------- |
duke@435 | 767 | class ConstInterface : public Interface { |
duke@435 | 768 | private: |
duke@435 | 769 | |
duke@435 | 770 | public: |
duke@435 | 771 | // Public Methods |
duke@435 | 772 | ConstInterface(); |
duke@435 | 773 | ~ConstInterface(); |
duke@435 | 774 | |
duke@435 | 775 | void dump(); |
duke@435 | 776 | void output(FILE *fp); |
duke@435 | 777 | }; |
duke@435 | 778 | |
duke@435 | 779 | //------------------------------MemInterface----------------------------------- |
duke@435 | 780 | class MemInterface : public Interface { |
duke@435 | 781 | private: |
duke@435 | 782 | |
duke@435 | 783 | public: |
duke@435 | 784 | // Public Data |
duke@435 | 785 | char *_base; // Base address |
duke@435 | 786 | char *_index; // index |
duke@435 | 787 | char *_scale; // scaling factor |
duke@435 | 788 | char *_disp; // displacement |
duke@435 | 789 | |
duke@435 | 790 | // Public Methods |
duke@435 | 791 | MemInterface(char *base, char *index, char *scale, char *disp); |
duke@435 | 792 | ~MemInterface(); |
duke@435 | 793 | |
duke@435 | 794 | void dump(); |
duke@435 | 795 | void output(FILE *fp); |
duke@435 | 796 | }; |
duke@435 | 797 | |
duke@435 | 798 | //------------------------------CondInterface---------------------------------- |
duke@435 | 799 | class CondInterface : public Interface { |
duke@435 | 800 | private: |
duke@435 | 801 | |
duke@435 | 802 | public: |
duke@435 | 803 | const char *_equal; |
duke@435 | 804 | const char *_not_equal; |
duke@435 | 805 | const char *_less; |
duke@435 | 806 | const char *_greater_equal; |
duke@435 | 807 | const char *_less_equal; |
duke@435 | 808 | const char *_greater; |
rbackman@5791 | 809 | const char *_overflow; |
rbackman@5791 | 810 | const char *_no_overflow; |
never@850 | 811 | const char *_equal_format; |
never@850 | 812 | const char *_not_equal_format; |
never@850 | 813 | const char *_less_format; |
never@850 | 814 | const char *_greater_equal_format; |
never@850 | 815 | const char *_less_equal_format; |
never@850 | 816 | const char *_greater_format; |
rbackman@5791 | 817 | const char *_overflow_format; |
rbackman@5791 | 818 | const char *_no_overflow_format; |
duke@435 | 819 | |
duke@435 | 820 | // Public Methods |
never@850 | 821 | CondInterface(const char* equal, const char* equal_format, |
never@850 | 822 | const char* not_equal, const char* not_equal_format, |
never@850 | 823 | const char* less, const char* less_format, |
never@850 | 824 | const char* greater_equal, const char* greater_equal_format, |
never@850 | 825 | const char* less_equal, const char* less_equal_format, |
rbackman@5791 | 826 | const char* greater, const char* greater_format, |
rbackman@5791 | 827 | const char* overflow, const char* overflow_format, |
rbackman@5791 | 828 | const char* no_overflow, const char* no_overflow_format); |
duke@435 | 829 | ~CondInterface(); |
duke@435 | 830 | |
duke@435 | 831 | void dump(); |
duke@435 | 832 | void output(FILE *fp); |
duke@435 | 833 | }; |
duke@435 | 834 | |
duke@435 | 835 | //------------------------------ConstructRule---------------------------------- |
duke@435 | 836 | class ConstructRule : public Form { |
duke@435 | 837 | private: |
duke@435 | 838 | |
duke@435 | 839 | public: |
duke@435 | 840 | // Public Data |
duke@435 | 841 | char *_expr; // String representing the match expression |
duke@435 | 842 | char *_construct; // String representing C++ constructor code |
duke@435 | 843 | |
duke@435 | 844 | // Public Methods |
duke@435 | 845 | ConstructRule(char *cnstr); |
duke@435 | 846 | ~ConstructRule(); |
duke@435 | 847 | |
duke@435 | 848 | void dump(); |
duke@435 | 849 | void output(FILE *fp); |
duke@435 | 850 | }; |
duke@435 | 851 | |
duke@435 | 852 | |
duke@435 | 853 | //==============================Shared========================================= |
duke@435 | 854 | //------------------------------AttributeForm---------------------------------- |
duke@435 | 855 | class AttributeForm : public Form { |
duke@435 | 856 | private: |
duke@435 | 857 | // counters for unique instruction or operand ID |
duke@435 | 858 | static int _insId; // user-defined machine instruction types |
duke@435 | 859 | static int _opId; // user-defined operand types |
duke@435 | 860 | |
duke@435 | 861 | int id; // hold type for this object |
duke@435 | 862 | |
duke@435 | 863 | public: |
duke@435 | 864 | // Public Data |
duke@435 | 865 | char *_attrname; // Name of attribute |
duke@435 | 866 | int _atype; // Either INS_ATTR or OP_ATTR |
duke@435 | 867 | char *_attrdef; // C++ source which evaluates to constant |
duke@435 | 868 | |
duke@435 | 869 | // Public Methods |
duke@435 | 870 | AttributeForm(char *attr, int type, char *attrdef); |
duke@435 | 871 | ~AttributeForm(); |
duke@435 | 872 | |
duke@435 | 873 | // Dynamic type check |
duke@435 | 874 | virtual AttributeForm *is_attribute() const; |
duke@435 | 875 | |
duke@435 | 876 | int type() { return id;} // return this object's "id" |
duke@435 | 877 | |
duke@435 | 878 | static const char* _ins_cost; // "ins_cost" |
duke@435 | 879 | static const char* _op_cost; // "op_cost" |
duke@435 | 880 | |
duke@435 | 881 | void dump(); // Debug printer |
duke@435 | 882 | void output(FILE *fp); // Write output files |
duke@435 | 883 | }; |
duke@435 | 884 | |
duke@435 | 885 | //------------------------------Component-------------------------------------- |
duke@435 | 886 | class Component : public Form { |
duke@435 | 887 | private: |
duke@435 | 888 | |
duke@435 | 889 | public: |
duke@435 | 890 | // Public Data |
duke@435 | 891 | const char *_name; // Name of this component |
duke@435 | 892 | const char *_type; // Type of this component |
duke@435 | 893 | int _usedef; // Value of component |
duke@435 | 894 | |
duke@435 | 895 | // Public Methods |
duke@435 | 896 | Component(const char *name, const char *type, int usedef); |
duke@435 | 897 | ~Component(); |
duke@435 | 898 | |
duke@435 | 899 | |
duke@435 | 900 | // Return 'true' if this use def info equals the parameter |
duke@435 | 901 | bool is(int use_def_kill_enum) const; |
duke@435 | 902 | // Return 'true' if this use def info is a superset of parameter |
duke@435 | 903 | bool isa(int use_def_kill_enum) const; |
duke@435 | 904 | int promote_use_def_info(int new_use_def); |
duke@435 | 905 | const char *base_type(FormDict &globals); |
duke@435 | 906 | // Form::DataType is_base_constant(FormDict &globals); |
duke@435 | 907 | |
duke@435 | 908 | void dump(); // Debug printer |
duke@435 | 909 | void output(FILE *fp); // Write to output files |
kvn@4161 | 910 | const char* getUsedefName(); |
duke@435 | 911 | |
duke@435 | 912 | public: |
duke@435 | 913 | // Implementation depends upon working bit intersection and union. |
duke@435 | 914 | enum use_def_enum { |
duke@435 | 915 | INVALID = 0x0, |
duke@435 | 916 | USE = 0x1, |
duke@435 | 917 | DEF = 0x2, USE_DEF = 0x3, |
duke@435 | 918 | KILL = 0x4, USE_KILL = 0x5, |
duke@435 | 919 | SYNTHETIC = 0x8, |
roland@3316 | 920 | TEMP = USE | SYNTHETIC, |
roland@3316 | 921 | CALL = 0x10 |
duke@435 | 922 | }; |
duke@435 | 923 | }; |
duke@435 | 924 | |
duke@435 | 925 | |
duke@435 | 926 | //------------------------------MatchNode-------------------------------------- |
duke@435 | 927 | class MatchNode : public Form { |
duke@435 | 928 | private: |
duke@435 | 929 | |
duke@435 | 930 | public: |
duke@435 | 931 | // Public Data |
duke@435 | 932 | const char *_result; // The name of the output of this node |
duke@435 | 933 | const char *_name; // The name that appeared in the match rule |
duke@435 | 934 | const char *_opType; // The Operation/Type matched |
duke@435 | 935 | MatchNode *_lChild; // Left child in expression tree |
duke@435 | 936 | MatchNode *_rChild; // Right child in expression tree |
duke@435 | 937 | int _numleaves; // Sum of numleaves for all direct children |
duke@435 | 938 | ArchDesc &_AD; // Reference to ArchDesc object |
duke@435 | 939 | char *_internalop; // String representing internal operand |
duke@435 | 940 | int _commutative_id; // id of commutative operation |
duke@435 | 941 | |
duke@435 | 942 | // Public Methods |
duke@435 | 943 | MatchNode(ArchDesc &ad, const char *result = 0, const char *expr = 0, |
duke@435 | 944 | const char *opType=0, MatchNode *lChild=NULL, |
duke@435 | 945 | MatchNode *rChild=NULL); |
duke@435 | 946 | MatchNode(ArchDesc &ad, MatchNode& mNode); // Shallow copy constructor; |
duke@435 | 947 | MatchNode(ArchDesc &ad, MatchNode& mNode, int clone); // Construct clone |
duke@435 | 948 | ~MatchNode(); |
duke@435 | 949 | |
duke@435 | 950 | // return 0 if not found: |
duke@435 | 951 | // return 1 if found and position is incremented by operand offset in rule |
duke@435 | 952 | bool find_name(const char *str, int &position) const; |
duke@435 | 953 | bool find_type(const char *str, int &position) const; |
twisti@1038 | 954 | virtual void append_components(FormDict& locals, ComponentList& components, |
twisti@1038 | 955 | bool def_flag = false) const; |
duke@435 | 956 | bool base_operand(uint &position, FormDict &globals, |
duke@435 | 957 | const char * &result, const char * &name, |
duke@435 | 958 | const char * &opType) const; |
duke@435 | 959 | // recursive count on operands |
duke@435 | 960 | uint num_consts(FormDict &globals) const; |
duke@435 | 961 | uint num_const_ptrs(FormDict &globals) const; |
duke@435 | 962 | // recursive count of constants with specified type |
duke@435 | 963 | uint num_consts(FormDict &globals, Form::DataType type) const; |
duke@435 | 964 | // uint num_consts() const; // Local inspection only |
duke@435 | 965 | int needs_ideal_memory_edge(FormDict &globals) const; |
duke@435 | 966 | int needs_base_oop_edge() const; |
duke@435 | 967 | |
duke@435 | 968 | // Help build instruction predicates. Search for operand names. |
duke@435 | 969 | void count_instr_names( Dict &names ); |
duke@435 | 970 | int build_instr_pred( char *buf, const char *name, int cnt ); |
duke@435 | 971 | void build_internalop( ); |
duke@435 | 972 | |
duke@435 | 973 | // Return the name of the operands associated with reducing to this operand: |
duke@435 | 974 | // The result type, plus the left and right sides of the binary match |
duke@435 | 975 | // Return NULL if there is no left or right hand side |
duke@435 | 976 | bool sets_result() const; // rule "Set"s result of match |
duke@435 | 977 | const char *reduce_right(FormDict &globals) const; |
duke@435 | 978 | const char *reduce_left (FormDict &globals) const; |
duke@435 | 979 | |
duke@435 | 980 | // Recursive version of check in MatchRule |
twisti@1038 | 981 | int cisc_spill_match(FormDict& globals, RegisterForm* registers, |
twisti@1038 | 982 | MatchNode* mRule2, const char* &operand, |
twisti@1038 | 983 | const char* ®_type); |
duke@435 | 984 | int cisc_spill_merge(int left_result, int right_result); |
duke@435 | 985 | |
twisti@1038 | 986 | virtual bool equivalent(FormDict& globals, MatchNode* mNode2); |
duke@435 | 987 | |
duke@435 | 988 | void count_commutative_op(int& count); |
duke@435 | 989 | void swap_commutative_op(bool atroot, int count); |
duke@435 | 990 | |
duke@435 | 991 | void dump(); |
duke@435 | 992 | void output(FILE *fp); |
duke@435 | 993 | }; |
duke@435 | 994 | |
duke@435 | 995 | //------------------------------MatchRule-------------------------------------- |
duke@435 | 996 | class MatchRule : public MatchNode { |
duke@435 | 997 | private: |
duke@435 | 998 | |
duke@435 | 999 | public: |
duke@435 | 1000 | // Public Data |
duke@435 | 1001 | const char *_machType; // Machine type index |
duke@435 | 1002 | int _depth; // Expression tree depth |
duke@435 | 1003 | char *_construct; // String representing C++ constructor code |
duke@435 | 1004 | int _numchilds; // Number of direct children |
duke@435 | 1005 | MatchRule *_next; // Pointer to next match rule |
duke@435 | 1006 | |
duke@435 | 1007 | // Public Methods |
duke@435 | 1008 | MatchRule(ArchDesc &ad); |
duke@435 | 1009 | MatchRule(ArchDesc &ad, MatchRule* mRule); // Shallow copy constructor; |
duke@435 | 1010 | MatchRule(ArchDesc &ad, MatchNode* mroot, int depth, char* construct, int numleaves); |
duke@435 | 1011 | ~MatchRule(); |
duke@435 | 1012 | |
twisti@1038 | 1013 | virtual void append_components(FormDict& locals, ComponentList& components, bool def_flag = false) const; |
duke@435 | 1014 | // Recursive call on all operands' match rules in my match rule. |
duke@435 | 1015 | bool base_operand(uint &position, FormDict &globals, |
duke@435 | 1016 | const char * &result, const char * &name, |
duke@435 | 1017 | const char * &opType) const; |
duke@435 | 1018 | |
duke@435 | 1019 | |
duke@435 | 1020 | bool is_base_register(FormDict &globals) const; |
duke@435 | 1021 | Form::DataType is_base_constant(FormDict &globals) const; |
duke@435 | 1022 | bool is_chain_rule(FormDict &globals) const; |
duke@435 | 1023 | int is_ideal_copy() const; |
duke@435 | 1024 | int is_expensive() const; // node matches ideal 'CosD' |
duke@435 | 1025 | bool is_ideal_if() const; // node matches ideal 'If' |
duke@435 | 1026 | bool is_ideal_fastlock() const; // node matches ideal 'FastLock' |
duke@435 | 1027 | bool is_ideal_jump() const; // node matches ideal 'Jump' |
duke@435 | 1028 | bool is_ideal_membar() const; // node matches ideal 'MemBarXXX' |
duke@435 | 1029 | bool is_ideal_loadPC() const; // node matches ideal 'LoadPC' |
duke@435 | 1030 | bool is_ideal_box() const; // node matches ideal 'Box' |
duke@435 | 1031 | bool is_ideal_goto() const; // node matches ideal 'Goto' |
duke@435 | 1032 | bool is_ideal_loopEnd() const; // node matches ideal 'LoopEnd' |
duke@435 | 1033 | bool is_ideal_bool() const; // node matches ideal 'Bool' |
kvn@3882 | 1034 | bool is_vector() const; // vector instruction |
duke@435 | 1035 | Form::DataType is_ideal_load() const;// node matches ideal 'LoadXNode' |
never@1290 | 1036 | // Should antidep checks be disabled for this rule |
never@1290 | 1037 | // See definition of MatchRule::skip_antidep_check |
never@1290 | 1038 | bool skip_antidep_check() const; |
duke@435 | 1039 | Form::DataType is_ideal_store() const;// node matches ideal 'StoreXNode' |
duke@435 | 1040 | |
duke@435 | 1041 | // Check if 'mRule2' is a cisc-spill variant of this MatchRule |
twisti@1038 | 1042 | int matchrule_cisc_spill_match(FormDict &globals, RegisterForm* registers, |
twisti@1038 | 1043 | MatchRule* mRule2, const char* &operand, |
twisti@1038 | 1044 | const char* ®_type); |
duke@435 | 1045 | |
duke@435 | 1046 | // Check if 'mRule2' is equivalent to this MatchRule |
twisti@1038 | 1047 | virtual bool equivalent(FormDict& globals, MatchNode* mRule2); |
duke@435 | 1048 | |
twisti@1038 | 1049 | void matchrule_swap_commutative_op(const char* instr_ident, int count, int& match_rules_cnt); |
duke@435 | 1050 | |
duke@435 | 1051 | void dump(); |
kvn@4161 | 1052 | void output_short(FILE *fp); |
duke@435 | 1053 | void output(FILE *fp); |
duke@435 | 1054 | }; |
duke@435 | 1055 | |
duke@435 | 1056 | //------------------------------Attribute-------------------------------------- |
duke@435 | 1057 | class Attribute : public Form { |
duke@435 | 1058 | private: |
duke@435 | 1059 | |
duke@435 | 1060 | public: |
duke@435 | 1061 | // Public Data |
duke@435 | 1062 | char *_ident; // Name of predefined attribute |
duke@435 | 1063 | char *_val; // C++ source which evaluates to constant |
duke@435 | 1064 | int _atype; // Either INS_ATTR or OP_ATTR |
duke@435 | 1065 | int int_val(ArchDesc &ad); // Return atoi(_val), ensuring syntax. |
duke@435 | 1066 | |
duke@435 | 1067 | // Public Methods |
duke@435 | 1068 | Attribute(char *id, char* val, int type); |
duke@435 | 1069 | ~Attribute(); |
duke@435 | 1070 | |
duke@435 | 1071 | void dump(); |
duke@435 | 1072 | void output(FILE *fp); |
duke@435 | 1073 | }; |
duke@435 | 1074 | |
duke@435 | 1075 | //------------------------------FormatRule------------------------------------- |
duke@435 | 1076 | class FormatRule : public Form { |
duke@435 | 1077 | private: |
duke@435 | 1078 | |
duke@435 | 1079 | public: |
duke@435 | 1080 | // Public Data |
duke@435 | 1081 | // There is an entry in _strings, perhaps NULL, that precedes each _rep_vars |
duke@435 | 1082 | NameList _strings; // Strings passed through to tty->print |
duke@435 | 1083 | NameList _rep_vars; // replacement variables |
duke@435 | 1084 | char *_temp; // String representing the assembly code |
duke@435 | 1085 | |
duke@435 | 1086 | // Public Methods |
duke@435 | 1087 | FormatRule(char *temp); |
duke@435 | 1088 | ~FormatRule(); |
duke@435 | 1089 | |
duke@435 | 1090 | void dump(); |
duke@435 | 1091 | void output(FILE *fp); |
duke@435 | 1092 | }; |
stefank@2314 | 1093 | |
stefank@2314 | 1094 | #endif // SHARE_VM_ADLC_FORMSSEL_HPP |