static void EmitOMPAtomicReadExpr(CodeGenFunction &CGF, bool IsSeqCst, const Expr *X, const Expr *V, SourceLocation Loc) { // v = x; assert(V->isLValue() && "V of 'omp atomic read' is not lvalue"); assert(X->isLValue() && "X of 'omp atomic read' is not lvalue"); LValue XLValue = CGF.EmitLValue(X); LValue VLValue = CGF.EmitLValue(V); RValue Res = XLValue.isGlobalReg() ? CGF.EmitLoadOfLValue(XLValue, Loc) : CGF.EmitAtomicLoad(XLValue, Loc); // OpenMP, 2.12.6, atomic Construct // Any atomic construct with a seq_cst clause forces the atomically // performed operation to include an implicit flush operation without a // list. if (IsSeqCst) CGF.CGM.getOpenMPRuntime().EmitOMPFlush(CGF, llvm::None, Loc); switch (CGF.getEvaluationKind(V->getType())) { case TEK_Scalar: CGF.EmitStoreOfScalar( convertToScalarValue(CGF, Res, X->getType(), V->getType()), VLValue); break; case TEK_Complex: CGF.EmitStoreOfComplex( convertToComplexValue(CGF, Res, X->getType(), V->getType()), VLValue, /*isInit=*/false); break; case TEK_Aggregate: llvm_unreachable("Must be a scalar or complex."); } }