Mercurial > hg > graal-compiler
comparison src/share/vm/opto/reg_split.cpp @ 14909:4ca6dc0799b6
Backout jdk9 merge
author | Gilles Duboscq <duboscq@ssw.jku.at> |
---|---|
date | Tue, 01 Apr 2014 13:57:07 +0200 |
parents | 04e7587c97dc |
children | 89152779163c |
comparison
equal
deleted
inserted
replaced
14908:8db6e76cb658 | 14909:4ca6dc0799b6 |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
53 | 53 |
54 //------------------------------get_spillcopy_wide----------------------------- | 54 //------------------------------get_spillcopy_wide----------------------------- |
55 // Get a SpillCopy node with wide-enough masks. Use the 'wide-mask', the | 55 // Get a SpillCopy node with wide-enough masks. Use the 'wide-mask', the |
56 // wide ideal-register spill-mask if possible. If the 'wide-mask' does | 56 // wide ideal-register spill-mask if possible. If the 'wide-mask' does |
57 // not cover the input (or output), use the input (or output) mask instead. | 57 // not cover the input (or output), use the input (or output) mask instead. |
58 Node *PhaseChaitin::get_spillcopy_wide(MachSpillCopyNode::SpillType spill_type, Node *def, Node *use, uint uidx ) { | 58 Node *PhaseChaitin::get_spillcopy_wide( Node *def, Node *use, uint uidx ) { |
59 // If ideal reg doesn't exist we've got a bad schedule happening | 59 // If ideal reg doesn't exist we've got a bad schedule happening |
60 // that is forcing us to spill something that isn't spillable. | 60 // that is forcing us to spill something that isn't spillable. |
61 // Bail rather than abort | 61 // Bail rather than abort |
62 int ireg = def->ideal_reg(); | 62 int ireg = def->ideal_reg(); |
63 if( ireg == 0 || ireg == Op_RegFlags ) { | 63 if( ireg == 0 || ireg == Op_RegFlags ) { |
91 // (and thus through memory)? | 91 // (and thus through memory)? |
92 if( !C->matcher()->idealreg2regmask[ireg]->overlap( *o_mask) && o_mask->is_UP() ) | 92 if( !C->matcher()->idealreg2regmask[ireg]->overlap( *o_mask) && o_mask->is_UP() ) |
93 // Here we assume a trip through memory is required. | 93 // Here we assume a trip through memory is required. |
94 w_i_mask = &C->FIRST_STACK_mask(); | 94 w_i_mask = &C->FIRST_STACK_mask(); |
95 } | 95 } |
96 return new (C) MachSpillCopyNode(spill_type, def, *w_i_mask, *w_o_mask ); | 96 return new (C) MachSpillCopyNode( def, *w_i_mask, *w_o_mask ); |
97 } | 97 } |
98 | 98 |
99 //------------------------------insert_proj------------------------------------ | 99 //------------------------------insert_proj------------------------------------ |
100 // Insert the spill at chosen location. Skip over any intervening Proj's or | 100 // Insert the spill at chosen location. Skip over any intervening Proj's or |
101 // Phis. Skip over a CatchNode and projs, inserting in the fall-through block | 101 // Phis. Skip over a CatchNode and projs, inserting in the fall-through block |
157 loc = 0; // Just past the Region | 157 loc = 0; // Just past the Region |
158 } | 158 } |
159 assert( loc >= 0, "must insert past block head" ); | 159 assert( loc >= 0, "must insert past block head" ); |
160 | 160 |
161 // Get a def-side SpillCopy | 161 // Get a def-side SpillCopy |
162 Node *spill = get_spillcopy_wide(MachSpillCopyNode::Definition, def, NULL, 0); | 162 Node *spill = get_spillcopy_wide(def,NULL,0); |
163 // Did we fail to split?, then bail | 163 // Did we fail to split?, then bail |
164 if (!spill) { | 164 if (!spill) { |
165 return 0; | 165 return 0; |
166 } | 166 } |
167 | 167 |
178 } | 178 } |
179 | 179 |
180 //------------------------------split_USE-------------------------------------- | 180 //------------------------------split_USE-------------------------------------- |
181 // Splits at uses can involve redeffing the LRG, so no CISC Spilling there. | 181 // Splits at uses can involve redeffing the LRG, so no CISC Spilling there. |
182 // Debug uses want to know if def is already stack enabled. | 182 // Debug uses want to know if def is already stack enabled. |
183 uint PhaseChaitin::split_USE(MachSpillCopyNode::SpillType spill_type, Node *def, Block *b, Node *use, uint useidx, uint maxlrg, bool def_down, bool cisc_sp, GrowableArray<uint> splits, int slidx ) { | 183 uint PhaseChaitin::split_USE( Node *def, Block *b, Node *use, uint useidx, uint maxlrg, bool def_down, bool cisc_sp, GrowableArray<uint> splits, int slidx ) { |
184 #ifdef ASSERT | 184 #ifdef ASSERT |
185 // Increment the counter for this lrg | 185 // Increment the counter for this lrg |
186 splits.at_put(slidx, splits.at(slidx)+1); | 186 splits.at_put(slidx, splits.at(slidx)+1); |
187 #endif | 187 #endif |
188 | 188 |
214 // Put the clone just prior to use | 214 // Put the clone just prior to use |
215 int bindex = b->find_node(use); | 215 int bindex = b->find_node(use); |
216 // DEF is UP, so must copy it DOWN and hook in USE | 216 // DEF is UP, so must copy it DOWN and hook in USE |
217 // Insert SpillCopy before the USE, which uses DEF as its input, | 217 // Insert SpillCopy before the USE, which uses DEF as its input, |
218 // and defs a new live range, which is used by this node. | 218 // and defs a new live range, which is used by this node. |
219 Node *spill = get_spillcopy_wide(spill_type, def,use,useidx); | 219 Node *spill = get_spillcopy_wide(def,use,useidx); |
220 // did we fail to split? | 220 // did we fail to split? |
221 if (!spill) { | 221 if (!spill) { |
222 // Bail | 222 // Bail |
223 return 0; | 223 return 0; |
224 } | 224 } |
266 } else { | 266 } else { |
267 // Put the clone just prior to use | 267 // Put the clone just prior to use |
268 bindex = b->find_node(use); | 268 bindex = b->find_node(use); |
269 } | 269 } |
270 | 270 |
271 Node *spill = get_spillcopy_wide(spill_type, def, use, useidx ); | 271 Node *spill = get_spillcopy_wide( def, use, useidx ); |
272 if( !spill ) return 0; // Bailed out | 272 if( !spill ) return 0; // Bailed out |
273 // Insert SpillCopy before the USE, which uses the reaching DEF as | 273 // Insert SpillCopy before the USE, which uses the reaching DEF as |
274 // its input, and defs a new live range, which is used by this node. | 274 // its input, and defs a new live range, which is used by this node. |
275 insert_proj( b, bindex, spill, maxlrg++ ); | 275 insert_proj( b, bindex, spill, maxlrg++ ); |
276 // Use the spill/clone | 276 // Use the spill/clone |
325 continue; | 325 continue; |
326 } | 326 } |
327 | 327 |
328 Block *b_def = _cfg.get_block_for_node(def); | 328 Block *b_def = _cfg.get_block_for_node(def); |
329 int idx_def = b_def->find_node(def); | 329 int idx_def = b_def->find_node(def); |
330 Node *in_spill = get_spillcopy_wide(MachSpillCopyNode::InputToRematerialization, in, def, i ); | 330 Node *in_spill = get_spillcopy_wide( in, def, i ); |
331 if( !in_spill ) return 0; // Bailed out | 331 if( !in_spill ) return 0; // Bailed out |
332 insert_proj(b_def,idx_def,in_spill,maxlrg++); | 332 insert_proj(b_def,idx_def,in_spill,maxlrg++); |
333 if( b_def == b ) | 333 if( b_def == b ) |
334 insidx++; | 334 insidx++; |
335 def->set_req(i,in_spill); | 335 def->set_req(i,in_spill); |
933 (mach && mach->ideal_Opcode() == Op_AddP && inpidx == AddPNode::Base)) { | 933 (mach && mach->ideal_Opcode() == Op_AddP && inpidx == AddPNode::Base)) { |
934 if (def->rematerialize() && lrgs(useidx)._was_spilled2) { | 934 if (def->rematerialize() && lrgs(useidx)._was_spilled2) { |
935 // This def has been rematerialized a couple of times without | 935 // This def has been rematerialized a couple of times without |
936 // progress. It doesn't care if it lives UP or DOWN, so | 936 // progress. It doesn't care if it lives UP or DOWN, so |
937 // spill it down now. | 937 // spill it down now. |
938 maxlrg = split_USE(MachSpillCopyNode::BasePointerToMem, def,b,n,inpidx,maxlrg,false,false,splits,slidx); | 938 maxlrg = split_USE(def,b,n,inpidx,maxlrg,false,false,splits,slidx); |
939 // If it wasn't split bail | 939 // If it wasn't split bail |
940 if (!maxlrg) { | 940 if (!maxlrg) { |
941 return 0; | 941 return 0; |
942 } | 942 } |
943 insidx++; // Reset iterator to skip USE side split | 943 insidx++; // Reset iterator to skip USE side split |
1013 (int)umask.Size() <= lrgs(useidx).num_regs() && | 1013 (int)umask.Size() <= lrgs(useidx).num_regs() && |
1014 (!def->rematerialize() || | 1014 (!def->rematerialize() || |
1015 !is_vect && umask.is_misaligned_pair())) { | 1015 !is_vect && umask.is_misaligned_pair())) { |
1016 // These need a Split regardless of overlap or pressure | 1016 // These need a Split regardless of overlap or pressure |
1017 // SPLIT - NO DEF - NO CISC SPILL | 1017 // SPLIT - NO DEF - NO CISC SPILL |
1018 maxlrg = split_USE(MachSpillCopyNode::Bound, def,b,n,inpidx,maxlrg,dup,false, splits,slidx); | 1018 maxlrg = split_USE(def,b,n,inpidx,maxlrg,dup,false, splits,slidx); |
1019 // If it wasn't split bail | 1019 // If it wasn't split bail |
1020 if (!maxlrg) { | 1020 if (!maxlrg) { |
1021 return 0; | 1021 return 0; |
1022 } | 1022 } |
1023 insidx++; // Reset iterator to skip USE side split | 1023 insidx++; // Reset iterator to skip USE side split |
1025 } | 1025 } |
1026 | 1026 |
1027 if (UseFPUForSpilling && n->is_MachCall() && !uup && !dup ) { | 1027 if (UseFPUForSpilling && n->is_MachCall() && !uup && !dup ) { |
1028 // The use at the call can force the def down so insert | 1028 // The use at the call can force the def down so insert |
1029 // a split before the use to allow the def more freedom. | 1029 // a split before the use to allow the def more freedom. |
1030 maxlrg = split_USE(MachSpillCopyNode::CallUse, def,b,n,inpidx,maxlrg,dup,false, splits,slidx); | 1030 maxlrg = split_USE(def,b,n,inpidx,maxlrg,dup,false, splits,slidx); |
1031 // If it wasn't split bail | 1031 // If it wasn't split bail |
1032 if (!maxlrg) { | 1032 if (!maxlrg) { |
1033 return 0; | 1033 return 0; |
1034 } | 1034 } |
1035 insidx++; // Reset iterator to skip USE side split | 1035 insidx++; // Reset iterator to skip USE side split |
1061 n->set_req(inpidx, def); | 1061 n->set_req(inpidx, def); |
1062 } | 1062 } |
1063 else { // Both are either up or down, and there is no overlap | 1063 else { // Both are either up or down, and there is no overlap |
1064 if( dup ) { // If UP, reg->reg copy | 1064 if( dup ) { // If UP, reg->reg copy |
1065 // COPY ACROSS HERE - NO DEF - NO CISC SPILL | 1065 // COPY ACROSS HERE - NO DEF - NO CISC SPILL |
1066 maxlrg = split_USE(MachSpillCopyNode::RegToReg, def,b,n,inpidx,maxlrg,false,false, splits,slidx); | 1066 maxlrg = split_USE(def,b,n,inpidx,maxlrg,false,false, splits,slidx); |
1067 // If it wasn't split bail | 1067 // If it wasn't split bail |
1068 if (!maxlrg) { | 1068 if (!maxlrg) { |
1069 return 0; | 1069 return 0; |
1070 } | 1070 } |
1071 insidx++; // Reset iterator to skip USE side split | 1071 insidx++; // Reset iterator to skip USE side split |
1073 else { // DOWN, mem->mem copy | 1073 else { // DOWN, mem->mem copy |
1074 // COPY UP & DOWN HERE - NO DEF - NO CISC SPILL | 1074 // COPY UP & DOWN HERE - NO DEF - NO CISC SPILL |
1075 // First Split-UP to move value into Register | 1075 // First Split-UP to move value into Register |
1076 uint def_ideal = def->ideal_reg(); | 1076 uint def_ideal = def->ideal_reg(); |
1077 const RegMask* tmp_rm = Matcher::idealreg2regmask[def_ideal]; | 1077 const RegMask* tmp_rm = Matcher::idealreg2regmask[def_ideal]; |
1078 Node *spill = new (C) MachSpillCopyNode(MachSpillCopyNode::MemToReg, def, dmask, *tmp_rm); | 1078 Node *spill = new (C) MachSpillCopyNode(def, dmask, *tmp_rm); |
1079 insert_proj( b, insidx, spill, maxlrg ); | 1079 insert_proj( b, insidx, spill, maxlrg ); |
1080 // Then Split-DOWN as if previous Split was DEF | 1080 // Then Split-DOWN as if previous Split was DEF |
1081 maxlrg = split_USE(MachSpillCopyNode::RegToMem, spill,b,n,inpidx,maxlrg,false,false, splits,slidx); | 1081 maxlrg = split_USE(spill,b,n,inpidx,maxlrg,false,false, splits,slidx); |
1082 // If it wasn't split bail | 1082 // If it wasn't split bail |
1083 if (!maxlrg) { | 1083 if (!maxlrg) { |
1084 return 0; | 1084 return 0; |
1085 } | 1085 } |
1086 insidx += 2; // Reset iterator to skip USE side splits | 1086 insidx += 2; // Reset iterator to skip USE side splits |
1101 } | 1101 } |
1102 continue; | 1102 continue; |
1103 } | 1103 } |
1104 } | 1104 } |
1105 // COPY DOWN HERE - NO DEF - NO CISC SPILL | 1105 // COPY DOWN HERE - NO DEF - NO CISC SPILL |
1106 maxlrg = split_USE(MachSpillCopyNode::RegToMem, def,b,n,inpidx,maxlrg,false,false, splits,slidx); | 1106 maxlrg = split_USE(def,b,n,inpidx,maxlrg,false,false, splits,slidx); |
1107 // If it wasn't split bail | 1107 // If it wasn't split bail |
1108 if (!maxlrg) { | 1108 if (!maxlrg) { |
1109 return 0; | 1109 return 0; |
1110 } | 1110 } |
1111 insidx++; // Reset iterator to skip USE side split | 1111 insidx++; // Reset iterator to skip USE side split |
1116 | 1116 |
1117 } | 1117 } |
1118 else { // DOWN, Split-UP and check register pressure | 1118 else { // DOWN, Split-UP and check register pressure |
1119 if( is_high_pressure( b, &lrgs(useidx), insidx ) ) { | 1119 if( is_high_pressure( b, &lrgs(useidx), insidx ) ) { |
1120 // COPY UP HERE - NO DEF - CISC SPILL | 1120 // COPY UP HERE - NO DEF - CISC SPILL |
1121 maxlrg = split_USE(MachSpillCopyNode::MemToReg, def,b,n,inpidx,maxlrg,true,true, splits,slidx); | 1121 maxlrg = split_USE(def,b,n,inpidx,maxlrg,true,true, splits,slidx); |
1122 // If it wasn't split bail | 1122 // If it wasn't split bail |
1123 if (!maxlrg) { | 1123 if (!maxlrg) { |
1124 return 0; | 1124 return 0; |
1125 } | 1125 } |
1126 insidx++; // Reset iterator to skip USE side split | 1126 insidx++; // Reset iterator to skip USE side split |
1127 } else { // LRP | 1127 } else { // LRP |
1128 // COPY UP HERE - WITH DEF - NO CISC SPILL | 1128 // COPY UP HERE - WITH DEF - NO CISC SPILL |
1129 maxlrg = split_USE(MachSpillCopyNode::MemToReg, def,b,n,inpidx,maxlrg,true,false, splits,slidx); | 1129 maxlrg = split_USE(def,b,n,inpidx,maxlrg,true,false, splits,slidx); |
1130 // If it wasn't split bail | 1130 // If it wasn't split bail |
1131 if (!maxlrg) { | 1131 if (!maxlrg) { |
1132 return 0; | 1132 return 0; |
1133 } | 1133 } |
1134 // Flag this lift-up in a low-pressure block as | 1134 // Flag this lift-up in a low-pressure block as |
1227 const RegMask &use_rm = n->in_RegMask(copyidx); | 1227 const RegMask &use_rm = n->in_RegMask(copyidx); |
1228 if( def_rm.overlap(use_rm) && n->is_SpillCopy() ) { // Bug 4707800, 'n' may be a storeSSL | 1228 if( def_rm.overlap(use_rm) && n->is_SpillCopy() ) { // Bug 4707800, 'n' may be a storeSSL |
1229 if (C->check_node_count(NodeLimitFudgeFactor, out_of_nodes)) { // Check when generating nodes | 1229 if (C->check_node_count(NodeLimitFudgeFactor, out_of_nodes)) { // Check when generating nodes |
1230 return 0; | 1230 return 0; |
1231 } | 1231 } |
1232 Node *spill = new (C) MachSpillCopyNode(MachSpillCopyNode::MemToReg, use,use_rm,def_rm); | 1232 Node *spill = new (C) MachSpillCopyNode(use,use_rm,def_rm); |
1233 n->set_req(copyidx,spill); | 1233 n->set_req(copyidx,spill); |
1234 n->as_MachSpillCopy()->set_in_RegMask(def_rm); | 1234 n->as_MachSpillCopy()->set_in_RegMask(def_rm); |
1235 // Put the spill just before the copy | 1235 // Put the spill just before the copy |
1236 insert_proj( b, insidx++, spill, maxlrg++ ); | 1236 insert_proj( b, insidx++, spill, maxlrg++ ); |
1237 } | 1237 } |
1334 // Update the Phi's input edge array | 1334 // Update the Phi's input edge array |
1335 phi->set_req(i,def); | 1335 phi->set_req(i,def); |
1336 // Grab the UP/DOWN sense for the input | 1336 // Grab the UP/DOWN sense for the input |
1337 u1 = UP[pidx][slidx]; | 1337 u1 = UP[pidx][slidx]; |
1338 if( u1 != (phi_up != 0)) { | 1338 if( u1 != (phi_up != 0)) { |
1339 maxlrg = split_USE(MachSpillCopyNode::PhiLocationDifferToInputLocation, def, b, phi, i, maxlrg, !u1, false, splits,slidx); | 1339 maxlrg = split_USE(def, b, phi, i, maxlrg, !u1, false, splits,slidx); |
1340 // If it wasn't split bail | 1340 // If it wasn't split bail |
1341 if (!maxlrg) { | 1341 if (!maxlrg) { |
1342 return 0; | 1342 return 0; |
1343 } | 1343 } |
1344 } | 1344 } |