comparison src/share/vm/adlc/formsopt.hpp @ 23049:a1642365d69f

8075798: Allow ADLC register class to depend on runtime conditions also for cisc-spillable classes Summary: Introduce a new register class, reg_class_dynamic, that supports also cist-spillable masks. Reviewed-by: kvn, dlong, roland
author zmajo
date Fri, 27 Mar 2015 10:57:42 +0100
parents db2e64ca2d5a
children
comparison
equal deleted inserted replaced
23048:173f9910da57 23049:a1642365d69f
58 class CondInterface; 58 class CondInterface;
59 class Opcode; 59 class Opcode;
60 class InsEncode; 60 class InsEncode;
61 class RegDef; 61 class RegDef;
62 class RegClass; 62 class RegClass;
63 class CodeSnippetRegClass;
64 class ConditionalRegClass;
63 class AllocClass; 65 class AllocClass;
64 class ResourceForm; 66 class ResourceForm;
65 class PipeClassForm; 67 class PipeClassForm;
66 class PipeClassOperandForm; 68 class PipeClassOperandForm;
67 class PipeClassResourceForm; 69 class PipeClassResourceForm;
96 RegisterForm(); 98 RegisterForm();
97 ~RegisterForm(); 99 ~RegisterForm();
98 100
99 void addRegDef(char *regName, char *callingConv, char *c_conv, 101 void addRegDef(char *regName, char *callingConv, char *c_conv,
100 char * idealtype, char *encoding, char* concreteName); 102 char * idealtype, char *encoding, char* concreteName);
101 RegClass *addRegClass(const char *className); 103 template<typename T> T* addRegClass(const char* className);
104
102 AllocClass *addAllocClass(char *allocName); 105 AllocClass *addAllocClass(char *allocName);
103 void addSpillRegClass(); 106 void addSpillRegClass();
104 107
105 // Provide iteration over all register definitions 108 // Provide iteration over all register definitions
106 // in the order used by the register allocator 109 // in the order used by the register allocator
152 void dump(); // Debug printer 155 void dump(); // Debug printer
153 void output(FILE *fp); // Write info to output files 156 void output(FILE *fp); // Write info to output files
154 }; 157 };
155 158
156 //------------------------------RegClass--------------------------------------- 159 //------------------------------RegClass---------------------------------------
160 // Generic register class. This register class is the internal representation
161 // for the following .ad file format:
162 //
163 // reg_class ptr(RAX, RBX, ...);
164 //
165 // where ptr is the name of the register class, RAX and RBX are registers.
166 //
167 // This register class allows registers to be spilled onto the stack. Spilling
168 // is allowed is field _stack_or_reg is true.
157 class RegClass : public Form { 169 class RegClass : public Form {
158 public: 170 public:
159 // Public Data 171 // Public Data
160 const char *_classid; // Name of class 172 const char *_classid; // Name of class
161 NameList _regDefs; // List of registers in class 173 NameList _regDefs; // List of registers in class
162 Dict _regDef; // Dictionary of registers in class 174 Dict _regDef; // Dictionary of registers in class
175 protected:
163 bool _stack_or_reg; // Allowed on any stack slot 176 bool _stack_or_reg; // Allowed on any stack slot
164 char* _user_defined; 177
165 178 public:
166 // Public Methods 179 // Public Methods
167 RegClass(const char *classid);// Constructor 180 RegClass(const char *classid);// Constructor
181 virtual ~RegClass();
168 182
169 void addReg(RegDef *regDef); // Add a register to this class 183 void addReg(RegDef *regDef); // Add a register to this class
170 184
171 uint size() const; // Number of registers in class 185 uint size() const; // Number of registers in class
172 int regs_in_word( int wordnum, bool stack_also ); 186 int regs_in_word( int wordnum, bool stack_also );
181 RegDef *RegDef_iter(); // which move jointly, 195 RegDef *RegDef_iter(); // which move jointly,
182 const char *rd_name_iter(); // invoking either advances both. 196 const char *rd_name_iter(); // invoking either advances both.
183 197
184 void dump(); // Debug printer 198 void dump(); // Debug printer
185 void output(FILE *fp); // Write info to output files 199 void output(FILE *fp); // Write info to output files
200
201 virtual bool has_stack_version() {
202 return _stack_or_reg;
203 }
204 virtual void set_stack_version(bool flag) {
205 _stack_or_reg = flag;
206 }
207
208 virtual void declare_register_masks(FILE* fp);
209 virtual void build_register_masks(FILE* fp);
210 };
211
212 //------------------------------CodeSnippetRegClass----------------------------
213 // Register class that has an user-defined C++ code snippet attached to it
214 // to determine at runtime which register class to use. This register class is
215 // the internal representation for the following .ad file format:
216 //
217 // reg_class actual_dflt_reg %{
218 // if (VM_Version::has_vfp3_32()) {
219 // return DFLT_REG_mask();
220 // } else {
221 // return DFLT_LOW_REG_mask();
222 // }
223 // %}
224 //
225 // where DFLT_REG_mask() and DFLT_LOW_REG_mask() are the internal names of the
226 // masks of register classes dflt_reg and dflt_low_reg.
227 //
228 // The attached code snippet can select also between more than two register classes.
229 // This register class can be, however, used only if the register class is not
230 // cisc-spillable (i.e., the registers of this class are not allowed on the stack,
231 // which is equivalent with _stack_or_reg being false).
232 class CodeSnippetRegClass : public RegClass {
233 protected:
234 char* _code_snippet;
235 public:
236 CodeSnippetRegClass(const char* classid);// Constructor
237 ~CodeSnippetRegClass();
238
239 void set_code_snippet(char* code) {
240 _code_snippet = code;
241 }
242 char* code_snippet() {
243 return _code_snippet;
244 }
245 void set_stack_version(bool flag) {
246 assert(false, "User defined register classes are not allowed to spill to the stack.");
247 }
248 void declare_register_masks(FILE* fp);
249 void build_register_masks(FILE* fp) {
250 // We do not need to generate register masks because we select at runtime
251 // between register masks generated for other register classes.
252 return;
253 }
254 };
255
256 //------------------------------ConditionalRegClass----------------------------
257 // Register class that has two register classes and a runtime condition attached
258 // to it. The condition is evaluated at runtime and either one of the register
259 // attached register classes is selected. This register class is the internal
260 // representation for the following .ad format:
261 //
262 // reg_class_dynamic actual_dflt_reg(dflt_reg, low_reg,
263 // %{ VM_Version::has_vfp3_32() }%
264 // );
265 //
266 // This example is equivalent to the example used with the CodeSnippetRegClass
267 // register class. A ConditionalRegClass works also if a register class is cisc-spillable
268 // (i.e., _stack_or_reg is true), but if can select only between two register classes.
269 class ConditionalRegClass : public RegClass {
270 protected:
271 // reference to condition code
272 char* _condition_code; // C++ condition code to dynamically determine which register class to use.
273
274 // Example syntax (equivalent to previous example):
275 //
276 // reg_class actual_dflt_reg(dflt_reg, low_reg,
277 // %{ VM_Version::has_vfp3_32() }%
278 // );
279 // reference to conditional register classes
280 RegClass* _rclasses[2]; // 0 is the register class selected if the condition code returns true
281 // 1 is the register class selected if the condition code returns false
282 public:
283 ConditionalRegClass(const char* classid);// Constructor
284 ~ConditionalRegClass();
285
286 virtual void set_stack_version(bool flag) {
287 RegClass::set_stack_version(flag);
288 assert((_rclasses[0] != NULL), "Register class NULL for condition code == true");
289 assert((_rclasses[1] != NULL), "Register class NULL for condition code == false");
290 _rclasses[0]->set_stack_version(flag);
291 _rclasses[1]->set_stack_version(flag);
292 }
293 void declare_register_masks(FILE* fp);
294 void build_register_masks(FILE* fp) {
295 // We do not need to generate register masks because we select at runtime
296 // between register masks generated for other register classes.
297 return;
298 }
299 void set_rclass_at_index(int index, RegClass* rclass) {
300 assert((0 <= index && index < 2), "Condition code can select only between two register classes");
301 _rclasses[index] = rclass;
302 }
303 void set_condition_code(char* code) {
304 _condition_code = code;
305 }
306 char* condition_code() {
307 return _condition_code;
308 }
186 }; 309 };
187 310
188 //------------------------------AllocClass------------------------------------- 311 //------------------------------AllocClass-------------------------------------
189 class AllocClass : public Form { 312 class AllocClass : public Form {
190 private: 313 private: