Skip to content

Commit 50c7033

Browse files
Teach capture tracking that readonly functions can
only capture their arguments by returning them or throwing an exception or not based on the argument value. Patch essentially by Frits van Bommel. llvm-svn: 70876
1 parent b88227e commit 50c7033

File tree

2 files changed

+67
-32
lines changed

2 files changed

+67
-32
lines changed

llvm/lib/Analysis/CaptureTracking.cpp

+47-28
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,7 @@ bool llvm::PointerMayBeCaptured(const Value *V, bool ReturnCaptures) {
4949
switch (I->getOpcode()) {
5050
case Instruction::Call:
5151
case Instruction::Invoke: {
52-
CallSite CS = CallSite::get(I);
53-
// Not captured if the callee is readonly and doesn't return a copy
54-
// through its return value.
55-
if (CS.onlyReadsMemory() && I->getType() == Type::VoidTy)
56-
break;
52+
CallSite CS(I);
5753

5854
// Not captured if only passed via 'nocapture' arguments. Note that
5955
// calling a function pointer does not in itself cause the pointer to
@@ -62,46 +58,69 @@ bool llvm::PointerMayBeCaptured(const Value *V, bool ReturnCaptures) {
6258
// that loading a value from a pointer does not cause the pointer to be
6359
// captured, even though the loaded value might be the pointer itself
6460
// (think of self-referential objects).
61+
bool MayBeCaptured = false;
6562
CallSite::arg_iterator B = CS.arg_begin(), E = CS.arg_end();
6663
for (CallSite::arg_iterator A = B; A != E; ++A)
67-
if (A->get() == V && !CS.paramHasAttr(A - B + 1, Attribute::NoCapture))
68-
// The parameter is not marked 'nocapture' - captured.
69-
return true;
70-
// Only passed via 'nocapture' arguments, or is the called function - not
71-
// captured.
64+
if (A->get() == V && !CS.paramHasAttr(A-B+1, Attribute::NoCapture)) {
65+
// The parameter is not marked 'nocapture' - handled by generic code
66+
// below.
67+
MayBeCaptured = true;
68+
break;
69+
}
70+
if (!MayBeCaptured)
71+
// Only passed via 'nocapture' arguments, or is the called function -
72+
// not captured.
73+
continue;
74+
if (!CS.doesNotThrow())
75+
// Even a readonly function can leak bits by throwing an exception or
76+
// not depending on the input value.
77+
return true;
78+
// Fall through to the generic code.
7279
break;
7380
}
7481
case Instruction::Free:
7582
// Freeing a pointer does not cause it to be captured.
76-
break;
83+
continue;
7784
case Instruction::Load:
7885
// Loading from a pointer does not cause it to be captured.
79-
break;
86+
continue;
8087
case Instruction::Ret:
8188
if (ReturnCaptures)
8289
return true;
83-
break;
90+
continue;
8491
case Instruction::Store:
8592
if (V == I->getOperand(0))
8693
// Stored the pointer - it may be captured.
8794
return true;
8895
// Storing to the pointee does not cause the pointer to be captured.
89-
break;
90-
case Instruction::BitCast:
91-
case Instruction::GetElementPtr:
92-
case Instruction::PHI:
93-
case Instruction::Select:
94-
// The original value is not captured via this if the new value isn't.
95-
for (Instruction::use_iterator UI = I->use_begin(), UE = I->use_end();
96-
UI != UE; ++UI) {
97-
Use *U = &UI.getUse();
98-
if (Visited.insert(U))
99-
Worklist.push_back(U);
100-
}
101-
break;
102-
default:
103-
// Something else - be conservative and say it is captured.
96+
continue;
97+
}
98+
99+
// If it may write to memory and isn't one of the special cases above,
100+
// be conservative and assume the pointer is captured.
101+
if (I->mayWriteToMemory())
104102
return true;
103+
104+
// If the instruction doesn't write memory, it can only capture by
105+
// having its own value depend on the input value.
106+
const Type* Ty = I->getType();
107+
if (Ty == Type::VoidTy)
108+
// The value of an instruction can't be a copy if it can't contain any
109+
// information.
110+
continue;
111+
if (!isa<PointerType>(Ty))
112+
// At the moment, we don't track non-pointer values, so be conservative
113+
// and assume the pointer is captured.
114+
// FIXME: Track these too. This would need to be done very carefully as
115+
// it is easy to leak bits via control flow if integer values are allowed.
116+
return true;
117+
118+
// The original value is not captured via this if the new value isn't.
119+
for (Instruction::use_iterator UI = I->use_begin(), UE = I->use_end();
120+
UI != UE; ++UI) {
121+
Use *U = &UI.getUse();
122+
if (Visited.insert(U))
123+
Worklist.push_back(U);
105124
}
106125
}
107126

llvm/test/Transforms/FunctionAttrs/2008-12-31-NoCapture.ll

+20-4
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,16 @@ define i1 @c5(i32* %q, i32 %bitno) {
3939
ret i1 %val
4040
}
4141

42+
declare void @throw_if_bit_set(i8*, i8) readonly
43+
define i1 @c6(i8* %q, i8 %bit) {
44+
invoke void @throw_if_bit_set(i8* %q, i8 %bit)
45+
to label %ret0 unwind label %ret1
46+
ret0:
47+
ret i1 0
48+
ret1:
49+
ret i1 1
50+
}
51+
4252
define i32 @nc1(i32* %q, i32* %p, i1 %b) {
4353
e:
4454
br label %l
@@ -63,14 +73,20 @@ define void @nc3(void ()* %p) {
6373
ret void
6474
}
6575

66-
declare void @external(i8*) readonly
76+
declare void @external(i8*) readonly nounwind
6777
define void @nc4(i8* %p) {
6878
call void @external(i8* %p)
6979
ret void
7080
}
7181

72-
define void @nc5(void (i8*)* %f, i8* %p) {
73-
call void %f(i8* %p) readonly
74-
call void %f(i8* nocapture %p)
82+
define void @nc5(void (i8*)* %p, i8* %r) {
83+
call void %p(i8* %r)
84+
call void %p(i8* nocapture %r)
85+
ret void
86+
}
87+
88+
declare i8* @external_identity(i8*) readonly nounwind
89+
define void @nc6(i8* %p) {
90+
call i8* @external_identity(i8* %p)
7591
ret void
7692
}

0 commit comments

Comments
 (0)