Mercurial > hg > graal-jvmci-8
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: |