xref: /llvm-project/llvm/unittests/Analysis/CaptureTrackingTest.cpp (revision a974b33a10745b528c34f0accbd230b0a4e1fb87)
1 //=======- 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 
20 using namespace llvm;
21 
22 TEST(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 }
79