1 /* |
1 /* |
2 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
262 LoopNode* lp() { return _lp; } |
262 LoopNode* lp() { return _lp; } |
263 void set_lp(LoopNode* lp) { _lp = lp; |
263 void set_lp(LoopNode* lp) { _lp = lp; |
264 _iv = lp->as_CountedLoop()->phi()->as_Phi(); } |
264 _iv = lp->as_CountedLoop()->phi()->as_Phi(); } |
265 int iv_stride() { return lp()->as_CountedLoop()->stride_con(); } |
265 int iv_stride() { return lp()->as_CountedLoop()->stride_con(); } |
266 |
266 |
267 int vector_width_in_bytes() { return Matcher::vector_width_in_bytes(); } |
267 int vector_width_in_bytes(BasicType bt) { |
|
268 return MIN2(ABS(iv_stride())*type2aelembytes(bt), |
|
269 Matcher::vector_width_in_bytes(bt)); |
|
270 } |
268 |
271 |
269 MemNode* align_to_ref() { return _align_to_ref; } |
272 MemNode* align_to_ref() { return _align_to_ref; } |
270 void set_align_to_ref(MemNode* m) { _align_to_ref = m; } |
273 void set_align_to_ref(MemNode* m) { _align_to_ref = m; } |
271 |
274 |
272 Node* ctrl(Node* n) const { return _phase->has_ctrl(n) ? _phase->get_ctrl(n) : n; } |
275 Node* ctrl(Node* n) const { return _phase->has_ctrl(n) ? _phase->get_ctrl(n) : n; } |
296 int depth(Node* n) { return _node_info.adr_at(bb_idx(n))->_depth; } |
299 int depth(Node* n) { return _node_info.adr_at(bb_idx(n))->_depth; } |
297 void set_depth(Node* n, int d) { int i = bb_idx(n); grow_node_info(i); _node_info.adr_at(i)->_depth = d; } |
300 void set_depth(Node* n, int d) { int i = bb_idx(n); grow_node_info(i); _node_info.adr_at(i)->_depth = d; } |
298 |
301 |
299 // vector element type |
302 // vector element type |
300 const Type* velt_type(Node* n) { return _node_info.adr_at(bb_idx(n))->_velt_type; } |
303 const Type* velt_type(Node* n) { return _node_info.adr_at(bb_idx(n))->_velt_type; } |
|
304 BasicType velt_basic_type(Node* n) { return velt_type(n)->array_element_basic_type(); } |
301 void set_velt_type(Node* n, const Type* t) { int i = bb_idx(n); grow_node_info(i); _node_info.adr_at(i)->_velt_type = t; } |
305 void set_velt_type(Node* n, const Type* t) { int i = bb_idx(n); grow_node_info(i); _node_info.adr_at(i)->_velt_type = t; } |
|
306 bool same_velt_type(Node* n1, Node* n2); |
302 |
307 |
303 // my_pack |
308 // my_pack |
304 Node_List* my_pack(Node* n) { return !in_bb(n) ? NULL : _node_info.adr_at(bb_idx(n))->_my_pack; } |
309 Node_List* my_pack(Node* n) { return !in_bb(n) ? NULL : _node_info.adr_at(bb_idx(n))->_my_pack; } |
305 void set_my_pack(Node* n, Node_List* p) { int i = bb_idx(n); grow_node_info(i); _node_info.adr_at(i)->_my_pack = p; } |
310 void set_my_pack(Node* n, Node_List* p) { int i = bb_idx(n); grow_node_info(i); _node_info.adr_at(i)->_my_pack = p; } |
306 |
311 |
309 // Extract the superword level parallelism |
314 // Extract the superword level parallelism |
310 void SLP_extract(); |
315 void SLP_extract(); |
311 // Find the adjacent memory references and create pack pairs for them. |
316 // Find the adjacent memory references and create pack pairs for them. |
312 void find_adjacent_refs(); |
317 void find_adjacent_refs(); |
313 // Find a memory reference to align the loop induction variable to. |
318 // Find a memory reference to align the loop induction variable to. |
314 void find_align_to_ref(Node_List &memops); |
319 MemNode* find_align_to_ref(Node_List &memops); |
|
320 // Calculate loop's iv adjustment for this memory ops. |
|
321 int get_iv_adjustment(MemNode* mem); |
315 // Can the preloop align the reference to position zero in the vector? |
322 // Can the preloop align the reference to position zero in the vector? |
316 bool ref_is_alignable(SWPointer& p); |
323 bool ref_is_alignable(SWPointer& p); |
317 // Construct dependency graph. |
324 // Construct dependency graph. |
318 void dependence_graph(); |
325 void dependence_graph(); |
319 // Return a memory slice (node list) in predecessor order starting at "start" |
326 // Return a memory slice (node list) in predecessor order starting at "start" |
392 // Alignment within a vector memory reference |
399 // Alignment within a vector memory reference |
393 int memory_alignment(MemNode* s, int iv_adjust_in_bytes); |
400 int memory_alignment(MemNode* s, int iv_adjust_in_bytes); |
394 // (Start, end] half-open range defining which operands are vector |
401 // (Start, end] half-open range defining which operands are vector |
395 void vector_opd_range(Node* n, uint* start, uint* end); |
402 void vector_opd_range(Node* n, uint* start, uint* end); |
396 // Smallest type containing range of values |
403 // Smallest type containing range of values |
397 static const Type* container_type(const Type* t); |
404 const Type* container_type(Node* n); |
398 // Adjust pre-loop limit so that in main loop, a load/store reference |
405 // Adjust pre-loop limit so that in main loop, a load/store reference |
399 // to align_to_ref will be a position zero in the vector. |
406 // to align_to_ref will be a position zero in the vector. |
400 void align_initial_loop_index(MemNode* align_to_ref); |
407 void align_initial_loop_index(MemNode* align_to_ref); |
401 // Find pre loop end from main loop. Returns null if none. |
408 // Find pre loop end from main loop. Returns null if none. |
402 CountedLoopEndNode* get_pre_loop_end(CountedLoopNode *cl); |
409 CountedLoopEndNode* get_pre_loop_end(CountedLoopNode *cl); |
460 bool valid() { return _adr != NULL; } |
467 bool valid() { return _adr != NULL; } |
461 bool has_iv() { return _scale != 0; } |
468 bool has_iv() { return _scale != 0; } |
462 |
469 |
463 Node* base() { return _base; } |
470 Node* base() { return _base; } |
464 Node* adr() { return _adr; } |
471 Node* adr() { return _adr; } |
|
472 MemNode* mem() { return _mem; } |
465 int scale_in_bytes() { return _scale; } |
473 int scale_in_bytes() { return _scale; } |
466 Node* invar() { return _invar; } |
474 Node* invar() { return _invar; } |
467 bool negate_invar() { return _negate_invar; } |
475 bool negate_invar() { return _negate_invar; } |
468 int offset_in_bytes() { return _offset; } |
476 int offset_in_bytes() { return _offset; } |
469 int memory_size() { return _mem->memory_size(); } |
477 int memory_size() { return _mem->memory_size(); } |