diff options
author | John McCall <rjmccall@apple.com> | 2011-03-09 04:27:21 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2011-03-09 04:27:21 +0000 |
commit | d26bc76c98006609002d9930f8840490e88ac5b5 (patch) | |
tree | f2a0c8ea750e38c4e98b006f171b137a0625f0f9 /lib/CodeGen/CGCall.cpp | |
parent | eecf5fa12d5426637c47d7072f0c193a8d7ff68b (diff) |
Use the "undergoes default argument promotion" bit on parameters to
simplify the logic of initializing function parameters so that we don't need
both a variable declaration and a type in FunctionArgList. This also means
that we need to propagate the CGFunctionInfo down in a lot of places rather
than recalculating it from the FAL. There's more we can do to eliminate
redundancy here, and I've left FIXMEs behind to do it.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@127314 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGCall.cpp')
-rw-r--r-- | lib/CodeGen/CGCall.cpp | 55 |
1 files changed, 38 insertions, 17 deletions
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index bd14d1be09..1ed3f63da1 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -223,10 +223,15 @@ const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy, llvm::SmallVector<CanQualType, 16> ArgTys; for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end(); i != e; ++i) - ArgTys.push_back(Context.getCanonicalParamType(i->second)); + ArgTys.push_back(Context.getCanonicalParamType((*i)->getType())); return getFunctionInfo(GetReturnType(ResTy), ArgTys, Info); } +const CGFunctionInfo &CodeGenTypes::getNullaryFunctionInfo() { + llvm::SmallVector<CanQualType, 1> args; + return getFunctionInfo(getContext().VoidTy, args, FunctionType::ExtInfo()); +} + const CGFunctionInfo &CodeGenTypes::getFunctionInfo(CanQualType ResTy, const llvm::SmallVectorImpl<CanQualType> &ArgTys, const FunctionType::ExtInfo &Info, @@ -826,6 +831,26 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI, PAL.push_back(llvm::AttributeWithIndex::get(~0, FuncAttrs)); } +/// An argument came in as a promoted argument; demote it back to its +/// declared type. +static llvm::Value *emitArgumentDemotion(CodeGenFunction &CGF, + const VarDecl *var, + llvm::Value *value) { + const llvm::Type *varType = CGF.ConvertType(var->getType()); + + // This can happen with promotions that actually don't change the + // underlying type, like the enum promotions. + if (value->getType() == varType) return value; + + assert((varType->isIntegerTy() || varType->isFloatingPointTy()) + && "unexpected promotion type"); + + if (isa<llvm::IntegerType>(varType)) + return CGF.Builder.CreateTrunc(value, varType, "arg.unpromote"); + + return CGF.Builder.CreateFPCast(value, varType, "arg.unpromote"); +} + void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI, llvm::Function *Fn, const FunctionArgList &Args) { @@ -860,10 +885,13 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI, CGFunctionInfo::const_arg_iterator info_it = FI.arg_begin(); for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end(); i != e; ++i, ++info_it, ++ArgNo) { - const VarDecl *Arg = i->first; + const VarDecl *Arg = *i; QualType Ty = info_it->type; const ABIArgInfo &ArgI = info_it->info; + bool isPromoted = + isa<ParmVarDecl>(Arg) && cast<ParmVarDecl>(Arg)->isKNRPromoted(); + switch (ArgI.getKind()) { case ABIArgInfo::Indirect: { llvm::Value *V = AI; @@ -893,11 +921,9 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI, // Load scalar value from indirect argument. CharUnits Alignment = getContext().getTypeAlignInChars(Ty); V = EmitLoadOfScalar(V, false, Alignment.getQuantity(), Ty); - if (!getContext().typesAreCompatible(Ty, Arg->getType())) { - // This must be a promotion, for something like - // "void a(x) short x; {..." - V = EmitScalarConversion(V, Ty, Arg->getType()); - } + + if (isPromoted) + V = emitArgumentDemotion(*this, Arg, V); } EmitParmDecl(*Arg, V, ArgNo); break; @@ -915,11 +941,9 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI, if (Arg->getType().isRestrictQualified()) AI->addAttr(llvm::Attribute::NoAlias); - if (!getContext().typesAreCompatible(Ty, Arg->getType())) { - // This must be a promotion, for something like - // "void a(x) short x; {..." - V = EmitScalarConversion(V, Ty, Arg->getType()); - } + if (isPromoted) + V = emitArgumentDemotion(*this, Arg, V); + EmitParmDecl(*Arg, V, ArgNo); break; } @@ -969,11 +993,8 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI, // Match to what EmitParmDecl is expecting for this type. if (!CodeGenFunction::hasAggregateLLVMType(Ty)) { V = EmitLoadOfScalar(V, false, AlignmentToUse, Ty); - if (!getContext().typesAreCompatible(Ty, Arg->getType())) { - // This must be a promotion, for something like - // "void a(x) short x; {..." - V = EmitScalarConversion(V, Ty, Arg->getType()); - } + if (isPromoted) + V = emitArgumentDemotion(*this, Arg, V); } EmitParmDecl(*Arg, V, ArgNo); continue; // Skip ++AI increment, already done. |