blob: 40c75af6efb573e660beb812f70fa71a65291020 [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"
Calin Juravle10e244f2015-01-26 18:54:32 +000020#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
Nicolas Geoffraye0fe7ae2015-03-09 10:02:49 +000025/**
26 * A debuggable application may require to reviving phis, to ensure their
27 * associated DEX register is available to a debugger. This class implements
28 * the logic for statement (c) of the SsaBuilder (see ssa_builder.h). It
29 * also makes sure that phis with incompatible input types are not revived
30 * (statement (b) of the SsaBuilder).
31 *
32 * This phase must be run after detecting dead phis through the
33 * DeadPhiElimination phase, and before deleting the dead phis.
34 */
35class DeadPhiHandling : public ValueObject {
36 public:
37 explicit DeadPhiHandling(HGraph* graph)
Vladimir Marko71bf8092015-09-15 15:33:14 +010038 : graph_(graph), worklist_(graph->GetArena()->Adapter(kArenaAllocSsaBuilder)) {
39 worklist_.reserve(kDefaultWorklistSize);
40 }
Nicolas Geoffraye0fe7ae2015-03-09 10:02:49 +000041
42 void Run();
43
44 private:
45 void VisitBasicBlock(HBasicBlock* block);
46 void ProcessWorklist();
47 void AddToWorklist(HPhi* phi);
48 void AddDependentInstructionsToWorklist(HPhi* phi);
49 bool UpdateType(HPhi* phi);
50
51 HGraph* const graph_;
Vladimir Marko71bf8092015-09-15 15:33:14 +010052 ArenaVector<HPhi*> worklist_;
Nicolas Geoffraye0fe7ae2015-03-09 10:02:49 +000053
54 static constexpr size_t kDefaultWorklistSize = 8;
55
56 DISALLOW_COPY_AND_ASSIGN(DeadPhiHandling);
57};
58
Nicolas Geoffrayb11fc612015-09-29 13:42:22 +010059static bool HasConflictingEquivalent(HPhi* phi) {
60 if (phi->GetNext() == nullptr) {
61 return false;
62 }
63 HPhi* next = phi->GetNext()->AsPhi();
64 if (next->GetRegNumber() == phi->GetRegNumber()) {
65 if (next->GetType() == Primitive::kPrimVoid) {
66 // We only get a void type for an equivalent phi we processed and found out
67 // it was conflicting.
68 return true;
69 } else {
70 // Go to the next phi, in case it is also an equivalent.
71 return HasConflictingEquivalent(next);
72 }
73 }
74 return false;
75}
76
Nicolas Geoffraye0fe7ae2015-03-09 10:02:49 +000077bool DeadPhiHandling::UpdateType(HPhi* phi) {
David Brazdilb7013152015-09-17 16:47:21 +010078 if (phi->IsDead()) {
79 // Phi was rendered dead while waiting in the worklist because it was replaced
80 // with an equivalent.
81 return false;
82 }
83
Nicolas Geoffraye0fe7ae2015-03-09 10:02:49 +000084 Primitive::Type existing = phi->GetType();
Nicolas Geoffraye0fe7ae2015-03-09 10:02:49 +000085
86 bool conflict = false;
87 Primitive::Type new_type = existing;
88 for (size_t i = 0, e = phi->InputCount(); i < e; ++i) {
89 HInstruction* input = phi->InputAt(i);
90 if (input->IsPhi() && input->AsPhi()->IsDead()) {
91 // We are doing a reverse post order visit of the graph, reviving
92 // phis that have environment uses and updating their types. If an
93 // input is a phi, and it is dead (because its input types are
94 // conflicting), this phi must be marked dead as well.
95 conflict = true;
96 break;
97 }
98 Primitive::Type input_type = HPhi::ToPhiType(input->GetType());
99
100 // The only acceptable transitions are:
101 // - From void to typed: first time we update the type of this phi.
102 // - From int to reference (or reference to int): the phi has to change
103 // to reference type. If the integer input cannot be converted to a
104 // reference input, the phi will remain dead.
105 if (new_type == Primitive::kPrimVoid) {
106 new_type = input_type;
107 } else if (new_type == Primitive::kPrimNot && input_type == Primitive::kPrimInt) {
Nicolas Geoffrayb11fc612015-09-29 13:42:22 +0100108 if (input->IsPhi() && HasConflictingEquivalent(input->AsPhi())) {
109 // If we already asked for an equivalent of the input phi, but that equivalent
110 // ended up conflicting, make this phi conflicting too.
111 conflict = true;
112 break;
113 }
Nicolas Geoffraye0fe7ae2015-03-09 10:02:49 +0000114 HInstruction* equivalent = SsaBuilder::GetReferenceTypeEquivalent(input);
115 if (equivalent == nullptr) {
116 conflict = true;
117 break;
Nicolas Geoffrayb11fc612015-09-29 13:42:22 +0100118 }
119 phi->ReplaceInput(equivalent, i);
120 if (equivalent->IsPhi()) {
121 DCHECK_EQ(equivalent->GetType(), Primitive::kPrimNot);
122 // We created a new phi, but that phi has the same inputs as the old phi. We
123 // add it to the worklist to ensure its inputs can also be converted to reference.
124 // If not, it will remain dead, and the algorithm will make the current phi dead
125 // as well.
126 equivalent->AsPhi()->SetLive();
127 AddToWorklist(equivalent->AsPhi());
Nicolas Geoffraye0fe7ae2015-03-09 10:02:49 +0000128 }
129 } else if (new_type == Primitive::kPrimInt && input_type == Primitive::kPrimNot) {
130 new_type = Primitive::kPrimNot;
131 // Start over, we may request reference equivalents for the inputs of the phi.
132 i = -1;
133 } else if (new_type != input_type) {
134 conflict = true;
135 break;
136 }
137 }
138
139 if (conflict) {
140 phi->SetType(Primitive::kPrimVoid);
141 phi->SetDead();
142 return true;
David Brazdilb7013152015-09-17 16:47:21 +0100143 } else if (existing == new_type) {
144 return false;
Nicolas Geoffraye0fe7ae2015-03-09 10:02:49 +0000145 }
David Brazdilb7013152015-09-17 16:47:21 +0100146
147 DCHECK(phi->IsLive());
148 phi->SetType(new_type);
149
150 // There might exist a `new_type` equivalent of `phi` already. In that case,
151 // we replace the equivalent with the, now live, `phi`.
152 HPhi* equivalent = phi->GetNextEquivalentPhiWithSameType();
153 if (equivalent != nullptr) {
154 // There cannot be more than two equivalents with the same type.
155 DCHECK(equivalent->GetNextEquivalentPhiWithSameType() == nullptr);
156 // If doing fix-point iteration, the equivalent might be in `worklist_`.
157 // Setting it dead will make UpdateType skip it.
158 equivalent->SetDead();
159 equivalent->ReplaceWith(phi);
160 }
161
162 return true;
Nicolas Geoffraye0fe7ae2015-03-09 10:02:49 +0000163}
164
165void DeadPhiHandling::VisitBasicBlock(HBasicBlock* block) {
166 for (HInstructionIterator it(block->GetPhis()); !it.Done(); it.Advance()) {
167 HPhi* phi = it.Current()->AsPhi();
168 if (phi->IsDead() && phi->HasEnvironmentUses()) {
169 phi->SetLive();
170 if (block->IsLoopHeader()) {
David Brazdil1d0a03c2015-09-28 14:11:09 +0100171 // Give a type to the loop phi to guarantee convergence of the algorithm.
172 // Note that the dead phi may already have a type if it is an equivalent
173 // generated for a typed LoadLocal. In that case we do not change the
174 // type because it could lead to an unsupported PrimNot/Float/Double ->
175 // PrimInt/Long transition and create same type equivalents.
176 if (phi->GetType() == Primitive::kPrimVoid) {
177 phi->SetType(phi->InputAt(0)->GetType());
178 }
Nicolas Geoffraye0fe7ae2015-03-09 10:02:49 +0000179 AddToWorklist(phi);
180 } else {
181 // Because we are doing a reverse post order visit, all inputs of
182 // this phi have been visited and therefore had their (initial) type set.
183 UpdateType(phi);
184 }
185 }
186 }
187}
188
189void DeadPhiHandling::ProcessWorklist() {
Vladimir Marko71bf8092015-09-15 15:33:14 +0100190 while (!worklist_.empty()) {
191 HPhi* instruction = worklist_.back();
192 worklist_.pop_back();
Nicolas Geoffraye0fe7ae2015-03-09 10:02:49 +0000193 // Note that the same equivalent phi can be added multiple times in the work list, if
194 // used by multiple phis. The first call to `UpdateType` will know whether the phi is
195 // dead or live.
196 if (instruction->IsLive() && UpdateType(instruction)) {
197 AddDependentInstructionsToWorklist(instruction);
198 }
199 }
200}
201
202void DeadPhiHandling::AddToWorklist(HPhi* instruction) {
203 DCHECK(instruction->IsLive());
Vladimir Marko71bf8092015-09-15 15:33:14 +0100204 worklist_.push_back(instruction);
Nicolas Geoffraye0fe7ae2015-03-09 10:02:49 +0000205}
206
207void DeadPhiHandling::AddDependentInstructionsToWorklist(HPhi* instruction) {
208 for (HUseIterator<HInstruction*> it(instruction->GetUses()); !it.Done(); it.Advance()) {
209 HPhi* phi = it.Current()->GetUser()->AsPhi();
210 if (phi != nullptr && !phi->IsDead()) {
211 AddToWorklist(phi);
212 }
213 }
214}
215
216void DeadPhiHandling::Run() {
217 for (HReversePostOrderIterator it(*graph_); !it.Done(); it.Advance()) {
218 VisitBasicBlock(it.Current());
219 }
220 ProcessWorklist();
221}
222
Calin Juravlea4f88312015-04-16 12:57:19 +0100223void SsaBuilder::FixNullConstantType() {
224 // The order doesn't matter here.
225 for (HReversePostOrderIterator itb(*GetGraph()); !itb.Done(); itb.Advance()) {
226 for (HInstructionIterator it(itb.Current()->GetInstructions()); !it.Done(); it.Advance()) {
227 HInstruction* equality_instr = it.Current();
228 if (!equality_instr->IsEqual() && !equality_instr->IsNotEqual()) {
229 continue;
230 }
231 HInstruction* left = equality_instr->InputAt(0);
232 HInstruction* right = equality_instr->InputAt(1);
Nicolas Geoffray51d400d2015-06-15 09:01:08 +0100233 HInstruction* int_operand = nullptr;
Calin Juravlea4f88312015-04-16 12:57:19 +0100234
Nicolas Geoffray51d400d2015-06-15 09:01:08 +0100235 if ((left->GetType() == Primitive::kPrimNot) && (right->GetType() == Primitive::kPrimInt)) {
236 int_operand = right;
237 } else if ((right->GetType() == Primitive::kPrimNot)
238 && (left->GetType() == Primitive::kPrimInt)) {
239 int_operand = left;
Calin Juravlea4f88312015-04-16 12:57:19 +0100240 } else {
241 continue;
242 }
243
244 // If we got here, we are comparing against a reference and the int constant
245 // should be replaced with a null constant.
Nicolas Geoffray51d400d2015-06-15 09:01:08 +0100246 // Both type propagation and redundant phi elimination ensure `int_operand`
247 // can only be the 0 constant.
248 DCHECK(int_operand->IsIntConstant());
249 DCHECK_EQ(0, int_operand->AsIntConstant()->GetValue());
250 equality_instr->ReplaceInput(GetGraph()->GetNullConstant(), int_operand == right ? 1 : 0);
Calin Juravlea4f88312015-04-16 12:57:19 +0100251 }
252 }
253}
254
255void SsaBuilder::EquivalentPhisCleanup() {
256 // The order doesn't matter here.
257 for (HReversePostOrderIterator itb(*GetGraph()); !itb.Done(); itb.Advance()) {
258 for (HInstructionIterator it(itb.Current()->GetPhis()); !it.Done(); it.Advance()) {
259 HPhi* phi = it.Current()->AsPhi();
260 HPhi* next = phi->GetNextEquivalentPhiWithSameType();
261 if (next != nullptr) {
Nicolas Geoffray4230e182015-06-29 14:34:46 +0100262 // Make sure we do not replace a live phi with a dead phi. A live phi has been
263 // handled by the type propagation phase, unlike a dead phi.
264 if (next->IsLive()) {
265 phi->ReplaceWith(next);
266 } else {
267 next->ReplaceWith(phi);
268 }
Calin Juravlea4f88312015-04-16 12:57:19 +0100269 DCHECK(next->GetNextEquivalentPhiWithSameType() == nullptr)
270 << "More then one phi equivalent with type " << phi->GetType()
271 << " found for phi" << phi->GetId();
272 }
273 }
274 }
275}
276
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100277void SsaBuilder::BuildSsa() {
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100278 // 1) Visit in reverse post order. We need to have all predecessors of a block visited
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100279 // (with the exception of loops) in order to create the right environment for that
280 // block. For loops, we create phis whose inputs will be set in 2).
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100281 for (HReversePostOrderIterator it(*GetGraph()); !it.Done(); it.Advance()) {
282 VisitBasicBlock(it.Current());
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100283 }
284
285 // 2) Set inputs of loop phis.
Vladimir Marko71bf8092015-09-15 15:33:14 +0100286 for (HBasicBlock* block : loop_headers_) {
Nicolas Geoffrayf635e632014-05-14 09:43:38 +0100287 for (HInstructionIterator it(block->GetPhis()); !it.Done(); it.Advance()) {
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100288 HPhi* phi = it.Current()->AsPhi();
Vladimir Marko60584552015-09-03 13:35:12 +0000289 for (HBasicBlock* predecessor : block->GetPredecessors()) {
290 HInstruction* input = ValueOfLocal(predecessor, phi->GetRegNumber());
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100291 phi->AddInput(input);
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100292 }
293 }
294 }
295
Nicolas Geoffrayd6138ef2015-02-18 14:48:53 +0000296 // 3) Mark dead phis. This will mark phis that are only used by environments:
Nicolas Geoffray31596742014-11-24 15:28:45 +0000297 // at the DEX level, the type of these phis does not need to be consistent, but
298 // our code generator will complain if the inputs of a phi do not have the same
Nicolas Geoffrayd6138ef2015-02-18 14:48:53 +0000299 // type. The marking allows the type propagation to know which phis it needs
300 // to handle. We mark but do not eliminate: the elimination will be done in
Nicolas Geoffrayb59dba02015-03-11 18:13:21 +0000301 // step 9).
302 SsaDeadPhiElimination dead_phis_for_type_propagation(GetGraph());
303 dead_phis_for_type_propagation.MarkDeadPhis();
Nicolas Geoffray31596742014-11-24 15:28:45 +0000304
305 // 4) Propagate types of phis. At this point, phis are typed void in the general
Nicolas Geoffrayd6138ef2015-02-18 14:48:53 +0000306 // case, or float/double/reference when we created an equivalent phi. So we
Nicolas Geoffray31596742014-11-24 15:28:45 +0000307 // need to propagate the types across phis to give them a correct type.
Calin Juravle10e244f2015-01-26 18:54:32 +0000308 PrimitiveTypePropagation type_propagation(GetGraph());
Nicolas Geoffray184d6402014-06-09 14:06:02 +0100309 type_propagation.Run();
310
Nicolas Geoffray51d400d2015-06-15 09:01:08 +0100311 // 5) When creating equivalent phis we copy the inputs of the original phi which
312 // may be improperly typed. This was fixed during the type propagation in 4) but
Calin Juravlea4f88312015-04-16 12:57:19 +0100313 // as a result we may end up with two equivalent phis with the same type for
314 // the same dex register. This pass cleans them up.
315 EquivalentPhisCleanup();
316
Nicolas Geoffray51d400d2015-06-15 09:01:08 +0100317 // 6) Mark dead phis again. Step 4) may have introduced new phis.
318 // Step 5) might enable the death of new phis.
Nicolas Geoffrayb59dba02015-03-11 18:13:21 +0000319 SsaDeadPhiElimination dead_phis(GetGraph());
320 dead_phis.MarkDeadPhis();
321
Nicolas Geoffray51d400d2015-06-15 09:01:08 +0100322 // 7) Now that the graph is correctly typed, we can get rid of redundant phis.
Nicolas Geoffraye0fe7ae2015-03-09 10:02:49 +0000323 // Note that we cannot do this phase before type propagation, otherwise
324 // we could get rid of phi equivalents, whose presence is a requirement for the
325 // type propagation phase. Note that this is to satisfy statement (a) of the
326 // SsaBuilder (see ssa_builder.h).
327 SsaRedundantPhiElimination redundant_phi(GetGraph());
328 redundant_phi.Run();
329
Nicolas Geoffray51d400d2015-06-15 09:01:08 +0100330 // 8) Fix the type for null constants which are part of an equality comparison.
331 // We need to do this after redundant phi elimination, to ensure the only cases
332 // that we can see are reference comparison against 0. The redundant phi
333 // elimination ensures we do not see a phi taking two 0 constants in a HEqual
334 // or HNotEqual.
335 FixNullConstantType();
336
Calin Juravlea4f88312015-04-16 12:57:19 +0100337 // 9) Make sure environments use the right phi "equivalent": a phi marked dead
Nicolas Geoffraye0fe7ae2015-03-09 10:02:49 +0000338 // can have a phi equivalent that is not dead. We must therefore update
339 // all environment uses of the dead phi to use its equivalent. Note that there
340 // can be multiple phis for the same Dex register that are live (for example
341 // when merging constants), in which case it is OK for the environments
342 // to just reference one.
343 for (HReversePostOrderIterator it(*GetGraph()); !it.Done(); it.Advance()) {
344 HBasicBlock* block = it.Current();
345 for (HInstructionIterator it_phis(block->GetPhis()); !it_phis.Done(); it_phis.Advance()) {
346 HPhi* phi = it_phis.Current()->AsPhi();
347 // If the phi is not dead, or has no environment uses, there is nothing to do.
348 if (!phi->IsDead() || !phi->HasEnvironmentUses()) continue;
349 HInstruction* next = phi->GetNext();
David Brazdild0180f92015-09-22 14:39:58 +0100350 if (!phi->IsVRegEquivalentOf(next)) continue;
Nicolas Geoffraye0fe7ae2015-03-09 10:02:49 +0000351 if (next->AsPhi()->IsDead()) {
352 // If the phi equivalent is dead, check if there is another one.
353 next = next->GetNext();
David Brazdild0180f92015-09-22 14:39:58 +0100354 if (!phi->IsVRegEquivalentOf(next)) continue;
Nicolas Geoffraye0fe7ae2015-03-09 10:02:49 +0000355 // There can be at most two phi equivalents.
David Brazdild0180f92015-09-22 14:39:58 +0100356 DCHECK(!phi->IsVRegEquivalentOf(next->GetNext()));
Nicolas Geoffraye0fe7ae2015-03-09 10:02:49 +0000357 if (next->AsPhi()->IsDead()) continue;
358 }
359 // We found a live phi equivalent. Update the environment uses of `phi` with it.
360 phi->ReplaceWith(next);
361 }
Nicolas Geoffrayd6138ef2015-02-18 14:48:53 +0000362 }
363
Calin Juravlea4f88312015-04-16 12:57:19 +0100364 // 10) Deal with phis to guarantee liveness of phis in case of a debuggable
Nicolas Geoffraye0fe7ae2015-03-09 10:02:49 +0000365 // application. This is for satisfying statement (c) of the SsaBuilder
366 // (see ssa_builder.h).
367 if (GetGraph()->IsDebuggable()) {
368 DeadPhiHandling dead_phi_handler(GetGraph());
369 dead_phi_handler.Run();
370 }
371
Calin Juravlea4f88312015-04-16 12:57:19 +0100372 // 11) Now that the right phis are used for the environments, and we
Nicolas Geoffraye0fe7ae2015-03-09 10:02:49 +0000373 // have potentially revive dead phis in case of a debuggable application,
374 // we can eliminate phis we do not need. Regardless of the debuggable status,
375 // this phase is necessary for statement (b) of the SsaBuilder (see ssa_builder.h),
376 // as well as for the code generation, which does not deal with phis of conflicting
377 // input types.
378 dead_phis.EliminateDeadPhis();
379
Calin Juravlea4f88312015-04-16 12:57:19 +0100380 // 12) Clear locals.
Nicolas Geoffrayf635e632014-05-14 09:43:38 +0100381 for (HInstructionIterator it(GetGraph()->GetEntryBlock()->GetInstructions());
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100382 !it.Done();
383 it.Advance()) {
384 HInstruction* current = it.Current();
Roland Levillain476df552014-10-09 17:51:36 +0100385 if (current->IsLocal()) {
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100386 current->GetBlock()->RemoveInstruction(current);
387 }
388 }
389}
390
David Brazdileead0712015-09-18 14:58:57 +0100391ArenaVector<HInstruction*>* SsaBuilder::GetLocalsFor(HBasicBlock* block) {
392 DCHECK_LT(block->GetBlockId(), locals_for_.size());
393 ArenaVector<HInstruction*>* locals = &locals_for_[block->GetBlockId()];
394 const size_t vregs = GetGraph()->GetNumberOfVRegs();
395 if (locals->empty() && vregs != 0u) {
396 locals->resize(vregs, nullptr);
397
398 if (block->IsCatchBlock()) {
399 ArenaAllocator* arena = GetGraph()->GetArena();
400 // We record incoming inputs of catch phis at throwing instructions and
401 // must therefore eagerly create the phis. Phis for undefined vregs will
402 // be deleted when the first throwing instruction with the vreg undefined
403 // is encountered. Unused phis will be removed by dead phi analysis.
404 for (size_t i = 0; i < vregs; ++i) {
405 // No point in creating the catch phi if it is already undefined at
406 // the first throwing instruction.
407 if ((*current_locals_)[i] != nullptr) {
408 HPhi* phi = new (arena) HPhi(arena, i, 0, Primitive::kPrimVoid);
409 block->AddPhi(phi);
410 (*locals)[i] = phi;
411 }
412 }
413 }
414 }
415 return locals;
416}
417
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100418HInstruction* SsaBuilder::ValueOfLocal(HBasicBlock* block, size_t local) {
Vladimir Marko71bf8092015-09-15 15:33:14 +0100419 ArenaVector<HInstruction*>* locals = GetLocalsFor(block);
420 DCHECK_LT(local, locals->size());
421 return (*locals)[local];
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100422}
423
424void SsaBuilder::VisitBasicBlock(HBasicBlock* block) {
425 current_locals_ = GetLocalsFor(block);
426
David Brazdilffee3d32015-07-06 11:48:53 +0100427 if (block->IsCatchBlock()) {
428 // Catch phis were already created and inputs collected from throwing sites.
David Brazdild0180f92015-09-22 14:39:58 +0100429 if (kIsDebugBuild) {
430 // Make sure there was at least one throwing instruction which initialized
431 // locals (guaranteed by HGraphBuilder) and that all try blocks have been
432 // visited already (from HTryBoundary scoping and reverse post order).
433 bool throwing_instruction_found = false;
434 bool catch_block_visited = false;
435 for (HReversePostOrderIterator it(*GetGraph()); !it.Done(); it.Advance()) {
436 HBasicBlock* current = it.Current();
437 if (current == block) {
438 catch_block_visited = true;
439 } else if (current->IsTryBlock() &&
440 current->GetTryCatchInformation()->GetTryEntry().HasExceptionHandler(*block)) {
441 DCHECK(!catch_block_visited) << "Catch block visited before its try block.";
442 throwing_instruction_found |= current->HasThrowingInstructions();
443 }
444 }
445 DCHECK(throwing_instruction_found) << "No instructions throwing into a live catch block.";
446 }
David Brazdilffee3d32015-07-06 11:48:53 +0100447 } else if (block->IsLoopHeader()) {
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100448 // If the block is a loop header, we know we only have visited the pre header
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100449 // because we are visiting in reverse post order. We create phis for all initialized
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100450 // locals from the pre header. Their inputs will be populated at the end of
451 // the analysis.
Vladimir Marko71bf8092015-09-15 15:33:14 +0100452 for (size_t local = 0; local < current_locals_->size(); ++local) {
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100453 HInstruction* incoming = ValueOfLocal(block->GetLoopInformation()->GetPreHeader(), local);
454 if (incoming != nullptr) {
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100455 HPhi* phi = new (GetGraph()->GetArena()) HPhi(
456 GetGraph()->GetArena(), local, 0, Primitive::kPrimVoid);
457 block->AddPhi(phi);
Vladimir Marko71bf8092015-09-15 15:33:14 +0100458 (*current_locals_)[local] = phi;
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100459 }
460 }
461 // Save the loop header so that the last phase of the analysis knows which
462 // blocks need to be updated.
Vladimir Marko71bf8092015-09-15 15:33:14 +0100463 loop_headers_.push_back(block);
Vladimir Marko60584552015-09-03 13:35:12 +0000464 } else if (block->GetPredecessors().size() > 0) {
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100465 // All predecessors have already been visited because we are visiting in reverse post order.
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100466 // We merge the values of all locals, creating phis if those values differ.
Vladimir Marko71bf8092015-09-15 15:33:14 +0100467 for (size_t local = 0; local < current_locals_->size(); ++local) {
Nicolas Geoffray7c3560f2014-06-04 12:12:08 +0100468 bool one_predecessor_has_no_value = false;
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100469 bool is_different = false;
Vladimir Marko60584552015-09-03 13:35:12 +0000470 HInstruction* value = ValueOfLocal(block->GetPredecessor(0), local);
Nicolas Geoffray7c3560f2014-06-04 12:12:08 +0100471
Vladimir Marko60584552015-09-03 13:35:12 +0000472 for (HBasicBlock* predecessor : block->GetPredecessors()) {
473 HInstruction* current = ValueOfLocal(predecessor, local);
Nicolas Geoffray7c3560f2014-06-04 12:12:08 +0100474 if (current == nullptr) {
Nicolas Geoffrayec7e4722014-06-06 11:24:33 +0100475 one_predecessor_has_no_value = true;
476 break;
Nicolas Geoffray7c3560f2014-06-04 12:12:08 +0100477 } else if (current != value) {
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100478 is_different = true;
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100479 }
480 }
Nicolas Geoffray7c3560f2014-06-04 12:12:08 +0100481
482 if (one_predecessor_has_no_value) {
483 // If one predecessor has no value for this local, we trust the verifier has
484 // successfully checked that there is a store dominating any read after this block.
485 continue;
486 }
487
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100488 if (is_different) {
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100489 HPhi* phi = new (GetGraph()->GetArena()) HPhi(
Vladimir Marko60584552015-09-03 13:35:12 +0000490 GetGraph()->GetArena(), local, block->GetPredecessors().size(), Primitive::kPrimVoid);
491 for (size_t i = 0; i < block->GetPredecessors().size(); i++) {
492 HInstruction* pred_value = ValueOfLocal(block->GetPredecessor(i), local);
Andreas Gampe277ccbd2014-11-03 21:36:10 -0800493 phi->SetRawInputAt(i, pred_value);
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100494 }
495 block->AddPhi(phi);
496 value = phi;
497 }
Vladimir Marko71bf8092015-09-15 15:33:14 +0100498 (*current_locals_)[local] = value;
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100499 }
500 }
501
502 // Visit all instructions. The instructions of interest are:
503 // - HLoadLocal: replace them with the current value of the local.
504 // - HStoreLocal: update current value of the local and remove the instruction.
505 // - Instructions that require an environment: populate their environment
506 // with the current values of the locals.
Nicolas Geoffrayf635e632014-05-14 09:43:38 +0100507 for (HInstructionIterator it(block->GetInstructions()); !it.Done(); it.Advance()) {
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100508 it.Current()->Accept(this);
509 }
510}
511
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100512/**
513 * Constants in the Dex format are not typed. So the builder types them as
514 * integers, but when doing the SSA form, we might realize the constant
515 * is used for floating point operations. We create a floating-point equivalent
516 * constant to make the operations correctly typed.
517 */
David Brazdil8d5b8b22015-03-24 10:51:52 +0000518HFloatConstant* SsaBuilder::GetFloatEquivalent(HIntConstant* constant) {
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100519 // We place the floating point constant next to this constant.
520 HFloatConstant* result = constant->GetNext()->AsFloatConstant();
521 if (result == nullptr) {
522 HGraph* graph = constant->GetBlock()->GetGraph();
523 ArenaAllocator* allocator = graph->GetArena();
Roland Levillainda4d79b2015-03-24 14:36:11 +0000524 result = new (allocator) HFloatConstant(bit_cast<float, int32_t>(constant->GetValue()));
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100525 constant->GetBlock()->InsertInstructionBefore(result, constant->GetNext());
Nicolas Geoffrayf213e052015-04-27 08:53:46 +0000526 graph->CacheFloatConstant(result);
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100527 } else {
528 // If there is already a constant with the expected type, we know it is
529 // the floating point equivalent of this constant.
Roland Levillainda4d79b2015-03-24 14:36:11 +0000530 DCHECK_EQ((bit_cast<int32_t, float>(result->GetValue())), constant->GetValue());
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100531 }
532 return result;
533}
534
535/**
536 * Wide constants in the Dex format are not typed. So the builder types them as
537 * longs, but when doing the SSA form, we might realize the constant
538 * is used for floating point operations. We create a floating-point equivalent
539 * constant to make the operations correctly typed.
540 */
David Brazdil8d5b8b22015-03-24 10:51:52 +0000541HDoubleConstant* SsaBuilder::GetDoubleEquivalent(HLongConstant* constant) {
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100542 // We place the floating point constant next to this constant.
543 HDoubleConstant* result = constant->GetNext()->AsDoubleConstant();
544 if (result == nullptr) {
545 HGraph* graph = constant->GetBlock()->GetGraph();
546 ArenaAllocator* allocator = graph->GetArena();
Roland Levillainda4d79b2015-03-24 14:36:11 +0000547 result = new (allocator) HDoubleConstant(bit_cast<double, int64_t>(constant->GetValue()));
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100548 constant->GetBlock()->InsertInstructionBefore(result, constant->GetNext());
Nicolas Geoffrayf213e052015-04-27 08:53:46 +0000549 graph->CacheDoubleConstant(result);
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100550 } else {
551 // If there is already a constant with the expected type, we know it is
552 // the floating point equivalent of this constant.
Roland Levillainda4d79b2015-03-24 14:36:11 +0000553 DCHECK_EQ((bit_cast<int64_t, double>(result->GetValue())), constant->GetValue());
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100554 }
555 return result;
556}
557
558/**
559 * Because of Dex format, we might end up having the same phi being
Nicolas Geoffrayd6138ef2015-02-18 14:48:53 +0000560 * used for non floating point operations and floating point / reference operations.
561 * Because we want the graph to be correctly typed (and thereafter avoid moves between
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100562 * floating point registers and core registers), we need to create a copy of the
Nicolas Geoffrayd6138ef2015-02-18 14:48:53 +0000563 * phi with a floating point / reference type.
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100564 */
David Brazdil8d5b8b22015-03-24 10:51:52 +0000565HPhi* SsaBuilder::GetFloatDoubleOrReferenceEquivalentOfPhi(HPhi* phi, Primitive::Type type) {
Nicolas Geoffrayd6138ef2015-02-18 14:48:53 +0000566 // We place the floating point /reference phi next to this phi.
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100567 HInstruction* next = phi->GetNext();
Nicolas Geoffrayd6138ef2015-02-18 14:48:53 +0000568 if (next != nullptr
569 && next->AsPhi()->GetRegNumber() == phi->GetRegNumber()
570 && next->GetType() != type) {
571 // Move to the next phi to see if it is the one we are looking for.
572 next = next->GetNext();
573 }
574
575 if (next == nullptr
576 || (next->AsPhi()->GetRegNumber() != phi->GetRegNumber())
577 || (next->GetType() != type)) {
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100578 ArenaAllocator* allocator = phi->GetBlock()->GetGraph()->GetArena();
579 HPhi* new_phi = new (allocator) HPhi(allocator, phi->GetRegNumber(), phi->InputCount(), type);
580 for (size_t i = 0, e = phi->InputCount(); i < e; ++i) {
581 // Copy the inputs. Note that the graph may not be correctly typed by doing this copy,
582 // but the type propagation phase will fix it.
583 new_phi->SetRawInputAt(i, phi->InputAt(i));
584 }
585 phi->GetBlock()->InsertPhiAfter(new_phi, phi);
586 return new_phi;
587 } else {
Nicolas Geoffray21cc7982014-11-17 17:50:33 +0000588 DCHECK_EQ(next->GetType(), type);
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100589 return next->AsPhi();
590 }
591}
592
593HInstruction* SsaBuilder::GetFloatOrDoubleEquivalent(HInstruction* user,
594 HInstruction* value,
595 Primitive::Type type) {
596 if (value->IsArrayGet()) {
597 // The verifier has checked that values in arrays cannot be used for both
598 // floating point and non-floating point operations. It is therefore safe to just
599 // change the type of the operation.
600 value->AsArrayGet()->SetType(type);
601 return value;
602 } else if (value->IsLongConstant()) {
603 return GetDoubleEquivalent(value->AsLongConstant());
604 } else if (value->IsIntConstant()) {
605 return GetFloatEquivalent(value->AsIntConstant());
606 } else if (value->IsPhi()) {
Nicolas Geoffrayd6138ef2015-02-18 14:48:53 +0000607 return GetFloatDoubleOrReferenceEquivalentOfPhi(value->AsPhi(), type);
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100608 } else {
609 // For other instructions, we assume the verifier has checked that the dex format is correctly
610 // typed and the value in a dex register will not be used for both floating point and
611 // non-floating point operations. So the only reason an instruction would want a floating
612 // point equivalent is for an unused phi that will be removed by the dead phi elimination phase.
Guillaume "Vermeille" Sanchez8909baf2015-04-23 21:35:11 +0100613 DCHECK(user->IsPhi()) << "is actually " << user->DebugName() << " (" << user->GetId() << ")";
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100614 return value;
615 }
616}
617
Nicolas Geoffrayd6138ef2015-02-18 14:48:53 +0000618HInstruction* SsaBuilder::GetReferenceTypeEquivalent(HInstruction* value) {
Nicolas Geoffraye0fe7ae2015-03-09 10:02:49 +0000619 if (value->IsIntConstant() && value->AsIntConstant()->GetValue() == 0) {
Nicolas Geoffrayd6138ef2015-02-18 14:48:53 +0000620 return value->GetBlock()->GetGraph()->GetNullConstant();
Nicolas Geoffraye0fe7ae2015-03-09 10:02:49 +0000621 } else if (value->IsPhi()) {
Nicolas Geoffrayd6138ef2015-02-18 14:48:53 +0000622 return GetFloatDoubleOrReferenceEquivalentOfPhi(value->AsPhi(), Primitive::kPrimNot);
Nicolas Geoffraye0fe7ae2015-03-09 10:02:49 +0000623 } else {
624 return nullptr;
Nicolas Geoffrayd6138ef2015-02-18 14:48:53 +0000625 }
626}
627
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100628void SsaBuilder::VisitLoadLocal(HLoadLocal* load) {
Vladimir Marko71bf8092015-09-15 15:33:14 +0100629 DCHECK_LT(load->GetLocal()->GetRegNumber(), current_locals_->size());
630 HInstruction* value = (*current_locals_)[load->GetLocal()->GetRegNumber()];
Nicolas Geoffrayd6138ef2015-02-18 14:48:53 +0000631 // If the operation requests a specific type, we make sure its input is of that type.
632 if (load->GetType() != value->GetType()) {
633 if (load->GetType() == Primitive::kPrimFloat || load->GetType() == Primitive::kPrimDouble) {
634 value = GetFloatOrDoubleEquivalent(load, value, load->GetType());
635 } else if (load->GetType() == Primitive::kPrimNot) {
636 value = GetReferenceTypeEquivalent(value);
637 }
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100638 }
639 load->ReplaceWith(value);
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100640 load->GetBlock()->RemoveInstruction(load);
641}
642
643void SsaBuilder::VisitStoreLocal(HStoreLocal* store) {
Vladimir Marko71bf8092015-09-15 15:33:14 +0100644 DCHECK_LT(store->GetLocal()->GetRegNumber(), current_locals_->size());
645 (*current_locals_)[store->GetLocal()->GetRegNumber()] = store->InputAt(1);
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100646 store->GetBlock()->RemoveInstruction(store);
647}
648
649void SsaBuilder::VisitInstruction(HInstruction* instruction) {
David Brazdilffee3d32015-07-06 11:48:53 +0100650 if (instruction->NeedsEnvironment()) {
651 HEnvironment* environment = new (GetGraph()->GetArena()) HEnvironment(
652 GetGraph()->GetArena(),
Vladimir Marko71bf8092015-09-15 15:33:14 +0100653 current_locals_->size(),
David Brazdilffee3d32015-07-06 11:48:53 +0100654 GetGraph()->GetDexFile(),
655 GetGraph()->GetMethodIdx(),
656 instruction->GetDexPc(),
657 GetGraph()->GetInvokeType(),
658 instruction);
659 environment->CopyFrom(*current_locals_);
660 instruction->SetRawEnvironment(environment);
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100661 }
David Brazdilffee3d32015-07-06 11:48:53 +0100662
663 // If in a try block, propagate values of locals into catch blocks.
David Brazdilec16f792015-08-19 15:04:01 +0100664 if (instruction->CanThrowIntoCatchBlock()) {
665 const HTryBoundary& try_entry =
666 instruction->GetBlock()->GetTryCatchInformation()->GetTryEntry();
667 for (HExceptionHandlerIterator it(try_entry); !it.Done(); it.Advance()) {
David Brazdil3eaa32f2015-09-18 10:58:32 +0100668 HBasicBlock* catch_block = it.Current();
669 ArenaVector<HInstruction*>* handler_locals = GetLocalsFor(catch_block);
Vladimir Marko71bf8092015-09-15 15:33:14 +0100670 DCHECK_EQ(handler_locals->size(), current_locals_->size());
David Brazdil3eaa32f2015-09-18 10:58:32 +0100671 for (size_t vreg = 0, e = current_locals_->size(); vreg < e; ++vreg) {
672 HInstruction* handler_value = (*handler_locals)[vreg];
673 if (handler_value == nullptr) {
674 // Vreg was undefined at a previously encountered throwing instruction
675 // and the catch phi was deleted. Do not record the local value.
676 continue;
677 }
678 DCHECK(handler_value->IsPhi());
679
680 HInstruction* local_value = (*current_locals_)[vreg];
681 if (local_value == nullptr) {
682 // This is the first instruction throwing into `catch_block` where
683 // `vreg` is undefined. Delete the catch phi.
684 catch_block->RemovePhi(handler_value->AsPhi());
685 (*handler_locals)[vreg] = nullptr;
686 } else {
687 // Vreg has been defined at all instructions throwing into `catch_block`
688 // encountered so far. Record the local value in the catch phi.
689 handler_value->AsPhi()->AddInput(local_value);
David Brazdilffee3d32015-07-06 11:48:53 +0100690 }
691 }
692 }
693 }
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100694}
695
Nicolas Geoffray421e9f92014-11-11 18:21:53 +0000696void SsaBuilder::VisitTemporary(HTemporary* temp) {
697 // Temporaries are only used by the baseline register allocator.
698 temp->GetBlock()->RemoveInstruction(temp);
699}
700
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100701} // namespace art