Mercurial > hg > graal-compiler
view src/share/vm/adlc/formsopt.hpp @ 1091:6aa7255741f3
6906727: UseCompressedOops: some card-marking fixes related to object arrays
Summary: Introduced a new write_ref_array(HeapWords* start, size_t count) method that does the requisite MemRegion range calculation so (some of the) clients of the erstwhile write_ref_array(MemRegion mr) do not need to worry. This removed all external uses of array_size(), which was also simplified and made private. Asserts were added to catch other possible issues. Further, less essential, fixes stemming from this investigation are deferred to CR 6904516 (to follow shortly in hs17).
Reviewed-by: kvn, coleenp, jmasa
author | ysr |
---|---|
date | Thu, 03 Dec 2009 15:01:57 -0800 |
parents | dbbe28fc66b5 |
children | c18cbe5936b8 |
line wrap: on
line source
/* * Copyright 1998-2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. * */ // FORMSOPT.HPP - ADL Parser Target Specific Optimization Forms Classes // Class List class Form; class InstructForm; 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 PeepMatch; class PeepConstraint; class EncClass; class Interface; class RegInterface; class ConstInterface; class MemInterface; class CondInterface; class Opcode; class InsEncode; class RegDef; class RegClass; class AllocClass; class ResourceForm; class PipeClassForm; class PipeClassOperandForm; class PipeClassResourceForm; class PeepMatch; class PeepConstraint; class PeepReplace; class MatchList; class ArchDesc; //==============================Register Allocation============================ //------------------------------RegisterForm----------------------------------- class RegisterForm : public Form { private: AllocClass *_current_ac; // State used by iter_RegDefs() public: // Public Data NameList _rdefs; // List of register definition names Dict _regDef; // map register name to RegDef* NameList _rclasses; // List of register class names Dict _regClass; // map register class name to RegClass* NameList _aclasses; // List of allocation class names Dict _allocClass; // Dictionary of allocation classes static int _reg_ctr; // Register counter static int RegMask_Size(); // Compute RegMask size // Public Methods RegisterForm(); ~RegisterForm(); void addRegDef(char *regName, char *callingConv, char *c_conv, char * idealtype, char *encoding, char* concreteName); RegClass *addRegClass(const char *className); AllocClass *addAllocClass(char *allocName); void addSpillRegClass(); // Provide iteration over all register definitions // in the order used by the register allocator void reset_RegDefs(); RegDef *iter_RegDefs(); RegDef *getRegDef (const char *regName); RegClass *getRegClass(const char *className); // Return register mask, compressed chunk and register # uint reg_mask(char *register_class); // Check that register classes are compatible with chunks bool verify(); void dump(); // Debug printer void output(FILE *fp); // Write info to output files }; //------------------------------RegDef----------------------------------------- class RegDef : public Form { public: // Public Data const char *_regname; // ADLC (Opto) Register name const char *_callconv; // Calling convention const char *_c_conv; // Native calling convention, 'C' const char *_idealtype; // Ideal Type for register save/restore const char *_concrete; // concrete register name private: const char *_register_encode; // The register encoding // The chunk and register mask bits define info for register allocation uint32 _register_num; // Which register am I public: // Public Methods RegDef(char *regname, char *callconv, char *c_conv, char *idealtype, char *encoding, char *concrete); ~RegDef(); // Destructor // Interface to define/redefine the register number void set_register_num(uint32 new_register_num); // Bit pattern used for generating machine code const char *register_encode() const; // Register number used in machine-independent code uint32 register_num() const; void dump(); // Debug printer void output(FILE *fp); // Write info to output files }; //------------------------------RegClass--------------------------------------- class RegClass : public Form { public: // Public Data const char *_classid; // Name of class NameList _regDefs; // List of registers in class Dict _regDef; // Dictionary of registers in class bool _stack_or_reg; // Allowed on any stack slot // Public Methods RegClass(const char *classid);// Constructor void addReg(RegDef *regDef); // Add a register to this class uint size() const; // Number of registers in class int regs_in_word( int wordnum, bool stack_also ); const RegDef *get_RegDef(const char *regDef_name) const; // Returns the lowest numbered register in the mask. const RegDef* find_first_elem(); // Iteration support void reset(); // Reset the following two iterators RegDef *RegDef_iter(); // which move jointly, const char *rd_name_iter(); // invoking either advances both. void dump(); // Debug printer void output(FILE *fp); // Write info to output files }; //------------------------------AllocClass------------------------------------- class AllocClass : public Form { private: public: // Public Data char *_classid; // Name of class NameList _regDefs; // List of registers in class Dict _regDef; // Dictionary of registers in class // Public Methods AllocClass(char *classid); // Constructor void addReg(RegDef *regDef); // Add a register to this class uint size() {return _regDef.Size();} // Number of registers in class void dump(); // Debug printer void output(FILE *fp); // Write info to output files }; //==============================Frame Handling================================ //------------------------------FrameForm------------------------------------- class FrameForm : public Form { private: public: // Public Data bool _direction; // Direction of stack growth char *_sync_stack_slots; char *_inline_cache_reg; char *_interpreter_method_oop_reg; char *_interpreter_frame_pointer_reg; char *_cisc_spilling_operand_name; char *_frame_pointer; char *_c_frame_pointer; char *_alignment; bool _return_addr_loc; bool _c_return_addr_loc; char *_return_addr; char *_c_return_addr; char *_in_preserve_slots; char *_varargs_C_out_slots_killed; char *_calling_convention; char *_c_calling_convention; char *_return_value; char *_c_return_value; // Public Methods FrameForm(); ~FrameForm(); void dump(); // Debug printer void output(FILE *fp); // Write info to output files }; //==============================Scheduling===================================== //------------------------------PipelineForm----------------------------------- class PipelineForm : public Form { private: public: // Public Data NameList _reslist; // List of pipeline resources FormDict _resdict; // Resource Name -> ResourceForm mapping int _rescount; // Number of resources (ignores OR cases) int _maxcycleused; // Largest cycle used relative to beginning of instruction NameList _stages; // List of pipeline stages on architecture int _stagecnt; // Number of stages listed NameList _classlist; // List of pipeline classes FormDict _classdict; // Class Name -> PipeClassForm mapping int _classcnt; // Number of classes NameList _noplist; // List of NOP instructions int _nopcnt; // Number of nop instructions bool _variableSizeInstrs; // Indicates if this architecture has variable sized instructions bool _branchHasDelaySlot; // Indicates that branches have delay slot instructions int _maxInstrsPerBundle; // Indicates the maximum number of instructions for ILP int _maxBundlesPerCycle; // Indicates the maximum number of bundles for ILP int _instrUnitSize; // The minimum instruction unit size, in bytes int _bundleUnitSize; // The bundle unit size, in bytes int _instrFetchUnitSize; // The size of the I-fetch unit, in bytes [must be power of 2] int _instrFetchUnits; // The number of I-fetch units processed per cycle // Public Methods PipelineForm(); ~PipelineForm(); void dump(); // Debug printer void output(FILE *fp); // Write info to output files }; //------------------------------ResourceForm----------------------------------- class ResourceForm : public Form { public: unsigned mask() const { return _resmask; }; private: // Public Data unsigned _resmask; // Resource Mask (OR of resource specifier bits) public: // Virtual Methods virtual ResourceForm *is_resource() const; // Public Methods ResourceForm(unsigned resmask); // Constructor ~ResourceForm(); // Destructor void dump(); // Debug printer void output(FILE *fp); // Write info to output files }; //------------------------------PipeClassOperandForm----------------------------- class PipeClassOperandForm : public Form { private: public: // Public Data const char *_stage; // Name of Stage unsigned _iswrite; // Read or Write unsigned _more_instrs; // Additional Instructions // Public Methods PipeClassOperandForm(const char *stage, unsigned iswrite, unsigned more_instrs) : _stage(stage) , _iswrite(iswrite) , _more_instrs(more_instrs) {}; ~PipeClassOperandForm() {}; // Destructor bool isWrite() const { return _iswrite != 0; } void dump(); // Debug printer void output(FILE *fp); // Write info to output files }; //------------------------------PipeClassResourceForm-------------------------- class PipeClassResourceForm : public Form { private: public: // Public Data const char *_resource; // Resource const char *_stage; // Stage the resource is used in int _cycles; // Number of cycles the resource is used // Public Methods PipeClassResourceForm(const char *resource, const char *stage, int cycles) // Constructor : _resource(resource) , _stage(stage) , _cycles(cycles) {}; ~PipeClassResourceForm() {}; // Destructor void dump(); // Debug printer void output(FILE *fp); // Write info to output files }; //------------------------------PipeClassForm---------------------------------- class PipeClassForm : public Form { private: public: // Public Data const char *_ident; // Name of class int _num; // Used in name of MachNode subclass NameList _parameters; // Locally defined names FormDict _localNames; // Table of operands & their types FormDict _localUsage; // Table of operand usage FormList _resUsage; // List of resource usage NameList _instructs; // List of instructions and machine nodes that use this pipeline class bool _has_fixed_latency; // Always takes this number of cycles int _fixed_latency; // Always takes this number of cycles int _instruction_count; // Number of instructions in first bundle bool _has_multiple_bundles; // Indicates if 1 or multiple bundles bool _has_branch_delay_slot; // Has branch delay slot as last instruction bool _force_serialization; // This node serializes relative to surrounding nodes bool _may_have_no_code; // This node may generate no code based on register allocation // Virtual Methods virtual PipeClassForm *is_pipeclass() const; // Public Methods PipeClassForm(const char *id, int num); // Constructor ~PipeClassForm(); // Destructor bool hasFixedLatency() { return _has_fixed_latency; } int fixedLatency() { return _fixed_latency; } void setFixedLatency(int fixed_latency) { _has_fixed_latency = 1; _fixed_latency = fixed_latency; } void setInstructionCount(int i) { _instruction_count = i; } void setMultipleBundles(bool b) { _has_multiple_bundles = b; } void setBranchDelay(bool s) { _has_branch_delay_slot = s; } void setForceSerialization(bool s) { _force_serialization = s; } void setMayHaveNoCode(bool s) { _may_have_no_code = s; } int InstructionCount() const { return _instruction_count; } bool hasMultipleBundles() const { return _has_multiple_bundles; } bool hasBranchDelay() const { return _has_branch_delay_slot; } bool forceSerialization() const { return _force_serialization; } bool mayHaveNoCode() const { return _may_have_no_code; } void dump(); // Debug printer void output(FILE *fp); // Write info to output files }; //==============================Peephole Optimization========================== //------------------------------Peephole--------------------------------------- class Peephole : public Form { private: static int _peephole_counter;// Incremented by each peephole rule parsed int _peephole_number;// Remember my order in architecture description PeepMatch *_match; // Instruction pattern to match PeepConstraint *_constraint; // List of additional constraints PeepReplace *_replace; // Instruction pattern to substitute in Peephole *_next; public: // Public Methods Peephole(); ~Peephole(); // Append a peephole rule with the same root instruction void append_peephole(Peephole *next_peephole); // Store the components of this peephole rule void add_match(PeepMatch *only_one_match); void append_constraint(PeepConstraint *next_constraint); void add_replace(PeepReplace *only_one_replacement); // Access the components of this peephole rule int peephole_number() { return _peephole_number; } PeepMatch *match() { return _match; } PeepConstraint *constraints() { return _constraint; } PeepReplace *replacement() { return _replace; } Peephole *next() { return _next; } void dump(); // Debug printer void output(FILE *fp); // Write info to output files }; class PeepMatch : public Form { private: char *_rule; // NameList _depth; // Depth of this instruction NameList _parent; NameList _position; NameList _instrs; // List of instructions in match rule NameList _input; // input position in parent's instruction int _max_position; public: // Public Methods PeepMatch(char *rule); ~PeepMatch(); // Insert info into the match-rule void add_instruction(int parent, int position, const char *name, int input); // Access info about instructions in the peep-match rule int max_position(); const char *instruction_name(int position); // Iterate through all info on matched instructions void reset(); void next_instruction(int &parent, int &position, const char* &name, int &input); // 'true' if current position in iteration is a placeholder, not matched. bool is_placeholder(); void dump(); void output(FILE *fp); }; class PeepConstraint : public Form { private: PeepConstraint *_next; // Additional constraints ANDed together public: const int _left_inst; const char* _left_op; const char* _relation; const int _right_inst; const char* _right_op; public: // Public Methods PeepConstraint(int left_inst, char* left_op, char* relation, int right_inst, char* right_op); ~PeepConstraint(); // Check if constraints use instruction at position bool constrains_instruction(int position); // Add another constraint void append(PeepConstraint *next_peep_constraint); // Access the next constraint in the list PeepConstraint *next(); void dump(); void output(FILE *fp); }; class PeepReplace : public Form { private: char *_rule; NameList _instruction; NameList _operand_inst_num; NameList _operand_op_name; public: // Public Methods PeepReplace(char *rule); ~PeepReplace(); // Add contents of peepreplace void add_instruction(char *root); void add_operand( int inst_num, char *inst_operand ); // Access contents of peepreplace void reset(); void next_instruction(const char * &root); void next_operand(int &inst_num, const char * &inst_operand ); // Utilities void dump(); void output(FILE *fp); }; class PeepChild : public Form { public: const int _inst_num; // Number of instruction (-1 if only named) const char *_inst_op; // Instruction's operand, NULL if number == -1 const char *_inst_name; // Name of the instruction public: PeepChild(char *inst_name) : _inst_num(-1), _inst_op(NULL), _inst_name(inst_name) {}; PeepChild(int inst_num, char *inst_op, char *inst_name) : _inst_num(inst_num), _inst_op(inst_op), _inst_name(inst_name) {}; ~PeepChild(); bool use_leaf_operand() { return _inst_num != -1; }; bool generate_an_instruction() { return _inst_num == -1; } void dump(); void output(FILE *fp); };