Hi everyone, I want to track the def-use chain for atomic variables. However, it seems that LLVM will not generate PHI nodes for atomic variables. I present the generated LLVM bytecode for the next code snippet as follow. I found that it only generated PHI node (*%8 = phi i32 [ %4, %3 ], [ %6, %5 ]*) for non-atomic variable 'data2' but not for atomic variable x? Why? With PHI node "*%8 = phi i32 [ %4, %3 ], [ %6, %5 ]*", we can easily know that *data3* dependents on *data4.* However, if no such PHI node can be generated, how to catch the information that *data1* dependents on *data4*? Thank you all in advance. int data1, data2, data3, data4; std::atomic<int> x; void f1() { if (data1 > 0) { x = data4; data2 = data4; } data3 = data2; data1 = x; } ; Function Attrs: uwtable define void @_Z2f1v() #3 personality i32 (...)* @__gxx_personality_v0 { tail call void @checker_thread_begin(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i64 0, i64 0)) %1 = load i32, i32* @data1, align 4, !tbaa !1 %2 = icmp sgt i32 %1, 0 br i1 %2, label %5, label %3 ; <label>:3: ; preds = %0 %4 = load i32, i32* @data2, align 4, !tbaa !1 br label %7 ; <label>:5: ; preds = %0 %6 = load i32, i32* @data4, align 4, !tbaa !1 store atomic i32 %6, i32* getelementptr inbounds (%"struct.std::atomic", %"struct.std::atomic"* @x, i64 0, i32 0, i32 0) seq_cst, align 4 store i32 %6, i32* @data2, align 4, !tbaa !1 br label %7 ; <label>:7: ; preds = %3, %5 * %8 = phi i32 [ %4, %3 ], [ %6, %5 ]* store i32 %8, i32* @data3, align 4, !tbaa !1 %9 = load atomic i32, i32* getelementptr inbounds (%"struct.std::atomic", %"struct.std::atomic"* @x, i64 0, i32 0, i32 0) seq_cst, align 4 store i32 %9, i32* @data1, align 4, !tbaa !1 tail call void @checker_thread_end() ret void } Best regards, Qiuping Yi Institute Of Software Chinese Academy of Sciences -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180207/a26ce3ad/attachment.html>
David Chisnall via llvm-dev
2018-Feb-08 09:11 UTC
[llvm-dev] PHI nodes for atomic variables
On 8 Feb 2018, at 04:07, Qiuping Yi via llvm-dev <llvm-dev at lists.llvm.org> wrote:> > I found that it only generated PHI node (%8 = phi i32 [ %4, %3 ], [ %6, %5 ]) for non-atomic variable 'data2' but not for atomic variable x? Why?LLVM IR does not contain variables, it contains (immutable) registers. Some of these registers refer to memory locations and are usable with loads and stores. The notion of ‘atomic’ doesn’t make sense in the context of a register, because registers are implicitly immutable (i.e. not updated, so atomic updates don’t make sense) and non-shared (so there’s nothing for accesses to them to be atomic with respect to). As such, the atomic qualifier makes sense only with memory locations. The memory address itself may be stored in a register, but updates to the location must be performed by loads and stores (or atomicrmw instructions). In the absence of any ordering constraints imposed by atomic memory operations (including fences), it is often safe to promote a sequence of loads and stores of a memory location to a single load / store pair with a sequence of registers storing temporary values. This is allowed because, in the absence of something that establishes a happens-before relationship between threads, a thread is allowed to make writes to memory visible to other threads in any order. David
Thanks for your explanation. Do you mean that LLVM will not maintain the def-use chain for atomic variables? So it is impossible to directly catch the fact that the load of x at the statement 'data1 = x; ' dependents on data4 (because of the statement x=data4 )? If I want to get such information, may be the only solution is to traverse all the predecessors of the statement 'data1 = x;'. Best regards, Qiuping Yi Institute Of Software Chinese Academy of Sciences On Thu, Feb 8, 2018 at 3:11 AM, David Chisnall <David.Chisnall at cl.cam.ac.uk> wrote:> On 8 Feb 2018, at 04:07, Qiuping Yi via llvm-dev <llvm-dev at lists.llvm.org> > wrote: > > > > I found that it only generated PHI node (%8 = phi i32 [ %4, %3 ], [ %6, > %5 ]) for non-atomic variable 'data2' but not for atomic variable x? Why? > > LLVM IR does not contain variables, it contains (immutable) registers. > Some of these registers refer to memory locations and are usable with loads > and stores. The notion of ‘atomic’ doesn’t make sense in the context of a > register, because registers are implicitly immutable (i.e. not updated, so > atomic updates don’t make sense) and non-shared (so there’s nothing for > accesses to them to be atomic with respect to). As such, the atomic > qualifier makes sense only with memory locations. The memory address > itself may be stored in a register, but updates to the location must be > performed by loads and stores (or atomicrmw instructions). > > In the absence of any ordering constraints imposed by atomic memory > operations (including fences), it is often safe to promote a sequence of > loads and stores of a memory location to a single load / store pair with a > sequence of registers storing temporary values. This is allowed because, > in the absence of something that establishes a happens-before relationship > between threads, a thread is allowed to make writes to memory visible to > other threads in any order. > > David > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180208/89cc461c/attachment.html>