Home | History | Annotate | Download | only in optimizing
      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_NODES_SHARED_H_
     18 #define ART_COMPILER_OPTIMIZING_NODES_SHARED_H_
     19 
     20 namespace art {
     21 
     22 class HMultiplyAccumulate : public HExpression<3> {
     23  public:
     24   HMultiplyAccumulate(Primitive::Type type,
     25                       InstructionKind op,
     26                       HInstruction* accumulator,
     27                       HInstruction* mul_left,
     28                       HInstruction* mul_right,
     29                       uint32_t dex_pc = kNoDexPc)
     30       : HExpression(type, SideEffects::None(), dex_pc), op_kind_(op) {
     31     SetRawInputAt(kInputAccumulatorIndex, accumulator);
     32     SetRawInputAt(kInputMulLeftIndex, mul_left);
     33     SetRawInputAt(kInputMulRightIndex, mul_right);
     34   }
     35 
     36   static constexpr int kInputAccumulatorIndex = 0;
     37   static constexpr int kInputMulLeftIndex = 1;
     38   static constexpr int kInputMulRightIndex = 2;
     39 
     40   bool CanBeMoved() const OVERRIDE { return true; }
     41   bool InstructionDataEquals(HInstruction* other) const OVERRIDE {
     42     return op_kind_ == other->AsMultiplyAccumulate()->op_kind_;
     43   }
     44 
     45   InstructionKind GetOpKind() const { return op_kind_; }
     46 
     47   DECLARE_INSTRUCTION(MultiplyAccumulate);
     48 
     49  private:
     50   // Indicates if this is a MADD or MSUB.
     51   const InstructionKind op_kind_;
     52 
     53   DISALLOW_COPY_AND_ASSIGN(HMultiplyAccumulate);
     54 };
     55 
     56 class HBitwiseNegatedRight : public HBinaryOperation {
     57  public:
     58   HBitwiseNegatedRight(Primitive::Type result_type,
     59                             InstructionKind op,
     60                             HInstruction* left,
     61                             HInstruction* right,
     62                             uint32_t dex_pc = kNoDexPc)
     63     : HBinaryOperation(result_type, left, right, SideEffects::None(), dex_pc),
     64       op_kind_(op) {
     65     DCHECK(op == HInstruction::kAnd || op == HInstruction::kOr || op == HInstruction::kXor) << op;
     66   }
     67 
     68   template <typename T, typename U>
     69   auto Compute(T x, U y) const -> decltype(x & ~y) {
     70     static_assert(std::is_same<decltype(x & ~y), decltype(x | ~y)>::value &&
     71                   std::is_same<decltype(x & ~y), decltype(x ^ ~y)>::value,
     72                   "Inconsistent negated bitwise types");
     73     switch (op_kind_) {
     74       case HInstruction::kAnd:
     75         return x & ~y;
     76       case HInstruction::kOr:
     77         return x | ~y;
     78       case HInstruction::kXor:
     79         return x ^ ~y;
     80       default:
     81         LOG(FATAL) << "Unreachable";
     82         UNREACHABLE();
     83     }
     84   }
     85 
     86   HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE {
     87     return GetBlock()->GetGraph()->GetIntConstant(
     88         Compute(x->GetValue(), y->GetValue()), GetDexPc());
     89   }
     90   HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE {
     91     return GetBlock()->GetGraph()->GetLongConstant(
     92         Compute(x->GetValue(), y->GetValue()), GetDexPc());
     93   }
     94   HConstant* Evaluate(HFloatConstant* x ATTRIBUTE_UNUSED,
     95                       HFloatConstant* y ATTRIBUTE_UNUSED) const OVERRIDE {
     96     LOG(FATAL) << DebugName() << " is not defined for float values";
     97     UNREACHABLE();
     98   }
     99   HConstant* Evaluate(HDoubleConstant* x ATTRIBUTE_UNUSED,
    100                       HDoubleConstant* y ATTRIBUTE_UNUSED) const OVERRIDE {
    101     LOG(FATAL) << DebugName() << " is not defined for double values";
    102     UNREACHABLE();
    103   }
    104 
    105   InstructionKind GetOpKind() const { return op_kind_; }
    106 
    107   DECLARE_INSTRUCTION(BitwiseNegatedRight);
    108 
    109  private:
    110   // Specifies the bitwise operation, which will be then negated.
    111   const InstructionKind op_kind_;
    112 
    113   DISALLOW_COPY_AND_ASSIGN(HBitwiseNegatedRight);
    114 };
    115 
    116 }  // namespace art
    117 
    118 #endif  // ART_COMPILER_OPTIMIZING_NODES_SHARED_H_
    119