annotate src/share/vm/opto/superword.cpp @ 1941:79d04223b8a5

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