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."); } }
// CopyObject - Utility to copy an object. Calls copy constructor as necessary. // DestPtr is casted to the right type. static void CopyObject(CodeGenFunction &CGF, const Expr *E, llvm::Value *DestPtr, llvm::Value *ExceptionPtrPtr) { QualType ObjectType = E->getType(); // Store the throw exception in the exception object. if (!CGF.hasAggregateLLVMType(ObjectType)) { llvm::Value *Value = CGF.EmitScalarExpr(E); const llvm::Type *ValuePtrTy = Value->getType()->getPointerTo(); CGF.Builder.CreateStore(Value, CGF.Builder.CreateBitCast(DestPtr, ValuePtrTy)); } else { const llvm::Type *Ty = CGF.ConvertType(ObjectType)->getPointerTo(); const CXXRecordDecl *RD = cast<CXXRecordDecl>(ObjectType->getAs<RecordType>()->getDecl()); llvm::Value *This = CGF.Builder.CreateBitCast(DestPtr, Ty); if (RD->hasTrivialCopyConstructor()) { CGF.EmitAggExpr(E, This, false); } else if (CXXConstructorDecl *CopyCtor = RD->getCopyConstructor(CGF.getContext(), 0)) { llvm::BasicBlock *PrevLandingPad = CGF.getInvokeDest(); if (CGF.Exceptions) { CodeGenFunction::EHCleanupBlock Cleanup(CGF); llvm::Constant *FreeExceptionFn = getFreeExceptionFn(CGF); // Load the exception pointer. llvm::Value *ExceptionPtr = CGF.Builder.CreateLoad(ExceptionPtrPtr); CGF.Builder.CreateCall(FreeExceptionFn, ExceptionPtr); } llvm::Value *Src = CGF.EmitLValue(E).getAddress(); CGF.setInvokeDest(PrevLandingPad); llvm::BasicBlock *TerminateHandler = CGF.getTerminateHandler(); PrevLandingPad = CGF.getInvokeDest(); CGF.setInvokeDest(TerminateHandler); // Stolen from EmitClassAggrMemberwiseCopy llvm::Value *Callee = CGF.CGM.GetAddrOfCXXConstructor(CopyCtor, Ctor_Complete); CallArgList CallArgs; CallArgs.push_back(std::make_pair(RValue::get(This), CopyCtor->getThisType(CGF.getContext()))); // Push the Src ptr. CallArgs.push_back(std::make_pair(RValue::get(Src), CopyCtor->getParamDecl(0)->getType())); QualType ResultType = CopyCtor->getType()->getAs<FunctionType>()->getResultType(); CGF.EmitCall(CGF.CGM.getTypes().getFunctionInfo(ResultType, CallArgs), Callee, CallArgs, CopyCtor); CGF.setInvokeDest(PrevLandingPad); } else llvm_unreachable("uncopyable object"); } }
/// \brief Emit a helper variable and return corresponding lvalue. static LValue EmitOMPHelperVar(CodeGenFunction &CGF, const DeclRefExpr *Helper) { auto VDecl = cast<VarDecl>(Helper->getDecl()); CGF.EmitVarDecl(*VDecl); return CGF.EmitLValue(Helper); }