annotate src/share/vm/opto/superword.cpp @ 1994:6cd6d394f280

7001033: assert(gch->gc_cause() == GCCause::_scavenge_alot || !gch->incremental_collection_failed()) 7002546: regression on SpecJbb2005 on 7b118 comparing to 7b117 on small heaps Summary: Relaxed assertion checking related to incremental_collection_failed flag to allow for ExplicitGCInvokesConcurrent behaviour where we do not want a failing scavenge to bail to a stop-world collection. Parameterized incremental_collection_will_fail() so we can selectively use, or not use, as appropriate, the statistical prediction at specific use sites. This essentially reverts the scavenge bail-out logic to what it was prior to some recent changes that had inadvertently started using the statistical prediction which can be noisy in the presence of bursty loads. Added some associated verbose non-product debugging messages. Reviewed-by: johnc, tonyp
author ysr
date Tue, 07 Dec 2010 21:55:53 -0800
parents f95d63e2154a
children 08eb13460b3a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
1585
49fac4acd688 6958485: fix for 6879921 was insufficient
never
parents: 1552
diff changeset
2 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1058
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1058
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1058
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 */
a61af66fc99e Initial load
duke
parents:
diff changeset
23
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1621
diff changeset
24 #include "precompiled.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1621
diff changeset
25 #include "compiler/compileLog.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1621
diff changeset
26 #include "libadt/vectset.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1621
diff changeset
27 #include "memory/allocation.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1621
diff changeset
28 #include "opto/addnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1621
diff changeset
29 #include "opto/callnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1621
diff changeset
30 #include "opto/divnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1621
diff changeset
31 #include "opto/matcher.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1621
diff changeset
32 #include "opto/memnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1621
diff changeset
33 #include "opto/mulnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1621
diff changeset
34 #include "opto/opcodes.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1621
diff changeset
35 #include "opto/superword.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1621
diff changeset
36 #include "opto/vectornode.hpp"
0
a61af66fc99e Initial load
duke
parents:
diff changeset
37
a61af66fc99e Initial load
duke
parents:
diff changeset
38 //
a61af66fc99e Initial load
duke
parents:
diff changeset
39 // S U P E R W O R D T R A N S F O R M
a61af66fc99e Initial load
duke
parents:
diff changeset
40 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
41
a61af66fc99e Initial load
duke
parents:
diff changeset
42 //------------------------------SuperWord---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
43 SuperWord::SuperWord(PhaseIdealLoop* phase) :
a61af66fc99e Initial load
duke
parents:
diff changeset
44 _phase(phase),
a61af66fc99e Initial load
duke
parents:
diff changeset
45 _igvn(phase->_igvn),
a61af66fc99e Initial load
duke
parents:
diff changeset
46 _arena(phase->C->comp_arena()),
a61af66fc99e Initial load
duke
parents:
diff changeset
47 _packset(arena(), 8, 0, NULL), // packs for the current block
a61af66fc99e Initial load
duke
parents:
diff changeset
48 _bb_idx(arena(), (int)(1.10 * phase->C->unique()), 0, 0), // node idx to index in bb
a61af66fc99e Initial load
duke
parents:
diff changeset
49 _block(arena(), 8, 0, NULL), // nodes in current block
a61af66fc99e Initial load
duke
parents:
diff changeset
50 _data_entry(arena(), 8, 0, NULL), // nodes with all inputs from outside
a61af66fc99e Initial load
duke
parents:
diff changeset
51 _mem_slice_head(arena(), 8, 0, NULL), // memory slice heads
a61af66fc99e Initial load
duke
parents:
diff changeset
52 _mem_slice_tail(arena(), 8, 0, NULL), // memory slice tails
a61af66fc99e Initial load
duke
parents:
diff changeset
53 _node_info(arena(), 8, 0, SWNodeInfo::initial), // info needed per node
a61af66fc99e Initial load
duke
parents:
diff changeset
54 _align_to_ref(NULL), // memory reference to align vectors to
a61af66fc99e Initial load
duke
parents:
diff changeset
55 _disjoint_ptrs(arena(), 8, 0, OrderedPair::initial), // runtime disambiguated pointer pairs
a61af66fc99e Initial load
duke
parents:
diff changeset
56 _dg(_arena), // dependence graph
a61af66fc99e Initial load
duke
parents:
diff changeset
57 _visited(arena()), // visited node set
a61af66fc99e Initial load
duke
parents:
diff changeset
58 _post_visited(arena()), // post visited node set
a61af66fc99e Initial load
duke
parents:
diff changeset
59 _n_idx_list(arena(), 8), // scratch list of (node,index) pairs
a61af66fc99e Initial load
duke
parents:
diff changeset
60 _stk(arena(), 8, 0, NULL), // scratch stack of nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
61 _nlist(arena(), 8, 0, NULL), // scratch list of nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
62 _lpt(NULL), // loop tree node
a61af66fc99e Initial load
duke
parents:
diff changeset
63 _lp(NULL), // LoopNode
a61af66fc99e Initial load
duke
parents:
diff changeset
64 _bb(NULL), // basic block
a61af66fc99e Initial load
duke
parents:
diff changeset
65 _iv(NULL) // induction var
a61af66fc99e Initial load
duke
parents:
diff changeset
66 {}
a61af66fc99e Initial load
duke
parents:
diff changeset
67
a61af66fc99e Initial load
duke
parents:
diff changeset
68 //------------------------------transform_loop---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
69 void SuperWord::transform_loop(IdealLoopTree* lpt) {
a61af66fc99e Initial load
duke
parents:
diff changeset
70 assert(lpt->_head->is_CountedLoop(), "must be");
a61af66fc99e Initial load
duke
parents:
diff changeset
71 CountedLoopNode *cl = lpt->_head->as_CountedLoop();
a61af66fc99e Initial load
duke
parents:
diff changeset
72
a61af66fc99e Initial load
duke
parents:
diff changeset
73 if (!cl->is_main_loop() ) return; // skip normal, pre, and post loops
a61af66fc99e Initial load
duke
parents:
diff changeset
74
a61af66fc99e Initial load
duke
parents:
diff changeset
75 // Check for no control flow in body (other than exit)
a61af66fc99e Initial load
duke
parents:
diff changeset
76 Node *cl_exit = cl->loopexit();
a61af66fc99e Initial load
duke
parents:
diff changeset
77 if (cl_exit->in(0) != lpt->_head) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
78
105
a7d0f95410bd 6646020: assert(in_bb(n),"must be in block") in -Xcomp mode
never
parents: 72
diff changeset
79 // Make sure the are no extra control users of the loop backedge
a7d0f95410bd 6646020: assert(in_bb(n),"must be in block") in -Xcomp mode
never
parents: 72
diff changeset
80 if (cl->back_control()->outcnt() != 1) {
a7d0f95410bd 6646020: assert(in_bb(n),"must be in block") in -Xcomp mode
never
parents: 72
diff changeset
81 return;
a7d0f95410bd 6646020: assert(in_bb(n),"must be in block") in -Xcomp mode
never
parents: 72
diff changeset
82 }
a7d0f95410bd 6646020: assert(in_bb(n),"must be in block") in -Xcomp mode
never
parents: 72
diff changeset
83
0
a61af66fc99e Initial load
duke
parents:
diff changeset
84 // Check for pre-loop ending with CountedLoopEnd(Bool(Cmp(x,Opaque1(limit))))
a61af66fc99e Initial load
duke
parents:
diff changeset
85 CountedLoopEndNode* pre_end = get_pre_loop_end(cl);
a61af66fc99e Initial load
duke
parents:
diff changeset
86 if (pre_end == NULL) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
87 Node *pre_opaq1 = pre_end->limit();
a61af66fc99e Initial load
duke
parents:
diff changeset
88 if (pre_opaq1->Opcode() != Op_Opaque1) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
89
a61af66fc99e Initial load
duke
parents:
diff changeset
90 // Do vectors exist on this architecture?
a61af66fc99e Initial load
duke
parents:
diff changeset
91 if (vector_width_in_bytes() == 0) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
92
a61af66fc99e Initial load
duke
parents:
diff changeset
93 init(); // initialize data structures
a61af66fc99e Initial load
duke
parents:
diff changeset
94
a61af66fc99e Initial load
duke
parents:
diff changeset
95 set_lpt(lpt);
a61af66fc99e Initial load
duke
parents:
diff changeset
96 set_lp(cl);
a61af66fc99e Initial load
duke
parents:
diff changeset
97
a61af66fc99e Initial load
duke
parents:
diff changeset
98 // For now, define one block which is the entire loop body
a61af66fc99e Initial load
duke
parents:
diff changeset
99 set_bb(cl);
a61af66fc99e Initial load
duke
parents:
diff changeset
100
a61af66fc99e Initial load
duke
parents:
diff changeset
101 assert(_packset.length() == 0, "packset must be empty");
a61af66fc99e Initial load
duke
parents:
diff changeset
102 SLP_extract();
a61af66fc99e Initial load
duke
parents:
diff changeset
103 }
a61af66fc99e Initial load
duke
parents:
diff changeset
104
a61af66fc99e Initial load
duke
parents:
diff changeset
105 //------------------------------SLP_extract---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
106 // Extract the superword level parallelism
a61af66fc99e Initial load
duke
parents:
diff changeset
107 //
a61af66fc99e Initial load
duke
parents:
diff changeset
108 // 1) A reverse post-order of nodes in the block is constructed. By scanning
a61af66fc99e Initial load
duke
parents:
diff changeset
109 // this list from first to last, all definitions are visited before their uses.
a61af66fc99e Initial load
duke
parents:
diff changeset
110 //
a61af66fc99e Initial load
duke
parents:
diff changeset
111 // 2) A point-to-point dependence graph is constructed between memory references.
a61af66fc99e Initial load
duke
parents:
diff changeset
112 // This simplies the upcoming "independence" checker.
a61af66fc99e Initial load
duke
parents:
diff changeset
113 //
a61af66fc99e Initial load
duke
parents:
diff changeset
114 // 3) The maximum depth in the node graph from the beginning of the block
a61af66fc99e Initial load
duke
parents:
diff changeset
115 // to each node is computed. This is used to prune the graph search
a61af66fc99e Initial load
duke
parents:
diff changeset
116 // in the independence checker.
a61af66fc99e Initial load
duke
parents:
diff changeset
117 //
a61af66fc99e Initial load
duke
parents:
diff changeset
118 // 4) For integer types, the necessary bit width is propagated backwards
a61af66fc99e Initial load
duke
parents:
diff changeset
119 // from stores to allow packed operations on byte, char, and short
a61af66fc99e Initial load
duke
parents:
diff changeset
120 // integers. This reverses the promotion to type "int" that javac
a61af66fc99e Initial load
duke
parents:
diff changeset
121 // did for operations like: char c1,c2,c3; c1 = c2 + c3.
a61af66fc99e Initial load
duke
parents:
diff changeset
122 //
a61af66fc99e Initial load
duke
parents:
diff changeset
123 // 5) One of the memory references is picked to be an aligned vector reference.
a61af66fc99e Initial load
duke
parents:
diff changeset
124 // The pre-loop trip count is adjusted to align this reference in the
a61af66fc99e Initial load
duke
parents:
diff changeset
125 // unrolled body.
a61af66fc99e Initial load
duke
parents:
diff changeset
126 //
a61af66fc99e Initial load
duke
parents:
diff changeset
127 // 6) The initial set of pack pairs is seeded with memory references.
a61af66fc99e Initial load
duke
parents:
diff changeset
128 //
a61af66fc99e Initial load
duke
parents:
diff changeset
129 // 7) The set of pack pairs is extended by following use->def and def->use links.
a61af66fc99e Initial load
duke
parents:
diff changeset
130 //
a61af66fc99e Initial load
duke
parents:
diff changeset
131 // 8) The pairs are combined into vector sized packs.
a61af66fc99e Initial load
duke
parents:
diff changeset
132 //
a61af66fc99e Initial load
duke
parents:
diff changeset
133 // 9) Reorder the memory slices to co-locate members of the memory packs.
a61af66fc99e Initial load
duke
parents:
diff changeset
134 //
a61af66fc99e Initial load
duke
parents:
diff changeset
135 // 10) Generate ideal vector nodes for the final set of packs and where necessary,
a61af66fc99e Initial load
duke
parents:
diff changeset
136 // inserting scalar promotion, vector creation from multiple scalars, and
a61af66fc99e Initial load
duke
parents:
diff changeset
137 // extraction of scalar values from vectors.
a61af66fc99e Initial load
duke
parents:
diff changeset
138 //
a61af66fc99e Initial load
duke
parents:
diff changeset
139 void SuperWord::SLP_extract() {
a61af66fc99e Initial load
duke
parents:
diff changeset
140
a61af66fc99e Initial load
duke
parents:
diff changeset
141 // Ready the block
a61af66fc99e Initial load
duke
parents:
diff changeset
142
a61af66fc99e Initial load
duke
parents:
diff changeset
143 construct_bb();
a61af66fc99e Initial load
duke
parents:
diff changeset
144
a61af66fc99e Initial load
duke
parents:
diff changeset
145 dependence_graph();
a61af66fc99e Initial load
duke
parents:
diff changeset
146
a61af66fc99e Initial load
duke
parents:
diff changeset
147 compute_max_depth();
a61af66fc99e Initial load
duke
parents:
diff changeset
148
a61af66fc99e Initial load
duke
parents:
diff changeset
149 compute_vector_element_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
150
a61af66fc99e Initial load
duke
parents:
diff changeset
151 // Attempt vectorization
a61af66fc99e Initial load
duke
parents:
diff changeset
152
a61af66fc99e Initial load
duke
parents:
diff changeset
153 find_adjacent_refs();
a61af66fc99e Initial load
duke
parents:
diff changeset
154
a61af66fc99e Initial load
duke
parents:
diff changeset
155 extend_packlist();
a61af66fc99e Initial load
duke
parents:
diff changeset
156
a61af66fc99e Initial load
duke
parents:
diff changeset
157 combine_packs();
a61af66fc99e Initial load
duke
parents:
diff changeset
158
a61af66fc99e Initial load
duke
parents:
diff changeset
159 construct_my_pack_map();
a61af66fc99e Initial load
duke
parents:
diff changeset
160
a61af66fc99e Initial load
duke
parents:
diff changeset
161 filter_packs();
a61af66fc99e Initial load
duke
parents:
diff changeset
162
a61af66fc99e Initial load
duke
parents:
diff changeset
163 schedule();
a61af66fc99e Initial load
duke
parents:
diff changeset
164
a61af66fc99e Initial load
duke
parents:
diff changeset
165 output();
a61af66fc99e Initial load
duke
parents:
diff changeset
166 }
a61af66fc99e Initial load
duke
parents:
diff changeset
167
a61af66fc99e Initial load
duke
parents:
diff changeset
168 //------------------------------find_adjacent_refs---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
169 // Find the adjacent memory references and create pack pairs for them.
a61af66fc99e Initial load
duke
parents:
diff changeset
170 // This is the initial set of packs that will then be extended by
a61af66fc99e Initial load
duke
parents:
diff changeset
171 // following use->def and def->use links. The align positions are
a61af66fc99e Initial load
duke
parents:
diff changeset
172 // assigned relative to the reference "align_to_ref"
a61af66fc99e Initial load
duke
parents:
diff changeset
173 void SuperWord::find_adjacent_refs() {
a61af66fc99e Initial load
duke
parents:
diff changeset
174 // Get list of memory operations
a61af66fc99e Initial load
duke
parents:
diff changeset
175 Node_List memops;
a61af66fc99e Initial load
duke
parents:
diff changeset
176 for (int i = 0; i < _block.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
177 Node* n = _block.at(i);
29
d5fc211aea19 6633953: type2aelembytes{T_ADDRESS} should be 8 bytes in 64 bit VM
kvn
parents: 0
diff changeset
178 if (n->is_Mem() && in_bb(n) &&
d5fc211aea19 6633953: type2aelembytes{T_ADDRESS} should be 8 bytes in 64 bit VM
kvn
parents: 0
diff changeset
179 is_java_primitive(n->as_Mem()->memory_type())) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
180 int align = memory_alignment(n->as_Mem(), 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
181 if (align != bottom_align) {
a61af66fc99e Initial load
duke
parents:
diff changeset
182 memops.push(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
183 }
a61af66fc99e Initial load
duke
parents:
diff changeset
184 }
a61af66fc99e Initial load
duke
parents:
diff changeset
185 }
a61af66fc99e Initial load
duke
parents:
diff changeset
186 if (memops.size() == 0) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
187
a61af66fc99e Initial load
duke
parents:
diff changeset
188 // Find a memory reference to align to. The pre-loop trip count
a61af66fc99e Initial load
duke
parents:
diff changeset
189 // is modified to align this reference to a vector-aligned address
a61af66fc99e Initial load
duke
parents:
diff changeset
190 find_align_to_ref(memops);
a61af66fc99e Initial load
duke
parents:
diff changeset
191 if (align_to_ref() == NULL) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
192
a61af66fc99e Initial load
duke
parents:
diff changeset
193 SWPointer align_to_ref_p(align_to_ref(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
194 int offset = align_to_ref_p.offset_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
195 int scale = align_to_ref_p.scale_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
196 int vw = vector_width_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
197 int stride_sign = (scale * iv_stride()) > 0 ? 1 : -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
198 int iv_adjustment = (stride_sign * vw - (offset % vw)) % vw;
a61af66fc99e Initial load
duke
parents:
diff changeset
199
a61af66fc99e Initial load
duke
parents:
diff changeset
200 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
201 if (TraceSuperWord)
72
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
202 tty->print_cr("\noffset = %d iv_adjustment = %d elt_align = %d scale = %d iv_stride = %d",
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
203 offset, iv_adjustment, align_to_ref_p.memory_size(), align_to_ref_p.scale_in_bytes(), iv_stride());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
204 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
205
a61af66fc99e Initial load
duke
parents:
diff changeset
206 // Set alignment relative to "align_to_ref"
a61af66fc99e Initial load
duke
parents:
diff changeset
207 for (int i = memops.size() - 1; i >= 0; i--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
208 MemNode* s = memops.at(i)->as_Mem();
a61af66fc99e Initial load
duke
parents:
diff changeset
209 SWPointer p2(s, this);
a61af66fc99e Initial load
duke
parents:
diff changeset
210 if (p2.comparable(align_to_ref_p)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
211 int align = memory_alignment(s, iv_adjustment);
a61af66fc99e Initial load
duke
parents:
diff changeset
212 set_alignment(s, align);
a61af66fc99e Initial load
duke
parents:
diff changeset
213 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
214 memops.remove(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
215 }
a61af66fc99e Initial load
duke
parents:
diff changeset
216 }
a61af66fc99e Initial load
duke
parents:
diff changeset
217
a61af66fc99e Initial load
duke
parents:
diff changeset
218 // Create initial pack pairs of memory operations
a61af66fc99e Initial load
duke
parents:
diff changeset
219 for (uint i = 0; i < memops.size(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
220 Node* s1 = memops.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
221 for (uint j = 0; j < memops.size(); j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
222 Node* s2 = memops.at(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
223 if (s1 != s2 && are_adjacent_refs(s1, s2)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
224 int align = alignment(s1);
a61af66fc99e Initial load
duke
parents:
diff changeset
225 if (stmts_can_pack(s1, s2, align)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
226 Node_List* pair = new Node_List();
a61af66fc99e Initial load
duke
parents:
diff changeset
227 pair->push(s1);
a61af66fc99e Initial load
duke
parents:
diff changeset
228 pair->push(s2);
a61af66fc99e Initial load
duke
parents:
diff changeset
229 _packset.append(pair);
a61af66fc99e Initial load
duke
parents:
diff changeset
230 }
a61af66fc99e Initial load
duke
parents:
diff changeset
231 }
a61af66fc99e Initial load
duke
parents:
diff changeset
232 }
a61af66fc99e Initial load
duke
parents:
diff changeset
233 }
a61af66fc99e Initial load
duke
parents:
diff changeset
234
a61af66fc99e Initial load
duke
parents:
diff changeset
235 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
236 if (TraceSuperWord) {
a61af66fc99e Initial load
duke
parents:
diff changeset
237 tty->print_cr("\nAfter find_adjacent_refs");
a61af66fc99e Initial load
duke
parents:
diff changeset
238 print_packset();
a61af66fc99e Initial load
duke
parents:
diff changeset
239 }
a61af66fc99e Initial load
duke
parents:
diff changeset
240 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
241 }
a61af66fc99e Initial load
duke
parents:
diff changeset
242
a61af66fc99e Initial load
duke
parents:
diff changeset
243 //------------------------------find_align_to_ref---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
244 // Find a memory reference to align the loop induction variable to.
a61af66fc99e Initial load
duke
parents:
diff changeset
245 // Looks first at stores then at loads, looking for a memory reference
a61af66fc99e Initial load
duke
parents:
diff changeset
246 // with the largest number of references similar to it.
a61af66fc99e Initial load
duke
parents:
diff changeset
247 void SuperWord::find_align_to_ref(Node_List &memops) {
a61af66fc99e Initial load
duke
parents:
diff changeset
248 GrowableArray<int> cmp_ct(arena(), memops.size(), memops.size(), 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
249
a61af66fc99e Initial load
duke
parents:
diff changeset
250 // Count number of comparable memory ops
a61af66fc99e Initial load
duke
parents:
diff changeset
251 for (uint i = 0; i < memops.size(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
252 MemNode* s1 = memops.at(i)->as_Mem();
a61af66fc99e Initial load
duke
parents:
diff changeset
253 SWPointer p1(s1, this);
a61af66fc99e Initial load
duke
parents:
diff changeset
254 // Discard if pre loop can't align this reference
a61af66fc99e Initial load
duke
parents:
diff changeset
255 if (!ref_is_alignable(p1)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
256 *cmp_ct.adr_at(i) = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
257 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
258 }
a61af66fc99e Initial load
duke
parents:
diff changeset
259 for (uint j = i+1; j < memops.size(); j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
260 MemNode* s2 = memops.at(j)->as_Mem();
a61af66fc99e Initial load
duke
parents:
diff changeset
261 if (isomorphic(s1, s2)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
262 SWPointer p2(s2, this);
a61af66fc99e Initial load
duke
parents:
diff changeset
263 if (p1.comparable(p2)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
264 (*cmp_ct.adr_at(i))++;
a61af66fc99e Initial load
duke
parents:
diff changeset
265 (*cmp_ct.adr_at(j))++;
a61af66fc99e Initial load
duke
parents:
diff changeset
266 }
a61af66fc99e Initial load
duke
parents:
diff changeset
267 }
a61af66fc99e Initial load
duke
parents:
diff changeset
268 }
a61af66fc99e Initial load
duke
parents:
diff changeset
269 }
a61af66fc99e Initial load
duke
parents:
diff changeset
270
a61af66fc99e Initial load
duke
parents:
diff changeset
271 // Find Store (or Load) with the greatest number of "comparable" references
a61af66fc99e Initial load
duke
parents:
diff changeset
272 int max_ct = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
273 int max_idx = -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
274 int min_size = max_jint;
a61af66fc99e Initial load
duke
parents:
diff changeset
275 int min_iv_offset = max_jint;
a61af66fc99e Initial load
duke
parents:
diff changeset
276 for (uint j = 0; j < memops.size(); j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
277 MemNode* s = memops.at(j)->as_Mem();
a61af66fc99e Initial load
duke
parents:
diff changeset
278 if (s->is_Store()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
279 SWPointer p(s, this);
a61af66fc99e Initial load
duke
parents:
diff changeset
280 if (cmp_ct.at(j) > max_ct ||
a61af66fc99e Initial load
duke
parents:
diff changeset
281 cmp_ct.at(j) == max_ct && (data_size(s) < min_size ||
a61af66fc99e Initial load
duke
parents:
diff changeset
282 data_size(s) == min_size &&
a61af66fc99e Initial load
duke
parents:
diff changeset
283 p.offset_in_bytes() < min_iv_offset)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
284 max_ct = cmp_ct.at(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
285 max_idx = j;
a61af66fc99e Initial load
duke
parents:
diff changeset
286 min_size = data_size(s);
a61af66fc99e Initial load
duke
parents:
diff changeset
287 min_iv_offset = p.offset_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
288 }
a61af66fc99e Initial load
duke
parents:
diff changeset
289 }
a61af66fc99e Initial load
duke
parents:
diff changeset
290 }
a61af66fc99e Initial load
duke
parents:
diff changeset
291 // If no stores, look at loads
a61af66fc99e Initial load
duke
parents:
diff changeset
292 if (max_ct == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
293 for (uint j = 0; j < memops.size(); j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
294 MemNode* s = memops.at(j)->as_Mem();
a61af66fc99e Initial load
duke
parents:
diff changeset
295 if (s->is_Load()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
296 SWPointer p(s, this);
a61af66fc99e Initial load
duke
parents:
diff changeset
297 if (cmp_ct.at(j) > max_ct ||
a61af66fc99e Initial load
duke
parents:
diff changeset
298 cmp_ct.at(j) == max_ct && (data_size(s) < min_size ||
a61af66fc99e Initial load
duke
parents:
diff changeset
299 data_size(s) == min_size &&
a61af66fc99e Initial load
duke
parents:
diff changeset
300 p.offset_in_bytes() < min_iv_offset)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
301 max_ct = cmp_ct.at(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
302 max_idx = j;
a61af66fc99e Initial load
duke
parents:
diff changeset
303 min_size = data_size(s);
a61af66fc99e Initial load
duke
parents:
diff changeset
304 min_iv_offset = p.offset_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
305 }
a61af66fc99e Initial load
duke
parents:
diff changeset
306 }
a61af66fc99e Initial load
duke
parents:
diff changeset
307 }
a61af66fc99e Initial load
duke
parents:
diff changeset
308 }
a61af66fc99e Initial load
duke
parents:
diff changeset
309
a61af66fc99e Initial load
duke
parents:
diff changeset
310 if (max_ct > 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
311 set_align_to_ref(memops.at(max_idx)->as_Mem());
a61af66fc99e Initial load
duke
parents:
diff changeset
312
a61af66fc99e Initial load
duke
parents:
diff changeset
313 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
314 if (TraceSuperWord && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
315 tty->print_cr("\nVector memops after find_align_to_refs");
a61af66fc99e Initial load
duke
parents:
diff changeset
316 for (uint i = 0; i < memops.size(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
317 MemNode* s = memops.at(i)->as_Mem();
a61af66fc99e Initial load
duke
parents:
diff changeset
318 s->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
319 }
a61af66fc99e Initial load
duke
parents:
diff changeset
320 }
a61af66fc99e Initial load
duke
parents:
diff changeset
321 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
322 }
a61af66fc99e Initial load
duke
parents:
diff changeset
323
a61af66fc99e Initial load
duke
parents:
diff changeset
324 //------------------------------ref_is_alignable---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
325 // Can the preloop align the reference to position zero in the vector?
a61af66fc99e Initial load
duke
parents:
diff changeset
326 bool SuperWord::ref_is_alignable(SWPointer& p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
327 if (!p.has_iv()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
328 return true; // no induction variable
a61af66fc99e Initial load
duke
parents:
diff changeset
329 }
a61af66fc99e Initial load
duke
parents:
diff changeset
330 CountedLoopEndNode* pre_end = get_pre_loop_end(lp()->as_CountedLoop());
a61af66fc99e Initial load
duke
parents:
diff changeset
331 assert(pre_end->stride_is_con(), "pre loop stride is constant");
a61af66fc99e Initial load
duke
parents:
diff changeset
332 int preloop_stride = pre_end->stride_con();
a61af66fc99e Initial load
duke
parents:
diff changeset
333
a61af66fc99e Initial load
duke
parents:
diff changeset
334 int span = preloop_stride * p.scale_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
335
a61af66fc99e Initial load
duke
parents:
diff changeset
336 // Stride one accesses are alignable.
a61af66fc99e Initial load
duke
parents:
diff changeset
337 if (ABS(span) == p.memory_size())
a61af66fc99e Initial load
duke
parents:
diff changeset
338 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
339
a61af66fc99e Initial load
duke
parents:
diff changeset
340 // If initial offset from start of object is computable,
a61af66fc99e Initial load
duke
parents:
diff changeset
341 // compute alignment within the vector.
a61af66fc99e Initial load
duke
parents:
diff changeset
342 int vw = vector_width_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
343 if (vw % span == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
344 Node* init_nd = pre_end->init_trip();
a61af66fc99e Initial load
duke
parents:
diff changeset
345 if (init_nd->is_Con() && p.invar() == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
346 int init = init_nd->bottom_type()->is_int()->get_con();
a61af66fc99e Initial load
duke
parents:
diff changeset
347
a61af66fc99e Initial load
duke
parents:
diff changeset
348 int init_offset = init * p.scale_in_bytes() + p.offset_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
349 assert(init_offset >= 0, "positive offset from object start");
a61af66fc99e Initial load
duke
parents:
diff changeset
350
a61af66fc99e Initial load
duke
parents:
diff changeset
351 if (span > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
352 return (vw - (init_offset % vw)) % span == 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
353 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
354 assert(span < 0, "nonzero stride * scale");
a61af66fc99e Initial load
duke
parents:
diff changeset
355 return (init_offset % vw) % -span == 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
356 }
a61af66fc99e Initial load
duke
parents:
diff changeset
357 }
a61af66fc99e Initial load
duke
parents:
diff changeset
358 }
a61af66fc99e Initial load
duke
parents:
diff changeset
359 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
360 }
a61af66fc99e Initial load
duke
parents:
diff changeset
361
a61af66fc99e Initial load
duke
parents:
diff changeset
362 //---------------------------dependence_graph---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
363 // Construct dependency graph.
a61af66fc99e Initial load
duke
parents:
diff changeset
364 // Add dependence edges to load/store nodes for memory dependence
a61af66fc99e Initial load
duke
parents:
diff changeset
365 // A.out()->DependNode.in(1) and DependNode.out()->B.prec(x)
a61af66fc99e Initial load
duke
parents:
diff changeset
366 void SuperWord::dependence_graph() {
a61af66fc99e Initial load
duke
parents:
diff changeset
367 // First, assign a dependence node to each memory node
a61af66fc99e Initial load
duke
parents:
diff changeset
368 for (int i = 0; i < _block.length(); i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
369 Node *n = _block.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
370 if (n->is_Mem() || n->is_Phi() && n->bottom_type() == Type::MEMORY) {
a61af66fc99e Initial load
duke
parents:
diff changeset
371 _dg.make_node(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
372 }
a61af66fc99e Initial load
duke
parents:
diff changeset
373 }
a61af66fc99e Initial load
duke
parents:
diff changeset
374
a61af66fc99e Initial load
duke
parents:
diff changeset
375 // For each memory slice, create the dependences
a61af66fc99e Initial load
duke
parents:
diff changeset
376 for (int i = 0; i < _mem_slice_head.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
377 Node* n = _mem_slice_head.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
378 Node* n_tail = _mem_slice_tail.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
379
a61af66fc99e Initial load
duke
parents:
diff changeset
380 // Get slice in predecessor order (last is first)
a61af66fc99e Initial load
duke
parents:
diff changeset
381 mem_slice_preds(n_tail, n, _nlist);
a61af66fc99e Initial load
duke
parents:
diff changeset
382
a61af66fc99e Initial load
duke
parents:
diff changeset
383 // Make the slice dependent on the root
a61af66fc99e Initial load
duke
parents:
diff changeset
384 DepMem* slice = _dg.dep(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
385 _dg.make_edge(_dg.root(), slice);
a61af66fc99e Initial load
duke
parents:
diff changeset
386
a61af66fc99e Initial load
duke
parents:
diff changeset
387 // Create a sink for the slice
a61af66fc99e Initial load
duke
parents:
diff changeset
388 DepMem* slice_sink = _dg.make_node(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
389 _dg.make_edge(slice_sink, _dg.tail());
a61af66fc99e Initial load
duke
parents:
diff changeset
390
a61af66fc99e Initial load
duke
parents:
diff changeset
391 // Now visit each pair of memory ops, creating the edges
a61af66fc99e Initial load
duke
parents:
diff changeset
392 for (int j = _nlist.length() - 1; j >= 0 ; j--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
393 Node* s1 = _nlist.at(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
394
a61af66fc99e Initial load
duke
parents:
diff changeset
395 // If no dependency yet, use slice
a61af66fc99e Initial load
duke
parents:
diff changeset
396 if (_dg.dep(s1)->in_cnt() == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
397 _dg.make_edge(slice, s1);
a61af66fc99e Initial load
duke
parents:
diff changeset
398 }
a61af66fc99e Initial load
duke
parents:
diff changeset
399 SWPointer p1(s1->as_Mem(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
400 bool sink_dependent = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
401 for (int k = j - 1; k >= 0; k--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
402 Node* s2 = _nlist.at(k);
a61af66fc99e Initial load
duke
parents:
diff changeset
403 if (s1->is_Load() && s2->is_Load())
a61af66fc99e Initial load
duke
parents:
diff changeset
404 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
405 SWPointer p2(s2->as_Mem(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
406
a61af66fc99e Initial load
duke
parents:
diff changeset
407 int cmp = p1.cmp(p2);
a61af66fc99e Initial load
duke
parents:
diff changeset
408 if (SuperWordRTDepCheck &&
a61af66fc99e Initial load
duke
parents:
diff changeset
409 p1.base() != p2.base() && p1.valid() && p2.valid()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
410 // Create a runtime check to disambiguate
a61af66fc99e Initial load
duke
parents:
diff changeset
411 OrderedPair pp(p1.base(), p2.base());
a61af66fc99e Initial load
duke
parents:
diff changeset
412 _disjoint_ptrs.append_if_missing(pp);
a61af66fc99e Initial load
duke
parents:
diff changeset
413 } else if (!SWPointer::not_equal(cmp)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
414 // Possibly same address
a61af66fc99e Initial load
duke
parents:
diff changeset
415 _dg.make_edge(s1, s2);
a61af66fc99e Initial load
duke
parents:
diff changeset
416 sink_dependent = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
417 }
a61af66fc99e Initial load
duke
parents:
diff changeset
418 }
a61af66fc99e Initial load
duke
parents:
diff changeset
419 if (sink_dependent) {
a61af66fc99e Initial load
duke
parents:
diff changeset
420 _dg.make_edge(s1, slice_sink);
a61af66fc99e Initial load
duke
parents:
diff changeset
421 }
a61af66fc99e Initial load
duke
parents:
diff changeset
422 }
a61af66fc99e Initial load
duke
parents:
diff changeset
423 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
424 if (TraceSuperWord) {
a61af66fc99e Initial load
duke
parents:
diff changeset
425 tty->print_cr("\nDependence graph for slice: %d", n->_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
426 for (int q = 0; q < _nlist.length(); q++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
427 _dg.print(_nlist.at(q));
a61af66fc99e Initial load
duke
parents:
diff changeset
428 }
a61af66fc99e Initial load
duke
parents:
diff changeset
429 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
430 }
a61af66fc99e Initial load
duke
parents:
diff changeset
431 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
432 _nlist.clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
433 }
a61af66fc99e Initial load
duke
parents:
diff changeset
434
a61af66fc99e Initial load
duke
parents:
diff changeset
435 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
436 if (TraceSuperWord) {
a61af66fc99e Initial load
duke
parents:
diff changeset
437 tty->print_cr("\ndisjoint_ptrs: %s", _disjoint_ptrs.length() > 0 ? "" : "NONE");
a61af66fc99e Initial load
duke
parents:
diff changeset
438 for (int r = 0; r < _disjoint_ptrs.length(); r++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
439 _disjoint_ptrs.at(r).print();
a61af66fc99e Initial load
duke
parents:
diff changeset
440 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
441 }
a61af66fc99e Initial load
duke
parents:
diff changeset
442 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
443 }
a61af66fc99e Initial load
duke
parents:
diff changeset
444 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
445 }
a61af66fc99e Initial load
duke
parents:
diff changeset
446
a61af66fc99e Initial load
duke
parents:
diff changeset
447 //---------------------------mem_slice_preds---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
448 // Return a memory slice (node list) in predecessor order starting at "start"
a61af66fc99e Initial load
duke
parents:
diff changeset
449 void SuperWord::mem_slice_preds(Node* start, Node* stop, GrowableArray<Node*> &preds) {
a61af66fc99e Initial load
duke
parents:
diff changeset
450 assert(preds.length() == 0, "start empty");
a61af66fc99e Initial load
duke
parents:
diff changeset
451 Node* n = start;
a61af66fc99e Initial load
duke
parents:
diff changeset
452 Node* prev = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
453 while (true) {
a61af66fc99e Initial load
duke
parents:
diff changeset
454 assert(in_bb(n), "must be in block");
a61af66fc99e Initial load
duke
parents:
diff changeset
455 for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
456 Node* out = n->fast_out(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
457 if (out->is_Load()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
458 if (in_bb(out)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
459 preds.push(out);
a61af66fc99e Initial load
duke
parents:
diff changeset
460 }
a61af66fc99e Initial load
duke
parents:
diff changeset
461 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
462 // FIXME
a61af66fc99e Initial load
duke
parents:
diff changeset
463 if (out->is_MergeMem() && !in_bb(out)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
464 // Either unrolling is causing a memory edge not to disappear,
a61af66fc99e Initial load
duke
parents:
diff changeset
465 // or need to run igvn.optimize() again before SLP
a61af66fc99e Initial load
duke
parents:
diff changeset
466 } else if (out->is_Phi() && out->bottom_type() == Type::MEMORY && !in_bb(out)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
467 // Ditto. Not sure what else to check further.
667
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
468 } else if (out->Opcode() == Op_StoreCM && out->in(MemNode::OopStore) == n) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
469 // StoreCM has an input edge used as a precedence edge.
a61af66fc99e Initial load
duke
parents:
diff changeset
470 // Maybe an issue when oop stores are vectorized.
a61af66fc99e Initial load
duke
parents:
diff changeset
471 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
472 assert(out == prev || prev == NULL, "no branches off of store slice");
a61af66fc99e Initial load
duke
parents:
diff changeset
473 }
a61af66fc99e Initial load
duke
parents:
diff changeset
474 }
a61af66fc99e Initial load
duke
parents:
diff changeset
475 }
a61af66fc99e Initial load
duke
parents:
diff changeset
476 if (n == stop) break;
a61af66fc99e Initial load
duke
parents:
diff changeset
477 preds.push(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
478 prev = n;
a61af66fc99e Initial load
duke
parents:
diff changeset
479 n = n->in(MemNode::Memory);
a61af66fc99e Initial load
duke
parents:
diff changeset
480 }
a61af66fc99e Initial load
duke
parents:
diff changeset
481 }
a61af66fc99e Initial load
duke
parents:
diff changeset
482
a61af66fc99e Initial load
duke
parents:
diff changeset
483 //------------------------------stmts_can_pack---------------------------
605
98cb887364d3 6810672: Comment typos
twisti
parents: 558
diff changeset
484 // Can s1 and s2 be in a pack with s1 immediately preceding s2 and
0
a61af66fc99e Initial load
duke
parents:
diff changeset
485 // s1 aligned at "align"
a61af66fc99e Initial load
duke
parents:
diff changeset
486 bool SuperWord::stmts_can_pack(Node* s1, Node* s2, int align) {
987
00977607da34 6879921: CTW failure jdk6_18/hotspot/src/share/vm/utilities/globalDefinitions.cpp:268
cfang
parents: 985
diff changeset
487
00977607da34 6879921: CTW failure jdk6_18/hotspot/src/share/vm/utilities/globalDefinitions.cpp:268
cfang
parents: 985
diff changeset
488 // Do not use superword for non-primitives
00977607da34 6879921: CTW failure jdk6_18/hotspot/src/share/vm/utilities/globalDefinitions.cpp:268
cfang
parents: 985
diff changeset
489 if((s1->is_Mem() && !is_java_primitive(s1->as_Mem()->memory_type())) ||
00977607da34 6879921: CTW failure jdk6_18/hotspot/src/share/vm/utilities/globalDefinitions.cpp:268
cfang
parents: 985
diff changeset
490 (s2->is_Mem() && !is_java_primitive(s2->as_Mem()->memory_type())))
00977607da34 6879921: CTW failure jdk6_18/hotspot/src/share/vm/utilities/globalDefinitions.cpp:268
cfang
parents: 985
diff changeset
491 return false;
00977607da34 6879921: CTW failure jdk6_18/hotspot/src/share/vm/utilities/globalDefinitions.cpp:268
cfang
parents: 985
diff changeset
492
0
a61af66fc99e Initial load
duke
parents:
diff changeset
493 if (isomorphic(s1, s2)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
494 if (independent(s1, s2)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
495 if (!exists_at(s1, 0) && !exists_at(s2, 1)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
496 if (!s1->is_Mem() || are_adjacent_refs(s1, s2)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
497 int s1_align = alignment(s1);
a61af66fc99e Initial load
duke
parents:
diff changeset
498 int s2_align = alignment(s2);
a61af66fc99e Initial load
duke
parents:
diff changeset
499 if (s1_align == top_align || s1_align == align) {
a61af66fc99e Initial load
duke
parents:
diff changeset
500 if (s2_align == top_align || s2_align == align + data_size(s1)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
501 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
502 }
a61af66fc99e Initial load
duke
parents:
diff changeset
503 }
a61af66fc99e Initial load
duke
parents:
diff changeset
504 }
a61af66fc99e Initial load
duke
parents:
diff changeset
505 }
a61af66fc99e Initial load
duke
parents:
diff changeset
506 }
a61af66fc99e Initial load
duke
parents:
diff changeset
507 }
a61af66fc99e Initial load
duke
parents:
diff changeset
508 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
509 }
a61af66fc99e Initial load
duke
parents:
diff changeset
510
a61af66fc99e Initial load
duke
parents:
diff changeset
511 //------------------------------exists_at---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
512 // Does s exist in a pack at position pos?
a61af66fc99e Initial load
duke
parents:
diff changeset
513 bool SuperWord::exists_at(Node* s, uint pos) {
a61af66fc99e Initial load
duke
parents:
diff changeset
514 for (int i = 0; i < _packset.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
515 Node_List* p = _packset.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
516 if (p->at(pos) == s) {
a61af66fc99e Initial load
duke
parents:
diff changeset
517 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
518 }
a61af66fc99e Initial load
duke
parents:
diff changeset
519 }
a61af66fc99e Initial load
duke
parents:
diff changeset
520 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
521 }
a61af66fc99e Initial load
duke
parents:
diff changeset
522
a61af66fc99e Initial load
duke
parents:
diff changeset
523 //------------------------------are_adjacent_refs---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
524 // Is s1 immediately before s2 in memory?
a61af66fc99e Initial load
duke
parents:
diff changeset
525 bool SuperWord::are_adjacent_refs(Node* s1, Node* s2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
526 if (!s1->is_Mem() || !s2->is_Mem()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
527 if (!in_bb(s1) || !in_bb(s2)) return false;
1585
49fac4acd688 6958485: fix for 6879921 was insufficient
never
parents: 1552
diff changeset
528
49fac4acd688 6958485: fix for 6879921 was insufficient
never
parents: 1552
diff changeset
529 // Do not use superword for non-primitives
49fac4acd688 6958485: fix for 6879921 was insufficient
never
parents: 1552
diff changeset
530 if (!is_java_primitive(s1->as_Mem()->memory_type()) ||
49fac4acd688 6958485: fix for 6879921 was insufficient
never
parents: 1552
diff changeset
531 !is_java_primitive(s2->as_Mem()->memory_type())) {
49fac4acd688 6958485: fix for 6879921 was insufficient
never
parents: 1552
diff changeset
532 return false;
49fac4acd688 6958485: fix for 6879921 was insufficient
never
parents: 1552
diff changeset
533 }
49fac4acd688 6958485: fix for 6879921 was insufficient
never
parents: 1552
diff changeset
534
0
a61af66fc99e Initial load
duke
parents:
diff changeset
535 // FIXME - co_locate_pack fails on Stores in different mem-slices, so
a61af66fc99e Initial load
duke
parents:
diff changeset
536 // only pack memops that are in the same alias set until that's fixed.
a61af66fc99e Initial load
duke
parents:
diff changeset
537 if (_phase->C->get_alias_index(s1->as_Mem()->adr_type()) !=
a61af66fc99e Initial load
duke
parents:
diff changeset
538 _phase->C->get_alias_index(s2->as_Mem()->adr_type()))
a61af66fc99e Initial load
duke
parents:
diff changeset
539 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
540 SWPointer p1(s1->as_Mem(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
541 SWPointer p2(s2->as_Mem(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
542 if (p1.base() != p2.base() || !p1.comparable(p2)) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
543 int diff = p2.offset_in_bytes() - p1.offset_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
544 return diff == data_size(s1);
a61af66fc99e Initial load
duke
parents:
diff changeset
545 }
a61af66fc99e Initial load
duke
parents:
diff changeset
546
a61af66fc99e Initial load
duke
parents:
diff changeset
547 //------------------------------isomorphic---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
548 // Are s1 and s2 similar?
a61af66fc99e Initial load
duke
parents:
diff changeset
549 bool SuperWord::isomorphic(Node* s1, Node* s2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
550 if (s1->Opcode() != s2->Opcode()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
551 if (s1->req() != s2->req()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
552 if (s1->in(0) != s2->in(0)) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
553 if (velt_type(s1) != velt_type(s2)) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
554 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
555 }
a61af66fc99e Initial load
duke
parents:
diff changeset
556
a61af66fc99e Initial load
duke
parents:
diff changeset
557 //------------------------------independent---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
558 // Is there no data path from s1 to s2 or s2 to s1?
a61af66fc99e Initial load
duke
parents:
diff changeset
559 bool SuperWord::independent(Node* s1, Node* s2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
560 // assert(s1->Opcode() == s2->Opcode(), "check isomorphic first");
a61af66fc99e Initial load
duke
parents:
diff changeset
561 int d1 = depth(s1);
a61af66fc99e Initial load
duke
parents:
diff changeset
562 int d2 = depth(s2);
a61af66fc99e Initial load
duke
parents:
diff changeset
563 if (d1 == d2) return s1 != s2;
a61af66fc99e Initial load
duke
parents:
diff changeset
564 Node* deep = d1 > d2 ? s1 : s2;
a61af66fc99e Initial load
duke
parents:
diff changeset
565 Node* shallow = d1 > d2 ? s2 : s1;
a61af66fc99e Initial load
duke
parents:
diff changeset
566
a61af66fc99e Initial load
duke
parents:
diff changeset
567 visited_clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
568
a61af66fc99e Initial load
duke
parents:
diff changeset
569 return independent_path(shallow, deep);
a61af66fc99e Initial load
duke
parents:
diff changeset
570 }
a61af66fc99e Initial load
duke
parents:
diff changeset
571
a61af66fc99e Initial load
duke
parents:
diff changeset
572 //------------------------------independent_path------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
573 // Helper for independent
a61af66fc99e Initial load
duke
parents:
diff changeset
574 bool SuperWord::independent_path(Node* shallow, Node* deep, uint dp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
575 if (dp >= 1000) return false; // stop deep recursion
a61af66fc99e Initial load
duke
parents:
diff changeset
576 visited_set(deep);
a61af66fc99e Initial load
duke
parents:
diff changeset
577 int shal_depth = depth(shallow);
a61af66fc99e Initial load
duke
parents:
diff changeset
578 assert(shal_depth <= depth(deep), "must be");
a61af66fc99e Initial load
duke
parents:
diff changeset
579 for (DepPreds preds(deep, _dg); !preds.done(); preds.next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
580 Node* pred = preds.current();
a61af66fc99e Initial load
duke
parents:
diff changeset
581 if (in_bb(pred) && !visited_test(pred)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
582 if (shallow == pred) {
a61af66fc99e Initial load
duke
parents:
diff changeset
583 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
584 }
a61af66fc99e Initial load
duke
parents:
diff changeset
585 if (shal_depth < depth(pred) && !independent_path(shallow, pred, dp+1)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
586 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
587 }
a61af66fc99e Initial load
duke
parents:
diff changeset
588 }
a61af66fc99e Initial load
duke
parents:
diff changeset
589 }
a61af66fc99e Initial load
duke
parents:
diff changeset
590 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
591 }
a61af66fc99e Initial load
duke
parents:
diff changeset
592
a61af66fc99e Initial load
duke
parents:
diff changeset
593 //------------------------------set_alignment---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
594 void SuperWord::set_alignment(Node* s1, Node* s2, int align) {
a61af66fc99e Initial load
duke
parents:
diff changeset
595 set_alignment(s1, align);
a61af66fc99e Initial load
duke
parents:
diff changeset
596 set_alignment(s2, align + data_size(s1));
a61af66fc99e Initial load
duke
parents:
diff changeset
597 }
a61af66fc99e Initial load
duke
parents:
diff changeset
598
a61af66fc99e Initial load
duke
parents:
diff changeset
599 //------------------------------data_size---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
600 int SuperWord::data_size(Node* s) {
a61af66fc99e Initial load
duke
parents:
diff changeset
601 const Type* t = velt_type(s);
a61af66fc99e Initial load
duke
parents:
diff changeset
602 BasicType bt = t->array_element_basic_type();
29
d5fc211aea19 6633953: type2aelembytes{T_ADDRESS} should be 8 bytes in 64 bit VM
kvn
parents: 0
diff changeset
603 int bsize = type2aelembytes(bt);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
604 assert(bsize != 0, "valid size");
a61af66fc99e Initial load
duke
parents:
diff changeset
605 return bsize;
a61af66fc99e Initial load
duke
parents:
diff changeset
606 }
a61af66fc99e Initial load
duke
parents:
diff changeset
607
a61af66fc99e Initial load
duke
parents:
diff changeset
608 //------------------------------extend_packlist---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
609 // Extend packset by following use->def and def->use links from pack members.
a61af66fc99e Initial load
duke
parents:
diff changeset
610 void SuperWord::extend_packlist() {
a61af66fc99e Initial load
duke
parents:
diff changeset
611 bool changed;
a61af66fc99e Initial load
duke
parents:
diff changeset
612 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
613 changed = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
614 for (int i = 0; i < _packset.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
615 Node_List* p = _packset.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
616 changed |= follow_use_defs(p);
a61af66fc99e Initial load
duke
parents:
diff changeset
617 changed |= follow_def_uses(p);
a61af66fc99e Initial load
duke
parents:
diff changeset
618 }
a61af66fc99e Initial load
duke
parents:
diff changeset
619 } while (changed);
a61af66fc99e Initial load
duke
parents:
diff changeset
620
a61af66fc99e Initial load
duke
parents:
diff changeset
621 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
622 if (TraceSuperWord) {
a61af66fc99e Initial load
duke
parents:
diff changeset
623 tty->print_cr("\nAfter extend_packlist");
a61af66fc99e Initial load
duke
parents:
diff changeset
624 print_packset();
a61af66fc99e Initial load
duke
parents:
diff changeset
625 }
a61af66fc99e Initial load
duke
parents:
diff changeset
626 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
627 }
a61af66fc99e Initial load
duke
parents:
diff changeset
628
a61af66fc99e Initial load
duke
parents:
diff changeset
629 //------------------------------follow_use_defs---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
630 // Extend the packset by visiting operand definitions of nodes in pack p
a61af66fc99e Initial load
duke
parents:
diff changeset
631 bool SuperWord::follow_use_defs(Node_List* p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
632 Node* s1 = p->at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
633 Node* s2 = p->at(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
634 assert(p->size() == 2, "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
635 assert(s1->req() == s2->req(), "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
636 assert(alignment(s1) + data_size(s1) == alignment(s2), "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
637
a61af66fc99e Initial load
duke
parents:
diff changeset
638 if (s1->is_Load()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
639
a61af66fc99e Initial load
duke
parents:
diff changeset
640 int align = alignment(s1);
a61af66fc99e Initial load
duke
parents:
diff changeset
641 bool changed = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
642 int start = s1->is_Store() ? MemNode::ValueIn : 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
643 int end = s1->is_Store() ? MemNode::ValueIn+1 : s1->req();
a61af66fc99e Initial load
duke
parents:
diff changeset
644 for (int j = start; j < end; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
645 Node* t1 = s1->in(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
646 Node* t2 = s2->in(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
647 if (!in_bb(t1) || !in_bb(t2))
a61af66fc99e Initial load
duke
parents:
diff changeset
648 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
649 if (stmts_can_pack(t1, t2, align)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
650 if (est_savings(t1, t2) >= 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
651 Node_List* pair = new Node_List();
a61af66fc99e Initial load
duke
parents:
diff changeset
652 pair->push(t1);
a61af66fc99e Initial load
duke
parents:
diff changeset
653 pair->push(t2);
a61af66fc99e Initial load
duke
parents:
diff changeset
654 _packset.append(pair);
a61af66fc99e Initial load
duke
parents:
diff changeset
655 set_alignment(t1, t2, align);
a61af66fc99e Initial load
duke
parents:
diff changeset
656 changed = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
657 }
a61af66fc99e Initial load
duke
parents:
diff changeset
658 }
a61af66fc99e Initial load
duke
parents:
diff changeset
659 }
a61af66fc99e Initial load
duke
parents:
diff changeset
660 return changed;
a61af66fc99e Initial load
duke
parents:
diff changeset
661 }
a61af66fc99e Initial load
duke
parents:
diff changeset
662
a61af66fc99e Initial load
duke
parents:
diff changeset
663 //------------------------------follow_def_uses---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
664 // Extend the packset by visiting uses of nodes in pack p
a61af66fc99e Initial load
duke
parents:
diff changeset
665 bool SuperWord::follow_def_uses(Node_List* p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
666 bool changed = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
667 Node* s1 = p->at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
668 Node* s2 = p->at(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
669 assert(p->size() == 2, "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
670 assert(s1->req() == s2->req(), "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
671 assert(alignment(s1) + data_size(s1) == alignment(s2), "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
672
a61af66fc99e Initial load
duke
parents:
diff changeset
673 if (s1->is_Store()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
674
a61af66fc99e Initial load
duke
parents:
diff changeset
675 int align = alignment(s1);
a61af66fc99e Initial load
duke
parents:
diff changeset
676 int savings = -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
677 Node* u1 = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
678 Node* u2 = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
679 for (DUIterator_Fast imax, i = s1->fast_outs(imax); i < imax; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
680 Node* t1 = s1->fast_out(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
681 if (!in_bb(t1)) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
682 for (DUIterator_Fast jmax, j = s2->fast_outs(jmax); j < jmax; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
683 Node* t2 = s2->fast_out(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
684 if (!in_bb(t2)) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
685 if (!opnd_positions_match(s1, t1, s2, t2))
a61af66fc99e Initial load
duke
parents:
diff changeset
686 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
687 if (stmts_can_pack(t1, t2, align)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
688 int my_savings = est_savings(t1, t2);
a61af66fc99e Initial load
duke
parents:
diff changeset
689 if (my_savings > savings) {
a61af66fc99e Initial load
duke
parents:
diff changeset
690 savings = my_savings;
a61af66fc99e Initial load
duke
parents:
diff changeset
691 u1 = t1;
a61af66fc99e Initial load
duke
parents:
diff changeset
692 u2 = t2;
a61af66fc99e Initial load
duke
parents:
diff changeset
693 }
a61af66fc99e Initial load
duke
parents:
diff changeset
694 }
a61af66fc99e Initial load
duke
parents:
diff changeset
695 }
a61af66fc99e Initial load
duke
parents:
diff changeset
696 }
a61af66fc99e Initial load
duke
parents:
diff changeset
697 if (savings >= 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
698 Node_List* pair = new Node_List();
a61af66fc99e Initial load
duke
parents:
diff changeset
699 pair->push(u1);
a61af66fc99e Initial load
duke
parents:
diff changeset
700 pair->push(u2);
a61af66fc99e Initial load
duke
parents:
diff changeset
701 _packset.append(pair);
a61af66fc99e Initial load
duke
parents:
diff changeset
702 set_alignment(u1, u2, align);
a61af66fc99e Initial load
duke
parents:
diff changeset
703 changed = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
704 }
a61af66fc99e Initial load
duke
parents:
diff changeset
705 return changed;
a61af66fc99e Initial load
duke
parents:
diff changeset
706 }
a61af66fc99e Initial load
duke
parents:
diff changeset
707
a61af66fc99e Initial load
duke
parents:
diff changeset
708 //---------------------------opnd_positions_match-------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
709 // Is the use of d1 in u1 at the same operand position as d2 in u2?
a61af66fc99e Initial load
duke
parents:
diff changeset
710 bool SuperWord::opnd_positions_match(Node* d1, Node* u1, Node* d2, Node* u2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
711 uint ct = u1->req();
a61af66fc99e Initial load
duke
parents:
diff changeset
712 if (ct != u2->req()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
713 uint i1 = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
714 uint i2 = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
715 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
716 for (i1++; i1 < ct; i1++) if (u1->in(i1) == d1) break;
a61af66fc99e Initial load
duke
parents:
diff changeset
717 for (i2++; i2 < ct; i2++) if (u2->in(i2) == d2) break;
a61af66fc99e Initial load
duke
parents:
diff changeset
718 if (i1 != i2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
719 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
720 }
a61af66fc99e Initial load
duke
parents:
diff changeset
721 } while (i1 < ct);
a61af66fc99e Initial load
duke
parents:
diff changeset
722 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
723 }
a61af66fc99e Initial load
duke
parents:
diff changeset
724
a61af66fc99e Initial load
duke
parents:
diff changeset
725 //------------------------------est_savings---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
726 // Estimate the savings from executing s1 and s2 as a pack
a61af66fc99e Initial load
duke
parents:
diff changeset
727 int SuperWord::est_savings(Node* s1, Node* s2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
728 int save = 2 - 1; // 2 operations per instruction in packed form
a61af66fc99e Initial load
duke
parents:
diff changeset
729
a61af66fc99e Initial load
duke
parents:
diff changeset
730 // inputs
a61af66fc99e Initial load
duke
parents:
diff changeset
731 for (uint i = 1; i < s1->req(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
732 Node* x1 = s1->in(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
733 Node* x2 = s2->in(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
734 if (x1 != x2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
735 if (are_adjacent_refs(x1, x2)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
736 save += adjacent_profit(x1, x2);
a61af66fc99e Initial load
duke
parents:
diff changeset
737 } else if (!in_packset(x1, x2)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
738 save -= pack_cost(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
739 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
740 save += unpack_cost(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
741 }
a61af66fc99e Initial load
duke
parents:
diff changeset
742 }
a61af66fc99e Initial load
duke
parents:
diff changeset
743 }
a61af66fc99e Initial load
duke
parents:
diff changeset
744
a61af66fc99e Initial load
duke
parents:
diff changeset
745 // uses of result
a61af66fc99e Initial load
duke
parents:
diff changeset
746 uint ct = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
747 for (DUIterator_Fast imax, i = s1->fast_outs(imax); i < imax; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
748 Node* s1_use = s1->fast_out(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
749 for (int j = 0; j < _packset.length(); j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
750 Node_List* p = _packset.at(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
751 if (p->at(0) == s1_use) {
a61af66fc99e Initial load
duke
parents:
diff changeset
752 for (DUIterator_Fast kmax, k = s2->fast_outs(kmax); k < kmax; k++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
753 Node* s2_use = s2->fast_out(k);
a61af66fc99e Initial load
duke
parents:
diff changeset
754 if (p->at(p->size()-1) == s2_use) {
a61af66fc99e Initial load
duke
parents:
diff changeset
755 ct++;
a61af66fc99e Initial load
duke
parents:
diff changeset
756 if (are_adjacent_refs(s1_use, s2_use)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
757 save += adjacent_profit(s1_use, s2_use);
a61af66fc99e Initial load
duke
parents:
diff changeset
758 }
a61af66fc99e Initial load
duke
parents:
diff changeset
759 }
a61af66fc99e Initial load
duke
parents:
diff changeset
760 }
a61af66fc99e Initial load
duke
parents:
diff changeset
761 }
a61af66fc99e Initial load
duke
parents:
diff changeset
762 }
a61af66fc99e Initial load
duke
parents:
diff changeset
763 }
a61af66fc99e Initial load
duke
parents:
diff changeset
764
a61af66fc99e Initial load
duke
parents:
diff changeset
765 if (ct < s1->outcnt()) save += unpack_cost(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
766 if (ct < s2->outcnt()) save += unpack_cost(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
767
a61af66fc99e Initial load
duke
parents:
diff changeset
768 return save;
a61af66fc99e Initial load
duke
parents:
diff changeset
769 }
a61af66fc99e Initial load
duke
parents:
diff changeset
770
a61af66fc99e Initial load
duke
parents:
diff changeset
771 //------------------------------costs---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
772 int SuperWord::adjacent_profit(Node* s1, Node* s2) { return 2; }
a61af66fc99e Initial load
duke
parents:
diff changeset
773 int SuperWord::pack_cost(int ct) { return ct; }
a61af66fc99e Initial load
duke
parents:
diff changeset
774 int SuperWord::unpack_cost(int ct) { return ct; }
a61af66fc99e Initial load
duke
parents:
diff changeset
775
a61af66fc99e Initial load
duke
parents:
diff changeset
776 //------------------------------combine_packs---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
777 // Combine packs A and B with A.last == B.first into A.first..,A.last,B.second,..B.last
a61af66fc99e Initial load
duke
parents:
diff changeset
778 void SuperWord::combine_packs() {
a61af66fc99e Initial load
duke
parents:
diff changeset
779 bool changed;
a61af66fc99e Initial load
duke
parents:
diff changeset
780 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
781 changed = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
782 for (int i = 0; i < _packset.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
783 Node_List* p1 = _packset.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
784 if (p1 == NULL) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
785 for (int j = 0; j < _packset.length(); j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
786 Node_List* p2 = _packset.at(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
787 if (p2 == NULL) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
788 if (p1->at(p1->size()-1) == p2->at(0)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
789 for (uint k = 1; k < p2->size(); k++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
790 p1->push(p2->at(k));
a61af66fc99e Initial load
duke
parents:
diff changeset
791 }
a61af66fc99e Initial load
duke
parents:
diff changeset
792 _packset.at_put(j, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
793 changed = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
794 }
a61af66fc99e Initial load
duke
parents:
diff changeset
795 }
a61af66fc99e Initial load
duke
parents:
diff changeset
796 }
a61af66fc99e Initial load
duke
parents:
diff changeset
797 } while (changed);
a61af66fc99e Initial load
duke
parents:
diff changeset
798
a61af66fc99e Initial load
duke
parents:
diff changeset
799 for (int i = _packset.length() - 1; i >= 0; i--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
800 Node_List* p1 = _packset.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
801 if (p1 == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
802 _packset.remove_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
803 }
a61af66fc99e Initial load
duke
parents:
diff changeset
804 }
a61af66fc99e Initial load
duke
parents:
diff changeset
805
a61af66fc99e Initial load
duke
parents:
diff changeset
806 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
807 if (TraceSuperWord) {
a61af66fc99e Initial load
duke
parents:
diff changeset
808 tty->print_cr("\nAfter combine_packs");
a61af66fc99e Initial load
duke
parents:
diff changeset
809 print_packset();
a61af66fc99e Initial load
duke
parents:
diff changeset
810 }
a61af66fc99e Initial load
duke
parents:
diff changeset
811 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
812 }
a61af66fc99e Initial load
duke
parents:
diff changeset
813
a61af66fc99e Initial load
duke
parents:
diff changeset
814 //-----------------------------construct_my_pack_map--------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
815 // Construct the map from nodes to packs. Only valid after the
a61af66fc99e Initial load
duke
parents:
diff changeset
816 // point where a node is only in one pack (after combine_packs).
a61af66fc99e Initial load
duke
parents:
diff changeset
817 void SuperWord::construct_my_pack_map() {
a61af66fc99e Initial load
duke
parents:
diff changeset
818 Node_List* rslt = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
819 for (int i = 0; i < _packset.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
820 Node_List* p = _packset.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
821 for (uint j = 0; j < p->size(); j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
822 Node* s = p->at(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
823 assert(my_pack(s) == NULL, "only in one pack");
a61af66fc99e Initial load
duke
parents:
diff changeset
824 set_my_pack(s, p);
a61af66fc99e Initial load
duke
parents:
diff changeset
825 }
a61af66fc99e Initial load
duke
parents:
diff changeset
826 }
a61af66fc99e Initial load
duke
parents:
diff changeset
827 }
a61af66fc99e Initial load
duke
parents:
diff changeset
828
a61af66fc99e Initial load
duke
parents:
diff changeset
829 //------------------------------filter_packs---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
830 // Remove packs that are not implemented or not profitable.
a61af66fc99e Initial load
duke
parents:
diff changeset
831 void SuperWord::filter_packs() {
a61af66fc99e Initial load
duke
parents:
diff changeset
832
a61af66fc99e Initial load
duke
parents:
diff changeset
833 // Remove packs that are not implemented
a61af66fc99e Initial load
duke
parents:
diff changeset
834 for (int i = _packset.length() - 1; i >= 0; i--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
835 Node_List* pk = _packset.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
836 bool impl = implemented(pk);
a61af66fc99e Initial load
duke
parents:
diff changeset
837 if (!impl) {
a61af66fc99e Initial load
duke
parents:
diff changeset
838 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
839 if (TraceSuperWord && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
840 tty->print_cr("Unimplemented");
a61af66fc99e Initial load
duke
parents:
diff changeset
841 pk->at(0)->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
842 }
a61af66fc99e Initial load
duke
parents:
diff changeset
843 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
844 remove_pack_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
845 }
a61af66fc99e Initial load
duke
parents:
diff changeset
846 }
a61af66fc99e Initial load
duke
parents:
diff changeset
847
a61af66fc99e Initial load
duke
parents:
diff changeset
848 // Remove packs that are not profitable
a61af66fc99e Initial load
duke
parents:
diff changeset
849 bool changed;
a61af66fc99e Initial load
duke
parents:
diff changeset
850 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
851 changed = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
852 for (int i = _packset.length() - 1; i >= 0; i--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
853 Node_List* pk = _packset.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
854 bool prof = profitable(pk);
a61af66fc99e Initial load
duke
parents:
diff changeset
855 if (!prof) {
a61af66fc99e Initial load
duke
parents:
diff changeset
856 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
857 if (TraceSuperWord && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
858 tty->print_cr("Unprofitable");
a61af66fc99e Initial load
duke
parents:
diff changeset
859 pk->at(0)->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
860 }
a61af66fc99e Initial load
duke
parents:
diff changeset
861 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
862 remove_pack_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
863 changed = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
864 }
a61af66fc99e Initial load
duke
parents:
diff changeset
865 }
a61af66fc99e Initial load
duke
parents:
diff changeset
866 } while (changed);
a61af66fc99e Initial load
duke
parents:
diff changeset
867
a61af66fc99e Initial load
duke
parents:
diff changeset
868 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
869 if (TraceSuperWord) {
a61af66fc99e Initial load
duke
parents:
diff changeset
870 tty->print_cr("\nAfter filter_packs");
a61af66fc99e Initial load
duke
parents:
diff changeset
871 print_packset();
a61af66fc99e Initial load
duke
parents:
diff changeset
872 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
873 }
a61af66fc99e Initial load
duke
parents:
diff changeset
874 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
875 }
a61af66fc99e Initial load
duke
parents:
diff changeset
876
a61af66fc99e Initial load
duke
parents:
diff changeset
877 //------------------------------implemented---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
878 // Can code be generated for pack p?
a61af66fc99e Initial load
duke
parents:
diff changeset
879 bool SuperWord::implemented(Node_List* p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
880 Node* p0 = p->at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
881 int vopc = VectorNode::opcode(p0->Opcode(), p->size(), velt_type(p0));
a61af66fc99e Initial load
duke
parents:
diff changeset
882 return vopc > 0 && Matcher::has_match_rule(vopc);
a61af66fc99e Initial load
duke
parents:
diff changeset
883 }
a61af66fc99e Initial load
duke
parents:
diff changeset
884
a61af66fc99e Initial load
duke
parents:
diff changeset
885 //------------------------------profitable---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
886 // For pack p, are all operands and all uses (with in the block) vector?
a61af66fc99e Initial load
duke
parents:
diff changeset
887 bool SuperWord::profitable(Node_List* p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
888 Node* p0 = p->at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
889 uint start, end;
a61af66fc99e Initial load
duke
parents:
diff changeset
890 vector_opd_range(p0, &start, &end);
a61af66fc99e Initial load
duke
parents:
diff changeset
891
a61af66fc99e Initial load
duke
parents:
diff changeset
892 // Return false if some input is not vector and inside block
a61af66fc99e Initial load
duke
parents:
diff changeset
893 for (uint i = start; i < end; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
894 if (!is_vector_use(p0, i)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
895 // For now, return false if not scalar promotion case (inputs are the same.)
605
98cb887364d3 6810672: Comment typos
twisti
parents: 558
diff changeset
896 // Later, implement PackNode and allow differing, non-vector inputs
0
a61af66fc99e Initial load
duke
parents:
diff changeset
897 // (maybe just the ones from outside the block.)
a61af66fc99e Initial load
duke
parents:
diff changeset
898 Node* p0_def = p0->in(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
899 for (uint j = 1; j < p->size(); j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
900 Node* use = p->at(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
901 Node* def = use->in(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
902 if (p0_def != def)
a61af66fc99e Initial load
duke
parents:
diff changeset
903 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
904 }
a61af66fc99e Initial load
duke
parents:
diff changeset
905 }
a61af66fc99e Initial load
duke
parents:
diff changeset
906 }
a61af66fc99e Initial load
duke
parents:
diff changeset
907 if (!p0->is_Store()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
908 // For now, return false if not all uses are vector.
a61af66fc99e Initial load
duke
parents:
diff changeset
909 // Later, implement ExtractNode and allow non-vector uses (maybe
a61af66fc99e Initial load
duke
parents:
diff changeset
910 // just the ones outside the block.)
a61af66fc99e Initial load
duke
parents:
diff changeset
911 for (uint i = 0; i < p->size(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
912 Node* def = p->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
913 for (DUIterator_Fast jmax, j = def->fast_outs(jmax); j < jmax; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
914 Node* use = def->fast_out(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
915 for (uint k = 0; k < use->req(); k++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
916 Node* n = use->in(k);
a61af66fc99e Initial load
duke
parents:
diff changeset
917 if (def == n) {
a61af66fc99e Initial load
duke
parents:
diff changeset
918 if (!is_vector_use(use, k)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
919 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
920 }
a61af66fc99e Initial load
duke
parents:
diff changeset
921 }
a61af66fc99e Initial load
duke
parents:
diff changeset
922 }
a61af66fc99e Initial load
duke
parents:
diff changeset
923 }
a61af66fc99e Initial load
duke
parents:
diff changeset
924 }
a61af66fc99e Initial load
duke
parents:
diff changeset
925 }
a61af66fc99e Initial load
duke
parents:
diff changeset
926 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
927 }
a61af66fc99e Initial load
duke
parents:
diff changeset
928
a61af66fc99e Initial load
duke
parents:
diff changeset
929 //------------------------------schedule---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
930 // Adjust the memory graph for the packed operations
a61af66fc99e Initial load
duke
parents:
diff changeset
931 void SuperWord::schedule() {
a61af66fc99e Initial load
duke
parents:
diff changeset
932
a61af66fc99e Initial load
duke
parents:
diff changeset
933 // Co-locate in the memory graph the members of each memory pack
a61af66fc99e Initial load
duke
parents:
diff changeset
934 for (int i = 0; i < _packset.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
935 co_locate_pack(_packset.at(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
936 }
a61af66fc99e Initial load
duke
parents:
diff changeset
937 }
a61af66fc99e Initial load
duke
parents:
diff changeset
938
667
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
939 //-------------------------------remove_and_insert-------------------
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
940 //remove "current" from its current position in the memory graph and insert
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
941 //it after the appropriate insertion point (lip or uip)
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
942 void SuperWord::remove_and_insert(MemNode *current, MemNode *prev, MemNode *lip,
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
943 Node *uip, Unique_Node_List &sched_before) {
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
944 Node* my_mem = current->in(MemNode::Memory);
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
945 _igvn.hash_delete(current);
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
946 _igvn.hash_delete(my_mem);
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
947
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
948 //remove current_store from its current position in the memmory graph
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
949 for (DUIterator i = current->outs(); current->has_out(i); i++) {
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
950 Node* use = current->out(i);
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
951 if (use->is_Mem()) {
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
952 assert(use->in(MemNode::Memory) == current, "must be");
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
953 _igvn.hash_delete(use);
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
954 if (use == prev) { // connect prev to my_mem
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
955 use->set_req(MemNode::Memory, my_mem);
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
956 } else if (sched_before.member(use)) {
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
957 _igvn.hash_delete(uip);
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
958 use->set_req(MemNode::Memory, uip);
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
959 } else {
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
960 _igvn.hash_delete(lip);
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
961 use->set_req(MemNode::Memory, lip);
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
962 }
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
963 _igvn._worklist.push(use);
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
964 --i; //deleted this edge; rescan position
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
965 }
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
966 }
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
967
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
968 bool sched_up = sched_before.member(current);
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
969 Node *insert_pt = sched_up ? uip : lip;
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
970 _igvn.hash_delete(insert_pt);
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
971
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
972 // all uses of insert_pt's memory state should use current's instead
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
973 for (DUIterator i = insert_pt->outs(); insert_pt->has_out(i); i++) {
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
974 Node* use = insert_pt->out(i);
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
975 if (use->is_Mem()) {
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
976 assert(use->in(MemNode::Memory) == insert_pt, "must be");
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
977 _igvn.hash_delete(use);
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
978 use->set_req(MemNode::Memory, current);
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
979 _igvn._worklist.push(use);
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
980 --i; //deleted this edge; rescan position
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
981 } else if (!sched_up && use->is_Phi() && use->bottom_type() == Type::MEMORY) {
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
982 uint pos; //lip (lower insert point) must be the last one in the memory slice
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
983 _igvn.hash_delete(use);
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
984 for (pos=1; pos < use->req(); pos++) {
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
985 if (use->in(pos) == insert_pt) break;
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
986 }
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
987 use->set_req(pos, current);
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
988 _igvn._worklist.push(use);
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
989 --i;
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
990 }
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
991 }
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
992
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
993 //connect current to insert_pt
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
994 current->set_req(MemNode::Memory, insert_pt);
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
995 _igvn._worklist.push(current);
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
996 }
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
997
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
998 //------------------------------co_locate_pack----------------------------------
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
999 // To schedule a store pack, we need to move any sandwiched memory ops either before
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1000 // or after the pack, based upon dependence information:
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1001 // (1) If any store in the pack depends on the sandwiched memory op, the
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1002 // sandwiched memory op must be scheduled BEFORE the pack;
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1003 // (2) If a sandwiched memory op depends on any store in the pack, the
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1004 // sandwiched memory op must be scheduled AFTER the pack;
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1005 // (3) If a sandwiched memory op (say, memA) depends on another sandwiched
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1006 // memory op (say memB), memB must be scheduled before memA. So, if memA is
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1007 // scheduled before the pack, memB must also be scheduled before the pack;
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1008 // (4) If there is no dependence restriction for a sandwiched memory op, we simply
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1009 // schedule this store AFTER the pack
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1010 // (5) We know there is no dependence cycle, so there in no other case;
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1011 // (6) Finally, all memory ops in another single pack should be moved in the same direction.
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1012 //
952
ace8397c8563 6876276: assert(!is_visited,"visit only once")
cfang
parents: 667
diff changeset
1013 // To schedule a load pack, we use the memory state of either the first or the last load in
ace8397c8563 6876276: assert(!is_visited,"visit only once")
cfang
parents: 667
diff changeset
1014 // the pack, based on the dependence constraint.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 void SuperWord::co_locate_pack(Node_List* pk) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 if (pk->at(0)->is_Store()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 MemNode* first = executed_first(pk)->as_Mem();
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 MemNode* last = executed_last(pk)->as_Mem();
667
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1019 Unique_Node_List schedule_before_pack;
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1020 Unique_Node_List memops;
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1021
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 MemNode* current = last->in(MemNode::Memory)->as_Mem();
667
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1023 MemNode* previous = last;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 while (true) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 assert(in_bb(current), "stay in block");
667
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1026 memops.push(previous);
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1027 for (DUIterator i = current->outs(); current->has_out(i); i++) {
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1028 Node* use = current->out(i);
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1029 if (use->is_Mem() && use != previous)
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1030 memops.push(use);
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1031 }
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1032 if(current == first) break;
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1033 previous = current;
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1034 current = current->in(MemNode::Memory)->as_Mem();
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1035 }
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1036
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1037 // determine which memory operations should be scheduled before the pack
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1038 for (uint i = 1; i < memops.size(); i++) {
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1039 Node *s1 = memops.at(i);
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1040 if (!in_pack(s1, pk) && !schedule_before_pack.member(s1)) {
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1041 for (uint j = 0; j< i; j++) {
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1042 Node *s2 = memops.at(j);
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1043 if (!independent(s1, s2)) {
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1044 if (in_pack(s2, pk) || schedule_before_pack.member(s2)) {
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1045 schedule_before_pack.push(s1); //s1 must be scheduled before
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1046 Node_List* mem_pk = my_pack(s1);
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1047 if (mem_pk != NULL) {
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1048 for (uint ii = 0; ii < mem_pk->size(); ii++) {
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1049 Node* s = mem_pk->at(ii); // follow partner
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1050 if (memops.member(s) && !schedule_before_pack.member(s))
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1051 schedule_before_pack.push(s);
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1052 }
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1053 }
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1054 }
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1055 }
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1056 }
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1057 }
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1058 }
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1059
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1060 MemNode* lower_insert_pt = last;
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1061 Node* upper_insert_pt = first->in(MemNode::Memory);
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1062 previous = last; //previous store in pk
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1063 current = last->in(MemNode::Memory)->as_Mem();
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1064
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1065 //start scheduling from "last" to "first"
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1066 while (true) {
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1067 assert(in_bb(current), "stay in block");
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1068 assert(in_pack(previous, pk), "previous stays in pack");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 Node* my_mem = current->in(MemNode::Memory);
667
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1070
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 if (in_pack(current, pk)) {
667
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1072 // Forward users of my memory state (except "previous) to my input memory state
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1073 _igvn.hash_delete(current);
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 for (DUIterator i = current->outs(); current->has_out(i); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 Node* use = current->out(i);
667
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1076 if (use->is_Mem() && use != previous) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1077 assert(use->in(MemNode::Memory) == current, "must be");
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 _igvn.hash_delete(use);
667
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1079 if (schedule_before_pack.member(use)) {
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1080 _igvn.hash_delete(upper_insert_pt);
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1081 use->set_req(MemNode::Memory, upper_insert_pt);
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1082 } else {
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1083 _igvn.hash_delete(lower_insert_pt);
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1084 use->set_req(MemNode::Memory, lower_insert_pt);
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1085 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 _igvn._worklist.push(use);
a61af66fc99e Initial load
duke
parents:
diff changeset
1087 --i; // deleted this edge; rescan position
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1089 }
667
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1090 previous = current;
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1091 } else { // !in_pack(current, pk) ==> a sandwiched store
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1092 remove_and_insert(current, previous, lower_insert_pt, upper_insert_pt, schedule_before_pack);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1093 }
667
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1094
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 if (current == first) break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1096 current = my_mem->as_Mem();
667
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1097 } // end while
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 628
diff changeset
1098 } else if (pk->at(0)->is_Load()) { //load
952
ace8397c8563 6876276: assert(!is_visited,"visit only once")
cfang
parents: 667
diff changeset
1099 // all loads in the pack should have the same memory state. By default,
ace8397c8563 6876276: assert(!is_visited,"visit only once")
cfang
parents: 667
diff changeset
1100 // we use the memory state of the last load. However, if any load could
ace8397c8563 6876276: assert(!is_visited,"visit only once")
cfang
parents: 667
diff changeset
1101 // not be moved down due to the dependence constraint, we use the memory
ace8397c8563 6876276: assert(!is_visited,"visit only once")
cfang
parents: 667
diff changeset
1102 // state of the first load.
ace8397c8563 6876276: assert(!is_visited,"visit only once")
cfang
parents: 667
diff changeset
1103 Node* last_mem = executed_last(pk)->in(MemNode::Memory);
ace8397c8563 6876276: assert(!is_visited,"visit only once")
cfang
parents: 667
diff changeset
1104 Node* first_mem = executed_first(pk)->in(MemNode::Memory);
ace8397c8563 6876276: assert(!is_visited,"visit only once")
cfang
parents: 667
diff changeset
1105 bool schedule_last = true;
ace8397c8563 6876276: assert(!is_visited,"visit only once")
cfang
parents: 667
diff changeset
1106 for (uint i = 0; i < pk->size(); i++) {
ace8397c8563 6876276: assert(!is_visited,"visit only once")
cfang
parents: 667
diff changeset
1107 Node* ld = pk->at(i);
ace8397c8563 6876276: assert(!is_visited,"visit only once")
cfang
parents: 667
diff changeset
1108 for (Node* current = last_mem; current != ld->in(MemNode::Memory);
ace8397c8563 6876276: assert(!is_visited,"visit only once")
cfang
parents: 667
diff changeset
1109 current=current->in(MemNode::Memory)) {
ace8397c8563 6876276: assert(!is_visited,"visit only once")
cfang
parents: 667
diff changeset
1110 assert(current != first_mem, "corrupted memory graph");
ace8397c8563 6876276: assert(!is_visited,"visit only once")
cfang
parents: 667
diff changeset
1111 if(current->is_Mem() && !independent(current, ld)){
ace8397c8563 6876276: assert(!is_visited,"visit only once")
cfang
parents: 667
diff changeset
1112 schedule_last = false; // a later store depends on this load
ace8397c8563 6876276: assert(!is_visited,"visit only once")
cfang
parents: 667
diff changeset
1113 break;
ace8397c8563 6876276: assert(!is_visited,"visit only once")
cfang
parents: 667
diff changeset
1114 }
ace8397c8563 6876276: assert(!is_visited,"visit only once")
cfang
parents: 667
diff changeset
1115 }
ace8397c8563 6876276: assert(!is_visited,"visit only once")
cfang
parents: 667
diff changeset
1116 }
ace8397c8563 6876276: assert(!is_visited,"visit only once")
cfang
parents: 667
diff changeset
1117
ace8397c8563 6876276: assert(!is_visited,"visit only once")
cfang
parents: 667
diff changeset
1118 Node* mem_input = schedule_last ? last_mem : first_mem;
ace8397c8563 6876276: assert(!is_visited,"visit only once")
cfang
parents: 667
diff changeset
1119 _igvn.hash_delete(mem_input);
ace8397c8563 6876276: assert(!is_visited,"visit only once")
cfang
parents: 667
diff changeset
1120 // Give each load the same memory state
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 for (uint i = 0; i < pk->size(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1122 LoadNode* ld = pk->at(i)->as_Load();
a61af66fc99e Initial load
duke
parents:
diff changeset
1123 _igvn.hash_delete(ld);
952
ace8397c8563 6876276: assert(!is_visited,"visit only once")
cfang
parents: 667
diff changeset
1124 ld->set_req(MemNode::Memory, mem_input);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1125 _igvn._worklist.push(ld);
a61af66fc99e Initial load
duke
parents:
diff changeset
1126 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1128 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1129
a61af66fc99e Initial load
duke
parents:
diff changeset
1130 //------------------------------output---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 // Convert packs into vector node operations
a61af66fc99e Initial load
duke
parents:
diff changeset
1132 void SuperWord::output() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1133 if (_packset.length() == 0) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1134
a61af66fc99e Initial load
duke
parents:
diff changeset
1135 // MUST ENSURE main loop's initial value is properly aligned:
a61af66fc99e Initial load
duke
parents:
diff changeset
1136 // (iv_initial_value + min_iv_offset) % vector_width_in_bytes() == 0
a61af66fc99e Initial load
duke
parents:
diff changeset
1137
a61af66fc99e Initial load
duke
parents:
diff changeset
1138 align_initial_loop_index(align_to_ref());
a61af66fc99e Initial load
duke
parents:
diff changeset
1139
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 // Insert extract (unpack) operations for scalar uses
a61af66fc99e Initial load
duke
parents:
diff changeset
1141 for (int i = 0; i < _packset.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1142 insert_extracts(_packset.at(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1144
a61af66fc99e Initial load
duke
parents:
diff changeset
1145 for (int i = 0; i < _block.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1146 Node* n = _block.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 Node_List* p = my_pack(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
1148 if (p && n == executed_last(p)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1149 uint vlen = p->size();
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 Node* vn = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1151 Node* low_adr = p->at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1152 Node* first = executed_first(p);
a61af66fc99e Initial load
duke
parents:
diff changeset
1153 if (n->is_Load()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1154 int opc = n->Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
1155 Node* ctl = n->in(MemNode::Control);
a61af66fc99e Initial load
duke
parents:
diff changeset
1156 Node* mem = first->in(MemNode::Memory);
a61af66fc99e Initial load
duke
parents:
diff changeset
1157 Node* adr = low_adr->in(MemNode::Address);
a61af66fc99e Initial load
duke
parents:
diff changeset
1158 const TypePtr* atyp = n->adr_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 vn = VectorLoadNode::make(_phase->C, opc, ctl, mem, adr, atyp, vlen);
a61af66fc99e Initial load
duke
parents:
diff changeset
1160
a61af66fc99e Initial load
duke
parents:
diff changeset
1161 } else if (n->is_Store()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1162 // Promote value to be stored to vector
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 VectorNode* val = vector_opd(p, MemNode::ValueIn);
a61af66fc99e Initial load
duke
parents:
diff changeset
1164
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 int opc = n->Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
1166 Node* ctl = n->in(MemNode::Control);
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 Node* mem = first->in(MemNode::Memory);
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 Node* adr = low_adr->in(MemNode::Address);
a61af66fc99e Initial load
duke
parents:
diff changeset
1169 const TypePtr* atyp = n->adr_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1170 vn = VectorStoreNode::make(_phase->C, opc, ctl, mem, adr, atyp, val, vlen);
a61af66fc99e Initial load
duke
parents:
diff changeset
1171
a61af66fc99e Initial load
duke
parents:
diff changeset
1172 } else if (n->req() == 3) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1173 // Promote operands to vector
a61af66fc99e Initial load
duke
parents:
diff changeset
1174 Node* in1 = vector_opd(p, 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1175 Node* in2 = vector_opd(p, 2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1176 vn = VectorNode::make(_phase->C, n->Opcode(), in1, in2, vlen, velt_type(n));
a61af66fc99e Initial load
duke
parents:
diff changeset
1177
a61af66fc99e Initial load
duke
parents:
diff changeset
1178 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1179 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1181
a61af66fc99e Initial load
duke
parents:
diff changeset
1182 _phase->_igvn.register_new_node_with_optimizer(vn);
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 _phase->set_ctrl(vn, _phase->get_ctrl(p->at(0)));
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 for (uint j = 0; j < p->size(); j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1185 Node* pm = p->at(j);
1621
6027dddc26c6 6677629: PhaseIterGVN::subsume_node() should call hash_delete() and add_users_to_worklist()
kvn
parents: 1585
diff changeset
1186 _igvn.replace_node(pm, vn);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1187 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1188 _igvn._worklist.push(vn);
a61af66fc99e Initial load
duke
parents:
diff changeset
1189 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1190 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1192
a61af66fc99e Initial load
duke
parents:
diff changeset
1193 //------------------------------vector_opd---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1194 // Create a vector operand for the nodes in pack p for operand: in(opd_idx)
a61af66fc99e Initial load
duke
parents:
diff changeset
1195 VectorNode* SuperWord::vector_opd(Node_List* p, int opd_idx) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1196 Node* p0 = p->at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1197 uint vlen = p->size();
a61af66fc99e Initial load
duke
parents:
diff changeset
1198 Node* opd = p0->in(opd_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1199
a61af66fc99e Initial load
duke
parents:
diff changeset
1200 bool same_opd = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1201 for (uint i = 1; i < vlen; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1202 Node* pi = p->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1203 Node* in = pi->in(opd_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1204 if (opd != in) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1205 same_opd = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1206 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1207 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1208 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1209
a61af66fc99e Initial load
duke
parents:
diff changeset
1210 if (same_opd) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1211 if (opd->is_Vector()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1212 return (VectorNode*)opd; // input is matching vector
a61af66fc99e Initial load
duke
parents:
diff changeset
1213 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1214 // Convert scalar input to vector. Use p0's type because it's container
a61af66fc99e Initial load
duke
parents:
diff changeset
1215 // maybe smaller than the operand's container.
a61af66fc99e Initial load
duke
parents:
diff changeset
1216 const Type* opd_t = velt_type(!in_bb(opd) ? p0 : opd);
a61af66fc99e Initial load
duke
parents:
diff changeset
1217 const Type* p0_t = velt_type(p0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1218 if (p0_t->higher_equal(opd_t)) opd_t = p0_t;
a61af66fc99e Initial load
duke
parents:
diff changeset
1219 VectorNode* vn = VectorNode::scalar2vector(_phase->C, opd, vlen, opd_t);
a61af66fc99e Initial load
duke
parents:
diff changeset
1220
a61af66fc99e Initial load
duke
parents:
diff changeset
1221 _phase->_igvn.register_new_node_with_optimizer(vn);
a61af66fc99e Initial load
duke
parents:
diff changeset
1222 _phase->set_ctrl(vn, _phase->get_ctrl(opd));
a61af66fc99e Initial load
duke
parents:
diff changeset
1223 return vn;
a61af66fc99e Initial load
duke
parents:
diff changeset
1224 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1225
a61af66fc99e Initial load
duke
parents:
diff changeset
1226 // Insert pack operation
a61af66fc99e Initial load
duke
parents:
diff changeset
1227 const Type* opd_t = velt_type(!in_bb(opd) ? p0 : opd);
a61af66fc99e Initial load
duke
parents:
diff changeset
1228 PackNode* pk = PackNode::make(_phase->C, opd, opd_t);
a61af66fc99e Initial load
duke
parents:
diff changeset
1229
a61af66fc99e Initial load
duke
parents:
diff changeset
1230 for (uint i = 1; i < vlen; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1231 Node* pi = p->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1232 Node* in = pi->in(opd_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1233 assert(my_pack(in) == NULL, "Should already have been unpacked");
a61af66fc99e Initial load
duke
parents:
diff changeset
1234 assert(opd_t == velt_type(!in_bb(in) ? pi : in), "all same type");
a61af66fc99e Initial load
duke
parents:
diff changeset
1235 pk->add_opd(in);
a61af66fc99e Initial load
duke
parents:
diff changeset
1236 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1237 _phase->_igvn.register_new_node_with_optimizer(pk);
a61af66fc99e Initial load
duke
parents:
diff changeset
1238 _phase->set_ctrl(pk, _phase->get_ctrl(opd));
a61af66fc99e Initial load
duke
parents:
diff changeset
1239 return pk;
a61af66fc99e Initial load
duke
parents:
diff changeset
1240 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1241
a61af66fc99e Initial load
duke
parents:
diff changeset
1242 //------------------------------insert_extracts---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1243 // If a use of pack p is not a vector use, then replace the
a61af66fc99e Initial load
duke
parents:
diff changeset
1244 // use with an extract operation.
a61af66fc99e Initial load
duke
parents:
diff changeset
1245 void SuperWord::insert_extracts(Node_List* p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1246 if (p->at(0)->is_Store()) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1247 assert(_n_idx_list.is_empty(), "empty (node,index) list");
a61af66fc99e Initial load
duke
parents:
diff changeset
1248
a61af66fc99e Initial load
duke
parents:
diff changeset
1249 // Inspect each use of each pack member. For each use that is
a61af66fc99e Initial load
duke
parents:
diff changeset
1250 // not a vector use, replace the use with an extract operation.
a61af66fc99e Initial load
duke
parents:
diff changeset
1251
a61af66fc99e Initial load
duke
parents:
diff changeset
1252 for (uint i = 0; i < p->size(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1253 Node* def = p->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 for (DUIterator_Fast jmax, j = def->fast_outs(jmax); j < jmax; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1255 Node* use = def->fast_out(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
1256 for (uint k = 0; k < use->req(); k++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1257 Node* n = use->in(k);
a61af66fc99e Initial load
duke
parents:
diff changeset
1258 if (def == n) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1259 if (!is_vector_use(use, k)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1260 _n_idx_list.push(use, k);
a61af66fc99e Initial load
duke
parents:
diff changeset
1261 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1262 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1263 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1264 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1266
a61af66fc99e Initial load
duke
parents:
diff changeset
1267 while (_n_idx_list.is_nonempty()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1268 Node* use = _n_idx_list.node();
a61af66fc99e Initial load
duke
parents:
diff changeset
1269 int idx = _n_idx_list.index();
a61af66fc99e Initial load
duke
parents:
diff changeset
1270 _n_idx_list.pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1271 Node* def = use->in(idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1272
a61af66fc99e Initial load
duke
parents:
diff changeset
1273 // Insert extract operation
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 _igvn.hash_delete(def);
a61af66fc99e Initial load
duke
parents:
diff changeset
1275 _igvn.hash_delete(use);
a61af66fc99e Initial load
duke
parents:
diff changeset
1276 int def_pos = alignment(def) / data_size(def);
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 const Type* def_t = velt_type(def);
a61af66fc99e Initial load
duke
parents:
diff changeset
1278
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 Node* ex = ExtractNode::make(_phase->C, def, def_pos, def_t);
a61af66fc99e Initial load
duke
parents:
diff changeset
1280 _phase->_igvn.register_new_node_with_optimizer(ex);
a61af66fc99e Initial load
duke
parents:
diff changeset
1281 _phase->set_ctrl(ex, _phase->get_ctrl(def));
a61af66fc99e Initial load
duke
parents:
diff changeset
1282 use->set_req(idx, ex);
a61af66fc99e Initial load
duke
parents:
diff changeset
1283 _igvn._worklist.push(def);
a61af66fc99e Initial load
duke
parents:
diff changeset
1284 _igvn._worklist.push(use);
a61af66fc99e Initial load
duke
parents:
diff changeset
1285
a61af66fc99e Initial load
duke
parents:
diff changeset
1286 bb_insert_after(ex, bb_idx(def));
a61af66fc99e Initial load
duke
parents:
diff changeset
1287 set_velt_type(ex, def_t);
a61af66fc99e Initial load
duke
parents:
diff changeset
1288 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1289 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1290
a61af66fc99e Initial load
duke
parents:
diff changeset
1291 //------------------------------is_vector_use---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1292 // Is use->in(u_idx) a vector use?
a61af66fc99e Initial load
duke
parents:
diff changeset
1293 bool SuperWord::is_vector_use(Node* use, int u_idx) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1294 Node_List* u_pk = my_pack(use);
a61af66fc99e Initial load
duke
parents:
diff changeset
1295 if (u_pk == NULL) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1296 Node* def = use->in(u_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1297 Node_List* d_pk = my_pack(def);
a61af66fc99e Initial load
duke
parents:
diff changeset
1298 if (d_pk == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1299 // check for scalar promotion
a61af66fc99e Initial load
duke
parents:
diff changeset
1300 Node* n = u_pk->at(0)->in(u_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1301 for (uint i = 1; i < u_pk->size(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1302 if (u_pk->at(i)->in(u_idx) != n) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1303 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1304 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1305 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1306 if (u_pk->size() != d_pk->size())
a61af66fc99e Initial load
duke
parents:
diff changeset
1307 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1308 for (uint i = 0; i < u_pk->size(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1309 Node* ui = u_pk->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1310 Node* di = d_pk->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1311 if (ui->in(u_idx) != di || alignment(ui) != alignment(di))
a61af66fc99e Initial load
duke
parents:
diff changeset
1312 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1313 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1314 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1315 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1316
a61af66fc99e Initial load
duke
parents:
diff changeset
1317 //------------------------------construct_bb---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1318 // Construct reverse postorder list of block members
a61af66fc99e Initial load
duke
parents:
diff changeset
1319 void SuperWord::construct_bb() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1320 Node* entry = bb();
a61af66fc99e Initial load
duke
parents:
diff changeset
1321
a61af66fc99e Initial load
duke
parents:
diff changeset
1322 assert(_stk.length() == 0, "stk is empty");
a61af66fc99e Initial load
duke
parents:
diff changeset
1323 assert(_block.length() == 0, "block is empty");
a61af66fc99e Initial load
duke
parents:
diff changeset
1324 assert(_data_entry.length() == 0, "data_entry is empty");
a61af66fc99e Initial load
duke
parents:
diff changeset
1325 assert(_mem_slice_head.length() == 0, "mem_slice_head is empty");
a61af66fc99e Initial load
duke
parents:
diff changeset
1326 assert(_mem_slice_tail.length() == 0, "mem_slice_tail is empty");
a61af66fc99e Initial load
duke
parents:
diff changeset
1327
a61af66fc99e Initial load
duke
parents:
diff changeset
1328 // Find non-control nodes with no inputs from within block,
a61af66fc99e Initial load
duke
parents:
diff changeset
1329 // create a temporary map from node _idx to bb_idx for use
a61af66fc99e Initial load
duke
parents:
diff changeset
1330 // by the visited and post_visited sets,
a61af66fc99e Initial load
duke
parents:
diff changeset
1331 // and count number of nodes in block.
a61af66fc99e Initial load
duke
parents:
diff changeset
1332 int bb_ct = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1333 for (uint i = 0; i < lpt()->_body.size(); i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1334 Node *n = lpt()->_body.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1335 set_bb_idx(n, i); // Create a temporary map
a61af66fc99e Initial load
duke
parents:
diff changeset
1336 if (in_bb(n)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1337 bb_ct++;
a61af66fc99e Initial load
duke
parents:
diff changeset
1338 if (!n->is_CFG()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1339 bool found = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1340 for (uint j = 0; j < n->req(); j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1341 Node* def = n->in(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
1342 if (def && in_bb(def)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1343 found = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1344 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1345 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1346 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1347 if (!found) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1348 assert(n != entry, "can't be entry");
a61af66fc99e Initial load
duke
parents:
diff changeset
1349 _data_entry.push(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
1350 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1351 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1352 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1353 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1354
a61af66fc99e Initial load
duke
parents:
diff changeset
1355 // Find memory slices (head and tail)
a61af66fc99e Initial load
duke
parents:
diff changeset
1356 for (DUIterator_Fast imax, i = lp()->fast_outs(imax); i < imax; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1357 Node *n = lp()->fast_out(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1358 if (in_bb(n) && (n->is_Phi() && n->bottom_type() == Type::MEMORY)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1359 Node* n_tail = n->in(LoopNode::LoopBackControl);
253
b0fe4deeb9fb 6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents: 235
diff changeset
1360 if (n_tail != n->in(LoopNode::EntryControl)) {
b0fe4deeb9fb 6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents: 235
diff changeset
1361 _mem_slice_head.push(n);
b0fe4deeb9fb 6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents: 235
diff changeset
1362 _mem_slice_tail.push(n_tail);
b0fe4deeb9fb 6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents: 235
diff changeset
1363 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1364 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1365 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1366
a61af66fc99e Initial load
duke
parents:
diff changeset
1367 // Create an RPO list of nodes in block
a61af66fc99e Initial load
duke
parents:
diff changeset
1368
a61af66fc99e Initial load
duke
parents:
diff changeset
1369 visited_clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
1370 post_visited_clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
1371
a61af66fc99e Initial load
duke
parents:
diff changeset
1372 // Push all non-control nodes with no inputs from within block, then control entry
a61af66fc99e Initial load
duke
parents:
diff changeset
1373 for (int j = 0; j < _data_entry.length(); j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1374 Node* n = _data_entry.at(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
1375 visited_set(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
1376 _stk.push(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
1377 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1378 visited_set(entry);
a61af66fc99e Initial load
duke
parents:
diff changeset
1379 _stk.push(entry);
a61af66fc99e Initial load
duke
parents:
diff changeset
1380
a61af66fc99e Initial load
duke
parents:
diff changeset
1381 // Do a depth first walk over out edges
a61af66fc99e Initial load
duke
parents:
diff changeset
1382 int rpo_idx = bb_ct - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1383 int size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1384 while ((size = _stk.length()) > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1385 Node* n = _stk.top(); // Leave node on stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1386 if (!visited_test_set(n)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1387 // forward arc in graph
a61af66fc99e Initial load
duke
parents:
diff changeset
1388 } else if (!post_visited_test(n)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1389 // cross or back arc
a61af66fc99e Initial load
duke
parents:
diff changeset
1390 for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1391 Node *use = n->fast_out(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1392 if (in_bb(use) && !visited_test(use) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1393 // Don't go around backedge
a61af66fc99e Initial load
duke
parents:
diff changeset
1394 (!use->is_Phi() || n == entry)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1395 _stk.push(use);
a61af66fc99e Initial load
duke
parents:
diff changeset
1396 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1397 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1398 if (_stk.length() == size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1399 // There were no additional uses, post visit node now
a61af66fc99e Initial load
duke
parents:
diff changeset
1400 _stk.pop(); // Remove node from stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1401 assert(rpo_idx >= 0, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1402 _block.at_put_grow(rpo_idx, n);
a61af66fc99e Initial load
duke
parents:
diff changeset
1403 rpo_idx--;
a61af66fc99e Initial load
duke
parents:
diff changeset
1404 post_visited_set(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
1405 assert(rpo_idx >= 0 || _stk.is_empty(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1406 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1407 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1408 _stk.pop(); // Remove post-visited node from stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1409 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1410 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1411
a61af66fc99e Initial load
duke
parents:
diff changeset
1412 // Create real map of block indices for nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
1413 for (int j = 0; j < _block.length(); j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1414 Node* n = _block.at(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
1415 set_bb_idx(n, j);
a61af66fc99e Initial load
duke
parents:
diff changeset
1416 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1417
a61af66fc99e Initial load
duke
parents:
diff changeset
1418 initialize_bb(); // Ensure extra info is allocated.
a61af66fc99e Initial load
duke
parents:
diff changeset
1419
a61af66fc99e Initial load
duke
parents:
diff changeset
1420 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1421 if (TraceSuperWord) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1422 print_bb();
a61af66fc99e Initial load
duke
parents:
diff changeset
1423 tty->print_cr("\ndata entry nodes: %s", _data_entry.length() > 0 ? "" : "NONE");
a61af66fc99e Initial load
duke
parents:
diff changeset
1424 for (int m = 0; m < _data_entry.length(); m++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1425 tty->print("%3d ", m);
a61af66fc99e Initial load
duke
parents:
diff changeset
1426 _data_entry.at(m)->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1427 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1428 tty->print_cr("\nmemory slices: %s", _mem_slice_head.length() > 0 ? "" : "NONE");
a61af66fc99e Initial load
duke
parents:
diff changeset
1429 for (int m = 0; m < _mem_slice_head.length(); m++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1430 tty->print("%3d ", m); _mem_slice_head.at(m)->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1431 tty->print(" "); _mem_slice_tail.at(m)->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1432 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1433 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1434 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1435 assert(rpo_idx == -1 && bb_ct == _block.length(), "all block members found");
a61af66fc99e Initial load
duke
parents:
diff changeset
1436 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1437
a61af66fc99e Initial load
duke
parents:
diff changeset
1438 //------------------------------initialize_bb---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1439 // Initialize per node info
a61af66fc99e Initial load
duke
parents:
diff changeset
1440 void SuperWord::initialize_bb() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1441 Node* last = _block.at(_block.length() - 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1442 grow_node_info(bb_idx(last));
a61af66fc99e Initial load
duke
parents:
diff changeset
1443 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1444
a61af66fc99e Initial load
duke
parents:
diff changeset
1445 //------------------------------bb_insert_after---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1446 // Insert n into block after pos
a61af66fc99e Initial load
duke
parents:
diff changeset
1447 void SuperWord::bb_insert_after(Node* n, int pos) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1448 int n_pos = pos + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1449 // Make room
a61af66fc99e Initial load
duke
parents:
diff changeset
1450 for (int i = _block.length() - 1; i >= n_pos; i--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1451 _block.at_put_grow(i+1, _block.at(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
1452 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1453 for (int j = _node_info.length() - 1; j >= n_pos; j--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1454 _node_info.at_put_grow(j+1, _node_info.at(j));
a61af66fc99e Initial load
duke
parents:
diff changeset
1455 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1456 // Set value
a61af66fc99e Initial load
duke
parents:
diff changeset
1457 _block.at_put_grow(n_pos, n);
a61af66fc99e Initial load
duke
parents:
diff changeset
1458 _node_info.at_put_grow(n_pos, SWNodeInfo::initial);
a61af66fc99e Initial load
duke
parents:
diff changeset
1459 // Adjust map from node->_idx to _block index
a61af66fc99e Initial load
duke
parents:
diff changeset
1460 for (int i = n_pos; i < _block.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1461 set_bb_idx(_block.at(i), i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1462 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1463 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1464
a61af66fc99e Initial load
duke
parents:
diff changeset
1465 //------------------------------compute_max_depth---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1466 // Compute max depth for expressions from beginning of block
a61af66fc99e Initial load
duke
parents:
diff changeset
1467 // Use to prune search paths during test for independence.
a61af66fc99e Initial load
duke
parents:
diff changeset
1468 void SuperWord::compute_max_depth() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1469 int ct = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1470 bool again;
a61af66fc99e Initial load
duke
parents:
diff changeset
1471 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
1472 again = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1473 for (int i = 0; i < _block.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1474 Node* n = _block.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1475 if (!n->is_Phi()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1476 int d_orig = depth(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
1477 int d_in = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1478 for (DepPreds preds(n, _dg); !preds.done(); preds.next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1479 Node* pred = preds.current();
a61af66fc99e Initial load
duke
parents:
diff changeset
1480 if (in_bb(pred)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1481 d_in = MAX2(d_in, depth(pred));
a61af66fc99e Initial load
duke
parents:
diff changeset
1482 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1483 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1484 if (d_in + 1 != d_orig) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1485 set_depth(n, d_in + 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1486 again = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1487 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1488 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1489 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1490 ct++;
a61af66fc99e Initial load
duke
parents:
diff changeset
1491 } while (again);
a61af66fc99e Initial load
duke
parents:
diff changeset
1492 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1493 if (TraceSuperWord && Verbose)
a61af66fc99e Initial load
duke
parents:
diff changeset
1494 tty->print_cr("compute_max_depth iterated: %d times", ct);
a61af66fc99e Initial load
duke
parents:
diff changeset
1495 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1496 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1497
a61af66fc99e Initial load
duke
parents:
diff changeset
1498 //-------------------------compute_vector_element_type-----------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1499 // Compute necessary vector element type for expressions
a61af66fc99e Initial load
duke
parents:
diff changeset
1500 // This propagates backwards a narrower integer type when the
a61af66fc99e Initial load
duke
parents:
diff changeset
1501 // upper bits of the value are not needed.
a61af66fc99e Initial load
duke
parents:
diff changeset
1502 // Example: char a,b,c; a = b + c;
a61af66fc99e Initial load
duke
parents:
diff changeset
1503 // Normally the type of the add is integer, but for packed character
a61af66fc99e Initial load
duke
parents:
diff changeset
1504 // operations the type of the add needs to be char.
a61af66fc99e Initial load
duke
parents:
diff changeset
1505 void SuperWord::compute_vector_element_type() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1506 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1507 if (TraceSuperWord && Verbose)
a61af66fc99e Initial load
duke
parents:
diff changeset
1508 tty->print_cr("\ncompute_velt_type:");
a61af66fc99e Initial load
duke
parents:
diff changeset
1509 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1510
a61af66fc99e Initial load
duke
parents:
diff changeset
1511 // Initial type
a61af66fc99e Initial load
duke
parents:
diff changeset
1512 for (int i = 0; i < _block.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1513 Node* n = _block.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1514 const Type* t = n->is_Mem() ? Type::get_const_basic_type(n->as_Mem()->memory_type())
a61af66fc99e Initial load
duke
parents:
diff changeset
1515 : _igvn.type(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
1516 const Type* vt = container_type(t);
a61af66fc99e Initial load
duke
parents:
diff changeset
1517 set_velt_type(n, vt);
a61af66fc99e Initial load
duke
parents:
diff changeset
1518 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1519
a61af66fc99e Initial load
duke
parents:
diff changeset
1520 // Propagate narrowed type backwards through operations
a61af66fc99e Initial load
duke
parents:
diff changeset
1521 // that don't depend on higher order bits
a61af66fc99e Initial load
duke
parents:
diff changeset
1522 for (int i = _block.length() - 1; i >= 0; i--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1523 Node* n = _block.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1524 // Only integer types need be examined
a61af66fc99e Initial load
duke
parents:
diff changeset
1525 if (n->bottom_type()->isa_int()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1526 uint start, end;
a61af66fc99e Initial load
duke
parents:
diff changeset
1527 vector_opd_range(n, &start, &end);
a61af66fc99e Initial load
duke
parents:
diff changeset
1528 const Type* vt = velt_type(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
1529
a61af66fc99e Initial load
duke
parents:
diff changeset
1530 for (uint j = start; j < end; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1531 Node* in = n->in(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
1532 // Don't propagate through a type conversion
a61af66fc99e Initial load
duke
parents:
diff changeset
1533 if (n->bottom_type() != in->bottom_type())
a61af66fc99e Initial load
duke
parents:
diff changeset
1534 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1535 switch(in->Opcode()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1536 case Op_AddI: case Op_AddL:
a61af66fc99e Initial load
duke
parents:
diff changeset
1537 case Op_SubI: case Op_SubL:
a61af66fc99e Initial load
duke
parents:
diff changeset
1538 case Op_MulI: case Op_MulL:
a61af66fc99e Initial load
duke
parents:
diff changeset
1539 case Op_AndI: case Op_AndL:
a61af66fc99e Initial load
duke
parents:
diff changeset
1540 case Op_OrI: case Op_OrL:
a61af66fc99e Initial load
duke
parents:
diff changeset
1541 case Op_XorI: case Op_XorL:
a61af66fc99e Initial load
duke
parents:
diff changeset
1542 case Op_LShiftI: case Op_LShiftL:
a61af66fc99e Initial load
duke
parents:
diff changeset
1543 case Op_CMoveI: case Op_CMoveL:
a61af66fc99e Initial load
duke
parents:
diff changeset
1544 if (in_bb(in)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1545 bool same_type = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1546 for (DUIterator_Fast kmax, k = in->fast_outs(kmax); k < kmax; k++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1547 Node *use = in->fast_out(k);
a61af66fc99e Initial load
duke
parents:
diff changeset
1548 if (!in_bb(use) || velt_type(use) != vt) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1549 same_type = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1550 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1551 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1552 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1553 if (same_type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1554 set_velt_type(in, vt);
a61af66fc99e Initial load
duke
parents:
diff changeset
1555 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1556 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1557 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1558 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1559 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1560 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1561 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1562 if (TraceSuperWord && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1563 for (int i = 0; i < _block.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1564 Node* n = _block.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1565 velt_type(n)->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1566 tty->print("\t");
a61af66fc99e Initial load
duke
parents:
diff changeset
1567 n->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1568 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1569 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1570 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1571 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1572
a61af66fc99e Initial load
duke
parents:
diff changeset
1573 //------------------------------memory_alignment---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1574 // Alignment within a vector memory reference
a61af66fc99e Initial load
duke
parents:
diff changeset
1575 int SuperWord::memory_alignment(MemNode* s, int iv_adjust_in_bytes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1576 SWPointer p(s, this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1577 if (!p.valid()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1578 return bottom_align;
a61af66fc99e Initial load
duke
parents:
diff changeset
1579 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1580 int offset = p.offset_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
1581 offset += iv_adjust_in_bytes;
a61af66fc99e Initial load
duke
parents:
diff changeset
1582 int off_rem = offset % vector_width_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
1583 int off_mod = off_rem >= 0 ? off_rem : off_rem + vector_width_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
1584 return off_mod;
a61af66fc99e Initial load
duke
parents:
diff changeset
1585 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1586
a61af66fc99e Initial load
duke
parents:
diff changeset
1587 //---------------------------container_type---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1588 // Smallest type containing range of values
a61af66fc99e Initial load
duke
parents:
diff changeset
1589 const Type* SuperWord::container_type(const Type* t) {
221
1e026f8da827 6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents: 113
diff changeset
1590 const Type* tp = t->make_ptr();
1e026f8da827 6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents: 113
diff changeset
1591 if (tp && tp->isa_aryptr()) {
1e026f8da827 6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents: 113
diff changeset
1592 t = tp->is_aryptr()->elem();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1593 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1594 if (t->basic_type() == T_INT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1595 if (t->higher_equal(TypeInt::BOOL)) return TypeInt::BOOL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1596 if (t->higher_equal(TypeInt::BYTE)) return TypeInt::BYTE;
a61af66fc99e Initial load
duke
parents:
diff changeset
1597 if (t->higher_equal(TypeInt::CHAR)) return TypeInt::CHAR;
a61af66fc99e Initial load
duke
parents:
diff changeset
1598 if (t->higher_equal(TypeInt::SHORT)) return TypeInt::SHORT;
a61af66fc99e Initial load
duke
parents:
diff changeset
1599 return TypeInt::INT;
a61af66fc99e Initial load
duke
parents:
diff changeset
1600 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1601 return t;
a61af66fc99e Initial load
duke
parents:
diff changeset
1602 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1603
a61af66fc99e Initial load
duke
parents:
diff changeset
1604 //-------------------------vector_opd_range-----------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1605 // (Start, end] half-open range defining which operands are vector
a61af66fc99e Initial load
duke
parents:
diff changeset
1606 void SuperWord::vector_opd_range(Node* n, uint* start, uint* end) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1607 switch (n->Opcode()) {
558
3b5ac9e7e6ea 6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents: 253
diff changeset
1608 case Op_LoadB: case Op_LoadUS:
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1609 case Op_LoadI: case Op_LoadL:
a61af66fc99e Initial load
duke
parents:
diff changeset
1610 case Op_LoadF: case Op_LoadD:
a61af66fc99e Initial load
duke
parents:
diff changeset
1611 case Op_LoadP:
a61af66fc99e Initial load
duke
parents:
diff changeset
1612 *start = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1613 *end = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1614 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1615 case Op_StoreB: case Op_StoreC:
a61af66fc99e Initial load
duke
parents:
diff changeset
1616 case Op_StoreI: case Op_StoreL:
a61af66fc99e Initial load
duke
parents:
diff changeset
1617 case Op_StoreF: case Op_StoreD:
a61af66fc99e Initial load
duke
parents:
diff changeset
1618 case Op_StoreP:
a61af66fc99e Initial load
duke
parents:
diff changeset
1619 *start = MemNode::ValueIn;
a61af66fc99e Initial load
duke
parents:
diff changeset
1620 *end = *start + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1621 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1622 case Op_LShiftI: case Op_LShiftL:
a61af66fc99e Initial load
duke
parents:
diff changeset
1623 *start = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1624 *end = 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
1625 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1626 case Op_CMoveI: case Op_CMoveL: case Op_CMoveF: case Op_CMoveD:
a61af66fc99e Initial load
duke
parents:
diff changeset
1627 *start = 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
1628 *end = n->req();
a61af66fc99e Initial load
duke
parents:
diff changeset
1629 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1630 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1631 *start = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1632 *end = n->req(); // default is all operands
a61af66fc99e Initial load
duke
parents:
diff changeset
1633 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1634
a61af66fc99e Initial load
duke
parents:
diff changeset
1635 //------------------------------in_packset---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1636 // Are s1 and s2 in a pack pair and ordered as s1,s2?
a61af66fc99e Initial load
duke
parents:
diff changeset
1637 bool SuperWord::in_packset(Node* s1, Node* s2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1638 for (int i = 0; i < _packset.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1639 Node_List* p = _packset.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1640 assert(p->size() == 2, "must be");
a61af66fc99e Initial load
duke
parents:
diff changeset
1641 if (p->at(0) == s1 && p->at(p->size()-1) == s2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1642 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1643 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1644 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1645 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1646 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1647
a61af66fc99e Initial load
duke
parents:
diff changeset
1648 //------------------------------in_pack---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1649 // Is s in pack p?
a61af66fc99e Initial load
duke
parents:
diff changeset
1650 Node_List* SuperWord::in_pack(Node* s, Node_List* p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1651 for (uint i = 0; i < p->size(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1652 if (p->at(i) == s) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1653 return p;
a61af66fc99e Initial load
duke
parents:
diff changeset
1654 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1655 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1656 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1657 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1658
a61af66fc99e Initial load
duke
parents:
diff changeset
1659 //------------------------------remove_pack_at---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1660 // Remove the pack at position pos in the packset
a61af66fc99e Initial load
duke
parents:
diff changeset
1661 void SuperWord::remove_pack_at(int pos) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1662 Node_List* p = _packset.at(pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
1663 for (uint i = 0; i < p->size(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1664 Node* s = p->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1665 set_my_pack(s, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1666 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1667 _packset.remove_at(pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
1668 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1669
a61af66fc99e Initial load
duke
parents:
diff changeset
1670 //------------------------------executed_first---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1671 // Return the node executed first in pack p. Uses the RPO block list
a61af66fc99e Initial load
duke
parents:
diff changeset
1672 // to determine order.
a61af66fc99e Initial load
duke
parents:
diff changeset
1673 Node* SuperWord::executed_first(Node_List* p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1674 Node* n = p->at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1675 int n_rpo = bb_idx(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
1676 for (uint i = 1; i < p->size(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1677 Node* s = p->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1678 int s_rpo = bb_idx(s);
a61af66fc99e Initial load
duke
parents:
diff changeset
1679 if (s_rpo < n_rpo) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1680 n = s;
a61af66fc99e Initial load
duke
parents:
diff changeset
1681 n_rpo = s_rpo;
a61af66fc99e Initial load
duke
parents:
diff changeset
1682 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1683 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1684 return n;
a61af66fc99e Initial load
duke
parents:
diff changeset
1685 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1686
a61af66fc99e Initial load
duke
parents:
diff changeset
1687 //------------------------------executed_last---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1688 // Return the node executed last in pack p.
a61af66fc99e Initial load
duke
parents:
diff changeset
1689 Node* SuperWord::executed_last(Node_List* p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1690 Node* n = p->at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1691 int n_rpo = bb_idx(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
1692 for (uint i = 1; i < p->size(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1693 Node* s = p->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1694 int s_rpo = bb_idx(s);
a61af66fc99e Initial load
duke
parents:
diff changeset
1695 if (s_rpo > n_rpo) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1696 n = s;
a61af66fc99e Initial load
duke
parents:
diff changeset
1697 n_rpo = s_rpo;
a61af66fc99e Initial load
duke
parents:
diff changeset
1698 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1699 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1700 return n;
a61af66fc99e Initial load
duke
parents:
diff changeset
1701 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1702
a61af66fc99e Initial load
duke
parents:
diff changeset
1703 //----------------------------align_initial_loop_index---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1704 // Adjust pre-loop limit so that in main loop, a load/store reference
a61af66fc99e Initial load
duke
parents:
diff changeset
1705 // to align_to_ref will be a position zero in the vector.
a61af66fc99e Initial load
duke
parents:
diff changeset
1706 // (iv + k) mod vector_align == 0
a61af66fc99e Initial load
duke
parents:
diff changeset
1707 void SuperWord::align_initial_loop_index(MemNode* align_to_ref) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1708 CountedLoopNode *main_head = lp()->as_CountedLoop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1709 assert(main_head->is_main_loop(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1710 CountedLoopEndNode* pre_end = get_pre_loop_end(main_head);
a61af66fc99e Initial load
duke
parents:
diff changeset
1711 assert(pre_end != NULL, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1712 Node *pre_opaq1 = pre_end->limit();
a61af66fc99e Initial load
duke
parents:
diff changeset
1713 assert(pre_opaq1->Opcode() == Op_Opaque1, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1714 Opaque1Node *pre_opaq = (Opaque1Node*)pre_opaq1;
72
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1715 Node *lim0 = pre_opaq->in(1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1716
a61af66fc99e Initial load
duke
parents:
diff changeset
1717 // Where we put new limit calculations
a61af66fc99e Initial load
duke
parents:
diff changeset
1718 Node *pre_ctrl = pre_end->loopnode()->in(LoopNode::EntryControl);
a61af66fc99e Initial load
duke
parents:
diff changeset
1719
a61af66fc99e Initial load
duke
parents:
diff changeset
1720 // Ensure the original loop limit is available from the
a61af66fc99e Initial load
duke
parents:
diff changeset
1721 // pre-loop Opaque1 node.
a61af66fc99e Initial load
duke
parents:
diff changeset
1722 Node *orig_limit = pre_opaq->original_loop_limit();
a61af66fc99e Initial load
duke
parents:
diff changeset
1723 assert(orig_limit != NULL && _igvn.type(orig_limit) != Type::TOP, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1724
a61af66fc99e Initial load
duke
parents:
diff changeset
1725 SWPointer align_to_ref_p(align_to_ref, this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1726
72
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1727 // Given:
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1728 // lim0 == original pre loop limit
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1729 // V == v_align (power of 2)
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1730 // invar == extra invariant piece of the address expression
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1731 // e == k [ +/- invar ]
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1732 //
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1733 // When reassociating expressions involving '%' the basic rules are:
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1734 // (a - b) % k == 0 => a % k == b % k
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1735 // and:
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1736 // (a + b) % k == 0 => a % k == (k - b) % k
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1737 //
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1738 // For stride > 0 && scale > 0,
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1739 // Derive the new pre-loop limit "lim" such that the two constraints:
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1740 // (1) lim = lim0 + N (where N is some positive integer < V)
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1741 // (2) (e + lim) % V == 0
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1742 // are true.
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1743 //
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1744 // Substituting (1) into (2),
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1745 // (e + lim0 + N) % V == 0
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1746 // solve for N:
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1747 // N = (V - (e + lim0)) % V
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1748 // substitute back into (1), so that new limit
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1749 // lim = lim0 + (V - (e + lim0)) % V
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1750 //
72
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1751 // For stride > 0 && scale < 0
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1752 // Constraints:
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1753 // lim = lim0 + N
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1754 // (e - lim) % V == 0
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1755 // Solving for lim:
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1756 // (e - lim0 - N) % V == 0
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1757 // N = (e - lim0) % V
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1758 // lim = lim0 + (e - lim0) % V
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1759 //
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1760 // For stride < 0 && scale > 0
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1761 // Constraints:
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1762 // lim = lim0 - N
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1763 // (e + lim) % V == 0
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1764 // Solving for lim:
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1765 // (e + lim0 - N) % V == 0
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1766 // N = (e + lim0) % V
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1767 // lim = lim0 - (e + lim0) % V
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1768 //
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1769 // For stride < 0 && scale < 0
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1770 // Constraints:
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1771 // lim = lim0 - N
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1772 // (e - lim) % V == 0
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1773 // Solving for lim:
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1774 // (e - lim0 + N) % V == 0
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1775 // N = (V - (e - lim0)) % V
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1776 // lim = lim0 - (V - (e - lim0)) % V
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1777
72
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1778 int stride = iv_stride();
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1779 int scale = align_to_ref_p.scale_in_bytes();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1780 int elt_size = align_to_ref_p.memory_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
1781 int v_align = vector_width_in_bytes() / elt_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1782 int k = align_to_ref_p.offset_in_bytes() / elt_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1783
a61af66fc99e Initial load
duke
parents:
diff changeset
1784 Node *kn = _igvn.intcon(k);
72
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1785
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1786 Node *e = kn;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1787 if (align_to_ref_p.invar() != NULL) {
72
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1788 // incorporate any extra invariant piece producing k +/- invar >>> log2(elt)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1789 Node* log2_elt = _igvn.intcon(exact_log2(elt_size));
a61af66fc99e Initial load
duke
parents:
diff changeset
1790 Node* aref = new (_phase->C, 3) URShiftINode(align_to_ref_p.invar(), log2_elt);
a61af66fc99e Initial load
duke
parents:
diff changeset
1791 _phase->_igvn.register_new_node_with_optimizer(aref);
a61af66fc99e Initial load
duke
parents:
diff changeset
1792 _phase->set_ctrl(aref, pre_ctrl);
72
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1793 if (align_to_ref_p.negate_invar()) {
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1794 e = new (_phase->C, 3) SubINode(e, aref);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1795 } else {
72
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1796 e = new (_phase->C, 3) AddINode(e, aref);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1797 }
72
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1798 _phase->_igvn.register_new_node_with_optimizer(e);
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1799 _phase->set_ctrl(e, pre_ctrl);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1800 }
72
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1801
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1802 // compute e +/- lim0
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1803 if (scale < 0) {
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1804 e = new (_phase->C, 3) SubINode(e, lim0);
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1805 } else {
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1806 e = new (_phase->C, 3) AddINode(e, lim0);
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1807 }
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1808 _phase->_igvn.register_new_node_with_optimizer(e);
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1809 _phase->set_ctrl(e, pre_ctrl);
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1810
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1811 if (stride * scale > 0) {
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1812 // compute V - (e +/- lim0)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1813 Node* va = _igvn.intcon(v_align);
72
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1814 e = new (_phase->C, 3) SubINode(va, e);
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1815 _phase->_igvn.register_new_node_with_optimizer(e);
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1816 _phase->set_ctrl(e, pre_ctrl);
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1817 }
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1818 // compute N = (exp) % V
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1819 Node* va_msk = _igvn.intcon(v_align - 1);
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1820 Node* N = new (_phase->C, 3) AndINode(e, va_msk);
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1821 _phase->_igvn.register_new_node_with_optimizer(N);
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1822 _phase->set_ctrl(N, pre_ctrl);
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1823
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1824 // substitute back into (1), so that new limit
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1825 // lim = lim0 + N
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1826 Node* lim;
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1827 if (stride < 0) {
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1828 lim = new (_phase->C, 3) SubINode(lim0, N);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1829 } else {
72
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1830 lim = new (_phase->C, 3) AddINode(lim0, N);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1831 }
72
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1832 _phase->_igvn.register_new_node_with_optimizer(lim);
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1833 _phase->set_ctrl(lim, pre_ctrl);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1834 Node* constrained =
72
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1835 (stride > 0) ? (Node*) new (_phase->C,3) MinINode(lim, orig_limit)
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1836 : (Node*) new (_phase->C,3) MaxINode(lim, orig_limit);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1837 _phase->_igvn.register_new_node_with_optimizer(constrained);
a61af66fc99e Initial load
duke
parents:
diff changeset
1838 _phase->set_ctrl(constrained, pre_ctrl);
a61af66fc99e Initial load
duke
parents:
diff changeset
1839 _igvn.hash_delete(pre_opaq);
a61af66fc99e Initial load
duke
parents:
diff changeset
1840 pre_opaq->set_req(1, constrained);
a61af66fc99e Initial load
duke
parents:
diff changeset
1841 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1842
a61af66fc99e Initial load
duke
parents:
diff changeset
1843 //----------------------------get_pre_loop_end---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1844 // Find pre loop end from main loop. Returns null if none.
a61af66fc99e Initial load
duke
parents:
diff changeset
1845 CountedLoopEndNode* SuperWord::get_pre_loop_end(CountedLoopNode *cl) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1846 Node *ctrl = cl->in(LoopNode::EntryControl);
a61af66fc99e Initial load
duke
parents:
diff changeset
1847 if (!ctrl->is_IfTrue() && !ctrl->is_IfFalse()) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1848 Node *iffm = ctrl->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1849 if (!iffm->is_If()) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1850 Node *p_f = iffm->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1851 if (!p_f->is_IfFalse()) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1852 if (!p_f->in(0)->is_CountedLoopEnd()) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1853 CountedLoopEndNode *pre_end = p_f->in(0)->as_CountedLoopEnd();
a61af66fc99e Initial load
duke
parents:
diff changeset
1854 if (!pre_end->loopnode()->is_pre_loop()) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1855 return pre_end;
a61af66fc99e Initial load
duke
parents:
diff changeset
1856 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1857
a61af66fc99e Initial load
duke
parents:
diff changeset
1858
a61af66fc99e Initial load
duke
parents:
diff changeset
1859 //------------------------------init---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1860 void SuperWord::init() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1861 _dg.init();
a61af66fc99e Initial load
duke
parents:
diff changeset
1862 _packset.clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
1863 _disjoint_ptrs.clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
1864 _block.clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
1865 _data_entry.clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
1866 _mem_slice_head.clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
1867 _mem_slice_tail.clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
1868 _node_info.clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
1869 _align_to_ref = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1870 _lpt = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1871 _lp = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1872 _bb = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1873 _iv = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1874 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1875
a61af66fc99e Initial load
duke
parents:
diff changeset
1876 //------------------------------print_packset---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1877 void SuperWord::print_packset() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1878 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1879 tty->print_cr("packset");
a61af66fc99e Initial load
duke
parents:
diff changeset
1880 for (int i = 0; i < _packset.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1881 tty->print_cr("Pack: %d", i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1882 Node_List* p = _packset.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1883 print_pack(p);
a61af66fc99e Initial load
duke
parents:
diff changeset
1884 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1885 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1886 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1887
a61af66fc99e Initial load
duke
parents:
diff changeset
1888 //------------------------------print_pack---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1889 void SuperWord::print_pack(Node_List* p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1890 for (uint i = 0; i < p->size(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1891 print_stmt(p->at(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
1892 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1893 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1894
a61af66fc99e Initial load
duke
parents:
diff changeset
1895 //------------------------------print_bb---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1896 void SuperWord::print_bb() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1897 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1898 tty->print_cr("\nBlock");
a61af66fc99e Initial load
duke
parents:
diff changeset
1899 for (int i = 0; i < _block.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1900 Node* n = _block.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1901 tty->print("%d ", i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1902 if (n) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1903 n->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1904 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1905 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1906 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1907 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1908
a61af66fc99e Initial load
duke
parents:
diff changeset
1909 //------------------------------print_stmt---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1910 void SuperWord::print_stmt(Node* s) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1911 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1912 tty->print(" align: %d \t", alignment(s));
a61af66fc99e Initial load
duke
parents:
diff changeset
1913 s->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1914 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1915 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1916
a61af66fc99e Initial load
duke
parents:
diff changeset
1917 //------------------------------blank---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1918 char* SuperWord::blank(uint depth) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1919 static char blanks[101];
a61af66fc99e Initial load
duke
parents:
diff changeset
1920 assert(depth < 101, "too deep");
a61af66fc99e Initial load
duke
parents:
diff changeset
1921 for (uint i = 0; i < depth; i++) blanks[i] = ' ';
a61af66fc99e Initial load
duke
parents:
diff changeset
1922 blanks[depth] = '\0';
a61af66fc99e Initial load
duke
parents:
diff changeset
1923 return blanks;
a61af66fc99e Initial load
duke
parents:
diff changeset
1924 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1925
a61af66fc99e Initial load
duke
parents:
diff changeset
1926
a61af66fc99e Initial load
duke
parents:
diff changeset
1927 //==============================SWPointer===========================
a61af66fc99e Initial load
duke
parents:
diff changeset
1928
a61af66fc99e Initial load
duke
parents:
diff changeset
1929 //----------------------------SWPointer------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1930 SWPointer::SWPointer(MemNode* mem, SuperWord* slp) :
a61af66fc99e Initial load
duke
parents:
diff changeset
1931 _mem(mem), _slp(slp), _base(NULL), _adr(NULL),
a61af66fc99e Initial load
duke
parents:
diff changeset
1932 _scale(0), _offset(0), _invar(NULL), _negate_invar(false) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1933
a61af66fc99e Initial load
duke
parents:
diff changeset
1934 Node* adr = mem->in(MemNode::Address);
a61af66fc99e Initial load
duke
parents:
diff changeset
1935 if (!adr->is_AddP()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1936 assert(!valid(), "too complex");
a61af66fc99e Initial load
duke
parents:
diff changeset
1937 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1938 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1939 // Match AddP(base, AddP(ptr, k*iv [+ invariant]), constant)
a61af66fc99e Initial load
duke
parents:
diff changeset
1940 Node* base = adr->in(AddPNode::Base);
1058
73a726751507 6852078: HSX 14/16 in jdk 5.0: api/javax_management api/org_omg jck tests crashes or make tnameserv crash
cfang
parents: 987
diff changeset
1941 //unsafe reference could not be aligned appropriately without runtime checking
73a726751507 6852078: HSX 14/16 in jdk 5.0: api/javax_management api/org_omg jck tests crashes or make tnameserv crash
cfang
parents: 987
diff changeset
1942 if (base == NULL || base->bottom_type() == Type::TOP) {
73a726751507 6852078: HSX 14/16 in jdk 5.0: api/javax_management api/org_omg jck tests crashes or make tnameserv crash
cfang
parents: 987
diff changeset
1943 assert(!valid(), "unsafe access");
73a726751507 6852078: HSX 14/16 in jdk 5.0: api/javax_management api/org_omg jck tests crashes or make tnameserv crash
cfang
parents: 987
diff changeset
1944 return;
73a726751507 6852078: HSX 14/16 in jdk 5.0: api/javax_management api/org_omg jck tests crashes or make tnameserv crash
cfang
parents: 987
diff changeset
1945 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1946 for (int i = 0; i < 3; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1947 if (!scaled_iv_plus_offset(adr->in(AddPNode::Offset))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1948 assert(!valid(), "too complex");
a61af66fc99e Initial load
duke
parents:
diff changeset
1949 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1950 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1951 adr = adr->in(AddPNode::Address);
a61af66fc99e Initial load
duke
parents:
diff changeset
1952 if (base == adr || !adr->is_AddP()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1953 break; // stop looking at addp's
a61af66fc99e Initial load
duke
parents:
diff changeset
1954 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1955 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1956 _base = base;
a61af66fc99e Initial load
duke
parents:
diff changeset
1957 _adr = adr;
a61af66fc99e Initial load
duke
parents:
diff changeset
1958 assert(valid(), "Usable");
a61af66fc99e Initial load
duke
parents:
diff changeset
1959 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1960
a61af66fc99e Initial load
duke
parents:
diff changeset
1961 // Following is used to create a temporary object during
a61af66fc99e Initial load
duke
parents:
diff changeset
1962 // the pattern match of an address expression.
a61af66fc99e Initial load
duke
parents:
diff changeset
1963 SWPointer::SWPointer(SWPointer* p) :
a61af66fc99e Initial load
duke
parents:
diff changeset
1964 _mem(p->_mem), _slp(p->_slp), _base(NULL), _adr(NULL),
a61af66fc99e Initial load
duke
parents:
diff changeset
1965 _scale(0), _offset(0), _invar(NULL), _negate_invar(false) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
1966
a61af66fc99e Initial load
duke
parents:
diff changeset
1967 //------------------------scaled_iv_plus_offset--------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1968 // Match: k*iv + offset
a61af66fc99e Initial load
duke
parents:
diff changeset
1969 // where: k is a constant that maybe zero, and
a61af66fc99e Initial load
duke
parents:
diff changeset
1970 // offset is (k2 [+/- invariant]) where k2 maybe zero and invariant is optional
a61af66fc99e Initial load
duke
parents:
diff changeset
1971 bool SWPointer::scaled_iv_plus_offset(Node* n) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1972 if (scaled_iv(n)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1973 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1974 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1975 if (offset_plus_k(n)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1976 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1977 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1978 int opc = n->Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
1979 if (opc == Op_AddI) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1980 if (scaled_iv(n->in(1)) && offset_plus_k(n->in(2))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1981 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1982 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1983 if (scaled_iv(n->in(2)) && offset_plus_k(n->in(1))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1984 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1985 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1986 } else if (opc == Op_SubI) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1987 if (scaled_iv(n->in(1)) && offset_plus_k(n->in(2), true)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1988 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1989 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1990 if (scaled_iv(n->in(2)) && offset_plus_k(n->in(1))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1991 _scale *= -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1992 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1993 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1994 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1995 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1996 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1997
a61af66fc99e Initial load
duke
parents:
diff changeset
1998 //----------------------------scaled_iv------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1999 // Match: k*iv where k is a constant that's not zero
a61af66fc99e Initial load
duke
parents:
diff changeset
2000 bool SWPointer::scaled_iv(Node* n) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2001 if (_scale != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2002 return false; // already found a scale
a61af66fc99e Initial load
duke
parents:
diff changeset
2003 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2004 if (n == iv()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2005 _scale = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2006 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2007 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2008 int opc = n->Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
2009 if (opc == Op_MulI) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2010 if (n->in(1) == iv() && n->in(2)->is_Con()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2011 _scale = n->in(2)->get_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
2012 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2013 } else if (n->in(2) == iv() && n->in(1)->is_Con()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2014 _scale = n->in(1)->get_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
2015 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2016 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2017 } else if (opc == Op_LShiftI) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2018 if (n->in(1) == iv() && n->in(2)->is_Con()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2019 _scale = 1 << n->in(2)->get_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
2020 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2021 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2022 } else if (opc == Op_ConvI2L) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2023 if (scaled_iv_plus_offset(n->in(1))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2024 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2025 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2026 } else if (opc == Op_LShiftL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2027 if (!has_iv() && _invar == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2028 // Need to preserve the current _offset value, so
a61af66fc99e Initial load
duke
parents:
diff changeset
2029 // create a temporary object for this expression subtree.
a61af66fc99e Initial load
duke
parents:
diff changeset
2030 // Hacky, so should re-engineer the address pattern match.
a61af66fc99e Initial load
duke
parents:
diff changeset
2031 SWPointer tmp(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2032 if (tmp.scaled_iv_plus_offset(n->in(1))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2033 if (tmp._invar == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2034 int mult = 1 << n->in(2)->get_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
2035 _scale = tmp._scale * mult;
a61af66fc99e Initial load
duke
parents:
diff changeset
2036 _offset += tmp._offset * mult;
a61af66fc99e Initial load
duke
parents:
diff changeset
2037 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2038 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2039 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2040 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2041 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2042 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2043 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2044
a61af66fc99e Initial load
duke
parents:
diff changeset
2045 //----------------------------offset_plus_k------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2046 // Match: offset is (k [+/- invariant])
a61af66fc99e Initial load
duke
parents:
diff changeset
2047 // where k maybe zero and invariant is optional, but not both.
a61af66fc99e Initial load
duke
parents:
diff changeset
2048 bool SWPointer::offset_plus_k(Node* n, bool negate) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2049 int opc = n->Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
2050 if (opc == Op_ConI) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2051 _offset += negate ? -(n->get_int()) : n->get_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
2052 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2053 } else if (opc == Op_ConL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2054 // Okay if value fits into an int
a61af66fc99e Initial load
duke
parents:
diff changeset
2055 const TypeLong* t = n->find_long_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
2056 if (t->higher_equal(TypeLong::INT)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2057 jlong loff = n->get_long();
a61af66fc99e Initial load
duke
parents:
diff changeset
2058 jint off = (jint)loff;
a61af66fc99e Initial load
duke
parents:
diff changeset
2059 _offset += negate ? -off : loff;
a61af66fc99e Initial load
duke
parents:
diff changeset
2060 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2061 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2062 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2063 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2064 if (_invar != NULL) return false; // already have an invariant
a61af66fc99e Initial load
duke
parents:
diff changeset
2065 if (opc == Op_AddI) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2066 if (n->in(2)->is_Con() && invariant(n->in(1))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2067 _negate_invar = negate;
a61af66fc99e Initial load
duke
parents:
diff changeset
2068 _invar = n->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2069 _offset += negate ? -(n->in(2)->get_int()) : n->in(2)->get_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
2070 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2071 } else if (n->in(1)->is_Con() && invariant(n->in(2))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2072 _offset += negate ? -(n->in(1)->get_int()) : n->in(1)->get_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
2073 _negate_invar = negate;
a61af66fc99e Initial load
duke
parents:
diff changeset
2074 _invar = n->in(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
2075 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2076 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2077 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2078 if (opc == Op_SubI) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2079 if (n->in(2)->is_Con() && invariant(n->in(1))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2080 _negate_invar = negate;
a61af66fc99e Initial load
duke
parents:
diff changeset
2081 _invar = n->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2082 _offset += !negate ? -(n->in(2)->get_int()) : n->in(2)->get_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
2083 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2084 } else if (n->in(1)->is_Con() && invariant(n->in(2))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2085 _offset += negate ? -(n->in(1)->get_int()) : n->in(1)->get_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
2086 _negate_invar = !negate;
a61af66fc99e Initial load
duke
parents:
diff changeset
2087 _invar = n->in(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
2088 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2089 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2090 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2091 if (invariant(n)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2092 _negate_invar = negate;
a61af66fc99e Initial load
duke
parents:
diff changeset
2093 _invar = n;
a61af66fc99e Initial load
duke
parents:
diff changeset
2094 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2095 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2096 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2097 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2098
a61af66fc99e Initial load
duke
parents:
diff changeset
2099 //----------------------------print------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2100 void SWPointer::print() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2101 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
2102 tty->print("base: %d adr: %d scale: %d offset: %d invar: %c%d\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
2103 _base != NULL ? _base->_idx : 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
2104 _adr != NULL ? _adr->_idx : 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
2105 _scale, _offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
2106 _negate_invar?'-':'+',
a61af66fc99e Initial load
duke
parents:
diff changeset
2107 _invar != NULL ? _invar->_idx : 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2108 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2109 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2110
a61af66fc99e Initial load
duke
parents:
diff changeset
2111 // ========================= OrderedPair =====================
a61af66fc99e Initial load
duke
parents:
diff changeset
2112
a61af66fc99e Initial load
duke
parents:
diff changeset
2113 const OrderedPair OrderedPair::initial;
a61af66fc99e Initial load
duke
parents:
diff changeset
2114
a61af66fc99e Initial load
duke
parents:
diff changeset
2115 // ========================= SWNodeInfo =====================
a61af66fc99e Initial load
duke
parents:
diff changeset
2116
a61af66fc99e Initial load
duke
parents:
diff changeset
2117 const SWNodeInfo SWNodeInfo::initial;
a61af66fc99e Initial load
duke
parents:
diff changeset
2118
a61af66fc99e Initial load
duke
parents:
diff changeset
2119
a61af66fc99e Initial load
duke
parents:
diff changeset
2120 // ============================ DepGraph ===========================
a61af66fc99e Initial load
duke
parents:
diff changeset
2121
a61af66fc99e Initial load
duke
parents:
diff changeset
2122 //------------------------------make_node---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2123 // Make a new dependence graph node for an ideal node.
a61af66fc99e Initial load
duke
parents:
diff changeset
2124 DepMem* DepGraph::make_node(Node* node) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2125 DepMem* m = new (_arena) DepMem(node);
a61af66fc99e Initial load
duke
parents:
diff changeset
2126 if (node != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2127 assert(_map.at_grow(node->_idx) == NULL, "one init only");
a61af66fc99e Initial load
duke
parents:
diff changeset
2128 _map.at_put_grow(node->_idx, m);
a61af66fc99e Initial load
duke
parents:
diff changeset
2129 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2130 return m;
a61af66fc99e Initial load
duke
parents:
diff changeset
2131 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2132
a61af66fc99e Initial load
duke
parents:
diff changeset
2133 //------------------------------make_edge---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2134 // Make a new dependence graph edge from dpred -> dsucc
a61af66fc99e Initial load
duke
parents:
diff changeset
2135 DepEdge* DepGraph::make_edge(DepMem* dpred, DepMem* dsucc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2136 DepEdge* e = new (_arena) DepEdge(dpred, dsucc, dsucc->in_head(), dpred->out_head());
a61af66fc99e Initial load
duke
parents:
diff changeset
2137 dpred->set_out_head(e);
a61af66fc99e Initial load
duke
parents:
diff changeset
2138 dsucc->set_in_head(e);
a61af66fc99e Initial load
duke
parents:
diff changeset
2139 return e;
a61af66fc99e Initial load
duke
parents:
diff changeset
2140 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2141
a61af66fc99e Initial load
duke
parents:
diff changeset
2142 // ========================== DepMem ========================
a61af66fc99e Initial load
duke
parents:
diff changeset
2143
a61af66fc99e Initial load
duke
parents:
diff changeset
2144 //------------------------------in_cnt---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2145 int DepMem::in_cnt() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2146 int ct = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2147 for (DepEdge* e = _in_head; e != NULL; e = e->next_in()) ct++;
a61af66fc99e Initial load
duke
parents:
diff changeset
2148 return ct;
a61af66fc99e Initial load
duke
parents:
diff changeset
2149 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2150
a61af66fc99e Initial load
duke
parents:
diff changeset
2151 //------------------------------out_cnt---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2152 int DepMem::out_cnt() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2153 int ct = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2154 for (DepEdge* e = _out_head; e != NULL; e = e->next_out()) ct++;
a61af66fc99e Initial load
duke
parents:
diff changeset
2155 return ct;
a61af66fc99e Initial load
duke
parents:
diff changeset
2156 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2157
a61af66fc99e Initial load
duke
parents:
diff changeset
2158 //------------------------------print-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2159 void DepMem::print() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2160 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
2161 tty->print(" DepNode %d (", _node->_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
2162 for (DepEdge* p = _in_head; p != NULL; p = p->next_in()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2163 Node* pred = p->pred()->node();
a61af66fc99e Initial load
duke
parents:
diff changeset
2164 tty->print(" %d", pred != NULL ? pred->_idx : 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2165 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2166 tty->print(") [");
a61af66fc99e Initial load
duke
parents:
diff changeset
2167 for (DepEdge* s = _out_head; s != NULL; s = s->next_out()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2168 Node* succ = s->succ()->node();
a61af66fc99e Initial load
duke
parents:
diff changeset
2169 tty->print(" %d", succ != NULL ? succ->_idx : 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2170 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2171 tty->print_cr(" ]");
a61af66fc99e Initial load
duke
parents:
diff changeset
2172 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2173 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2174
a61af66fc99e Initial load
duke
parents:
diff changeset
2175 // =========================== DepEdge =========================
a61af66fc99e Initial load
duke
parents:
diff changeset
2176
a61af66fc99e Initial load
duke
parents:
diff changeset
2177 //------------------------------DepPreds---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2178 void DepEdge::print() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2179 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
2180 tty->print_cr("DepEdge: %d [ %d ]", _pred->node()->_idx, _succ->node()->_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
2181 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2182 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2183
a61af66fc99e Initial load
duke
parents:
diff changeset
2184 // =========================== DepPreds =========================
a61af66fc99e Initial load
duke
parents:
diff changeset
2185 // Iterator over predecessor edges in the dependence graph.
a61af66fc99e Initial load
duke
parents:
diff changeset
2186
a61af66fc99e Initial load
duke
parents:
diff changeset
2187 //------------------------------DepPreds---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2188 DepPreds::DepPreds(Node* n, DepGraph& dg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2189 _n = n;
a61af66fc99e Initial load
duke
parents:
diff changeset
2190 _done = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2191 if (_n->is_Store() || _n->is_Load()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2192 _next_idx = MemNode::Address;
a61af66fc99e Initial load
duke
parents:
diff changeset
2193 _end_idx = n->req();
a61af66fc99e Initial load
duke
parents:
diff changeset
2194 _dep_next = dg.dep(_n)->in_head();
a61af66fc99e Initial load
duke
parents:
diff changeset
2195 } else if (_n->is_Mem()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2196 _next_idx = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2197 _end_idx = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2198 _dep_next = dg.dep(_n)->in_head();
a61af66fc99e Initial load
duke
parents:
diff changeset
2199 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2200 _next_idx = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2201 _end_idx = _n->req();
a61af66fc99e Initial load
duke
parents:
diff changeset
2202 _dep_next = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2203 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2204 next();
a61af66fc99e Initial load
duke
parents:
diff changeset
2205 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2206
a61af66fc99e Initial load
duke
parents:
diff changeset
2207 //------------------------------next---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2208 void DepPreds::next() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2209 if (_dep_next != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2210 _current = _dep_next->pred()->node();
a61af66fc99e Initial load
duke
parents:
diff changeset
2211 _dep_next = _dep_next->next_in();
a61af66fc99e Initial load
duke
parents:
diff changeset
2212 } else if (_next_idx < _end_idx) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2213 _current = _n->in(_next_idx++);
a61af66fc99e Initial load
duke
parents:
diff changeset
2214 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2215 _done = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2216 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2217 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2218
a61af66fc99e Initial load
duke
parents:
diff changeset
2219 // =========================== DepSuccs =========================
a61af66fc99e Initial load
duke
parents:
diff changeset
2220 // Iterator over successor edges in the dependence graph.
a61af66fc99e Initial load
duke
parents:
diff changeset
2221
a61af66fc99e Initial load
duke
parents:
diff changeset
2222 //------------------------------DepSuccs---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2223 DepSuccs::DepSuccs(Node* n, DepGraph& dg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2224 _n = n;
a61af66fc99e Initial load
duke
parents:
diff changeset
2225 _done = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2226 if (_n->is_Load()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2227 _next_idx = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2228 _end_idx = _n->outcnt();
a61af66fc99e Initial load
duke
parents:
diff changeset
2229 _dep_next = dg.dep(_n)->out_head();
a61af66fc99e Initial load
duke
parents:
diff changeset
2230 } else if (_n->is_Mem() || _n->is_Phi() && _n->bottom_type() == Type::MEMORY) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2231 _next_idx = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2232 _end_idx = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2233 _dep_next = dg.dep(_n)->out_head();
a61af66fc99e Initial load
duke
parents:
diff changeset
2234 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2235 _next_idx = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2236 _end_idx = _n->outcnt();
a61af66fc99e Initial load
duke
parents:
diff changeset
2237 _dep_next = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2238 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2239 next();
a61af66fc99e Initial load
duke
parents:
diff changeset
2240 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2241
a61af66fc99e Initial load
duke
parents:
diff changeset
2242 //-------------------------------next---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2243 void DepSuccs::next() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2244 if (_dep_next != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2245 _current = _dep_next->succ()->node();
a61af66fc99e Initial load
duke
parents:
diff changeset
2246 _dep_next = _dep_next->next_out();
a61af66fc99e Initial load
duke
parents:
diff changeset
2247 } else if (_next_idx < _end_idx) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2248 _current = _n->raw_out(_next_idx++);
a61af66fc99e Initial load
duke
parents:
diff changeset
2249 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2250 _done = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2251 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2252 }