/*
 * Copyright (C) 2014 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 "base/arena_allocator.h"
#include "builder.h"
#include "gvn.h"
#include "nodes.h"
#include "optimizing_unit_test.h"
#include "side_effects_analysis.h"

#include "gtest/gtest.h"

namespace art {

TEST(GVNTest, LocalFieldElimination) {
  ArenaPool pool;
  ArenaAllocator allocator(&pool);

  HGraph* graph = new (&allocator) HGraph(&allocator);
  HBasicBlock* entry = new (&allocator) HBasicBlock(graph);
  graph->AddBlock(entry);
  graph->SetEntryBlock(entry);
  HInstruction* parameter = new (&allocator) HParameterValue(0, Primitive::kPrimNot);
  entry->AddInstruction(parameter);

  HBasicBlock* block = new (&allocator) HBasicBlock(graph);
  graph->AddBlock(block);
  entry->AddSuccessor(block);

  block->AddInstruction(
      new (&allocator) HInstanceFieldGet(parameter, Primitive::kPrimNot,
          MemberOffset(42), false));
  block->AddInstruction(
      new (&allocator) HInstanceFieldGet(parameter, Primitive::kPrimNot,
          MemberOffset(42), false));
  HInstruction* to_remove = block->GetLastInstruction();
  block->AddInstruction(
      new (&allocator) HInstanceFieldGet(parameter, Primitive::kPrimNot,
          MemberOffset(43), false));
  HInstruction* different_offset = block->GetLastInstruction();
  // Kill the value.
  block->AddInstruction(new (&allocator) HInstanceFieldSet(
      parameter, parameter, Primitive::kPrimNot, MemberOffset(42), false));
  block->AddInstruction(
      new (&allocator) HInstanceFieldGet(parameter, Primitive::kPrimNot,
          MemberOffset(42), false));
  HInstruction* use_after_kill = block->GetLastInstruction();
  block->AddInstruction(new (&allocator) HExit());

  ASSERT_EQ(to_remove->GetBlock(), block);
  ASSERT_EQ(different_offset->GetBlock(), block);
  ASSERT_EQ(use_after_kill->GetBlock(), block);

  graph->TryBuildingSsa();
  SideEffectsAnalysis side_effects(graph);
  side_effects.Run();
  GVNOptimization(graph, side_effects).Run();

  ASSERT_TRUE(to_remove->GetBlock() == nullptr);
  ASSERT_EQ(different_offset->GetBlock(), block);
  ASSERT_EQ(use_after_kill->GetBlock(), block);
}

TEST(GVNTest, GlobalFieldElimination) {
  ArenaPool pool;
  ArenaAllocator allocator(&pool);

  HGraph* graph = new (&allocator) HGraph(&allocator);
  HBasicBlock* entry = new (&allocator) HBasicBlock(graph);
  graph->AddBlock(entry);
  graph->SetEntryBlock(entry);
  HInstruction* parameter = new (&allocator) HParameterValue(0, Primitive::kPrimNot);
  entry->AddInstruction(parameter);

  HBasicBlock* block = new (&allocator) HBasicBlock(graph);
  graph->AddBlock(block);
  entry->AddSuccessor(block);
  block->AddInstruction(
      new (&allocator) HInstanceFieldGet(parameter, Primitive::kPrimBoolean,
          MemberOffset(42), false));

  block->AddInstruction(new (&allocator) HIf(block->GetLastInstruction()));
  HBasicBlock* then = new (&allocator) HBasicBlock(graph);
  HBasicBlock* else_ = new (&allocator) HBasicBlock(graph);
  HBasicBlock* join = new (&allocator) HBasicBlock(graph);
  graph->AddBlock(then);
  graph->AddBlock(else_);
  graph->AddBlock(join);

  block->AddSuccessor(then);
  block->AddSuccessor(else_);
  then->AddSuccessor(join);
  else_->AddSuccessor(join);

  then->AddInstruction(
      new (&allocator) HInstanceFieldGet(parameter, Primitive::kPrimBoolean,
          MemberOffset(42), false));
  then->AddInstruction(new (&allocator) HGoto());
  else_->AddInstruction(
      new (&allocator) HInstanceFieldGet(parameter, Primitive::kPrimBoolean,
          MemberOffset(42), false));
  else_->AddInstruction(new (&allocator) HGoto());
  join->AddInstruction(
      new (&allocator) HInstanceFieldGet(parameter, Primitive::kPrimBoolean,
          MemberOffset(42), false));
  join->AddInstruction(new (&allocator) HExit());

  graph->TryBuildingSsa();
  SideEffectsAnalysis side_effects(graph);
  side_effects.Run();
  GVNOptimization(graph, side_effects).Run();

  // Check that all field get instructions have been GVN'ed.
  ASSERT_TRUE(then->GetFirstInstruction()->IsGoto());
  ASSERT_TRUE(else_->GetFirstInstruction()->IsGoto());
  ASSERT_TRUE(join->GetFirstInstruction()->IsExit());
}

TEST(GVNTest, LoopFieldElimination) {
  ArenaPool pool;
  ArenaAllocator allocator(&pool);

  HGraph* graph = new (&allocator) HGraph(&allocator);
  HBasicBlock* entry = new (&allocator) HBasicBlock(graph);
  graph->AddBlock(entry);
  graph->SetEntryBlock(entry);

  HInstruction* parameter = new (&allocator) HParameterValue(0, Primitive::kPrimNot);
  entry->AddInstruction(parameter);

  HBasicBlock* block = new (&allocator) HBasicBlock(graph);
  graph->AddBlock(block);
  entry->AddSuccessor(block);
  block->AddInstruction(
      new (&allocator) HInstanceFieldGet(parameter, Primitive::kPrimBoolean,
          MemberOffset(42), false));
  block->AddInstruction(new (&allocator) HGoto());

  HBasicBlock* loop_header = new (&allocator) HBasicBlock(graph);
  HBasicBlock* loop_body = new (&allocator) HBasicBlock(graph);
  HBasicBlock* exit = new (&allocator) HBasicBlock(graph);

  graph->AddBlock(loop_header);
  graph->AddBlock(loop_body);
  graph->AddBlock(exit);
  block->AddSuccessor(loop_header);
  loop_header->AddSuccessor(loop_body);
  loop_header->AddSuccessor(exit);
  loop_body->AddSuccessor(loop_header);

  loop_header->AddInstruction(
      new (&allocator) HInstanceFieldGet(parameter, Primitive::kPrimBoolean,
          MemberOffset(42), false));
  HInstruction* field_get_in_loop_header = loop_header->GetLastInstruction();
  loop_header->AddInstruction(new (&allocator) HIf(block->GetLastInstruction()));

  // Kill inside the loop body to prevent field gets inside the loop header
  // and the body to be GVN'ed.
  loop_body->AddInstruction(new (&allocator) HInstanceFieldSet(
      parameter, parameter, Primitive::kPrimNot, MemberOffset(42), false));
  HInstruction* field_set = loop_body->GetLastInstruction();
  loop_body->AddInstruction(
      new (&allocator) HInstanceFieldGet(parameter, Primitive::kPrimBoolean,
          MemberOffset(42), false));
  HInstruction* field_get_in_loop_body = loop_body->GetLastInstruction();
  loop_body->AddInstruction(new (&allocator) HGoto());

  exit->AddInstruction(
      new (&allocator) HInstanceFieldGet(parameter, Primitive::kPrimBoolean,
          MemberOffset(42), false));
  HInstruction* field_get_in_exit = exit->GetLastInstruction();
  exit->AddInstruction(new (&allocator) HExit());

  ASSERT_EQ(field_get_in_loop_header->GetBlock(), loop_header);
  ASSERT_EQ(field_get_in_loop_body->GetBlock(), loop_body);
  ASSERT_EQ(field_get_in_exit->GetBlock(), exit);

  graph->TryBuildingSsa();
  {
    SideEffectsAnalysis side_effects(graph);
    side_effects.Run();
    GVNOptimization(graph, side_effects).Run();
  }

  // Check that all field get instructions are still there.
  ASSERT_EQ(field_get_in_loop_header->GetBlock(), loop_header);
  ASSERT_EQ(field_get_in_loop_body->GetBlock(), loop_body);
  // The exit block is dominated by the loop header, whose field get
  // does not get killed by the loop flags.
  ASSERT_TRUE(field_get_in_exit->GetBlock() == nullptr);

  // Now remove the field set, and check that all field get instructions have been GVN'ed.
  loop_body->RemoveInstruction(field_set);
  {
    SideEffectsAnalysis side_effects(graph);
    side_effects.Run();
    GVNOptimization(graph, side_effects).Run();
  }

  ASSERT_TRUE(field_get_in_loop_header->GetBlock() == nullptr);
  ASSERT_TRUE(field_get_in_loop_body->GetBlock() == nullptr);
  ASSERT_TRUE(field_get_in_exit->GetBlock() == nullptr);
}

// Test that inner loops affect the side effects of the outer loop.
TEST(GVNTest, LoopSideEffects) {
  ArenaPool pool;
  ArenaAllocator allocator(&pool);

  HGraph* graph = new (&allocator) HGraph(&allocator);
  HBasicBlock* entry = new (&allocator) HBasicBlock(graph);
  graph->AddBlock(entry);
  graph->SetEntryBlock(entry);

  HBasicBlock* outer_loop_header = new (&allocator) HBasicBlock(graph);
  HBasicBlock* outer_loop_body = new (&allocator) HBasicBlock(graph);
  HBasicBlock* outer_loop_exit = new (&allocator) HBasicBlock(graph);
  HBasicBlock* inner_loop_header = new (&allocator) HBasicBlock(graph);
  HBasicBlock* inner_loop_body = new (&allocator) HBasicBlock(graph);
  HBasicBlock* inner_loop_exit = new (&allocator) HBasicBlock(graph);

  graph->AddBlock(outer_loop_header);
  graph->AddBlock(outer_loop_body);
  graph->AddBlock(outer_loop_exit);
  graph->AddBlock(inner_loop_header);
  graph->AddBlock(inner_loop_body);
  graph->AddBlock(inner_loop_exit);

  entry->AddSuccessor(outer_loop_header);
  outer_loop_header->AddSuccessor(outer_loop_body);
  outer_loop_header->AddSuccessor(outer_loop_exit);
  outer_loop_body->AddSuccessor(inner_loop_header);
  inner_loop_header->AddSuccessor(inner_loop_body);
  inner_loop_header->AddSuccessor(inner_loop_exit);
  inner_loop_body->AddSuccessor(inner_loop_header);
  inner_loop_exit->AddSuccessor(outer_loop_header);

  HInstruction* parameter = new (&allocator) HParameterValue(0, Primitive::kPrimBoolean);
  entry->AddInstruction(parameter);
  entry->AddInstruction(new (&allocator) HGoto());
  outer_loop_header->AddInstruction(new (&allocator) HIf(parameter));
  outer_loop_body->AddInstruction(new (&allocator) HGoto());
  inner_loop_header->AddInstruction(new (&allocator) HIf(parameter));
  inner_loop_body->AddInstruction(new (&allocator) HGoto());
  inner_loop_exit->AddInstruction(new (&allocator) HGoto());
  outer_loop_exit->AddInstruction(new (&allocator) HExit());

  graph->TryBuildingSsa();

  ASSERT_TRUE(inner_loop_header->GetLoopInformation()->IsIn(
      *outer_loop_header->GetLoopInformation()));

  // Check that the loops don't have side effects.
  {
    // Make one block with a side effect.
    entry->AddInstruction(new (&allocator) HInstanceFieldSet(
        parameter, parameter, Primitive::kPrimNot, MemberOffset(42), false));

    SideEffectsAnalysis side_effects(graph);
    side_effects.Run();

    ASSERT_TRUE(side_effects.GetBlockEffects(entry).HasSideEffects());
    ASSERT_FALSE(side_effects.GetLoopEffects(outer_loop_header).HasSideEffects());
    ASSERT_FALSE(side_effects.GetLoopEffects(inner_loop_header).HasSideEffects());
  }

  // Check that the side effects of the outer loop does not affect the inner loop.
  {
    outer_loop_body->InsertInstructionBefore(
        new (&allocator) HInstanceFieldSet(
            parameter, parameter, Primitive::kPrimNot, MemberOffset(42), false),
        outer_loop_body->GetLastInstruction());

    SideEffectsAnalysis side_effects(graph);
    side_effects.Run();

    ASSERT_TRUE(side_effects.GetBlockEffects(entry).HasSideEffects());
    ASSERT_TRUE(side_effects.GetBlockEffects(outer_loop_body).HasSideEffects());
    ASSERT_TRUE(side_effects.GetLoopEffects(outer_loop_header).HasSideEffects());
    ASSERT_FALSE(side_effects.GetLoopEffects(inner_loop_header).HasSideEffects());
  }

  // Check that the side effects of the inner loop affects the outer loop.
  {
    outer_loop_body->RemoveInstruction(outer_loop_body->GetFirstInstruction());
    inner_loop_body->InsertInstructionBefore(
        new (&allocator) HInstanceFieldSet(
            parameter, parameter, Primitive::kPrimNot, MemberOffset(42), false),
        inner_loop_body->GetLastInstruction());

    SideEffectsAnalysis side_effects(graph);
    side_effects.Run();

    ASSERT_TRUE(side_effects.GetBlockEffects(entry).HasSideEffects());
    ASSERT_FALSE(side_effects.GetBlockEffects(outer_loop_body).HasSideEffects());
    ASSERT_TRUE(side_effects.GetLoopEffects(outer_loop_header).HasSideEffects());
    ASSERT_TRUE(side_effects.GetLoopEffects(inner_loop_header).HasSideEffects());
  }
}
}  // namespace art
