From: Chris Lattner Date: Sat, 26 Jun 2010 22:09:34 +0000 (+0000) Subject: move scalar inc/dec codegen into ScalarExprEmitter instead X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8c11a65c18ae607b7073e1e451264492d2297726;p=clang move scalar inc/dec codegen into ScalarExprEmitter instead of being in CGF. No functionality change. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@106961 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 1484334edc..2c7ea39d8b 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -385,95 +385,6 @@ void CodeGenFunction::EmitCheck(llvm::Value *Address, unsigned Size) { } -llvm::Value *CodeGenFunction:: -EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, - bool isInc, bool isPre) { - QualType ValTy = E->getSubExpr()->getType(); - llvm::Value *InVal = EmitLoadOfLValue(LV, ValTy).getScalarVal(); - - int AmountVal = isInc ? 1 : -1; - - if (ValTy->isPointerType() && - ValTy->getAs()->isVariableArrayType()) { - // The amount of the addition/subtraction needs to account for the VLA size - ErrorUnsupported(E, "VLA pointer inc/dec"); - } - - llvm::Value *NextVal; - if (const llvm::PointerType *PT = - dyn_cast(InVal->getType())) { - llvm::Constant *Inc = - llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), AmountVal); - if (!isa(PT->getElementType())) { - QualType PTEE = ValTy->getPointeeType(); - if (const ObjCObjectType *OIT = PTEE->getAs()) { - // Handle interface types, which are not represented with a concrete - // type. - int size = getContext().getTypeSize(OIT) / 8; - if (!isInc) - size = -size; - Inc = llvm::ConstantInt::get(Inc->getType(), size); - const llvm::Type *i8Ty = llvm::Type::getInt8PtrTy(VMContext); - InVal = Builder.CreateBitCast(InVal, i8Ty); - NextVal = Builder.CreateGEP(InVal, Inc, "add.ptr"); - llvm::Value *lhs = LV.getAddress(); - lhs = Builder.CreateBitCast(lhs, llvm::PointerType::getUnqual(i8Ty)); - LV = LValue::MakeAddr(lhs, MakeQualifiers(ValTy)); - } else - NextVal = Builder.CreateInBoundsGEP(InVal, Inc, "ptrincdec"); - } else { - const llvm::Type *i8Ty = llvm::Type::getInt8PtrTy(VMContext); - NextVal = Builder.CreateBitCast(InVal, i8Ty, "tmp"); - NextVal = Builder.CreateGEP(NextVal, Inc, "ptrincdec"); - NextVal = Builder.CreateBitCast(NextVal, InVal->getType()); - } - } else if (InVal->getType()->isIntegerTy(1) && isInc) { - // Bool++ is an interesting case, due to promotion rules, we get: - // Bool++ -> Bool = Bool+1 -> Bool = (int)Bool+1 -> - // Bool = ((int)Bool+1) != 0 - // An interesting aspect of this is that increment is always true. - // Decrement does not have this property. - NextVal = llvm::ConstantInt::getTrue(VMContext); - } else if (isa(InVal->getType())) { - NextVal = llvm::ConstantInt::get(InVal->getType(), AmountVal); - - // Signed integer overflow is undefined behavior. - if (ValTy->isSignedIntegerType()) - NextVal = Builder.CreateNSWAdd(InVal, NextVal, isInc ? "inc" : "dec"); - else - NextVal = Builder.CreateAdd(InVal, NextVal, isInc ? "inc" : "dec"); - } else { - // Add the inc/dec to the real part. - if (InVal->getType()->isFloatTy()) - NextVal = - llvm::ConstantFP::get(VMContext, - llvm::APFloat(static_cast(AmountVal))); - else if (InVal->getType()->isDoubleTy()) - NextVal = - llvm::ConstantFP::get(VMContext, - llvm::APFloat(static_cast(AmountVal))); - else { - llvm::APFloat F(static_cast(AmountVal)); - bool ignored; - F.convert(Target.getLongDoubleFormat(), llvm::APFloat::rmTowardZero, - &ignored); - NextVal = llvm::ConstantFP::get(VMContext, F); - } - NextVal = Builder.CreateFAdd(InVal, NextVal, isInc ? "inc" : "dec"); - } - - // Store the updated result through the lvalue. - if (LV.isBitField()) - EmitStoreThroughBitfieldLValue(RValue::get(NextVal), LV, ValTy, &NextVal); - else - EmitStoreThroughLValue(RValue::get(NextVal), LV, ValTy); - - // If this is a postinc, return the value read from memory, otherwise use the - // updated value. - return isPre ? NextVal : InVal; -} - - CodeGenFunction::ComplexPairTy CodeGenFunction:: EmitComplexPrePostIncDec(const UnaryOperator *E, LValue LV, bool isInc, bool isPre) { diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index c5bc320727..63d14f0e53 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -213,22 +213,27 @@ public: Value *VisitBlockDeclRefExpr(const BlockDeclRefExpr *E); // Unary Operators. - Value *VisitPrePostIncDec(const UnaryOperator *E, bool isInc, bool isPre) { - LValue LV = EmitLValue(E->getSubExpr()); - return CGF.EmitScalarPrePostIncDec(E, LV, isInc, isPre); - } Value *VisitUnaryPostDec(const UnaryOperator *E) { - return VisitPrePostIncDec(E, false, false); + LValue LV = EmitLValue(E->getSubExpr()); + return EmitScalarPrePostIncDec(E, LV, false, false); } Value *VisitUnaryPostInc(const UnaryOperator *E) { - return VisitPrePostIncDec(E, true, false); + LValue LV = EmitLValue(E->getSubExpr()); + return EmitScalarPrePostIncDec(E, LV, true, false); } Value *VisitUnaryPreDec(const UnaryOperator *E) { - return VisitPrePostIncDec(E, false, true); + LValue LV = EmitLValue(E->getSubExpr()); + return EmitScalarPrePostIncDec(E, LV, false, true); } Value *VisitUnaryPreInc(const UnaryOperator *E) { - return VisitPrePostIncDec(E, true, true); + LValue LV = EmitLValue(E->getSubExpr()); + return EmitScalarPrePostIncDec(E, LV, true, true); } + + llvm::Value *EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, + bool isInc, bool isPre); + + Value *VisitUnaryAddrOf(const UnaryOperator *E) { return EmitLValue(E->getSubExpr()).getAddress(); } @@ -1121,6 +1126,97 @@ Value *ScalarExprEmitter::VisitBlockDeclRefExpr(const BlockDeclRefExpr *E) { // Unary Operators //===----------------------------------------------------------------------===// +llvm::Value *ScalarExprEmitter:: +EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, + bool isInc, bool isPre) { + + QualType ValTy = E->getSubExpr()->getType(); + llvm::Value *InVal = EmitLoadOfLValue(LV, ValTy); + + int AmountVal = isInc ? 1 : -1; + + if (ValTy->isPointerType() && + ValTy->getAs()->isVariableArrayType()) { + // The amount of the addition/subtraction needs to account for the VLA size + CGF.ErrorUnsupported(E, "VLA pointer inc/dec"); + } + + llvm::Value *NextVal; + if (const llvm::PointerType *PT = + dyn_cast(InVal->getType())) { + llvm::Constant *Inc = + llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), AmountVal); + if (!isa(PT->getElementType())) { + QualType PTEE = ValTy->getPointeeType(); + if (const ObjCObjectType *OIT = PTEE->getAs()) { + // Handle interface types, which are not represented with a concrete + // type. + int size = CGF.getContext().getTypeSize(OIT) / 8; + if (!isInc) + size = -size; + Inc = llvm::ConstantInt::get(Inc->getType(), size); + const llvm::Type *i8Ty = llvm::Type::getInt8PtrTy(VMContext); + InVal = Builder.CreateBitCast(InVal, i8Ty); + NextVal = Builder.CreateGEP(InVal, Inc, "add.ptr"); + llvm::Value *lhs = LV.getAddress(); + lhs = Builder.CreateBitCast(lhs, llvm::PointerType::getUnqual(i8Ty)); + LV = LValue::MakeAddr(lhs, CGF.MakeQualifiers(ValTy)); + } else + NextVal = Builder.CreateInBoundsGEP(InVal, Inc, "ptrincdec"); + } else { + const llvm::Type *i8Ty = llvm::Type::getInt8PtrTy(VMContext); + NextVal = Builder.CreateBitCast(InVal, i8Ty, "tmp"); + NextVal = Builder.CreateGEP(NextVal, Inc, "ptrincdec"); + NextVal = Builder.CreateBitCast(NextVal, InVal->getType()); + } + } else if (InVal->getType()->isIntegerTy(1) && isInc) { + // Bool++ is an interesting case, due to promotion rules, we get: + // Bool++ -> Bool = Bool+1 -> Bool = (int)Bool+1 -> + // Bool = ((int)Bool+1) != 0 + // An interesting aspect of this is that increment is always true. + // Decrement does not have this property. + NextVal = llvm::ConstantInt::getTrue(VMContext); + } else if (isa(InVal->getType())) { + NextVal = llvm::ConstantInt::get(InVal->getType(), AmountVal); + + // Signed integer overflow is undefined behavior. + if (ValTy->isSignedIntegerType()) + NextVal = Builder.CreateNSWAdd(InVal, NextVal, isInc ? "inc" : "dec"); + else + NextVal = Builder.CreateAdd(InVal, NextVal, isInc ? "inc" : "dec"); + } else { + // Add the inc/dec to the real part. + if (InVal->getType()->isFloatTy()) + NextVal = + llvm::ConstantFP::get(VMContext, + llvm::APFloat(static_cast(AmountVal))); + else if (InVal->getType()->isDoubleTy()) + NextVal = + llvm::ConstantFP::get(VMContext, + llvm::APFloat(static_cast(AmountVal))); + else { + llvm::APFloat F(static_cast(AmountVal)); + bool ignored; + F.convert(CGF.Target.getLongDoubleFormat(), llvm::APFloat::rmTowardZero, + &ignored); + NextVal = llvm::ConstantFP::get(VMContext, F); + } + NextVal = Builder.CreateFAdd(InVal, NextVal, isInc ? "inc" : "dec"); + } + + // Store the updated result through the lvalue. + if (LV.isBitField()) + CGF.EmitStoreThroughBitfieldLValue(RValue::get(NextVal), LV, ValTy, &NextVal); + else + CGF.EmitStoreThroughLValue(RValue::get(NextVal), LV, ValTy); + + // If this is a postinc, return the value read from memory, otherwise use the + // updated value. + return isPre ? NextVal : InVal; +} + + + Value *ScalarExprEmitter::VisitUnaryMinus(const UnaryOperator *E) { TestAndClearIgnoreResultAssign(); // Emit unary minus with EmitSub so we handle overflow cases etc. @@ -2047,6 +2143,13 @@ Value *CodeGenFunction::EmitComplexToScalarConversion(ComplexPairTy Src, DstTy); } + +llvm::Value *CodeGenFunction:: +EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, + bool isInc, bool isPre) { + return ScalarExprEmitter(*this).EmitScalarPrePostIncDec(E, LV, isInc, isPre); +} + LValue CodeGenFunction::EmitObjCIsaExpr(const ObjCIsaExpr *E) { llvm::Value *V; // object->isa or (*object).isa