/* * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. *
*/
// FORMSSEL.HPP - ADL Parser Instruction Selection Forms Classes
// Class List class Form; class InstructForm; class MachNodeForm; class OperandForm; class OpClassForm; class AttributeForm; class RegisterForm; class PipelineForm; class SourceForm; class EncodeForm; class Component; class Constraint; class Predicate; class MatchRule; class Attribute; class Effect; class ExpandRule; class RewriteRule; class ConstructRule; class FormatRule; class Peephole; class EncClass; class Interface; class RegInterface; class ConstInterface; class MemInterface; class CondInterface; class Opcode; class InsEncode; class RegDef; class RegClass; class CodeSnippetRegClass; class ConditionalRegClass; class AllocClass; class ResourceForm; class PipeDesc; class PipeClass; class PeepMatch; class PeepConstraint; class PeepReplace; class MatchList;
class ArchDesc;
//==============================Instructions=================================== //------------------------------InstructForm----------------------------------- class InstructForm : public Form { private: bool _ideal_only; // Not a user-defined instruction // Members used for tracking CISC-spilling int _cisc_spill_operand;// Which operand may cisc-spill void set_cisc_spill_operand(uint op_index) { _cisc_spill_operand = op_index; } bool _is_cisc_alternate;
InstructForm *_cisc_spill_alternate;// cisc possible replacement constchar *_cisc_reg_mask_name;
InstructForm *_short_branch_form; bool _is_short_branch; bool _is_mach_constant; // True if Node is a MachConstantNode. bool _needs_constant_base; // True if Node needs the mach_constant_base input.
uint _alignment;
public: // Public Data constchar *_ident; // Name of this instruction
NameList _parameters; // Locally defined names
FormDict _localNames; // Table of operands & their types
MatchRule *_matrule; // Matching rule for this instruction
Opcode *_opcode; // Encoding of the opcode for instruction char *_size; // Size of instruction
InsEncode *_insencode; // Encoding class instruction belongs to
InsEncode *_constant; // Encoding class constant value belongs to bool _is_postalloc_expand; // Indicates that encoding just does a lateExpand.
Attribute *_attribs; // List of Attribute rules
Predicate *_predicate; // Predicate test for this instruction
FormDict _effects; // Dictionary of effect rules
ExpandRule *_exprule; // Expand rule for this instruction
RewriteRule *_rewrule; // Rewrite rule for this instruction
FormatRule *_format; // Format for assembly generation
Peephole *_peephole; // List of peephole rules for instruction constchar *_ins_pipe; // Instruction Scheduling description class
uint *_uniq_idx; // Indexes of unique operands
uint _uniq_idx_length; // Length of _uniq_idx array
uint _num_uniq; // Number of unique operands
ComponentList _components; // List of Components matches MachNode's // operand structure
bool _has_call; // contain a call and caller save registers should be saved?
// Dynamic type check virtual InstructForm *is_instruction() const;
virtualbool ideal_only() const;
// This instruction sets a result virtualbool sets_result() const; // This instruction needs projections for additional DEFs or KILLs virtualbool needs_projections(); // This instruction needs extra nodes for temporary inputs virtualbool has_temps(); // This instruction defines or kills more than one object virtual uint num_defs_or_kills(); // This instruction has an expand rule? virtualbool expands() const ; // This instruction has a late expand rule? virtualbool postalloc_expands() const; // Return this instruction's first peephole rule, or NULL virtual Peephole *peepholes() const; // Add a peephole rule to this instruction virtualvoid append_peephole(Peephole *peep);
virtual Form::CallType is_ideal_call() const; // matches ideal 'Call' virtual Form::DataType is_ideal_load() const; // node matches ideal 'LoadXNode' // Should antidep checks be disabled for this Instruct // See definition of MatchRule::skip_antidep_check bool skip_antidep_check() const; virtual Form::DataType is_ideal_store() const;// node matches ideal 'StoreXNode' bool is_ideal_mem() const { return is_ideal_load() != Form::none || is_ideal_store() != Form::none; } virtual uint two_address(FormDict &globals); // output reg must match input reg // when chaining a constant to an instruction, return 'true' and set opType virtual Form::DataType is_chain_of_constant(FormDict &globals); virtual Form::DataType is_chain_of_constant(FormDict &globals, constchar * &opType); virtual Form::DataType is_chain_of_constant(FormDict &globals, constchar * &opType, constchar * &result_type);
// Check if a simple chain rule virtualbool is_simple_chain_rule(FormDict &globals) const;
// check for structural rematerialization virtualbool rematerialize(FormDict &globals, RegisterForm *registers);
// loads from memory, so must check for anti-dependence virtualbool needs_anti_dependence_check(FormDict &globals) const; virtualint memory_operand(FormDict &globals) const;
// This instruction captures the machine-independent bottom_type // Expected use is for pointer vs oop determination for LoadP virtualbool captures_bottom_type(FormDict& globals) const;
virtualconstchar *cost(); // Access ins_cost attribute virtual uint num_opnds(); // Count of num_opnds for MachNode class // Counts USE_DEF opnds twice. See also num_unique_opnds(). virtual uint num_post_match_opnds(); virtual uint num_consts(FormDict &globals) const;// Constants in match rule // Constants in match rule with specified type virtual uint num_consts(FormDict &globals, Form::DataType type) const;
// Return the register class associated with 'leaf'. virtualconstchar *out_reg_class(FormDict &globals);
// number of ideal node inputs to skip virtual uint oper_input_base(FormDict &globals);
// Does this instruction need a base-oop edge? int needs_base_oop_edge(FormDict &globals) const;
// Build instruction predicates. If the user uses the same operand name // twice, we need to check that the operands are pointer-eequivalent in // the DFA during the labeling process.
Predicate *build_predicate();
virtualvoid build_components(); // top-level operands // Return zero-based position in component list; -1 if not in list. virtualint operand_position(constchar *name, int usedef); virtualint operand_position_format(constchar *name);
// Return zero-based position in component list; -1 if not in list. virtualint label_position(); virtualint method_position(); // Return number of relocation entries needed for this instruction. virtual uint reloc(FormDict &globals);
constchar *opnd_ident(int idx); // Name of operand #idx. constchar *reduce_result(); // Return the name of the operand on the right hand side of the binary match // Return NULL if there is no right hand side constchar *reduce_right(FormDict &globals) const; constchar *reduce_left(FormDict &globals) const;
// Base class for this instruction, MachNode except for calls virtualconstchar *mach_base_class(FormDict &globals) const;
// Search through operands to determine operands unique positions. void set_unique_opnds();
uint num_unique_opnds() { return _num_uniq; }
uint unique_opnds_idx(int idx) { if (_uniq_idx != NULL && idx > 0) {
assert((uint)idx < _uniq_idx_length, "out of bounds"); return _uniq_idx[idx];
} else { return idx;
}
} constchar *unique_opnd_ident(uint idx); // Name of operand at unique idx.
// Operands which are only KILLs aren't part of the input array and // require special handling in some cases. Their position in this // operand list is higher than the number of unique operands. bool is_noninput_operand(uint idx) { return (idx >= num_unique_opnds());
}
// --------------------------- FILE *output_routines // // Generate the format call for the replacement variable void rep_var_format(FILE *fp, constchar *rep_var); // Generate index values needed for determining the operand position void index_temps (FILE *fp, FormDict &globals, constchar *prefix = "", constchar *receiver = ""); // ---------------------------
virtualbool verify(); // Check consistency after parsing
void dump(); // Debug printer void output(FILE *fp); // Write info to output files
};
//------------------------------EncClass--------------------------------------- class EncClass : public Form { public: // NameList for parameter type and name
NameList _parameter_type;
NameList _parameter_name;
// Breakdown the encoding into strings separated by $replacement_variables // There is an entry in _strings, perhaps NULL, that precedes each _rep_vars
NameList _code; // Strings passed through to tty->print
NameList _rep_vars; // replacement variables
NameList _parameters; // Locally defined names
FormDict _localNames; // Table of components & their types
public: // Public Data constchar *_name; // encoding class name
// Public Methods
EncClass(constchar *name);
~EncClass();
// --------------------------- Parameters // Add a parameter <type,name> pair void add_parameter(constchar *parameter_type, constchar *parameter_name); // Verify operand types in parameter list bool check_parameter_types(FormDict &globals); // Obtain the zero-based index corresponding to a replacement variable int rep_var_index(constchar *rep_var); int num_args() { return _parameter_name.count(); }
// --------------------------- Code Block // Add code void add_code(constchar *string_preceding_replacement_var); // Add a replacement variable or one of its subfields // Subfields are stored with a leading '$' void add_rep_var(char *replacement_var);
//------------------------------InsEncode-------------------------------------- class InsEncode : public Form { private: // Public Data (access directly only for reads) // The encodings can only have the values predefined by the ADLC: // blank, RegReg, RegMem, MemReg, ...
NameList _encoding; // NameList _parameter; // The parameters for each encoding are preceded by a NameList::_signal // and follow the parameters for the previous encoding.
// char *_encode; // Type of instruction encoding
public: // Public Methods
InsEncode();
~InsEncode();
// Add "encode class name" and its parameters
NameAndList *add_encode(char *encode_method_name); // Parameters are added to the returned "NameAndList" by the parser
// Access the list of encodings void reset(); constchar *encode_class_iter();
// Returns the number of arguments to the current encoding in the iteration int current_encoding_num_args() { return ((NameAndList*)_encoding.current())->count();
}
// --------------------------- Parameters // The following call depends upon position within encode_class_iteration // // Obtain parameter name from zero based index constchar *rep_var_name(InstructForm &inst, uint param_no); // ---------------------------
void dump(); void output(FILE *fp);
};
//------------------------------Effect----------------------------------------- class Effect : public Form { private:
public: // Public Data constchar *_name; // Pre-defined name for effect int _use_def; // Enumeration value of effect
// Public Methods
Effect(constchar *name); // Constructor
~Effect(); // Destructor
// Dynamic type check virtual Effect *is_effect() const;
// Return 'true' if this use def info equals the parameter bool is(int use_def_kill_enum) const; // Return 'true' if this use def info is a superset of parameter bool isa(int use_def_kill_enum) const;
void dump(); // Debug printer void output(FILE *fp); // Write info to output files
};
//------------------------------ExpandRule------------------------------------- class ExpandRule : public Form { private:
NameList _expand_instrs; // ordered list of instructions and operands
public: // Public Data
NameList _newopers; // List of newly created operands
Dict _newopconst; // Map new operands to their constructors
// Public Methods
ExpandRule(); // Constructor
~ExpandRule(); // Destructor
void dump(); // Debug printer void output(FILE *fp); // Write info to output files
};
//------------------------------RewriteRule------------------------------------ class RewriteRule : public Form { private:
public: // Public Data
SourceForm *_condition; // Rewrite condition code
InstructForm *_instrs; // List of instructions to expand to
OperandForm *_opers; // List of operands generated by expand char *_tempParams; // Hold string until parser is finished. char *_tempBlock; // Hold string until parser is finished.
// Public Methods
RewriteRule(char* params, char* block) ;
~RewriteRule(); // Destructor void dump(); // Debug printer void output(FILE *fp); // Write info to output files
};
//==============================Operands======================================= //------------------------------OpClassForm------------------------------------ class OpClassForm : public Form { public: // Public Data constchar *_ident; // Name of this operand
NameList _oplst; // List of operand forms included in class
// Public Methods
OpClassForm(constchar *id);
~OpClassForm();
//------------------------------OperandForm------------------------------------ class OperandForm : public OpClassForm { private: bool _ideal_only; // Not a user-defined instruction
public: // Public Data
NameList _parameters; // Locally defined names
FormDict _localNames; // Table of components & their types
MatchRule *_matrule; // Matching rule for this operand
Interface *_interface; // Encoding interface for this operand
Attribute *_attribs; // List of Attribute rules
Predicate *_predicate; // Predicate test for this operand
Constraint *_constraint; // Constraint Rule for this operand
ConstructRule *_construct; // Construction of operand data after matching
FormatRule *_format; // Format for assembly generation
NameList _classes; // List of opclasses which contain this oper
ComponentList _components; //
// Public Methods
OperandForm(constchar *id);
OperandForm(constchar *id, bool ideal_only);
~OperandForm();
// Dynamic type check virtual OperandForm *is_operand() const;
virtualconstchar *cost(); // Access ins_cost attribute virtual uint num_leaves() const;// Leaves in complex operand // Constants in operands' match rules virtual uint num_consts(FormDict &globals) const; // Constants in operand's match rule with specified type virtual uint num_consts(FormDict &globals, Form::DataType type) const; // Pointer Constants in operands' match rules virtual uint num_const_ptrs(FormDict &globals) const; // The number of input edges in the machine world == num_leaves - num_consts virtual uint num_edges(FormDict &globals) const;
// Check if this operand is usable for cisc-spilling virtualbool is_cisc_reg(FormDict &globals) const;
// node matches ideal 'Bool', grab condition codes from the ideal world virtualbool is_ideal_bool() const;
// Node is user-defined operand for an sRegX virtual Form::DataType is_user_name_for_sReg() const;
// Return ideal type, if there is a single ideal type for this operand virtualconstchar *ideal_type(FormDict &globals, RegisterForm *registers = NULL) const; // If there is a single ideal type for this interface field, return it. virtualconstchar *interface_ideal_type(FormDict &globals, constchar *field_name) const;
// Return true if this operand represents a bound register class bool is_bound_register() const;
// Return the Register class for this operand. Returns NULL if // operand isn't a register form.
RegClass* get_RegClass() const;
// If this operand has a single ideal type, return its type virtual Form::DataType simple_type(FormDict &globals) const; // If this operand is an ideal constant, return its type virtual Form::DataType is_base_constant(FormDict &globals) const;
// "true" if this operand is a simple type that is swallowed virtualbool swallowed(FormDict &globals) const;
// Return register class name if a constraint specifies the register class. virtualconstchar *constrained_reg_class() const; // Return the register class associated with 'leaf'. virtualconstchar *in_reg_class(uint leaf, FormDict &globals);
// Build component list from MatchRule and operand's parameter list virtualvoid build_components(); // top-level operands
// Return zero-based position in component list; -1 if not in list. virtualint operand_position(constchar *name, int usedef);
// Return zero-based position in component list; -1 if not in list. virtualint constant_position(FormDict &globals, const Component *comp); virtualint constant_position(FormDict &globals, constchar *local_name); // Return the operand form corresponding to the given index, else NULL. virtual OperandForm *constant_operand(FormDict &globals, uint const_index);
// Return zero-based position in component list; -1 if not in list. virtualint register_position(FormDict &globals, constchar *regname);
constchar *reduce_result() const; // Return the name of the operand on the right hand side of the binary match // Return NULL if there is no right hand side constchar *reduce_right(FormDict &globals) const; constchar *reduce_left(FormDict &globals) const;
// --------------------------- FILE *output_routines // // Output code for disp_is_oop, if true. void disp_is_oop(FILE *fp, FormDict &globals); // Generate code for internal and external format methods void int_format(FILE *fp, FormDict &globals, uint index); void ext_format(FILE *fp, FormDict &globals, uint index); void format_constant(FILE *fp, uint con_index, uint con_type); // Output code to access the value of the index'th constant void access_constant(FILE *fp, FormDict &globals,
uint con_index); // ---------------------------
//------------------------------ConstructRule---------------------------------- class ConstructRule : public Form { private:
public: // Public Data char *_expr; // String representing the match expression char *_construct; // String representing C++ constructor code
// Public Methods
ConstructRule(char *cnstr);
~ConstructRule();
void dump(); void output(FILE *fp);
};
//==============================Shared========================================= //------------------------------AttributeForm---------------------------------- class AttributeForm : public Form { private: // counters for unique instruction or operand ID staticint _insId; // user-defined machine instruction types staticint _opId; // user-defined operand types
int id; // hold type for this object
public: // Public Data char *_attrname; // Name of attribute int _atype; // Either INS_ATTR or OP_ATTR char *_attrdef; // C++ source which evaluates to constant
// Public Methods
AttributeForm(char *attr, int type, char *attrdef);
~AttributeForm();
// Dynamic type check virtual AttributeForm *is_attribute() const;
int type() { return id;} // return this object's "id"
//------------------------------Component-------------------------------------- class Component : public Form { private:
public: // Public Data constchar *_name; // Name of this component constchar *_type; // Type of this component int _usedef; // Value of component
// Public Methods
Component(constchar *name, constchar *type, int usedef);
~Component();
// Return 'true' if this use def info equals the parameter bool is(int use_def_kill_enum) const; // Return 'true' if this use def info is a superset of parameter bool isa(int use_def_kill_enum) const; int promote_use_def_info(int new_use_def); constchar *base_type(FormDict &globals); // Form::DataType is_base_constant(FormDict &globals);
public: // Implementation depends upon working bit intersection and union. enum use_def_enum {
INVALID = 0x0,
USE = 0x1,
DEF = 0x2,
USE_DEF = USE | DEF,
KILL = 0x4,
USE_KILL = USE | KILL,
SYNTHETIC = 0x8,
TEMP = USE | SYNTHETIC,
TEMP_DEF = TEMP | DEF,
CALL = 0x10
};
};
//------------------------------MatchNode-------------------------------------- class MatchNode : public Form { private:
public: // Public Data constchar *_result; // The name of the output of this node constchar *_name; // The name that appeared in the match rule constchar *_opType; // The Operation/Type matched
MatchNode *_lChild; // Left child in expression tree
MatchNode *_rChild; // Right child in expression tree int _numleaves; // Sum of numleaves for all direct children
ArchDesc &_AD; // Reference to ArchDesc object char *_internalop; // String representing internal operand int _commutative_id; // id of commutative operation
// return 0 if not found: // return 1 if found and position is incremented by operand offset in rule bool find_name(constchar *str, int &position) const; bool find_type(constchar *str, int &position) const; virtualvoid append_components(FormDict& locals, ComponentList& components, bool def_flag = false) const; bool base_operand(uint &position, FormDict &globals, constchar * &result, constchar * &name, constchar * &opType) const; // recursive count on operands
uint num_consts(FormDict &globals) const;
uint num_const_ptrs(FormDict &globals) const; // recursive count of constants with specified type
uint num_consts(FormDict &globals, Form::DataType type) const; // uint num_consts() const; // Local inspection only int needs_ideal_memory_edge(FormDict &globals) const; int needs_base_oop_edge() const;
// Help build instruction predicates. Search for operand names. void count_instr_names( Dict &names ); int build_instr_pred( char *buf, constchar *name, int cnt, int path_bitmask, int level); void build_internalop( );
// Return the name of the operands associated with reducing to this operand: // The result type, plus the left and right sides of the binary match // Return NULL if there is no left or right hand side bool sets_result() const; // rule "Set"s result of match constchar *reduce_right(FormDict &globals) const; constchar *reduce_left (FormDict &globals) const;
// Recursive version of check in MatchRule int cisc_spill_match(FormDict& globals, RegisterForm* registers,
MatchNode* mRule2, constchar* &operand, constchar* ®_type); int cisc_spill_merge(int left_result, int right_result);
void count_commutative_op(int& count); void swap_commutative_op(bool atroot, int count);
void dump(); void output(FILE *fp);
};
//------------------------------MatchRule-------------------------------------- class MatchRule : public MatchNode { private:
public: // Public Data constchar *_machType; // Machine type index int _depth; // Expression tree depth char *_construct; // String representing C++ constructor code int _numchilds; // Number of direct children
MatchRule *_next; // Pointer to next match rule
// Public Methods
MatchRule(ArchDesc &ad);
MatchRule(ArchDesc &ad, MatchRule* mRule); // Shallow copy constructor;
MatchRule(ArchDesc &ad, MatchNode* mroot, int depth, char* construct, int numleaves);
~MatchRule();
virtualvoid append_components(FormDict& locals, ComponentList& components, bool def_flag = false) const; // Recursive call on all operands' match rules in my match rule. bool base_operand(uint &position, FormDict &globals, constchar * &result, constchar * &name, constchar * &opType) const;
// Check if 'mRule2' is a cisc-spill variant of this MatchRule int matchrule_cisc_spill_match(FormDict &globals, RegisterForm* registers,
MatchRule* mRule2, constchar* &operand, constchar* ®_type);
// Check if 'mRule2' is equivalent to this MatchRule virtualbool equivalent(FormDict& globals, MatchNode* mRule2);
void matchrule_swap_commutative_op(constchar* instr_ident, int count, int& match_rules_cnt);
//------------------------------Attribute-------------------------------------- class Attribute : public Form { private:
public: // Public Data char *_ident; // Name of predefined attribute char *_val; // C++ source which evaluates to constant int _atype; // Either INS_ATTR or OP_ATTR int int_val(ArchDesc &ad); // Return atoi(_val), ensuring syntax.
// Public Methods
Attribute(char *id, char* val, int type);
~Attribute();
void dump(); void output(FILE *fp);
};
//------------------------------FormatRule------------------------------------- class FormatRule : public Form { private:
public: // Public Data // There is an entry in _strings, perhaps NULL, that precedes each _rep_vars
NameList _strings; // Strings passed through to tty->print
NameList _rep_vars; // replacement variables char *_temp; // String representing the assembly code
// Public Methods
FormatRule(char *temp);
~FormatRule();
void dump(); void output(FILE *fp);
};
#endif// SHARE_ADLC_FORMSSEL_HPP
¤ Dauer der Verarbeitung: 0.17 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.