Merge remote-tracking branch 'origin/swift-4.1-branch' into stable
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index 419e9a7..a596ba6 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -537,7 +537,7 @@
/// rules. For example, the RHS of (0 && foo()) is not evaluated. We can
/// evaluate the expression regardless of what the RHS is, but C only allows
/// certain things in certain situations.
- struct LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) EvalInfo {
+ struct EvalInfo {
ASTContext &Ctx;
/// EvalStatus - Contains information about the evaluation.
@@ -977,24 +977,22 @@
/// RAII object used to optionally suppress diagnostics and side-effects from
/// a speculative evaluation.
class SpeculativeEvaluationRAII {
- /// Pair of EvalInfo, and a bit that stores whether or not we were
- /// speculatively evaluating when we created this RAII.
- llvm::PointerIntPair<EvalInfo *, 1, bool> InfoAndOldSpecEval;
- Expr::EvalStatus Old;
+ EvalInfo *Info = nullptr;
+ Expr::EvalStatus OldStatus;
+ bool OldIsSpeculativelyEvaluating;
void moveFromAndCancel(SpeculativeEvaluationRAII &&Other) {
- InfoAndOldSpecEval = Other.InfoAndOldSpecEval;
- Old = Other.Old;
- Other.InfoAndOldSpecEval.setPointer(nullptr);
+ Info = Other.Info;
+ OldStatus = Other.OldStatus;
+ Other.Info = nullptr;
}
void maybeRestoreState() {
- EvalInfo *Info = InfoAndOldSpecEval.getPointer();
if (!Info)
return;
- Info->EvalStatus = Old;
- Info->IsSpeculativelyEvaluating = InfoAndOldSpecEval.getInt();
+ Info->EvalStatus = OldStatus;
+ Info->IsSpeculativelyEvaluating = OldIsSpeculativelyEvaluating;
}
public:
@@ -1002,8 +1000,8 @@
SpeculativeEvaluationRAII(
EvalInfo &Info, SmallVectorImpl<PartialDiagnosticAt> *NewDiag = nullptr)
- : InfoAndOldSpecEval(&Info, Info.IsSpeculativelyEvaluating),
- Old(Info.EvalStatus) {
+ : Info(&Info), OldStatus(Info.EvalStatus),
+ OldIsSpeculativelyEvaluating(Info.IsSpeculativelyEvaluating) {
Info.EvalStatus.Diag = NewDiag;
Info.IsSpeculativelyEvaluating = true;
}
diff --git a/lib/CodeGen/CGOpenMPRuntime.cpp b/lib/CodeGen/CGOpenMPRuntime.cpp
index 951fa63..2280f47 100644
--- a/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -4250,9 +4250,20 @@
// Build type kmp_routine_entry_t (if not built yet).
emitKmpRoutineEntryT(KmpInt32Ty);
// Build type kmp_task_t (if not built yet).
- if (KmpTaskTQTy.isNull()) {
- KmpTaskTQTy = C.getRecordType(createKmpTaskTRecordDecl(
- CGM, D.getDirectiveKind(), KmpInt32Ty, KmpRoutineEntryPtrQTy));
+ if (isOpenMPTaskLoopDirective(D.getDirectiveKind())) {
+ if (SavedKmpTaskloopTQTy.isNull()) {
+ SavedKmpTaskloopTQTy = C.getRecordType(createKmpTaskTRecordDecl(
+ CGM, D.getDirectiveKind(), KmpInt32Ty, KmpRoutineEntryPtrQTy));
+ }
+ KmpTaskTQTy = SavedKmpTaskloopTQTy;
+ } else if (D.getDirectiveKind() == OMPD_task) {
+ assert(D.getDirectiveKind() == OMPD_task &&
+ "Expected taskloop or task directive");
+ if (SavedKmpTaskTQTy.isNull()) {
+ SavedKmpTaskTQTy = C.getRecordType(createKmpTaskTRecordDecl(
+ CGM, D.getDirectiveKind(), KmpInt32Ty, KmpRoutineEntryPtrQTy));
+ }
+ KmpTaskTQTy = SavedKmpTaskTQTy;
}
auto *KmpTaskTQTyRD = cast<RecordDecl>(KmpTaskTQTy->getAsTagDecl());
// Build particular struct kmp_task_t for the given task.
diff --git a/lib/CodeGen/CGOpenMPRuntime.h b/lib/CodeGen/CGOpenMPRuntime.h
index 30e37a8..897e809 100644
--- a/lib/CodeGen/CGOpenMPRuntime.h
+++ b/lib/CodeGen/CGOpenMPRuntime.h
@@ -318,6 +318,10 @@
/// deconstructors of firstprivate C++ objects */
/// } kmp_task_t;
QualType KmpTaskTQTy;
+ /// Saved kmp_task_t for task directive.
+ QualType SavedKmpTaskTQTy;
+ /// Saved kmp_task_t for taskloop-based directive.
+ QualType SavedKmpTaskloopTQTy;
/// \brief Type typedef struct kmp_depend_info {
/// kmp_intptr_t base_addr;
/// size_t len;
diff --git a/test/OpenMP/taskloop_codegen.cpp b/test/OpenMP/taskloop_codegen.cpp
index 8de5202..94cf536 100644
--- a/test/OpenMP/taskloop_codegen.cpp
+++ b/test/OpenMP/taskloop_codegen.cpp
@@ -8,6 +8,10 @@
// CHECK-LABEL: @main
int main(int argc, char **argv) {
// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num(%ident_t* [[DEFLOC:@.+]])
+// CHECK: call i8* @__kmpc_omp_task_alloc(%ident_t* [[DEFLOC]], i32 [[GTID]],
+// CHECK: call i32 @__kmpc_omp_task(%ident_t* [[DEFLOC]], i32 [[GTID]],
+#pragma omp task
+ ;
// CHECK: call void @__kmpc_taskgroup(%ident_t* [[DEFLOC]], i32 [[GTID]])
// CHECK: [[TASKV:%.+]] = call i8* @__kmpc_omp_task_alloc(%ident_t* [[DEFLOC]], i32 [[GTID]], i32 33, i64 80, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[TDP_TY:%.+]]*)* [[TASK1:@.+]] to i32 (i32, i8*)*))
// CHECK: [[TASK:%.+]] = bitcast i8* [[TASKV]] to [[TDP_TY]]*