blob: 814202e97b320f88ca905c09134e9763d3fa7a04 [file] [log] [blame]
Artem Udovichenko4a0dad62016-01-26 12:28:31 +03001/*
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_NODES_SHARED_H_
18#define ART_COMPILER_OPTIMIZING_NODES_SHARED_H_
19
Alexandre Ramesebc32802016-09-19 13:56:18 +010020// This `#include` should never be used by compilation, as this file (`nodes_shared.h`) is included
21// in `nodes.h`. However it helps editing tools (e.g. YouCompleteMe) by giving them better context
22// (defining `HInstruction` and co).
23#include "nodes.h"
24
Artem Udovichenko4a0dad62016-01-26 12:28:31 +030025namespace art {
26
Vladimir Markofcb503c2016-05-18 12:48:17 +010027class HMultiplyAccumulate FINAL : public HExpression<3> {
Artem Udovichenko4a0dad62016-01-26 12:28:31 +030028 public:
29 HMultiplyAccumulate(Primitive::Type type,
30 InstructionKind op,
31 HInstruction* accumulator,
32 HInstruction* mul_left,
33 HInstruction* mul_right,
34 uint32_t dex_pc = kNoDexPc)
35 : HExpression(type, SideEffects::None(), dex_pc), op_kind_(op) {
36 SetRawInputAt(kInputAccumulatorIndex, accumulator);
37 SetRawInputAt(kInputMulLeftIndex, mul_left);
38 SetRawInputAt(kInputMulRightIndex, mul_right);
39 }
40
41 static constexpr int kInputAccumulatorIndex = 0;
42 static constexpr int kInputMulLeftIndex = 1;
43 static constexpr int kInputMulRightIndex = 2;
44
45 bool CanBeMoved() const OVERRIDE { return true; }
Vladimir Marko372f10e2016-05-17 16:30:10 +010046 bool InstructionDataEquals(const HInstruction* other) const OVERRIDE {
Artem Udovichenko4a0dad62016-01-26 12:28:31 +030047 return op_kind_ == other->AsMultiplyAccumulate()->op_kind_;
48 }
49
50 InstructionKind GetOpKind() const { return op_kind_; }
51
52 DECLARE_INSTRUCTION(MultiplyAccumulate);
53
54 private:
55 // Indicates if this is a MADD or MSUB.
56 const InstructionKind op_kind_;
57
58 DISALLOW_COPY_AND_ASSIGN(HMultiplyAccumulate);
59};
60
Vladimir Markofcb503c2016-05-18 12:48:17 +010061class HBitwiseNegatedRight FINAL : public HBinaryOperation {
Artem Serov7fc63502016-02-09 17:15:29 +000062 public:
63 HBitwiseNegatedRight(Primitive::Type result_type,
64 InstructionKind op,
65 HInstruction* left,
66 HInstruction* right,
67 uint32_t dex_pc = kNoDexPc)
68 : HBinaryOperation(result_type, left, right, SideEffects::None(), dex_pc),
69 op_kind_(op) {
70 DCHECK(op == HInstruction::kAnd || op == HInstruction::kOr || op == HInstruction::kXor) << op;
71 }
72
73 template <typename T, typename U>
74 auto Compute(T x, U y) const -> decltype(x & ~y) {
75 static_assert(std::is_same<decltype(x & ~y), decltype(x | ~y)>::value &&
76 std::is_same<decltype(x & ~y), decltype(x ^ ~y)>::value,
77 "Inconsistent negated bitwise types");
78 switch (op_kind_) {
79 case HInstruction::kAnd:
80 return x & ~y;
81 case HInstruction::kOr:
82 return x | ~y;
83 case HInstruction::kXor:
84 return x ^ ~y;
85 default:
86 LOG(FATAL) << "Unreachable";
87 UNREACHABLE();
88 }
89 }
90
91 HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE {
92 return GetBlock()->GetGraph()->GetIntConstant(
93 Compute(x->GetValue(), y->GetValue()), GetDexPc());
94 }
95 HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE {
96 return GetBlock()->GetGraph()->GetLongConstant(
97 Compute(x->GetValue(), y->GetValue()), GetDexPc());
98 }
99 HConstant* Evaluate(HFloatConstant* x ATTRIBUTE_UNUSED,
100 HFloatConstant* y ATTRIBUTE_UNUSED) const OVERRIDE {
101 LOG(FATAL) << DebugName() << " is not defined for float values";
102 UNREACHABLE();
103 }
104 HConstant* Evaluate(HDoubleConstant* x ATTRIBUTE_UNUSED,
105 HDoubleConstant* y ATTRIBUTE_UNUSED) const OVERRIDE {
106 LOG(FATAL) << DebugName() << " is not defined for double values";
107 UNREACHABLE();
108 }
109
110 InstructionKind GetOpKind() const { return op_kind_; }
111
112 DECLARE_INSTRUCTION(BitwiseNegatedRight);
113
114 private:
115 // Specifies the bitwise operation, which will be then negated.
116 const InstructionKind op_kind_;
117
118 DISALLOW_COPY_AND_ASSIGN(HBitwiseNegatedRight);
119};
120
Artem Serov328429f2016-07-06 16:23:04 +0100121
122// This instruction computes an intermediate address pointing in the 'middle' of an object. The
123// result pointer cannot be handled by GC, so extra care is taken to make sure that this value is
124// never used across anything that can trigger GC.
Alexandre Rames91a65162016-09-19 13:54:30 +0100125// The result of this instruction is not a pointer in the sense of `Primitive::kPrimNot`. So we
126// represent it by the type `Primitive::kPrimInt`.
Artem Serov328429f2016-07-06 16:23:04 +0100127class HIntermediateAddress FINAL : public HExpression<2> {
128 public:
129 HIntermediateAddress(HInstruction* base_address, HInstruction* offset, uint32_t dex_pc)
Alexandre Rames91a65162016-09-19 13:54:30 +0100130 : HExpression(Primitive::kPrimInt, SideEffects::DependsOnGC(), dex_pc) {
131 DCHECK_EQ(Primitive::ComponentSize(Primitive::kPrimInt),
132 Primitive::ComponentSize(Primitive::kPrimNot))
133 << "kPrimInt and kPrimNot have different sizes.";
Artem Serov328429f2016-07-06 16:23:04 +0100134 SetRawInputAt(0, base_address);
135 SetRawInputAt(1, offset);
136 }
137
138 bool CanBeMoved() const OVERRIDE { return true; }
139 bool InstructionDataEquals(const HInstruction* other ATTRIBUTE_UNUSED) const OVERRIDE {
140 return true;
141 }
142 bool IsActualObject() const OVERRIDE { return false; }
143
144 HInstruction* GetBaseAddress() const { return InputAt(0); }
145 HInstruction* GetOffset() const { return InputAt(1); }
146
147 DECLARE_INSTRUCTION(IntermediateAddress);
148
149 private:
150 DISALLOW_COPY_AND_ASSIGN(HIntermediateAddress);
151};
152
153
Artem Udovichenko4a0dad62016-01-26 12:28:31 +0300154} // namespace art
155
156#endif // ART_COMPILER_OPTIMIZING_NODES_SHARED_H_