[cfe-commits] r63083 - /cfe/trunk/lib/CodeGen/CGCall.cpp

Daniel Dunbar daniel at zuster.org
Mon Jan 26 17:36:03 PST 2009


Author: ddunbar
Date: Mon Jan 26 19:36:03 2009
New Revision: 63083

URL: http://llvm.org/viewvc/llvm-project?rev=63083&view=rev
Log:
Implement support for coercion to wider types during ABI handling.
 - Code quality is poor, but simple.

Modified:
    cfe/trunk/lib/CodeGen/CGCall.cpp

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Mon Jan 26 19:36:03 2009
@@ -22,6 +22,7 @@
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Attributes.h"
 #include "llvm/Support/CommandLine.h"
+#include "llvm/Target/TargetData.h"
 using namespace clang;
 using namespace CodeGen;
 
@@ -935,6 +936,71 @@
   assert(AI == Fn->arg_end() && "Argument mismatch!");
 }
 
+/// CreateCoercedLoad - Create a load from \arg SrcPtr interpreted as
+/// a pointer to an object of type \arg Ty.
+///
+/// This safely handles the case when the src type is smaller than the
+/// destination type; in this situation the values of bits which not
+/// present in the src are undefined.
+static llvm::Value *CreateCoercedLoad(llvm::Value *SrcPtr,
+                                      const llvm::Type *Ty,
+                                      CodeGenFunction &CGF) {
+  const llvm::Type *SrcTy = 
+    cast<llvm::PointerType>(SrcPtr->getType())->getElementType();
+  unsigned SrcSize = CGF.CGM.getTargetData().getTypePaddedSize(SrcTy);
+  unsigned DstSize = CGF.CGM.getTargetData().getTypePaddedSize(Ty);
+
+  // If load is legal, just bitcase the src pointer.
+  if (SrcSize == DstSize) {
+    llvm::Value *Casted =
+      CGF.Builder.CreateBitCast(SrcPtr, llvm::PointerType::getUnqual(Ty));
+    return CGF.Builder.CreateLoad(Casted);
+  } else {
+    assert(SrcSize < DstSize && "Coercion is losing source bits!");
+
+    // Otherwise do coercion through memory. This is stupid, but
+    // simple.
+    llvm::Value *Tmp = CGF.CreateTempAlloca(Ty);
+    llvm::Value *Casted = 
+      CGF.Builder.CreateBitCast(Tmp, llvm::PointerType::getUnqual(SrcTy));
+    CGF.Builder.CreateStore(CGF.Builder.CreateLoad(SrcPtr), Casted);
+    return CGF.Builder.CreateLoad(Tmp);
+  }
+}
+
+/// CreateCoercedStore - Create a store to \arg DstPtr from \arg Src,
+/// where the source and destination may have different types.
+///
+/// This safely handles the case when the src type is larger than the
+/// destination type; the upper bits of the src will be lost.
+static void CreateCoercedStore(llvm::Value *Src,
+                               llvm::Value *DstPtr,
+                               CodeGenFunction &CGF) {
+  const llvm::Type *SrcTy = Src->getType();
+  const llvm::Type *DstTy = 
+    cast<llvm::PointerType>(DstPtr->getType())->getElementType();
+
+  unsigned SrcSize = CGF.CGM.getTargetData().getTypePaddedSize(SrcTy);
+  unsigned DstSize = CGF.CGM.getTargetData().getTypePaddedSize(DstTy);
+
+  // If store is legal, just bitcase the src pointer.
+  if (SrcSize == DstSize) {
+    llvm::Value *Casted =
+      CGF.Builder.CreateBitCast(DstPtr, llvm::PointerType::getUnqual(SrcTy));
+    CGF.Builder.CreateStore(Src, Casted);
+  } else {
+    assert(SrcSize > DstSize && "Coercion is missing bits!");
+    
+    // Otherwise do coercion through memory. This is stupid, but
+    // simple.
+    llvm::Value *Tmp = CGF.CreateTempAlloca(SrcTy);
+    CGF.Builder.CreateStore(Src, Tmp);
+    llvm::Value *Casted = 
+      CGF.Builder.CreateBitCast(Tmp, llvm::PointerType::getUnqual(DstTy));
+    CGF.Builder.CreateStore(CGF.Builder.CreateLoad(Casted), DstPtr);
+  }
+}
+
 void CodeGenFunction::EmitFunctionEpilog(QualType RetTy, 
                                          llvm::Value *ReturnValue) {
   llvm::Value *RV = 0;
@@ -965,9 +1031,7 @@
       break;
       
     case ABIArgInfo::Coerce: {
-      const llvm::Type *CoerceToPTy = 
-        llvm::PointerType::getUnqual(RetAI.getCoerceToType());
-      RV = Builder.CreateLoad(Builder.CreateBitCast(ReturnValue, CoerceToPTy));
+      RV = CreateCoercedLoad(ReturnValue, RetAI.getCoerceToType(), *this);
       break;
     }
 
@@ -1073,10 +1137,8 @@
     return RValue::get(0);
 
   case ABIArgInfo::Coerce: {
-    const llvm::Type *CoerceToPTy = 
-      llvm::PointerType::getUnqual(RetAI.getCoerceToType());
-    llvm::Value *V = CreateTempAlloca(ConvertType(RetTy), "tmp");
-    Builder.CreateStore(CI, Builder.CreateBitCast(V, CoerceToPTy));
+    llvm::Value *V = CreateTempAlloca(ConvertType(RetTy), "coerce");
+    CreateCoercedStore(CI, V, *this);
     if (RetTy->isAnyComplexType())
       return RValue::getComplex(LoadComplexFromAddr(V, false));
     else if (CodeGenFunction::hasAggregateLLVMType(RetTy))





More information about the cfe-commits mailing list