430N/A/*
3261N/A * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
430N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
430N/A *
430N/A * This code is free software; you can redistribute it and/or modify it
430N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation.
430N/A *
2362N/A * This code is distributed in the hope that it will be useful, but WITHOUT
430N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
430N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
430N/A * version 2 for more details (a copy is included in the LICENSE file that
430N/A * accompanied this code).
430N/A *
430N/A * You should have received a copy of the GNU General Public License version
430N/A * 2 along with this work; if not, write to the Free Software Foundation,
430N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
430N/A *
430N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
430N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
2362N/A *
2362N/A */
430N/A
430N/A#ifndef SHARE_VM_ADLC_FORMSOPT_HPP
430N/A#define SHARE_VM_ADLC_FORMSOPT_HPP
430N/A
430N/A// FORMSOPT.HPP - ADL Parser Target Specific Optimization Forms Classes
430N/A
430N/A// Class List
430N/Aclass Form;
430N/Aclass InstructForm;
430N/Aclass OperandForm;
430N/Aclass OpClassForm;
430N/Aclass AttributeForm;
430N/Aclass RegisterForm;
430N/Aclass PipelineForm;
430N/Aclass SourceForm;
430N/Aclass EncodeForm;
1061N/Aclass Component;
430N/Aclass Constraint;
430N/Aclass Predicate;
430N/Aclass MatchRule;
430N/Aclass Attribute;
430N/Aclass Effect;
430N/Aclass ExpandRule;
430N/Aclass RewriteRule;
430N/Aclass ConstructRule;
430N/Aclass FormatRule;
430N/Aclass Peephole;
430N/Aclass PeepMatch;
430N/Aclass PeepConstraint;
430N/Aclass EncClass;
430N/Aclass Interface;
430N/Aclass RegInterface;
430N/Aclass ConstInterface;
430N/Aclass MemInterface;
430N/Aclass CondInterface;
430N/Aclass Opcode;
430N/Aclass InsEncode;
430N/Aclass RegDef;
430N/Aclass RegClass;
430N/Aclass AllocClass;
430N/Aclass ResourceForm;
430N/Aclass PipeClassForm;
430N/Aclass PipeClassOperandForm;
430N/Aclass PipeClassResourceForm;
430N/Aclass PeepMatch;
430N/Aclass PeepConstraint;
430N/Aclass PeepReplace;
430N/Aclass MatchList;
430N/A
430N/Aclass ArchDesc;
430N/A
430N/A//==============================Register Allocation============================
430N/A//------------------------------RegisterForm-----------------------------------
430N/Aclass RegisterForm : public Form {
430N/Aprivate:
430N/A AllocClass *_current_ac; // State used by iter_RegDefs()
430N/A
430N/Apublic:
430N/A // Public Data
430N/A NameList _rdefs; // List of register definition names
430N/A Dict _regDef; // map register name to RegDef*
430N/A
430N/A NameList _rclasses; // List of register class names
430N/A Dict _regClass; // map register class name to RegClass*
430N/A
430N/A NameList _aclasses; // List of allocation class names
430N/A Dict _allocClass; // Dictionary of allocation classes
430N/A
430N/A static int _reg_ctr; // Register counter
430N/A static int RegMask_Size(); // Compute RegMask size
430N/A
430N/A // Public Methods
430N/A RegisterForm();
430N/A ~RegisterForm();
430N/A
430N/A void addRegDef(char *regName, char *callingConv, char *c_conv,
430N/A char * idealtype, char *encoding, char* concreteName);
430N/A RegClass *addRegClass(const char *className);
430N/A AllocClass *addAllocClass(char *allocName);
430N/A void addSpillRegClass();
2285N/A
2285N/A // Provide iteration over all register definitions
2285N/A // in the order used by the register allocator
2285N/A void reset_RegDefs();
2285N/A RegDef *iter_RegDefs();
2285N/A RegDef *getRegDef (const char *regName);
2285N/A
430N/A RegClass *getRegClass(const char *className);
2285N/A
430N/A // Return register mask, compressed chunk and register #
430N/A uint reg_mask(char *register_class);
430N/A
430N/A // Check that register classes are compatible with chunks
430N/A bool verify();
430N/A
430N/A void dump(); // Debug printer
430N/A void output(FILE *fp); // Write info to output files
430N/A};
430N/A
430N/A//------------------------------RegDef-----------------------------------------
430N/Aclass RegDef : public Form {
430N/Apublic:
430N/A // Public Data
430N/A const char *_regname; // ADLC (Opto) Register name
430N/A const char *_callconv; // Calling convention
430N/A const char *_c_conv; // Native calling convention, 'C'
430N/A const char *_idealtype; // Ideal Type for register save/restore
430N/A const char *_concrete; // concrete register name
430N/A
430N/Aprivate:
430N/A const char *_register_encode; // The register encoding
430N/A // The chunk and register mask bits define info for register allocation
430N/A uint32 _register_num; // Which register am I
430N/A
430N/Apublic:
430N/A // Public Methods
430N/A RegDef(char *regname, char *callconv, char *c_conv,
430N/A char *idealtype, char *encoding, char *concrete);
430N/A ~RegDef(); // Destructor
430N/A
430N/A // Interface to define/redefine the register number
430N/A void set_register_num(uint32 new_register_num);
430N/A
430N/A // Bit pattern used for generating machine code
430N/A const char *register_encode() const;
430N/A // Register number used in machine-independent code
430N/A uint32 register_num() const;
430N/A
430N/A void dump(); // Debug printer
430N/A void output(FILE *fp); // Write info to output files
430N/A};
430N/A
430N/A//------------------------------RegClass---------------------------------------
430N/Aclass RegClass : public Form {
430N/Apublic:
430N/A // Public Data
430N/A const char *_classid; // Name of class
430N/A NameList _regDefs; // List of registers in class
430N/A Dict _regDef; // Dictionary of registers in class
430N/A bool _stack_or_reg; // Allowed on any stack slot
430N/A char* _user_defined;
430N/A
430N/A // Public Methods
430N/A RegClass(const char *classid);// Constructor
430N/A
430N/A void addReg(RegDef *regDef); // Add a register to this class
430N/A
430N/A uint size() const; // Number of registers in class
430N/A int regs_in_word( int wordnum, bool stack_also );
430N/A
430N/A const RegDef *get_RegDef(const char *regDef_name) const;
430N/A
430N/A // Returns the lowest numbered register in the mask.
430N/A const RegDef* find_first_elem();
430N/A
430N/A // Iteration support
430N/A void reset(); // Reset the following two iterators
430N/A RegDef *RegDef_iter(); // which move jointly,
430N/A const char *rd_name_iter(); // invoking either advances both.
430N/A
430N/A void dump(); // Debug printer
430N/A void output(FILE *fp); // Write info to output files
430N/A};
430N/A
430N/A//------------------------------AllocClass-------------------------------------
430N/Aclass AllocClass : public Form {
430N/Aprivate:
430N/A
430N/Apublic:
430N/A // Public Data
430N/A char *_classid; // Name of class
430N/A NameList _regDefs; // List of registers in class
430N/A Dict _regDef; // Dictionary of registers in class
430N/A
430N/A // Public Methods
430N/A AllocClass(char *classid); // Constructor
430N/A
430N/A void addReg(RegDef *regDef); // Add a register to this class
430N/A uint size() {return _regDef.Size();} // Number of registers in class
430N/A
430N/A void dump(); // Debug printer
430N/A void output(FILE *fp); // Write info to output files
430N/A};
430N/A
430N/A
430N/A//==============================Frame Handling================================
430N/A//------------------------------FrameForm-------------------------------------
430N/Aclass FrameForm : public Form {
430N/Aprivate:
430N/A
430N/Apublic:
430N/A // Public Data
430N/A bool _direction; // Direction of stack growth
430N/A char *_sync_stack_slots;
430N/A char *_inline_cache_reg;
430N/A char *_interpreter_method_oop_reg;
430N/A char *_interpreter_frame_pointer_reg;
430N/A char *_cisc_spilling_operand_name;
430N/A char *_frame_pointer;
430N/A char *_c_frame_pointer;
430N/A char *_alignment;
430N/A bool _return_addr_loc;
430N/A bool _c_return_addr_loc;
430N/A char *_return_addr;
430N/A char *_c_return_addr;
430N/A char *_in_preserve_slots;
430N/A char *_varargs_C_out_slots_killed;
430N/A char *_calling_convention;
430N/A char *_c_calling_convention;
430N/A char *_return_value;
430N/A char *_c_return_value;
430N/A
430N/A // Public Methods
430N/A FrameForm();
430N/A ~FrameForm();
430N/A
430N/A void dump(); // Debug printer
430N/A void output(FILE *fp); // Write info to output files
430N/A};
430N/A
430N/A
430N/A//==============================Scheduling=====================================
430N/A//------------------------------PipelineForm-----------------------------------
430N/Aclass PipelineForm : public Form {
430N/Aprivate:
430N/A
430N/Apublic:
430N/A // Public Data
430N/A NameList _reslist; // List of pipeline resources
430N/A FormDict _resdict; // Resource Name -> ResourceForm mapping
430N/A int _rescount; // Number of resources (ignores OR cases)
430N/A int _maxcycleused; // Largest cycle used relative to beginning of instruction
430N/A
430N/A NameList _stages; // List of pipeline stages on architecture
430N/A int _stagecnt; // Number of stages listed
430N/A
430N/A NameList _classlist; // List of pipeline classes
430N/A FormDict _classdict; // Class Name -> PipeClassForm mapping
430N/A int _classcnt; // Number of classes
430N/A
430N/A NameList _noplist; // List of NOP instructions
430N/A int _nopcnt; // Number of nop instructions
430N/A
430N/A bool _variableSizeInstrs; // Indicates if this architecture has variable sized instructions
430N/A bool _branchHasDelaySlot; // Indicates that branches have delay slot instructions
430N/A int _maxInstrsPerBundle; // Indicates the maximum number of instructions for ILP
430N/A int _maxBundlesPerCycle; // Indicates the maximum number of bundles for ILP
430N/A int _instrUnitSize; // The minimum instruction unit size, in bytes
430N/A int _bundleUnitSize; // The bundle unit size, in bytes
430N/A int _instrFetchUnitSize; // The size of the I-fetch unit, in bytes [must be power of 2]
430N/A int _instrFetchUnits; // The number of I-fetch units processed per cycle
430N/A
430N/A // Public Methods
430N/A PipelineForm();
430N/A ~PipelineForm();
430N/A
430N/A void dump(); // Debug printer
430N/A void output(FILE *fp); // Write info to output files
430N/A};
430N/A
430N/A//------------------------------ResourceForm-----------------------------------
430N/Aclass ResourceForm : public Form {
1061N/Apublic:
1061N/A unsigned mask() const { return _resmask; };
1061N/A
1061N/Aprivate:
1061N/A // Public Data
1061N/A unsigned _resmask; // Resource Mask (OR of resource specifier bits)
430N/A
430N/Apublic:
430N/A
430N/A // Virtual Methods
430N/A virtual ResourceForm *is_resource() const;
430N/A
430N/A // Public Methods
430N/A ResourceForm(unsigned resmask); // Constructor
430N/A ~ResourceForm(); // Destructor
430N/A
430N/A void dump(); // Debug printer
430N/A void output(FILE *fp); // Write info to output files
430N/A};
430N/A
430N/A//------------------------------PipeClassOperandForm-----------------------------
430N/Aclass PipeClassOperandForm : public Form {
430N/Aprivate:
430N/A
430N/Apublic:
430N/A // Public Data
430N/A const char *_stage; // Name of Stage
430N/A unsigned _iswrite; // Read or Write
430N/A unsigned _more_instrs; // Additional Instructions
430N/A
430N/A // Public Methods
430N/A PipeClassOperandForm(const char *stage, unsigned iswrite, unsigned more_instrs)
430N/A : _stage(stage)
430N/A , _iswrite(iswrite)
430N/A , _more_instrs(more_instrs)
430N/A {};
430N/A
430N/A ~PipeClassOperandForm() {}; // Destructor
430N/A
430N/A bool isWrite() const { return _iswrite != 0; }
430N/A
430N/A void dump(); // Debug printer
430N/A void output(FILE *fp); // Write info to output files
430N/A};
430N/A
430N/A//------------------------------PipeClassResourceForm--------------------------
430N/Aclass PipeClassResourceForm : public Form {
430N/Aprivate:
430N/A
430N/Apublic:
430N/A // Public Data
430N/A const char *_resource; // Resource
430N/A const char *_stage; // Stage the resource is used in
430N/A int _cycles; // Number of cycles the resource is used
430N/A
430N/A // Public Methods
430N/A PipeClassResourceForm(const char *resource, const char *stage, int cycles)
430N/A // Constructor
430N/A : _resource(resource)
430N/A , _stage(stage)
430N/A , _cycles(cycles)
430N/A {};
430N/A
430N/A ~PipeClassResourceForm() {}; // Destructor
430N/A
430N/A void dump(); // Debug printer
430N/A void output(FILE *fp); // Write info to output files
430N/A};
430N/A
430N/A//------------------------------PipeClassForm----------------------------------
430N/Aclass PipeClassForm : public Form {
430N/Aprivate:
430N/A
430N/Apublic:
430N/A
430N/A // Public Data
430N/A const char *_ident; // Name of class
430N/A int _num; // Used in name of MachNode subclass
430N/A NameList _parameters; // Locally defined names
430N/A FormDict _localNames; // Table of operands & their types
430N/A FormDict _localUsage; // Table of operand usage
430N/A FormList _resUsage; // List of resource usage
430N/A NameList _instructs; // List of instructions and machine nodes that use this pipeline class
430N/A bool _has_fixed_latency; // Always takes this number of cycles
430N/A int _fixed_latency; // Always takes this number of cycles
430N/A int _instruction_count; // Number of instructions in first bundle
430N/A bool _has_multiple_bundles; // Indicates if 1 or multiple bundles
430N/A bool _has_branch_delay_slot; // Has branch delay slot as last instruction
430N/A bool _force_serialization; // This node serializes relative to surrounding nodes
430N/A bool _may_have_no_code; // This node may generate no code based on register allocation
430N/A
430N/A // Virtual Methods
430N/A virtual PipeClassForm *is_pipeclass() const;
430N/A
430N/A // Public Methods
430N/A PipeClassForm(const char *id, int num);
430N/A // Constructor
430N/A ~PipeClassForm(); // Destructor
430N/A
430N/A bool hasFixedLatency() { return _has_fixed_latency; }
430N/A int fixedLatency() { return _fixed_latency; }
430N/A
430N/A void setFixedLatency(int fixed_latency) { _has_fixed_latency = 1; _fixed_latency = fixed_latency; }
430N/A
430N/A void setInstructionCount(int i) { _instruction_count = i; }
430N/A void setMultipleBundles(bool b) { _has_multiple_bundles = b; }
430N/A void setBranchDelay(bool s) { _has_branch_delay_slot = s; }
430N/A void setForceSerialization(bool s) { _force_serialization = s; }
430N/A void setMayHaveNoCode(bool s) { _may_have_no_code = s; }
430N/A
430N/A int InstructionCount() const { return _instruction_count; }
430N/A bool hasMultipleBundles() const { return _has_multiple_bundles; }
430N/A bool hasBranchDelay() const { return _has_branch_delay_slot; }
430N/A bool forceSerialization() const { return _force_serialization; }
430N/A bool mayHaveNoCode() const { return _may_have_no_code; }
430N/A
430N/A void dump(); // Debug printer
430N/A void output(FILE *fp); // Write info to output files
430N/A};
430N/A
430N/A
430N/A//==============================Peephole Optimization==========================
430N/A//------------------------------Peephole---------------------------------------
430N/Aclass Peephole : public Form {
430N/Aprivate:
430N/A static int _peephole_counter;// Incremented by each peephole rule parsed
430N/A int _peephole_number;// Remember my order in architecture description
430N/A PeepMatch *_match; // Instruction pattern to match
430N/A PeepConstraint *_constraint; // List of additional constraints
430N/A PeepReplace *_replace; // Instruction pattern to substitute in
430N/A
430N/A Peephole *_next;
430N/A
430N/Apublic:
430N/A // Public Methods
430N/A Peephole();
430N/A ~Peephole();
430N/A
430N/A // Append a peephole rule with the same root instruction
430N/A void append_peephole(Peephole *next_peephole);
430N/A
430N/A // Store the components of this peephole rule
430N/A void add_match(PeepMatch *only_one_match);
430N/A void append_constraint(PeepConstraint *next_constraint);
430N/A void add_replace(PeepReplace *only_one_replacement);
430N/A
430N/A // Access the components of this peephole rule
430N/A int peephole_number() { return _peephole_number; }
430N/A PeepMatch *match() { return _match; }
430N/A PeepConstraint *constraints() { return _constraint; }
430N/A PeepReplace *replacement() { return _replace; }
430N/A Peephole *next() { return _next; }
430N/A
430N/A void dump(); // Debug printer
430N/A void output(FILE *fp); // Write info to output files
430N/A};
430N/A
430N/A
430N/Aclass PeepMatch : public Form {
430N/Aprivate:
430N/A char *_rule;
430N/A // NameList _depth; // Depth of this instruction
430N/A NameList _parent;
430N/A NameList _position;
430N/A NameList _instrs; // List of instructions in match rule
430N/A NameList _input; // input position in parent's instruction
430N/A int _max_position;
430N/A
430N/Apublic:
430N/A // Public Methods
430N/A PeepMatch(char *rule);
430N/A ~PeepMatch();
430N/A
430N/A // Insert info into the match-rule
430N/A void add_instruction(int parent, int position, const char *name, int input);
430N/A
430N/A // Access info about instructions in the peep-match rule
430N/A int max_position();
430N/A const char *instruction_name(int position);
430N/A // Iterate through all info on matched instructions
430N/A void reset();
430N/A void next_instruction(int &parent, int &position, const char* &name, int &input);
430N/A // 'true' if current position in iteration is a placeholder, not matched.
430N/A bool is_placeholder();
430N/A
430N/A void dump();
430N/A void output(FILE *fp);
430N/A};
430N/A
430N/A
430N/Aclass PeepConstraint : public Form {
430N/Aprivate:
430N/A PeepConstraint *_next; // Additional constraints ANDed together
430N/A
430N/Apublic:
430N/A const int _left_inst;
430N/A const char* _left_op;
430N/A const char* _relation;
430N/A const int _right_inst;
430N/A const char* _right_op;
430N/A
430N/Apublic:
430N/A // Public Methods
430N/A PeepConstraint(int left_inst, char* left_op, char* relation,
430N/A int right_inst, char* right_op);
430N/A ~PeepConstraint();
430N/A
430N/A // Check if constraints use instruction at position
430N/A bool constrains_instruction(int position);
430N/A
430N/A // Add another constraint
430N/A void append(PeepConstraint *next_peep_constraint);
430N/A // Access the next constraint in the list
430N/A PeepConstraint *next();
430N/A
430N/A void dump();
430N/A void output(FILE *fp);
430N/A};
430N/A
430N/A
430N/Aclass PeepReplace : public Form {
430N/Aprivate:
430N/A char *_rule;
430N/A NameList _instruction;
430N/A NameList _operand_inst_num;
430N/A NameList _operand_op_name;
430N/A
430N/Apublic:
430N/A
430N/A // Public Methods
430N/A PeepReplace(char *rule);
430N/A ~PeepReplace();
430N/A
430N/A // Add contents of peepreplace
430N/A void add_instruction(char *root);
430N/A void add_operand( int inst_num, char *inst_operand );
430N/A
430N/A // Access contents of peepreplace
430N/A void reset();
430N/A void next_instruction(const char * &root);
430N/A void next_operand(int &inst_num, const char * &inst_operand );
430N/A
430N/A // Utilities
430N/A void dump();
430N/A void output(FILE *fp);
430N/A};
430N/A
430N/A
430N/Aclass PeepChild : public Form {
430N/Apublic:
430N/A const int _inst_num; // Number of instruction (-1 if only named)
430N/A const char *_inst_op; // Instruction's operand, NULL if number == -1
430N/A const char *_inst_name; // Name of the instruction
430N/A
430N/Apublic:
430N/A PeepChild(char *inst_name)
430N/A : _inst_num(-1), _inst_op(NULL), _inst_name(inst_name) {};
430N/A PeepChild(int inst_num, char *inst_op, char *inst_name)
430N/A : _inst_num(inst_num), _inst_op(inst_op), _inst_name(inst_name) {};
430N/A ~PeepChild();
430N/A
430N/A bool use_leaf_operand() { return _inst_num != -1; };
430N/A bool generate_an_instruction() { return _inst_num == -1; }
430N/A
void dump();
void output(FILE *fp);
};
#endif // SHARE_VM_ADLC_FORMSOPT_HPP