summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGCall.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen/CGCall.cpp')
-rw-r--r--clang/lib/CodeGen/CGCall.cpp196
1 files changed, 77 insertions, 119 deletions
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index e7b2acc52ad..f7736c14389 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -1040,49 +1040,42 @@ void CodeGenFunction::ExpandTypeFromArgs(
}
void CodeGenFunction::ExpandTypeToArgs(
- QualType Ty, CallArg Arg, llvm::FunctionType *IRFuncTy,
+ QualType Ty, RValue RV, llvm::FunctionType *IRFuncTy,
SmallVectorImpl<llvm::Value *> &IRCallArgs, unsigned &IRCallArgPos) {
auto Exp = getTypeExpansion(Ty, getContext());
if (auto CAExp = dyn_cast<ConstantArrayExpansion>(Exp.get())) {
- Address Addr = Arg.hasLValue() ? Arg.getKnownLValue().getAddress()
- : Arg.getKnownRValue().getAggregateAddress();
- forConstantArrayExpansion(
- *this, CAExp, Addr, [&](Address EltAddr) {
- CallArg EltArg = CallArg(
- convertTempToRValue(EltAddr, CAExp->EltTy, SourceLocation()),
- CAExp->EltTy);
- ExpandTypeToArgs(CAExp->EltTy, EltArg, IRFuncTy, IRCallArgs,
- IRCallArgPos);
- });
+ forConstantArrayExpansion(*this, CAExp, RV.getAggregateAddress(),
+ [&](Address EltAddr) {
+ RValue EltRV =
+ convertTempToRValue(EltAddr, CAExp->EltTy, SourceLocation());
+ ExpandTypeToArgs(CAExp->EltTy, EltRV, IRFuncTy, IRCallArgs, IRCallArgPos);
+ });
} else if (auto RExp = dyn_cast<RecordExpansion>(Exp.get())) {
- Address This = Arg.hasLValue() ? Arg.getKnownLValue().getAddress()
- : Arg.getKnownRValue().getAggregateAddress();
+ Address This = RV.getAggregateAddress();
for (const CXXBaseSpecifier *BS : RExp->Bases) {
// Perform a single step derived-to-base conversion.
Address Base =
GetAddressOfBaseClass(This, Ty->getAsCXXRecordDecl(), &BS, &BS + 1,
/*NullCheckValue=*/false, SourceLocation());
- CallArg BaseArg = CallArg(RValue::getAggregate(Base), BS->getType());
+ RValue BaseRV = RValue::getAggregate(Base);
// Recurse onto bases.
- ExpandTypeToArgs(BS->getType(), BaseArg, IRFuncTy, IRCallArgs,
+ ExpandTypeToArgs(BS->getType(), BaseRV, IRFuncTy, IRCallArgs,
IRCallArgPos);
}
LValue LV = MakeAddrLValue(This, Ty);
for (auto FD : RExp->Fields) {
- CallArg FldArg =
- CallArg(EmitRValueForField(LV, FD, SourceLocation()), FD->getType());
- ExpandTypeToArgs(FD->getType(), FldArg, IRFuncTy, IRCallArgs,
+ RValue FldRV = EmitRValueForField(LV, FD, SourceLocation());
+ ExpandTypeToArgs(FD->getType(), FldRV, IRFuncTy, IRCallArgs,
IRCallArgPos);
}
} else if (isa<ComplexExpansion>(Exp.get())) {
- ComplexPairTy CV = Arg.getKnownRValue().getComplexVal();
+ ComplexPairTy CV = RV.getComplexVal();
IRCallArgs[IRCallArgPos++] = CV.first;
IRCallArgs[IRCallArgPos++] = CV.second;
} else {
assert(isa<NoExpansion>(Exp.get()));
- auto RV = Arg.getKnownRValue();
assert(RV.isScalar() &&
"Unexpected non-scalar rvalue during struct expansion.");
@@ -3425,17 +3418,13 @@ void CodeGenFunction::EmitCallArgs(
assert(InitialArgSize + 1 == Args.size() &&
"The code below depends on only adding one arg per EmitCallArg");
(void)InitialArgSize;
- // Since pointer argument are never emitted as LValue, it is safe to emit
- // non-null argument check for r-value only.
- if (!Args.back().hasLValue()) {
- RValue RVArg = Args.back().getKnownRValue();
- EmitNonNullArgCheck(RVArg, ArgTypes[Idx], (*Arg)->getExprLoc(), AC,
- ParamsToSkip + Idx);
- // @llvm.objectsize should never have side-effects and shouldn't need
- // destruction/cleanups, so we can safely "emit" it after its arg,
- // regardless of right-to-leftness
- MaybeEmitImplicitObjectSize(Idx, *Arg, RVArg);
- }
+ RValue RVArg = Args.back().RV;
+ EmitNonNullArgCheck(RVArg, ArgTypes[Idx], (*Arg)->getExprLoc(), AC,
+ ParamsToSkip + Idx);
+ // @llvm.objectsize should never have side-effects and shouldn't need
+ // destruction/cleanups, so we can safely "emit" it after its arg,
+ // regardless of right-to-leftness
+ MaybeEmitImplicitObjectSize(Idx, *Arg, RVArg);
}
if (!LeftToRight) {
@@ -3482,31 +3471,6 @@ struct DisableDebugLocationUpdates {
} // end anonymous namespace
-RValue CallArg::getRValue(CodeGenFunction &CGF) const {
- if (!HasLV)
- return RV;
- LValue Copy = CGF.MakeAddrLValue(CGF.CreateMemTemp(Ty), Ty);
- CGF.EmitAggregateCopy(Copy, LV, Ty, LV.isVolatile());
- IsUsed = true;
- return RValue::getAggregate(Copy.getAddress());
-}
-
-void CallArg::copyInto(CodeGenFunction &CGF, Address Addr) const {
- LValue Dst = CGF.MakeAddrLValue(Addr, Ty);
- if (!HasLV && RV.isScalar())
- CGF.EmitStoreOfScalar(RV.getScalarVal(), Dst, /*init=*/true);
- else if (!HasLV && RV.isComplex())
- CGF.EmitStoreOfComplex(RV.getComplexVal(), Dst, /*init=*/true);
- else {
- auto Addr = HasLV ? LV.getAddress() : RV.getAggregateAddress();
- LValue SrcLV = CGF.MakeAddrLValue(Addr, Ty);
- CGF.EmitAggregateCopy(Dst, SrcLV, Ty,
- HasLV ? LV.isVolatileQualified()
- : RV.isVolatileQualified());
- }
- IsUsed = true;
-}
-
void CodeGenFunction::EmitCallArg(CallArgList &args, const Expr *E,
QualType type) {
DisableDebugLocationUpdates Dis(*this, E);
@@ -3572,7 +3536,15 @@ void CodeGenFunction::EmitCallArg(CallArgList &args, const Expr *E,
cast<CastExpr>(E)->getCastKind() == CK_LValueToRValue) {
LValue L = EmitLValue(cast<CastExpr>(E)->getSubExpr());
assert(L.isSimple());
- args.addUncopiedAggregate(L, type);
+ if (L.getAlignment() >= getContext().getTypeAlignInChars(type)) {
+ args.add(L.asAggregateRValue(), type, /*NeedsCopy*/true);
+ } else {
+ // We can't represent a misaligned lvalue in the CallArgList, so copy
+ // to an aligned temporary now.
+ LValue Dest = MakeAddrLValue(CreateMemTemp(type), type);
+ EmitAggregateCopy(Dest, L, type, L.isVolatile());
+ args.add(RValue::getAggregate(Dest.getAddress()), type);
+ }
return;
}
@@ -3730,6 +3702,16 @@ CodeGenFunction::EmitCallOrInvoke(llvm::Value *Callee,
return llvm::CallSite(Inst);
}
+/// \brief Store a non-aggregate value to an address to initialize it. For
+/// initialization, a non-atomic store will be used.
+static void EmitInitStoreOfNonAggregate(CodeGenFunction &CGF, RValue Src,
+ LValue Dst) {
+ if (Src.isScalar())
+ CGF.EmitStoreOfScalar(Src.getScalarVal(), Dst, /*init=*/true);
+ else
+ CGF.EmitStoreOfComplex(Src.getComplexVal(), Dst, /*init=*/true);
+}
+
void CodeGenFunction::deferPlaceholderReplacement(llvm::Instruction *Old,
llvm::Value *New) {
DeferredReplacements.push_back(std::make_pair(Old, New));
@@ -3821,6 +3803,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
for (CallArgList::const_iterator I = CallArgs.begin(), E = CallArgs.end();
I != E; ++I, ++info_it, ++ArgNo) {
const ABIArgInfo &ArgInfo = info_it->info;
+ RValue RV = I->RV;
// Insert a padding argument to ensure proper alignment.
if (IRFunctionArgs.hasPaddingArg(ArgNo))
@@ -3834,16 +3817,13 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
case ABIArgInfo::InAlloca: {
assert(NumIRArgs == 0);
assert(getTarget().getTriple().getArch() == llvm::Triple::x86);
- if (I->isAggregate()) {
+ if (RV.isAggregate()) {
// Replace the placeholder with the appropriate argument slot GEP.
- Address Addr = I->hasLValue()
- ? I->getKnownLValue().getAddress()
- : I->getKnownRValue().getAggregateAddress();
llvm::Instruction *Placeholder =
- cast<llvm::Instruction>(Addr.getPointer());
+ cast<llvm::Instruction>(RV.getAggregatePointer());
CGBuilderTy::InsertPoint IP = Builder.saveIP();
Builder.SetInsertPoint(Placeholder);
- Addr = createInAllocaStructGEP(ArgInfo.getInAllocaFieldIndex());
+ Address Addr = createInAllocaStructGEP(ArgInfo.getInAllocaFieldIndex());
Builder.restoreIP(IP);
deferPlaceholderReplacement(Placeholder, Addr.getPointer());
} else {
@@ -3856,20 +3836,22 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
// from {}* to (%struct.foo*)*.
if (Addr.getType() != MemType)
Addr = Builder.CreateBitCast(Addr, MemType);
- I->copyInto(*this, Addr);
+ LValue argLV = MakeAddrLValue(Addr, I->Ty);
+ EmitInitStoreOfNonAggregate(*this, RV, argLV);
}
break;
}
case ABIArgInfo::Indirect: {
assert(NumIRArgs == 1);
- if (!I->isAggregate()) {
+ if (RV.isScalar() || RV.isComplex()) {
// Make a temporary alloca to pass the argument.
Address Addr = CreateMemTemp(I->Ty, ArgInfo.getIndirectAlign(),
"indirect-arg-temp", false);
IRCallArgs[FirstIRArg] = Addr.getPointer();
- I->copyInto(*this, Addr);
+ LValue argLV = MakeAddrLValue(Addr, I->Ty);
+ EmitInitStoreOfNonAggregate(*this, RV, argLV);
} else {
// We want to avoid creating an unnecessary temporary+copy here;
// however, we need one in three cases:
@@ -3877,51 +3859,32 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
// source. (This case doesn't occur on any common architecture.)
// 2. If the argument is byval, RV is not sufficiently aligned, and
// we cannot force it to be sufficiently aligned.
- // 3. If the argument is byval, but RV is not located in default
- // or alloca address space.
- Address Addr = I->hasLValue()
- ? I->getKnownLValue().getAddress()
- : I->getKnownRValue().getAggregateAddress();
- llvm::Value *V = Addr.getPointer();
+ // 3. If the argument is byval, but RV is located in an address space
+ // different than that of the argument (0).
+ Address Addr = RV.getAggregateAddress();
CharUnits Align = ArgInfo.getIndirectAlign();
const llvm::DataLayout *TD = &CGM.getDataLayout();
-
- assert((FirstIRArg >= IRFuncTy->getNumParams() ||
- IRFuncTy->getParamType(FirstIRArg)->getPointerAddressSpace() ==
- TD->getAllocaAddrSpace()) &&
- "indirect argument must be in alloca address space");
-
- bool NeedCopy = false;
-
- if (Addr.getAlignment() < Align &&
- llvm::getOrEnforceKnownAlignment(V, Align.getQuantity(), *TD) <
- Align.getQuantity()) {
- NeedCopy = true;
- } else if (I->hasLValue()) {
- auto LV = I->getKnownLValue();
- auto AS = LV.getAddressSpace();
- if ((!ArgInfo.getIndirectByVal() &&
- (LV.getAlignment() >=
- getContext().getTypeAlignInChars(I->Ty))) ||
- (ArgInfo.getIndirectByVal() &&
- ((AS != LangAS::Default && AS != LangAS::opencl_private &&
- AS != CGM.getASTAllocaAddressSpace())))) {
- NeedCopy = true;
- }
- }
- if (NeedCopy) {
+ const unsigned RVAddrSpace = Addr.getType()->getAddressSpace();
+ const unsigned ArgAddrSpace =
+ (FirstIRArg < IRFuncTy->getNumParams()
+ ? IRFuncTy->getParamType(FirstIRArg)->getPointerAddressSpace()
+ : 0);
+ if ((!ArgInfo.getIndirectByVal() && I->NeedsCopy) ||
+ (ArgInfo.getIndirectByVal() && Addr.getAlignment() < Align &&
+ llvm::getOrEnforceKnownAlignment(Addr.getPointer(),
+ Align.getQuantity(), *TD)
+ < Align.getQuantity()) ||
+ (ArgInfo.getIndirectByVal() && (RVAddrSpace != ArgAddrSpace))) {
// Create an aligned temporary, and copy to it.
Address AI = CreateMemTemp(I->Ty, ArgInfo.getIndirectAlign(),
"byval-temp", false);
IRCallArgs[FirstIRArg] = AI.getPointer();
- I->copyInto(*this, AI);
+ LValue Dest = MakeAddrLValue(AI, I->Ty);
+ LValue Src = MakeAddrLValue(Addr, I->Ty);
+ EmitAggregateCopy(Dest, Src, I->Ty, RV.isVolatileQualified());
} else {
// Skip the extra memcpy call.
- auto *T = V->getType()->getPointerElementType()->getPointerTo(
- CGM.getDataLayout().getAllocaAddrSpace());
- IRCallArgs[FirstIRArg] = getTargetHooks().performAddrSpaceCast(
- *this, V, LangAS::Default, CGM.getASTAllocaAddressSpace(), T,
- true);
+ IRCallArgs[FirstIRArg] = Addr.getPointer();
}
}
break;
@@ -3938,12 +3901,10 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
ArgInfo.getDirectOffset() == 0) {
assert(NumIRArgs == 1);
llvm::Value *V;
- if (!I->isAggregate())
- V = I->getKnownRValue().getScalarVal();
+ if (RV.isScalar())
+ V = RV.getScalarVal();
else
- V = Builder.CreateLoad(
- I->hasLValue() ? I->getKnownLValue().getAddress()
- : I->getKnownRValue().getAggregateAddress());
+ V = Builder.CreateLoad(RV.getAggregateAddress());
// Implement swifterror by copying into a new swifterror argument.
// We'll write back in the normal path out of the call.
@@ -3981,12 +3942,12 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
// FIXME: Avoid the conversion through memory if possible.
Address Src = Address::invalid();
- if (!I->isAggregate()) {
+ if (RV.isScalar() || RV.isComplex()) {
Src = CreateMemTemp(I->Ty, "coerce");
- I->copyInto(*this, Src);
+ LValue SrcLV = MakeAddrLValue(Src, I->Ty);
+ EmitInitStoreOfNonAggregate(*this, RV, SrcLV);
} else {
- Src = I->hasLValue() ? I->getKnownLValue().getAddress()
- : I->getKnownRValue().getAggregateAddress();
+ Src = RV.getAggregateAddress();
}
// If the value is offset in memory, apply the offset now.
@@ -4040,12 +4001,9 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
llvm::Value *tempSize = nullptr;
Address addr = Address::invalid();
- if (I->isAggregate()) {
- addr = I->hasLValue() ? I->getKnownLValue().getAddress()
- : I->getKnownRValue().getAggregateAddress();
-
+ if (RV.isAggregate()) {
+ addr = RV.getAggregateAddress();
} else {
- RValue RV = I->getKnownRValue();
assert(RV.isScalar()); // complex should always just be direct
llvm::Type *scalarType = RV.getScalarVal()->getType();
@@ -4082,7 +4040,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
case ABIArgInfo::Expand:
unsigned IRArgPos = FirstIRArg;
- ExpandTypeToArgs(I->Ty, *I, IRFuncTy, IRCallArgs, IRArgPos);
+ ExpandTypeToArgs(I->Ty, RV, IRFuncTy, IRCallArgs, IRArgPos);
assert(IRArgPos == FirstIRArg + NumIRArgs);
break;
}
@@ -4441,7 +4399,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
OffsetValue);
} else if (const auto *AA = TargetDecl->getAttr<AllocAlignAttr>()) {
llvm::Value *ParamVal =
- CallArgs[AA->getParamIndex() - 1].getRValue(*this).getScalarVal();
+ CallArgs[AA->getParamIndex() - 1].RV.getScalarVal();
EmitAlignmentAssumption(Ret.getScalarVal(), ParamVal);
}
}
OpenPOWER on IntegriCloud