[PATCH] D32673: [CaptureTracking] Handle capturing of invariant.group.barrier
Piotr Padlewski via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Sat Apr 29 13:58:02 PDT 2017
Prazek created this revision.
Herald added a subscriber: JDevlieghere.
invariant.group.barrier has the same rules of capturing as
bitcast, gep, etc - the original value is not captured
if the returned pointer is not captured.
https://reviews.llvm.org/D32673
Files:
lib/Analysis/CaptureTracking.cpp
test/Transforms/FunctionAttrs/nocapture.ll
Index: test/Transforms/FunctionAttrs/nocapture.ll
===================================================================
--- test/Transforms/FunctionAttrs/nocapture.ll
+++ test/Transforms/FunctionAttrs/nocapture.ll
@@ -218,3 +218,21 @@
store volatile i32 0, i32* %gep, align 4
ret void
}
+
+; CHECK: nocaptureBarriers(i8* nocapture %p)
+define void @nocaptureBarriers(i8* %p) {
+entry:
+ %b = call i8* @llvm.invariant.group.barrier(i8* %p)
+ store i8 42, i8* %b
+ ret void
+}
+
+ at g2 = global i8* null
+; CHECK: define void @captureBarrier(i8* %p)
+define void @captureBarrier(i8* %p) {
+ %b = call i8* @llvm.invariant.group.barrier(i8* %p)
+ store i8* %b, i8** @g2
+ ret void
+}
+
+declare i8* @llvm.invariant.group.barrier(i8*)
Index: lib/Analysis/CaptureTracking.cpp
===================================================================
--- lib/Analysis/CaptureTracking.cpp
+++ lib/Analysis/CaptureTracking.cpp
@@ -215,18 +215,22 @@
assert(V->getType()->isPointerTy() && "Capture is for pointers only!");
SmallVector<const Use *, Threshold> Worklist;
SmallSet<const Use *, Threshold> Visited;
- int Count = 0;
- for (const Use &U : V->uses()) {
- // If there are lots of uses, conservatively say that the value
- // is captured to avoid taking too much compile time.
- if (Count++ >= Threshold)
- return Tracker->tooManyUses();
-
- if (!Tracker->shouldExplore(&U)) continue;
- Visited.insert(&U);
- Worklist.push_back(&U);
- }
+ auto AddUses = [&](const Value *V) {
+ int Count = 0;
+ for (const Use &U : V->uses()) {
+ // If there are lots of uses, conservatively say that the value
+ // is captured to avoid taking too much compile time.
+ if (Count++ >= Threshold)
+ return Tracker->tooManyUses();
+ if (!Visited.insert(&U).second)
+ continue;
+ if (!Tracker->shouldExplore(&U))
+ continue;
+ Worklist.push_back(&U);
+ }
+ };
+ AddUses(V);
while (!Worklist.empty()) {
const Use *U = Worklist.pop_back_val();
@@ -243,6 +247,13 @@
if (CS.onlyReadsMemory() && CS.doesNotThrow() && I->getType()->isVoidTy())
break;
+ // invariant.group.barrier only captures pointer by returning it,
+ // so the pointer wasn't captured if returned pointer is not captured.
+ if (CS.getIntrinsicID() == Intrinsic::invariant_group_barrier) {
+ AddUses(I);
+ break;
+ }
+
// Volatile operations effectively capture the memory location that they
// load and store to.
if (auto *MI = dyn_cast<MemIntrinsic>(I))
@@ -313,17 +324,7 @@
case Instruction::Select:
case Instruction::AddrSpaceCast:
// The original value is not captured via this if the new value isn't.
- Count = 0;
- for (Use &UU : I->uses()) {
- // If there are lots of uses, conservatively say that the value
- // is captured to avoid taking too much compile time.
- if (Count++ >= Threshold)
- return Tracker->tooManyUses();
-
- if (Visited.insert(&UU).second)
- if (Tracker->shouldExplore(&UU))
- Worklist.push_back(&UU);
- }
+ AddUses(I);
break;
case Instruction::ICmp: {
// Don't count comparisons of a no-alias return value against null as
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D32673.97196.patch
Type: text/x-patch
Size: 3290 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170429/d06c7cdd/attachment.bin>
More information about the llvm-commits
mailing list