diff options
author | Alexey Bataev <a.bataev@hotmail.com> | 2015-08-28 06:09:05 +0000 |
---|---|---|
committer | Alexey Bataev <a.bataev@hotmail.com> | 2015-08-28 06:09:05 +0000 |
commit | 117fb35cf7348c04f824a1f971cdb8ac78ab370c (patch) | |
tree | eb94f3fe46d44a6b48281638e90abf6fd240aa2e /clang/lib/CodeGen/CGExpr.cpp | |
parent | 8cff17469fa144bd7e8f19fa30aa881eb85983a3 (diff) | |
download | bcm5719-llvm-117fb35cf7348c04f824a1f971cdb8ac78ab370c.tar.gz bcm5719-llvm-117fb35cf7348c04f824a1f971cdb8ac78ab370c.zip |
[OPENMP 4.0] Codegen for array sections.
Added codegen for array section in 'depend' clause of 'task' directive. It emits to pointers, one for the begin of array section and another for the end of array section. Size of the section is calculated as (end + 1 - start) * sizeof(basic_element_type).
llvm-svn: 246278
Diffstat (limited to 'clang/lib/CodeGen/CGExpr.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index a0d004d315c..bf660b448c3 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -911,6 +911,8 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) { return EmitUnaryOpLValue(cast<UnaryOperator>(E)); case Expr::ArraySubscriptExprClass: return EmitArraySubscriptExpr(cast<ArraySubscriptExpr>(E)); + case Expr::OMPArraySectionExprClass: + return EmitOMPArraySectionExpr(cast<OMPArraySectionExpr>(E)); case Expr::ExtVectorElementExprClass: return EmitExtVectorElementExpr(cast<ExtVectorElementExpr>(E)); case Expr::MemberExprClass: @@ -2559,6 +2561,131 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E, return LV; } +LValue CodeGenFunction::EmitOMPArraySectionExpr(const OMPArraySectionExpr *E, + bool LowerBound) { + LValue Base; + if (auto *ASE = + dyn_cast<OMPArraySectionExpr>(E->getBase()->IgnoreParenImpCasts())) + Base = EmitOMPArraySectionExpr(ASE, LowerBound); + else + Base = EmitLValue(E->getBase()); + QualType BaseTy = Base.getType(); + llvm::Value *Idx; + QualType ResultExprTy; + if (auto *AT = getContext().getAsArrayType(BaseTy)) + ResultExprTy = AT->getElementType(); + else + ResultExprTy = BaseTy->getPointeeType(); + if (LowerBound) { + Idx = E->getLowerBound() + ? Builder.CreateIntCast(EmitScalarExpr(E->getLowerBound()), + IntPtrTy, + E->getLowerBound() + ->getType() + ->hasSignedIntegerRepresentation()) + : llvm::ConstantInt::getNullValue(IntPtrTy); + } else { + auto &C = CGM.getContext(); + auto *Length = E->getLength(); + if (Length || E->getColonLoc().isInvalid()) { + // Idx = LowerBound + Length - 1; + auto *One = llvm::ConstantInt::get(IntPtrTy, /*V=*/1); + if (Length) { + Idx = Builder.CreateIntCast( + EmitScalarExpr(Length), IntPtrTy, + Length->getType()->hasSignedIntegerRepresentation()); + } + auto *LowerBound = E->getLowerBound(); + llvm::APSInt ConstLowerBound; + if (LowerBound && LowerBound->isIntegerConstantExpr(ConstLowerBound, C)) + LowerBound = nullptr; + if (LowerBound && ConstLowerBound.getZExtValue() != 0) { + auto *LowerBoundVal = Builder.CreateIntCast( + EmitScalarExpr(LowerBound), IntPtrTy, + LowerBound->getType()->hasSignedIntegerRepresentation()); + if (E->getColonLoc().isValid()) { + if (getLangOpts().isSignedOverflowDefined()) + Idx = Builder.CreateAdd(Idx, LowerBoundVal); + else + Idx = Builder.CreateNSWAdd(Idx, LowerBoundVal); + } else + Idx = LowerBoundVal; + } + if (E->getColonLoc().isValid()) { + if (getLangOpts().isSignedOverflowDefined()) + Idx = Builder.CreateSub(Idx, One); + else + Idx = Builder.CreateNSWSub(Idx, One); + } + } else if (auto *VAT = C.getAsVariableArrayType(BaseTy)) { + // Idx = ArrSize - 1; + Length = VAT->getSizeExpr(); + Idx = Builder.CreateIntCast( + EmitScalarExpr(Length), IntPtrTy, + Length->getType()->hasSignedIntegerRepresentation()); + auto *One = llvm::ConstantInt::get(IntPtrTy, /*V=*/1); + if (getLangOpts().isSignedOverflowDefined()) + Idx = Builder.CreateSub(Idx, One); + else + Idx = Builder.CreateNSWSub(Idx, One); + } else { + // Idx = ArrSize - 1; + auto *CAT = C.getAsConstantArrayType(BaseTy); + Idx = llvm::ConstantInt::get(IntPtrTy, CAT->getSize().getZExtValue() - 1); + } + } + + llvm::Value *Address; + CharUnits ArrayAlignment; + if (auto *VLA = getContext().getAsVariableArrayType(ResultExprTy)) { + // The element count here is the total number of non-VLA elements. + llvm::Value *numElements = getVLASize(VLA).first; + + // Effectively, the multiply by the VLA size is part of the GEP. + // GEP indexes are signed, and scaling an index isn't permitted to + // signed-overflow, so we use the same semantics for our explicit + // multiply. We suppress this if overflow is not undefined behavior. + if (getLangOpts().isSignedOverflowDefined()) { + Idx = Builder.CreateMul(Idx, numElements); + Address = Builder.CreateGEP(Base.getAddress(), Idx, "arrayidx"); + } else { + Idx = Builder.CreateNSWMul(Idx, numElements); + Address = Builder.CreateInBoundsGEP(Base.getAddress(), Idx, "arrayidx"); + } + } else if (BaseTy->isConstantArrayType()) { + llvm::Value *ArrayPtr = Base.getAddress(); + llvm::Value *Zero = llvm::ConstantInt::getNullValue(IntPtrTy); + llvm::Value *Args[] = {Zero, Idx}; + + // Propagate the alignment from the array itself to the result. + ArrayAlignment = Base.getAlignment(); + + if (getLangOpts().isSignedOverflowDefined()) + Address = Builder.CreateGEP(ArrayPtr, Args, "arrayidx"); + else + Address = Builder.CreateInBoundsGEP(ArrayPtr, Args, "arrayidx"); + } else { + // The base must be a pointer, which is not an aggregate. Emit it. + if (getLangOpts().isSignedOverflowDefined()) + Address = Builder.CreateGEP(Base.getAddress(), Idx, "arrayidx"); + else + Address = Builder.CreateInBoundsGEP(Base.getAddress(), Idx, "arrayidx"); + } + + // Limit the alignment to that of the result type. + LValue LV; + if (!ArrayAlignment.isZero()) { + CharUnits Align = getContext().getTypeAlignInChars(ResultExprTy); + ArrayAlignment = std::min(Align, ArrayAlignment); + LV = MakeAddrLValue(Address, ResultExprTy, ArrayAlignment); + } else + LV = MakeNaturalAlignAddrLValue(Address, ResultExprTy); + + LV.getQuals().setAddressSpace(BaseTy.getAddressSpace()); + + return LV; +} + LValue CodeGenFunction:: EmitExtVectorElementExpr(const ExtVectorElementExpr *E) { // Emit the base vector as an l-value. |