blob: 9e6cfbe65347210e65de276a3b1512e594643082 [file] [log] [blame]
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +01001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "ssa_builder.h"
Nicolas Geoffray184d6402014-06-09 14:06:02 +010018
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +010019#include "nodes.h"
Alex Light68289a52015-12-15 17:30:30 -080020#include "primitive_type_propagation.h"
Nicolas Geoffray31596742014-11-24 15:28:45 +000021#include "ssa_phi_elimination.h"
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +010022
23namespace art {
24
Alex Light68289a52015-12-15 17:30:30 -080025// Returns whether this is a loop header phi which was eagerly created but later
26// found inconsistent due to the vreg being undefined in one of its predecessors.
27// Such phi is marked dead and should be ignored until its removal in SsaPhiElimination.
28static bool IsUndefinedLoopHeaderPhi(HPhi* phi) {
29 return phi->IsLoopHeaderPhi() && phi->InputCount() != phi->GetBlock()->GetPredecessors().size();
30}
31
32/**
33 * A debuggable application may require to reviving phis, to ensure their
34 * associated DEX register is available to a debugger. This class implements
35 * the logic for statement (c) of the SsaBuilder (see ssa_builder.h). It
36 * also makes sure that phis with incompatible input types are not revived
37 * (statement (b) of the SsaBuilder).
38 *
39 * This phase must be run after detecting dead phis through the
40 * DeadPhiElimination phase, and before deleting the dead phis.
41 */
42class DeadPhiHandling : public ValueObject {
43 public:
44 explicit DeadPhiHandling(HGraph* graph)
45 : graph_(graph), worklist_(graph->GetArena()->Adapter(kArenaAllocSsaBuilder)) {
46 worklist_.reserve(kDefaultWorklistSize);
47 }
48
49 void Run();
50
51 private:
52 void VisitBasicBlock(HBasicBlock* block);
53 void ProcessWorklist();
54 void AddToWorklist(HPhi* phi);
55 void AddDependentInstructionsToWorklist(HPhi* phi);
56 bool UpdateType(HPhi* phi);
57
58 HGraph* const graph_;
59 ArenaVector<HPhi*> worklist_;
60
61 static constexpr size_t kDefaultWorklistSize = 8;
62
63 DISALLOW_COPY_AND_ASSIGN(DeadPhiHandling);
64};
65
66static bool HasConflictingEquivalent(HPhi* phi) {
67 if (phi->GetNext() == nullptr) {
68 return false;
69 }
70 HPhi* next = phi->GetNext()->AsPhi();
71 if (next->GetRegNumber() == phi->GetRegNumber()) {
72 if (next->GetType() == Primitive::kPrimVoid) {
73 // We only get a void type for an equivalent phi we processed and found out
74 // it was conflicting.
75 return true;
76 } else {
77 // Go to the next phi, in case it is also an equivalent.
78 return HasConflictingEquivalent(next);
79 }
80 }
81 return false;
82}
83
84bool DeadPhiHandling::UpdateType(HPhi* phi) {
85 if (phi->IsDead()) {
86 // Phi was rendered dead while waiting in the worklist because it was replaced
87 // with an equivalent.
88 return false;
89 }
90
91 Primitive::Type existing = phi->GetType();
92
93 bool conflict = false;
94 Primitive::Type new_type = existing;
95 for (size_t i = 0, e = phi->InputCount(); i < e; ++i) {
96 HInstruction* input = phi->InputAt(i);
97 if (input->IsPhi() && input->AsPhi()->IsDead()) {
98 // We are doing a reverse post order visit of the graph, reviving
99 // phis that have environment uses and updating their types. If an
100 // input is a phi, and it is dead (because its input types are
101 // conflicting), this phi must be marked dead as well.
102 conflict = true;
103 break;
104 }
105 Primitive::Type input_type = HPhi::ToPhiType(input->GetType());
106
107 // The only acceptable transitions are:
108 // - From void to typed: first time we update the type of this phi.
109 // - From int to reference (or reference to int): the phi has to change
110 // to reference type. If the integer input cannot be converted to a
111 // reference input, the phi will remain dead.
112 if (new_type == Primitive::kPrimVoid) {
113 new_type = input_type;
114 } else if (new_type == Primitive::kPrimNot && input_type == Primitive::kPrimInt) {
115 if (input->IsPhi() && HasConflictingEquivalent(input->AsPhi())) {
116 // If we already asked for an equivalent of the input phi, but that equivalent
117 // ended up conflicting, make this phi conflicting too.
118 conflict = true;
119 break;
120 }
121 HInstruction* equivalent = SsaBuilder::GetReferenceTypeEquivalent(input);
122 if (equivalent == nullptr) {
123 conflict = true;
124 break;
125 }
126 phi->ReplaceInput(equivalent, i);
127 if (equivalent->IsPhi()) {
128 DCHECK_EQ(equivalent->GetType(), Primitive::kPrimNot);
129 // We created a new phi, but that phi has the same inputs as the old phi. We
130 // add it to the worklist to ensure its inputs can also be converted to reference.
131 // If not, it will remain dead, and the algorithm will make the current phi dead
132 // as well.
133 equivalent->AsPhi()->SetLive();
134 AddToWorklist(equivalent->AsPhi());
135 }
136 } else if (new_type == Primitive::kPrimInt && input_type == Primitive::kPrimNot) {
137 new_type = Primitive::kPrimNot;
138 // Start over, we may request reference equivalents for the inputs of the phi.
139 i = -1;
140 } else if (new_type != input_type) {
141 conflict = true;
142 break;
143 }
144 }
145
146 if (conflict) {
147 phi->SetType(Primitive::kPrimVoid);
148 phi->SetDead();
149 return true;
150 } else if (existing == new_type) {
151 return false;
152 }
153
154 DCHECK(phi->IsLive());
155 phi->SetType(new_type);
156
157 // There might exist a `new_type` equivalent of `phi` already. In that case,
158 // we replace the equivalent with the, now live, `phi`.
159 HPhi* equivalent = phi->GetNextEquivalentPhiWithSameType();
160 if (equivalent != nullptr) {
161 // There cannot be more than two equivalents with the same type.
162 DCHECK(equivalent->GetNextEquivalentPhiWithSameType() == nullptr);
163 // If doing fix-point iteration, the equivalent might be in `worklist_`.
164 // Setting it dead will make UpdateType skip it.
165 equivalent->SetDead();
166 equivalent->ReplaceWith(phi);
167 }
168
169 return true;
170}
171
172void DeadPhiHandling::VisitBasicBlock(HBasicBlock* block) {
173 for (HInstructionIterator it(block->GetPhis()); !it.Done(); it.Advance()) {
174 HPhi* phi = it.Current()->AsPhi();
175 if (IsUndefinedLoopHeaderPhi(phi)) {
176 DCHECK(phi->IsDead());
177 continue;
178 }
179 if (phi->IsDead() && phi->HasEnvironmentUses()) {
180 phi->SetLive();
181 if (block->IsLoopHeader()) {
182 // Loop phis must have a type to guarantee convergence of the algorithm.
183 DCHECK_NE(phi->GetType(), Primitive::kPrimVoid);
184 AddToWorklist(phi);
185 } else {
186 // Because we are doing a reverse post order visit, all inputs of
187 // this phi have been visited and therefore had their (initial) type set.
188 UpdateType(phi);
189 }
190 }
191 }
192}
193
194void DeadPhiHandling::ProcessWorklist() {
195 while (!worklist_.empty()) {
196 HPhi* instruction = worklist_.back();
197 worklist_.pop_back();
198 // Note that the same equivalent phi can be added multiple times in the work list, if
199 // used by multiple phis. The first call to `UpdateType` will know whether the phi is
200 // dead or live.
201 if (instruction->IsLive() && UpdateType(instruction)) {
202 AddDependentInstructionsToWorklist(instruction);
203 }
204 }
205}
206
207void DeadPhiHandling::AddToWorklist(HPhi* instruction) {
208 DCHECK(instruction->IsLive());
209 worklist_.push_back(instruction);
210}
211
212void DeadPhiHandling::AddDependentInstructionsToWorklist(HPhi* instruction) {
213 for (HUseIterator<HInstruction*> it(instruction->GetUses()); !it.Done(); it.Advance()) {
214 HPhi* phi = it.Current()->GetUser()->AsPhi();
215 if (phi != nullptr && !phi->IsDead()) {
216 AddToWorklist(phi);
217 }
218 }
219}
220
221void DeadPhiHandling::Run() {
222 for (HReversePostOrderIterator it(*graph_); !it.Done(); it.Advance()) {
223 VisitBasicBlock(it.Current());
224 }
225 ProcessWorklist();
226}
227
David Brazdil809d70f2015-11-19 10:29:39 +0000228void SsaBuilder::SetLoopHeaderPhiInputs() {
229 for (size_t i = loop_headers_.size(); i > 0; --i) {
230 HBasicBlock* block = loop_headers_[i - 1];
231 for (HInstructionIterator it(block->GetPhis()); !it.Done(); it.Advance()) {
232 HPhi* phi = it.Current()->AsPhi();
233 size_t vreg = phi->GetRegNumber();
234 for (HBasicBlock* predecessor : block->GetPredecessors()) {
235 HInstruction* value = ValueOfLocal(predecessor, vreg);
236 if (value == nullptr) {
237 // Vreg is undefined at this predecessor. Mark it dead and leave with
238 // fewer inputs than predecessors. SsaChecker will fail if not removed.
239 phi->SetDead();
240 break;
241 } else {
242 phi->AddInput(value);
243 }
244 }
245 }
246 }
247}
248
Calin Juravlea4f88312015-04-16 12:57:19 +0100249void SsaBuilder::FixNullConstantType() {
250 // The order doesn't matter here.
251 for (HReversePostOrderIterator itb(*GetGraph()); !itb.Done(); itb.Advance()) {
252 for (HInstructionIterator it(itb.Current()->GetInstructions()); !it.Done(); it.Advance()) {
253 HInstruction* equality_instr = it.Current();
254 if (!equality_instr->IsEqual() && !equality_instr->IsNotEqual()) {
255 continue;
256 }
257 HInstruction* left = equality_instr->InputAt(0);
258 HInstruction* right = equality_instr->InputAt(1);
Nicolas Geoffray51d400d2015-06-15 09:01:08 +0100259 HInstruction* int_operand = nullptr;
Calin Juravlea4f88312015-04-16 12:57:19 +0100260
Nicolas Geoffray51d400d2015-06-15 09:01:08 +0100261 if ((left->GetType() == Primitive::kPrimNot) && (right->GetType() == Primitive::kPrimInt)) {
262 int_operand = right;
263 } else if ((right->GetType() == Primitive::kPrimNot)
264 && (left->GetType() == Primitive::kPrimInt)) {
265 int_operand = left;
Calin Juravlea4f88312015-04-16 12:57:19 +0100266 } else {
267 continue;
268 }
269
270 // If we got here, we are comparing against a reference and the int constant
271 // should be replaced with a null constant.
Nicolas Geoffray51d400d2015-06-15 09:01:08 +0100272 // Both type propagation and redundant phi elimination ensure `int_operand`
273 // can only be the 0 constant.
274 DCHECK(int_operand->IsIntConstant());
275 DCHECK_EQ(0, int_operand->AsIntConstant()->GetValue());
276 equality_instr->ReplaceInput(GetGraph()->GetNullConstant(), int_operand == right ? 1 : 0);
Calin Juravlea4f88312015-04-16 12:57:19 +0100277 }
278 }
279}
280
281void SsaBuilder::EquivalentPhisCleanup() {
282 // The order doesn't matter here.
283 for (HReversePostOrderIterator itb(*GetGraph()); !itb.Done(); itb.Advance()) {
284 for (HInstructionIterator it(itb.Current()->GetPhis()); !it.Done(); it.Advance()) {
285 HPhi* phi = it.Current()->AsPhi();
286 HPhi* next = phi->GetNextEquivalentPhiWithSameType();
287 if (next != nullptr) {
Alex Light68289a52015-12-15 17:30:30 -0800288 // Make sure we do not replace a live phi with a dead phi. A live phi has been
289 // handled by the type propagation phase, unlike a dead phi.
Nicolas Geoffray4230e182015-06-29 14:34:46 +0100290 if (next->IsLive()) {
291 phi->ReplaceWith(next);
292 } else {
293 next->ReplaceWith(phi);
294 }
Calin Juravlea4f88312015-04-16 12:57:19 +0100295 DCHECK(next->GetNextEquivalentPhiWithSameType() == nullptr)
296 << "More then one phi equivalent with type " << phi->GetType()
297 << " found for phi" << phi->GetId();
298 }
299 }
300 }
301}
302
Alex Light68289a52015-12-15 17:30:30 -0800303void SsaBuilder::BuildSsa() {
304 // 1) Visit in reverse post order. We need to have all predecessors of a block visited
305 // (with the exception of loops) in order to create the right environment for that
306 // block. For loops, we create phis whose inputs will be set in 2).
307 for (HReversePostOrderIterator it(*GetGraph()); !it.Done(); it.Advance()) {
308 VisitBasicBlock(it.Current());
309 }
310
311 // 2) Set inputs of loop phis.
312 SetLoopHeaderPhiInputs();
313
314 // 3) Mark dead phis. This will mark phis that are only used by environments:
315 // at the DEX level, the type of these phis does not need to be consistent, but
316 // our code generator will complain if the inputs of a phi do not have the same
317 // type. The marking allows the type propagation to know which phis it needs
318 // to handle. We mark but do not eliminate: the elimination will be done in
319 // step 9).
320 SsaDeadPhiElimination dead_phis_for_type_propagation(GetGraph());
321 dead_phis_for_type_propagation.MarkDeadPhis();
322
323 // 4) Propagate types of phis. At this point, phis are typed void in the general
324 // case, or float/double/reference when we created an equivalent phi. So we
325 // need to propagate the types across phis to give them a correct type.
326 PrimitiveTypePropagation type_propagation(GetGraph());
327 type_propagation.Run();
328
329 // 5) When creating equivalent phis we copy the inputs of the original phi which
330 // may be improperly typed. This was fixed during the type propagation in 4) but
331 // as a result we may end up with two equivalent phis with the same type for
332 // the same dex register. This pass cleans them up.
333 EquivalentPhisCleanup();
334
335 // 6) Mark dead phis again. Step 4) may have introduced new phis.
336 // Step 5) might enable the death of new phis.
337 SsaDeadPhiElimination dead_phis(GetGraph());
338 dead_phis.MarkDeadPhis();
339
340 // 7) Now that the graph is correctly typed, we can get rid of redundant phis.
341 // Note that we cannot do this phase before type propagation, otherwise
342 // we could get rid of phi equivalents, whose presence is a requirement for the
343 // type propagation phase. Note that this is to satisfy statement (a) of the
344 // SsaBuilder (see ssa_builder.h).
345 SsaRedundantPhiElimination redundant_phi(GetGraph());
346 redundant_phi.Run();
347
348 // 8) Fix the type for null constants which are part of an equality comparison.
349 // We need to do this after redundant phi elimination, to ensure the only cases
350 // that we can see are reference comparison against 0. The redundant phi
351 // elimination ensures we do not see a phi taking two 0 constants in a HEqual
352 // or HNotEqual.
353 FixNullConstantType();
354
355 // 9) Make sure environments use the right phi "equivalent": a phi marked dead
356 // can have a phi equivalent that is not dead. We must therefore update
357 // all environment uses of the dead phi to use its equivalent. Note that there
358 // can be multiple phis for the same Dex register that are live (for example
359 // when merging constants), in which case it is OK for the environments
360 // to just reference one.
Nicolas Geoffraye0fe7ae2015-03-09 10:02:49 +0000361 for (HReversePostOrderIterator it(*GetGraph()); !it.Done(); it.Advance()) {
362 HBasicBlock* block = it.Current();
363 for (HInstructionIterator it_phis(block->GetPhis()); !it_phis.Done(); it_phis.Advance()) {
364 HPhi* phi = it_phis.Current()->AsPhi();
365 // If the phi is not dead, or has no environment uses, there is nothing to do.
366 if (!phi->IsDead() || !phi->HasEnvironmentUses()) continue;
367 HInstruction* next = phi->GetNext();
David Brazdild0180f92015-09-22 14:39:58 +0100368 if (!phi->IsVRegEquivalentOf(next)) continue;
Nicolas Geoffraye0fe7ae2015-03-09 10:02:49 +0000369 if (next->AsPhi()->IsDead()) {
370 // If the phi equivalent is dead, check if there is another one.
371 next = next->GetNext();
David Brazdild0180f92015-09-22 14:39:58 +0100372 if (!phi->IsVRegEquivalentOf(next)) continue;
Nicolas Geoffraye0fe7ae2015-03-09 10:02:49 +0000373 // There can be at most two phi equivalents.
David Brazdild0180f92015-09-22 14:39:58 +0100374 DCHECK(!phi->IsVRegEquivalentOf(next->GetNext()));
Nicolas Geoffraye0fe7ae2015-03-09 10:02:49 +0000375 if (next->AsPhi()->IsDead()) continue;
376 }
377 // We found a live phi equivalent. Update the environment uses of `phi` with it.
378 phi->ReplaceWith(next);
379 }
Nicolas Geoffrayd6138ef2015-02-18 14:48:53 +0000380 }
381
Alex Light68289a52015-12-15 17:30:30 -0800382 // 10) Deal with phis to guarantee liveness of phis in case of a debuggable
383 // application. This is for satisfying statement (c) of the SsaBuilder
384 // (see ssa_builder.h).
385 if (GetGraph()->IsDebuggable()) {
386 DeadPhiHandling dead_phi_handler(GetGraph());
387 dead_phi_handler.Run();
Nicolas Geoffraye0fe7ae2015-03-09 10:02:49 +0000388 }
389
Alex Light68289a52015-12-15 17:30:30 -0800390 // 11) Now that the right phis are used for the environments, and we
391 // have potentially revive dead phis in case of a debuggable application,
392 // we can eliminate phis we do not need. Regardless of the debuggable status,
393 // this phase is necessary for statement (b) of the SsaBuilder (see ssa_builder.h),
394 // as well as for the code generation, which does not deal with phis of conflicting
David Brazdild9510df2015-11-04 23:30:22 +0000395 // input types.
Alex Light68289a52015-12-15 17:30:30 -0800396 dead_phis.EliminateDeadPhis();
David Brazdild9510df2015-11-04 23:30:22 +0000397
Alex Light68289a52015-12-15 17:30:30 -0800398 // 12) Clear locals.
Nicolas Geoffrayf635e632014-05-14 09:43:38 +0100399 for (HInstructionIterator it(GetGraph()->GetEntryBlock()->GetInstructions());
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100400 !it.Done();
401 it.Advance()) {
402 HInstruction* current = it.Current();
Roland Levillain476df552014-10-09 17:51:36 +0100403 if (current->IsLocal()) {
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100404 current->GetBlock()->RemoveInstruction(current);
405 }
406 }
407}
408
David Brazdileead0712015-09-18 14:58:57 +0100409ArenaVector<HInstruction*>* SsaBuilder::GetLocalsFor(HBasicBlock* block) {
David Brazdileead0712015-09-18 14:58:57 +0100410 ArenaVector<HInstruction*>* locals = &locals_for_[block->GetBlockId()];
411 const size_t vregs = GetGraph()->GetNumberOfVRegs();
412 if (locals->empty() && vregs != 0u) {
413 locals->resize(vregs, nullptr);
414
415 if (block->IsCatchBlock()) {
416 ArenaAllocator* arena = GetGraph()->GetArena();
417 // We record incoming inputs of catch phis at throwing instructions and
418 // must therefore eagerly create the phis. Phis for undefined vregs will
419 // be deleted when the first throwing instruction with the vreg undefined
420 // is encountered. Unused phis will be removed by dead phi analysis.
421 for (size_t i = 0; i < vregs; ++i) {
422 // No point in creating the catch phi if it is already undefined at
423 // the first throwing instruction.
David Brazdil809d70f2015-11-19 10:29:39 +0000424 HInstruction* current_local_value = (*current_locals_)[i];
425 if (current_local_value != nullptr) {
426 HPhi* phi = new (arena) HPhi(
427 arena,
428 i,
429 0,
430 current_local_value->GetType());
David Brazdileead0712015-09-18 14:58:57 +0100431 block->AddPhi(phi);
432 (*locals)[i] = phi;
433 }
434 }
435 }
436 }
437 return locals;
438}
439
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100440HInstruction* SsaBuilder::ValueOfLocal(HBasicBlock* block, size_t local) {
Vladimir Marko71bf8092015-09-15 15:33:14 +0100441 ArenaVector<HInstruction*>* locals = GetLocalsFor(block);
Vladimir Marko71bf8092015-09-15 15:33:14 +0100442 return (*locals)[local];
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100443}
444
445void SsaBuilder::VisitBasicBlock(HBasicBlock* block) {
446 current_locals_ = GetLocalsFor(block);
447
David Brazdilffee3d32015-07-06 11:48:53 +0100448 if (block->IsCatchBlock()) {
449 // Catch phis were already created and inputs collected from throwing sites.
David Brazdild0180f92015-09-22 14:39:58 +0100450 if (kIsDebugBuild) {
451 // Make sure there was at least one throwing instruction which initialized
452 // locals (guaranteed by HGraphBuilder) and that all try blocks have been
453 // visited already (from HTryBoundary scoping and reverse post order).
454 bool throwing_instruction_found = false;
455 bool catch_block_visited = false;
456 for (HReversePostOrderIterator it(*GetGraph()); !it.Done(); it.Advance()) {
457 HBasicBlock* current = it.Current();
458 if (current == block) {
459 catch_block_visited = true;
460 } else if (current->IsTryBlock() &&
461 current->GetTryCatchInformation()->GetTryEntry().HasExceptionHandler(*block)) {
462 DCHECK(!catch_block_visited) << "Catch block visited before its try block.";
463 throwing_instruction_found |= current->HasThrowingInstructions();
464 }
465 }
466 DCHECK(throwing_instruction_found) << "No instructions throwing into a live catch block.";
467 }
David Brazdilffee3d32015-07-06 11:48:53 +0100468 } else if (block->IsLoopHeader()) {
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100469 // If the block is a loop header, we know we only have visited the pre header
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100470 // because we are visiting in reverse post order. We create phis for all initialized
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100471 // locals from the pre header. Their inputs will be populated at the end of
472 // the analysis.
Vladimir Marko71bf8092015-09-15 15:33:14 +0100473 for (size_t local = 0; local < current_locals_->size(); ++local) {
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100474 HInstruction* incoming = ValueOfLocal(block->GetLoopInformation()->GetPreHeader(), local);
475 if (incoming != nullptr) {
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100476 HPhi* phi = new (GetGraph()->GetArena()) HPhi(
David Brazdil809d70f2015-11-19 10:29:39 +0000477 GetGraph()->GetArena(),
478 local,
479 0,
480 incoming->GetType());
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100481 block->AddPhi(phi);
Vladimir Marko71bf8092015-09-15 15:33:14 +0100482 (*current_locals_)[local] = phi;
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100483 }
484 }
485 // Save the loop header so that the last phase of the analysis knows which
486 // blocks need to be updated.
Vladimir Marko71bf8092015-09-15 15:33:14 +0100487 loop_headers_.push_back(block);
Vladimir Marko60584552015-09-03 13:35:12 +0000488 } else if (block->GetPredecessors().size() > 0) {
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100489 // All predecessors have already been visited because we are visiting in reverse post order.
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100490 // We merge the values of all locals, creating phis if those values differ.
Vladimir Marko71bf8092015-09-15 15:33:14 +0100491 for (size_t local = 0; local < current_locals_->size(); ++local) {
Nicolas Geoffray7c3560f2014-06-04 12:12:08 +0100492 bool one_predecessor_has_no_value = false;
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100493 bool is_different = false;
Vladimir Markoec7802a2015-10-01 20:57:57 +0100494 HInstruction* value = ValueOfLocal(block->GetPredecessors()[0], local);
Nicolas Geoffray7c3560f2014-06-04 12:12:08 +0100495
Vladimir Marko60584552015-09-03 13:35:12 +0000496 for (HBasicBlock* predecessor : block->GetPredecessors()) {
497 HInstruction* current = ValueOfLocal(predecessor, local);
Nicolas Geoffray7c3560f2014-06-04 12:12:08 +0100498 if (current == nullptr) {
Nicolas Geoffrayec7e4722014-06-06 11:24:33 +0100499 one_predecessor_has_no_value = true;
500 break;
Nicolas Geoffray7c3560f2014-06-04 12:12:08 +0100501 } else if (current != value) {
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100502 is_different = true;
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100503 }
504 }
Nicolas Geoffray7c3560f2014-06-04 12:12:08 +0100505
506 if (one_predecessor_has_no_value) {
507 // If one predecessor has no value for this local, we trust the verifier has
508 // successfully checked that there is a store dominating any read after this block.
509 continue;
510 }
511
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100512 if (is_different) {
David Brazdil809d70f2015-11-19 10:29:39 +0000513 HInstruction* first_input = ValueOfLocal(block->GetPredecessors()[0], local);
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100514 HPhi* phi = new (GetGraph()->GetArena()) HPhi(
David Brazdil809d70f2015-11-19 10:29:39 +0000515 GetGraph()->GetArena(),
516 local,
517 block->GetPredecessors().size(),
518 first_input->GetType());
Vladimir Marko60584552015-09-03 13:35:12 +0000519 for (size_t i = 0; i < block->GetPredecessors().size(); i++) {
Vladimir Markoec7802a2015-10-01 20:57:57 +0100520 HInstruction* pred_value = ValueOfLocal(block->GetPredecessors()[i], local);
Andreas Gampe277ccbd2014-11-03 21:36:10 -0800521 phi->SetRawInputAt(i, pred_value);
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100522 }
523 block->AddPhi(phi);
524 value = phi;
525 }
Vladimir Marko71bf8092015-09-15 15:33:14 +0100526 (*current_locals_)[local] = value;
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100527 }
528 }
529
530 // Visit all instructions. The instructions of interest are:
531 // - HLoadLocal: replace them with the current value of the local.
532 // - HStoreLocal: update current value of the local and remove the instruction.
533 // - Instructions that require an environment: populate their environment
534 // with the current values of the locals.
Nicolas Geoffrayf635e632014-05-14 09:43:38 +0100535 for (HInstructionIterator it(block->GetInstructions()); !it.Done(); it.Advance()) {
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100536 it.Current()->Accept(this);
537 }
538}
539
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100540/**
541 * Constants in the Dex format are not typed. So the builder types them as
542 * integers, but when doing the SSA form, we might realize the constant
543 * is used for floating point operations. We create a floating-point equivalent
544 * constant to make the operations correctly typed.
545 */
David Brazdil8d5b8b22015-03-24 10:51:52 +0000546HFloatConstant* SsaBuilder::GetFloatEquivalent(HIntConstant* constant) {
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100547 // We place the floating point constant next to this constant.
548 HFloatConstant* result = constant->GetNext()->AsFloatConstant();
549 if (result == nullptr) {
550 HGraph* graph = constant->GetBlock()->GetGraph();
551 ArenaAllocator* allocator = graph->GetArena();
Roland Levillainda4d79b2015-03-24 14:36:11 +0000552 result = new (allocator) HFloatConstant(bit_cast<float, int32_t>(constant->GetValue()));
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100553 constant->GetBlock()->InsertInstructionBefore(result, constant->GetNext());
Nicolas Geoffrayf213e052015-04-27 08:53:46 +0000554 graph->CacheFloatConstant(result);
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100555 } else {
556 // If there is already a constant with the expected type, we know it is
557 // the floating point equivalent of this constant.
Roland Levillainda4d79b2015-03-24 14:36:11 +0000558 DCHECK_EQ((bit_cast<int32_t, float>(result->GetValue())), constant->GetValue());
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100559 }
560 return result;
561}
562
563/**
564 * Wide constants in the Dex format are not typed. So the builder types them as
565 * longs, but when doing the SSA form, we might realize the constant
566 * is used for floating point operations. We create a floating-point equivalent
567 * constant to make the operations correctly typed.
568 */
David Brazdil8d5b8b22015-03-24 10:51:52 +0000569HDoubleConstant* SsaBuilder::GetDoubleEquivalent(HLongConstant* constant) {
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100570 // We place the floating point constant next to this constant.
571 HDoubleConstant* result = constant->GetNext()->AsDoubleConstant();
572 if (result == nullptr) {
573 HGraph* graph = constant->GetBlock()->GetGraph();
574 ArenaAllocator* allocator = graph->GetArena();
Roland Levillainda4d79b2015-03-24 14:36:11 +0000575 result = new (allocator) HDoubleConstant(bit_cast<double, int64_t>(constant->GetValue()));
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100576 constant->GetBlock()->InsertInstructionBefore(result, constant->GetNext());
Nicolas Geoffrayf213e052015-04-27 08:53:46 +0000577 graph->CacheDoubleConstant(result);
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100578 } else {
579 // If there is already a constant with the expected type, we know it is
580 // the floating point equivalent of this constant.
Roland Levillainda4d79b2015-03-24 14:36:11 +0000581 DCHECK_EQ((bit_cast<int64_t, double>(result->GetValue())), constant->GetValue());
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100582 }
583 return result;
584}
585
586/**
587 * Because of Dex format, we might end up having the same phi being
Nicolas Geoffrayd6138ef2015-02-18 14:48:53 +0000588 * used for non floating point operations and floating point / reference operations.
589 * Because we want the graph to be correctly typed (and thereafter avoid moves between
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100590 * floating point registers and core registers), we need to create a copy of the
Nicolas Geoffrayd6138ef2015-02-18 14:48:53 +0000591 * phi with a floating point / reference type.
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100592 */
David Brazdil8d5b8b22015-03-24 10:51:52 +0000593HPhi* SsaBuilder::GetFloatDoubleOrReferenceEquivalentOfPhi(HPhi* phi, Primitive::Type type) {
Nicolas Geoffrayd6138ef2015-02-18 14:48:53 +0000594 // We place the floating point /reference phi next to this phi.
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100595 HInstruction* next = phi->GetNext();
Nicolas Geoffrayd6138ef2015-02-18 14:48:53 +0000596 if (next != nullptr
597 && next->AsPhi()->GetRegNumber() == phi->GetRegNumber()
598 && next->GetType() != type) {
599 // Move to the next phi to see if it is the one we are looking for.
600 next = next->GetNext();
601 }
602
603 if (next == nullptr
604 || (next->AsPhi()->GetRegNumber() != phi->GetRegNumber())
605 || (next->GetType() != type)) {
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100606 ArenaAllocator* allocator = phi->GetBlock()->GetGraph()->GetArena();
607 HPhi* new_phi = new (allocator) HPhi(allocator, phi->GetRegNumber(), phi->InputCount(), type);
608 for (size_t i = 0, e = phi->InputCount(); i < e; ++i) {
Alex Light68289a52015-12-15 17:30:30 -0800609 // Copy the inputs. Note that the graph may not be correctly typed by doing this copy,
610 // but the type propagation phase will fix it.
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100611 new_phi->SetRawInputAt(i, phi->InputAt(i));
612 }
613 phi->GetBlock()->InsertPhiAfter(new_phi, phi);
614 return new_phi;
615 } else {
David Brazdil809d70f2015-11-19 10:29:39 +0000616 HPhi* next_phi = next->AsPhi();
617 DCHECK_EQ(next_phi->GetType(), type);
Alex Light68289a52015-12-15 17:30:30 -0800618 if (next_phi->IsDead()) {
619 // TODO(dbrazdil): Remove this SetLive (we should not need to revive phis)
620 // once we stop running MarkDeadPhis before PrimitiveTypePropagation. This
621 // cannot revive undefined loop header phis because they cannot have uses.
622 DCHECK(!IsUndefinedLoopHeaderPhi(next_phi));
623 next_phi->SetLive();
David Brazdild9510df2015-11-04 23:30:22 +0000624 }
Alex Light68289a52015-12-15 17:30:30 -0800625 return next_phi;
David Brazdild9510df2015-11-04 23:30:22 +0000626 }
627}
628
Alex Light68289a52015-12-15 17:30:30 -0800629HInstruction* SsaBuilder::GetFloatOrDoubleEquivalent(HInstruction* user,
630 HInstruction* value,
631 Primitive::Type type) {
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100632 if (value->IsArrayGet()) {
Alex Light68289a52015-12-15 17:30:30 -0800633 // The verifier has checked that values in arrays cannot be used for both
634 // floating point and non-floating point operations. It is therefore safe to just
635 // change the type of the operation.
636 value->AsArrayGet()->SetType(type);
637 return value;
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100638 } else if (value->IsLongConstant()) {
639 return GetDoubleEquivalent(value->AsLongConstant());
640 } else if (value->IsIntConstant()) {
641 return GetFloatEquivalent(value->AsIntConstant());
642 } else if (value->IsPhi()) {
Nicolas Geoffrayd6138ef2015-02-18 14:48:53 +0000643 return GetFloatDoubleOrReferenceEquivalentOfPhi(value->AsPhi(), type);
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100644 } else {
Alex Light68289a52015-12-15 17:30:30 -0800645 // For other instructions, we assume the verifier has checked that the dex format is correctly
646 // typed and the value in a dex register will not be used for both floating point and
647 // non-floating point operations. So the only reason an instruction would want a floating
648 // point equivalent is for an unused phi that will be removed by the dead phi elimination phase.
649 DCHECK(user->IsPhi()) << "is actually " << user->DebugName() << " (" << user->GetId() << ")";
650 return value;
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100651 }
652}
653
Nicolas Geoffrayd6138ef2015-02-18 14:48:53 +0000654HInstruction* SsaBuilder::GetReferenceTypeEquivalent(HInstruction* value) {
Nicolas Geoffraye0fe7ae2015-03-09 10:02:49 +0000655 if (value->IsIntConstant() && value->AsIntConstant()->GetValue() == 0) {
Nicolas Geoffrayd6138ef2015-02-18 14:48:53 +0000656 return value->GetBlock()->GetGraph()->GetNullConstant();
Nicolas Geoffraye0fe7ae2015-03-09 10:02:49 +0000657 } else if (value->IsPhi()) {
Nicolas Geoffrayd6138ef2015-02-18 14:48:53 +0000658 return GetFloatDoubleOrReferenceEquivalentOfPhi(value->AsPhi(), Primitive::kPrimNot);
Nicolas Geoffraye0fe7ae2015-03-09 10:02:49 +0000659 } else {
660 return nullptr;
Nicolas Geoffrayd6138ef2015-02-18 14:48:53 +0000661 }
662}
663
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100664void SsaBuilder::VisitLoadLocal(HLoadLocal* load) {
Vladimir Marko71bf8092015-09-15 15:33:14 +0100665 HInstruction* value = (*current_locals_)[load->GetLocal()->GetRegNumber()];
Nicolas Geoffrayd6138ef2015-02-18 14:48:53 +0000666 // If the operation requests a specific type, we make sure its input is of that type.
Alex Light68289a52015-12-15 17:30:30 -0800667 if (load->GetType() != value->GetType()) {
668 if (load->GetType() == Primitive::kPrimFloat || load->GetType() == Primitive::kPrimDouble) {
669 value = GetFloatOrDoubleEquivalent(load, value, load->GetType());
670 } else if (load->GetType() == Primitive::kPrimNot) {
Nicolas Geoffrayd6138ef2015-02-18 14:48:53 +0000671 value = GetReferenceTypeEquivalent(value);
672 }
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100673 }
674 load->ReplaceWith(value);
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100675 load->GetBlock()->RemoveInstruction(load);
676}
677
678void SsaBuilder::VisitStoreLocal(HStoreLocal* store) {
David Brazdil809d70f2015-11-19 10:29:39 +0000679 uint32_t reg_number = store->GetLocal()->GetRegNumber();
680 HInstruction* stored_value = store->InputAt(1);
681 Primitive::Type stored_type = stored_value->GetType();
682 DCHECK_NE(stored_type, Primitive::kPrimVoid);
683
684 // Storing into vreg `reg_number` may implicitly invalidate the surrounding
685 // registers. Consider the following cases:
686 // (1) Storing a wide value must overwrite previous values in both `reg_number`
687 // and `reg_number+1`. We store `nullptr` in `reg_number+1`.
688 // (2) If vreg `reg_number-1` holds a wide value, writing into `reg_number`
689 // must invalidate it. We store `nullptr` in `reg_number-1`.
690 // Consequently, storing a wide value into the high vreg of another wide value
691 // will invalidate both `reg_number-1` and `reg_number+1`.
692
693 if (reg_number != 0) {
694 HInstruction* local_low = (*current_locals_)[reg_number - 1];
695 if (local_low != nullptr && Primitive::Is64BitType(local_low->GetType())) {
696 // The vreg we are storing into was previously the high vreg of a pair.
697 // We need to invalidate its low vreg.
698 DCHECK((*current_locals_)[reg_number] == nullptr);
699 (*current_locals_)[reg_number - 1] = nullptr;
700 }
701 }
702
703 (*current_locals_)[reg_number] = stored_value;
704 if (Primitive::Is64BitType(stored_type)) {
705 // We are storing a pair. Invalidate the instruction in the high vreg.
706 (*current_locals_)[reg_number + 1] = nullptr;
707 }
708
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100709 store->GetBlock()->RemoveInstruction(store);
710}
711
712void SsaBuilder::VisitInstruction(HInstruction* instruction) {
David Brazdilffee3d32015-07-06 11:48:53 +0100713 if (instruction->NeedsEnvironment()) {
714 HEnvironment* environment = new (GetGraph()->GetArena()) HEnvironment(
715 GetGraph()->GetArena(),
Vladimir Marko71bf8092015-09-15 15:33:14 +0100716 current_locals_->size(),
David Brazdilffee3d32015-07-06 11:48:53 +0100717 GetGraph()->GetDexFile(),
718 GetGraph()->GetMethodIdx(),
719 instruction->GetDexPc(),
720 GetGraph()->GetInvokeType(),
721 instruction);
722 environment->CopyFrom(*current_locals_);
723 instruction->SetRawEnvironment(environment);
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100724 }
David Brazdilffee3d32015-07-06 11:48:53 +0100725
726 // If in a try block, propagate values of locals into catch blocks.
David Brazdilec16f792015-08-19 15:04:01 +0100727 if (instruction->CanThrowIntoCatchBlock()) {
728 const HTryBoundary& try_entry =
729 instruction->GetBlock()->GetTryCatchInformation()->GetTryEntry();
David Brazdild26a4112015-11-10 11:07:31 +0000730 for (HBasicBlock* catch_block : try_entry.GetExceptionHandlers()) {
David Brazdil3eaa32f2015-09-18 10:58:32 +0100731 ArenaVector<HInstruction*>* handler_locals = GetLocalsFor(catch_block);
Vladimir Marko71bf8092015-09-15 15:33:14 +0100732 DCHECK_EQ(handler_locals->size(), current_locals_->size());
David Brazdil3eaa32f2015-09-18 10:58:32 +0100733 for (size_t vreg = 0, e = current_locals_->size(); vreg < e; ++vreg) {
734 HInstruction* handler_value = (*handler_locals)[vreg];
735 if (handler_value == nullptr) {
736 // Vreg was undefined at a previously encountered throwing instruction
737 // and the catch phi was deleted. Do not record the local value.
738 continue;
739 }
740 DCHECK(handler_value->IsPhi());
741
742 HInstruction* local_value = (*current_locals_)[vreg];
743 if (local_value == nullptr) {
744 // This is the first instruction throwing into `catch_block` where
745 // `vreg` is undefined. Delete the catch phi.
746 catch_block->RemovePhi(handler_value->AsPhi());
747 (*handler_locals)[vreg] = nullptr;
748 } else {
749 // Vreg has been defined at all instructions throwing into `catch_block`
750 // encountered so far. Record the local value in the catch phi.
751 handler_value->AsPhi()->AddInput(local_value);
David Brazdilffee3d32015-07-06 11:48:53 +0100752 }
753 }
754 }
755 }
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100756}
757
Nicolas Geoffray421e9f92014-11-11 18:21:53 +0000758void SsaBuilder::VisitTemporary(HTemporary* temp) {
759 // Temporaries are only used by the baseline register allocator.
760 temp->GetBlock()->RemoveInstruction(temp);
761}
762
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100763} // namespace art