/*
 * 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 "mir_graph.h"
#include "gtest/gtest.h"

namespace art {

class TopologicalSortOrderTest : public testing::Test {
 protected:
  struct BBDef {
    static constexpr size_t kMaxSuccessors = 4;
    static constexpr size_t kMaxPredecessors = 4;

    BBType type;
    size_t num_successors;
    BasicBlockId successors[kMaxPredecessors];
    size_t num_predecessors;
    BasicBlockId predecessors[kMaxPredecessors];
  };

#define DEF_SUCC0() \
    0u, { }
#define DEF_SUCC1(s1) \
    1u, { s1 }
#define DEF_SUCC2(s1, s2) \
    2u, { s1, s2 }
#define DEF_SUCC3(s1, s2, s3) \
    3u, { s1, s2, s3 }
#define DEF_SUCC4(s1, s2, s3, s4) \
    4u, { s1, s2, s3, s4 }
#define DEF_PRED0() \
    0u, { }
#define DEF_PRED1(p1) \
    1u, { p1 }
#define DEF_PRED2(p1, p2) \
    2u, { p1, p2 }
#define DEF_PRED3(p1, p2, p3) \
    3u, { p1, p2, p3 }
#define DEF_PRED4(p1, p2, p3, p4) \
    4u, { p1, p2, p3, p4 }
#define DEF_BB(type, succ, pred) \
    { type, succ, pred }

  void DoPrepareBasicBlocks(const BBDef* defs, size_t count) {
    cu_.mir_graph->block_id_map_.clear();
    cu_.mir_graph->block_list_.clear();
    ASSERT_LT(3u, count);  // null, entry, exit and at least one bytecode block.
    ASSERT_EQ(kNullBlock, defs[0].type);
    ASSERT_EQ(kEntryBlock, defs[1].type);
    ASSERT_EQ(kExitBlock, defs[2].type);
    for (size_t i = 0u; i != count; ++i) {
      const BBDef* def = &defs[i];
      BasicBlock* bb = cu_.mir_graph->CreateNewBB(def->type);
      if (def->num_successors <= 2) {
        bb->successor_block_list_type = kNotUsed;
        bb->fall_through = (def->num_successors >= 1) ? def->successors[0] : 0u;
        bb->taken = (def->num_successors >= 2) ? def->successors[1] : 0u;
      } else {
        bb->successor_block_list_type = kPackedSwitch;
        bb->fall_through = 0u;
        bb->taken = 0u;
        bb->successor_blocks.reserve(def->num_successors);
        for (size_t j = 0u; j != def->num_successors; ++j) {
          SuccessorBlockInfo* successor_block_info =
              static_cast<SuccessorBlockInfo*>(cu_.arena.Alloc(sizeof(SuccessorBlockInfo),
                                                               kArenaAllocSuccessor));
          successor_block_info->block = j;
          successor_block_info->key = 0u;  // Not used by class init check elimination.
          bb->successor_blocks.push_back(successor_block_info);
        }
      }
      bb->predecessors.assign(def->predecessors, def->predecessors + def->num_predecessors);
      if (def->type == kDalvikByteCode || def->type == kEntryBlock || def->type == kExitBlock) {
        bb->data_flow_info = static_cast<BasicBlockDataFlow*>(
            cu_.arena.Alloc(sizeof(BasicBlockDataFlow), kArenaAllocDFInfo));
      }
    }
    ASSERT_EQ(count, cu_.mir_graph->block_list_.size());
    cu_.mir_graph->entry_block_ = cu_.mir_graph->block_list_[1];
    ASSERT_EQ(kEntryBlock, cu_.mir_graph->entry_block_->block_type);
    cu_.mir_graph->exit_block_ = cu_.mir_graph->block_list_[2];
    ASSERT_EQ(kExitBlock, cu_.mir_graph->exit_block_->block_type);

    DexFile::CodeItem* code_item = static_cast<DexFile::CodeItem*>(cu_.arena.Alloc(sizeof(DexFile::CodeItem),
                                                                                   kArenaAllocMisc));
    cu_.mir_graph->current_code_item_ = code_item;
  }

  template <size_t count>
  void PrepareBasicBlocks(const BBDef (&defs)[count]) {
    DoPrepareBasicBlocks(defs, count);
  }

  void ComputeTopologicalSortOrder() {
    cu_.mir_graph->SSATransformationStart();
    cu_.mir_graph->ComputeDFSOrders();
    cu_.mir_graph->ComputeDominators();
    cu_.mir_graph->ComputeTopologicalSortOrder();
    cu_.mir_graph->SSATransformationEnd();
    ASSERT_FALSE(cu_.mir_graph->topological_order_.empty());
    ASSERT_FALSE(cu_.mir_graph->topological_order_loop_ends_.empty());
    ASSERT_FALSE(cu_.mir_graph->topological_order_indexes_.empty());
    ASSERT_EQ(cu_.mir_graph->GetNumBlocks(), cu_.mir_graph->topological_order_indexes_.size());
    for (size_t i = 0, size = cu_.mir_graph->GetTopologicalSortOrder().size(); i != size; ++i) {
      ASSERT_LT(cu_.mir_graph->topological_order_[i], cu_.mir_graph->GetNumBlocks());
      BasicBlockId id = cu_.mir_graph->topological_order_[i];
      EXPECT_EQ(i, cu_.mir_graph->topological_order_indexes_[id]);
    }
  }

  void DoCheckOrder(const BasicBlockId* ids, size_t count) {
    ASSERT_EQ(count, cu_.mir_graph->GetTopologicalSortOrder().size());
    for (size_t i = 0; i != count; ++i) {
      EXPECT_EQ(ids[i], cu_.mir_graph->GetTopologicalSortOrder()[i]) << i;
    }
  }

  template <size_t count>
  void CheckOrder(const BasicBlockId (&ids)[count]) {
    DoCheckOrder(ids, count);
  }

  void DoCheckLoopEnds(const uint16_t* ends, size_t count) {
    for (size_t i = 0; i != count; ++i) {
      ASSERT_LT(i, cu_.mir_graph->GetTopologicalSortOrderLoopEnds().size());
      EXPECT_EQ(ends[i], cu_.mir_graph->GetTopologicalSortOrderLoopEnds()[i]) << i;
    }
  }

  template <size_t count>
  void CheckLoopEnds(const uint16_t (&ends)[count]) {
    DoCheckLoopEnds(ends, count);
  }

  TopologicalSortOrderTest()
      : pool_(),
        cu_(&pool_) {
    cu_.mir_graph.reset(new MIRGraph(&cu_, &cu_.arena));
  }

  ArenaPool pool_;
  CompilationUnit cu_;
};

TEST_F(TopologicalSortOrderTest, DoWhile) {
  const BBDef bbs[] = {
      DEF_BB(kNullBlock, DEF_SUCC0(), DEF_PRED0()),
      DEF_BB(kEntryBlock, DEF_SUCC1(3), DEF_PRED0()),
      DEF_BB(kExitBlock, DEF_SUCC0(), DEF_PRED1(5)),
      DEF_BB(kDalvikByteCode, DEF_SUCC1(4), DEF_PRED1(1)),
      DEF_BB(kDalvikByteCode, DEF_SUCC2(5, 4), DEF_PRED2(3, 4)),  // "taken" loops to self.
      DEF_BB(kDalvikByteCode, DEF_SUCC1(2), DEF_PRED1(4)),
  };
  const BasicBlockId expected_order[] = {
      1, 3, 4, 5, 2
  };
  const uint16_t loop_ends[] = {
      0, 0, 3, 0, 0
  };

  PrepareBasicBlocks(bbs);
  ComputeTopologicalSortOrder();
  CheckOrder(expected_order);
  CheckLoopEnds(loop_ends);
}

TEST_F(TopologicalSortOrderTest, While) {
  const BBDef bbs[] = {
      DEF_BB(kNullBlock, DEF_SUCC0(), DEF_PRED0()),
      DEF_BB(kEntryBlock, DEF_SUCC1(3), DEF_PRED0()),
      DEF_BB(kExitBlock, DEF_SUCC0(), DEF_PRED1(5)),
      DEF_BB(kDalvikByteCode, DEF_SUCC2(4, 5), DEF_PRED2(1, 4)),
      DEF_BB(kDalvikByteCode, DEF_SUCC1(3), DEF_PRED1(3)),     // Loops to 3.
      DEF_BB(kDalvikByteCode, DEF_SUCC1(2), DEF_PRED1(3)),
  };
  const BasicBlockId expected_order[] = {
      1, 3, 4, 5, 2
  };
  const uint16_t loop_ends[] = {
      0, 3, 0, 0, 0
  };

  PrepareBasicBlocks(bbs);
  ComputeTopologicalSortOrder();
  CheckOrder(expected_order);
  CheckLoopEnds(loop_ends);
}

TEST_F(TopologicalSortOrderTest, WhileWithTwoBackEdges) {
  const BBDef bbs[] = {
      DEF_BB(kNullBlock, DEF_SUCC0(), DEF_PRED0()),
      DEF_BB(kEntryBlock, DEF_SUCC1(3), DEF_PRED0()),
      DEF_BB(kExitBlock, DEF_SUCC0(), DEF_PRED1(6)),
      DEF_BB(kDalvikByteCode, DEF_SUCC2(4, 6), DEF_PRED3(1, 4, 5)),
      DEF_BB(kDalvikByteCode, DEF_SUCC2(5, 3), DEF_PRED1(3)),     // Loops to 3.
      DEF_BB(kDalvikByteCode, DEF_SUCC1(3), DEF_PRED1(4)),        // Loops to 3.
      DEF_BB(kDalvikByteCode, DEF_SUCC1(2), DEF_PRED1(3)),
  };
  const BasicBlockId expected_order[] = {
      1, 3, 4, 5, 6, 2
  };
  const uint16_t loop_ends[] = {
      0, 4, 0, 0, 0, 0
  };

  PrepareBasicBlocks(bbs);
  ComputeTopologicalSortOrder();
  CheckOrder(expected_order);
  CheckLoopEnds(loop_ends);
}

TEST_F(TopologicalSortOrderTest, NestedLoop) {
  const BBDef bbs[] = {
      DEF_BB(kNullBlock, DEF_SUCC0(), DEF_PRED0()),
      DEF_BB(kEntryBlock, DEF_SUCC1(3), DEF_PRED0()),
      DEF_BB(kExitBlock, DEF_SUCC0(), DEF_PRED1(7)),
      DEF_BB(kDalvikByteCode, DEF_SUCC2(4, 7), DEF_PRED2(1, 6)),
      DEF_BB(kDalvikByteCode, DEF_SUCC2(5, 6), DEF_PRED2(3, 5)),
      DEF_BB(kDalvikByteCode, DEF_SUCC1(4), DEF_PRED1(4)),            // Loops to 4.
      DEF_BB(kDalvikByteCode, DEF_SUCC1(3), DEF_PRED1(4)),            // Loops to 3.
      DEF_BB(kDalvikByteCode, DEF_SUCC1(2), DEF_PRED1(3)),
  };
  const BasicBlockId expected_order[] = {
      1, 3, 4, 5, 6, 7, 2
  };
  const uint16_t loop_ends[] = {
      0, 5, 4, 0, 0, 0, 0
  };

  PrepareBasicBlocks(bbs);
  ComputeTopologicalSortOrder();
  CheckOrder(expected_order);
  CheckLoopEnds(loop_ends);
}

TEST_F(TopologicalSortOrderTest, NestedLoopHeadLoops) {
  const BBDef bbs[] = {
      DEF_BB(kNullBlock, DEF_SUCC0(), DEF_PRED0()),
      DEF_BB(kEntryBlock, DEF_SUCC1(3), DEF_PRED0()),
      DEF_BB(kExitBlock, DEF_SUCC0(), DEF_PRED1(6)),
      DEF_BB(kDalvikByteCode, DEF_SUCC2(4, 6), DEF_PRED2(1, 4)),
      DEF_BB(kDalvikByteCode, DEF_SUCC2(5, 3), DEF_PRED2(3, 5)),      // Nested head, loops to 3.
      DEF_BB(kDalvikByteCode, DEF_SUCC1(4), DEF_PRED1(4)),            // Loops to 4.
      DEF_BB(kDalvikByteCode, DEF_SUCC1(2), DEF_PRED1(3)),
  };
  const BasicBlockId expected_order[] = {
      1, 3, 4, 5, 6, 2
  };
  const uint16_t loop_ends[] = {
      0, 4, 4, 0, 0, 0
  };

  PrepareBasicBlocks(bbs);
  ComputeTopologicalSortOrder();
  CheckOrder(expected_order);
  CheckLoopEnds(loop_ends);
}

TEST_F(TopologicalSortOrderTest, NestedLoopSameBackBranchBlock) {
  const BBDef bbs[] = {
      DEF_BB(kNullBlock, DEF_SUCC0(), DEF_PRED0()),
      DEF_BB(kEntryBlock, DEF_SUCC1(3), DEF_PRED0()),
      DEF_BB(kExitBlock, DEF_SUCC0(), DEF_PRED1(6)),
      DEF_BB(kDalvikByteCode, DEF_SUCC2(4, 6), DEF_PRED2(1, 5)),
      DEF_BB(kDalvikByteCode, DEF_SUCC1(5), DEF_PRED2(3, 5)),
      DEF_BB(kDalvikByteCode, DEF_SUCC2(4, 3), DEF_PRED1(4)),         // Loops to 4 and 3.
      DEF_BB(kDalvikByteCode, DEF_SUCC1(2), DEF_PRED1(3)),
  };
  const BasicBlockId expected_order[] = {
      1, 3, 4, 5, 6, 2
  };
  const uint16_t loop_ends[] = {
      0, 4, 4, 0, 0, 0
  };

  PrepareBasicBlocks(bbs);
  ComputeTopologicalSortOrder();
  CheckOrder(expected_order);
  CheckLoopEnds(loop_ends);
}

TEST_F(TopologicalSortOrderTest, TwoReorderedInnerLoops) {
  // This is a simplified version of real code graph where the branch from 8 to 5 must prevent
  // the block 5 from being considered a loop head before processing the loop 7-8.
  const BBDef bbs[] = {
      DEF_BB(kNullBlock, DEF_SUCC0(), DEF_PRED0()),
      DEF_BB(kEntryBlock, DEF_SUCC1(3), DEF_PRED0()),
      DEF_BB(kExitBlock, DEF_SUCC0(), DEF_PRED1(9)),
      DEF_BB(kDalvikByteCode, DEF_SUCC2(4, 9), DEF_PRED2(1, 5)),
      DEF_BB(kDalvikByteCode, DEF_SUCC2(5, 7), DEF_PRED1(3)),         // Branch over loop in 5.
      DEF_BB(kDalvikByteCode, DEF_SUCC2(6, 3), DEF_PRED3(4, 6, 8)),   // Loops to 4; inner loop.
      DEF_BB(kDalvikByteCode, DEF_SUCC1(5), DEF_PRED1(5)),            // Loops to 5.
      DEF_BB(kDalvikByteCode, DEF_SUCC1(8), DEF_PRED2(4, 8)),         // Loop head.
      DEF_BB(kDalvikByteCode, DEF_SUCC2(7, 5), DEF_PRED1(7)),         // Loops to 7; branches to 5.
      DEF_BB(kDalvikByteCode, DEF_SUCC1(2), DEF_PRED1(3)),
  };
  const BasicBlockId expected_order[] = {
      1, 3, 4, 7, 8, 5, 6, 9, 2
  };
  const uint16_t loop_ends[] = {
      0, 7, 0, 5, 0, 7, 0, 0, 0
  };

  PrepareBasicBlocks(bbs);
  ComputeTopologicalSortOrder();
  CheckOrder(expected_order);
  CheckLoopEnds(loop_ends);
}

TEST_F(TopologicalSortOrderTest, NestedLoopWithBackEdgeAfterOuterLoopBackEdge) {
  // This is a simplified version of real code graph. The back-edge from 7 to the inner
  // loop head 4 comes after the back-edge from 6 to the outer loop head 3. To make this
  // appear a bit more complex, there's also a back-edge from 5 to 4.
  const BBDef bbs[] = {
      DEF_BB(kNullBlock, DEF_SUCC0(), DEF_PRED0()),
      DEF_BB(kEntryBlock, DEF_SUCC1(3), DEF_PRED0()),
      DEF_BB(kExitBlock, DEF_SUCC0(), DEF_PRED1(7)),
      DEF_BB(kDalvikByteCode, DEF_SUCC1(4), DEF_PRED2(1, 6)),         // Outer loop head.
      DEF_BB(kDalvikByteCode, DEF_SUCC2(5, 6), DEF_PRED3(3, 5, 7)),   // Inner loop head.
      DEF_BB(kDalvikByteCode, DEF_SUCC1(4), DEF_PRED1(4)),            // Loops to inner loop head 4.
      DEF_BB(kDalvikByteCode, DEF_SUCC2(7, 3), DEF_PRED1(4)),         // Loops to outer loop head 3.
      DEF_BB(kDalvikByteCode, DEF_SUCC2(2, 4), DEF_PRED1(6)),         // Loops to inner loop head 4.
  };
  const BasicBlockId expected_order[] = {
      // NOTE: The 5 goes before 6 only because 5 is a "fall-through" from 4 while 6 is "taken".
      1, 3, 4, 5, 6, 7, 2
  };
  const uint16_t loop_ends[] = {
      0, 6, 6, 0, 0, 0, 0
  };

  PrepareBasicBlocks(bbs);
  ComputeTopologicalSortOrder();
  CheckOrder(expected_order);
  CheckLoopEnds(loop_ends);
}

TEST_F(TopologicalSortOrderTest, LoopWithTwoEntryPoints) {
  const BBDef bbs[] = {
      DEF_BB(kNullBlock, DEF_SUCC0(), DEF_PRED0()),
      DEF_BB(kEntryBlock, DEF_SUCC1(3), DEF_PRED0()),
      DEF_BB(kExitBlock, DEF_SUCC0(), DEF_PRED1(7)),
      DEF_BB(kDalvikByteCode, DEF_SUCC2(5, 4), DEF_PRED1(1)),
      DEF_BB(kDalvikByteCode, DEF_SUCC1(5), DEF_PRED2(3, 6)),  // Fall-back block is chosen as
      DEF_BB(kDalvikByteCode, DEF_SUCC1(6), DEF_PRED2(3, 4)),  // the earlier from these two.
      DEF_BB(kDalvikByteCode, DEF_SUCC2(4, 7), DEF_PRED1(5)),
      DEF_BB(kDalvikByteCode, DEF_SUCC1(2), DEF_PRED1(6)),
  };
  const BasicBlockId expected_order[] = {
      1, 3, 4, 5, 6, 7, 2
  };
  const uint16_t loop_ends[] = {
      0, 0, 5, 0, 0, 0, 0
  };

  PrepareBasicBlocks(bbs);
  ComputeTopologicalSortOrder();
  CheckOrder(expected_order);
  CheckLoopEnds(loop_ends);
}

}  // namespace art
