annotate src/share/vm/opto/superword.cpp @ 4710:41406797186b

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