1 /* 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 "post_opt_passes.h" 18 #include "dataflow_iterator.h" 19 #include "dataflow_iterator-inl.h" 20 21 namespace art { 22 23 /* 24 * MethodUseCount pass implementation start. 25 */ Gate(const PassDataHolder * data) const26bool MethodUseCount::Gate(const PassDataHolder* data) const { 27 DCHECK(data != nullptr); 28 CompilationUnit* c_unit = down_cast<const PassMEDataHolder*>(data)->c_unit; 29 DCHECK(c_unit != nullptr); 30 // First initialize the data. 31 c_unit->mir_graph->InitializeMethodUses(); 32 33 // Now check if the pass is to be ignored. 34 bool res = ((c_unit->disable_opt & (1 << kPromoteRegs)) == 0); 35 36 return res; 37 } 38 Worker(const PassDataHolder * data) const39bool MethodUseCount::Worker(const PassDataHolder* data) const { 40 DCHECK(data != nullptr); 41 const PassMEDataHolder* pass_me_data_holder = down_cast<const PassMEDataHolder*>(data); 42 CompilationUnit* c_unit = pass_me_data_holder->c_unit; 43 DCHECK(c_unit != nullptr); 44 BasicBlock* bb = pass_me_data_holder->bb; 45 DCHECK(bb != nullptr); 46 c_unit->mir_graph->CountUses(bb); 47 // No need of repeating, so just return false. 48 return false; 49 } 50 51 Worker(const PassDataHolder * data) const52bool ClearPhiInstructions::Worker(const PassDataHolder* data) const { 53 DCHECK(data != nullptr); 54 const PassMEDataHolder* pass_me_data_holder = down_cast<const PassMEDataHolder*>(data); 55 CompilationUnit* c_unit = pass_me_data_holder->c_unit; 56 DCHECK(c_unit != nullptr); 57 BasicBlock* bb = pass_me_data_holder->bb; 58 DCHECK(bb != nullptr); 59 MIR* mir = bb->first_mir_insn; 60 61 while (mir != nullptr) { 62 MIR* next = mir->next; 63 64 Instruction::Code opcode = mir->dalvikInsn.opcode; 65 66 if (opcode == static_cast<Instruction::Code> (kMirOpPhi)) { 67 bb->RemoveMIR(mir); 68 } 69 70 mir = next; 71 } 72 73 // We do not care in reporting a change or not in the MIR. 74 return false; 75 } 76 Start(PassDataHolder * data) const77void CalculatePredecessors::Start(PassDataHolder* data) const { 78 DCHECK(data != nullptr); 79 CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit; 80 DCHECK(c_unit != nullptr); 81 // First get the MIRGraph here to factorize a bit the code. 82 MIRGraph *mir_graph = c_unit->mir_graph.get(); 83 84 // First clear all predecessors. 85 AllNodesIterator first(mir_graph); 86 for (BasicBlock* bb = first.Next(); bb != nullptr; bb = first.Next()) { 87 bb->predecessors->Reset(); 88 } 89 90 // Now calculate all predecessors. 91 AllNodesIterator second(mir_graph); 92 for (BasicBlock* bb = second.Next(); bb != nullptr; bb = second.Next()) { 93 // We only care about non hidden blocks. 94 if (bb->hidden == true) { 95 continue; 96 } 97 98 // Create iterator for visiting children. 99 ChildBlockIterator child_iter(bb, mir_graph); 100 101 // Now iterate through the children to set the predecessor bits. 102 for (BasicBlock* child = child_iter.Next(); child != nullptr; child = child_iter.Next()) { 103 child->predecessors->Insert(bb->id); 104 } 105 } 106 } 107 108 } // namespace art 109