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