[cfe-commits] r109738 - in /cfe/trunk: lib/CodeGen/TargetInfo.cpp test/CodeGen/x86_64-arguments.c

Chris Lattner sabre at nondot.org
Thu Jul 29 00:43:55 PDT 2010


Author: lattner
Date: Thu Jul 29 02:43:55 2010
New Revision: 109738

URL: http://llvm.org/viewvc/llvm-project?rev=109738&view=rev
Log:
This is a little bit far, but optimize cases like:

struct a {
  struct c {
    double x;
    int y;
  } x[1];
};

void foo(struct a A) {
}

into:

define void @foo(double %A.coerce0, i32 %A.coerce1) nounwind {
entry:
  %A = alloca %struct.a, align 8                  ; <%struct.a*> [#uses=1]
  %0 = bitcast %struct.a* %A to %struct.c*        ; <%struct.c*> [#uses=2]
  %1 = getelementptr %struct.c* %0, i32 0, i32 0  ; <double*> [#uses=1]
  store double %A.coerce0, double* %1
  %2 = getelementptr %struct.c* %0, i32 0, i32 1  ; <i32*> [#uses=1]
  store i32 %A.coerce1, i32* %2

instead of:

define void @foo(double %A.coerce0, i64 %A.coerce1) nounwind {
entry:
  %A = alloca %struct.a, align 8                  ; <%struct.a*> [#uses=1]
  %0 = bitcast %struct.a* %A to %0*               ; <%0*> [#uses=2]
  %1 = getelementptr %0* %0, i32 0, i32 0         ; <double*> [#uses=1]
  store double %A.coerce0, double* %1
  %2 = getelementptr %0* %0, i32 0, i32 1         ; <i64*> [#uses=1]
  store i64 %A.coerce1, i64* %2

I only do this now because I never want to look at this code again :)
 

Modified:
    cfe/trunk/lib/CodeGen/TargetInfo.cpp
    cfe/trunk/test/CodeGen/x86_64-arguments.c

Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=109738&r1=109737&r2=109738&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Thu Jul 29 02:43:55 2010
@@ -1226,9 +1226,24 @@
   if (TySize <= StartBit)
     return true;
 
-  //if (const ConstantArrayType *AT = Context.getAsConstantArrayType(Ty)) {
-    // TODO.
-  //}
+  if (const ConstantArrayType *AT = Context.getAsConstantArrayType(Ty)) {
+    unsigned EltSize = (unsigned)Context.getTypeSize(AT->getElementType());
+    unsigned NumElts = (unsigned)AT->getSize().getZExtValue();
+
+    // Check each element to see if the element overlaps with the queried range.
+    for (unsigned i = 0; i != NumElts; ++i) {
+      // If the element is after the span we care about, then we're done..
+      unsigned EltOffset = i*EltSize;
+      if (EltOffset >= EndBit) break;
+      
+      unsigned EltStart = EltOffset < StartBit ? StartBit-EltOffset :0;
+      if (!BitsContainNoUserData(AT->getElementType(), EltStart,
+                                 EndBit-EltOffset, Context))
+        return false;
+    }
+    // If it overlaps no elements, then it is safe to process as padding.
+    return true;
+  }
   
   if (const RecordType *RT = Ty->getAs<RecordType>()) {
     const RecordDecl *RD = RT->getDecl();
@@ -1332,6 +1347,14 @@
     }      
   }
   
+  if (const llvm::ArrayType *ATy = dyn_cast<llvm::ArrayType>(IRType)) {
+    const llvm::Type *EltTy = ATy->getElementType();
+    unsigned EltSize = getTargetData().getTypeAllocSize(EltTy);
+    unsigned EltOffset = IROffset/EltSize*EltSize;
+    return Get8ByteTypeAtOffset(EltTy, IROffset-EltOffset, SourceTy,
+                                SourceOffset);
+  }
+  
   // Okay, we don't have any better idea of what to pass, so we pass this in an
   // integer register that isn't too big to fit the rest of the struct.
   uint64_t TySizeInBytes =

Modified: cfe/trunk/test/CodeGen/x86_64-arguments.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/x86_64-arguments.c?rev=109738&r1=109737&r2=109738&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/x86_64-arguments.c (original)
+++ cfe/trunk/test/CodeGen/x86_64-arguments.c Thu Jul 29 02:43:55 2010
@@ -194,3 +194,13 @@
   // CHECK: define void @f28(double %C.coerce0, i32 %C.coerce1)
 }
 
+struct f29a {
+  struct c {
+    double x;
+    int y;
+  } x[1];
+};
+
+void f29a(struct f29a A) {
+  // CHECK: define void @f29a(double %A.coerce0, i32 %A.coerce1)
+}





More information about the cfe-commits mailing list