< prev index next >
src/share/vm/opto/superword.hpp
Print this page
rev 8471 : SIMD: fixing bug in alignment - invariant and scale. Also A LOT of tracing.
rev 8472 : SIMD: fixing bug in alignment - invariant and scale. Also A LOT of tracing + fixing long lines.
*** 201,210 ****
--- 201,211 ----
};
// -----------------------------SuperWord---------------------------------
// Transforms scalar operations into packed (superword) operations.
class SuperWord : public ResourceObj {
+ friend SWPointer;
private:
PhaseIdealLoop* _phase;
Arena* _arena;
PhaseIterGVN &_igvn;
*** 243,266 ****
// Accessors for SWPointer
PhaseIdealLoop* phase() { return _phase; }
IdealLoopTree* lpt() { return _lpt; }
PhiNode* iv() { return _iv; }
!
private:
IdealLoopTree* _lpt; // Current loop tree node
LoopNode* _lp; // Current LoopNode
Node* _bb; // Current basic block
PhiNode* _iv; // Induction var
bool _race_possible; // In cases where SDMU is true
bool _do_vector_loop; // whether to do vectorization/simd style
- bool _vector_loop_debug; // provide more printing in debug mode
int _num_work_vecs; // Number of non memory vector operations
int _num_reductions; // Number of reduction expressions applied
int _ii_first; // generation with direct deps from mem phi
int _ii_last; // generation with direct deps to mem phi
GrowableArray<int> _ii_order;
// Accessors
Arena* arena() { return _arena; }
Node* bb() { return _bb; }
--- 244,276 ----
// Accessors for SWPointer
PhaseIdealLoop* phase() { return _phase; }
IdealLoopTree* lpt() { return _lpt; }
PhiNode* iv() { return _iv; }
! #ifndef PRODUCT
! bool is_debug() { return _vector_loop_debug > 0; }
! bool is_trace_alignment() { return (_vector_loop_debug & 2) > 0; }
! bool is_trace_mem_slice() { return (_vector_loop_debug & 4) > 0; }
! bool is_trace_loop() { return (_vector_loop_debug & 8) > 0; }
! bool is_trace_adjacent() { return (_vector_loop_debug & 16) > 0; }
! #endif
! bool do_vector_loop() { return _do_vector_loop; }
private:
IdealLoopTree* _lpt; // Current loop tree node
LoopNode* _lp; // Current LoopNode
Node* _bb; // Current basic block
PhiNode* _iv; // Induction var
bool _race_possible; // In cases where SDMU is true
bool _do_vector_loop; // whether to do vectorization/simd style
int _num_work_vecs; // Number of non memory vector operations
int _num_reductions; // Number of reduction expressions applied
int _ii_first; // generation with direct deps from mem phi
int _ii_last; // generation with direct deps to mem phi
GrowableArray<int> _ii_order;
+ #ifndef PRODUCT
+ uintx _vector_loop_debug; // provide more printing in debug mode
+ #endif
// Accessors
Arena* arena() { return _arena; }
Node* bb() { return _bb; }
*** 319,328 ****
--- 329,342 ----
// my_pack
Node_List* my_pack(Node* n) { return !in_bb(n) ? NULL : _node_info.adr_at(bb_idx(n))->_my_pack; }
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; }
+ // CloneMap utilities
+ bool same_origin_idx(Node* a, Node* b) const;
+ bool same_generation(Node* a, Node* b) const;
+
// methods
// Extract the superword level parallelism
void SLP_extract();
// Find the adjacent memory references and create pack pairs for them.
*** 334,350 ****
// Can the preloop align the reference to position zero in the vector?
bool ref_is_alignable(SWPointer& p);
// rebuild the graph so all loads in different iterations of cloned loop become dependant on phi node (in _do_vector_loop only)
bool hoist_loads_in_graph();
// Test whether MemNode::Memory dependency to the same load but in the first iteration of this loop is coming from memory phi
! // Return false if failed.
Node* find_phi_for_mem_dep(LoadNode* ld);
// Return same node but from the first generation. Return 0, if not found
Node* first_node(Node* nd);
// Return same node as this but from the last generation. Return 0, if not found
Node* last_node(Node* n);
! // Mark nodes belonging to first and last generation,
// returns first generation index or -1 if vectorization/simd is impossible
int mark_generations();
// swapping inputs of commutative instruction (Add or Mul)
bool fix_commutative_inputs(Node* gold, Node* fix);
// make packs forcefully (in _do_vector_loop only)
--- 348,364 ----
// Can the preloop align the reference to position zero in the vector?
bool ref_is_alignable(SWPointer& p);
// rebuild the graph so all loads in different iterations of cloned loop become dependant on phi node (in _do_vector_loop only)
bool hoist_loads_in_graph();
// Test whether MemNode::Memory dependency to the same load but in the first iteration of this loop is coming from memory phi
! // Return false if failed
Node* find_phi_for_mem_dep(LoadNode* ld);
// Return same node but from the first generation. Return 0, if not found
Node* first_node(Node* nd);
// Return same node as this but from the last generation. Return 0, if not found
Node* last_node(Node* n);
! // Mark nodes belonging to first and last generation
// returns first generation index or -1 if vectorization/simd is impossible
int mark_generations();
// swapping inputs of commutative instruction (Add or Mul)
bool fix_commutative_inputs(Node* gold, Node* fix);
// make packs forcefully (in _do_vector_loop only)
*** 469,487 ****
Node* _adr; // address pointer
jint _scale; // multiplier for iv (in bytes), 0 if no loop iv
jint _offset; // constant offset (in bytes)
Node* _invar; // invariant offset (in bytes), NULL if none
bool _negate_invar; // if true then use: (0 - _invar)
!
PhaseIdealLoop* phase() { return _slp->phase(); }
IdealLoopTree* lpt() { return _slp->lpt(); }
PhiNode* iv() { return _slp->iv(); } // Induction var
! bool invariant(Node* n) {
! Node *n_c = phase()->get_ctrl(n);
! return !lpt()->is_member(phase()->get_loop(n_c));
! }
// Match: k*iv + offset
bool scaled_iv_plus_offset(Node* n);
// Match: k*iv where k is a constant that's not zero
bool scaled_iv(Node* n);
--- 483,500 ----
Node* _adr; // address pointer
jint _scale; // multiplier for iv (in bytes), 0 if no loop iv
jint _offset; // constant offset (in bytes)
Node* _invar; // invariant offset (in bytes), NULL if none
bool _negate_invar; // if true then use: (0 - _invar)
! #ifndef PRODUCT
! static int _depth; // depth of the current syntax clause in the syntax expression (for debug only)
! #endif
PhaseIdealLoop* phase() { return _slp->phase(); }
IdealLoopTree* lpt() { return _slp->lpt(); }
PhiNode* iv() { return _slp->iv(); } // Induction var
! bool invariant(Node* n);
// Match: k*iv + offset
bool scaled_iv_plus_offset(Node* n);
// Match: k*iv where k is a constant that's not zero
bool scaled_iv(Node* n);
*** 535,544 ****
--- 548,572 ----
static bool not_equal(int cmp) { return cmp <= NotEqual; }
static bool equal(int cmp) { return cmp == Equal; }
static bool comparable(int cmp) { return cmp < NotComparable; }
void print();
+ #ifndef PRODUCT
+ void print_depth();
+ int depth() { return _depth; }
+ void set_depth(int d) { _depth = d; }
+ void inc_depth() { _depth++;}
+ void dec_depth() { if (_depth > 0) _depth--;}
+ #endif
+
+ class Depth {
+ friend SWPointer;
+ #ifndef PRODUCT
+ Depth() { ++_depth; }
+ ~Depth() { if (_depth > 0) _depth--;}
+ #endif
+ };
};
//------------------------------OrderedPair---------------------------
// Ordered pair of Node*.
< prev index next >