Mon, 11 Jan 2016 16:02:42 +0100
8146792: Predicate moved after partial peel may lead to broken graph
Summary: partial peel can leave a pinned node between predicates and loop and prevent some loop predication
Reviewed-by: kvn, phh, andrew
src/share/vm/opto/loopPredicate.cpp | file | annotate | diff | comparison | revisions | |
test/compiler/loopopts/BadPredicateAfterPartialPeel.java | file | annotate | diff | comparison | revisions |
1.1 --- a/src/share/vm/opto/loopPredicate.cpp Wed Jan 29 07:06:55 2020 +0000 1.2 +++ b/src/share/vm/opto/loopPredicate.cpp Mon Jan 11 16:02:42 2016 +0100 1.3 @@ -502,7 +502,31 @@ 1.4 _lpt(lpt), _phase(lpt->_phase), 1.5 _visited(area), _invariant(area), _stack(area, 10 /* guess */), 1.6 _clone_visited(area), _old_new(area) 1.7 - {} 1.8 + { 1.9 + Node* head = _lpt->_head; 1.10 + Node* entry = head->in(LoopNode::EntryControl); 1.11 + if (entry->outcnt() != 1) { 1.12 + // If a node is pinned between the predicates and the loop 1.13 + // entry, we won't be able to move any node in the loop that 1.14 + // depends on it above it in a predicate. Mark all those nodes 1.15 + // as non loop invariatnt. 1.16 + Unique_Node_List wq; 1.17 + wq.push(entry); 1.18 + for (uint next = 0; next < wq.size(); ++next) { 1.19 + Node *n = wq.at(next); 1.20 + for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { 1.21 + Node* u = n->fast_out(i); 1.22 + if (!u->is_CFG()) { 1.23 + Node* c = _phase->get_ctrl(u); 1.24 + if (_lpt->is_member(_phase->get_loop(c)) || _phase->is_dominator(c, head)) { 1.25 + _visited.set(u->_idx); 1.26 + wq.push(u); 1.27 + } 1.28 + } 1.29 + } 1.30 + } 1.31 + } 1.32 + } 1.33 1.34 // Map old to n for invariance computation and clone 1.35 void map_ctrl(Node* old, Node* n) {
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/test/compiler/loopopts/BadPredicateAfterPartialPeel.java Mon Jan 11 16:02:42 2016 +0100 2.3 @@ -0,0 +1,312 @@ 2.4 +/* 2.5 + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. 2.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.7 + * 2.8 + * This code is free software; you can redistribute it and/or modify it 2.9 + * under the terms of the GNU General Public License version 2 only, as 2.10 + * published by the Free Software Foundation. 2.11 + * 2.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 2.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 2.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 2.15 + * version 2 for more details (a copy is included in the LICENSE file that 2.16 + * accompanied this code). 2.17 + * 2.18 + * You should have received a copy of the GNU General Public License version 2.19 + * 2 along with this work; if not, write to the Free Software Foundation, 2.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2.21 + * 2.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2.23 + * or visit www.oracle.com if you need additional information or have any 2.24 + * questions. 2.25 + * 2.26 + */ 2.27 + 2.28 +/** 2.29 + * @test 2.30 + * @bug 8146792 2.31 + * @summary Predicate moved after partial peel may lead to broken graph 2.32 + * @run main/othervm -XX:-TieredCompilation -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:CompileOnly=BadPredicateAfterPartialPeel::m -XX:CompileCommand=dontinline,BadPredicateAfterPartialPeel::not_inlined* -XX:CompileCommand=quiet BadPredicateAfterPartialPeel 2.33 + * 2.34 + */ 2.35 + 2.36 +public class BadPredicateAfterPartialPeel { 2.37 + 2.38 + static void not_inlined1() {} 2.39 + static void not_inlined4() {} 2.40 + 2.41 + static int m_helper(int i, int i3, int i4) { 2.42 + return i3 == 4 ? i4 : i; 2.43 + } 2.44 + 2.45 + static float[] array = new float[1000]; 2.46 + static int[] array2 = new int[1000]; 2.47 + 2.48 + boolean flag; 2.49 + int j; 2.50 + 2.51 + static void m(BadPredicateAfterPartialPeel o1, BadPredicateAfterPartialPeel o2, BadPredicateAfterPartialPeel o, int i4) { 2.52 + int i1 = 1; 2.53 + 2.54 + // To delay partial peeling to the loop opts pass right before CCP 2.55 + int i2 = 0; 2.56 + for (; i2 < 10; i2 += i1); 2.57 + i2 = i2 / 10; 2.58 + 2.59 + // Simplified during CCP: 2.60 + int i3 = 2; 2.61 + for (; i3 < 4; i3 *= 2); 2.62 + 2.63 + // Loop is partial peeled right before CCP 2.64 + int i = 0; 2.65 + boolean b = true; 2.66 + 2.67 + not_inlined1(); 2.68 + 2.69 + array[0] = -1; 2.70 + do { 2.71 + // peeled section starts here 2.72 + o.flag = false; 2.73 + o.j = 0; 2.74 + 2.75 + if (b) { 2.76 + // The following store will be pinned between 2.77 + // predicates and the loop after partial peeling. All 2.78 + // control flow will be optimized out and so nothing 2.79 + // will prevent predicates from being moved out the 2.80 + // loop. 2.81 + array[i] = 0; 2.82 + } 2.83 + if (array[0] != 0) { 2.84 + } 2.85 + if (i >= 10) { 2.86 + // peeled section ends here 2.87 + return; 2.88 + } 2.89 + i += i2; 2.90 + b = false; 2.91 + int i5 = m_helper(i, i3, i4); // This will be simpliflied during CCP 2.92 + if (array[i5] != 0) { // and this will become a predicate 2.93 + } 2.94 + if (o2.flag) { 2.95 + } 2.96 + // A bunch of stuff to grow loop body size and prevent peeling: 2.97 + array2[0] = 0; 2.98 + array2[1] = 0; 2.99 + array2[2] = 0; 2.100 + array2[3] = 0; 2.101 + array2[4] = 0; 2.102 + array2[5] = 0; 2.103 + array2[6] = 0; 2.104 + array2[7] = 0; 2.105 + array2[8] = 0; 2.106 + array2[9] = 0; 2.107 + array2[10] = 0; 2.108 + array2[11] = 0; 2.109 + array2[12] = 0; 2.110 + array2[13] = 0; 2.111 + array2[14] = 0; 2.112 + array2[15] = 0; 2.113 + array2[16] = 0; 2.114 + array2[17] = 0; 2.115 + array2[18] = 0; 2.116 + array2[19] = 0; 2.117 + array2[20] = 0; 2.118 + array2[21] = 0; 2.119 + array2[22] = 0; 2.120 + array2[23] = 0; 2.121 + array2[24] = 0; 2.122 + array2[25] = 0; 2.123 + array2[26] = 0; 2.124 + array2[27] = 0; 2.125 + array2[28] = 0; 2.126 + array2[29] = 0; 2.127 + array2[30] = 0; 2.128 + array2[31] = 0; 2.129 + array2[32] = 0; 2.130 + array2[33] = 0; 2.131 + array2[34] = 0; 2.132 + array2[35] = 0; 2.133 + array2[36] = 0; 2.134 + array2[37] = 0; 2.135 + array2[38] = 0; 2.136 + array2[39] = 0; 2.137 + array2[40] = 0; 2.138 + array2[41] = 0; 2.139 + array2[42] = 0; 2.140 + array2[43] = 0; 2.141 + array2[44] = 0; 2.142 + array2[45] = 0; 2.143 + array2[46] = 0; 2.144 + array2[47] = 0; 2.145 + array2[48] = 0; 2.146 + array2[49] = 0; 2.147 + array2[50] = 0; 2.148 + array2[51] = 0; 2.149 + array2[52] = 0; 2.150 + array2[53] = 0; 2.151 + array2[54] = 0; 2.152 + array2[55] = 0; 2.153 + array2[56] = 0; 2.154 + array2[57] = 0; 2.155 + array2[58] = 0; 2.156 + array2[59] = 0; 2.157 + array2[60] = 0; 2.158 + array2[61] = 0; 2.159 + array2[62] = 0; 2.160 + array2[63] = 0; 2.161 + array2[64] = 0; 2.162 + array2[65] = 0; 2.163 + array2[66] = 0; 2.164 + array2[67] = 0; 2.165 + array2[68] = 0; 2.166 + array2[69] = 0; 2.167 + array2[70] = 0; 2.168 + array2[71] = 0; 2.169 + array2[72] = 0; 2.170 + array2[73] = 0; 2.171 + array2[74] = 0; 2.172 + array2[75] = 0; 2.173 + array2[76] = 0; 2.174 + array2[77] = 0; 2.175 + array2[78] = 0; 2.176 + array2[79] = 0; 2.177 + array2[80] = 0; 2.178 + array2[81] = 0; 2.179 + array2[82] = 0; 2.180 + array2[83] = 0; 2.181 + array2[84] = 0; 2.182 + array2[85] = 0; 2.183 + array2[86] = 0; 2.184 + array2[87] = 0; 2.185 + array2[88] = 0; 2.186 + array2[89] = 0; 2.187 + array2[90] = 0; 2.188 + array2[91] = 0; 2.189 + array2[92] = 0; 2.190 + array2[93] = 0; 2.191 + array2[94] = 0; 2.192 + array2[95] = 0; 2.193 + array2[96] = 0; 2.194 + array2[97] = 0; 2.195 + array2[98] = 0; 2.196 + array2[99] = 0; 2.197 + 2.198 + array2[100] = 0; 2.199 + array2[101] = 0; 2.200 + array2[102] = 0; 2.201 + array2[103] = 0; 2.202 + array2[104] = 0; 2.203 + array2[105] = 0; 2.204 + array2[106] = 0; 2.205 + array2[107] = 0; 2.206 + array2[108] = 0; 2.207 + array2[109] = 0; 2.208 + array2[110] = 0; 2.209 + array2[111] = 0; 2.210 + array2[112] = 0; 2.211 + array2[113] = 0; 2.212 + array2[114] = 0; 2.213 + array2[115] = 0; 2.214 + array2[116] = 0; 2.215 + array2[117] = 0; 2.216 + array2[118] = 0; 2.217 + array2[119] = 0; 2.218 + array2[120] = 0; 2.219 + array2[121] = 0; 2.220 + array2[122] = 0; 2.221 + array2[123] = 0; 2.222 + array2[124] = 0; 2.223 + array2[125] = 0; 2.224 + array2[126] = 0; 2.225 + array2[127] = 0; 2.226 + array2[128] = 0; 2.227 + array2[129] = 0; 2.228 + array2[130] = 0; 2.229 + array2[131] = 0; 2.230 + array2[132] = 0; 2.231 + array2[133] = 0; 2.232 + array2[134] = 0; 2.233 + array2[135] = 0; 2.234 + array2[136] = 0; 2.235 + array2[137] = 0; 2.236 + array2[138] = 0; 2.237 + array2[139] = 0; 2.238 + array2[140] = 0; 2.239 + array2[141] = 0; 2.240 + array2[142] = 0; 2.241 + array2[143] = 0; 2.242 + array2[144] = 0; 2.243 + array2[145] = 0; 2.244 + array2[146] = 0; 2.245 + array2[147] = 0; 2.246 + array2[148] = 0; 2.247 + array2[149] = 0; 2.248 + array2[150] = 0; 2.249 + array2[151] = 0; 2.250 + array2[152] = 0; 2.251 + array2[153] = 0; 2.252 + array2[154] = 0; 2.253 + array2[155] = 0; 2.254 + array2[156] = 0; 2.255 + array2[157] = 0; 2.256 + array2[158] = 0; 2.257 + array2[159] = 0; 2.258 + array2[160] = 0; 2.259 + array2[161] = 0; 2.260 + array2[162] = 0; 2.261 + array2[163] = 0; 2.262 + array2[164] = 0; 2.263 + array2[165] = 0; 2.264 + array2[166] = 0; 2.265 + array2[167] = 0; 2.266 + array2[168] = 0; 2.267 + array2[169] = 0; 2.268 + array2[170] = 0; 2.269 + array2[171] = 0; 2.270 + array2[172] = 0; 2.271 + array2[173] = 0; 2.272 + array2[174] = 0; 2.273 + array2[175] = 0; 2.274 + array2[176] = 0; 2.275 + array2[177] = 0; 2.276 + array2[178] = 0; 2.277 + array2[179] = 0; 2.278 + array2[180] = 0; 2.279 + array2[181] = 0; 2.280 + array2[182] = 0; 2.281 + array2[183] = 0; 2.282 + array2[184] = 0; 2.283 + array2[185] = 0; 2.284 + array2[186] = 0; 2.285 + array2[187] = 0; 2.286 + array2[188] = 0; 2.287 + array2[189] = 0; 2.288 + array2[190] = 0; 2.289 + array2[191] = 0; 2.290 + array2[192] = 0; 2.291 + array2[193] = 0; 2.292 + array2[194] = 0; 2.293 + array2[195] = 0; 2.294 + array2[196] = 0; 2.295 + array2[197] = 0; 2.296 + array2[198] = 0; 2.297 + array2[199] = 0; 2.298 + if (o1.j >= 20) { 2.299 + break; 2.300 + } 2.301 + o1.j++; 2.302 + } while(true); 2.303 + not_inlined4(); 2.304 + } 2.305 + 2.306 + static public void main(String[] args) { 2.307 + BadPredicateAfterPartialPeel o1 = new BadPredicateAfterPartialPeel(); 2.308 + BadPredicateAfterPartialPeel o2 = new BadPredicateAfterPartialPeel(); 2.309 + for (int i = 0; i < 20000; i++) { 2.310 + o1.j = 0; 2.311 + m(o1, o2, o2, 0); 2.312 + m_helper(i, 2, i); // pollute profile 2.313 + } 2.314 + } 2.315 +}