================
Comment at: lib/CodeGen/CGStmtOpenMP.cpp:591
@@ +590,3 @@
+      llvm::Value *ScalarVal;
+      switch (CGF.getEvaluationKind(X->getType())) {
+      case TEK_Scalar:
----------------
rjmccall wrote:
> ABataev wrote:
> > rjmccall wrote:
> > > ABataev wrote:
> > > > rjmccall wrote:
> > > > > I think you'll want this functionality for some of the other atomic 
> > > > > ops anyway, so you might as well make this a separate function that 
> > > > > you can call like this:
> > > > >   llvm::Value *ScalarVal = convertToScalarValue(CGF, Res, 
> > > > > X->getType(), V->getType());
> > > > > 
> > > > > It's kindof a shame that you have to redo all of this instead of just 
> > > > > relying on the implicit casts that Sema already created when it 
> > > > > analyzed the expression, but maybe this is better than messing around 
> > > > > with OpaqueValueExprs, and it works because you don't have a 
> > > > > requirement to handle custom operators.
> > > > 1. Agree, I'll rework this.
> > > > 2. Yes, I tried to implement it using some hooks/hacks in AST, but 
> > > > there was a lot of troubles with atomic ops.
> > > > 3. We will have to support some custom operators in future (in OpenMP 
> > > > 4.0 reductions introduces user-defined reductions, which must be called 
> > > > as atomic ops and I plan to use global locks for them).
> > > You can't mix locking and non-locking atomics on the same object:  
> > > they'll be atomic with respect to themselves, but not with respect to 
> > > each other.  That is, assuming that atomic_start and atomic_end aren't 
> > > implemented by halting all other OpenMP threads.
> > > 
> > > e.g. imagine that you have a *= that's implemented with a 
> > > compare-and-swap loop and a custom reduction that you've implemented with 
> > > the global lock.  The global lock doesn't keep the compare-and-swap from 
> > > firing during the execution of the custom reduction, so (1) different 
> > > parts of the custom reduction might see different values for the original 
> > > l-value and (2) the custom reduction will completely overwrite the *= 
> > > rather than appearing to execute before or after.
> > > 
> > > In fact, you have a similar problem with aggregates, where an atomic 
> > > access to an aggregate (e.g. a std::pair<float,float>) cannot be made 
> > > atomic with respect to an atomic access to a subobject unless the 
> > > aggregate will be accessed locklessly.  (You could do *some* operations 
> > > locklessly if you wrote them very carefully, e.g. reads and writes, but I 
> > > don't know of any way to do an aggregate compare-and-swap that's atomic 
> > > with a subobject compare-and-swap when the first requires a lock and the 
> > > second doesn't.)  That's mostly defined away by the current requirement 
> > > that the l-value have scalar type, except that you do support _Complex 
> > > l-values right now, and 32-bit platforms generally can't make _Complex 
> > > double lockless.  The reverse problem applies to vectors: a 16-byte 
> > > vector will generally be sufficiently aligned that a 64-bit platform can 
> > > access it locklessly, but you're implementing some accesses to subobjects 
> > > with locks: specifically, vector projections that create compound 
> > > l-values.
> > > 
> > > This is really a specification problem: OpenMP wants simple operations to 
> > > be implementable with native atomics, but that really restricts the set 
> > > of operations you can do unless you can assume at a high level that there 
> > > are never partially overlapping atomic operations.   The easiest language 
> > > solution is to say that, for the purposes of OpenMP's atomics, _Complex 
> > > and vector types don't count as scalars.  But I don't know if that would 
> > > fly — it might be a goal to loosen the restrictions about what types you 
> > > can use in atomic operations.
> > I agree with you, currently the code is not quite correct. I think we can 
> > resolve this problem by emitting OpenMP specific locks for target supported 
> > lockfree atomic operations. But in this case we don't need target atomic 
> > ops at all, we can rely on runtime library interface only.
> You mean, always grabbing a lock instead of ever using lock-free operations?  
> I agree that that's the most general solution, but it's really heavy-handed.
> 
> It's possible that you can still do user-defined reductions with a 
> compare-and-swap loop, depending on how they're defined. (Specifically: you 
> have to be allowed to try the reduction multiple times, and the reduction's 
> only allowed to access a single atomic value.  The existing specification 
> about the #pragma tries to enforce those conditions even for the simple cases 
> allowed there, so I'm optimistic that whoever is writing your spec is at 
> least thinking about these problems.)
> 
> What you really need here is a statement about subobjects.  The C11/C++11 
> atomic types are very nice because they tell you exactly at what level 
> something is atomic: you can have an std::atomic<std::pair<int,int>>, but 
> that type doesn't provide accessors for atomically accessing the individual 
> members of the pair; you can't just project out a std::atomic<int>& from the 
> first element.  That's really important, because it tells you locally that 
> all atomic accesses are going to reference the full, 64-byte aggregate, which 
> means you can agree very easily on a protocol for that access.
> 
> OpenMP doesn't tie into the type system that way, but you can still impose 
> that rule at a high level by saying that it's undefined behavior for atomic 
> accesses to an aggregate to race with atomic accesses to a subobject.  For 
> example, you can have an atomic operation on a _Complex float, and you can 
> have a simultaneous atomic operation on a float, but the fact that they're 
> simultaneous means that we can assume they don't alias.  That still lets us 
> decide on the atomic access pattern based purely on the type of the atomic 
> l-value.
John, I decided to use lock free operations on simple lvalues, but for other 
lvalues I'm going to use global lock provided by the runtime. I think in this 
case we can avoid conflicts conflicts. What do you think about this solution?

http://reviews.llvm.org/D6431

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/



_______________________________________________
cfe-commits mailing list
cfe-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to