Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(233)

Side by Side Diff: src/hydrogen-environment-liveness.cc

Issue 15533004: Liveness analysis for environment slots in Hydrogen (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: fixed bug (again; the same one as patch set 6) Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28
29 #include "hydrogen-environment-liveness.h"
30
31
32 namespace v8 {
33 namespace internal {
34
35
36 void EnvironmentSlotLivenessAnalysis::ZapEnvironmentSlot(int index,
37 HSimulate* simulate) {
38 int operand_index = simulate->ToOperandIndex(index);
39 if (operand_index == -1) {
40 simulate->AddAssignedValue(index, graph_->GetConstantUndefined());
41 } else {
42 simulate->SetOperandAt(operand_index, graph_->GetConstantUndefined());
43 }
44 }
45
46
47 void EnvironmentSlotLivenessAnalysis::ZapEnvironmentSlotsInSuccessors(
48 HBasicBlock* block) {
49 // When a value is live in successor A but dead in B, we must
50 // explicitly zap it in B.
51 for (HSuccessorIterator it(block->end()); !it.Done(); it.Advance()) {
52 HBasicBlock* successor = it.Current();
53 int successor_id = successor->block_id();
54 BitVector* live_in_successor = live_at_block_start_->at(successor_id);
55 if (live_in_successor->Equals(*live_)) continue;
56 for (int i = 0; i < live_->length(); ++i) {
57 if (!live_->Contains(i)) continue;
58 if (live_in_successor->Contains(i)) continue;
59 if (first_simulate_invalid_for_index_->at(successor_id)->Contains(i)) {
60 continue;
61 }
62 HSimulate* simulate = first_simulate_->at(successor_id);
63 if (simulate == NULL) continue;
64 ASSERT(simulate->closure().is_identical_to(
65 block->last_environment()->closure()));
66 ZapEnvironmentSlot(i, simulate);
67 }
68 }
69 }
70
71
72 void EnvironmentSlotLivenessAnalysis::ZapEnvironmentSlotsForInstruction(
73 HEnvironmentMarker* marker) {
74 if (!marker->CheckFlag(HValue::kEndsLiveRange)) return;
75 HSimulate* simulate = marker->next_simulate();
76 if (simulate != NULL) {
77 ASSERT(simulate->closure().is_identical_to(marker->closure()));
78 ZapEnvironmentSlot(marker->index(), simulate);
79 }
80 }
81
82
83 void EnvironmentSlotLivenessAnalysis::UpdateLivenessAtBlockEnd(
84 HBasicBlock* block) {
titzer 2013/05/29 16:58:05 E.g. here, it would be more clear to pass in the t
Jakob Kummerow 2013/06/03 17:50:38 Done.
85 // Liveness at the end of each block: union of liveness in successors.
86 live_->Clear();
87 for (HSuccessorIterator it(block->end()); !it.Done(); it.Advance()) {
88 live_->Union(*live_at_block_start_->at(it.Current()->block_id()));
89 }
90 }
91
92
93 void EnvironmentSlotLivenessAnalysis::UpdateLivenessAtInstruction(
94 HInstruction* instr) {
95 switch (instr->opcode()) {
96 case HValue::kEnvironmentMarker: {
97 HEnvironmentMarker* marker = HEnvironmentMarker::cast(instr);
98 int index = marker->index();
99 if (!live_->Contains(index)) {
100 marker->SetFlag(HValue::kEndsLiveRange);
101 } else {
102 marker->ClearFlag(HValue::kEndsLiveRange);
103 }
104 if (!went_live_since_last_simulate_->Contains(index)) {
105 marker->set_next_simulate(last_simulate_);
106 }
107 if (marker->kind() == HEnvironmentMarker::LOOKUP) {
108 live_->Add(index);
109 } else {
110 ASSERT(marker->kind() == HEnvironmentMarker::BIND);
111 live_->Remove(index);
112 went_live_since_last_simulate_->Add(index);
113 }
114 if (collect_markers_) {
titzer 2013/05/29 16:58:05 This is a little tricky; maybe a comment that we o
Jakob Kummerow 2013/06/03 17:50:38 Done.
115 markers_->Add(marker, &zone_);
116 }
117 break;
118 }
119 case HValue::kLeaveInlined:
120 // No environment values are live at the end of an inlined section.
121 live_->Clear();
122 last_simulate_ = NULL;
123
124 // The following ASSERTs guard the assumption used in case
125 // kEnterInlined below:
126 ASSERT(instr->next()->IsSimulate());
127 ASSERT(instr->next()->next()->IsGoto());
128
129 break;
130 case HValue::kEnterInlined: {
131 // Those environment values are live that are live at any return
132 // target block. Here we make use of the fact that the end of an
133 // inline sequence always looks like this: HLeaveInlined, HSimulate,
134 // HGoto (to return_target block), with no environment lookups in
135 // between (see ASSERTs above).
136 HEnterInlined* enter = HEnterInlined::cast(instr);
137 live_->Clear();
138 for (int i = 0; i < enter->return_targets()->length(); ++i) {
139 int return_id = enter->return_targets()->at(i)->block_id();
140 // When an AbnormalExit is involved, it can happen that the return
141 // target block doesn't actually exist.
142 if (return_id < live_at_block_start_->length()) {
143 live_->Union(*live_at_block_start_->at(return_id));
144 }
145 }
146 last_simulate_ = NULL;
147 break;
148 }
149 case HValue::kDeoptimize: {
titzer 2013/05/29 16:58:05 What about kSoftDeoptimize?
Jakob Kummerow 2013/06/03 17:50:38 Usage is different. HSoftDeoptimize instructions d
150 // Keep all environment slots alive.
151 HDeoptimize* deopt = HDeoptimize::cast(instr);
152 for (int i = deopt->first_local_index();
153 i < deopt->first_expression_index(); ++i) {
154 live_->Add(i);
155 }
156 break;
157 }
158 case HValue::kSimulate:
159 last_simulate_ = HSimulate::cast(instr);
160 went_live_since_last_simulate_->Clear();
161 break;
162 default:
163 break;
164 }
165 }
166
167
168 // Values in the environment are kept alive by every subsequent LInstruction
titzer 2013/05/29 16:58:05 Some reordering of the sentences might make this p
Jakob Kummerow 2013/06/03 17:50:38 Done, and moved to the class, where this comment r
169 // that is assigned an LEnvironment. This creates register pressure and
170 // unnecessary spill slot moves. Therefore it is beneficial to trim the
171 // live ranges of environment slots by zapping them with a constant after
172 // the last lookup that refers to them. This is similar but not identical
173 // to live range analysis for HValues, so we perform an explicit liveness
174 // analysis on environment slots (identified by their index).
175 // This only affects slots whitelisted by
176 // HOptimizedGraphBuilder::IsEligibleForEnvironmentLivenessAnalysis().
177 void EnvironmentSlotLivenessAnalysis::AnalyzeAndPrune() {
178 HPhase phase("H_EnvironmentLivenessAnalysis", graph_);
179 if (maximum_environment_size_ == 0) return;
180
181 // Main iteration. Compute liveness of environment slots, and store it
182 // for each block until it doesn't change any more. For efficiency, visit
183 // blocks in reverse order and walk backwards through each block. We
184 // need several iterations to propagate liveness through nested loops.
185 BitVector* worklist = new(zone()) BitVector(block_count_, zone());
186 for (int i = 0; i < block_count_; ++i) {
187 worklist->Add(i);
188 }
189 while (!worklist->IsEmpty()) {
190 for (int block_id = block_count_ - 1; block_id >= 0; --block_id) {
191 if (!worklist->Contains(block_id)) {
192 continue;
193 }
194 worklist->Remove(block_id);
195 last_simulate_ = NULL;
196
197 HBasicBlock* block = graph_->blocks()->at(block_id);
198 UpdateLivenessAtBlockEnd(block);
199
200 for (HInstruction* instr = block->last(); instr != NULL;
201 instr = instr->previous()) {
202 UpdateLivenessAtInstruction(instr);
203 }
204
205 // Reached the start of the block, do necessary bookkeeping.
titzer 2013/05/29 16:58:05 Explain bookkeeping steps. E.g. "propagate livenes
Jakob Kummerow 2013/06/03 17:50:38 Done.
206 first_simulate_->Set(block_id, last_simulate_);
207 first_simulate_invalid_for_index_->at(block_id)->CopyFrom(
208 *went_live_since_last_simulate_);
209 if (live_at_block_start_->at(block_id)->UnionIsChanged(*live_)) {
210 for (int i = 0; i < block->predecessors()->length(); ++i) {
211 worklist->Add(block->predecessors()->at(i)->block_id());
212 }
213 if (block->IsInlineReturnTarget()) {
214 worklist->Add(block->inlined_entry_block()->block_id());
215 }
216 }
217 }
218 // Only collect bind/lookup instructions during the first pass.
219 collect_markers_ = false;
220 }
221
222 // Analysis finished. Zap dead environment slots.
223 for (int i = 0; i < markers_->length(); ++i) {
224 ZapEnvironmentSlotsForInstruction(markers_->at(i));
225 }
226 for (int block_id = block_count_ - 1; block_id >= 0; --block_id) {
227 HBasicBlock* block = graph_->blocks()->at(block_id);
228 UpdateLivenessAtBlockEnd(block);
229 ZapEnvironmentSlotsInSuccessors(block);
230 }
231
232 // Finally, remove the HEnvironment{Bind,Lookup} markers.
233 for (int i = 0; i < markers_->length(); ++i) {
234 markers_->at(i)->DeleteAndReplaceWith(NULL);
235 }
236 }
237
238 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698