//===- DDGTest.cpp - DDGAnalysis unit tests -------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "llvm/Analysis/DDG.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/BasicAliasAnalysis.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/AsmParser/Parser.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/SourceMgr.h"
#include "gtest/gtest.h"

using namespace llvm;

/// Build the DDG analysis for a loop and run the given test \p Test.
static void runTest(Module &M, StringRef FuncName,
                    function_ref<void(Function &F, LoopInfo &LI,
                                      DependenceInfo &DI, ScalarEvolution &SE)>
                        Test) {
  auto *F = M.getFunction(FuncName);
  ASSERT_NE(F, nullptr) << "Could not find " << FuncName;

  TargetLibraryInfoImpl TLII;
  TargetLibraryInfo TLI(TLII);
  AssumptionCache AC(*F);
  DominatorTree DT(*F);
  LoopInfo LI(DT);
  ScalarEvolution SE(*F, TLI, AC, DT, LI);
  AAResults AA(TLI);
  DependenceInfo DI(F, &AA, &SE, &LI);
  Test(*F, LI, DI, SE);
}

static std::unique_ptr<Module> makeLLVMModule(LLVMContext &Context,
                                              const char *ModuleStr) {
  SMDiagnostic Err;
  return parseAssemblyString(ModuleStr, Err, Context);
}

TEST(DDGTest, getDependencies) {
  const char *ModuleStr =
      "target datalayout = \"e-m:e-i64:64-n32:64\"\n"
      "target triple = \"powerpc64le-unknown-linux-gnu\"\n"
      "\n"
      "define dso_local void @foo(i32 signext %n, i32* noalias %A, i32* "
      "noalias %B) {\n"
      "entry:\n"
      "   %cmp1 = icmp sgt i32 %n, 0\n"
      "   br i1 %cmp1, label %for.body.preheader, label %for.end\n"
      "\n"
      "for.body.preheader:\n"
      "   %wide.trip.count = zext i32 %n to i64\n"
      "   br label %for.body\n"
      " \n"
      " for.body:\n"
      "   %indvars.iv = phi i64 [ 0, %for.body.preheader ], [ "
      "%indvars.iv.next, %for.body ]\n"
      "   %arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv\n"
      "  %0 = trunc i64 %indvars.iv to i32\n"
      "  store i32 %0, i32* %arrayidx, align 4\n"
      "  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1\n"
      "  %arrayidx2 = getelementptr inbounds i32, i32* %A, i64 "
      "%indvars.iv.next\n"
      "  %1 = load i32, i32* %arrayidx2, align 4\n"
      "  %add3 = add nsw i32 %1, 1\n"
      "  %arrayidx5 = getelementptr inbounds i32, i32* %B, i64 %indvars.iv\n"
      "  store i32 %add3, i32* %arrayidx5, align 4\n"
      "  %exitcond = icmp ne i64 %indvars.iv.next, %wide.trip.count\n"
      "  br i1 %exitcond, label %for.body, label %for.end.loopexit\n"
      "\n"
      "for.end.loopexit:\n"
      "  br label %for.end\n"
      "\n"
      "for.end:\n"
      "  ret void\n"
      "}\n";

  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);

  runTest(
      *M, "foo",
      [&](Function &F, LoopInfo &LI, DependenceInfo &DI, ScalarEvolution &SE) {
        Loop *L = *LI.begin();
        assert(L && "expected the loop to be identified.");

        DataDependenceGraph DDG(*L, LI, DI);

        // Collect all the nodes that have an outgoing memory edge
        // while collecting all memory edges as well. There should
        // only be one node with an outgoing memory edge and there
        // should only be one memory edge in the entire graph.
        std::vector<DDGNode *> DependenceSourceNodes;
        std::vector<DDGEdge *> MemoryEdges;
        for (DDGNode *N : DDG) {
          for (DDGEdge *E : *N) {
            bool SourceAdded = false;
            if (E->isMemoryDependence()) {
              MemoryEdges.push_back(E);
              if (!SourceAdded) {
                DependenceSourceNodes.push_back(N);
                SourceAdded = true;
              }
            }
          }
        }

        EXPECT_EQ(DependenceSourceNodes.size(), 1ull);
        EXPECT_EQ(MemoryEdges.size(), 1ull);

        DataDependenceGraph::DependenceList DL;
        DDG.getDependencies(*DependenceSourceNodes.back(),
                            MemoryEdges.back()->getTargetNode(), DL);

        EXPECT_EQ(DL.size(), 1ull);
        EXPECT_TRUE(DL.back()->isAnti());
        EXPECT_EQ(DL.back()->getLevels(), 1u);
        EXPECT_NE(DL.back()->getDistance(1), nullptr);
        EXPECT_EQ(DL.back()->getDistance(1),
                  SE.getOne(DL.back()->getDistance(1)->getType()));
      });
}

/// Test to make sure that when pi-blocks are formed, multiple edges of the same
/// kind and direction are collapsed into a single edge.
/// In the test below, %loadASubI belongs to an outside node, which has input
/// dependency with multiple load instructions in the pi-block containing
/// %loadBSubI. We expect a single memory dependence edge from the outside node
/// to this pi-block. The pi-block also contains %add and %add7 both of which
/// feed a phi in an outside node. We expect a single def-use edge from the
/// pi-block to the node containing that phi.
TEST(DDGTest, avoidDuplicateEdgesToFromPiBlocks) {
  const char *ModuleStr =
      "target datalayout = \"e-m:e-i64:64-n32:64-v256:256:256-v512:512:512\"\n"
      "\n"
      "define void @foo(float* noalias %A, float* noalias %B, float* noalias "
      "%C, float* noalias %D, i32 signext %n) {\n"
      "entry:\n"
      "  %cmp1 = icmp sgt i32 %n, 0\n"
      "  br i1 %cmp1, label %for.body.preheader, label %for.end\n"
      "\n"
      "for.body.preheader:                               ; preds = %entry\n"
      "  %wide.trip.count = zext i32 %n to i64\n"
      "  br label %for.body\n"
      "\n"
      "for.body:                                         ; preds = "
      "%for.body.preheader, %if.end\n"
      "  %indvars.iv = phi i64 [ 0, %for.body.preheader ], [ %indvars.iv.next, "
      "%if.end ]\n"
      "  %arrayidx = getelementptr inbounds float, float* %A, i64 %indvars.iv\n"
      "  %loadASubI = load float, float* %arrayidx, align 4\n"
      "  %arrayidx2 = getelementptr inbounds float, float* %B, i64 "
      "%indvars.iv\n"
      "  %loadBSubI = load float, float* %arrayidx2, align 4\n"
      "  %add = fadd fast float %loadASubI, %loadBSubI\n"
      "  %arrayidx4 = getelementptr inbounds float, float* %A, i64 "
      "%indvars.iv\n"
      "  store float %add, float* %arrayidx4, align 4\n"
      "  %arrayidx6 = getelementptr inbounds float, float* %A, i64 "
      "%indvars.iv\n"
      "  %0 = load float, float* %arrayidx6, align 4\n"
      "  %add7 = fadd fast float %0, 1.000000e+00\n"
      "  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1\n"
      "  %arrayidx10 = getelementptr inbounds float, float* %B, i64 "
      "%indvars.iv.next\n"
      "  store float %add7, float* %arrayidx10, align 4\n"
      "  %arrayidx12 = getelementptr inbounds float, float* %A, i64 "
      "%indvars.iv\n"
      "  %1 = load float, float* %arrayidx12, align 4\n"
      "  %cmp13 = fcmp fast ogt float %1, 1.000000e+02\n"
      "  br i1 %cmp13, label %if.then, label %if.else\n"
      "\n"
      "if.then:                                          ; preds = %for.body\n"
      "  br label %if.end\n"
      "\n"
      "if.else:                                          ; preds = %for.body\n"
      "  br label %if.end\n"
      "\n"
      "if.end:                                           ; preds = %if.else, "
      "%if.then\n"
      "  %ff.0 = phi float [ %add, %if.then ], [ %add7, %if.else ]\n"
      "  store float %ff.0, float* %C, align 4\n"
      "  %exitcond = icmp ne i64 %indvars.iv.next, %wide.trip.count\n"
      "  br i1 %exitcond, label %for.body, label %for.end.loopexit\n"
      "\n"
      "for.end.loopexit:                                 ; preds = %if.end\n"
      "  br label %for.end\n"
      "\n"
      "for.end:                                          ; preds = "
      "%for.end.loopexit, %entry\n"
      "  ret void\n"
      "}\n";

  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);

  runTest(
      *M, "foo",
      [&](Function &F, LoopInfo &LI, DependenceInfo &DI, ScalarEvolution &SE) {
        Loop *L = *LI.begin();
        assert(L && "expected the loop to be identified.");

        DataDependenceGraph DDG(*L, LI, DI);

        const DDGNode *LoadASubI = nullptr;
        for (DDGNode *N : DDG) {
          if (!isa<SimpleDDGNode>(N))
            continue;
          SmallVector<Instruction *, 8> IList;
          N->collectInstructions([](const Instruction *I) { return true; },
                                 IList);
          if (llvm::any_of(IList, [](Instruction *I) {
                return I->getName() == "loadASubI";
              })) {
            LoadASubI = N;
            break;
          }
        }
        assert(LoadASubI && "Did not find load of A[i]");

        const PiBlockDDGNode *PiBlockWithBSubI = nullptr;
        for (DDGNode *N : DDG) {
          if (!isa<PiBlockDDGNode>(N))
            continue;
          for (DDGNode *M : cast<PiBlockDDGNode>(N)->getNodes()) {
            SmallVector<Instruction *, 8> IList;
            M->collectInstructions([](const Instruction *I) { return true; },
                                   IList);
            if (llvm::any_of(IList, [](Instruction *I) {
                  return I->getName() == "loadBSubI";
                })) {
              PiBlockWithBSubI = static_cast<PiBlockDDGNode *>(N);
              break;
            }
          }
          if (PiBlockWithBSubI)
            break;
        }
        assert(PiBlockWithBSubI &&
               "Did not find pi-block containing load of B[i]");

        const DDGNode *FFPhi = nullptr;
        for (DDGNode *N : DDG) {
          if (!isa<SimpleDDGNode>(N))
            continue;
          SmallVector<Instruction *, 8> IList;
          N->collectInstructions([](const Instruction *I) { return true; },
                                 IList);
          if (llvm::any_of(IList, [](Instruction *I) {
                return I->getName() == "ff.0";
              })) {
            FFPhi = N;
            break;
          }
        }
        assert(FFPhi && "Did not find ff.0 phi instruction");

        // Expect a single memory edge from '%0 = A[i]' to the pi-block. This
        // means the duplicate incoming memory edges are removed during pi-block
        // formation.
        SmallVector<DDGEdge *, 4> EL;
        LoadASubI->findEdgesTo(*PiBlockWithBSubI, EL);
        unsigned NumMemoryEdges = llvm::count_if(
            EL, [](DDGEdge *Edge) { return Edge->isMemoryDependence(); });
        EXPECT_EQ(NumMemoryEdges, 1ull);

        /// Expect a single def-use edge from the pi-block to '%ff.0 = phi...`.
        /// This means the duplicate outgoing def-use edges are removed during
        /// pi-block formation.
        EL.clear();
        PiBlockWithBSubI->findEdgesTo(*FFPhi, EL);
        NumMemoryEdges =
            llvm::count_if(EL, [](DDGEdge *Edge) { return Edge->isDefUse(); });
        EXPECT_EQ(NumMemoryEdges, 1ull);
      });
}
