From 47fb9508714ba52bfb996f7490ce0df3ca52ce88 Mon Sep 17 00:00:00 2001 From: John McCall Date: Thu, 7 Mar 2013 21:37:08 +0000 Subject: [PATCH] Change hasAggregateLLVMType, which conflates complex and aggregate types in a profoundly wrong way that has to be worked around in every call site, to getEvaluationKind, which classifies and distinguishes between all of these cases. Also, normalize the API for loading and storing complexes. I'm working on a larger patch and wanted to pull these changes out, but it would have be annoying to detangle them from each other. llvm-svn: 176656 --- clang/lib/CodeGen/CGBuiltin.cpp | 4 +- clang/lib/CodeGen/CGCall.cpp | 124 ++++++++++++------------- clang/lib/CodeGen/CGClass.cpp | 28 +++--- clang/lib/CodeGen/CGCleanup.cpp | 12 ++- clang/lib/CodeGen/CGDecl.cpp | 18 ++-- clang/lib/CodeGen/CGDeclCXX.cpp | 14 ++- clang/lib/CodeGen/CGException.cpp | 33 ++++--- clang/lib/CodeGen/CGExpr.cpp | 164 +++++++++++++++++++--------------- clang/lib/CodeGen/CGExprAgg.cpp | 34 ++++--- clang/lib/CodeGen/CGExprCXX.cpp | 17 ++-- clang/lib/CodeGen/CGExprComplex.cpp | 114 ++++++++++++----------- clang/lib/CodeGen/CGExprScalar.cpp | 8 +- clang/lib/CodeGen/CGObjC.cpp | 21 +++-- clang/lib/CodeGen/CGStmt.cpp | 38 +++++--- clang/lib/CodeGen/CGVTables.cpp | 2 +- clang/lib/CodeGen/CGValue.h | 4 +- clang/lib/CodeGen/CodeGenFunction.cpp | 70 ++++++++------- clang/lib/CodeGen/CodeGenFunction.h | 40 ++++++--- clang/lib/CodeGen/TargetInfo.cpp | 2 +- 19 files changed, 425 insertions(+), 322 deletions(-) diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index f55a8e5..8a69e8a 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -1496,9 +1496,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, ErrorUnsupported(E, "builtin function"); // Unknown builtin, for now just dump it out and return undef. - if (hasAggregateLLVMType(E->getType())) - return RValue::getAggregate(CreateMemTemp(E->getType())); - return RValue::get(llvm::UndefValue::get(ConvertType(E->getType()))); + return GetUndefRValue(E->getType()); } Value *CodeGenFunction::EmitTargetBuiltinExpr(unsigned BuiltinID, diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 6aabd64..b6ec67d 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -1278,7 +1278,7 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI, case ABIArgInfo::Indirect: { llvm::Value *V = AI; - if (hasAggregateLLVMType(Ty)) { + if (!hasScalarEvaluationKind(Ty)) { // Aggregates and complex variables are accessed by reference. All we // need to do is realign the value, if requested if (ArgI.getIndirectRealign()) { @@ -1411,7 +1411,7 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI, // Match to what EmitParmDecl is expecting for this type. - if (!CodeGenFunction::hasAggregateLLVMType(Ty)) { + if (CodeGenFunction::hasScalarEvaluationKind(Ty)) { V = EmitLoadOfScalar(V, false, AlignmentToUse, Ty); if (isPromoted) V = emitArgumentDemotion(*this, Arg, V); @@ -1440,7 +1440,7 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI, case ABIArgInfo::Ignore: // Initialize the local variable appropriately. - if (hasAggregateLLVMType(Ty)) + if (!hasScalarEvaluationKind(Ty)) EmitParmDecl(*Arg, CreateMemTemp(Ty), ArgNo); else EmitParmDecl(*Arg, llvm::UndefValue::get(ConvertType(Arg->getType())), @@ -1664,15 +1664,23 @@ void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI) { switch (RetAI.getKind()) { case ABIArgInfo::Indirect: { - unsigned Alignment = getContext().getTypeAlignInChars(RetTy).getQuantity(); - if (RetTy->isAnyComplexType()) { - ComplexPairTy RT = LoadComplexFromAddr(ReturnValue, false); - StoreComplexToAddr(RT, CurFn->arg_begin(), false); - } else if (CodeGenFunction::hasAggregateLLVMType(RetTy)) { + switch (getEvaluationKind(RetTy)) { + case TEK_Complex: { + ComplexPairTy RT = + EmitLoadOfComplex(MakeNaturalAlignAddrLValue(ReturnValue, RetTy)); + EmitStoreOfComplex(RT, + MakeNaturalAlignAddrLValue(CurFn->arg_begin(), RetTy), + /*isInit*/ true); + break; + } + case TEK_Aggregate: // Do nothing; aggregrates get evaluated directly into the destination. - } else { - EmitStoreOfScalar(Builder.CreateLoad(ReturnValue), CurFn->arg_begin(), - false, Alignment, RetTy); + break; + case TEK_Scalar: + EmitStoreOfScalar(Builder.CreateLoad(ReturnValue), + MakeNaturalAlignAddrLValue(CurFn->arg_begin(), RetTy), + /*isInit*/ true); + break; } break; } @@ -1749,10 +1757,10 @@ void CodeGenFunction::EmitDelegateCallArg(CallArgList &args, // For the most part, we just need to load the alloca, except: // 1) aggregate r-values are actually pointers to temporaries, and - // 2) references to aggregates are pointers directly to the aggregate. - // I don't know why references to non-aggregates are different here. + // 2) references to non-scalars are pointers directly to the aggregate. + // I don't know why references to scalars are different here. if (const ReferenceType *ref = type->getAs()) { - if (hasAggregateLLVMType(ref->getPointeeType())) + if (!hasScalarEvaluationKind(ref->getPointeeType())) return args.add(RValue::getAggregate(local), type); // Locals which are references to scalars are represented @@ -1760,17 +1768,7 @@ void CodeGenFunction::EmitDelegateCallArg(CallArgList &args, return args.add(RValue::get(Builder.CreateLoad(local)), type); } - if (type->isAnyComplexType()) { - ComplexPairTy complex = LoadComplexFromAddr(local, /*volatile*/ false); - return args.add(RValue::getComplex(complex), type); - } - - if (hasAggregateLLVMType(type)) - return args.add(RValue::getAggregate(local), type); - - unsigned alignment = getContext().getDeclAlign(param).getQuantity(); - llvm::Value *value = EmitLoadOfScalar(local, false, alignment, type); - return args.add(RValue::get(value), type); + args.add(convertTempToRValue(local, type), type); } static bool isProvablyNull(llvm::Value *addr) { @@ -1935,7 +1933,7 @@ void CodeGenFunction::EmitCallArg(CallArgList &args, const Expr *E, type); } - if (hasAggregateLLVMType(type) && !E->getType()->isAnyComplexType() && + if (hasAggregateEvaluationKind(type) && isa(E) && cast(E)->getCastKind() == CK_LValueToRValue) { LValue L = EmitLValue(cast(E)->getSubExpr()); @@ -2079,15 +2077,7 @@ void CodeGenFunction::ExpandTypeToArgs(QualType Ty, RValue RV, llvm::Value *Addr = RV.getAggregateAddr(); for (unsigned Elt = 0; Elt < NumElts; ++Elt) { llvm::Value *EltAddr = Builder.CreateConstGEP2_32(Addr, 0, Elt); - LValue LV = MakeAddrLValue(EltAddr, EltTy); - RValue EltRV; - if (EltTy->isAnyComplexType()) - // FIXME: Volatile? - EltRV = RValue::getComplex(LoadComplexFromAddr(LV.getAddress(), false)); - else if (CodeGenFunction::hasAggregateLLVMType(EltTy)) - EltRV = LV.asAggregateRValue(); - else - EltRV = EmitLoadOfLValue(LV); + RValue EltRV = convertTempToRValue(EltAddr, EltTy); ExpandTypeToArgs(EltTy, EltRV, Args, IRFuncTy); } } else if (const RecordType *RT = Ty->getAs()) { @@ -2180,8 +2170,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, const ABIArgInfo &ArgInfo = info_it->info; RValue RV = I->RV; - unsigned TypeAlign = - getContext().getTypeAlignInChars(I->Ty).getQuantity(); + CharUnits TypeAlign = getContext().getTypeAlignInChars(I->Ty); // Insert a padding argument to ensure proper alignment. if (llvm::Type *PaddingType = ArgInfo.getPaddingType()) { @@ -2197,12 +2186,14 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, if (ArgInfo.getIndirectAlign() > AI->getAlignment()) AI->setAlignment(ArgInfo.getIndirectAlign()); Args.push_back(AI); + + LValue argLV = + MakeAddrLValue(Args.back(), I->Ty, TypeAlign); if (RV.isScalar()) - EmitStoreOfScalar(RV.getScalarVal(), Args.back(), false, - TypeAlign, I->Ty); + EmitStoreOfScalar(RV.getScalarVal(), argLV, /*init*/ true); else - StoreComplexToAddr(RV.getComplexVal(), Args.back(), false); + EmitStoreOfComplex(RV.getComplexVal(), argLV, /*init*/ true); // Validate argument match. checkArgMatches(AI, IRArgNo, IRFuncTy); @@ -2217,7 +2208,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, unsigned Align = ArgInfo.getIndirectAlign(); const llvm::DataLayout *TD = &CGM.getDataLayout(); if ((!ArgInfo.getIndirectByVal() && I->NeedsCopy) || - (ArgInfo.getIndirectByVal() && TypeAlign < Align && + (ArgInfo.getIndirectByVal() && TypeAlign.getQuantity() < Align && llvm::getOrEnforceKnownAlignment(Addr, Align, TD) < Align)) { // Create an aligned temporary, and copy to it. llvm::AllocaInst *AI = CreateMemTemp(I->Ty); @@ -2266,12 +2257,14 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, // FIXME: Avoid the conversion through memory if possible. llvm::Value *SrcPtr; - if (RV.isScalar()) { - SrcPtr = CreateMemTemp(I->Ty, "coerce"); - EmitStoreOfScalar(RV.getScalarVal(), SrcPtr, false, TypeAlign, I->Ty); - } else if (RV.isComplex()) { + if (RV.isScalar() || RV.isComplex()) { SrcPtr = CreateMemTemp(I->Ty, "coerce"); - StoreComplexToAddr(RV.getComplexVal(), SrcPtr, false); + LValue SrcLV = MakeAddrLValue(SrcPtr, I->Ty, TypeAlign); + if (RV.isScalar()) { + EmitStoreOfScalar(RV.getScalarVal(), SrcLV, /*init*/ true); + } else { + EmitStoreOfComplex(RV.getComplexVal(), SrcLV, /*init*/ true); + } } else SrcPtr = RV.getAggregateAddr(); @@ -2424,14 +2417,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, emitWritebacks(*this, CallArgs); switch (RetAI.getKind()) { - case ABIArgInfo::Indirect: { - unsigned Alignment = getContext().getTypeAlignInChars(RetTy).getQuantity(); - if (RetTy->isAnyComplexType()) - return RValue::getComplex(LoadComplexFromAddr(Args[0], false)); - if (CodeGenFunction::hasAggregateLLVMType(RetTy)) - return RValue::getAggregate(Args[0]); - return RValue::get(EmitLoadOfScalar(Args[0], false, Alignment, RetTy)); - } + case ABIArgInfo::Indirect: + return convertTempToRValue(Args[0], RetTy); case ABIArgInfo::Ignore: // If we are ignoring an argument that had a result, make sure to @@ -2442,12 +2429,13 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, case ABIArgInfo::Direct: { llvm::Type *RetIRTy = ConvertType(RetTy); if (RetAI.getCoerceToType() == RetIRTy && RetAI.getDirectOffset() == 0) { - if (RetTy->isAnyComplexType()) { + switch (getEvaluationKind(RetTy)) { + case TEK_Complex: { llvm::Value *Real = Builder.CreateExtractValue(CI, 0); llvm::Value *Imag = Builder.CreateExtractValue(CI, 1); return RValue::getComplex(std::make_pair(Real, Imag)); } - if (CodeGenFunction::hasAggregateLLVMType(RetTy)) { + case TEK_Aggregate: { llvm::Value *DestPtr = ReturnValue.getValue(); bool DestIsVolatile = ReturnValue.isVolatile(); @@ -2458,13 +2446,16 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, BuildAggStore(*this, CI, DestPtr, DestIsVolatile, false); return RValue::getAggregate(DestPtr); } - - // If the argument doesn't match, perform a bitcast to coerce it. This - // can happen due to trivial type mismatches. - llvm::Value *V = CI; - if (V->getType() != RetIRTy) - V = Builder.CreateBitCast(V, RetIRTy); - return RValue::get(V); + case TEK_Scalar: { + // If the argument doesn't match, perform a bitcast to coerce it. This + // can happen due to trivial type mismatches. + llvm::Value *V = CI; + if (V->getType() != RetIRTy) + V = Builder.CreateBitCast(V, RetIRTy); + return RValue::get(V); + } + } + llvm_unreachable("bad evaluation kind"); } llvm::Value *DestPtr = ReturnValue.getValue(); @@ -2485,12 +2476,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, } CreateCoercedStore(CI, StorePtr, DestIsVolatile, *this); - unsigned Alignment = getContext().getTypeAlignInChars(RetTy).getQuantity(); - if (RetTy->isAnyComplexType()) - return RValue::getComplex(LoadComplexFromAddr(DestPtr, false)); - if (CodeGenFunction::hasAggregateLLVMType(RetTy)) - return RValue::getAggregate(DestPtr); - return RValue::get(EmitLoadOfScalar(DestPtr, false, Alignment, RetTy)); + return convertTempToRValue(DestPtr, RetTy); } case ABIArgInfo::Expand: diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index 4319e43..287d164 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -451,12 +451,14 @@ static void EmitAggMemberInitializer(CodeGenFunction &CGF, LV.setAlignment(std::min(Align, LV.getAlignment())); } - if (!CGF.hasAggregateLLVMType(T)) { + switch (CGF.getEvaluationKind(T)) { + case TEK_Scalar: CGF.EmitScalarInit(Init, /*decl*/ 0, LV, false); - } else if (T->isAnyComplexType()) { - CGF.EmitComplexExprIntoAddr(Init, LV.getAddress(), - LV.isVolatileQualified()); - } else { + break; + case TEK_Complex: + CGF.EmitComplexExprIntoLValue(Init, LV, /*isInit*/ true); + break; + case TEK_Aggregate: { AggValueSlot Slot = AggValueSlot::forLValue(LV, AggValueSlot::IsDestructed, @@ -464,6 +466,8 @@ static void EmitAggMemberInitializer(CodeGenFunction &CGF, AggValueSlot::IsNotAliased); CGF.EmitAggExpr(Init, Slot); + break; + } } } @@ -600,16 +604,19 @@ void CodeGenFunction::EmitInitializerForField(FieldDecl *Field, LValue LHS, Expr *Init, ArrayRef ArrayIndexes) { QualType FieldType = Field->getType(); - if (!hasAggregateLLVMType(FieldType)) { + switch (getEvaluationKind(FieldType)) { + case TEK_Scalar: if (LHS.isSimple()) { EmitExprAsInit(Init, Field, LHS, false); } else { RValue RHS = RValue::get(EmitScalarExpr(Init)); EmitStoreThroughLValue(RHS, LHS); } - } else if (FieldType->isAnyComplexType()) { - EmitComplexExprIntoAddr(Init, LHS.getAddress(), LHS.isVolatileQualified()); - } else { + break; + case TEK_Complex: + EmitComplexExprIntoLValue(Init, LHS, /*isInit*/ true); + break; + case TEK_Aggregate: { llvm::Value *ArrayIndexVar = 0; if (ArrayIndexes.size()) { llvm::Type *SizeTy = ConvertType(getContext().getSizeType()); @@ -638,6 +645,7 @@ void CodeGenFunction::EmitInitializerForField(FieldDecl *Field, EmitAggMemberInitializer(*this, LHS, Init, ArrayIndexVar, FieldType, ArrayIndexes, 0); } + } // Ensure that we destroy this object if an exception is thrown // later in the constructor. @@ -2173,7 +2181,7 @@ void CodeGenFunction::EmitForwardingCallToLambda(const CXXRecordDecl *lambda, ReturnValueSlot returnSlot; if (!resultType->isVoidType() && calleeFnInfo.getReturnInfo().getKind() == ABIArgInfo::Indirect && - hasAggregateLLVMType(calleeFnInfo.getReturnType())) + !hasScalarEvaluationKind(calleeFnInfo.getReturnType())) returnSlot = ReturnValueSlot(ReturnValue, resultType.isVolatileQualified()); // We don't need to separately arrange the call arguments because diff --git a/clang/lib/CodeGen/CGCleanup.cpp b/clang/lib/CodeGen/CGCleanup.cpp index f9ea7e0..861d31f 100644 --- a/clang/lib/CodeGen/CGCleanup.cpp +++ b/clang/lib/CodeGen/CGCleanup.cpp @@ -52,7 +52,8 @@ DominatingValue::saved_type::save(CodeGenFunction &CGF, RValue rv) { llvm::StructType::get(V.first->getType(), V.second->getType(), (void*) 0); llvm::Value *addr = CGF.CreateTempAlloca(ComplexTy, "saved-complex"); - CGF.StoreComplexToAddr(V, addr, /*volatile*/ false); + CGF.Builder.CreateStore(V.first, CGF.Builder.CreateStructGEP(addr, 0)); + CGF.Builder.CreateStore(V.second, CGF.Builder.CreateStructGEP(addr, 1)); return saved_type(addr, ComplexAddress); } @@ -79,8 +80,13 @@ RValue DominatingValue::saved_type::restore(CodeGenFunction &CGF) { return RValue::getAggregate(Value); case AggregateAddress: return RValue::getAggregate(CGF.Builder.CreateLoad(Value)); - case ComplexAddress: - return RValue::getComplex(CGF.LoadComplexFromAddr(Value, false)); + case ComplexAddress: { + llvm::Value *real = + CGF.Builder.CreateLoad(CGF.Builder.CreateStructGEP(Value, 0)); + llvm::Value *imag = + CGF.Builder.CreateLoad(CGF.Builder.CreateStructGEP(Value, 1)); + return RValue::getComplex(real, imag); + } } llvm_unreachable("bad saved r-value kind"); diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index 9c52314..bb5d638 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -1115,21 +1115,29 @@ void CodeGenFunction::EmitExprAsInit(const Expr *init, if (capturedByInit) drillIntoBlockVariable(*this, lvalue, cast(D)); EmitStoreThroughLValue(rvalue, lvalue, true); - } else if (!hasAggregateLLVMType(type)) { + return; + } + switch (getEvaluationKind(type)) { + case TEK_Scalar: EmitScalarInit(init, D, lvalue, capturedByInit); - } else if (type->isAnyComplexType()) { + return; + case TEK_Complex: { ComplexPairTy complex = EmitComplexExpr(init); if (capturedByInit) drillIntoBlockVariable(*this, lvalue, cast(D)); - StoreComplexToAddr(complex, lvalue.getAddress(), lvalue.isVolatile()); - } else { + EmitStoreOfComplex(complex, lvalue, /*init*/ true); + return; + } + case TEK_Aggregate: // TODO: how can we delay here if D is captured by its initializer? EmitAggExpr(init, AggValueSlot::forLValue(lvalue, AggValueSlot::IsDestructed, AggValueSlot::DoesNotNeedGCBarriers, AggValueSlot::IsNotAliased)); MaybeEmitStdInitializerListCleanup(lvalue.getAddress(), init); + return; } + llvm_unreachable("bad evaluation kind"); } /// Enter a destroy cleanup for the given local variable. @@ -1521,7 +1529,7 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, llvm::Value *Arg, llvm::Value *DeclPtr; // If this is an aggregate or variable sized value, reuse the input pointer. if (!Ty->isConstantSizeType() || - CodeGenFunction::hasAggregateLLVMType(Ty)) { + !CodeGenFunction::hasScalarEvaluationKind(Ty)) { DeclPtr = Arg; } else { // Otherwise, create a temporary to hold the value. diff --git a/clang/lib/CodeGen/CGDeclCXX.cpp b/clang/lib/CodeGen/CGDeclCXX.cpp index 9b6c5d7..0448d31 100644 --- a/clang/lib/CodeGen/CGDeclCXX.cpp +++ b/clang/lib/CodeGen/CGDeclCXX.cpp @@ -34,7 +34,8 @@ static void EmitDeclInit(CodeGenFunction &CGF, const VarDecl &D, LValue lv = CGF.MakeAddrLValue(DeclPtr, type, alignment); const Expr *Init = D.getInit(); - if (!CGF.hasAggregateLLVMType(type)) { + switch (CGF.getEvaluationKind(type)) { + case TEK_Scalar: { CodeGenModule &CGM = CGF.CGM; if (lv.isObjCStrong()) CGM.getObjCRuntime().EmitObjCGlobalAssign(CGF, CGF.EmitScalarExpr(Init), @@ -44,13 +45,18 @@ static void EmitDeclInit(CodeGenFunction &CGF, const VarDecl &D, DeclPtr); else CGF.EmitScalarInit(Init, &D, lv, false); - } else if (type->isAnyComplexType()) { - CGF.EmitComplexExprIntoAddr(Init, DeclPtr, lv.isVolatile()); - } else { + return; + } + case TEK_Complex: + CGF.EmitComplexExprIntoLValue(Init, lv, /*isInit*/ true); + return; + case TEK_Aggregate: CGF.EmitAggExpr(Init, AggValueSlot::forLValue(lv,AggValueSlot::IsDestructed, AggValueSlot::DoesNotNeedGCBarriers, AggValueSlot::IsNotAliased)); + return; } + llvm_unreachable("bad evaluation kind"); } /// Emit code to cause the destruction of the given variable with diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp index 9794ca4..36642bc 100644 --- a/clang/lib/CodeGen/CGException.cpp +++ b/clang/lib/CodeGen/CGException.cpp @@ -1002,10 +1002,9 @@ static void InitCatchParam(CodeGenFunction &CGF, return; } - // Non-aggregates (plus complexes). - bool IsComplex = false; - if (!CGF.hasAggregateLLVMType(CatchType) || - (IsComplex = CatchType->isAnyComplexType())) { + // Scalars and complexes. + TypeEvaluationKind TEK = CGF.getEvaluationKind(CatchType); + if (TEK != TEK_Aggregate) { llvm::Value *AdjustedExn = CallBeginCatch(CGF, Exn, false); // If the catch type is a pointer type, __cxa_begin_catch returns @@ -1037,17 +1036,23 @@ static void InitCatchParam(CodeGenFunction &CGF, llvm::Type *PtrTy = LLVMCatchTy->getPointerTo(0); // addrspace 0 ok llvm::Value *Cast = CGF.Builder.CreateBitCast(AdjustedExn, PtrTy); - if (IsComplex) { - CGF.StoreComplexToAddr(CGF.LoadComplexFromAddr(Cast, /*volatile*/ false), - ParamAddr, /*volatile*/ false); - } else { - unsigned Alignment = - CGF.getContext().getDeclAlign(&CatchParam).getQuantity(); - llvm::Value *ExnLoad = CGF.Builder.CreateLoad(Cast, "exn.scalar"); - CGF.EmitStoreOfScalar(ExnLoad, ParamAddr, /*volatile*/ false, Alignment, - CatchType); + LValue srcLV = CGF.MakeNaturalAlignAddrLValue(Cast, CatchType); + LValue destLV = CGF.MakeAddrLValue(ParamAddr, CatchType, + CGF.getContext().getDeclAlign(&CatchParam)); + switch (TEK) { + case TEK_Complex: + CGF.EmitStoreOfComplex(CGF.EmitLoadOfComplex(srcLV), destLV, + /*init*/ true); + return; + case TEK_Scalar: { + llvm::Value *ExnLoad = CGF.EmitLoadOfScalar(srcLV); + CGF.EmitStoreOfScalar(ExnLoad, destLV, /*init*/ true); + return; } - return; + case TEK_Aggregate: + llvm_unreachable("evaluation kind filtered out!"); + } + llvm_unreachable("bad evaluation kind"); } assert(isa(CatchType) && "unexpected catch type!"); diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 9b3638a..21cb08d 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -114,15 +114,18 @@ void CodeGenFunction::EmitIgnoredExpr(const Expr *E) { RValue CodeGenFunction::EmitAnyExpr(const Expr *E, AggValueSlot aggSlot, bool ignoreResult) { - if (!hasAggregateLLVMType(E->getType())) + switch (getEvaluationKind(E->getType())) { + case TEK_Scalar: return RValue::get(EmitScalarExpr(E, ignoreResult)); - else if (E->getType()->isAnyComplexType()) + case TEK_Complex: return RValue::getComplex(EmitComplexExpr(E, ignoreResult, ignoreResult)); - - if (!ignoreResult && aggSlot.isIgnored()) - aggSlot = CreateAggTemp(E->getType(), "agg-temp"); - EmitAggExpr(E, aggSlot); - return aggSlot.asRValue(); + case TEK_Aggregate: + if (!ignoreResult && aggSlot.isIgnored()) + aggSlot = CreateAggTemp(E->getType(), "agg-temp"); + EmitAggExpr(E, aggSlot); + return aggSlot.asRValue(); + } + llvm_unreachable("bad evaluation kind"); } /// EmitAnyExprToTemp - Similary to EmitAnyExpr(), however, the result will @@ -130,8 +133,7 @@ RValue CodeGenFunction::EmitAnyExpr(const Expr *E, RValue CodeGenFunction::EmitAnyExprToTemp(const Expr *E) { AggValueSlot AggSlot = AggValueSlot::ignored(); - if (hasAggregateLLVMType(E->getType()) && - !E->getType()->isAnyComplexType()) + if (hasAggregateEvaluationKind(E->getType())) AggSlot = CreateAggTemp(E->getType(), "agg.tmp"); return EmitAnyExpr(E, AggSlot); } @@ -143,19 +145,30 @@ void CodeGenFunction::EmitAnyExprToMem(const Expr *E, Qualifiers Quals, bool IsInit) { // FIXME: This function should take an LValue as an argument. - if (E->getType()->isAnyComplexType()) { - EmitComplexExprIntoAddr(E, Location, Quals.hasVolatile()); - } else if (hasAggregateLLVMType(E->getType())) { + switch (getEvaluationKind(E->getType())) { + case TEK_Complex: + EmitComplexExprIntoLValue(E, + MakeNaturalAlignAddrLValue(Location, E->getType()), + /*isInit*/ false); + return; + + case TEK_Aggregate: { CharUnits Alignment = getContext().getTypeAlignInChars(E->getType()); EmitAggExpr(E, AggValueSlot::forAddr(Location, Alignment, Quals, AggValueSlot::IsDestructed_t(IsInit), AggValueSlot::DoesNotNeedGCBarriers, AggValueSlot::IsAliased_t(!IsInit))); - } else { + return; + } + + case TEK_Scalar: { RValue RV = RValue::get(EmitScalarExpr(E, /*Ignore*/ false)); LValue LV = MakeAddrLValue(Location, E->getType()); EmitStoreThroughLValue(RV, LV); + return; } + } + llvm_unreachable("bad evaluation kind"); } static llvm::Value * @@ -288,8 +301,7 @@ EmitExprForReferenceBinding(CodeGenFunction &CGF, const Expr *E, // Create a reference temporary if necessary. AggValueSlot AggSlot = AggValueSlot::ignored(); - if (CGF.hasAggregateLLVMType(E->getType()) && - !E->getType()->isAnyComplexType()) { + if (CGF.hasAggregateEvaluationKind(E->getType())) { ReferenceTemporary = CreateReferenceTemporary(CGF, E->getType(), InitializedDecl); CharUnits Alignment = CGF.getContext().getTypeAlignInChars(E->getType()); @@ -370,14 +382,12 @@ EmitExprForReferenceBinding(CodeGenFunction &CGF, const Expr *E, InitializedDecl); - unsigned Alignment = - CGF.getContext().getTypeAlignInChars(E->getType()).getQuantity(); + LValue tempLV = CGF.MakeNaturalAlignAddrLValue(ReferenceTemporary, + E->getType()); if (RV.isScalar()) - CGF.EmitStoreOfScalar(RV.getScalarVal(), ReferenceTemporary, - /*Volatile=*/false, Alignment, E->getType()); + CGF.EmitStoreOfScalar(RV.getScalarVal(), tempLV, /*init*/ true); else - CGF.StoreComplexToAddr(RV.getComplexVal(), ReferenceTemporary, - /*Volatile=*/false); + CGF.EmitStoreOfComplex(RV.getComplexVal(), tempLV, /*init*/ true); return ReferenceTemporary; } @@ -713,8 +723,7 @@ void CodeGenFunction::EmitBoundsCheck(const Expr *E, const Expr *Base, CodeGenFunction::ComplexPairTy CodeGenFunction:: EmitComplexPrePostIncDec(const UnaryOperator *E, LValue LV, bool isInc, bool isPre) { - ComplexPairTy InVal = LoadComplexFromAddr(LV.getAddress(), - LV.isVolatileQualified()); + ComplexPairTy InVal = EmitLoadOfComplex(LV); llvm::Value *NextVal; if (isa(InVal.first->getType())) { @@ -737,7 +746,7 @@ EmitComplexPrePostIncDec(const UnaryOperator *E, LValue LV, ComplexPairTy IncVal(NextVal, InVal.second); // Store the updated result through the lvalue. - StoreComplexToAddr(IncVal, LV.getAddress(), LV.isVolatileQualified()); + EmitStoreOfComplex(IncVal, LV, /*init*/ false); // If this is a postinc, return the value read from memory, otherwise use the // updated value. @@ -752,9 +761,11 @@ EmitComplexPrePostIncDec(const UnaryOperator *E, LValue LV, RValue CodeGenFunction::GetUndefRValue(QualType Ty) { if (Ty->isVoidType()) return RValue::get(0); - - if (const ComplexType *CTy = Ty->getAs()) { - llvm::Type *EltTy = ConvertType(CTy->getElementType()); + + switch (getEvaluationKind(Ty)) { + case TEK_Complex: { + llvm::Type *EltTy = + ConvertType(Ty->castAs()->getElementType()); llvm::Value *U = llvm::UndefValue::get(EltTy); return RValue::getComplex(std::make_pair(U, U)); } @@ -762,12 +773,15 @@ RValue CodeGenFunction::GetUndefRValue(QualType Ty) { // If this is a use of an undefined aggregate type, the aggregate must have an // identifiable address. Just because the contents of the value are undefined // doesn't mean that the address can't be taken and compared. - if (hasAggregateLLVMType(Ty)) { + case TEK_Aggregate: { llvm::Value *DestPtr = CreateMemTemp(Ty, "undef.agg.tmp"); return RValue::getAggregate(DestPtr); } - - return RValue::get(llvm::UndefValue::get(ConvertType(Ty))); + + case TEK_Scalar: + return RValue::get(llvm::UndefValue::get(ConvertType(Ty))); + } + llvm_unreachable("bad evaluation kind"); } RValue CodeGenFunction::EmitUnsupportedRValue(const Expr *E, @@ -1093,7 +1107,6 @@ llvm::MDNode *CodeGenFunction::getRangeForLoadFromType(QualType Ty) { llvm::Value *CodeGenFunction::EmitLoadOfScalar(llvm::Value *Addr, bool Volatile, unsigned Alignment, QualType Ty, llvm::MDNode *TBAAInfo) { - // For better performance, handle vector loads differently. if (Ty->isVectorType()) { llvm::Value *V; @@ -1237,7 +1250,7 @@ void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, llvm::Value *Addr, } Value = EmitToMemory(Value, Ty); - + llvm::StoreInst *Store = Builder.CreateStore(Value, Addr, Volatile); if (Alignment) Store->setAlignment(Alignment); @@ -1248,7 +1261,7 @@ void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, llvm::Value *Addr, } void CodeGenFunction::EmitStoreOfScalar(llvm::Value *value, LValue lvalue, - bool isInit) { + bool isInit) { EmitStoreOfScalar(value, lvalue.getAddress(), lvalue.isVolatile(), lvalue.getAlignment().getQuantity(), lvalue.getType(), lvalue.getTBAAInfo(), isInit); @@ -2579,8 +2592,7 @@ LValue CodeGenFunction:: EmitConditionalOperatorLValue(const AbstractConditionalOperator *expr) { if (!expr->isGLValue()) { // ?: here should be an aggregate. - assert((hasAggregateLLVMType(expr->getType()) && - !expr->getType()->isAnyComplexType()) && + assert(hasAggregateEvaluationKind(expr->getType()) && "Unexpected conditional operator!"); return EmitAggExprToLValue(expr); } @@ -2808,14 +2820,15 @@ RValue CodeGenFunction::EmitRValueForField(LValue LV, const FieldDecl *FD) { QualType FT = FD->getType(); LValue FieldLV = EmitLValueForField(LV, FD); - if (FT->isAnyComplexType()) - return RValue::getComplex( - LoadComplexFromAddr(FieldLV.getAddress(), - FieldLV.isVolatileQualified())); - else if (CodeGenFunction::hasAggregateLLVMType(FT)) + switch (getEvaluationKind(FT)) { + case TEK_Complex: + return RValue::getComplex(EmitLoadOfComplex(FieldLV)); + case TEK_Aggregate: return FieldLV.asAggregateRValue(); - - return EmitLoadOfLValue(FieldLV); + case TEK_Scalar: + return EmitLoadOfLValue(FieldLV); + } + llvm_unreachable("bad evaluation kind"); } //===--------------------------------------------------------------------===// @@ -2922,8 +2935,9 @@ LValue CodeGenFunction::EmitBinaryOperatorLValue(const BinaryOperator *E) { // Note that in all of these cases, __block variables need the RHS // evaluated first just in case the variable gets moved by the RHS. - - if (!hasAggregateLLVMType(E->getType())) { + + switch (getEvaluationKind(E->getType())) { + case TEK_Scalar: { switch (E->getLHS()->getType().getObjCLifetime()) { case Qualifiers::OCL_Strong: return EmitARCStoreStrong(E, /*ignored*/ false).first; @@ -2944,10 +2958,13 @@ LValue CodeGenFunction::EmitBinaryOperatorLValue(const BinaryOperator *E) { return LV; } - if (E->getType()->isAnyComplexType()) + case TEK_Complex: return EmitComplexAssignmentLValue(E); - return EmitAggExprToLValue(E); + case TEK_Aggregate: + return EmitAggExprToLValue(E); + } + llvm_unreachable("bad evaluation kind"); } LValue CodeGenFunction::EmitCallExprLValue(const CallExpr *E) { @@ -3271,13 +3288,20 @@ EmitValToTemp(CodeGenFunction &CGF, Expr *E) { return DeclPtr; } -static RValue ConvertTempToRValue(CodeGenFunction &CGF, QualType Ty, - llvm::Value *Dest) { - if (Ty->isAnyComplexType()) - return RValue::getComplex(CGF.LoadComplexFromAddr(Dest, false)); - if (CGF.hasAggregateLLVMType(Ty)) - return RValue::getAggregate(Dest); - return RValue::get(CGF.EmitLoadOfScalar(CGF.MakeAddrLValue(Dest, Ty))); +/// Given the address of a temporary variable, produce an r-value of +/// its type. +RValue CodeGenFunction::convertTempToRValue(llvm::Value *addr, + QualType type) { + LValue lvalue = MakeNaturalAlignAddrLValue(addr, type); + switch (getEvaluationKind(type)) { + case TEK_Complex: + return RValue::getComplex(EmitLoadOfComplex(lvalue)); + case TEK_Aggregate: + return lvalue.asAggregateRValue(); + case TEK_Scalar: + return RValue::get(EmitLoadOfScalar(lvalue)); + } + llvm_unreachable("bad evaluation kind"); } RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E, llvm::Value *Dest) { @@ -3299,23 +3323,24 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E, llvm::Value *Dest) { if (E->getOp() == AtomicExpr::AO__c11_atomic_init) { assert(!Dest && "Init does not return a value"); - if (!hasAggregateLLVMType(E->getVal1()->getType())) { - QualType PointeeType - = E->getPtr()->getType()->getAs()->getPointeeType(); - EmitScalarInit(EmitScalarExpr(E->getVal1()), - LValue::MakeAddr(Ptr, PointeeType, alignChars, - getContext())); - } else if (E->getType()->isAnyComplexType()) { - EmitComplexExprIntoAddr(E->getVal1(), Ptr, E->isVolatile()); - } else { - AggValueSlot Slot = AggValueSlot::forAddr(Ptr, alignChars, - AtomicTy.getQualifiers(), + LValue LV = MakeAddrLValue(Ptr, AtomicTy, alignChars); + switch (getEvaluationKind(E->getVal1()->getType())) { + case TEK_Scalar: + EmitScalarInit(EmitScalarExpr(E->getVal1()), LV); + return RValue::get(0); + case TEK_Complex: + EmitComplexExprIntoLValue(E->getVal1(), LV, /*isInit*/ true); + return RValue::get(0); + case TEK_Aggregate: { + AggValueSlot Slot = AggValueSlot::forLValue(LV, AggValueSlot::IsNotDestructed, AggValueSlot::DoesNotNeedGCBarriers, AggValueSlot::IsNotAliased); EmitAggExpr(E->getVal1(), Slot); + return RValue::get(0); } - return RValue::get(0); + } + llvm_unreachable("bad evaluation kind"); } Order = EmitScalarExpr(E->getOrder()); @@ -3485,7 +3510,7 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E, llvm::Value *Dest) { return Res; if (E->getType()->isVoidType()) return RValue::get(0); - return ConvertTempToRValue(*this, E->getType(), Dest); + return convertTempToRValue(Dest, E->getType()); } bool IsStore = E->getOp() == AtomicExpr::AO__c11_atomic_store || @@ -3540,7 +3565,7 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E, llvm::Value *Dest) { } if (E->getType()->isVoidType()) return RValue::get(0); - return ConvertTempToRValue(*this, E->getType(), OrigDest); + return convertTempToRValue(OrigDest, E->getType()); } // Long case, when Order isn't obviously constant. @@ -3602,7 +3627,7 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E, llvm::Value *Dest) { Builder.SetInsertPoint(ContBB); if (E->getType()->isVoidType()) return RValue::get(0); - return ConvertTempToRValue(*this, E->getType(), OrigDest); + return convertTempToRValue(OrigDest, E->getType()); } void CodeGenFunction::SetFPAccuracy(llvm::Value *Val, float Accuracy) { @@ -3646,8 +3671,7 @@ static LValueOrRValue emitPseudoObjectExpr(CodeGenFunction &CGF, typedef CodeGenFunction::OpaqueValueMappingData OVMA; OVMA opaqueData; if (ov == resultExpr && ov->isRValue() && !forLValue && - CodeGenFunction::hasAggregateLLVMType(ov->getType()) && - !ov->getType()->isAnyComplexType()) { + CodeGenFunction::hasAggregateEvaluationKind(ov->getType())) { CGF.EmitAggExpr(ov->getSourceExpr(), slot); LValue LV = CGF.MakeAddrLValue(slot.getAddr(), ov->getType()); diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp index f9f2733..f8921db 100644 --- a/clang/lib/CodeGen/CGExprAgg.cpp +++ b/clang/lib/CodeGen/CGExprAgg.cpp @@ -935,24 +935,34 @@ AggExprEmitter::EmitInitializationToLValue(Expr* E, LValue LV) { // FIXME: Are initializers affected by volatile? if (Dest.isZeroed() && isSimpleZero(E, CGF)) { // Storing "i32 0" to a zero'd memory location is a noop. + return; } else if (isa(E) || isa(E)) { - EmitNullInitializationToLValue(LV); + return EmitNullInitializationToLValue(LV); } else if (type->isReferenceType()) { RValue RV = CGF.EmitReferenceBindingToExpr(E, /*InitializedDecl=*/0); - CGF.EmitStoreThroughLValue(RV, LV); - } else if (type->isAnyComplexType()) { - CGF.EmitComplexExprIntoAddr(E, LV.getAddress(), false); - } else if (CGF.hasAggregateLLVMType(type)) { + return CGF.EmitStoreThroughLValue(RV, LV); + } + + switch (CGF.getEvaluationKind(type)) { + case TEK_Complex: + CGF.EmitComplexExprIntoLValue(E, LV, /*isInit*/ true); + return; + case TEK_Aggregate: CGF.EmitAggExpr(E, AggValueSlot::forLValue(LV, AggValueSlot::IsDestructed, AggValueSlot::DoesNotNeedGCBarriers, AggValueSlot::IsNotAliased, Dest.isZeroed())); - } else if (LV.isSimple()) { - CGF.EmitScalarInit(E, /*D=*/0, LV, /*Captured=*/false); - } else { - CGF.EmitStoreThroughLValue(RValue::get(CGF.EmitScalarExpr(E)), LV); + return; + case TEK_Scalar: + if (LV.isSimple()) { + CGF.EmitScalarInit(E, /*D=*/0, LV, /*Captured=*/false); + } else { + CGF.EmitStoreThroughLValue(RValue::get(CGF.EmitScalarExpr(E)), LV); + } + return; } + llvm_unreachable("bad evaluation kind"); } void AggExprEmitter::EmitNullInitializationToLValue(LValue lv) { @@ -963,7 +973,7 @@ void AggExprEmitter::EmitNullInitializationToLValue(LValue lv) { if (Dest.isZeroed() && CGF.getTypes().isZeroInitializable(type)) return; - if (!CGF.hasAggregateLLVMType(type)) { + if (CGF.hasScalarEvaluationKind(type)) { // For non-aggregates, we can store the appropriate null constant. llvm::Value *null = CGF.CGM.EmitNullConstant(type); // Note that the following is not equivalent to @@ -1254,7 +1264,7 @@ static void CheckAggExprForMemSetUse(AggValueSlot &Slot, const Expr *E, /// the value of the aggregate expression is not needed. If VolatileDest is /// true, DestPtr cannot be 0. void CodeGenFunction::EmitAggExpr(const Expr *E, AggValueSlot Slot) { - assert(E && hasAggregateLLVMType(E->getType()) && + assert(E && hasAggregateEvaluationKind(E->getType()) && "Invalid aggregate expression to emit"); assert((Slot.getAddr() != 0 || Slot.isIgnored()) && "slot has bits but no address"); @@ -1266,7 +1276,7 @@ void CodeGenFunction::EmitAggExpr(const Expr *E, AggValueSlot Slot) { } LValue CodeGenFunction::EmitAggExprToLValue(const Expr *E) { - assert(hasAggregateLLVMType(E->getType()) && "Invalid argument!"); + assert(hasAggregateEvaluationKind(E->getType()) && "Invalid argument!"); llvm::Value *Temp = CreateMemTemp(E->getType()); LValue LV = MakeAddrLValue(Temp, E->getType()); EmitAggExpr(E, AggValueSlot::forLValue(LV, AggValueSlot::IsNotDestructed, diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp index 7ad497b..13ae8bb 100644 --- a/clang/lib/CodeGen/CGExprCXX.cpp +++ b/clang/lib/CodeGen/CGExprCXX.cpp @@ -820,14 +820,18 @@ static void StoreAnyExprIntoOneUnit(CodeGenFunction &CGF, const Expr *Init, QualType AllocType, llvm::Value *NewPtr) { CharUnits Alignment = CGF.getContext().getTypeAlignInChars(AllocType); - if (!CGF.hasAggregateLLVMType(AllocType)) + switch (CGF.getEvaluationKind(AllocType)) { + case TEK_Scalar: CGF.EmitScalarInit(Init, 0, CGF.MakeAddrLValue(NewPtr, AllocType, Alignment), false); - else if (AllocType->isAnyComplexType()) - CGF.EmitComplexExprIntoAddr(Init, NewPtr, - AllocType.isVolatileQualified()); - else { + return; + case TEK_Complex: + CGF.EmitComplexExprIntoLValue(Init, CGF.MakeAddrLValue(NewPtr, AllocType, + Alignment), + /*isInit*/ true); + return; + case TEK_Aggregate: { AggValueSlot Slot = AggValueSlot::forAddr(NewPtr, Alignment, AllocType.getQualifiers(), AggValueSlot::IsDestructed, @@ -836,7 +840,10 @@ static void StoreAnyExprIntoOneUnit(CodeGenFunction &CGF, const Expr *Init, CGF.EmitAggExpr(Init, Slot); CGF.MaybeEmitStdInitializerListCleanup(NewPtr, Init); + return; + } } + llvm_unreachable("bad evaluation kind"); } void diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp index 0a53d4f..840463b 100644 --- a/clang/lib/CodeGen/CGExprComplex.cpp +++ b/clang/lib/CodeGen/CGExprComplex.cpp @@ -27,6 +27,16 @@ using namespace CodeGen; typedef CodeGenFunction::ComplexPairTy ComplexPairTy; +/// Return the complex type that we are meant to emit. +static const ComplexType *getComplexType(QualType type) { + type = type.getCanonicalType(); + if (const ComplexType *comp = dyn_cast(type)) { + return comp; + } else { + return cast(cast(type)->getValueType()); + } +} + namespace { class ComplexExprEmitter : public StmtVisitor { @@ -63,25 +73,11 @@ public: return EmitLoadOfLValue(CGF.EmitLValue(E)); } - ComplexPairTy EmitLoadOfLValue(LValue LV) { - assert(LV.isSimple() && "complex l-value must be simple"); - return EmitLoadOfComplex(LV.getAddress(), LV.isVolatileQualified()); - } - - /// EmitLoadOfComplex - Given a pointer to a complex value, emit code to load - /// the real and imaginary pieces. - ComplexPairTy EmitLoadOfComplex(llvm::Value *SrcPtr, bool isVolatile); - - /// EmitStoreThroughLValue - Given an l-value of complex type, store - /// a complex number into it. - void EmitStoreThroughLValue(ComplexPairTy Val, LValue LV) { - assert(LV.isSimple() && "complex l-value must be simple"); - return EmitStoreOfComplex(Val, LV.getAddress(), LV.isVolatileQualified()); - } + ComplexPairTy EmitLoadOfLValue(LValue LV); /// EmitStoreOfComplex - Store the specified real/imag parts into the /// specified value pointer. - void EmitStoreOfComplex(ComplexPairTy Val, llvm::Value *ResPtr, bool isVol); + void EmitStoreOfComplex(ComplexPairTy Val, LValue LV, bool isInit); /// EmitComplexToComplexCast - Emit a cast from complex value Val to DestType. ComplexPairTy EmitComplexToComplexCast(ComplexPairTy Val, QualType SrcType, @@ -194,13 +190,13 @@ public: } ComplexPairTy VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) { assert(E->getType()->isAnyComplexType() && "Expected complex type!"); - QualType Elem = E->getType()->getAs()->getElementType(); + QualType Elem = E->getType()->castAs()->getElementType(); llvm::Constant *Null = llvm::Constant::getNullValue(CGF.ConvertType(Elem)); return ComplexPairTy(Null, Null); } ComplexPairTy VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) { assert(E->getType()->isAnyComplexType() && "Expected complex type!"); - QualType Elem = E->getType()->getAs()->getElementType(); + QualType Elem = E->getType()->castAs()->getElementType(); llvm::Constant *Null = llvm::Constant::getNullValue(CGF.ConvertType(Elem)); return ComplexPairTy(Null, Null); @@ -286,10 +282,13 @@ public: // Utilities //===----------------------------------------------------------------------===// -/// EmitLoadOfComplex - Given an RValue reference for a complex, emit code to +/// EmitLoadOfLValue - Given an RValue reference for a complex, emit code to /// load the real and imaginary pieces, returning them as Real/Imag. -ComplexPairTy ComplexExprEmitter::EmitLoadOfComplex(llvm::Value *SrcPtr, - bool isVolatile) { +ComplexPairTy ComplexExprEmitter::EmitLoadOfLValue(LValue lvalue) { + assert(lvalue.isSimple() && "non-simple complex l-value?"); + llvm::Value *SrcPtr = lvalue.getAddress(); + bool isVolatile = lvalue.isVolatileQualified(); + llvm::Value *Real=0, *Imag=0; if (!IgnoreReal || isVolatile) { @@ -308,13 +307,16 @@ ComplexPairTy ComplexExprEmitter::EmitLoadOfComplex(llvm::Value *SrcPtr, /// EmitStoreOfComplex - Store the specified real/imag parts into the /// specified value pointer. -void ComplexExprEmitter::EmitStoreOfComplex(ComplexPairTy Val, llvm::Value *Ptr, - bool isVolatile) { +void ComplexExprEmitter::EmitStoreOfComplex(ComplexPairTy Val, + LValue lvalue, + bool isInit) { + llvm::Value *Ptr = lvalue.getAddress(); llvm::Value *RealPtr = Builder.CreateStructGEP(Ptr, 0, "real"); llvm::Value *ImagPtr = Builder.CreateStructGEP(Ptr, 1, "imag"); - Builder.CreateStore(Val.first, RealPtr, isVolatile); - Builder.CreateStore(Val.second, ImagPtr, isVolatile); + // TODO: alignment + Builder.CreateStore(Val.first, RealPtr, lvalue.isVolatileQualified()); + Builder.CreateStore(Val.second, ImagPtr, lvalue.isVolatileQualified()); } @@ -326,7 +328,7 @@ void ComplexExprEmitter::EmitStoreOfComplex(ComplexPairTy Val, llvm::Value *Ptr, ComplexPairTy ComplexExprEmitter::VisitExpr(Expr *E) { CGF.ErrorUnsupported(E, "complex expression"); llvm::Type *EltTy = - CGF.ConvertType(E->getType()->getAs()->getElementType()); + CGF.ConvertType(getComplexType(E->getType())->getElementType()); llvm::Value *U = llvm::UndefValue::get(EltTy); return ComplexPairTy(U, U); } @@ -355,8 +357,8 @@ ComplexPairTy ComplexExprEmitter::EmitComplexToComplexCast(ComplexPairTy Val, QualType SrcType, QualType DestType) { // Get the src/dest element type. - SrcType = SrcType->getAs()->getElementType(); - DestType = DestType->getAs()->getElementType(); + SrcType = SrcType->castAs()->getElementType(); + DestType = DestType->castAs()->getElementType(); // C99 6.3.1.6: When a value of complex type is converted to another // complex type, both the real and imaginary parts follow the conversion @@ -381,11 +383,12 @@ ComplexPairTy ComplexExprEmitter::EmitCast(CastExpr::CastKind CK, Expr *Op, return Visit(Op); case CK_LValueBitCast: { - llvm::Value *V = CGF.EmitLValue(Op).getAddress(); + LValue origLV = CGF.EmitLValue(Op); + llvm::Value *V = origLV.getAddress(); V = Builder.CreateBitCast(V, CGF.ConvertType(CGF.getContext().getPointerType(DestTy))); - // FIXME: Are the qualifiers correct here? - return EmitLoadOfComplex(V, DestTy.isVolatileQualified()); + return EmitLoadOfLValue(CGF.MakeAddrLValue(V, DestTy, + origLV.getAlignment())); } case CK_BitCast: @@ -436,7 +439,7 @@ ComplexPairTy ComplexExprEmitter::EmitCast(CastExpr::CastKind CK, Expr *Op, llvm::Value *Elt = CGF.EmitScalarExpr(Op); // Convert the input element to the element type of the complex. - DestTy = DestTy->getAs()->getElementType(); + DestTy = DestTy->castAs()->getElementType(); Elt = CGF.EmitScalarConversion(Elt, Op->getType(), DestTy); // Return (realval, 0). @@ -569,7 +572,7 @@ ComplexPairTy ComplexExprEmitter::EmitBinDiv(const BinOpInfo &Op) { llvm::Value *Tmp8 = Builder.CreateMul(LHSr, RHSi); // a*d llvm::Value *Tmp9 = Builder.CreateSub(Tmp7, Tmp8); // bc-ad - if (Op.Ty->getAs()->getElementType()->isUnsignedIntegerType()) { + if (Op.Ty->castAs()->getElementType()->isUnsignedIntegerType()) { DSTr = Builder.CreateUDiv(Tmp3, Tmp6); DSTi = Builder.CreateUDiv(Tmp9, Tmp6); } else { @@ -629,7 +632,7 @@ EmitCompoundAssignLValue(const CompoundAssignOperator *E, Val = Result; // Store the result value into the LHS lvalue. - EmitStoreThroughLValue(Result, LHS); + EmitStoreOfComplex(Result, LHS, /*isInit*/ false); return LHS; } @@ -649,7 +652,7 @@ EmitCompoundAssign(const CompoundAssignOperator *E, if (!LV.isVolatileQualified()) return Val; - return EmitLoadOfComplex(LV.getAddress(), LV.isVolatileQualified()); + return EmitLoadOfLValue(LV); } LValue ComplexExprEmitter::EmitBinAssignLValue(const BinaryOperator *E, @@ -667,7 +670,7 @@ LValue ComplexExprEmitter::EmitBinAssignLValue(const BinaryOperator *E, LValue LHS = CGF.EmitLValue(E->getLHS()); // Store the result value into the LHS lvalue. - EmitStoreThroughLValue(Val, LHS); + EmitStoreOfComplex(Val, LHS, /*isInit*/ false); return LHS; } @@ -684,7 +687,7 @@ ComplexPairTy ComplexExprEmitter::VisitBinAssign(const BinaryOperator *E) { if (!LV.isVolatileQualified()) return Val; - return EmitLoadOfComplex(LV.getAddress(), LV.isVolatileQualified()); + return EmitLoadOfLValue(LV); } ComplexPairTy ComplexExprEmitter::VisitBinComma(const BinaryOperator *E) { @@ -755,7 +758,7 @@ ComplexPairTy ComplexExprEmitter::VisitInitListExpr(InitListExpr *E) { // Empty init list intializes to null assert(E->getNumInits() == 0 && "Unexpected number of inits"); - QualType Ty = E->getType()->getAs()->getElementType(); + QualType Ty = E->getType()->castAs()->getElementType(); llvm::Type* LTy = CGF.ConvertType(Ty); llvm::Value* zeroConstant = llvm::Constant::getNullValue(LTy); return ComplexPairTy(zeroConstant, zeroConstant); @@ -768,13 +771,13 @@ ComplexPairTy ComplexExprEmitter::VisitVAArgExpr(VAArgExpr *E) { if (!ArgPtr) { CGF.ErrorUnsupported(E, "complex va_arg expression"); llvm::Type *EltTy = - CGF.ConvertType(E->getType()->getAs()->getElementType()); + CGF.ConvertType(E->getType()->castAs()->getElementType()); llvm::Value *U = llvm::UndefValue::get(EltTy); return ComplexPairTy(U, U); } - // FIXME Volatility. - return EmitLoadOfComplex(ArgPtr, false); + return EmitLoadOfLValue( + CGF.MakeNaturalAlignAddrLValue(ArgPtr, E->getType())); } //===----------------------------------------------------------------------===// @@ -785,36 +788,31 @@ ComplexPairTy ComplexExprEmitter::VisitVAArgExpr(VAArgExpr *E) { /// complex type, ignoring the result. ComplexPairTy CodeGenFunction::EmitComplexExpr(const Expr *E, bool IgnoreReal, bool IgnoreImag) { - assert(E && E->getType()->isAnyComplexType() && + assert(E && getComplexType(E->getType()) && "Invalid complex expression to emit"); return ComplexExprEmitter(*this, IgnoreReal, IgnoreImag) .Visit(const_cast(E)); } -/// EmitComplexExprIntoAddr - Emit the computation of the specified expression -/// of complex type, storing into the specified Value*. -void CodeGenFunction::EmitComplexExprIntoAddr(const Expr *E, - llvm::Value *DestAddr, - bool DestIsVolatile) { - assert(E && E->getType()->isAnyComplexType() && +void CodeGenFunction::EmitComplexExprIntoLValue(const Expr *E, LValue dest, + bool isInit) { + assert(E && getComplexType(E->getType()) && "Invalid complex expression to emit"); ComplexExprEmitter Emitter(*this); ComplexPairTy Val = Emitter.Visit(const_cast(E)); - Emitter.EmitStoreOfComplex(Val, DestAddr, DestIsVolatile); + Emitter.EmitStoreOfComplex(Val, dest, isInit); } -/// StoreComplexToAddr - Store a complex number into the specified address. -void CodeGenFunction::StoreComplexToAddr(ComplexPairTy V, - llvm::Value *DestAddr, - bool DestIsVolatile) { - ComplexExprEmitter(*this).EmitStoreOfComplex(V, DestAddr, DestIsVolatile); +/// EmitStoreOfComplex - Store a complex number into the specified l-value. +void CodeGenFunction::EmitStoreOfComplex(ComplexPairTy V, LValue dest, + bool isInit) { + ComplexExprEmitter(*this).EmitStoreOfComplex(V, dest, isInit); } -/// LoadComplexFromAddr - Load a complex number from the specified address. -ComplexPairTy CodeGenFunction::LoadComplexFromAddr(llvm::Value *SrcAddr, - bool SrcIsVolatile) { - return ComplexExprEmitter(*this).EmitLoadOfComplex(SrcAddr, SrcIsVolatile); +/// EmitLoadOfComplex - Load a complex number from the specified address. +ComplexPairTy CodeGenFunction::EmitLoadOfComplex(LValue src) { + return ComplexExprEmitter(*this).EmitLoadOfLValue(src); } LValue CodeGenFunction::EmitComplexAssignmentLValue(const BinaryOperator *E) { diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index 7df4818..56b150a 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -775,7 +775,7 @@ Value *ScalarExprEmitter:: EmitComplexToScalarConversion(CodeGenFunction::ComplexPairTy Src, QualType SrcTy, QualType DstTy) { // Get the source element type. - SrcTy = SrcTy->getAs()->getElementType(); + SrcTy = SrcTy->castAs()->getElementType(); // Handle conversions to bool first, they are special: comparisons against 0. if (DstTy->isBooleanType()) { @@ -3160,7 +3160,7 @@ Value *ScalarExprEmitter::VisitAtomicExpr(AtomicExpr *E) { /// EmitScalarExpr - Emit the computation of the specified expression of scalar /// type, ignoring the result. Value *CodeGenFunction::EmitScalarExpr(const Expr *E, bool IgnoreResultAssign) { - assert(E && !hasAggregateLLVMType(E->getType()) && + assert(E && hasScalarEvaluationKind(E->getType()) && "Invalid scalar expression to emit"); if (isa(E)) @@ -3176,7 +3176,7 @@ Value *CodeGenFunction::EmitScalarExpr(const Expr *E, bool IgnoreResultAssign) { /// specified destination type, both of which are LLVM scalar types. Value *CodeGenFunction::EmitScalarConversion(Value *Src, QualType SrcTy, QualType DstTy) { - assert(!hasAggregateLLVMType(SrcTy) && !hasAggregateLLVMType(DstTy) && + assert(hasScalarEvaluationKind(SrcTy) && hasScalarEvaluationKind(DstTy) && "Invalid scalar expression to emit"); return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy); } @@ -3187,7 +3187,7 @@ Value *CodeGenFunction::EmitScalarConversion(Value *Src, QualType SrcTy, Value *CodeGenFunction::EmitComplexToScalarConversion(ComplexPairTy Src, QualType SrcTy, QualType DstTy) { - assert(SrcTy->isAnyComplexType() && !hasAggregateLLVMType(DstTy) && + assert(SrcTy->isAnyComplexType() && hasScalarEvaluationKind(DstTy) && "Invalid complex -> scalar conversion"); return ScalarExprEmitter(*this).EmitComplexToScalarConversion(Src, SrcTy, DstTy); diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp index 235b0da..ad7d629 100644 --- a/clang/lib/CodeGen/CGObjC.cpp +++ b/clang/lib/CodeGen/CGObjC.cpp @@ -895,16 +895,21 @@ CodeGenFunction::generateObjCGetterBody(const ObjCImplementationDecl *classImpl, LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), ivar, 0); QualType ivarType = ivar->getType(); - if (ivarType->isAnyComplexType()) { - ComplexPairTy pair = LoadComplexFromAddr(LV.getAddress(), - LV.isVolatileQualified()); - StoreComplexToAddr(pair, ReturnValue, LV.isVolatileQualified()); - } else if (hasAggregateLLVMType(ivarType)) { + switch (getEvaluationKind(ivarType)) { + case TEK_Complex: { + ComplexPairTy pair = EmitLoadOfComplex(LV); + EmitStoreOfComplex(pair, + MakeNaturalAlignAddrLValue(ReturnValue, ivarType), + /*init*/ true); + return; + } + case TEK_Aggregate: // The return value slot is guaranteed to not be aliased, but // that's not necessarily the same as "on the stack", so // we still potentially need objc_memmove_collectable. EmitAggregateCopy(ReturnValue, LV.getAddress(), ivarType); - } else { + return; + case TEK_Scalar: { llvm::Value *value; if (propType->isReferenceType()) { value = LV.getAddress(); @@ -926,8 +931,10 @@ CodeGenFunction::generateObjCGetterBody(const ObjCImplementationDecl *classImpl, } EmitReturnOfRValue(RValue::get(value), propType); + return; } - return; + } + llvm_unreachable("bad evaluation kind"); } } diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index 842eaf1..9e7ddfb 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -741,7 +741,9 @@ void CodeGenFunction::EmitReturnOfRValue(RValue RV, QualType Ty) { } else if (RV.isAggregate()) { EmitAggregateCopy(ReturnValue, RV.getAggregateAddr(), Ty); } else { - StoreComplexToAddr(RV.getComplexVal(), ReturnValue, false); + EmitStoreOfComplex(RV.getComplexVal(), + MakeNaturalAlignAddrLValue(ReturnValue, Ty), + /*init*/ true); } EmitBranchThroughCleanup(ReturnBlock); } @@ -788,16 +790,26 @@ void CodeGenFunction::EmitReturnStmt(const ReturnStmt &S) { // rather than the value. RValue Result = EmitReferenceBindingToExpr(RV, /*InitializedDecl=*/0); Builder.CreateStore(Result.getScalarVal(), ReturnValue); - } else if (!hasAggregateLLVMType(RV->getType())) { - Builder.CreateStore(EmitScalarExpr(RV), ReturnValue); - } else if (RV->getType()->isAnyComplexType()) { - EmitComplexExprIntoAddr(RV, ReturnValue, false); } else { - CharUnits Alignment = getContext().getTypeAlignInChars(RV->getType()); - EmitAggExpr(RV, AggValueSlot::forAddr(ReturnValue, Alignment, Qualifiers(), - AggValueSlot::IsDestructed, - AggValueSlot::DoesNotNeedGCBarriers, - AggValueSlot::IsNotAliased)); + switch (getEvaluationKind(RV->getType())) { + case TEK_Scalar: + Builder.CreateStore(EmitScalarExpr(RV), ReturnValue); + break; + case TEK_Complex: + EmitComplexExprIntoLValue(RV, + MakeNaturalAlignAddrLValue(ReturnValue, RV->getType()), + /*isInit*/ true); + break; + case TEK_Aggregate: { + CharUnits Alignment = getContext().getTypeAlignInChars(RV->getType()); + EmitAggExpr(RV, AggValueSlot::forAddr(ReturnValue, Alignment, + Qualifiers(), + AggValueSlot::IsDestructed, + AggValueSlot::DoesNotNeedGCBarriers, + AggValueSlot::IsNotAliased)); + break; + } + } } cleanupScope.ForceCleanup(); @@ -1355,7 +1367,7 @@ CodeGenFunction::EmitAsmInputLValue(const TargetInfo::ConstraintInfo &Info, std::string &ConstraintStr) { llvm::Value *Arg; if (Info.allowsRegister() || !Info.allowsMemory()) { - if (!CodeGenFunction::hasAggregateLLVMType(InputType)) { + if (CodeGenFunction::hasScalarEvaluationKind(InputType)) { Arg = EmitLoadOfLValue(InputValue).getScalarVal(); } else { llvm::Type *Ty = ConvertType(InputType); @@ -1384,7 +1396,7 @@ llvm::Value* CodeGenFunction::EmitAsmInput( const Expr *InputExpr, std::string &ConstraintStr) { if (Info.allowsRegister() || !Info.allowsMemory()) - if (!CodeGenFunction::hasAggregateLLVMType(InputExpr->getType())) + if (CodeGenFunction::hasScalarEvaluationKind(InputExpr->getType())) return EmitScalarExpr(InputExpr); InputExpr = InputExpr->IgnoreParenNoopCasts(getContext()); @@ -1479,7 +1491,7 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { // If this is a register output, then make the inline asm return it // by-value. If this is a memory result, return the value by-reference. - if (!Info.allowsMemory() && !hasAggregateLLVMType(OutExpr->getType())) { + if (!Info.allowsMemory() && hasScalarEvaluationKind(OutExpr->getType())) { Constraints += "=" + OutputConstraint; ResultRegQualTys.push_back(OutExpr->getType()); ResultRegDests.push_back(Dest); diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp index b7ddc97..069cd5f 100644 --- a/clang/lib/CodeGen/CGVTables.cpp +++ b/clang/lib/CodeGen/CGVTables.cpp @@ -361,7 +361,7 @@ void CodeGenFunction::GenerateThunk(llvm::Function *Fn, ReturnValueSlot Slot; if (!ResultType->isVoidType() && FnInfo.getReturnInfo().getKind() == ABIArgInfo::Indirect && - hasAggregateLLVMType(CurFnInfo->getReturnType())) + !hasScalarEvaluationKind(CurFnInfo->getReturnType())) Slot = ReturnValueSlot(ReturnValue, ResultType.isVolatileQualified()); // Now emit our call. diff --git a/clang/lib/CodeGen/CGValue.h b/clang/lib/CodeGen/CGValue.h index 01dee1f..0bbd373 100644 --- a/clang/lib/CodeGen/CGValue.h +++ b/clang/lib/CodeGen/CGValue.h @@ -18,11 +18,11 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/CharUnits.h" #include "clang/AST/Type.h" -#include "llvm/IR/Metadata.h" +#include "llvm/IR/Value.h" namespace llvm { class Constant; - class Value; + class MDNode; } namespace clang { diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 973ee88..5e8bce9 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -77,45 +77,53 @@ llvm::Type *CodeGenFunction::ConvertType(QualType T) { return CGM.getTypes().ConvertType(T); } -bool CodeGenFunction::hasAggregateLLVMType(QualType type) { - switch (type.getCanonicalType()->getTypeClass()) { +TypeEvaluationKind CodeGenFunction::getEvaluationKind(QualType type) { + type = type.getCanonicalType(); + while (true) { + switch (type->getTypeClass()) { #define TYPE(name, parent) #define ABSTRACT_TYPE(name, parent) #define NON_CANONICAL_TYPE(name, parent) case Type::name: #define DEPENDENT_TYPE(name, parent) case Type::name: #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(name, parent) case Type::name: #include "clang/AST/TypeNodes.def" - llvm_unreachable("non-canonical or dependent type in IR-generation"); - - case Type::Builtin: - case Type::Pointer: - case Type::BlockPointer: - case Type::LValueReference: - case Type::RValueReference: - case Type::MemberPointer: - case Type::Vector: - case Type::ExtVector: - case Type::FunctionProto: - case Type::FunctionNoProto: - case Type::Enum: - case Type::ObjCObjectPointer: - return false; + llvm_unreachable("non-canonical or dependent type in IR-generation"); - // Complexes, arrays, records, and Objective-C objects. - case Type::Complex: - case Type::ConstantArray: - case Type::IncompleteArray: - case Type::VariableArray: - case Type::Record: - case Type::ObjCObject: - case Type::ObjCInterface: - return true; + // Various scalar types. + case Type::Builtin: + case Type::Pointer: + case Type::BlockPointer: + case Type::LValueReference: + case Type::RValueReference: + case Type::MemberPointer: + case Type::Vector: + case Type::ExtVector: + case Type::FunctionProto: + case Type::FunctionNoProto: + case Type::Enum: + case Type::ObjCObjectPointer: + return TEK_Scalar; + + // Complexes. + case Type::Complex: + return TEK_Complex; + + // Arrays, records, and Objective-C objects. + case Type::ConstantArray: + case Type::IncompleteArray: + case Type::VariableArray: + case Type::Record: + case Type::ObjCObject: + case Type::ObjCInterface: + return TEK_Aggregate; - // In IRGen, atomic types are just the underlying type - case Type::Atomic: - return hasAggregateLLVMType(type->getAs()->getValueType()); + // We operate on atomic values according to their underlying type. + case Type::Atomic: + type = cast(type)->getValueType(); + continue; + } + llvm_unreachable("unknown type kind!"); } - llvm_unreachable("unknown type kind!"); } void CodeGenFunction::EmitReturnBlock() { @@ -422,7 +430,7 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, // Void type; nothing to return. ReturnValue = 0; } else if (CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect && - hasAggregateLLVMType(CurFnInfo->getReturnType())) { + !hasScalarEvaluationKind(CurFnInfo->getReturnType())) { // Indirect aggregate return; emit returned value directly into sret slot. // This reduces code size, and affects correctness in C++. ReturnValue = CurFn->arg_begin(); diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index cd738f0..4e6c72e 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -78,6 +78,17 @@ namespace CodeGen { class BlockFlags; class BlockFieldFlags; +/// The kind of evaluation to perform on values of a particular +/// type. Basically, is the code in CGExprScalar, CGExprComplex, or +/// CGExprAgg? +/// +/// TODO: should vectors maybe be split out into their own thing? +enum TypeEvaluationKind { + TEK_Scalar, + TEK_Complex, + TEK_Aggregate +}; + /// A branch fixup. These are required when emitting a goto to a /// label which hasn't been emitted yet. The goto is optimistically /// emitted as a branch to the basic block for the label, and (if it @@ -1515,7 +1526,15 @@ public: /// hasAggregateLLVMType - Return true if the specified AST type will map into /// an aggregate LLVM type or is void. - static bool hasAggregateLLVMType(QualType T); + static TypeEvaluationKind getEvaluationKind(QualType T); + + static bool hasScalarEvaluationKind(QualType T) { + return getEvaluationKind(T) == TEK_Scalar; + } + + static bool hasAggregateEvaluationKind(QualType T) { + return getEvaluationKind(T) == TEK_Aggregate; + } /// createBasicBlock - Create an LLVM basic block. llvm::BasicBlock *createBasicBlock(const Twine &name = "", @@ -2128,6 +2147,8 @@ public: /// that the address will be used to access the object. LValue EmitCheckedLValue(const Expr *E, TypeCheckKind TCK); + RValue convertTempToRValue(llvm::Value *addr, QualType type); + /// EmitToMemory - Change a scalar value from its value /// representation to its in-memory representation. llvm::Value *EmitToMemory(llvm::Value *Value, QualType Ty); @@ -2504,16 +2525,15 @@ public: bool IgnoreReal = false, bool IgnoreImag = false); - /// EmitComplexExprIntoAddr - Emit the computation of the specified expression - /// of complex type, storing into the specified Value*. - void EmitComplexExprIntoAddr(const Expr *E, llvm::Value *DestAddr, - bool DestIsVolatile); + /// EmitComplexExprIntoLValue - Emit the given expression of complex + /// type and place its result into the specified l-value. + void EmitComplexExprIntoLValue(const Expr *E, LValue dest, bool isInit); + + /// EmitStoreOfComplex - Store a complex number into the specified l-value. + void EmitStoreOfComplex(ComplexPairTy V, LValue dest, bool isInit); - /// StoreComplexToAddr - Store a complex number into the specified address. - void StoreComplexToAddr(ComplexPairTy V, llvm::Value *DestAddr, - bool DestIsVolatile); - /// LoadComplexFromAddr - Load a complex number from the specified address. - ComplexPairTy LoadComplexFromAddr(llvm::Value *SrcAddr, bool SrcIsVolatile); + /// EmitLoadOfComplex - Load a complex number from the specified l-value. + ComplexPairTy EmitLoadOfComplex(LValue src); /// CreateStaticVarDecl - Create a zero-initialized LLVM global for /// a static local variable. diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index 77f4fb4..81267ca 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -37,7 +37,7 @@ static void AssignToArrayRange(CodeGen::CGBuilderTy &Builder, } static bool isAggregateTypeForABI(QualType T) { - return CodeGenFunction::hasAggregateLLVMType(T) || + return !CodeGenFunction::hasScalarEvaluationKind(T) || T->isMemberFunctionPointerType(); } -- 2.7.4