[cfe-commits] r97030 - in /cfe/trunk: lib/CodeGen/CGCall.cpp lib/CodeGen/CGCall.h lib/CodeGen/CodeGenTypes.h lib/CodeGen/TargetInfo.cpp test/CodeGen/functions.c test/CodeGenObjC/messages-2.m

John McCall rjmccall at apple.com
Tue Feb 23 23:14:12 PST 2010


Author: rjmccall
Date: Wed Feb 24 01:14:12 2010
New Revision: 97030

URL: http://llvm.org/viewvc/llvm-project?rev=97030&view=rev
Log:
Canonicalize parameter and return types before computing ABI info.  Eliminates
a common source of oddities and, in theory, removes some redundant ABI
computations.  Also fixes a miscompile I introduced yesterday by refactoring
some code and causing a slightly different code path to be taken that
didn't perform *parameter* type canonicalization, just normal type
canonicalization;  this in turn caused a bit of ABI code to misfire because
it was looking for 'double' or 'float' but received 'const float'.


Modified:
    cfe/trunk/lib/CodeGen/CGCall.cpp
    cfe/trunk/lib/CodeGen/CGCall.h
    cfe/trunk/lib/CodeGen/CodeGenTypes.h
    cfe/trunk/lib/CodeGen/TargetInfo.cpp
    cfe/trunk/test/CodeGen/functions.c
    cfe/trunk/test/CodeGenObjC/messages-2.m

Modified: cfe/trunk/lib/CodeGen/CGCall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=97030&r1=97029&r2=97030&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Wed Feb 24 01:14:12 2010
@@ -41,21 +41,54 @@
   }
 }
 
-const
-CGFunctionInfo &CodeGenTypes::getFunctionInfo(const FunctionNoProtoType *FTNP) {
-  return getFunctionInfo(FTNP->getResultType(),
+/// Derives the 'this' type for codegen purposes, i.e. ignoring method
+/// qualification.
+/// FIXME: address space qualification?
+static QualType GetThisType(ASTContext &Context, const CXXRecordDecl *RD) {
+  return Context.getPointerType(Context.getTagDeclType(RD));
+}
+
+/// Returns the canonical formal type of the given C++ method.
+static const FunctionProtoType *GetFormalType(const CXXMethodDecl *MD) {
+  return cast<FunctionProtoType>(MD->getType()->getCanonicalTypeInternal());
+}
+
+/// Returns the "extra-canonicalized" return type, which discards
+/// qualifiers on the return type.  Codegen doesn't care about them,
+/// and it makes ABI code a little easier to be able to assume that
+/// all parameter and return types are top-level unqualified.
+static QualType GetReturnType(QualType RetTy) {
+  return RetTy->getCanonicalTypeInternal().getUnqualifiedType();
+}
+
+const CGFunctionInfo &
+CodeGenTypes::getFunctionInfo(const FunctionNoProtoType *FTNP) {
+  assert(FTNP->isCanonicalUnqualified() && "type must be canonical");
+  return getFunctionInfo(GetReturnType(FTNP->getResultType()),
                          llvm::SmallVector<QualType, 16>(),
-                         FTNP->getCallConv(), FTNP->getNoReturnAttr());
+                         FTNP->getCallConv(),
+                         FTNP->getNoReturnAttr());
 }
 
-const
-CGFunctionInfo &CodeGenTypes::getFunctionInfo(const FunctionProtoType *FTP) {
-  llvm::SmallVector<QualType, 16> ArgTys;
+/// \param Args - contains any initial parameters besides those
+///   in the formal type
+static const CGFunctionInfo &getFunctionInfo(CodeGenTypes &CGT,
+                                       llvm::SmallVectorImpl<QualType> &ArgTys,
+                                             const FunctionProtoType *FTP) {
+  assert(FTP->isCanonicalUnqualified() && "type must be canonical");
   // FIXME: Kill copy.
   for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
     ArgTys.push_back(FTP->getArgType(i));
-  return getFunctionInfo(FTP->getResultType(), ArgTys,
-                         FTP->getCallConv(), FTP->getNoReturnAttr());
+  return CGT.getFunctionInfo(GetReturnType(FTP->getResultType()),
+                             ArgTys,
+                             FTP->getCallConv(),
+                             FTP->getNoReturnAttr());
+}
+
+const CGFunctionInfo &
+CodeGenTypes::getFunctionInfo(const FunctionProtoType *FTP) {
+  llvm::SmallVector<QualType, 16> ArgTys;
+  return ::getFunctionInfo(*this, ArgTys, FTP);
 }
 
 static CallingConv getCallingConventionForDecl(const Decl *D) {
@@ -72,30 +105,22 @@
 const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXRecordDecl *RD,
                                                  const FunctionProtoType *FTP) {
   llvm::SmallVector<QualType, 16> ArgTys;
-  
+
   // Add the 'this' pointer.
-  ArgTys.push_back(Context.getPointerType(Context.getTagDeclType(RD)));
-  
-  for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
-    ArgTys.push_back(FTP->getArgType(i));
-  
-  // FIXME: Set calling convention correctly, it needs to be associated with the
-  // type somehow.
-  return getFunctionInfo(FTP->getResultType(), ArgTys,
-                         FTP->getCallConv(), FTP->getNoReturnAttr());
+  ArgTys.push_back(GetThisType(Context, RD));
+
+  return ::getFunctionInfo(*this, ArgTys,
+                   cast<FunctionProtoType>(FTP->getCanonicalTypeInternal()));
 }
 
 const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXMethodDecl *MD) {
   llvm::SmallVector<QualType, 16> ArgTys;
+
   // Add the 'this' pointer unless this is a static method.
   if (MD->isInstance())
-    ArgTys.push_back(MD->getThisType(Context));
+    ArgTys.push_back(GetThisType(Context, MD->getParent()));
 
-  const FunctionProtoType *FTP = MD->getType()->getAs<FunctionProtoType>();
-  for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
-    ArgTys.push_back(FTP->getArgType(i));
-  return getFunctionInfo(FTP->getResultType(), ArgTys, FTP->getCallConv(),
-                         FTP->getNoReturnAttr());
+  return ::getFunctionInfo(*this, ArgTys, GetFormalType(MD));
 }
 
 const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXConstructorDecl *D, 
@@ -103,17 +128,13 @@
   llvm::SmallVector<QualType, 16> ArgTys;
 
   // Add the 'this' pointer.
-  ArgTys.push_back(D->getThisType(Context));
+  ArgTys.push_back(GetThisType(Context, D->getParent()));
 
   // Check if we need to add a VTT parameter (which has type void **).
   if (Type == Ctor_Base && D->getParent()->getNumVBases() != 0)
     ArgTys.push_back(Context.getPointerType(Context.VoidPtrTy));
-  
-  const FunctionProtoType *FTP = D->getType()->getAs<FunctionProtoType>();
-  for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
-    ArgTys.push_back(FTP->getArgType(i));
-  return getFunctionInfo(FTP->getResultType(), ArgTys, FTP->getCallConv(),
-                         FTP->getNoReturnAttr());
+
+  return ::getFunctionInfo(*this, ArgTys, GetFormalType(D));
 }
 
 const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXDestructorDecl *D,
@@ -126,12 +147,8 @@
   // Check if we need to add a VTT parameter (which has type void **).
   if (Type == Dtor_Base && D->getParent()->getNumVBases() != 0)
     ArgTys.push_back(Context.getPointerType(Context.VoidPtrTy));
-  
-  const FunctionProtoType *FTP = D->getType()->getAs<FunctionProtoType>();
-  for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
-    ArgTys.push_back(FTP->getArgType(i));
-  return getFunctionInfo(FTP->getResultType(), ArgTys, FTP->getCallConv(),
-                         FTP->getNoReturnAttr());
+
+  return ::getFunctionInfo(*this, ArgTys, GetFormalType(D));
 }
 
 const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const FunctionDecl *FD) {
@@ -139,19 +156,11 @@
     if (MD->isInstance())
       return getFunctionInfo(MD);
 
-  const FunctionType *FTy = FD->getType()->getAs<FunctionType>();
-  if (const FunctionNoProtoType *FNTP = dyn_cast<FunctionNoProtoType>(FTy))
-    return getFunctionInfo(FNTP->getResultType(), 
-                           llvm::SmallVector<QualType, 16>(),
-                           FNTP->getCallConv(), FNTP->getNoReturnAttr());
-  
-  const FunctionProtoType *FPT = cast<FunctionProtoType>(FTy);
-  llvm::SmallVector<QualType, 16> ArgTys;
-  // FIXME: Kill copy.
-  for (unsigned i = 0, e = FPT->getNumArgs(); i != e; ++i)
-    ArgTys.push_back(FPT->getArgType(i));
-  return getFunctionInfo(FPT->getResultType(), ArgTys,
-                         FPT->getCallConv(), FPT->getNoReturnAttr());
+  const FunctionType *FTy
+    = cast<FunctionType>(FD->getType()->getCanonicalTypeInternal());
+  if (isa<FunctionNoProtoType>(FTy))
+    return getFunctionInfo(cast<FunctionNoProtoType>(FTy));  
+  return getFunctionInfo(cast<FunctionProtoType>(FTy));
 }
 
 const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const ObjCMethodDecl *MD) {
@@ -160,9 +169,11 @@
   ArgTys.push_back(Context.getObjCSelType());
   // FIXME: Kill copy?
   for (ObjCMethodDecl::param_iterator i = MD->param_begin(),
-         e = MD->param_end(); i != e; ++i)
-    ArgTys.push_back((*i)->getType());
-  return getFunctionInfo(MD->getResultType(), ArgTys,
+         e = MD->param_end(); i != e; ++i) {
+    ArgTys.push_back(Context.getCanonicalParamType((*i)->getType()));
+  }
+  return getFunctionInfo(GetReturnType(MD->getResultType()),
+                         ArgTys,
                          getCallingConventionForDecl(MD),
                          /*NoReturn*/ false);
 }
@@ -188,8 +199,8 @@
   llvm::SmallVector<QualType, 16> ArgTys;
   for (CallArgList::const_iterator i = Args.begin(), e = Args.end();
        i != e; ++i)
-    ArgTys.push_back(i->second);
-  return getFunctionInfo(ResTy, ArgTys, CC, NoReturn);
+    ArgTys.push_back(Context.getCanonicalParamType(i->second));
+  return getFunctionInfo(GetReturnType(ResTy), ArgTys, CC, NoReturn);
 }
 
 const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy,
@@ -200,12 +211,12 @@
   llvm::SmallVector<QualType, 16> ArgTys;
   for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end();
        i != e; ++i)
-    ArgTys.push_back(i->second);
-  return getFunctionInfo(ResTy, ArgTys, CC, NoReturn);
+    ArgTys.push_back(Context.getCanonicalParamType(i->second));
+  return getFunctionInfo(GetReturnType(ResTy), ArgTys, CC, NoReturn);
 }
 
 const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy,
-                                  const llvm::SmallVector<QualType, 16> &ArgTys,
+                           const llvm::SmallVectorImpl<QualType> &ArgTys,
                                                     CallingConv CallConv,
                                                     bool NoReturn) {
   unsigned CC = ClangCallConvToLLVMCallConv(CallConv);
@@ -233,7 +244,7 @@
 CGFunctionInfo::CGFunctionInfo(unsigned _CallingConvention,
                                bool _NoReturn,
                                QualType ResTy,
-                               const llvm::SmallVector<QualType, 16> &ArgTys) 
+                               const llvm::SmallVectorImpl<QualType> &ArgTys) 
   : CallingConvention(_CallingConvention),
     EffectiveCallingConvention(_CallingConvention),
     NoReturn(_NoReturn)

Modified: cfe/trunk/lib/CodeGen/CGCall.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.h?rev=97030&r1=97029&r2=97030&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.h (original)
+++ cfe/trunk/lib/CodeGen/CGCall.h Wed Feb 24 01:14:12 2010
@@ -82,7 +82,7 @@
     CGFunctionInfo(unsigned CallingConvention,
                    bool NoReturn,
                    QualType ResTy,
-                   const llvm::SmallVector<QualType, 16> &ArgTys);
+                   const llvm::SmallVectorImpl<QualType> &ArgTys);
     ~CGFunctionInfo() { delete[] Args; }
 
     const_arg_iterator arg_begin() const { return Args + 1; }

Modified: cfe/trunk/lib/CodeGen/CodeGenTypes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenTypes.h?rev=97030&r1=97029&r2=97030&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenTypes.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenTypes.h Wed Feb 24 01:14:12 2010
@@ -186,11 +186,6 @@
   /// replace the 'opaque' type we previously made for it if applicable.
   void UpdateCompletedType(const TagDecl *TD);
 
-private:
-  const CGFunctionInfo &getFunctionInfo(const FunctionNoProtoType *FTNP);
-  const CGFunctionInfo &getFunctionInfo(const FunctionProtoType *FTP);
-
-public:
   /// getFunctionInfo - Get the function info for the specified function decl.
   const CGFunctionInfo &getFunctionInfo(GlobalDecl GD);
   
@@ -207,6 +202,8 @@
     return getFunctionInfo(Ty->getResultType(), Args,
                            Ty->getCallConv(), Ty->getNoReturnAttr());
   }
+  const CGFunctionInfo &getFunctionInfo(const FunctionProtoType *Ty);
+  const CGFunctionInfo &getFunctionInfo(const FunctionNoProtoType *Ty);
 
   // getFunctionInfo - Get the function info for a member function.
   const CGFunctionInfo &getFunctionInfo(const CXXRecordDecl *RD,
@@ -224,7 +221,7 @@
                                         CallingConv CC,
                                         bool NoReturn);
   const CGFunctionInfo &getFunctionInfo(QualType RetTy,
-                                  const llvm::SmallVector<QualType, 16> &ArgTys,
+                                  const llvm::SmallVectorImpl<QualType> &ArgTys,
                                         CallingConv CC,
                                         bool NoReturn);
 

Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=97030&r1=97029&r2=97030&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Wed Feb 24 01:14:12 2010
@@ -972,12 +972,11 @@
       return (Ty->isPromotableIntegerType() ?
               ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
   } else if (CoerceTo == llvm::Type::getDoubleTy(CoerceTo->getContext())) {
-    // FIXME: It would probably be better to make CGFunctionInfo only map using
-    // canonical types than to canonize here.
-    QualType CTy = Context.getCanonicalType(Ty);
+    assert(Ty.isCanonical() && "should always have a canonical type here");
+    assert(!Ty.hasQualifiers() && "should never have a qualified type here");
 
     // Float and double end up in a single SSE reg.
-    if (CTy == Context.FloatTy || CTy == Context.DoubleTy)
+    if (Ty == Context.FloatTy || Ty == Context.DoubleTy)
       return ABIArgInfo::getDirect();
 
   }

Modified: cfe/trunk/test/CodeGen/functions.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/functions.c?rev=97030&r1=97029&r2=97030&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/functions.c (original)
+++ cfe/trunk/test/CodeGen/functions.c Wed Feb 24 01:14:12 2010
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -emit-llvm -o %t
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
 
 int g();
 
@@ -38,3 +38,12 @@
 // PR4423 - This shouldn't crash in codegen
 void f4() {}
 void f5() { f4(42); }
+
+// Qualifiers on parameter types shouldn't make a difference.
+static void f6(const float f, const float g) {
+}
+void f7(float f, float g) {
+  f6(f, g);
+// CHECK: define void @f7(float{{.*}}, float{{.*}})
+// CHECK: call void @f6(float{{.*}}, float{{.*}})
+}

Modified: cfe/trunk/test/CodeGenObjC/messages-2.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/messages-2.m?rev=97030&r1=97029&r2=97030&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjC/messages-2.m (original)
+++ cfe/trunk/test/CodeGenObjC/messages-2.m Wed Feb 24 01:14:12 2010
@@ -136,4 +136,7 @@
   x.height *= 2;
   return x;
 }
+-(const float) returnAConstFloat {
+  return 5;
+}
 @end





More information about the cfe-commits mailing list