annotate src/share/vm/opto/superword.cpp @ 452:00b023ae2d78

6722113: CMS: Incorrect overflow handling during precleaning of Reference lists Summary: When we encounter marking stack overflow during precleaning of Reference lists, we were using the overflow list mechanism, which can cause problems on account of mutating the mark word of the header because of conflicts with mutator accesses and updates of that field. Instead we should use the usual mechanism for overflow handling in concurrent phases, namely dirtying of the card on which the overflowed object lies. Since precleaning effectively does a form of discovered list processing, albeit with discovery enabled, we needed to adjust some code to be correct in the face of interleaved processing and discovery. Reviewed-by: apetrusenko, jcoomes
author ysr
date Thu, 20 Nov 2008 12:27:41 -0800
parents b0fe4deeb9fb
children 3b5ac9e7e6ea
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
196
d1605aabd0a1 6719955: Update copyright year
xdono
parents: 113
diff changeset
2 * Copyright 2007-2008 Sun Microsystems, Inc. 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 *
a61af66fc99e Initial load
duke
parents:
diff changeset
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
a61af66fc99e Initial load
duke
parents:
diff changeset
20 * CA 95054 USA or visit www.sun.com if you need additional information or
a61af66fc99e Initial load
duke
parents:
diff changeset
21 * have any questions.
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.
a61af66fc99e Initial load
duke
parents:
diff changeset
457 } else if (out->Opcode() == Op_StoreCM && out->in(4) == n) {
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---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
473 // Can s1 and s2 be in a pack with s1 immediately preceeding s2 and
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) {
a61af66fc99e Initial load
duke
parents:
diff changeset
476 if (isomorphic(s1, s2)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
477 if (independent(s1, s2)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
478 if (!exists_at(s1, 0) && !exists_at(s2, 1)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
479 if (!s1->is_Mem() || are_adjacent_refs(s1, s2)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
480 int s1_align = alignment(s1);
a61af66fc99e Initial load
duke
parents:
diff changeset
481 int s2_align = alignment(s2);
a61af66fc99e Initial load
duke
parents:
diff changeset
482 if (s1_align == top_align || s1_align == align) {
a61af66fc99e Initial load
duke
parents:
diff changeset
483 if (s2_align == top_align || s2_align == align + data_size(s1)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
484 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
485 }
a61af66fc99e Initial load
duke
parents:
diff changeset
486 }
a61af66fc99e Initial load
duke
parents:
diff changeset
487 }
a61af66fc99e Initial load
duke
parents:
diff changeset
488 }
a61af66fc99e Initial load
duke
parents:
diff changeset
489 }
a61af66fc99e Initial load
duke
parents:
diff changeset
490 }
a61af66fc99e Initial load
duke
parents:
diff changeset
491 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
492 }
a61af66fc99e Initial load
duke
parents:
diff changeset
493
a61af66fc99e Initial load
duke
parents:
diff changeset
494 //------------------------------exists_at---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
495 // Does s exist in a pack at position pos?
a61af66fc99e Initial load
duke
parents:
diff changeset
496 bool SuperWord::exists_at(Node* s, uint pos) {
a61af66fc99e Initial load
duke
parents:
diff changeset
497 for (int i = 0; i < _packset.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
498 Node_List* p = _packset.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
499 if (p->at(pos) == s) {
a61af66fc99e Initial load
duke
parents:
diff changeset
500 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
501 }
a61af66fc99e Initial load
duke
parents:
diff changeset
502 }
a61af66fc99e Initial load
duke
parents:
diff changeset
503 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
504 }
a61af66fc99e Initial load
duke
parents:
diff changeset
505
a61af66fc99e Initial load
duke
parents:
diff changeset
506 //------------------------------are_adjacent_refs---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
507 // Is s1 immediately before s2 in memory?
a61af66fc99e Initial load
duke
parents:
diff changeset
508 bool SuperWord::are_adjacent_refs(Node* s1, Node* s2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
509 if (!s1->is_Mem() || !s2->is_Mem()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
510 if (!in_bb(s1) || !in_bb(s2)) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
511 // FIXME - co_locate_pack fails on Stores in different mem-slices, so
a61af66fc99e Initial load
duke
parents:
diff changeset
512 // only pack memops that are in the same alias set until that's fixed.
a61af66fc99e Initial load
duke
parents:
diff changeset
513 if (_phase->C->get_alias_index(s1->as_Mem()->adr_type()) !=
a61af66fc99e Initial load
duke
parents:
diff changeset
514 _phase->C->get_alias_index(s2->as_Mem()->adr_type()))
a61af66fc99e Initial load
duke
parents:
diff changeset
515 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
516 SWPointer p1(s1->as_Mem(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
517 SWPointer p2(s2->as_Mem(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
518 if (p1.base() != p2.base() || !p1.comparable(p2)) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
519 int diff = p2.offset_in_bytes() - p1.offset_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
520 return diff == data_size(s1);
a61af66fc99e Initial load
duke
parents:
diff changeset
521 }
a61af66fc99e Initial load
duke
parents:
diff changeset
522
a61af66fc99e Initial load
duke
parents:
diff changeset
523 //------------------------------isomorphic---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
524 // Are s1 and s2 similar?
a61af66fc99e Initial load
duke
parents:
diff changeset
525 bool SuperWord::isomorphic(Node* s1, Node* s2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
526 if (s1->Opcode() != s2->Opcode()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
527 if (s1->req() != s2->req()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
528 if (s1->in(0) != s2->in(0)) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
529 if (velt_type(s1) != velt_type(s2)) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
530 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
531 }
a61af66fc99e Initial load
duke
parents:
diff changeset
532
a61af66fc99e Initial load
duke
parents:
diff changeset
533 //------------------------------independent---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
534 // Is there no data path from s1 to s2 or s2 to s1?
a61af66fc99e Initial load
duke
parents:
diff changeset
535 bool SuperWord::independent(Node* s1, Node* s2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
536 // assert(s1->Opcode() == s2->Opcode(), "check isomorphic first");
a61af66fc99e Initial load
duke
parents:
diff changeset
537 int d1 = depth(s1);
a61af66fc99e Initial load
duke
parents:
diff changeset
538 int d2 = depth(s2);
a61af66fc99e Initial load
duke
parents:
diff changeset
539 if (d1 == d2) return s1 != s2;
a61af66fc99e Initial load
duke
parents:
diff changeset
540 Node* deep = d1 > d2 ? s1 : s2;
a61af66fc99e Initial load
duke
parents:
diff changeset
541 Node* shallow = d1 > d2 ? s2 : s1;
a61af66fc99e Initial load
duke
parents:
diff changeset
542
a61af66fc99e Initial load
duke
parents:
diff changeset
543 visited_clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
544
a61af66fc99e Initial load
duke
parents:
diff changeset
545 return independent_path(shallow, deep);
a61af66fc99e Initial load
duke
parents:
diff changeset
546 }
a61af66fc99e Initial load
duke
parents:
diff changeset
547
a61af66fc99e Initial load
duke
parents:
diff changeset
548 //------------------------------independent_path------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
549 // Helper for independent
a61af66fc99e Initial load
duke
parents:
diff changeset
550 bool SuperWord::independent_path(Node* shallow, Node* deep, uint dp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
551 if (dp >= 1000) return false; // stop deep recursion
a61af66fc99e Initial load
duke
parents:
diff changeset
552 visited_set(deep);
a61af66fc99e Initial load
duke
parents:
diff changeset
553 int shal_depth = depth(shallow);
a61af66fc99e Initial load
duke
parents:
diff changeset
554 assert(shal_depth <= depth(deep), "must be");
a61af66fc99e Initial load
duke
parents:
diff changeset
555 for (DepPreds preds(deep, _dg); !preds.done(); preds.next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
556 Node* pred = preds.current();
a61af66fc99e Initial load
duke
parents:
diff changeset
557 if (in_bb(pred) && !visited_test(pred)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
558 if (shallow == pred) {
a61af66fc99e Initial load
duke
parents:
diff changeset
559 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
560 }
a61af66fc99e Initial load
duke
parents:
diff changeset
561 if (shal_depth < depth(pred) && !independent_path(shallow, pred, dp+1)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
562 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
563 }
a61af66fc99e Initial load
duke
parents:
diff changeset
564 }
a61af66fc99e Initial load
duke
parents:
diff changeset
565 }
a61af66fc99e Initial load
duke
parents:
diff changeset
566 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
567 }
a61af66fc99e Initial load
duke
parents:
diff changeset
568
a61af66fc99e Initial load
duke
parents:
diff changeset
569 //------------------------------set_alignment---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
570 void SuperWord::set_alignment(Node* s1, Node* s2, int align) {
a61af66fc99e Initial load
duke
parents:
diff changeset
571 set_alignment(s1, align);
a61af66fc99e Initial load
duke
parents:
diff changeset
572 set_alignment(s2, align + data_size(s1));
a61af66fc99e Initial load
duke
parents:
diff changeset
573 }
a61af66fc99e Initial load
duke
parents:
diff changeset
574
a61af66fc99e Initial load
duke
parents:
diff changeset
575 //------------------------------data_size---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
576 int SuperWord::data_size(Node* s) {
a61af66fc99e Initial load
duke
parents:
diff changeset
577 const Type* t = velt_type(s);
a61af66fc99e Initial load
duke
parents:
diff changeset
578 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
579 int bsize = type2aelembytes(bt);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
580 assert(bsize != 0, "valid size");
a61af66fc99e Initial load
duke
parents:
diff changeset
581 return bsize;
a61af66fc99e Initial load
duke
parents:
diff changeset
582 }
a61af66fc99e Initial load
duke
parents:
diff changeset
583
a61af66fc99e Initial load
duke
parents:
diff changeset
584 //------------------------------extend_packlist---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
585 // Extend packset by following use->def and def->use links from pack members.
a61af66fc99e Initial load
duke
parents:
diff changeset
586 void SuperWord::extend_packlist() {
a61af66fc99e Initial load
duke
parents:
diff changeset
587 bool changed;
a61af66fc99e Initial load
duke
parents:
diff changeset
588 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
589 changed = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
590 for (int i = 0; i < _packset.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
591 Node_List* p = _packset.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
592 changed |= follow_use_defs(p);
a61af66fc99e Initial load
duke
parents:
diff changeset
593 changed |= follow_def_uses(p);
a61af66fc99e Initial load
duke
parents:
diff changeset
594 }
a61af66fc99e Initial load
duke
parents:
diff changeset
595 } while (changed);
a61af66fc99e Initial load
duke
parents:
diff changeset
596
a61af66fc99e Initial load
duke
parents:
diff changeset
597 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
598 if (TraceSuperWord) {
a61af66fc99e Initial load
duke
parents:
diff changeset
599 tty->print_cr("\nAfter extend_packlist");
a61af66fc99e Initial load
duke
parents:
diff changeset
600 print_packset();
a61af66fc99e Initial load
duke
parents:
diff changeset
601 }
a61af66fc99e Initial load
duke
parents:
diff changeset
602 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
603 }
a61af66fc99e Initial load
duke
parents:
diff changeset
604
a61af66fc99e Initial load
duke
parents:
diff changeset
605 //------------------------------follow_use_defs---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
606 // Extend the packset by visiting operand definitions of nodes in pack p
a61af66fc99e Initial load
duke
parents:
diff changeset
607 bool SuperWord::follow_use_defs(Node_List* p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
608 Node* s1 = p->at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
609 Node* s2 = p->at(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
610 assert(p->size() == 2, "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
611 assert(s1->req() == s2->req(), "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
612 assert(alignment(s1) + data_size(s1) == alignment(s2), "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
613
a61af66fc99e Initial load
duke
parents:
diff changeset
614 if (s1->is_Load()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
615
a61af66fc99e Initial load
duke
parents:
diff changeset
616 int align = alignment(s1);
a61af66fc99e Initial load
duke
parents:
diff changeset
617 bool changed = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
618 int start = s1->is_Store() ? MemNode::ValueIn : 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
619 int end = s1->is_Store() ? MemNode::ValueIn+1 : s1->req();
a61af66fc99e Initial load
duke
parents:
diff changeset
620 for (int j = start; j < end; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
621 Node* t1 = s1->in(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
622 Node* t2 = s2->in(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
623 if (!in_bb(t1) || !in_bb(t2))
a61af66fc99e Initial load
duke
parents:
diff changeset
624 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
625 if (stmts_can_pack(t1, t2, align)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
626 if (est_savings(t1, t2) >= 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
627 Node_List* pair = new Node_List();
a61af66fc99e Initial load
duke
parents:
diff changeset
628 pair->push(t1);
a61af66fc99e Initial load
duke
parents:
diff changeset
629 pair->push(t2);
a61af66fc99e Initial load
duke
parents:
diff changeset
630 _packset.append(pair);
a61af66fc99e Initial load
duke
parents:
diff changeset
631 set_alignment(t1, t2, align);
a61af66fc99e Initial load
duke
parents:
diff changeset
632 changed = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
633 }
a61af66fc99e Initial load
duke
parents:
diff changeset
634 }
a61af66fc99e Initial load
duke
parents:
diff changeset
635 }
a61af66fc99e Initial load
duke
parents:
diff changeset
636 return changed;
a61af66fc99e Initial load
duke
parents:
diff changeset
637 }
a61af66fc99e Initial load
duke
parents:
diff changeset
638
a61af66fc99e Initial load
duke
parents:
diff changeset
639 //------------------------------follow_def_uses---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
640 // Extend the packset by visiting uses of nodes in pack p
a61af66fc99e Initial load
duke
parents:
diff changeset
641 bool SuperWord::follow_def_uses(Node_List* p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
642 bool changed = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
643 Node* s1 = p->at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
644 Node* s2 = p->at(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
645 assert(p->size() == 2, "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
646 assert(s1->req() == s2->req(), "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
647 assert(alignment(s1) + data_size(s1) == alignment(s2), "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
648
a61af66fc99e Initial load
duke
parents:
diff changeset
649 if (s1->is_Store()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
650
a61af66fc99e Initial load
duke
parents:
diff changeset
651 int align = alignment(s1);
a61af66fc99e Initial load
duke
parents:
diff changeset
652 int savings = -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
653 Node* u1 = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
654 Node* u2 = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
655 for (DUIterator_Fast imax, i = s1->fast_outs(imax); i < imax; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
656 Node* t1 = s1->fast_out(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
657 if (!in_bb(t1)) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
658 for (DUIterator_Fast jmax, j = s2->fast_outs(jmax); j < jmax; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
659 Node* t2 = s2->fast_out(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
660 if (!in_bb(t2)) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
661 if (!opnd_positions_match(s1, t1, s2, t2))
a61af66fc99e Initial load
duke
parents:
diff changeset
662 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
663 if (stmts_can_pack(t1, t2, align)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
664 int my_savings = est_savings(t1, t2);
a61af66fc99e Initial load
duke
parents:
diff changeset
665 if (my_savings > savings) {
a61af66fc99e Initial load
duke
parents:
diff changeset
666 savings = my_savings;
a61af66fc99e Initial load
duke
parents:
diff changeset
667 u1 = t1;
a61af66fc99e Initial load
duke
parents:
diff changeset
668 u2 = t2;
a61af66fc99e Initial load
duke
parents:
diff changeset
669 }
a61af66fc99e Initial load
duke
parents:
diff changeset
670 }
a61af66fc99e Initial load
duke
parents:
diff changeset
671 }
a61af66fc99e Initial load
duke
parents:
diff changeset
672 }
a61af66fc99e Initial load
duke
parents:
diff changeset
673 if (savings >= 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
674 Node_List* pair = new Node_List();
a61af66fc99e Initial load
duke
parents:
diff changeset
675 pair->push(u1);
a61af66fc99e Initial load
duke
parents:
diff changeset
676 pair->push(u2);
a61af66fc99e Initial load
duke
parents:
diff changeset
677 _packset.append(pair);
a61af66fc99e Initial load
duke
parents:
diff changeset
678 set_alignment(u1, u2, align);
a61af66fc99e Initial load
duke
parents:
diff changeset
679 changed = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
680 }
a61af66fc99e Initial load
duke
parents:
diff changeset
681 return changed;
a61af66fc99e Initial load
duke
parents:
diff changeset
682 }
a61af66fc99e Initial load
duke
parents:
diff changeset
683
a61af66fc99e Initial load
duke
parents:
diff changeset
684 //---------------------------opnd_positions_match-------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
685 // Is the use of d1 in u1 at the same operand position as d2 in u2?
a61af66fc99e Initial load
duke
parents:
diff changeset
686 bool SuperWord::opnd_positions_match(Node* d1, Node* u1, Node* d2, Node* u2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
687 uint ct = u1->req();
a61af66fc99e Initial load
duke
parents:
diff changeset
688 if (ct != u2->req()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
689 uint i1 = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
690 uint i2 = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
691 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
692 for (i1++; i1 < ct; i1++) if (u1->in(i1) == d1) break;
a61af66fc99e Initial load
duke
parents:
diff changeset
693 for (i2++; i2 < ct; i2++) if (u2->in(i2) == d2) break;
a61af66fc99e Initial load
duke
parents:
diff changeset
694 if (i1 != i2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
695 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
696 }
a61af66fc99e Initial load
duke
parents:
diff changeset
697 } while (i1 < ct);
a61af66fc99e Initial load
duke
parents:
diff changeset
698 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
699 }
a61af66fc99e Initial load
duke
parents:
diff changeset
700
a61af66fc99e Initial load
duke
parents:
diff changeset
701 //------------------------------est_savings---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
702 // Estimate the savings from executing s1 and s2 as a pack
a61af66fc99e Initial load
duke
parents:
diff changeset
703 int SuperWord::est_savings(Node* s1, Node* s2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
704 int save = 2 - 1; // 2 operations per instruction in packed form
a61af66fc99e Initial load
duke
parents:
diff changeset
705
a61af66fc99e Initial load
duke
parents:
diff changeset
706 // inputs
a61af66fc99e Initial load
duke
parents:
diff changeset
707 for (uint i = 1; i < s1->req(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
708 Node* x1 = s1->in(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
709 Node* x2 = s2->in(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
710 if (x1 != x2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
711 if (are_adjacent_refs(x1, x2)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
712 save += adjacent_profit(x1, x2);
a61af66fc99e Initial load
duke
parents:
diff changeset
713 } else if (!in_packset(x1, x2)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
714 save -= pack_cost(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
715 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
716 save += unpack_cost(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
717 }
a61af66fc99e Initial load
duke
parents:
diff changeset
718 }
a61af66fc99e Initial load
duke
parents:
diff changeset
719 }
a61af66fc99e Initial load
duke
parents:
diff changeset
720
a61af66fc99e Initial load
duke
parents:
diff changeset
721 // uses of result
a61af66fc99e Initial load
duke
parents:
diff changeset
722 uint ct = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
723 for (DUIterator_Fast imax, i = s1->fast_outs(imax); i < imax; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
724 Node* s1_use = s1->fast_out(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
725 for (int j = 0; j < _packset.length(); j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
726 Node_List* p = _packset.at(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
727 if (p->at(0) == s1_use) {
a61af66fc99e Initial load
duke
parents:
diff changeset
728 for (DUIterator_Fast kmax, k = s2->fast_outs(kmax); k < kmax; k++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
729 Node* s2_use = s2->fast_out(k);
a61af66fc99e Initial load
duke
parents:
diff changeset
730 if (p->at(p->size()-1) == s2_use) {
a61af66fc99e Initial load
duke
parents:
diff changeset
731 ct++;
a61af66fc99e Initial load
duke
parents:
diff changeset
732 if (are_adjacent_refs(s1_use, s2_use)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
733 save += adjacent_profit(s1_use, s2_use);
a61af66fc99e Initial load
duke
parents:
diff changeset
734 }
a61af66fc99e Initial load
duke
parents:
diff changeset
735 }
a61af66fc99e Initial load
duke
parents:
diff changeset
736 }
a61af66fc99e Initial load
duke
parents:
diff changeset
737 }
a61af66fc99e Initial load
duke
parents:
diff changeset
738 }
a61af66fc99e Initial load
duke
parents:
diff changeset
739 }
a61af66fc99e Initial load
duke
parents:
diff changeset
740
a61af66fc99e Initial load
duke
parents:
diff changeset
741 if (ct < s1->outcnt()) save += unpack_cost(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
742 if (ct < s2->outcnt()) save += unpack_cost(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
743
a61af66fc99e Initial load
duke
parents:
diff changeset
744 return save;
a61af66fc99e Initial load
duke
parents:
diff changeset
745 }
a61af66fc99e Initial load
duke
parents:
diff changeset
746
a61af66fc99e Initial load
duke
parents:
diff changeset
747 //------------------------------costs---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
748 int SuperWord::adjacent_profit(Node* s1, Node* s2) { return 2; }
a61af66fc99e Initial load
duke
parents:
diff changeset
749 int SuperWord::pack_cost(int ct) { return ct; }
a61af66fc99e Initial load
duke
parents:
diff changeset
750 int SuperWord::unpack_cost(int ct) { return ct; }
a61af66fc99e Initial load
duke
parents:
diff changeset
751
a61af66fc99e Initial load
duke
parents:
diff changeset
752 //------------------------------combine_packs---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
753 // 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
754 void SuperWord::combine_packs() {
a61af66fc99e Initial load
duke
parents:
diff changeset
755 bool changed;
a61af66fc99e Initial load
duke
parents:
diff changeset
756 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
757 changed = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
758 for (int i = 0; i < _packset.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
759 Node_List* p1 = _packset.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
760 if (p1 == NULL) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
761 for (int j = 0; j < _packset.length(); j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
762 Node_List* p2 = _packset.at(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
763 if (p2 == NULL) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
764 if (p1->at(p1->size()-1) == p2->at(0)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
765 for (uint k = 1; k < p2->size(); k++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
766 p1->push(p2->at(k));
a61af66fc99e Initial load
duke
parents:
diff changeset
767 }
a61af66fc99e Initial load
duke
parents:
diff changeset
768 _packset.at_put(j, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
769 changed = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
770 }
a61af66fc99e Initial load
duke
parents:
diff changeset
771 }
a61af66fc99e Initial load
duke
parents:
diff changeset
772 }
a61af66fc99e Initial load
duke
parents:
diff changeset
773 } while (changed);
a61af66fc99e Initial load
duke
parents:
diff changeset
774
a61af66fc99e Initial load
duke
parents:
diff changeset
775 for (int i = _packset.length() - 1; i >= 0; i--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
776 Node_List* p1 = _packset.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
777 if (p1 == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
778 _packset.remove_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
779 }
a61af66fc99e Initial load
duke
parents:
diff changeset
780 }
a61af66fc99e Initial load
duke
parents:
diff changeset
781
a61af66fc99e Initial load
duke
parents:
diff changeset
782 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
783 if (TraceSuperWord) {
a61af66fc99e Initial load
duke
parents:
diff changeset
784 tty->print_cr("\nAfter combine_packs");
a61af66fc99e Initial load
duke
parents:
diff changeset
785 print_packset();
a61af66fc99e Initial load
duke
parents:
diff changeset
786 }
a61af66fc99e Initial load
duke
parents:
diff changeset
787 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
788 }
a61af66fc99e Initial load
duke
parents:
diff changeset
789
a61af66fc99e Initial load
duke
parents:
diff changeset
790 //-----------------------------construct_my_pack_map--------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
791 // Construct the map from nodes to packs. Only valid after the
a61af66fc99e Initial load
duke
parents:
diff changeset
792 // point where a node is only in one pack (after combine_packs).
a61af66fc99e Initial load
duke
parents:
diff changeset
793 void SuperWord::construct_my_pack_map() {
a61af66fc99e Initial load
duke
parents:
diff changeset
794 Node_List* rslt = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
795 for (int i = 0; i < _packset.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
796 Node_List* p = _packset.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
797 for (uint j = 0; j < p->size(); j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
798 Node* s = p->at(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
799 assert(my_pack(s) == NULL, "only in one pack");
a61af66fc99e Initial load
duke
parents:
diff changeset
800 set_my_pack(s, p);
a61af66fc99e Initial load
duke
parents:
diff changeset
801 }
a61af66fc99e Initial load
duke
parents:
diff changeset
802 }
a61af66fc99e Initial load
duke
parents:
diff changeset
803 }
a61af66fc99e Initial load
duke
parents:
diff changeset
804
a61af66fc99e Initial load
duke
parents:
diff changeset
805 //------------------------------filter_packs---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
806 // Remove packs that are not implemented or not profitable.
a61af66fc99e Initial load
duke
parents:
diff changeset
807 void SuperWord::filter_packs() {
a61af66fc99e Initial load
duke
parents:
diff changeset
808
a61af66fc99e Initial load
duke
parents:
diff changeset
809 // Remove packs that are not implemented
a61af66fc99e Initial load
duke
parents:
diff changeset
810 for (int i = _packset.length() - 1; i >= 0; i--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
811 Node_List* pk = _packset.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
812 bool impl = implemented(pk);
a61af66fc99e Initial load
duke
parents:
diff changeset
813 if (!impl) {
a61af66fc99e Initial load
duke
parents:
diff changeset
814 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
815 if (TraceSuperWord && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
816 tty->print_cr("Unimplemented");
a61af66fc99e Initial load
duke
parents:
diff changeset
817 pk->at(0)->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
818 }
a61af66fc99e Initial load
duke
parents:
diff changeset
819 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
820 remove_pack_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
821 }
a61af66fc99e Initial load
duke
parents:
diff changeset
822 }
a61af66fc99e Initial load
duke
parents:
diff changeset
823
a61af66fc99e Initial load
duke
parents:
diff changeset
824 // Remove packs that are not profitable
a61af66fc99e Initial load
duke
parents:
diff changeset
825 bool changed;
a61af66fc99e Initial load
duke
parents:
diff changeset
826 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
827 changed = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
828 for (int i = _packset.length() - 1; i >= 0; i--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
829 Node_List* pk = _packset.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
830 bool prof = profitable(pk);
a61af66fc99e Initial load
duke
parents:
diff changeset
831 if (!prof) {
a61af66fc99e Initial load
duke
parents:
diff changeset
832 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
833 if (TraceSuperWord && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
834 tty->print_cr("Unprofitable");
a61af66fc99e Initial load
duke
parents:
diff changeset
835 pk->at(0)->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
836 }
a61af66fc99e Initial load
duke
parents:
diff changeset
837 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
838 remove_pack_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
839 changed = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
840 }
a61af66fc99e Initial load
duke
parents:
diff changeset
841 }
a61af66fc99e Initial load
duke
parents:
diff changeset
842 } while (changed);
a61af66fc99e Initial load
duke
parents:
diff changeset
843
a61af66fc99e Initial load
duke
parents:
diff changeset
844 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
845 if (TraceSuperWord) {
a61af66fc99e Initial load
duke
parents:
diff changeset
846 tty->print_cr("\nAfter filter_packs");
a61af66fc99e Initial load
duke
parents:
diff changeset
847 print_packset();
a61af66fc99e Initial load
duke
parents:
diff changeset
848 tty->cr();
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 }
a61af66fc99e Initial load
duke
parents:
diff changeset
852
a61af66fc99e Initial load
duke
parents:
diff changeset
853 //------------------------------implemented---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
854 // Can code be generated for pack p?
a61af66fc99e Initial load
duke
parents:
diff changeset
855 bool SuperWord::implemented(Node_List* p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
856 Node* p0 = p->at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
857 int vopc = VectorNode::opcode(p0->Opcode(), p->size(), velt_type(p0));
a61af66fc99e Initial load
duke
parents:
diff changeset
858 return vopc > 0 && Matcher::has_match_rule(vopc);
a61af66fc99e Initial load
duke
parents:
diff changeset
859 }
a61af66fc99e Initial load
duke
parents:
diff changeset
860
a61af66fc99e Initial load
duke
parents:
diff changeset
861 //------------------------------profitable---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
862 // For pack p, are all operands and all uses (with in the block) vector?
a61af66fc99e Initial load
duke
parents:
diff changeset
863 bool SuperWord::profitable(Node_List* p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
864 Node* p0 = p->at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
865 uint start, end;
a61af66fc99e Initial load
duke
parents:
diff changeset
866 vector_opd_range(p0, &start, &end);
a61af66fc99e Initial load
duke
parents:
diff changeset
867
a61af66fc99e Initial load
duke
parents:
diff changeset
868 // Return false if some input is not vector and inside block
a61af66fc99e Initial load
duke
parents:
diff changeset
869 for (uint i = start; i < end; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
870 if (!is_vector_use(p0, i)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
871 // For now, return false if not scalar promotion case (inputs are the same.)
a61af66fc99e Initial load
duke
parents:
diff changeset
872 // Later, implement PackNode and allow differring, non-vector inputs
a61af66fc99e Initial load
duke
parents:
diff changeset
873 // (maybe just the ones from outside the block.)
a61af66fc99e Initial load
duke
parents:
diff changeset
874 Node* p0_def = p0->in(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
875 for (uint j = 1; j < p->size(); j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
876 Node* use = p->at(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
877 Node* def = use->in(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
878 if (p0_def != def)
a61af66fc99e Initial load
duke
parents:
diff changeset
879 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
880 }
a61af66fc99e Initial load
duke
parents:
diff changeset
881 }
a61af66fc99e Initial load
duke
parents:
diff changeset
882 }
a61af66fc99e Initial load
duke
parents:
diff changeset
883 if (!p0->is_Store()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
884 // For now, return false if not all uses are vector.
a61af66fc99e Initial load
duke
parents:
diff changeset
885 // Later, implement ExtractNode and allow non-vector uses (maybe
a61af66fc99e Initial load
duke
parents:
diff changeset
886 // just the ones outside the block.)
a61af66fc99e Initial load
duke
parents:
diff changeset
887 for (uint i = 0; i < p->size(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
888 Node* def = p->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
889 for (DUIterator_Fast jmax, j = def->fast_outs(jmax); j < jmax; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
890 Node* use = def->fast_out(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
891 for (uint k = 0; k < use->req(); k++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
892 Node* n = use->in(k);
a61af66fc99e Initial load
duke
parents:
diff changeset
893 if (def == n) {
a61af66fc99e Initial load
duke
parents:
diff changeset
894 if (!is_vector_use(use, k)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
895 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
896 }
a61af66fc99e Initial load
duke
parents:
diff changeset
897 }
a61af66fc99e Initial load
duke
parents:
diff changeset
898 }
a61af66fc99e Initial load
duke
parents:
diff changeset
899 }
a61af66fc99e Initial load
duke
parents:
diff changeset
900 }
a61af66fc99e Initial load
duke
parents:
diff changeset
901 }
a61af66fc99e Initial load
duke
parents:
diff changeset
902 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
903 }
a61af66fc99e Initial load
duke
parents:
diff changeset
904
a61af66fc99e Initial load
duke
parents:
diff changeset
905 //------------------------------schedule---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
906 // Adjust the memory graph for the packed operations
a61af66fc99e Initial load
duke
parents:
diff changeset
907 void SuperWord::schedule() {
a61af66fc99e Initial load
duke
parents:
diff changeset
908
a61af66fc99e Initial load
duke
parents:
diff changeset
909 // Co-locate in the memory graph the members of each memory pack
a61af66fc99e Initial load
duke
parents:
diff changeset
910 for (int i = 0; i < _packset.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
911 co_locate_pack(_packset.at(i));
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 //------------------------------co_locate_pack---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
916 // Within a pack, move stores down to the last executed store,
a61af66fc99e Initial load
duke
parents:
diff changeset
917 // and move loads up to the first executed load.
a61af66fc99e Initial load
duke
parents:
diff changeset
918 void SuperWord::co_locate_pack(Node_List* pk) {
a61af66fc99e Initial load
duke
parents:
diff changeset
919 if (pk->at(0)->is_Store()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
920 // Push Stores down towards last executed pack member
a61af66fc99e Initial load
duke
parents:
diff changeset
921 MemNode* first = executed_first(pk)->as_Mem();
a61af66fc99e Initial load
duke
parents:
diff changeset
922 MemNode* last = executed_last(pk)->as_Mem();
a61af66fc99e Initial load
duke
parents:
diff changeset
923 MemNode* insert_pt = last;
a61af66fc99e Initial load
duke
parents:
diff changeset
924 MemNode* current = last->in(MemNode::Memory)->as_Mem();
a61af66fc99e Initial load
duke
parents:
diff changeset
925 while (true) {
a61af66fc99e Initial load
duke
parents:
diff changeset
926 assert(in_bb(current), "stay in block");
a61af66fc99e Initial load
duke
parents:
diff changeset
927 Node* my_mem = current->in(MemNode::Memory);
a61af66fc99e Initial load
duke
parents:
diff changeset
928 if (in_pack(current, pk)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
929 // Forward users of my memory state to my input memory state
a61af66fc99e Initial load
duke
parents:
diff changeset
930 _igvn.hash_delete(current);
a61af66fc99e Initial load
duke
parents:
diff changeset
931 _igvn.hash_delete(my_mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
932 for (DUIterator i = current->outs(); current->has_out(i); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
933 Node* use = current->out(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
934 if (use->is_Mem()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
935 assert(use->in(MemNode::Memory) == current, "must be");
a61af66fc99e Initial load
duke
parents:
diff changeset
936 _igvn.hash_delete(use);
a61af66fc99e Initial load
duke
parents:
diff changeset
937 use->set_req(MemNode::Memory, my_mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
938 _igvn._worklist.push(use);
a61af66fc99e Initial load
duke
parents:
diff changeset
939 --i; // deleted this edge; rescan position
a61af66fc99e Initial load
duke
parents:
diff changeset
940 }
a61af66fc99e Initial load
duke
parents:
diff changeset
941 }
a61af66fc99e Initial load
duke
parents:
diff changeset
942 // put current immediately before insert_pt
a61af66fc99e Initial load
duke
parents:
diff changeset
943 current->set_req(MemNode::Memory, insert_pt->in(MemNode::Memory));
a61af66fc99e Initial load
duke
parents:
diff changeset
944 _igvn.hash_delete(insert_pt);
a61af66fc99e Initial load
duke
parents:
diff changeset
945 insert_pt->set_req(MemNode::Memory, current);
a61af66fc99e Initial load
duke
parents:
diff changeset
946 _igvn._worklist.push(insert_pt);
a61af66fc99e Initial load
duke
parents:
diff changeset
947 _igvn._worklist.push(current);
a61af66fc99e Initial load
duke
parents:
diff changeset
948 insert_pt = current;
a61af66fc99e Initial load
duke
parents:
diff changeset
949 }
a61af66fc99e Initial load
duke
parents:
diff changeset
950 if (current == first) break;
a61af66fc99e Initial load
duke
parents:
diff changeset
951 current = my_mem->as_Mem();
a61af66fc99e Initial load
duke
parents:
diff changeset
952 }
a61af66fc99e Initial load
duke
parents:
diff changeset
953 } else if (pk->at(0)->is_Load()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
954 // Pull Loads up towards first executed pack member
a61af66fc99e Initial load
duke
parents:
diff changeset
955 LoadNode* first = executed_first(pk)->as_Load();
a61af66fc99e Initial load
duke
parents:
diff changeset
956 Node* first_mem = first->in(MemNode::Memory);
a61af66fc99e Initial load
duke
parents:
diff changeset
957 _igvn.hash_delete(first_mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
958 // Give each load same memory state as first
a61af66fc99e Initial load
duke
parents:
diff changeset
959 for (uint i = 0; i < pk->size(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
960 LoadNode* ld = pk->at(i)->as_Load();
a61af66fc99e Initial load
duke
parents:
diff changeset
961 _igvn.hash_delete(ld);
a61af66fc99e Initial load
duke
parents:
diff changeset
962 ld->set_req(MemNode::Memory, first_mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
963 _igvn._worklist.push(ld);
a61af66fc99e Initial load
duke
parents:
diff changeset
964 }
a61af66fc99e Initial load
duke
parents:
diff changeset
965 }
a61af66fc99e Initial load
duke
parents:
diff changeset
966 }
a61af66fc99e Initial load
duke
parents:
diff changeset
967
a61af66fc99e Initial load
duke
parents:
diff changeset
968 //------------------------------output---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
969 // Convert packs into vector node operations
a61af66fc99e Initial load
duke
parents:
diff changeset
970 void SuperWord::output() {
a61af66fc99e Initial load
duke
parents:
diff changeset
971 if (_packset.length() == 0) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
972
a61af66fc99e Initial load
duke
parents:
diff changeset
973 // MUST ENSURE main loop's initial value is properly aligned:
a61af66fc99e Initial load
duke
parents:
diff changeset
974 // (iv_initial_value + min_iv_offset) % vector_width_in_bytes() == 0
a61af66fc99e Initial load
duke
parents:
diff changeset
975
a61af66fc99e Initial load
duke
parents:
diff changeset
976 align_initial_loop_index(align_to_ref());
a61af66fc99e Initial load
duke
parents:
diff changeset
977
a61af66fc99e Initial load
duke
parents:
diff changeset
978 // Insert extract (unpack) operations for scalar uses
a61af66fc99e Initial load
duke
parents:
diff changeset
979 for (int i = 0; i < _packset.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
980 insert_extracts(_packset.at(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
981 }
a61af66fc99e Initial load
duke
parents:
diff changeset
982
a61af66fc99e Initial load
duke
parents:
diff changeset
983 for (int i = 0; i < _block.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
984 Node* n = _block.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
985 Node_List* p = my_pack(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
986 if (p && n == executed_last(p)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
987 uint vlen = p->size();
a61af66fc99e Initial load
duke
parents:
diff changeset
988 Node* vn = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
989 Node* low_adr = p->at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
990 Node* first = executed_first(p);
a61af66fc99e Initial load
duke
parents:
diff changeset
991 if (n->is_Load()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
992 int opc = n->Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
993 Node* ctl = n->in(MemNode::Control);
a61af66fc99e Initial load
duke
parents:
diff changeset
994 Node* mem = first->in(MemNode::Memory);
a61af66fc99e Initial load
duke
parents:
diff changeset
995 Node* adr = low_adr->in(MemNode::Address);
a61af66fc99e Initial load
duke
parents:
diff changeset
996 const TypePtr* atyp = n->adr_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
997 vn = VectorLoadNode::make(_phase->C, opc, ctl, mem, adr, atyp, vlen);
a61af66fc99e Initial load
duke
parents:
diff changeset
998
a61af66fc99e Initial load
duke
parents:
diff changeset
999 } else if (n->is_Store()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 // Promote value to be stored to vector
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 VectorNode* val = vector_opd(p, MemNode::ValueIn);
a61af66fc99e Initial load
duke
parents:
diff changeset
1002
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 int opc = n->Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 Node* ctl = n->in(MemNode::Control);
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 Node* mem = first->in(MemNode::Memory);
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 Node* adr = low_adr->in(MemNode::Address);
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 const TypePtr* atyp = n->adr_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 vn = VectorStoreNode::make(_phase->C, opc, ctl, mem, adr, atyp, val, vlen);
a61af66fc99e Initial load
duke
parents:
diff changeset
1009
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 } else if (n->req() == 3) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 // Promote operands to vector
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 Node* in1 = vector_opd(p, 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 Node* in2 = vector_opd(p, 2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 vn = VectorNode::make(_phase->C, n->Opcode(), in1, in2, vlen, velt_type(n));
a61af66fc99e Initial load
duke
parents:
diff changeset
1015
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1019
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 _phase->_igvn.register_new_node_with_optimizer(vn);
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 _phase->set_ctrl(vn, _phase->get_ctrl(p->at(0)));
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 for (uint j = 0; j < p->size(); j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 Node* pm = p->at(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 _igvn.hash_delete(pm);
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 _igvn.subsume_node(pm, vn);
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1027 _igvn._worklist.push(vn);
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1031
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 //------------------------------vector_opd---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 // Create a vector operand for the nodes in pack p for operand: in(opd_idx)
a61af66fc99e Initial load
duke
parents:
diff changeset
1034 VectorNode* SuperWord::vector_opd(Node_List* p, int opd_idx) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 Node* p0 = p->at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 uint vlen = p->size();
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 Node* opd = p0->in(opd_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1038
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 bool same_opd = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 for (uint i = 1; i < vlen; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 Node* pi = p->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1042 Node* in = pi->in(opd_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1043 if (opd != in) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 same_opd = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1045 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1048
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 if (same_opd) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 if (opd->is_Vector()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 return (VectorNode*)opd; // input is matching vector
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 // Convert scalar input to vector. Use p0's type because it's container
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 // maybe smaller than the operand's container.
a61af66fc99e Initial load
duke
parents:
diff changeset
1055 const Type* opd_t = velt_type(!in_bb(opd) ? p0 : opd);
a61af66fc99e Initial load
duke
parents:
diff changeset
1056 const Type* p0_t = velt_type(p0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 if (p0_t->higher_equal(opd_t)) opd_t = p0_t;
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 VectorNode* vn = VectorNode::scalar2vector(_phase->C, opd, vlen, opd_t);
a61af66fc99e Initial load
duke
parents:
diff changeset
1059
a61af66fc99e Initial load
duke
parents:
diff changeset
1060 _phase->_igvn.register_new_node_with_optimizer(vn);
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 _phase->set_ctrl(vn, _phase->get_ctrl(opd));
a61af66fc99e Initial load
duke
parents:
diff changeset
1062 return vn;
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1064
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 // Insert pack operation
a61af66fc99e Initial load
duke
parents:
diff changeset
1066 const Type* opd_t = velt_type(!in_bb(opd) ? p0 : opd);
a61af66fc99e Initial load
duke
parents:
diff changeset
1067 PackNode* pk = PackNode::make(_phase->C, opd, opd_t);
a61af66fc99e Initial load
duke
parents:
diff changeset
1068
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 for (uint i = 1; i < vlen; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1070 Node* pi = p->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 Node* in = pi->in(opd_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 assert(my_pack(in) == NULL, "Should already have been unpacked");
a61af66fc99e Initial load
duke
parents:
diff changeset
1073 assert(opd_t == velt_type(!in_bb(in) ? pi : in), "all same type");
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 pk->add_opd(in);
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1076 _phase->_igvn.register_new_node_with_optimizer(pk);
a61af66fc99e Initial load
duke
parents:
diff changeset
1077 _phase->set_ctrl(pk, _phase->get_ctrl(opd));
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 return pk;
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1080
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 //------------------------------insert_extracts---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1082 // If a use of pack p is not a vector use, then replace the
a61af66fc99e Initial load
duke
parents:
diff changeset
1083 // use with an extract operation.
a61af66fc99e Initial load
duke
parents:
diff changeset
1084 void SuperWord::insert_extracts(Node_List* p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1085 if (p->at(0)->is_Store()) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 assert(_n_idx_list.is_empty(), "empty (node,index) list");
a61af66fc99e Initial load
duke
parents:
diff changeset
1087
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 // Inspect each use of each pack member. For each use that is
a61af66fc99e Initial load
duke
parents:
diff changeset
1089 // not a vector use, replace the use with an extract operation.
a61af66fc99e Initial load
duke
parents:
diff changeset
1090
a61af66fc99e Initial load
duke
parents:
diff changeset
1091 for (uint i = 0; i < p->size(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1092 Node* def = p->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1093 for (DUIterator_Fast jmax, j = def->fast_outs(jmax); j < jmax; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1094 Node* use = def->fast_out(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 for (uint k = 0; k < use->req(); k++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1096 Node* n = use->in(k);
a61af66fc99e Initial load
duke
parents:
diff changeset
1097 if (def == n) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1098 if (!is_vector_use(use, k)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1099 _n_idx_list.push(use, k);
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1101 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1102 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1104 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1105
a61af66fc99e Initial load
duke
parents:
diff changeset
1106 while (_n_idx_list.is_nonempty()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1107 Node* use = _n_idx_list.node();
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 int idx = _n_idx_list.index();
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 _n_idx_list.pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1110 Node* def = use->in(idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1111
a61af66fc99e Initial load
duke
parents:
diff changeset
1112 // Insert extract operation
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 _igvn.hash_delete(def);
a61af66fc99e Initial load
duke
parents:
diff changeset
1114 _igvn.hash_delete(use);
a61af66fc99e Initial load
duke
parents:
diff changeset
1115 int def_pos = alignment(def) / data_size(def);
a61af66fc99e Initial load
duke
parents:
diff changeset
1116 const Type* def_t = velt_type(def);
a61af66fc99e Initial load
duke
parents:
diff changeset
1117
a61af66fc99e Initial load
duke
parents:
diff changeset
1118 Node* ex = ExtractNode::make(_phase->C, def, def_pos, def_t);
a61af66fc99e Initial load
duke
parents:
diff changeset
1119 _phase->_igvn.register_new_node_with_optimizer(ex);
a61af66fc99e Initial load
duke
parents:
diff changeset
1120 _phase->set_ctrl(ex, _phase->get_ctrl(def));
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 use->set_req(idx, ex);
a61af66fc99e Initial load
duke
parents:
diff changeset
1122 _igvn._worklist.push(def);
a61af66fc99e Initial load
duke
parents:
diff changeset
1123 _igvn._worklist.push(use);
a61af66fc99e Initial load
duke
parents:
diff changeset
1124
a61af66fc99e Initial load
duke
parents:
diff changeset
1125 bb_insert_after(ex, bb_idx(def));
a61af66fc99e Initial load
duke
parents:
diff changeset
1126 set_velt_type(ex, def_t);
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1128 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1129
a61af66fc99e Initial load
duke
parents:
diff changeset
1130 //------------------------------is_vector_use---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 // Is use->in(u_idx) a vector use?
a61af66fc99e Initial load
duke
parents:
diff changeset
1132 bool SuperWord::is_vector_use(Node* use, int u_idx) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1133 Node_List* u_pk = my_pack(use);
a61af66fc99e Initial load
duke
parents:
diff changeset
1134 if (u_pk == NULL) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1135 Node* def = use->in(u_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1136 Node_List* d_pk = my_pack(def);
a61af66fc99e Initial load
duke
parents:
diff changeset
1137 if (d_pk == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1138 // check for scalar promotion
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 Node* n = u_pk->at(0)->in(u_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 for (uint i = 1; i < u_pk->size(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1141 if (u_pk->at(i)->in(u_idx) != n) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1142 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1144 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1145 if (u_pk->size() != d_pk->size())
a61af66fc99e Initial load
duke
parents:
diff changeset
1146 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 for (uint i = 0; i < u_pk->size(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1148 Node* ui = u_pk->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1149 Node* di = d_pk->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 if (ui->in(u_idx) != di || alignment(ui) != alignment(di))
a61af66fc99e Initial load
duke
parents:
diff changeset
1151 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1152 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1153 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1154 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1155
a61af66fc99e Initial load
duke
parents:
diff changeset
1156 //------------------------------construct_bb---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1157 // Construct reverse postorder list of block members
a61af66fc99e Initial load
duke
parents:
diff changeset
1158 void SuperWord::construct_bb() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 Node* entry = bb();
a61af66fc99e Initial load
duke
parents:
diff changeset
1160
a61af66fc99e Initial load
duke
parents:
diff changeset
1161 assert(_stk.length() == 0, "stk is empty");
a61af66fc99e Initial load
duke
parents:
diff changeset
1162 assert(_block.length() == 0, "block is empty");
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 assert(_data_entry.length() == 0, "data_entry is empty");
a61af66fc99e Initial load
duke
parents:
diff changeset
1164 assert(_mem_slice_head.length() == 0, "mem_slice_head is empty");
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 assert(_mem_slice_tail.length() == 0, "mem_slice_tail is empty");
a61af66fc99e Initial load
duke
parents:
diff changeset
1166
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 // Find non-control nodes with no inputs from within block,
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 // create a temporary map from node _idx to bb_idx for use
a61af66fc99e Initial load
duke
parents:
diff changeset
1169 // by the visited and post_visited sets,
a61af66fc99e Initial load
duke
parents:
diff changeset
1170 // and count number of nodes in block.
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 int bb_ct = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1172 for (uint i = 0; i < lpt()->_body.size(); i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1173 Node *n = lpt()->_body.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1174 set_bb_idx(n, i); // Create a temporary map
a61af66fc99e Initial load
duke
parents:
diff changeset
1175 if (in_bb(n)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1176 bb_ct++;
a61af66fc99e Initial load
duke
parents:
diff changeset
1177 if (!n->is_CFG()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1178 bool found = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1179 for (uint j = 0; j < n->req(); j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 Node* def = n->in(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
1181 if (def && in_bb(def)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1182 found = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1185 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1186 if (!found) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1187 assert(n != entry, "can't be entry");
a61af66fc99e Initial load
duke
parents:
diff changeset
1188 _data_entry.push(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
1189 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1190 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1192 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1193
a61af66fc99e Initial load
duke
parents:
diff changeset
1194 // Find memory slices (head and tail)
a61af66fc99e Initial load
duke
parents:
diff changeset
1195 for (DUIterator_Fast imax, i = lp()->fast_outs(imax); i < imax; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1196 Node *n = lp()->fast_out(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1197 if (in_bb(n) && (n->is_Phi() && n->bottom_type() == Type::MEMORY)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1198 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
1199 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
1200 _mem_slice_head.push(n);
b0fe4deeb9fb 6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents: 235
diff changeset
1201 _mem_slice_tail.push(n_tail);
b0fe4deeb9fb 6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents: 235
diff changeset
1202 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1203 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1204 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1205
a61af66fc99e Initial load
duke
parents:
diff changeset
1206 // Create an RPO list of nodes in block
a61af66fc99e Initial load
duke
parents:
diff changeset
1207
a61af66fc99e Initial load
duke
parents:
diff changeset
1208 visited_clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
1209 post_visited_clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
1210
a61af66fc99e Initial load
duke
parents:
diff changeset
1211 // Push all non-control nodes with no inputs from within block, then control entry
a61af66fc99e Initial load
duke
parents:
diff changeset
1212 for (int j = 0; j < _data_entry.length(); j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1213 Node* n = _data_entry.at(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
1214 visited_set(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
1215 _stk.push(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
1216 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1217 visited_set(entry);
a61af66fc99e Initial load
duke
parents:
diff changeset
1218 _stk.push(entry);
a61af66fc99e Initial load
duke
parents:
diff changeset
1219
a61af66fc99e Initial load
duke
parents:
diff changeset
1220 // Do a depth first walk over out edges
a61af66fc99e Initial load
duke
parents:
diff changeset
1221 int rpo_idx = bb_ct - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1222 int size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1223 while ((size = _stk.length()) > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1224 Node* n = _stk.top(); // Leave node on stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1225 if (!visited_test_set(n)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1226 // forward arc in graph
a61af66fc99e Initial load
duke
parents:
diff changeset
1227 } else if (!post_visited_test(n)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1228 // cross or back arc
a61af66fc99e Initial load
duke
parents:
diff changeset
1229 for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1230 Node *use = n->fast_out(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1231 if (in_bb(use) && !visited_test(use) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1232 // Don't go around backedge
a61af66fc99e Initial load
duke
parents:
diff changeset
1233 (!use->is_Phi() || n == entry)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1234 _stk.push(use);
a61af66fc99e Initial load
duke
parents:
diff changeset
1235 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1236 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1237 if (_stk.length() == size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1238 // There were no additional uses, post visit node now
a61af66fc99e Initial load
duke
parents:
diff changeset
1239 _stk.pop(); // Remove node from stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1240 assert(rpo_idx >= 0, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1241 _block.at_put_grow(rpo_idx, n);
a61af66fc99e Initial load
duke
parents:
diff changeset
1242 rpo_idx--;
a61af66fc99e Initial load
duke
parents:
diff changeset
1243 post_visited_set(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
1244 assert(rpo_idx >= 0 || _stk.is_empty(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1245 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1246 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1247 _stk.pop(); // Remove post-visited node from stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1248 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1249 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1250
a61af66fc99e Initial load
duke
parents:
diff changeset
1251 // Create real map of block indices for nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
1252 for (int j = 0; j < _block.length(); j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1253 Node* n = _block.at(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 set_bb_idx(n, j);
a61af66fc99e Initial load
duke
parents:
diff changeset
1255 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1256
a61af66fc99e Initial load
duke
parents:
diff changeset
1257 initialize_bb(); // Ensure extra info is allocated.
a61af66fc99e Initial load
duke
parents:
diff changeset
1258
a61af66fc99e Initial load
duke
parents:
diff changeset
1259 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1260 if (TraceSuperWord) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1261 print_bb();
a61af66fc99e Initial load
duke
parents:
diff changeset
1262 tty->print_cr("\ndata entry nodes: %s", _data_entry.length() > 0 ? "" : "NONE");
a61af66fc99e Initial load
duke
parents:
diff changeset
1263 for (int m = 0; m < _data_entry.length(); m++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1264 tty->print("%3d ", m);
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 _data_entry.at(m)->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1266 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1267 tty->print_cr("\nmemory slices: %s", _mem_slice_head.length() > 0 ? "" : "NONE");
a61af66fc99e Initial load
duke
parents:
diff changeset
1268 for (int m = 0; m < _mem_slice_head.length(); m++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1269 tty->print("%3d ", m); _mem_slice_head.at(m)->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1270 tty->print(" "); _mem_slice_tail.at(m)->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1271 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1272 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1273 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 assert(rpo_idx == -1 && bb_ct == _block.length(), "all block members found");
a61af66fc99e Initial load
duke
parents:
diff changeset
1275 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1276
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 //------------------------------initialize_bb---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1278 // Initialize per node info
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 void SuperWord::initialize_bb() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1280 Node* last = _block.at(_block.length() - 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1281 grow_node_info(bb_idx(last));
a61af66fc99e Initial load
duke
parents:
diff changeset
1282 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1283
a61af66fc99e Initial load
duke
parents:
diff changeset
1284 //------------------------------bb_insert_after---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1285 // Insert n into block after pos
a61af66fc99e Initial load
duke
parents:
diff changeset
1286 void SuperWord::bb_insert_after(Node* n, int pos) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1287 int n_pos = pos + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1288 // Make room
a61af66fc99e Initial load
duke
parents:
diff changeset
1289 for (int i = _block.length() - 1; i >= n_pos; i--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1290 _block.at_put_grow(i+1, _block.at(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
1291 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1292 for (int j = _node_info.length() - 1; j >= n_pos; j--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1293 _node_info.at_put_grow(j+1, _node_info.at(j));
a61af66fc99e Initial load
duke
parents:
diff changeset
1294 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1295 // Set value
a61af66fc99e Initial load
duke
parents:
diff changeset
1296 _block.at_put_grow(n_pos, n);
a61af66fc99e Initial load
duke
parents:
diff changeset
1297 _node_info.at_put_grow(n_pos, SWNodeInfo::initial);
a61af66fc99e Initial load
duke
parents:
diff changeset
1298 // Adjust map from node->_idx to _block index
a61af66fc99e Initial load
duke
parents:
diff changeset
1299 for (int i = n_pos; i < _block.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1300 set_bb_idx(_block.at(i), i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1301 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1302 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1303
a61af66fc99e Initial load
duke
parents:
diff changeset
1304 //------------------------------compute_max_depth---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1305 // Compute max depth for expressions from beginning of block
a61af66fc99e Initial load
duke
parents:
diff changeset
1306 // Use to prune search paths during test for independence.
a61af66fc99e Initial load
duke
parents:
diff changeset
1307 void SuperWord::compute_max_depth() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1308 int ct = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1309 bool again;
a61af66fc99e Initial load
duke
parents:
diff changeset
1310 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
1311 again = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1312 for (int i = 0; i < _block.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1313 Node* n = _block.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1314 if (!n->is_Phi()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1315 int d_orig = depth(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
1316 int d_in = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1317 for (DepPreds preds(n, _dg); !preds.done(); preds.next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1318 Node* pred = preds.current();
a61af66fc99e Initial load
duke
parents:
diff changeset
1319 if (in_bb(pred)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1320 d_in = MAX2(d_in, depth(pred));
a61af66fc99e Initial load
duke
parents:
diff changeset
1321 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1322 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1323 if (d_in + 1 != d_orig) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1324 set_depth(n, d_in + 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1325 again = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1326 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1327 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1328 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1329 ct++;
a61af66fc99e Initial load
duke
parents:
diff changeset
1330 } while (again);
a61af66fc99e Initial load
duke
parents:
diff changeset
1331 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1332 if (TraceSuperWord && Verbose)
a61af66fc99e Initial load
duke
parents:
diff changeset
1333 tty->print_cr("compute_max_depth iterated: %d times", ct);
a61af66fc99e Initial load
duke
parents:
diff changeset
1334 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1335 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1336
a61af66fc99e Initial load
duke
parents:
diff changeset
1337 //-------------------------compute_vector_element_type-----------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1338 // Compute necessary vector element type for expressions
a61af66fc99e Initial load
duke
parents:
diff changeset
1339 // This propagates backwards a narrower integer type when the
a61af66fc99e Initial load
duke
parents:
diff changeset
1340 // upper bits of the value are not needed.
a61af66fc99e Initial load
duke
parents:
diff changeset
1341 // Example: char a,b,c; a = b + c;
a61af66fc99e Initial load
duke
parents:
diff changeset
1342 // Normally the type of the add is integer, but for packed character
a61af66fc99e Initial load
duke
parents:
diff changeset
1343 // operations the type of the add needs to be char.
a61af66fc99e Initial load
duke
parents:
diff changeset
1344 void SuperWord::compute_vector_element_type() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1345 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1346 if (TraceSuperWord && Verbose)
a61af66fc99e Initial load
duke
parents:
diff changeset
1347 tty->print_cr("\ncompute_velt_type:");
a61af66fc99e Initial load
duke
parents:
diff changeset
1348 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1349
a61af66fc99e Initial load
duke
parents:
diff changeset
1350 // Initial type
a61af66fc99e Initial load
duke
parents:
diff changeset
1351 for (int i = 0; i < _block.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1352 Node* n = _block.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1353 const Type* t = n->is_Mem() ? Type::get_const_basic_type(n->as_Mem()->memory_type())
a61af66fc99e Initial load
duke
parents:
diff changeset
1354 : _igvn.type(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
1355 const Type* vt = container_type(t);
a61af66fc99e Initial load
duke
parents:
diff changeset
1356 set_velt_type(n, vt);
a61af66fc99e Initial load
duke
parents:
diff changeset
1357 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1358
a61af66fc99e Initial load
duke
parents:
diff changeset
1359 // Propagate narrowed type backwards through operations
a61af66fc99e Initial load
duke
parents:
diff changeset
1360 // that don't depend on higher order bits
a61af66fc99e Initial load
duke
parents:
diff changeset
1361 for (int i = _block.length() - 1; i >= 0; i--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1362 Node* n = _block.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1363 // Only integer types need be examined
a61af66fc99e Initial load
duke
parents:
diff changeset
1364 if (n->bottom_type()->isa_int()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1365 uint start, end;
a61af66fc99e Initial load
duke
parents:
diff changeset
1366 vector_opd_range(n, &start, &end);
a61af66fc99e Initial load
duke
parents:
diff changeset
1367 const Type* vt = velt_type(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
1368
a61af66fc99e Initial load
duke
parents:
diff changeset
1369 for (uint j = start; j < end; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1370 Node* in = n->in(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
1371 // Don't propagate through a type conversion
a61af66fc99e Initial load
duke
parents:
diff changeset
1372 if (n->bottom_type() != in->bottom_type())
a61af66fc99e Initial load
duke
parents:
diff changeset
1373 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1374 switch(in->Opcode()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1375 case Op_AddI: case Op_AddL:
a61af66fc99e Initial load
duke
parents:
diff changeset
1376 case Op_SubI: case Op_SubL:
a61af66fc99e Initial load
duke
parents:
diff changeset
1377 case Op_MulI: case Op_MulL:
a61af66fc99e Initial load
duke
parents:
diff changeset
1378 case Op_AndI: case Op_AndL:
a61af66fc99e Initial load
duke
parents:
diff changeset
1379 case Op_OrI: case Op_OrL:
a61af66fc99e Initial load
duke
parents:
diff changeset
1380 case Op_XorI: case Op_XorL:
a61af66fc99e Initial load
duke
parents:
diff changeset
1381 case Op_LShiftI: case Op_LShiftL:
a61af66fc99e Initial load
duke
parents:
diff changeset
1382 case Op_CMoveI: case Op_CMoveL:
a61af66fc99e Initial load
duke
parents:
diff changeset
1383 if (in_bb(in)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1384 bool same_type = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1385 for (DUIterator_Fast kmax, k = in->fast_outs(kmax); k < kmax; k++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1386 Node *use = in->fast_out(k);
a61af66fc99e Initial load
duke
parents:
diff changeset
1387 if (!in_bb(use) || velt_type(use) != vt) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1388 same_type = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1389 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1390 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1391 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1392 if (same_type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1393 set_velt_type(in, vt);
a61af66fc99e Initial load
duke
parents:
diff changeset
1394 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1395 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1396 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1397 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1398 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1399 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1400 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1401 if (TraceSuperWord && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1402 for (int i = 0; i < _block.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1403 Node* n = _block.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1404 velt_type(n)->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1405 tty->print("\t");
a61af66fc99e Initial load
duke
parents:
diff changeset
1406 n->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1407 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1408 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1409 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1410 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1411
a61af66fc99e Initial load
duke
parents:
diff changeset
1412 //------------------------------memory_alignment---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1413 // Alignment within a vector memory reference
a61af66fc99e Initial load
duke
parents:
diff changeset
1414 int SuperWord::memory_alignment(MemNode* s, int iv_adjust_in_bytes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1415 SWPointer p(s, this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1416 if (!p.valid()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1417 return bottom_align;
a61af66fc99e Initial load
duke
parents:
diff changeset
1418 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1419 int offset = p.offset_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
1420 offset += iv_adjust_in_bytes;
a61af66fc99e Initial load
duke
parents:
diff changeset
1421 int off_rem = offset % vector_width_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
1422 int off_mod = off_rem >= 0 ? off_rem : off_rem + vector_width_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
1423 return off_mod;
a61af66fc99e Initial load
duke
parents:
diff changeset
1424 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1425
a61af66fc99e Initial load
duke
parents:
diff changeset
1426 //---------------------------container_type---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1427 // Smallest type containing range of values
a61af66fc99e Initial load
duke
parents:
diff changeset
1428 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
1429 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
1430 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
1431 t = tp->is_aryptr()->elem();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1432 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1433 if (t->basic_type() == T_INT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1434 if (t->higher_equal(TypeInt::BOOL)) return TypeInt::BOOL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1435 if (t->higher_equal(TypeInt::BYTE)) return TypeInt::BYTE;
a61af66fc99e Initial load
duke
parents:
diff changeset
1436 if (t->higher_equal(TypeInt::CHAR)) return TypeInt::CHAR;
a61af66fc99e Initial load
duke
parents:
diff changeset
1437 if (t->higher_equal(TypeInt::SHORT)) return TypeInt::SHORT;
a61af66fc99e Initial load
duke
parents:
diff changeset
1438 return TypeInt::INT;
a61af66fc99e Initial load
duke
parents:
diff changeset
1439 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1440 return t;
a61af66fc99e Initial load
duke
parents:
diff changeset
1441 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1442
a61af66fc99e Initial load
duke
parents:
diff changeset
1443 //-------------------------vector_opd_range-----------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1444 // (Start, end] half-open range defining which operands are vector
a61af66fc99e Initial load
duke
parents:
diff changeset
1445 void SuperWord::vector_opd_range(Node* n, uint* start, uint* end) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1446 switch (n->Opcode()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1447 case Op_LoadB: case Op_LoadC:
a61af66fc99e Initial load
duke
parents:
diff changeset
1448 case Op_LoadI: case Op_LoadL:
a61af66fc99e Initial load
duke
parents:
diff changeset
1449 case Op_LoadF: case Op_LoadD:
a61af66fc99e Initial load
duke
parents:
diff changeset
1450 case Op_LoadP:
a61af66fc99e Initial load
duke
parents:
diff changeset
1451 *start = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1452 *end = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1453 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1454 case Op_StoreB: case Op_StoreC:
a61af66fc99e Initial load
duke
parents:
diff changeset
1455 case Op_StoreI: case Op_StoreL:
a61af66fc99e Initial load
duke
parents:
diff changeset
1456 case Op_StoreF: case Op_StoreD:
a61af66fc99e Initial load
duke
parents:
diff changeset
1457 case Op_StoreP:
a61af66fc99e Initial load
duke
parents:
diff changeset
1458 *start = MemNode::ValueIn;
a61af66fc99e Initial load
duke
parents:
diff changeset
1459 *end = *start + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1460 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1461 case Op_LShiftI: case Op_LShiftL:
a61af66fc99e Initial load
duke
parents:
diff changeset
1462 *start = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1463 *end = 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
1464 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1465 case Op_CMoveI: case Op_CMoveL: case Op_CMoveF: case Op_CMoveD:
a61af66fc99e Initial load
duke
parents:
diff changeset
1466 *start = 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
1467 *end = n->req();
a61af66fc99e Initial load
duke
parents:
diff changeset
1468 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1469 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1470 *start = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1471 *end = n->req(); // default is all operands
a61af66fc99e Initial load
duke
parents:
diff changeset
1472 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1473
a61af66fc99e Initial load
duke
parents:
diff changeset
1474 //------------------------------in_packset---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1475 // Are s1 and s2 in a pack pair and ordered as s1,s2?
a61af66fc99e Initial load
duke
parents:
diff changeset
1476 bool SuperWord::in_packset(Node* s1, Node* s2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1477 for (int i = 0; i < _packset.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1478 Node_List* p = _packset.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1479 assert(p->size() == 2, "must be");
a61af66fc99e Initial load
duke
parents:
diff changeset
1480 if (p->at(0) == s1 && p->at(p->size()-1) == s2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1481 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1482 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1483 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1484 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1485 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1486
a61af66fc99e Initial load
duke
parents:
diff changeset
1487 //------------------------------in_pack---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1488 // Is s in pack p?
a61af66fc99e Initial load
duke
parents:
diff changeset
1489 Node_List* SuperWord::in_pack(Node* s, Node_List* p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1490 for (uint i = 0; i < p->size(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1491 if (p->at(i) == s) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1492 return p;
a61af66fc99e Initial load
duke
parents:
diff changeset
1493 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1494 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1495 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1496 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1497
a61af66fc99e Initial load
duke
parents:
diff changeset
1498 //------------------------------remove_pack_at---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1499 // Remove the pack at position pos in the packset
a61af66fc99e Initial load
duke
parents:
diff changeset
1500 void SuperWord::remove_pack_at(int pos) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1501 Node_List* p = _packset.at(pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
1502 for (uint i = 0; i < p->size(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1503 Node* s = p->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1504 set_my_pack(s, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1505 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1506 _packset.remove_at(pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
1507 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1508
a61af66fc99e Initial load
duke
parents:
diff changeset
1509 //------------------------------executed_first---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1510 // Return the node executed first in pack p. Uses the RPO block list
a61af66fc99e Initial load
duke
parents:
diff changeset
1511 // to determine order.
a61af66fc99e Initial load
duke
parents:
diff changeset
1512 Node* SuperWord::executed_first(Node_List* p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1513 Node* n = p->at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1514 int n_rpo = bb_idx(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
1515 for (uint i = 1; i < p->size(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1516 Node* s = p->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1517 int s_rpo = bb_idx(s);
a61af66fc99e Initial load
duke
parents:
diff changeset
1518 if (s_rpo < n_rpo) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1519 n = s;
a61af66fc99e Initial load
duke
parents:
diff changeset
1520 n_rpo = s_rpo;
a61af66fc99e Initial load
duke
parents:
diff changeset
1521 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1522 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1523 return n;
a61af66fc99e Initial load
duke
parents:
diff changeset
1524 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1525
a61af66fc99e Initial load
duke
parents:
diff changeset
1526 //------------------------------executed_last---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1527 // Return the node executed last in pack p.
a61af66fc99e Initial load
duke
parents:
diff changeset
1528 Node* SuperWord::executed_last(Node_List* p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1529 Node* n = p->at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1530 int n_rpo = bb_idx(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
1531 for (uint i = 1; i < p->size(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1532 Node* s = p->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1533 int s_rpo = bb_idx(s);
a61af66fc99e Initial load
duke
parents:
diff changeset
1534 if (s_rpo > n_rpo) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1535 n = s;
a61af66fc99e Initial load
duke
parents:
diff changeset
1536 n_rpo = s_rpo;
a61af66fc99e Initial load
duke
parents:
diff changeset
1537 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1538 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1539 return n;
a61af66fc99e Initial load
duke
parents:
diff changeset
1540 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1541
a61af66fc99e Initial load
duke
parents:
diff changeset
1542 //----------------------------align_initial_loop_index---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1543 // Adjust pre-loop limit so that in main loop, a load/store reference
a61af66fc99e Initial load
duke
parents:
diff changeset
1544 // to align_to_ref will be a position zero in the vector.
a61af66fc99e Initial load
duke
parents:
diff changeset
1545 // (iv + k) mod vector_align == 0
a61af66fc99e Initial load
duke
parents:
diff changeset
1546 void SuperWord::align_initial_loop_index(MemNode* align_to_ref) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1547 CountedLoopNode *main_head = lp()->as_CountedLoop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1548 assert(main_head->is_main_loop(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1549 CountedLoopEndNode* pre_end = get_pre_loop_end(main_head);
a61af66fc99e Initial load
duke
parents:
diff changeset
1550 assert(pre_end != NULL, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1551 Node *pre_opaq1 = pre_end->limit();
a61af66fc99e Initial load
duke
parents:
diff changeset
1552 assert(pre_opaq1->Opcode() == Op_Opaque1, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1553 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
1554 Node *lim0 = pre_opaq->in(1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1555
a61af66fc99e Initial load
duke
parents:
diff changeset
1556 // Where we put new limit calculations
a61af66fc99e Initial load
duke
parents:
diff changeset
1557 Node *pre_ctrl = pre_end->loopnode()->in(LoopNode::EntryControl);
a61af66fc99e Initial load
duke
parents:
diff changeset
1558
a61af66fc99e Initial load
duke
parents:
diff changeset
1559 // Ensure the original loop limit is available from the
a61af66fc99e Initial load
duke
parents:
diff changeset
1560 // pre-loop Opaque1 node.
a61af66fc99e Initial load
duke
parents:
diff changeset
1561 Node *orig_limit = pre_opaq->original_loop_limit();
a61af66fc99e Initial load
duke
parents:
diff changeset
1562 assert(orig_limit != NULL && _igvn.type(orig_limit) != Type::TOP, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1563
a61af66fc99e Initial load
duke
parents:
diff changeset
1564 SWPointer align_to_ref_p(align_to_ref, this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1565
72
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1566 // Given:
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1567 // 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
1568 // 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
1569 // 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
1570 // e == k [ +/- invar ]
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1571 //
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1572 // 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
1573 // (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
1574 // and:
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1575 // (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
1576 //
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1577 // 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
1578 // 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
1579 // (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
1580 // (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
1581 // are true.
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1582 //
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1583 // 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
1584 // (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
1585 // solve for N:
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1586 // 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
1587 // 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
1588 // lim = lim0 + (V - (e + lim0)) % V
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1589 //
72
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1590 // 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
1591 // Constraints:
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1592 // lim = lim0 + N
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1593 // (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
1594 // Solving for lim:
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1595 // (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
1596 // 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
1597 // 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
1598 //
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1599 // 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
1600 // Constraints:
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1601 // lim = lim0 - N
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1602 // (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
1603 // Solving for lim:
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1604 // (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
1605 // 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
1606 // 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
1607 //
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1608 // 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
1609 // Constraints:
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1610 // lim = lim0 - N
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1611 // (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
1612 // Solving for lim:
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1613 // (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
1614 // 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
1615 // lim = lim0 - (V - (e - lim0)) % V
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1616
72
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1617 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
1618 int scale = align_to_ref_p.scale_in_bytes();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1619 int elt_size = align_to_ref_p.memory_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
1620 int v_align = vector_width_in_bytes() / elt_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1621 int k = align_to_ref_p.offset_in_bytes() / elt_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1622
a61af66fc99e Initial load
duke
parents:
diff changeset
1623 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
1624
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1625 Node *e = kn;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1626 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
1627 // incorporate any extra invariant piece producing k +/- invar >>> log2(elt)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1628 Node* log2_elt = _igvn.intcon(exact_log2(elt_size));
a61af66fc99e Initial load
duke
parents:
diff changeset
1629 Node* aref = new (_phase->C, 3) URShiftINode(align_to_ref_p.invar(), log2_elt);
a61af66fc99e Initial load
duke
parents:
diff changeset
1630 _phase->_igvn.register_new_node_with_optimizer(aref);
a61af66fc99e Initial load
duke
parents:
diff changeset
1631 _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
1632 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
1633 e = new (_phase->C, 3) SubINode(e, aref);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1634 } else {
72
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1635 e = new (_phase->C, 3) AddINode(e, aref);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1636 }
72
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1637 _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
1638 _phase->set_ctrl(e, pre_ctrl);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1639 }
72
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1640
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1641 // compute e +/- lim0
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1642 if (scale < 0) {
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1643 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
1644 } else {
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1645 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
1646 }
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1647 _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
1648 _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
1649
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1650 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
1651 // compute V - (e +/- lim0)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1652 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
1653 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
1654 _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
1655 _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
1656 }
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1657 // 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
1658 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
1659 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
1660 _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
1661 _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
1662
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1663 // 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
1664 // lim = lim0 + N
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1665 Node* lim;
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1666 if (stride < 0) {
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1667 lim = new (_phase->C, 3) SubINode(lim0, N);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1668 } else {
72
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1669 lim = new (_phase->C, 3) AddINode(lim0, N);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1670 }
72
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1671 _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
1672 _phase->set_ctrl(lim, pre_ctrl);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1673 Node* constrained =
72
f705f25597eb 6663621: JVM crashes while trying to execute api/java_security/Signature/SignatureTests.html#initSign tests.
never
parents: 29
diff changeset
1674 (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
1675 : (Node*) new (_phase->C,3) MaxINode(lim, orig_limit);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1676 _phase->_igvn.register_new_node_with_optimizer(constrained);
a61af66fc99e Initial load
duke
parents:
diff changeset
1677 _phase->set_ctrl(constrained, pre_ctrl);
a61af66fc99e Initial load
duke
parents:
diff changeset
1678 _igvn.hash_delete(pre_opaq);
a61af66fc99e Initial load
duke
parents:
diff changeset
1679 pre_opaq->set_req(1, constrained);
a61af66fc99e Initial load
duke
parents:
diff changeset
1680 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1681
a61af66fc99e Initial load
duke
parents:
diff changeset
1682 //----------------------------get_pre_loop_end---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1683 // Find pre loop end from main loop. Returns null if none.
a61af66fc99e Initial load
duke
parents:
diff changeset
1684 CountedLoopEndNode* SuperWord::get_pre_loop_end(CountedLoopNode *cl) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1685 Node *ctrl = cl->in(LoopNode::EntryControl);
a61af66fc99e Initial load
duke
parents:
diff changeset
1686 if (!ctrl->is_IfTrue() && !ctrl->is_IfFalse()) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1687 Node *iffm = ctrl->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1688 if (!iffm->is_If()) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1689 Node *p_f = iffm->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1690 if (!p_f->is_IfFalse()) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1691 if (!p_f->in(0)->is_CountedLoopEnd()) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1692 CountedLoopEndNode *pre_end = p_f->in(0)->as_CountedLoopEnd();
a61af66fc99e Initial load
duke
parents:
diff changeset
1693 if (!pre_end->loopnode()->is_pre_loop()) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1694 return pre_end;
a61af66fc99e Initial load
duke
parents:
diff changeset
1695 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1696
a61af66fc99e Initial load
duke
parents:
diff changeset
1697
a61af66fc99e Initial load
duke
parents:
diff changeset
1698 //------------------------------init---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1699 void SuperWord::init() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1700 _dg.init();
a61af66fc99e Initial load
duke
parents:
diff changeset
1701 _packset.clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
1702 _disjoint_ptrs.clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
1703 _block.clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
1704 _data_entry.clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
1705 _mem_slice_head.clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
1706 _mem_slice_tail.clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
1707 _node_info.clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
1708 _align_to_ref = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1709 _lpt = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1710 _lp = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1711 _bb = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1712 _iv = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1713 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1714
a61af66fc99e Initial load
duke
parents:
diff changeset
1715 //------------------------------print_packset---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1716 void SuperWord::print_packset() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1717 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1718 tty->print_cr("packset");
a61af66fc99e Initial load
duke
parents:
diff changeset
1719 for (int i = 0; i < _packset.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1720 tty->print_cr("Pack: %d", i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1721 Node_List* p = _packset.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1722 print_pack(p);
a61af66fc99e Initial load
duke
parents:
diff changeset
1723 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1724 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1725 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1726
a61af66fc99e Initial load
duke
parents:
diff changeset
1727 //------------------------------print_pack---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1728 void SuperWord::print_pack(Node_List* p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1729 for (uint i = 0; i < p->size(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1730 print_stmt(p->at(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
1731 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1732 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1733
a61af66fc99e Initial load
duke
parents:
diff changeset
1734 //------------------------------print_bb---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1735 void SuperWord::print_bb() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1736 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1737 tty->print_cr("\nBlock");
a61af66fc99e Initial load
duke
parents:
diff changeset
1738 for (int i = 0; i < _block.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1739 Node* n = _block.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1740 tty->print("%d ", i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1741 if (n) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1742 n->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1743 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1744 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1745 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1746 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1747
a61af66fc99e Initial load
duke
parents:
diff changeset
1748 //------------------------------print_stmt---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1749 void SuperWord::print_stmt(Node* s) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1750 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1751 tty->print(" align: %d \t", alignment(s));
a61af66fc99e Initial load
duke
parents:
diff changeset
1752 s->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1753 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1754 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1755
a61af66fc99e Initial load
duke
parents:
diff changeset
1756 //------------------------------blank---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1757 char* SuperWord::blank(uint depth) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1758 static char blanks[101];
a61af66fc99e Initial load
duke
parents:
diff changeset
1759 assert(depth < 101, "too deep");
a61af66fc99e Initial load
duke
parents:
diff changeset
1760 for (uint i = 0; i < depth; i++) blanks[i] = ' ';
a61af66fc99e Initial load
duke
parents:
diff changeset
1761 blanks[depth] = '\0';
a61af66fc99e Initial load
duke
parents:
diff changeset
1762 return blanks;
a61af66fc99e Initial load
duke
parents:
diff changeset
1763 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1764
a61af66fc99e Initial load
duke
parents:
diff changeset
1765
a61af66fc99e Initial load
duke
parents:
diff changeset
1766 //==============================SWPointer===========================
a61af66fc99e Initial load
duke
parents:
diff changeset
1767
a61af66fc99e Initial load
duke
parents:
diff changeset
1768 //----------------------------SWPointer------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1769 SWPointer::SWPointer(MemNode* mem, SuperWord* slp) :
a61af66fc99e Initial load
duke
parents:
diff changeset
1770 _mem(mem), _slp(slp), _base(NULL), _adr(NULL),
a61af66fc99e Initial load
duke
parents:
diff changeset
1771 _scale(0), _offset(0), _invar(NULL), _negate_invar(false) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1772
a61af66fc99e Initial load
duke
parents:
diff changeset
1773 Node* adr = mem->in(MemNode::Address);
a61af66fc99e Initial load
duke
parents:
diff changeset
1774 if (!adr->is_AddP()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1775 assert(!valid(), "too complex");
a61af66fc99e Initial load
duke
parents:
diff changeset
1776 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1777 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1778 // Match AddP(base, AddP(ptr, k*iv [+ invariant]), constant)
a61af66fc99e Initial load
duke
parents:
diff changeset
1779 Node* base = adr->in(AddPNode::Base);
a61af66fc99e Initial load
duke
parents:
diff changeset
1780 for (int i = 0; i < 3; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1781 if (!scaled_iv_plus_offset(adr->in(AddPNode::Offset))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1782 assert(!valid(), "too complex");
a61af66fc99e Initial load
duke
parents:
diff changeset
1783 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1784 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1785 adr = adr->in(AddPNode::Address);
a61af66fc99e Initial load
duke
parents:
diff changeset
1786 if (base == adr || !adr->is_AddP()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1787 break; // stop looking at addp's
a61af66fc99e Initial load
duke
parents:
diff changeset
1788 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1789 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1790 _base = base;
a61af66fc99e Initial load
duke
parents:
diff changeset
1791 _adr = adr;
a61af66fc99e Initial load
duke
parents:
diff changeset
1792 assert(valid(), "Usable");
a61af66fc99e Initial load
duke
parents:
diff changeset
1793 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1794
a61af66fc99e Initial load
duke
parents:
diff changeset
1795 // Following is used to create a temporary object during
a61af66fc99e Initial load
duke
parents:
diff changeset
1796 // the pattern match of an address expression.
a61af66fc99e Initial load
duke
parents:
diff changeset
1797 SWPointer::SWPointer(SWPointer* p) :
a61af66fc99e Initial load
duke
parents:
diff changeset
1798 _mem(p->_mem), _slp(p->_slp), _base(NULL), _adr(NULL),
a61af66fc99e Initial load
duke
parents:
diff changeset
1799 _scale(0), _offset(0), _invar(NULL), _negate_invar(false) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
1800
a61af66fc99e Initial load
duke
parents:
diff changeset
1801 //------------------------scaled_iv_plus_offset--------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1802 // Match: k*iv + offset
a61af66fc99e Initial load
duke
parents:
diff changeset
1803 // where: k is a constant that maybe zero, and
a61af66fc99e Initial load
duke
parents:
diff changeset
1804 // offset is (k2 [+/- invariant]) where k2 maybe zero and invariant is optional
a61af66fc99e Initial load
duke
parents:
diff changeset
1805 bool SWPointer::scaled_iv_plus_offset(Node* n) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1806 if (scaled_iv(n)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1807 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1808 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1809 if (offset_plus_k(n)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1810 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1811 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1812 int opc = n->Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
1813 if (opc == Op_AddI) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1814 if (scaled_iv(n->in(1)) && offset_plus_k(n->in(2))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1815 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1816 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1817 if (scaled_iv(n->in(2)) && offset_plus_k(n->in(1))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1818 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1819 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1820 } else if (opc == Op_SubI) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1821 if (scaled_iv(n->in(1)) && offset_plus_k(n->in(2), true)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1822 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1823 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1824 if (scaled_iv(n->in(2)) && offset_plus_k(n->in(1))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1825 _scale *= -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1826 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1827 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1828 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1829 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1830 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1831
a61af66fc99e Initial load
duke
parents:
diff changeset
1832 //----------------------------scaled_iv------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1833 // Match: k*iv where k is a constant that's not zero
a61af66fc99e Initial load
duke
parents:
diff changeset
1834 bool SWPointer::scaled_iv(Node* n) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1835 if (_scale != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1836 return false; // already found a scale
a61af66fc99e Initial load
duke
parents:
diff changeset
1837 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1838 if (n == iv()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1839 _scale = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1840 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1841 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1842 int opc = n->Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
1843 if (opc == Op_MulI) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1844 if (n->in(1) == iv() && n->in(2)->is_Con()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1845 _scale = n->in(2)->get_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
1846 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1847 } else if (n->in(2) == iv() && n->in(1)->is_Con()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1848 _scale = n->in(1)->get_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
1849 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1850 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1851 } else if (opc == Op_LShiftI) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1852 if (n->in(1) == iv() && n->in(2)->is_Con()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1853 _scale = 1 << n->in(2)->get_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
1854 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1855 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1856 } else if (opc == Op_ConvI2L) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1857 if (scaled_iv_plus_offset(n->in(1))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1858 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1859 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1860 } else if (opc == Op_LShiftL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1861 if (!has_iv() && _invar == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1862 // Need to preserve the current _offset value, so
a61af66fc99e Initial load
duke
parents:
diff changeset
1863 // create a temporary object for this expression subtree.
a61af66fc99e Initial load
duke
parents:
diff changeset
1864 // Hacky, so should re-engineer the address pattern match.
a61af66fc99e Initial load
duke
parents:
diff changeset
1865 SWPointer tmp(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1866 if (tmp.scaled_iv_plus_offset(n->in(1))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1867 if (tmp._invar == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1868 int mult = 1 << n->in(2)->get_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
1869 _scale = tmp._scale * mult;
a61af66fc99e Initial load
duke
parents:
diff changeset
1870 _offset += tmp._offset * mult;
a61af66fc99e Initial load
duke
parents:
diff changeset
1871 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1872 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1873 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1874 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1875 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1876 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1877 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1878
a61af66fc99e Initial load
duke
parents:
diff changeset
1879 //----------------------------offset_plus_k------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1880 // Match: offset is (k [+/- invariant])
a61af66fc99e Initial load
duke
parents:
diff changeset
1881 // where k maybe zero and invariant is optional, but not both.
a61af66fc99e Initial load
duke
parents:
diff changeset
1882 bool SWPointer::offset_plus_k(Node* n, bool negate) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1883 int opc = n->Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
1884 if (opc == Op_ConI) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1885 _offset += negate ? -(n->get_int()) : n->get_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
1886 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1887 } else if (opc == Op_ConL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1888 // Okay if value fits into an int
a61af66fc99e Initial load
duke
parents:
diff changeset
1889 const TypeLong* t = n->find_long_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1890 if (t->higher_equal(TypeLong::INT)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1891 jlong loff = n->get_long();
a61af66fc99e Initial load
duke
parents:
diff changeset
1892 jint off = (jint)loff;
a61af66fc99e Initial load
duke
parents:
diff changeset
1893 _offset += negate ? -off : loff;
a61af66fc99e Initial load
duke
parents:
diff changeset
1894 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1895 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1896 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1897 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1898 if (_invar != NULL) return false; // already have an invariant
a61af66fc99e Initial load
duke
parents:
diff changeset
1899 if (opc == Op_AddI) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1900 if (n->in(2)->is_Con() && invariant(n->in(1))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1901 _negate_invar = negate;
a61af66fc99e Initial load
duke
parents:
diff changeset
1902 _invar = n->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1903 _offset += negate ? -(n->in(2)->get_int()) : n->in(2)->get_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
1904 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1905 } else if (n->in(1)->is_Con() && invariant(n->in(2))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1906 _offset += negate ? -(n->in(1)->get_int()) : n->in(1)->get_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
1907 _negate_invar = negate;
a61af66fc99e Initial load
duke
parents:
diff changeset
1908 _invar = n->in(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1909 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1910 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1911 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1912 if (opc == Op_SubI) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1913 if (n->in(2)->is_Con() && invariant(n->in(1))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1914 _negate_invar = negate;
a61af66fc99e Initial load
duke
parents:
diff changeset
1915 _invar = n->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1916 _offset += !negate ? -(n->in(2)->get_int()) : n->in(2)->get_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
1917 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1918 } else if (n->in(1)->is_Con() && invariant(n->in(2))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1919 _offset += negate ? -(n->in(1)->get_int()) : n->in(1)->get_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
1920 _negate_invar = !negate;
a61af66fc99e Initial load
duke
parents:
diff changeset
1921 _invar = n->in(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1922 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1923 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1924 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1925 if (invariant(n)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1926 _negate_invar = negate;
a61af66fc99e Initial load
duke
parents:
diff changeset
1927 _invar = n;
a61af66fc99e Initial load
duke
parents:
diff changeset
1928 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1929 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1930 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1931 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1932
a61af66fc99e Initial load
duke
parents:
diff changeset
1933 //----------------------------print------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1934 void SWPointer::print() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1935 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1936 tty->print("base: %d adr: %d scale: %d offset: %d invar: %c%d\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
1937 _base != NULL ? _base->_idx : 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
1938 _adr != NULL ? _adr->_idx : 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
1939 _scale, _offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
1940 _negate_invar?'-':'+',
a61af66fc99e Initial load
duke
parents:
diff changeset
1941 _invar != NULL ? _invar->_idx : 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1942 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1943 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1944
a61af66fc99e Initial load
duke
parents:
diff changeset
1945 // ========================= OrderedPair =====================
a61af66fc99e Initial load
duke
parents:
diff changeset
1946
a61af66fc99e Initial load
duke
parents:
diff changeset
1947 const OrderedPair OrderedPair::initial;
a61af66fc99e Initial load
duke
parents:
diff changeset
1948
a61af66fc99e Initial load
duke
parents:
diff changeset
1949 // ========================= SWNodeInfo =====================
a61af66fc99e Initial load
duke
parents:
diff changeset
1950
a61af66fc99e Initial load
duke
parents:
diff changeset
1951 const SWNodeInfo SWNodeInfo::initial;
a61af66fc99e Initial load
duke
parents:
diff changeset
1952
a61af66fc99e Initial load
duke
parents:
diff changeset
1953
a61af66fc99e Initial load
duke
parents:
diff changeset
1954 // ============================ DepGraph ===========================
a61af66fc99e Initial load
duke
parents:
diff changeset
1955
a61af66fc99e Initial load
duke
parents:
diff changeset
1956 //------------------------------make_node---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1957 // Make a new dependence graph node for an ideal node.
a61af66fc99e Initial load
duke
parents:
diff changeset
1958 DepMem* DepGraph::make_node(Node* node) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1959 DepMem* m = new (_arena) DepMem(node);
a61af66fc99e Initial load
duke
parents:
diff changeset
1960 if (node != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1961 assert(_map.at_grow(node->_idx) == NULL, "one init only");
a61af66fc99e Initial load
duke
parents:
diff changeset
1962 _map.at_put_grow(node->_idx, m);
a61af66fc99e Initial load
duke
parents:
diff changeset
1963 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1964 return m;
a61af66fc99e Initial load
duke
parents:
diff changeset
1965 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1966
a61af66fc99e Initial load
duke
parents:
diff changeset
1967 //------------------------------make_edge---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1968 // Make a new dependence graph edge from dpred -> dsucc
a61af66fc99e Initial load
duke
parents:
diff changeset
1969 DepEdge* DepGraph::make_edge(DepMem* dpred, DepMem* dsucc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1970 DepEdge* e = new (_arena) DepEdge(dpred, dsucc, dsucc->in_head(), dpred->out_head());
a61af66fc99e Initial load
duke
parents:
diff changeset
1971 dpred->set_out_head(e);
a61af66fc99e Initial load
duke
parents:
diff changeset
1972 dsucc->set_in_head(e);
a61af66fc99e Initial load
duke
parents:
diff changeset
1973 return e;
a61af66fc99e Initial load
duke
parents:
diff changeset
1974 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1975
a61af66fc99e Initial load
duke
parents:
diff changeset
1976 // ========================== DepMem ========================
a61af66fc99e Initial load
duke
parents:
diff changeset
1977
a61af66fc99e Initial load
duke
parents:
diff changeset
1978 //------------------------------in_cnt---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1979 int DepMem::in_cnt() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1980 int ct = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1981 for (DepEdge* e = _in_head; e != NULL; e = e->next_in()) ct++;
a61af66fc99e Initial load
duke
parents:
diff changeset
1982 return ct;
a61af66fc99e Initial load
duke
parents:
diff changeset
1983 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1984
a61af66fc99e Initial load
duke
parents:
diff changeset
1985 //------------------------------out_cnt---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1986 int DepMem::out_cnt() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1987 int ct = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1988 for (DepEdge* e = _out_head; e != NULL; e = e->next_out()) ct++;
a61af66fc99e Initial load
duke
parents:
diff changeset
1989 return ct;
a61af66fc99e Initial load
duke
parents:
diff changeset
1990 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1991
a61af66fc99e Initial load
duke
parents:
diff changeset
1992 //------------------------------print-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1993 void DepMem::print() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1994 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1995 tty->print(" DepNode %d (", _node->_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1996 for (DepEdge* p = _in_head; p != NULL; p = p->next_in()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1997 Node* pred = p->pred()->node();
a61af66fc99e Initial load
duke
parents:
diff changeset
1998 tty->print(" %d", pred != NULL ? pred->_idx : 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1999 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2000 tty->print(") [");
a61af66fc99e Initial load
duke
parents:
diff changeset
2001 for (DepEdge* s = _out_head; s != NULL; s = s->next_out()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2002 Node* succ = s->succ()->node();
a61af66fc99e Initial load
duke
parents:
diff changeset
2003 tty->print(" %d", succ != NULL ? succ->_idx : 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2004 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2005 tty->print_cr(" ]");
a61af66fc99e Initial load
duke
parents:
diff changeset
2006 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2007 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2008
a61af66fc99e Initial load
duke
parents:
diff changeset
2009 // =========================== DepEdge =========================
a61af66fc99e Initial load
duke
parents:
diff changeset
2010
a61af66fc99e Initial load
duke
parents:
diff changeset
2011 //------------------------------DepPreds---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2012 void DepEdge::print() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2013 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
2014 tty->print_cr("DepEdge: %d [ %d ]", _pred->node()->_idx, _succ->node()->_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
2015 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2016 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2017
a61af66fc99e Initial load
duke
parents:
diff changeset
2018 // =========================== DepPreds =========================
a61af66fc99e Initial load
duke
parents:
diff changeset
2019 // Iterator over predecessor edges in the dependence graph.
a61af66fc99e Initial load
duke
parents:
diff changeset
2020
a61af66fc99e Initial load
duke
parents:
diff changeset
2021 //------------------------------DepPreds---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2022 DepPreds::DepPreds(Node* n, DepGraph& dg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2023 _n = n;
a61af66fc99e Initial load
duke
parents:
diff changeset
2024 _done = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2025 if (_n->is_Store() || _n->is_Load()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2026 _next_idx = MemNode::Address;
a61af66fc99e Initial load
duke
parents:
diff changeset
2027 _end_idx = n->req();
a61af66fc99e Initial load
duke
parents:
diff changeset
2028 _dep_next = dg.dep(_n)->in_head();
a61af66fc99e Initial load
duke
parents:
diff changeset
2029 } else if (_n->is_Mem()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2030 _next_idx = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2031 _end_idx = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2032 _dep_next = dg.dep(_n)->in_head();
a61af66fc99e Initial load
duke
parents:
diff changeset
2033 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2034 _next_idx = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2035 _end_idx = _n->req();
a61af66fc99e Initial load
duke
parents:
diff changeset
2036 _dep_next = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2037 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2038 next();
a61af66fc99e Initial load
duke
parents:
diff changeset
2039 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2040
a61af66fc99e Initial load
duke
parents:
diff changeset
2041 //------------------------------next---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2042 void DepPreds::next() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2043 if (_dep_next != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2044 _current = _dep_next->pred()->node();
a61af66fc99e Initial load
duke
parents:
diff changeset
2045 _dep_next = _dep_next->next_in();
a61af66fc99e Initial load
duke
parents:
diff changeset
2046 } else if (_next_idx < _end_idx) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2047 _current = _n->in(_next_idx++);
a61af66fc99e Initial load
duke
parents:
diff changeset
2048 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2049 _done = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2050 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2051 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2052
a61af66fc99e Initial load
duke
parents:
diff changeset
2053 // =========================== DepSuccs =========================
a61af66fc99e Initial load
duke
parents:
diff changeset
2054 // Iterator over successor edges in the dependence graph.
a61af66fc99e Initial load
duke
parents:
diff changeset
2055
a61af66fc99e Initial load
duke
parents:
diff changeset
2056 //------------------------------DepSuccs---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2057 DepSuccs::DepSuccs(Node* n, DepGraph& dg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2058 _n = n;
a61af66fc99e Initial load
duke
parents:
diff changeset
2059 _done = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2060 if (_n->is_Load()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2061 _next_idx = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2062 _end_idx = _n->outcnt();
a61af66fc99e Initial load
duke
parents:
diff changeset
2063 _dep_next = dg.dep(_n)->out_head();
a61af66fc99e Initial load
duke
parents:
diff changeset
2064 } else if (_n->is_Mem() || _n->is_Phi() && _n->bottom_type() == Type::MEMORY) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2065 _next_idx = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2066 _end_idx = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2067 _dep_next = dg.dep(_n)->out_head();
a61af66fc99e Initial load
duke
parents:
diff changeset
2068 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2069 _next_idx = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2070 _end_idx = _n->outcnt();
a61af66fc99e Initial load
duke
parents:
diff changeset
2071 _dep_next = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2072 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2073 next();
a61af66fc99e Initial load
duke
parents:
diff changeset
2074 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2075
a61af66fc99e Initial load
duke
parents:
diff changeset
2076 //-------------------------------next---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2077 void DepSuccs::next() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2078 if (_dep_next != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2079 _current = _dep_next->succ()->node();
a61af66fc99e Initial load
duke
parents:
diff changeset
2080 _dep_next = _dep_next->next_out();
a61af66fc99e Initial load
duke
parents:
diff changeset
2081 } else if (_next_idx < _end_idx) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2082 _current = _n->raw_out(_next_idx++);
a61af66fc99e Initial load
duke
parents:
diff changeset
2083 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2084 _done = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2085 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2086 }