There are troubles with codegen for 'schedule' clause with non-constant chunk size in combined directives like 'omp parallel for'. Currently, all variables, used in this chunk expression, must be captured and passed to outlined function for implicit 'parallel' region. But this does not happen because this expression is generated outside of 'parallel for' directive region and it causes compiler crash.
The codegen is changed so, that if non-constant chunk size is found, it is evaluated outside of OpenMP region and the value is stored into private global variable. When loop directive needs this schedule chunk, it just loads the value stored inside this global variable and uses it as a chunk size.
Details
Diff Detail
Event Timeline
Mostly seems fine, but using a global variable is problematic.
lib/CodeGen/CGStmtOpenMP.cpp | ||
---|---|---|
980 | Using a global variable here makes this non-reentrant. Unless there's some weird restriction on where this clause can appear, that's not okay. You might have to capture this value in the CapturedStmt. That should just be a matter of making an artificial VarDecl, initializing it to the captured value, and capturing it. If you can capture it by value instead of by reference, that would be slightly preferable. | |
1052 | Please test for a global value instead of checking the type. |
John, I already reworked it and committed. I did as you said: captured
it in the CapturedStmt, because globals cause a lot of troubles with
offloading support. That's why this revision was abandoned.
Best regards,
Alexey Bataev
Software Engineer
Intel Compiler Team
21.05.2015 10:06, John McCall пишет:
Mostly seems fine, but using a global variable is problematic.
Comment at: lib/CodeGen/CGStmtOpenMP.cpp:980
@@ +979,3 @@
+ CGF.Builder.CreateAlignedStore(Chunk, LoopChunk, Alignment);
+ return LoopChunk;+ }
Using a global variable here makes this non-reentrant. Unless there's some weird restriction on where this clause can appear, that's not okay.
You might have to capture this value in the CapturedStmt. That should just be a matter of making an artificial VarDecl, initializing it to the captured value, and capturing it. If you can capture it by value instead of by reference, that would be slightly preferable.
Comment at: lib/CodeGen/CGStmtOpenMP.cpp:1052
@@ -1020,5 +1051,3 @@ScheduleKind = C->getScheduleKind();
- if (auto Ch = C->getChunkSize()) {
- Chunk = EmitScalarExpr(Ch);
- Chunk = EmitScalarConversion(Chunk, Ch->getType(),
- S.getIterationVariable()->getType());
+ if (Chunk && Chunk->getType()->isPointerTy()) {
+ Chunk = Builder.CreateAlignedLoad(
Please test for a global value instead of checking the type.
EMAIL PREFERENCES
http://reviews.llvm.org/settings/panel/emailpreferences/
Using a global variable here makes this non-reentrant. Unless there's some weird restriction on where this clause can appear, that's not okay.
You might have to capture this value in the CapturedStmt. That should just be a matter of making an artificial VarDecl, initializing it to the captured value, and capturing it. If you can capture it by value instead of by reference, that would be slightly preferable.