diff options
Diffstat (limited to 'clang/lib/CodeGen/CGExprConstant.cpp')
| -rw-r--r-- | clang/lib/CodeGen/CGExprConstant.cpp | 82 |
1 files changed, 58 insertions, 24 deletions
diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp index 353ee56839f3..604e3958161d 100644 --- a/clang/lib/CodeGen/CGExprConstant.cpp +++ b/clang/lib/CodeGen/CGExprConstant.cpp @@ -25,6 +25,7 @@ #include "clang/Basic/Builtins.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Sequence.h" +#include "llvm/Analysis/ConstantFolding.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/Function.h" @@ -934,7 +935,7 @@ tryEmitGlobalCompoundLiteral(ConstantEmitter &emitter, auto GV = new llvm::GlobalVariable( CGM.getModule(), C->getType(), - CGM.isTypeConstant(E->getType(), true, false), + E->getType().isConstantStorage(CGM.getContext(), true, false), llvm::GlobalValue::InternalLinkage, C, ".compoundliteral", nullptr, llvm::GlobalVariable::NotThreadLocal, CGM.getContext().getTargetAddressSpace(addressSpace)); @@ -1127,9 +1128,36 @@ public: case CK_ConstructorConversion: return Visit(subExpr, destType); + case CK_ArrayToPointerDecay: + if (const auto *S = dyn_cast<StringLiteral>(subExpr)) + return CGM.GetAddrOfConstantStringFromLiteral(S).getPointer(); + return nullptr; + case CK_NullToPointer: + if (Visit(subExpr, destType)) + return CGM.EmitNullConstant(destType); + return nullptr; + case CK_IntToOCLSampler: llvm_unreachable("global sampler variables are not generated"); + case CK_IntegralCast: { + QualType FromType = subExpr->getType(); + // See also HandleIntToIntCast in ExprConstant.cpp + if (FromType->isIntegerType()) + if (llvm::Constant *C = Visit(subExpr, FromType)) + if (auto *CI = dyn_cast<llvm::ConstantInt>(C)) { + unsigned SrcWidth = CGM.getContext().getIntWidth(FromType); + unsigned DstWidth = CGM.getContext().getIntWidth(destType); + if (DstWidth == SrcWidth) + return CI; + llvm::APInt A = FromType->isSignedIntegerType() + ? CI->getValue().sextOrTrunc(DstWidth) + : CI->getValue().zextOrTrunc(DstWidth); + return llvm::ConstantInt::get(CGM.getLLVMContext(), A); + } + return nullptr; + } + case CK_Dependent: llvm_unreachable("saw dependent cast!"); case CK_BuiltinFnToFnPtr: @@ -1164,7 +1192,6 @@ public: case CK_CPointerToObjCPointerCast: case CK_BlockPointerToObjCPointerCast: case CK_AnyPointerToBlockPointerCast: - case CK_ArrayToPointerDecay: case CK_FunctionToPointerDecay: case CK_BaseToDerived: case CK_DerivedToBase: @@ -1183,8 +1210,6 @@ public: case CK_IntegralComplexToFloatingComplex: case CK_PointerToIntegral: case CK_PointerToBoolean: - case CK_NullToPointer: - case CK_IntegralCast: case CK_BooleanToSignedIntegral: case CK_IntegralToPointer: case CK_IntegralToBoolean: @@ -1215,6 +1240,10 @@ public: return Visit(E->getSubExpr(), T); } + llvm::Constant *VisitIntegerLiteral(IntegerLiteral *I, QualType T) { + return llvm::ConstantInt::get(CGM.getLLVMContext(), I->getValue()); + } + llvm::Constant *EmitArrayInitialization(InitListExpr *ILE, QualType T) { auto *CAT = CGM.getContext().getAsConstantArrayType(ILE->getType()); assert(CAT && "can't emit array init for non-constant-bound array"); @@ -1352,6 +1381,13 @@ public: return Visit(E->getSubExpr(), T); } + llvm::Constant *VisitUnaryMinus(UnaryOperator *U, QualType T) { + if (llvm::Constant *C = Visit(U->getSubExpr(), T)) + if (auto *CI = dyn_cast<llvm::ConstantInt>(C)) + return llvm::ConstantInt::get(CGM.getLLVMContext(), -CI->getValue()); + return nullptr; + } + // Utility methods llvm::Type *ConvertType(QualType T) { return CGM.getTypes().ConvertType(T); @@ -1594,13 +1630,8 @@ namespace { IndexValues[i] = llvm::ConstantInt::get(CGM.Int32Ty, Indices[i]); } - // Form a GEP and then bitcast to the placeholder type so that the - // replacement will succeed. - llvm::Constant *location = - llvm::ConstantExpr::getInBoundsGetElementPtr(BaseValueTy, - Base, IndexValues); - location = llvm::ConstantExpr::getBitCast(location, - placeholder->getType()); + llvm::Constant *location = llvm::ConstantExpr::getInBoundsGetElementPtr( + BaseValueTy, Base, IndexValues); Locations.insert({placeholder, location}); } @@ -1726,7 +1757,10 @@ llvm::Constant *ConstantEmitter::emitForMemory(CodeGenModule &CGM, // Zero-extend bool. if (C->getType()->isIntegerTy(1) && !destType->isBitIntType()) { llvm::Type *boolTy = CGM.getTypes().ConvertTypeForMem(destType); - return llvm::ConstantExpr::getZExt(C, boolTy); + llvm::Constant *Res = llvm::ConstantFoldCastOperand( + llvm::Instruction::ZExt, C, boolTy, CGM.getDataLayout()); + assert(Res && "Constant folding must succeed"); + return Res; } return C; @@ -1736,9 +1770,10 @@ llvm::Constant *ConstantEmitter::tryEmitPrivate(const Expr *E, QualType destType) { assert(!destType->isVoidType() && "can't emit a void constant"); - if (llvm::Constant *C = - ConstExprEmitter(*this).Visit(const_cast<Expr *>(E), destType)) - return C; + if (!destType->isReferenceType()) + if (llvm::Constant *C = + ConstExprEmitter(*this).Visit(const_cast<Expr *>(E), destType)) + return C; Expr::EvalResult Result; @@ -1826,10 +1861,7 @@ private: if (!hasNonZeroOffset()) return C; - llvm::Type *origPtrTy = C->getType(); - C = llvm::ConstantExpr::getGetElementPtr(CGM.Int8Ty, C, getOffset()); - C = llvm::ConstantExpr::getPointerCast(C, origPtrTy); - return C; + return llvm::ConstantExpr::getGetElementPtr(CGM.Int8Ty, C, getOffset()); } }; @@ -1890,8 +1922,9 @@ ConstantLValueEmitter::tryEmitAbsolute(llvm::Type *destTy) { // FIXME: signedness depends on the original integer type. auto intptrTy = CGM.getDataLayout().getIntPtrType(destPtrTy); llvm::Constant *C; - C = llvm::ConstantExpr::getIntegerCast(getOffset(), intptrTy, - /*isSigned*/ false); + C = llvm::ConstantFoldIntegerCast(getOffset(), intptrTy, /*isSigned*/ false, + CGM.getDataLayout()); + assert(C && "Must have folded, as Offset is a ConstantInt"); C = llvm::ConstantExpr::getIntToPtr(C, destPtrTy); return C; } @@ -1918,7 +1951,7 @@ ConstantLValueEmitter::tryEmitBase(const APValue::LValueBase &base) { if (VD->isLocalVarDecl()) { return CGM.getOrCreateStaticVarDecl( - *VD, CGM.getLLVMLinkageVarDefinition(VD, /*IsConstant=*/false)); + *VD, CGM.getLLVMLinkageVarDefinition(VD)); } } } @@ -1996,8 +2029,6 @@ ConstantLValue ConstantLValueEmitter::VisitAddrLabelExpr(const AddrLabelExpr *E) { assert(Emitter.CGF && "Invalid address of label expression outside function"); llvm::Constant *Ptr = Emitter.CGF->GetAddrOfLabel(E->getLabel()); - Ptr = llvm::ConstantExpr::getBitCast(Ptr, - CGM.getTypes().ConvertType(E->getType())); return Ptr; } @@ -2112,6 +2143,9 @@ llvm::Constant *ConstantEmitter::tryEmitPrivate(const APValue &Value, Inits[I] = llvm::ConstantInt::get(CGM.getLLVMContext(), Elt.getInt()); else if (Elt.isFloat()) Inits[I] = llvm::ConstantFP::get(CGM.getLLVMContext(), Elt.getFloat()); + else if (Elt.isIndeterminate()) + Inits[I] = llvm::UndefValue::get(CGM.getTypes().ConvertType( + DestType->castAs<VectorType>()->getElementType())); else llvm_unreachable("unsupported vector element type"); } |
