/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "instruction_simplifier.h"

#include <initializer_list>
#include <tuple>

#include "gtest/gtest.h"

#include "class_root-inl.h"
#include "nodes.h"
#include "optimizing/data_type.h"
#include "optimizing_unit_test.h"

namespace art HIDDEN {

namespace mirror {
class ClassExt;
class Throwable;
}  // namespace mirror

static constexpr bool kDebugSimplifierTests = false;

template<typename SuperClass>
class InstructionSimplifierTestBase : public SuperClass, public OptimizingUnitTestHelper {
 public:
  InstructionSimplifierTestBase() {
    this->use_boot_image_ = true;  // Make the Runtime creation cheaper.
  }

  void SetUp() override {
    SuperClass::SetUp();
    gLogVerbosity.compiler = true;
  }

  void TearDown() override {
    SuperClass::TearDown();
    gLogVerbosity.compiler = false;
  }

  void PerformSimplification(const AdjacencyListGraph& blks) {
    if (kDebugSimplifierTests) {
      LOG(INFO) << "Pre simplification " << blks;
    }
    graph_->ClearDominanceInformation();
    graph_->BuildDominatorTree();
    InstructionSimplifier simp(graph_, /*codegen=*/nullptr);
    simp.Run();
    if (kDebugSimplifierTests) {
      LOG(INFO) << "Post simplify " << blks;
    }
  }
};

class InstructionSimplifierTest : public InstructionSimplifierTestBase<CommonCompilerTest> {};

// Various configs we can use for testing. Currently used in PartialComparison tests.
enum class InstanceOfKind {
  kSelf,
  kUnrelatedLoaded,
  kUnrelatedUnloaded,
  kSupertype,
};

std::ostream& operator<<(std::ostream& os, const InstanceOfKind& comp) {
  switch (comp) {
    case InstanceOfKind::kSupertype:
      return os << "kSupertype";
    case InstanceOfKind::kSelf:
      return os << "kSelf";
    case InstanceOfKind::kUnrelatedLoaded:
      return os << "kUnrelatedLoaded";
    case InstanceOfKind::kUnrelatedUnloaded:
      return os << "kUnrelatedUnloaded";
  }
}

class InstanceOfInstructionSimplifierTestGroup
    : public InstructionSimplifierTestBase<CommonCompilerTestWithParam<InstanceOfKind>> {
 public:
  bool GetConstantResult() const {
    switch (GetParam()) {
      case InstanceOfKind::kSupertype:
      case InstanceOfKind::kSelf:
        return true;
      case InstanceOfKind::kUnrelatedLoaded:
      case InstanceOfKind::kUnrelatedUnloaded:
        return false;
    }
  }

  std::pair<HLoadClass*, HLoadClass*> GetLoadClasses(VariableSizedHandleScope* vshs) {
    InstanceOfKind kind = GetParam();
    ScopedObjectAccess soa(Thread::Current());
    // New inst always needs to have a valid rti since we dcheck that.
    HLoadClass* new_inst = MakeClassLoad(
        /* ti= */ std::nullopt, vshs->NewHandle<mirror::Class>(GetClassRoot<mirror::ClassExt>()));
    new_inst->SetValidLoadedClassRTI();
    if (kind == InstanceOfKind::kSelf) {
      return {new_inst, new_inst};
    }
    if (kind == InstanceOfKind::kUnrelatedUnloaded) {
      HLoadClass* target_class = MakeClassLoad();
      EXPECT_FALSE(target_class->GetLoadedClassRTI().IsValid());
      return {new_inst, target_class};
    }
    // Force both classes to be a real classes.
    // For simplicity we use class-roots as the types. The new-inst will always
    // be a ClassExt, unrelated-loaded will always be Throwable and super will
    // always be Object
    HLoadClass* target_class = MakeClassLoad(
        /* ti= */ std::nullopt,
        vshs->NewHandle<mirror::Class>(kind == InstanceOfKind::kSupertype ?
                                           GetClassRoot<mirror::Object>() :
                                           GetClassRoot<mirror::Throwable>()));
    target_class->SetValidLoadedClassRTI();
    EXPECT_TRUE(target_class->GetLoadedClassRTI().IsValid());
    return {new_inst, target_class};
  }
};

// // ENTRY
// switch (param) {
// case 1:
//   obj1 = param2; break;
// case 2:
//   obj1 = param3; break;
// default:
//   obj2 = new Obj();
// }
// val_phi = PHI[3,4,10]
// target_phi = PHI[param2, param3, obj2]
// return PredFieldGet[val_phi, target_phi] => PredFieldGet[val_phi, target_phi]
TEST_F(InstructionSimplifierTest, SimplifyPredicatedFieldGetNoMerge) {
  ScopedObjectAccess soa(Thread::Current());
  VariableSizedHandleScope vshs(soa.Self());
  CreateGraph(&vshs);
  AdjacencyListGraph blks(SetupFromAdjacencyList("entry",
                                                 "exit",
                                                 {{"entry", "case1"},
                                                  {"entry", "case2"},
                                                  {"entry", "case3"},
                                                  {"case1", "breturn"},
                                                  {"case2", "breturn"},
                                                  {"case3", "breturn"},
                                                  {"breturn", "exit"}}));
#define GET_BLOCK(name) HBasicBlock* name = blks.Get(#name)
  GET_BLOCK(entry);
  GET_BLOCK(exit);
  GET_BLOCK(case1);
  GET_BLOCK(case2);
  GET_BLOCK(case3);
  GET_BLOCK(breturn);
#undef GET_BLOCK

  HInstruction* bool_value = MakeParam(DataType::Type::kInt32);
  HInstruction* obj1_param = MakeParam(DataType::Type::kReference);
  HInstruction* obj2_param = MakeParam(DataType::Type::kReference);
  HInstruction* c3 = graph_->GetIntConstant(3);
  HInstruction* c4 = graph_->GetIntConstant(4);
  HInstruction* c10 = graph_->GetIntConstant(10);

  HInstruction* cls = MakeClassLoad();
  HInstruction* switch_inst = new (GetAllocator()) HPackedSwitch(0, 2, bool_value);
  entry->AddInstruction(cls);
  entry->AddInstruction(switch_inst);
  ManuallyBuildEnvFor(cls, {});

  HInstruction* goto_c1 = new (GetAllocator()) HGoto();
  case1->AddInstruction(goto_c1);

  HInstruction* goto_c2 = new (GetAllocator()) HGoto();
  case2->AddInstruction(goto_c2);

  HInstruction* obj3 = MakeNewInstance(cls);
  HInstruction* goto_c3 = new (GetAllocator()) HGoto();
  case3->AddInstruction(obj3);
  case3->AddInstruction(goto_c3);

  HPhi* val_phi = MakePhi({c3, c4, c10});
  HPhi* obj_phi = MakePhi({obj1_param, obj2_param, obj3});
  HPredicatedInstanceFieldGet* read_end =
      new (GetAllocator()) HPredicatedInstanceFieldGet(obj_phi,
                                                       nullptr,
                                                       val_phi,
                                                       val_phi->GetType(),
                                                       MemberOffset(10),
                                                       false,
                                                       42,
                                                       0,
                                                       graph_->GetDexFile(),
                                                       0);
  HInstruction* return_exit = new (GetAllocator()) HReturn(read_end);
  breturn->AddPhi(val_phi);
  breturn->AddPhi(obj_phi);
  breturn->AddInstruction(read_end);
  breturn->AddInstruction(return_exit);

  SetupExit(exit);

  PerformSimplification(blks);

  EXPECT_INS_RETAINED(read_end);

  EXPECT_INS_EQ(read_end->GetTarget(), obj_phi);
  EXPECT_INS_EQ(read_end->GetDefaultValue(), val_phi);
}

// // ENTRY
// switch (param) {
// case 1:
//   obj1 = param2; break;
// case 2:
//   obj1 = param3; break;
// default:
//   obj2 = new Obj();
// }
// val_phi = PHI[3,3,10]
// target_phi = PHI[param2, param3, obj2]
// return PredFieldGet[val_phi, target_phi] => PredFieldGet[3, target_phi]
TEST_F(InstructionSimplifierTest, SimplifyPredicatedFieldGetMerge) {
  ScopedObjectAccess soa(Thread::Current());
  VariableSizedHandleScope vshs(soa.Self());
  CreateGraph(&vshs);
  AdjacencyListGraph blks(SetupFromAdjacencyList("entry",
                                                 "exit",
                                                 {{"entry", "case1"},
                                                  {"entry", "case2"},
                                                  {"entry", "case3"},
                                                  {"case1", "breturn"},
                                                  {"case2", "breturn"},
                                                  {"case3", "breturn"},
                                                  {"breturn", "exit"}}));
#define GET_BLOCK(name) HBasicBlock* name = blks.Get(#name)
  GET_BLOCK(entry);
  GET_BLOCK(exit);
  GET_BLOCK(case1);
  GET_BLOCK(case2);
  GET_BLOCK(case3);
  GET_BLOCK(breturn);
#undef GET_BLOCK

  HInstruction* bool_value = MakeParam(DataType::Type::kInt32);
  HInstruction* obj1_param = MakeParam(DataType::Type::kReference);
  HInstruction* obj2_param = MakeParam(DataType::Type::kReference);
  HInstruction* c3 = graph_->GetIntConstant(3);
  HInstruction* c10 = graph_->GetIntConstant(10);

  HInstruction* cls = MakeClassLoad();
  HInstruction* switch_inst = new (GetAllocator()) HPackedSwitch(0, 2, bool_value);
  entry->AddInstruction(cls);
  entry->AddInstruction(switch_inst);
  ManuallyBuildEnvFor(cls, {});

  HInstruction* goto_c1 = new (GetAllocator()) HGoto();
  case1->AddInstruction(goto_c1);

  HInstruction* goto_c2 = new (GetAllocator()) HGoto();
  case2->AddInstruction(goto_c2);

  HInstruction* obj3 = MakeNewInstance(cls);
  HInstruction* goto_c3 = new (GetAllocator()) HGoto();
  case3->AddInstruction(obj3);
  case3->AddInstruction(goto_c3);

  HPhi* val_phi = MakePhi({c3, c3, c10});
  HPhi* obj_phi = MakePhi({obj1_param, obj2_param, obj3});
  HPredicatedInstanceFieldGet* read_end =
      new (GetAllocator()) HPredicatedInstanceFieldGet(obj_phi,
                                                       nullptr,
                                                       val_phi,
                                                       val_phi->GetType(),
                                                       MemberOffset(10),
                                                       false,
                                                       42,
                                                       0,
                                                       graph_->GetDexFile(),
                                                       0);
  HInstruction* return_exit = new (GetAllocator()) HReturn(read_end);
  breturn->AddPhi(val_phi);
  breturn->AddPhi(obj_phi);
  breturn->AddInstruction(read_end);
  breturn->AddInstruction(return_exit);

  SetupExit(exit);

  PerformSimplification(blks);

  EXPECT_FALSE(obj3->CanBeNull());
  EXPECT_INS_RETAINED(read_end);

  EXPECT_INS_EQ(read_end->GetTarget(), obj_phi);
  EXPECT_INS_EQ(read_end->GetDefaultValue(), c3);
}

// // ENTRY
// if (param) {
//   obj1 = new Obj();
// } else {
//   obj2 = new Obj();
// }
// val_phi = PHI[3,10]
// target_phi = PHI[obj1, obj2]
// return PredFieldGet[val_phi, target_phi] => FieldGet[target_phi]
TEST_F(InstructionSimplifierTest, SimplifyPredicatedFieldGetNoNull) {
  ScopedObjectAccess soa(Thread::Current());
  VariableSizedHandleScope vshs(soa.Self());
  CreateGraph(&vshs);
  AdjacencyListGraph blks(SetupFromAdjacencyList("entry",
                                                 "exit",
                                                 {{"entry", "left"},
                                                  {"entry", "right"},
                                                  {"left", "breturn"},
                                                  {"right", "breturn"},
                                                  {"breturn", "exit"}}));
#define GET_BLOCK(name) HBasicBlock* name = blks.Get(#name)
  GET_BLOCK(entry);
  GET_BLOCK(exit);
  GET_BLOCK(left);
  GET_BLOCK(right);
  GET_BLOCK(breturn);
#undef GET_BLOCK

  HInstruction* bool_value = MakeParam(DataType::Type::kBool);
  HInstruction* c3 = graph_->GetIntConstant(3);
  HInstruction* c10 = graph_->GetIntConstant(10);

  HInstruction* cls = MakeClassLoad();
  HInstruction* if_inst = new (GetAllocator()) HIf(bool_value);
  entry->AddInstruction(cls);
  entry->AddInstruction(if_inst);
  ManuallyBuildEnvFor(cls, {});

  HInstruction* obj1 = MakeNewInstance(cls);
  HInstruction* goto_left = new (GetAllocator()) HGoto();
  left->AddInstruction(obj1);
  left->AddInstruction(goto_left);

  HInstruction* obj2 = MakeNewInstance(cls);
  HInstruction* goto_right = new (GetAllocator()) HGoto();
  right->AddInstruction(obj2);
  right->AddInstruction(goto_right);

  HPhi* val_phi = MakePhi({c3, c10});
  HPhi* obj_phi = MakePhi({obj1, obj2});
  obj_phi->SetCanBeNull(false);
  HInstruction* read_end = new (GetAllocator()) HPredicatedInstanceFieldGet(obj_phi,
                                                                            nullptr,
                                                                            val_phi,
                                                                            val_phi->GetType(),
                                                                            MemberOffset(10),
                                                                            false,
                                                                            42,
                                                                            0,
                                                                            graph_->GetDexFile(),
                                                                            0);
  HInstruction* return_exit = new (GetAllocator()) HReturn(read_end);
  breturn->AddPhi(val_phi);
  breturn->AddPhi(obj_phi);
  breturn->AddInstruction(read_end);
  breturn->AddInstruction(return_exit);

  SetupExit(exit);

  PerformSimplification(blks);

  EXPECT_FALSE(obj1->CanBeNull());
  EXPECT_FALSE(obj2->CanBeNull());
  EXPECT_INS_REMOVED(read_end);

  HInstanceFieldGet* ifget = FindSingleInstruction<HInstanceFieldGet>(graph_, breturn);
  ASSERT_NE(ifget, nullptr);
  EXPECT_INS_EQ(ifget->InputAt(0), obj_phi);
}

// // ENTRY
// obj = new Obj();
// // Make sure this graph isn't broken
// if (obj instanceof <other>) {
//   // LEFT
// } else {
//   // RIGHT
// }
// EXIT
// return obj.field
TEST_P(InstanceOfInstructionSimplifierTestGroup, ExactClassInstanceOfOther) {
  ScopedObjectAccess soa(Thread::Current());
  VariableSizedHandleScope vshs(soa.Self());
  InitGraph(/*handles=*/&vshs);

  AdjacencyListGraph blks(SetupFromAdjacencyList("entry",
                                                 "exit",
                                                 {{"entry", "left"},
                                                  {"entry", "right"},
                                                  {"left", "breturn"},
                                                  {"right", "breturn"},
                                                  {"breturn", "exit"}}));
#define GET_BLOCK(name) HBasicBlock* name = blks.Get(#name)
  GET_BLOCK(entry);
  GET_BLOCK(exit);
  GET_BLOCK(breturn);
  GET_BLOCK(left);
  GET_BLOCK(right);
#undef GET_BLOCK
  EnsurePredecessorOrder(breturn, {left, right});
  HInstruction* test_res = graph_->GetIntConstant(GetConstantResult() ? 1 : 0);

  auto [new_inst_klass, target_klass] = GetLoadClasses(&vshs);
  HInstruction* new_inst = MakeNewInstance(new_inst_klass);
  new_inst->SetReferenceTypeInfo(
      ReferenceTypeInfo::Create(new_inst_klass->GetClass(), /*is_exact=*/true));
  HInstanceOf* instance_of = new (GetAllocator()) HInstanceOf(new_inst,
                                                              target_klass,
                                                              TypeCheckKind::kClassHierarchyCheck,
                                                              target_klass->GetClass(),
                                                              0u,
                                                              GetAllocator(),
                                                              nullptr,
                                                              nullptr);
  if (target_klass->GetLoadedClassRTI().IsValid()) {
    instance_of->SetValidTargetClassRTI();
  }
  HInstruction* if_inst = new (GetAllocator()) HIf(instance_of);
  entry->AddInstruction(new_inst_klass);
  if (new_inst_klass != target_klass) {
    entry->AddInstruction(target_klass);
  }
  entry->AddInstruction(new_inst);
  entry->AddInstruction(instance_of);
  entry->AddInstruction(if_inst);
  ManuallyBuildEnvFor(new_inst_klass, {});
  if (new_inst_klass != target_klass) {
    target_klass->CopyEnvironmentFrom(new_inst_klass->GetEnvironment());
  }
  new_inst->CopyEnvironmentFrom(new_inst_klass->GetEnvironment());

  HInstruction* goto_left = new (GetAllocator()) HGoto();
  left->AddInstruction(goto_left);

  HInstruction* goto_right = new (GetAllocator()) HGoto();
  right->AddInstruction(goto_right);

  HInstruction* read_bottom = MakeIFieldGet(new_inst, DataType::Type::kInt32, MemberOffset(32));
  HInstruction* return_exit = new (GetAllocator()) HReturn(read_bottom);
  breturn->AddInstruction(read_bottom);
  breturn->AddInstruction(return_exit);

  SetupExit(exit);

  PerformSimplification(blks);

  if (!GetConstantResult() || GetParam() == InstanceOfKind::kSelf) {
    EXPECT_INS_RETAINED(target_klass);
  } else {
    EXPECT_INS_REMOVED(target_klass);
  }
  EXPECT_INS_REMOVED(instance_of);
  EXPECT_INS_EQ(if_inst->InputAt(0), test_res);
}

// // ENTRY
// obj = new Obj();
// (<other>)obj;
// // Make sure this graph isn't broken
// EXIT
// return obj
TEST_P(InstanceOfInstructionSimplifierTestGroup, ExactClassCheckCastOther) {
  ScopedObjectAccess soa(Thread::Current());
  VariableSizedHandleScope vshs(soa.Self());
  InitGraph(/*handles=*/&vshs);

  AdjacencyListGraph blks(SetupFromAdjacencyList("entry", "exit", {{"entry", "exit"}}));
#define GET_BLOCK(name) HBasicBlock* name = blks.Get(#name)
  GET_BLOCK(entry);
  GET_BLOCK(exit);
#undef GET_BLOCK

  auto [new_inst_klass, target_klass] = GetLoadClasses(&vshs);
  HInstruction* new_inst = MakeNewInstance(new_inst_klass);
  new_inst->SetReferenceTypeInfo(
      ReferenceTypeInfo::Create(new_inst_klass->GetClass(), /*is_exact=*/true));
  HCheckCast* check_cast = new (GetAllocator()) HCheckCast(new_inst,
                                                           target_klass,
                                                           TypeCheckKind::kClassHierarchyCheck,
                                                           target_klass->GetClass(),
                                                           0u,
                                                           GetAllocator(),
                                                           nullptr,
                                                           nullptr);
  if (target_klass->GetLoadedClassRTI().IsValid()) {
    check_cast->SetValidTargetClassRTI();
  }
  HInstruction* entry_return = new (GetAllocator()) HReturn(new_inst);
  entry->AddInstruction(new_inst_klass);
  if (new_inst_klass != target_klass) {
    entry->AddInstruction(target_klass);
  }
  entry->AddInstruction(new_inst);
  entry->AddInstruction(check_cast);
  entry->AddInstruction(entry_return);
  ManuallyBuildEnvFor(new_inst_klass, {});
  if (new_inst_klass != target_klass) {
    target_klass->CopyEnvironmentFrom(new_inst_klass->GetEnvironment());
  }
  new_inst->CopyEnvironmentFrom(new_inst_klass->GetEnvironment());

  SetupExit(exit);

  PerformSimplification(blks);

  if (!GetConstantResult() || GetParam() == InstanceOfKind::kSelf) {
    EXPECT_INS_RETAINED(target_klass);
  } else {
    EXPECT_INS_REMOVED(target_klass);
  }
  if (GetConstantResult()) {
    EXPECT_INS_REMOVED(check_cast);
  } else {
    EXPECT_INS_RETAINED(check_cast);
  }
}

INSTANTIATE_TEST_SUITE_P(InstructionSimplifierTest,
                         InstanceOfInstructionSimplifierTestGroup,
                         testing::Values(InstanceOfKind::kSelf,
                                         InstanceOfKind::kUnrelatedLoaded,
                                         InstanceOfKind::kUnrelatedUnloaded,
                                         InstanceOfKind::kSupertype));

}  // namespace art
