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