================
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
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits