Mercurial > hg > truffle
annotate src/cpu/x86/vm/c1_FpuStackSim_x86.cpp @ 15388:769fc3629f59
Add phase FlowSensitiveReductionPhase.
It is possible to remove GuardingPiNodes, CheckCastNodes, and FixedGuards during
HighTier under certain conditions (control-flow sensitive conditions).
The phase added in this commit (FlowSensitiveReductionPhase) does that,
and in addition replaces usages with "downcasting" PiNodes when possible
thus resulting in more precise object stamps (e.g., non-null).
Finally, usages of floating, side-effects free, expressions are also simplified
(as per control-flow sensitive conditions).
The newly added phase runs only during HighTier and can be deactivated
using Graal option FlowSensitiveReduction (it is active by default).
author | Miguel Garcia <miguel.m.garcia@oracle.com> |
---|---|
date | Fri, 25 Apr 2014 16:50:52 +0200 |
parents | f95d63e2154a |
children |
rev | line source |
---|---|
0 | 1 /* |
1972 | 2 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
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 | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "c1/c1_FpuStackSim.hpp" | |
27 #include "c1/c1_FrameMap.hpp" | |
28 #include "utilities/array.hpp" | |
29 #include "utilities/ostream.hpp" | |
0 | 30 |
31 //-------------------------------------------------------- | |
32 // FpuStackSim | |
33 //-------------------------------------------------------- | |
34 | |
35 // This class maps the FPU registers to their stack locations; it computes | |
36 // the offsets between individual registers and simulates the FPU stack. | |
37 | |
38 const int EMPTY = -1; | |
39 | |
40 int FpuStackSim::regs_at(int i) const { | |
41 assert(i >= 0 && i < FrameMap::nof_fpu_regs, "out of bounds"); | |
42 return _regs[i]; | |
43 } | |
44 | |
45 void FpuStackSim::set_regs_at(int i, int val) { | |
46 assert(i >= 0 && i < FrameMap::nof_fpu_regs, "out of bounds"); | |
47 _regs[i] = val; | |
48 } | |
49 | |
50 void FpuStackSim::dec_stack_size() { | |
51 _stack_size--; | |
52 assert(_stack_size >= 0, "FPU stack underflow"); | |
53 } | |
54 | |
55 void FpuStackSim::inc_stack_size() { | |
56 _stack_size++; | |
57 assert(_stack_size <= FrameMap::nof_fpu_regs, "FPU stack overflow"); | |
58 } | |
59 | |
60 FpuStackSim::FpuStackSim(Compilation* compilation) | |
61 : _compilation(compilation) | |
62 { | |
63 _stack_size = 0; | |
64 for (int i = 0; i < FrameMap::nof_fpu_regs; i++) { | |
65 set_regs_at(i, EMPTY); | |
66 } | |
67 } | |
68 | |
69 | |
70 void FpuStackSim::pop() { | |
71 if (TraceFPUStack) { tty->print("FPU-pop "); print(); tty->cr(); } | |
72 set_regs_at(tos_index(), EMPTY); | |
73 dec_stack_size(); | |
74 } | |
75 | |
76 void FpuStackSim::pop(int rnr) { | |
77 if (TraceFPUStack) { tty->print("FPU-pop %d", rnr); print(); tty->cr(); } | |
78 assert(regs_at(tos_index()) == rnr, "rnr is not on TOS"); | |
79 set_regs_at(tos_index(), EMPTY); | |
80 dec_stack_size(); | |
81 } | |
82 | |
83 | |
84 void FpuStackSim::push(int rnr) { | |
85 if (TraceFPUStack) { tty->print("FPU-push %d", rnr); print(); tty->cr(); } | |
86 assert(regs_at(stack_size()) == EMPTY, "should be empty"); | |
87 set_regs_at(stack_size(), rnr); | |
88 inc_stack_size(); | |
89 } | |
90 | |
91 | |
92 void FpuStackSim::swap(int offset) { | |
93 if (TraceFPUStack) { tty->print("FPU-swap %d", offset); print(); tty->cr(); } | |
94 int t = regs_at(tos_index() - offset); | |
95 set_regs_at(tos_index() - offset, regs_at(tos_index())); | |
96 set_regs_at(tos_index(), t); | |
97 } | |
98 | |
99 | |
100 int FpuStackSim::offset_from_tos(int rnr) const { | |
101 for (int i = tos_index(); i >= 0; i--) { | |
102 if (regs_at(i) == rnr) { | |
103 return tos_index() - i; | |
104 } | |
105 } | |
106 assert(false, "FpuStackSim: register not found"); | |
107 BAILOUT_("FpuStackSim: register not found", 0); | |
108 } | |
109 | |
110 | |
111 int FpuStackSim::get_slot(int tos_offset) const { | |
112 return regs_at(tos_index() - tos_offset); | |
113 } | |
114 | |
115 void FpuStackSim::set_slot(int tos_offset, int rnr) { | |
116 set_regs_at(tos_index() - tos_offset, rnr); | |
117 } | |
118 | |
119 void FpuStackSim::rename(int old_rnr, int new_rnr) { | |
120 if (TraceFPUStack) { tty->print("FPU-rename %d %d", old_rnr, new_rnr); print(); tty->cr(); } | |
121 if (old_rnr == new_rnr) | |
122 return; | |
123 bool found = false; | |
124 for (int i = 0; i < stack_size(); i++) { | |
125 assert(regs_at(i) != new_rnr, "should not see old occurrences of new_rnr on the stack"); | |
126 if (regs_at(i) == old_rnr) { | |
127 set_regs_at(i, new_rnr); | |
128 found = true; | |
129 } | |
130 } | |
131 assert(found, "should have found at least one instance of old_rnr"); | |
132 } | |
133 | |
134 | |
135 bool FpuStackSim::contains(int rnr) { | |
136 for (int i = 0; i < stack_size(); i++) { | |
137 if (regs_at(i) == rnr) { | |
138 return true; | |
139 } | |
140 } | |
141 return false; | |
142 } | |
143 | |
144 bool FpuStackSim::is_empty() { | |
145 #ifdef ASSERT | |
146 if (stack_size() == 0) { | |
147 for (int i = 0; i < FrameMap::nof_fpu_regs; i++) { | |
148 assert(regs_at(i) == EMPTY, "must be empty"); | |
149 } | |
150 } | |
151 #endif | |
152 return stack_size() == 0; | |
153 } | |
154 | |
155 | |
156 bool FpuStackSim::slot_is_empty(int tos_offset) { | |
157 return (regs_at(tos_index() - tos_offset) == EMPTY); | |
158 } | |
159 | |
160 | |
161 void FpuStackSim::clear() { | |
162 if (TraceFPUStack) { tty->print("FPU-clear"); print(); tty->cr(); } | |
163 for (int i = tos_index(); i >= 0; i--) { | |
164 set_regs_at(i, EMPTY); | |
165 } | |
166 _stack_size = 0; | |
167 } | |
168 | |
169 | |
170 intArray* FpuStackSim::write_state() { | |
171 intArray* res = new intArray(1 + FrameMap::nof_fpu_regs); | |
172 (*res)[0] = stack_size(); | |
173 for (int i = 0; i < FrameMap::nof_fpu_regs; i++) { | |
174 (*res)[1 + i] = regs_at(i); | |
175 } | |
176 return res; | |
177 } | |
178 | |
179 | |
180 void FpuStackSim::read_state(intArray* fpu_stack_state) { | |
181 _stack_size = (*fpu_stack_state)[0]; | |
182 for (int i = 0; i < FrameMap::nof_fpu_regs; i++) { | |
183 set_regs_at(i, (*fpu_stack_state)[1 + i]); | |
184 } | |
185 } | |
186 | |
187 | |
188 #ifndef PRODUCT | |
189 void FpuStackSim::print() { | |
190 tty->print(" N=%d[", stack_size());\ | |
191 for (int i = 0; i < stack_size(); i++) { | |
192 int reg = regs_at(i); | |
193 if (reg != EMPTY) { | |
194 tty->print("%d", reg); | |
195 } else { | |
196 tty->print("_"); | |
197 } | |
198 }; | |
199 tty->print(" ]"); | |
200 } | |
201 #endif |