1 /* 2 * Copyright (C) 2015 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 #ifndef ART_COMPILER_OPTIMIZING_INSTRUCTION_SIMPLIFIER_ARM_H_ 18 #define ART_COMPILER_OPTIMIZING_INSTRUCTION_SIMPLIFIER_ARM_H_ 19 20 #include "nodes.h" 21 #include "optimization.h" 22 23 namespace art { 24 namespace arm { 25 26 class InstructionSimplifierArmVisitor : public HGraphVisitor { 27 public: InstructionSimplifierArmVisitor(HGraph * graph,OptimizingCompilerStats * stats)28 InstructionSimplifierArmVisitor(HGraph* graph, OptimizingCompilerStats* stats) 29 : HGraphVisitor(graph), stats_(stats) {} 30 31 private: RecordSimplification()32 void RecordSimplification() { 33 if (stats_ != nullptr) { 34 stats_->RecordStat(kInstructionSimplificationsArch); 35 } 36 } 37 38 bool TryMergeIntoUsersShifterOperand(HInstruction* instruction); 39 bool TryMergeIntoShifterOperand(HInstruction* use, HInstruction* bitfield_op, bool do_merge); CanMergeIntoShifterOperand(HInstruction * use,HInstruction * bitfield_op)40 bool CanMergeIntoShifterOperand(HInstruction* use, HInstruction* bitfield_op) { 41 return TryMergeIntoShifterOperand(use, bitfield_op, /* do_merge */ false); 42 } MergeIntoShifterOperand(HInstruction * use,HInstruction * bitfield_op)43 bool MergeIntoShifterOperand(HInstruction* use, HInstruction* bitfield_op) { 44 DCHECK(CanMergeIntoShifterOperand(use, bitfield_op)); 45 return TryMergeIntoShifterOperand(use, bitfield_op, /* do_merge */ true); 46 } 47 48 /** 49 * This simplifier uses a special-purpose BB visitor. 50 * (1) No need to visit Phi nodes. 51 * (2) Since statements can be removed in a "forward" fashion, 52 * the visitor should test if each statement is still there. 53 */ VisitBasicBlock(HBasicBlock * block)54 void VisitBasicBlock(HBasicBlock* block) OVERRIDE { 55 // TODO: fragile iteration, provide more robust iterators? 56 for (HInstructionIterator it(block->GetInstructions()); !it.Done(); it.Advance()) { 57 HInstruction* instruction = it.Current(); 58 if (instruction->IsInBlock()) { 59 instruction->Accept(this); 60 } 61 } 62 } 63 64 void VisitAnd(HAnd* instruction) OVERRIDE; 65 void VisitArrayGet(HArrayGet* instruction) OVERRIDE; 66 void VisitArraySet(HArraySet* instruction) OVERRIDE; 67 void VisitMul(HMul* instruction) OVERRIDE; 68 void VisitOr(HOr* instruction) OVERRIDE; 69 void VisitShl(HShl* instruction) OVERRIDE; 70 void VisitShr(HShr* instruction) OVERRIDE; 71 void VisitTypeConversion(HTypeConversion* instruction) OVERRIDE; 72 void VisitUShr(HUShr* instruction) OVERRIDE; 73 74 OptimizingCompilerStats* stats_; 75 }; 76 77 78 class InstructionSimplifierArm : public HOptimization { 79 public: InstructionSimplifierArm(HGraph * graph,OptimizingCompilerStats * stats)80 InstructionSimplifierArm(HGraph* graph, OptimizingCompilerStats* stats) 81 : HOptimization(graph, kInstructionSimplifierArmPassName, stats) {} 82 83 static constexpr const char* kInstructionSimplifierArmPassName = "instruction_simplifier_arm"; 84 Run()85 void Run() OVERRIDE { 86 InstructionSimplifierArmVisitor visitor(graph_, stats_); 87 visitor.VisitReversePostOrder(); 88 } 89 }; 90 91 } // namespace arm 92 } // namespace art 93 94 #endif // ART_COMPILER_OPTIMIZING_INSTRUCTION_SIMPLIFIER_ARM_H_ 95