DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(OrigVD),
/*RefersToEnclosingVariableOrCapture=*/FD != nullptr,
(*IRef)->getType(), VK_LValue, (*IRef)->getExprLoc());
- LValue OriginalLVal = EmitLValue(&DRE);
+ LValue OriginalLVal;
+ if (!FD) {
+ // Check if the firstprivate variable is just a constant value.
+ ConstantEmission CE = tryEmitAsConstant(&DRE);
+ if (CE && !CE.isReference()) {
+ // Constant value, no need to create a copy.
+ ++IRef;
+ ++InitsRef;
+ continue;
+ }
+ if (CE && CE.isReference()) {
+ OriginalLVal = CE.getReferenceLValue(*this, &DRE);
+ } else {
+ assert(!CE && "Expected non-constant firstprivate.");
+ OriginalLVal = EmitLValue(&DRE);
+ }
+ } else {
+ OriginalLVal = EmitLValue(&DRE);
+ }
QualType Type = VD->getType();
if (Type->isArrayType()) {
// Emit VarDecl with copy init for arrays.
s_arr[0] = var;
sivar = 2;
}
-#pragma omp parallel allocate(omp_default_mem_alloc: t_var) firstprivate(t_var)
- {}
+ const int a = 0;
+#pragma omp parallel allocate(omp_default_mem_alloc: t_var) firstprivate(t_var, a)
+ { t_var = a; }
return tmain<int>();
#endif
}
// CHECK: [[T_VAR:%.+]] = alloca i32,
// CHECK: [[T_VARCAST:%.+]] = alloca [[iz:i64|i32]],
// CHECK: [[SIVARCAST:%.+]] = alloca [[iz]],
+// CHECK: [[A:%.+]] = alloca i32,
// CHECK: [[T_VARCAST1:%.+]] = alloca [[iz:i64|i32]],
// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]])
// CHECK: [[T_VARVAL:%.+]] = load i32, i32* [[T_VAR]],
// CHECK-32: [[T_VAR_VAL:%.+]] = load i32, i32* [[T_VAR_ADDR]],
// CHECK-64: [[T_VAR_VAL:%.+]] = load i32, i32* [[BC]],
// CHECK: store i32 [[T_VAR_VAL]], i32* [[T_VAR_PRIV]],
+// CHECK: store i32 0, i32* [[T_VAR_PRIV]],
// CHECK: call void @__kmpc_free(i32 [[GTID]], i8* [[T_VAR_VOID_PTR]], i8* inttoptr ([[iz]] 1 to i8*))
// CHECK: ret void