144b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames/*
244b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames * Copyright (C) 2015 The Android Open Source Project
344b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames *
444b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames * Licensed under the Apache License, Version 2.0 (the "License");
544b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames * you may not use this file except in compliance with the License.
644b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames * You may obtain a copy of the License at
744b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames *
844b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames *      http://www.apache.org/licenses/LICENSE-2.0
944b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames *
1044b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames * Unless required by applicable law or agreed to in writing, software
1144b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames * distributed under the License is distributed on an "AS IS" BASIS,
1244b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1344b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames * See the License for the specific language governing permissions and
1444b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames * limitations under the License.
1544b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames */
1644b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames
1744b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames#ifndef ART_COMPILER_OPTIMIZING_INSTRUCTION_SIMPLIFIER_ARM64_H_
1844b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames#define ART_COMPILER_OPTIMIZING_INSTRUCTION_SIMPLIFIER_ARM64_H_
1944b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames
2044b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames#include "nodes.h"
2144b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames#include "optimization.h"
2244b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames
2344b9cf937836bb33139123e15ca8b586b5853268Alexandre Ramesnamespace art {
2444b9cf937836bb33139123e15ca8b586b5853268Alexandre Ramesnamespace arm64 {
2544b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames
2644b9cf937836bb33139123e15ca8b586b5853268Alexandre Ramesclass InstructionSimplifierArm64Visitor : public HGraphVisitor {
2744b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames public:
2844b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames  InstructionSimplifierArm64Visitor(HGraph* graph, OptimizingCompilerStats* stats)
2944b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames      : HGraphVisitor(graph), stats_(stats) {}
3044b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames
3144b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames private:
3244b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames  void RecordSimplification() {
3344b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames    if (stats_ != nullptr) {
3444b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames      stats_->RecordStat(kInstructionSimplificationsArch);
3544b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames    }
3644b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames  }
3744b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames
38e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames  void TryExtractArrayAccessAddress(HInstruction* access,
39e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames                                    HInstruction* array,
40e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames                                    HInstruction* index,
41e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames                                    int access_size);
428626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  bool TryMergeIntoUsersShifterOperand(HInstruction* instruction);
438626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  bool TryMergeIntoShifterOperand(HInstruction* use,
448626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames                                  HInstruction* bitfield_op,
458626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames                                  bool do_merge);
468626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  bool CanMergeIntoShifterOperand(HInstruction* use, HInstruction* bitfield_op) {
478626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames    return TryMergeIntoShifterOperand(use, bitfield_op, false);
488626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  }
498626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  bool MergeIntoShifterOperand(HInstruction* use, HInstruction* bitfield_op) {
508626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames    DCHECK(CanMergeIntoShifterOperand(use, bitfield_op));
518626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames    return TryMergeIntoShifterOperand(use, bitfield_op, true);
528626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  }
53e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames
54968056faf5c2cf118321871ebf234fe70db1c3c8Aart Bik  /**
55968056faf5c2cf118321871ebf234fe70db1c3c8Aart Bik   * This simplifier uses a special-purpose BB visitor.
56968056faf5c2cf118321871ebf234fe70db1c3c8Aart Bik   * (1) No need to visit Phi nodes.
57968056faf5c2cf118321871ebf234fe70db1c3c8Aart Bik   * (2) Since statements can be removed in a "forward" fashion,
58968056faf5c2cf118321871ebf234fe70db1c3c8Aart Bik   *     the visitor should test if each statement is still there.
59968056faf5c2cf118321871ebf234fe70db1c3c8Aart Bik   */
60968056faf5c2cf118321871ebf234fe70db1c3c8Aart Bik  void VisitBasicBlock(HBasicBlock* block) OVERRIDE {
61968056faf5c2cf118321871ebf234fe70db1c3c8Aart Bik    // TODO: fragile iteration, provide more robust iterators?
62968056faf5c2cf118321871ebf234fe70db1c3c8Aart Bik    for (HInstructionIterator it(block->GetInstructions()); !it.Done(); it.Advance()) {
63968056faf5c2cf118321871ebf234fe70db1c3c8Aart Bik      HInstruction* instruction = it.Current();
64968056faf5c2cf118321871ebf234fe70db1c3c8Aart Bik      if (instruction->IsInBlock()) {
65968056faf5c2cf118321871ebf234fe70db1c3c8Aart Bik        instruction->Accept(this);
66968056faf5c2cf118321871ebf234fe70db1c3c8Aart Bik      }
67968056faf5c2cf118321871ebf234fe70db1c3c8Aart Bik    }
68968056faf5c2cf118321871ebf234fe70db1c3c8Aart Bik  }
69968056faf5c2cf118321871ebf234fe70db1c3c8Aart Bik
70418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  // HInstruction visitors, sorted alphabetically.
719ff0d205fd60cba6753a91f613b198ca2d67f04dKevin Brodsky  void VisitAnd(HAnd* instruction) OVERRIDE;
72e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames  void VisitArrayGet(HArrayGet* instruction) OVERRIDE;
73e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames  void VisitArraySet(HArraySet* instruction) OVERRIDE;
74418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  void VisitMul(HMul* instruction) OVERRIDE;
759ff0d205fd60cba6753a91f613b198ca2d67f04dKevin Brodsky  void VisitOr(HOr* instruction) OVERRIDE;
768626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  void VisitShl(HShl* instruction) OVERRIDE;
778626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  void VisitShr(HShr* instruction) OVERRIDE;
788626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  void VisitTypeConversion(HTypeConversion* instruction) OVERRIDE;
798626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  void VisitUShr(HUShr* instruction) OVERRIDE;
809ff0d205fd60cba6753a91f613b198ca2d67f04dKevin Brodsky  void VisitXor(HXor* instruction) OVERRIDE;
81e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames
8244b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames  OptimizingCompilerStats* stats_;
8344b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames};
8444b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames
8544b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames
8644b9cf937836bb33139123e15ca8b586b5853268Alexandre Ramesclass InstructionSimplifierArm64 : public HOptimization {
8744b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames public:
8844b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames  InstructionSimplifierArm64(HGraph* graph, OptimizingCompilerStats* stats)
8944b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames    : HOptimization(graph, "instruction_simplifier_arm64", stats) {}
9044b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames
9144b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames  void Run() OVERRIDE {
9244b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames    InstructionSimplifierArm64Visitor visitor(graph_, stats_);
9344b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames    visitor.VisitReversePostOrder();
9444b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames  }
9544b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames};
9644b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames
9744b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames}  // namespace arm64
9844b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames}  // namespace art
9944b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames
10044b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames#endif  // ART_COMPILER_OPTIMIZING_INSTRUCTION_SIMPLIFIER_ARM64_H_
101