[cfe-commits] r82050 - in /cfe/trunk: clang.xcodeproj/project.pbxproj lib/CodeGen/ABIInfo.h lib/CodeGen/CGCall.cpp lib/CodeGen/TargetABIInfo.cpp test/CodeGenCXX/x86_64-arguments.cpp

Anders Carlsson andersca at mac.com
Wed Sep 16 08:53:40 PDT 2009


Author: andersca
Date: Wed Sep 16 10:53:40 2009
New Revision: 82050

URL: http://llvm.org/viewvc/llvm-project?rev=82050&view=rev
Log:
x86-64 ABI: If a type is a C++ record with either a non-trivial destructor or a non-trivial copy constructor, it should be passed in a pointer. Daniel, plz review.

Added:
    cfe/trunk/test/CodeGenCXX/x86_64-arguments.cpp
Modified:
    cfe/trunk/clang.xcodeproj/project.pbxproj
    cfe/trunk/lib/CodeGen/ABIInfo.h
    cfe/trunk/lib/CodeGen/CGCall.cpp
    cfe/trunk/lib/CodeGen/TargetABIInfo.cpp

Modified: cfe/trunk/clang.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/clang.xcodeproj/project.pbxproj?rev=82050&r1=82049&r2=82050&view=diff

==============================================================================
--- cfe/trunk/clang.xcodeproj/project.pbxproj (original)
+++ cfe/trunk/clang.xcodeproj/project.pbxproj Wed Sep 16 10:53:40 2009
@@ -388,7 +388,7 @@
 		1ADF47AE0F782C3200E48A8A /* SemaTemplateInstantiateDecl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = SemaTemplateInstantiateDecl.cpp; path = lib/Sema/SemaTemplateInstantiateDecl.cpp; sourceTree = "<group>"; tabWidth = 2; };
 		1AE4EE3B103B89CA00888A23 /* TreeTransform.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = TreeTransform.h; path = lib/Sema/TreeTransform.h; sourceTree = "<group>"; tabWidth = 2; };
 		1AE4EE3D103B89ED00888A23 /* StmtProfile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = StmtProfile.cpp; path = lib/AST/StmtProfile.cpp; sourceTree = "<group>"; tabWidth = 2; };
-		1AE4EE3F103B8A0A00888A23 /* TargetABIInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TargetABIInfo.cpp; path = lib/CodeGen/TargetABIInfo.cpp; sourceTree = "<group>"; };
+		1AE4EE3F103B8A0A00888A23 /* TargetABIInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = TargetABIInfo.cpp; path = lib/CodeGen/TargetABIInfo.cpp; sourceTree = "<group>"; tabWidth = 2; };
 		1AFEF4050F8A6B2300476F2B /* clang-cc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = "clang-cc.cpp"; path = "tools/clang-cc/clang-cc.cpp"; sourceTree = "<group>"; tabWidth = 2; };
 		1AFF8AE11012BFC900D248DA /* CGRecordLayoutBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGRecordLayoutBuilder.cpp; path = lib/CodeGen/CGRecordLayoutBuilder.cpp; sourceTree = "<group>"; tabWidth = 2; };
 		1AFF8AE21012BFC900D248DA /* CGRecordLayoutBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = CGRecordLayoutBuilder.h; path = lib/CodeGen/CGRecordLayoutBuilder.h; sourceTree = "<group>"; tabWidth = 2; };

Modified: cfe/trunk/lib/CodeGen/ABIInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ABIInfo.h?rev=82050&r1=82049&r2=82050&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/ABIInfo.h (original)
+++ cfe/trunk/lib/CodeGen/ABIInfo.h Wed Sep 16 10:53:40 2009
@@ -72,11 +72,12 @@
     Kind TheKind;
     const llvm::Type *TypeData;
     unsigned UIntData;
+    bool BoolData;
 
     ABIArgInfo(Kind K, const llvm::Type *TD=0,
-               unsigned UI=0) : TheKind(K),
-                                TypeData(TD),
-                                UIntData(UI) {}
+               unsigned UI=0, bool B = false) 
+      : TheKind(K), TypeData(TD), UIntData(UI), BoolData(B) {}
+
   public:
     ABIArgInfo() : TheKind(Direct), TypeData(0), UIntData(0) {}
 
@@ -92,8 +93,8 @@
     static ABIArgInfo getCoerce(const llvm::Type *T) {
       return ABIArgInfo(Coerce, T);
     }
-    static ABIArgInfo getIndirect(unsigned Alignment) {
-      return ABIArgInfo(Indirect, 0, Alignment);
+    static ABIArgInfo getIndirect(unsigned Alignment, bool ByVal = true) {
+      return ABIArgInfo(Indirect, 0, Alignment, ByVal);
     }
     static ABIArgInfo getExpand() {
       return ABIArgInfo(Expand);
@@ -113,12 +114,17 @@
       return TypeData;
     }
 
-    // ByVal accessors
+    // Indirect accessors
     unsigned getIndirectAlign() const {
       assert(TheKind == Indirect && "Invalid kind!");
       return UIntData;
     }
 
+    bool getIndirectByVal() const {
+      assert(TheKind == Indirect && "Invalid kind!");
+      return BoolData;
+    }
+    
     void dump() const;
   };
 

Modified: cfe/trunk/lib/CodeGen/CGCall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=82050&r1=82049&r2=82050&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Wed Sep 16 10:53:40 2009
@@ -492,7 +492,9 @@
       break;
 
     case ABIArgInfo::Indirect:
-      Attributes |= llvm::Attribute::ByVal;
+      if (AI.getIndirectByVal())
+        Attributes |= llvm::Attribute::ByVal;
+
       Attributes |=
         llvm::Attribute::constructAlignmentFromInt(AI.getIndirectAlign());
       // byval disables readnone and readonly.

Modified: cfe/trunk/lib/CodeGen/TargetABIInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetABIInfo.cpp?rev=82050&r1=82049&r2=82050&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/TargetABIInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/TargetABIInfo.cpp Wed Sep 16 10:53:40 2009
@@ -86,6 +86,27 @@
   return true;
 }
 
+/// hasNonTrivialDestructorOrCopyConstructor - Determine if a type has either
+/// a non-trivial destructor or a non-trivial copy constructor.
+static bool hasNonTrivialDestructorOrCopyConstructor(const RecordType *RT) {
+  const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
+  if (!RD)
+    return false;
+  
+  return !RD->hasTrivialDestructor() || !RD->hasTrivialCopyConstructor();
+}
+
+/// isRecordWithNonTrivialDestructorOrCopyConstructor - Determine if a type is
+/// a record type with either a non-trivial destructor or a non-trivial copy
+/// constructor.
+static bool isRecordWithNonTrivialDestructorOrCopyConstructor(QualType T) {
+  const RecordType *RT = T->getAs<RecordType>();
+  if (!RT)
+    return false;
+
+  return hasNonTrivialDestructorOrCopyConstructor(RT);
+}
+
 /// isSingleElementStruct - Determine if a structure is a "single
 /// element struct", i.e. it has exactly one non-empty field or
 /// exactly one field which is itself a single element
@@ -717,6 +738,12 @@
     if (Size > 128)
       return;
 
+    // AMD64-ABI 3.2.3p2: Rule 2. If a C++ object has either a non-trivial
+    // copy constructor or a non-trivial destructor, it is passed by invisible
+    // reference.
+    if (hasNonTrivialDestructorOrCopyConstructor(RT))
+      return;
+    
     const RecordDecl *RD = RT->getDecl();
 
     // Assume variable sized types are passed in memory.
@@ -830,8 +857,10 @@
     return (Ty->isPromotableIntegerType() ?
             ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
 
+  bool ByVal = !isRecordWithNonTrivialDestructorOrCopyConstructor(Ty);
+
   // FIXME: Set alignment correctly.
-  return ABIArgInfo::getIndirect(0);
+  return ABIArgInfo::getIndirect(0, ByVal);
 }
 
 ABIArgInfo X86_64ABIInfo::classifyReturnType(QualType RetTy,

Added: cfe/trunk/test/CodeGenCXX/x86_64-arguments.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/x86_64-arguments.cpp?rev=82050&view=auto

==============================================================================
--- cfe/trunk/test/CodeGenCXX/x86_64-arguments.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/x86_64-arguments.cpp Wed Sep 16 10:53:40 2009
@@ -0,0 +1,10 @@
+// RUN: clang-cc -triple x86_64-unknown-unknown -emit-llvm -o %t %s &&
+struct A { ~A(); };
+
+// RUN: grep 'define void @_Z2f11A(.struct.A\* .a)' %t &&
+void f1(A a) { }
+
+// RUN: grep 'define void @_Z2f2v(.struct.A\* noalias sret .agg.result)' %t &&
+A f2() { return A(); }
+
+// RUN: true





More information about the cfe-commits mailing list