blob: ee6e0106a1dc52e62e66dada91047a63dce13da0 [file] [log] [blame]
Artur Pilipenkoa25a3442019-01-03 20:16:33 +00001//=======- CaptureTrackingTest.cpp - Unit test for the Capture Tracking ---===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "llvm/Analysis/CaptureTracking.h"
11#include "llvm/Analysis/OrderedBasicBlock.h"
12#include "llvm/AsmParser/Parser.h"
13#include "llvm/IR/Dominators.h"
14#include "llvm/IR/Instructions.h"
15#include "llvm/IR/LLVMContext.h"
16#include "llvm/IR/Module.h"
17#include "llvm/Support/SourceMgr.h"
18#include "gtest/gtest.h"
19
20using namespace llvm;
21
22TEST(CaptureTracking, MaxUsesToExplore) {
23 StringRef Assembly = R"(
24 ; Function Attrs: nounwind ssp uwtable
25 declare void @doesnt_capture(i8* nocapture, i8* nocapture, i8* nocapture,
26 i8* nocapture, i8* nocapture)
27
28 ; %arg has 5 uses
29 define void @test_few_uses(i8* %arg) {
30 call void @doesnt_capture(i8* %arg, i8* %arg, i8* %arg, i8* %arg, i8* %arg)
31 ret void
32 }
33
34 ; %arg has 50 uses
35 define void @test_many_uses(i8* %arg) {
36 call void @doesnt_capture(i8* %arg, i8* %arg, i8* %arg, i8* %arg, i8* %arg)
37 call void @doesnt_capture(i8* %arg, i8* %arg, i8* %arg, i8* %arg, i8* %arg)
38 call void @doesnt_capture(i8* %arg, i8* %arg, i8* %arg, i8* %arg, i8* %arg)
39 call void @doesnt_capture(i8* %arg, i8* %arg, i8* %arg, i8* %arg, i8* %arg)
40 call void @doesnt_capture(i8* %arg, i8* %arg, i8* %arg, i8* %arg, i8* %arg)
41 call void @doesnt_capture(i8* %arg, i8* %arg, i8* %arg, i8* %arg, i8* %arg)
42 call void @doesnt_capture(i8* %arg, i8* %arg, i8* %arg, i8* %arg, i8* %arg)
43 call void @doesnt_capture(i8* %arg, i8* %arg, i8* %arg, i8* %arg, i8* %arg)
44 call void @doesnt_capture(i8* %arg, i8* %arg, i8* %arg, i8* %arg, i8* %arg)
45 call void @doesnt_capture(i8* %arg, i8* %arg, i8* %arg, i8* %arg, i8* %arg)
46 ret void
47 }
48 )";
49
50 LLVMContext Context;
51 SMDiagnostic Error;
52 auto M = parseAssemblyString(Assembly, Error, Context);
53 ASSERT_TRUE(M) << "Bad assembly?";
54
55 auto Test = [&M](const char *FName, unsigned FalseMaxUsesLimit,
56 unsigned TrueMaxUsesLimit) {
57 Function *F = M->getFunction(FName);
58 ASSERT_NE(F, nullptr);
59 Value *Arg = &*F->arg_begin();
60 ASSERT_NE(Arg, nullptr);
61 ASSERT_FALSE(PointerMayBeCaptured(Arg, true, true, FalseMaxUsesLimit));
62 ASSERT_TRUE(PointerMayBeCaptured(Arg, true, true, TrueMaxUsesLimit));
63
64 BasicBlock *EntryBB = &F->getEntryBlock();
65 DominatorTree DT(*F);
66 OrderedBasicBlock OBB(EntryBB);
67
68 Instruction *Ret = EntryBB->getTerminator();
69 ASSERT_TRUE(isa<ReturnInst>(Ret));
70 ASSERT_FALSE(PointerMayBeCapturedBefore(Arg, true, true, Ret, &DT, false,
71 &OBB, FalseMaxUsesLimit));
72 ASSERT_TRUE(PointerMayBeCapturedBefore(Arg, true, true, Ret, &DT, false,
73 &OBB, TrueMaxUsesLimit));
74 };
75
76 Test("test_few_uses", 6, 4);
77 Test("test_many_uses", 50, 30);
78}