1 /* 2 * Copyright (C) 2016 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_NODES_MIPS_H_ 18 #define ART_COMPILER_OPTIMIZING_NODES_MIPS_H_ 19 20 namespace art { 21 22 // Compute the address of the method for MIPS Constant area support. 23 class HMipsComputeBaseMethodAddress : public HExpression<0> { 24 public: 25 // Treat the value as an int32_t, but it is really a 32 bit native pointer. HMipsComputeBaseMethodAddress()26 HMipsComputeBaseMethodAddress() 27 : HExpression(kMipsComputeBaseMethodAddress, 28 DataType::Type::kInt32, 29 SideEffects::None(), 30 kNoDexPc) { 31 } 32 CanBeMoved()33 bool CanBeMoved() const override { return true; } 34 35 DECLARE_INSTRUCTION(MipsComputeBaseMethodAddress); 36 37 protected: 38 DEFAULT_COPY_CONSTRUCTOR(MipsComputeBaseMethodAddress); 39 }; 40 41 // Mips version of HPackedSwitch that holds a pointer to the base method address. 42 class HMipsPackedSwitch final : public HExpression<2> { 43 public: HMipsPackedSwitch(int32_t start_value,int32_t num_entries,HInstruction * input,HMipsComputeBaseMethodAddress * method_base,uint32_t dex_pc)44 HMipsPackedSwitch(int32_t start_value, 45 int32_t num_entries, 46 HInstruction* input, 47 HMipsComputeBaseMethodAddress* method_base, 48 uint32_t dex_pc) 49 : HExpression(kMipsPackedSwitch, SideEffects::None(), dex_pc), 50 start_value_(start_value), 51 num_entries_(num_entries) { 52 SetRawInputAt(0, input); 53 SetRawInputAt(1, method_base); 54 } 55 IsControlFlow()56 bool IsControlFlow() const override { return true; } 57 GetStartValue()58 int32_t GetStartValue() const { return start_value_; } 59 GetNumEntries()60 int32_t GetNumEntries() const { return num_entries_; } 61 GetDefaultBlock()62 HBasicBlock* GetDefaultBlock() const { 63 // Last entry is the default block. 64 return GetBlock()->GetSuccessors()[num_entries_]; 65 } 66 67 DECLARE_INSTRUCTION(MipsPackedSwitch); 68 69 protected: 70 DEFAULT_COPY_CONSTRUCTOR(MipsPackedSwitch); 71 72 private: 73 const int32_t start_value_; 74 const int32_t num_entries_; 75 }; 76 77 // This instruction computes part of the array access offset (index offset). 78 // 79 // For array accesses the element address has the following structure: 80 // Address = CONST_OFFSET + base_addr + index << ELEM_SHIFT. The address part 81 // (index << ELEM_SHIFT) can be shared across array accesses with 82 // the same data type and index. For example, in the following loop 5 accesses can share address 83 // computation: 84 // 85 // void foo(int[] a, int[] b, int[] c) { 86 // for (i...) { 87 // a[i] = a[i] + 5; 88 // b[i] = b[i] + c[i]; 89 // } 90 // } 91 // 92 // Note: as the instruction doesn't involve base array address into computations it has no side 93 // effects. 94 class HIntermediateArrayAddressIndex final : public HExpression<2> { 95 public: HIntermediateArrayAddressIndex(HInstruction * index,HInstruction * shift,uint32_t dex_pc)96 HIntermediateArrayAddressIndex(HInstruction* index, HInstruction* shift, uint32_t dex_pc) 97 : HExpression(kIntermediateArrayAddressIndex, 98 DataType::Type::kInt32, 99 SideEffects::None(), 100 dex_pc) { 101 SetRawInputAt(0, index); 102 SetRawInputAt(1, shift); 103 } 104 CanBeMoved()105 bool CanBeMoved() const override { return true; } InstructionDataEquals(const HInstruction * other ATTRIBUTE_UNUSED)106 bool InstructionDataEquals(const HInstruction* other ATTRIBUTE_UNUSED) const override { 107 return true; 108 } IsActualObject()109 bool IsActualObject() const override { return false; } 110 GetIndex()111 HInstruction* GetIndex() const { return InputAt(0); } GetShift()112 HInstruction* GetShift() const { return InputAt(1); } 113 114 DECLARE_INSTRUCTION(IntermediateArrayAddressIndex); 115 116 protected: 117 DEFAULT_COPY_CONSTRUCTOR(IntermediateArrayAddressIndex); 118 }; 119 120 } // namespace art 121 122 #endif // ART_COMPILER_OPTIMIZING_NODES_MIPS_H_ 123