[cfe-commits] r108379 - in /cfe/trunk: include/clang/Basic/TargetInfo.h lib/Basic/TargetInfo.cpp lib/Basic/Targets.cpp lib/CodeGen/CGBlocks.cpp lib/CodeGen/CGCall.cpp lib/CodeGen/CGObjCMac.cpp lib/CodeGen/CodeGenModule.h

Daniel Dunbar daniel at zuster.org
Wed Jul 14 16:39:37 PDT 2010


Author: ddunbar
Date: Wed Jul 14 18:39:36 2010
New Revision: 108379

URL: http://llvm.org/viewvc/llvm-project?rev=108379&view=rev
Log:
CodeGen/ObjC/NeXT: Fix Obj-C message send to match llvm-gcc when choosing
whether to use objc_msgSend_fpret; the choice is target dependent, not Obj-C ABI
dependent.
 - <rdar://problem/8139758> arm objc _objc_msgSend_fpret bug

Modified:
    cfe/trunk/include/clang/Basic/TargetInfo.h
    cfe/trunk/lib/Basic/TargetInfo.cpp
    cfe/trunk/lib/Basic/Targets.cpp
    cfe/trunk/lib/CodeGen/CGBlocks.cpp
    cfe/trunk/lib/CodeGen/CGCall.cpp
    cfe/trunk/lib/CodeGen/CGObjCMac.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.h

Modified: cfe/trunk/include/clang/Basic/TargetInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TargetInfo.h?rev=108379&r1=108378&r2=108379&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/TargetInfo.h (original)
+++ cfe/trunk/include/clang/Basic/TargetInfo.h Wed Jul 14 18:39:36 2010
@@ -61,6 +61,7 @@
   std::string CXXABI;
 
   unsigned HasAlignMac68kSupport : 1;
+  unsigned RealTypeUsesObjCFPRet : 3;
 
   // TargetInfo Constructor.  Default initializes all fields.
   TargetInfo(const std::string &T);
@@ -87,6 +88,13 @@
     SignedLongLong,
     UnsignedLongLong
   };
+
+  enum RealType {
+    Float = 0,
+    Double,
+    LongDouble
+  };
+
 protected:
   IntType SizeType, IntMaxType, UIntMaxType, PtrDiffType, IntPtrType, WCharType,
           WIntType, Char16Type, Char32Type, Int64Type, SigAtomicType;
@@ -233,6 +241,12 @@
   /// integer type enum. For example, SignedLong -> "L".
   static const char *getTypeConstantSuffix(IntType T);
 
+  /// \brief Check whether the given real type should use the "fpret" flavor of
+  /// Obj-C message passing on this target.
+  bool useObjCFPRetForRealType(RealType T) const {
+    return RealTypeUsesObjCFPRet & (1 << T);
+  }
+
   ///===---- Other target property query methods --------------------------===//
 
   /// getTargetDefines - Appends the target-specific #define values for this

Modified: cfe/trunk/lib/Basic/TargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/TargetInfo.cpp?rev=108379&r1=108378&r2=108379&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/TargetInfo.cpp (original)
+++ cfe/trunk/lib/Basic/TargetInfo.cpp Wed Jul 14 18:39:36 2010
@@ -55,6 +55,9 @@
                       "i64:64:64-f32:32:32-f64:64:64-n32";
   UserLabelPrefix = "_";
   HasAlignMac68kSupport = false;
+
+  // Default to no types using fpret.
+  RealTypeUsesObjCFPRet = 0;
 }
 
 // Out of line virtual dtor for TargetInfo.

Modified: cfe/trunk/lib/Basic/Targets.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Targets.cpp?rev=108379&r1=108378&r2=108379&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/Targets.cpp (original)
+++ cfe/trunk/lib/Basic/Targets.cpp Wed Jul 14 18:39:36 2010
@@ -1245,6 +1245,11 @@
     PtrDiffType = SignedInt;
     IntPtrType = SignedInt;
     RegParmMax = 3;
+
+    // Use fpret for all types.
+    RealTypeUsesObjCFPRet = ((1 << TargetInfo::Float) |
+                             (1 << TargetInfo::Double) |
+                             (1 << TargetInfo::LongDouble));
   }
   virtual const char *getVAListDeclaration() const {
     return "typedef char* __builtin_va_list;";
@@ -1411,6 +1416,9 @@
     DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
                         "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
                         "a0:0:64-s0:64:64-f80:128:128-n8:16:32:64";
+
+    // Use fpret only for long double.
+    RealTypeUsesObjCFPRet = (1 << TargetInfo::LongDouble);
   }
   virtual const char *getVAListDeclaration() const {
     return "typedef struct __va_list_tag {"

Modified: cfe/trunk/lib/CodeGen/CGBlocks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBlocks.cpp?rev=108379&r1=108378&r2=108379&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGBlocks.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBlocks.cpp Wed Jul 14 18:39:36 2010
@@ -253,7 +253,7 @@
       CodeGenTypes &Types = CGM.getTypes();
       const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, Args,
                                                        FunctionType::ExtInfo());
-      if (CGM.ReturnTypeUsesSret(FnInfo))
+      if (CGM.ReturnTypeUsesSRet(FnInfo))
         flags |= BLOCK_USE_STRET;
     }
     const llvm::IntegerType *IntTy = cast<llvm::IntegerType>(

Modified: cfe/trunk/lib/CodeGen/CGCall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=108379&r1=108378&r2=108379&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Wed Jul 14 18:39:36 2010
@@ -564,10 +564,28 @@
 
 /***/
 
-bool CodeGenModule::ReturnTypeUsesSret(const CGFunctionInfo &FI) {
+bool CodeGenModule::ReturnTypeUsesSRet(const CGFunctionInfo &FI) {
   return FI.getReturnInfo().isIndirect();
 }
 
+bool CodeGenModule::ReturnTypeUsesFPRet(QualType ResultType) {
+  if (const BuiltinType *BT = ResultType->getAs<BuiltinType>()) {
+    switch (BT->getKind()) {
+    default:
+      return false;
+    case BuiltinType::Float:
+      return getContext().Target.useObjCFPRetForRealType(TargetInfo::Float);
+    case BuiltinType::Double:
+      return getContext().Target.useObjCFPRetForRealType(TargetInfo::Double);
+    case BuiltinType::LongDouble:
+      return getContext().Target.useObjCFPRetForRealType(
+        TargetInfo::LongDouble);
+    }
+  }
+
+  return false;
+}
+
 const llvm::FunctionType *CodeGenTypes::GetFunctionType(GlobalDecl GD) {
   const CGFunctionInfo &FI = getFunctionInfo(GD);
   
@@ -841,7 +859,7 @@
   llvm::Function::arg_iterator AI = Fn->arg_begin();
 
   // Name the struct return argument.
-  if (CGM.ReturnTypeUsesSret(FI)) {
+  if (CGM.ReturnTypeUsesSRet(FI)) {
     AI->setName("agg.result");
     ++AI;
   }
@@ -1116,7 +1134,7 @@
 
   // If the call returns a temporary with struct return, create a temporary
   // alloca to hold the result, unless one is given to us.
-  if (CGM.ReturnTypeUsesSret(CallInfo)) {
+  if (CGM.ReturnTypeUsesSRet(CallInfo)) {
     llvm::Value *Value = ReturnValue.getValue();
     if (!Value)
       Value = CreateMemTemp(RetTy);

Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=108379&r1=108378&r2=108379&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Wed Jul 14 18:39:36 2010
@@ -1650,29 +1650,17 @@
            "Result type mismatch!");
 
   llvm::Constant *Fn = NULL;
-  if (CGM.ReturnTypeUsesSret(FnInfo)) {
+  if (CGM.ReturnTypeUsesSRet(FnInfo)) {
     Fn = (ObjCABI == 2) ?  ObjCTypes.getSendStretFn2(IsSuper)
       : ObjCTypes.getSendStretFn(IsSuper);
-  } else if (ResultType->isRealFloatingType()) {
-    if (ObjCABI == 2) {
-      if (const BuiltinType *BT = ResultType->getAs<BuiltinType>()) {
-        BuiltinType::Kind k = BT->getKind();
-        Fn = (k == BuiltinType::LongDouble) ? ObjCTypes.getSendFpretFn2(IsSuper)
-          : ObjCTypes.getSendFn2(IsSuper);
-      } else {
-        Fn = ObjCTypes.getSendFn2(IsSuper);
-      }
-    } else
-      // FIXME. This currently matches gcc's API for x86-32. May need to change
-      // for others if we have their API.
-      Fn = ObjCTypes.getSendFpretFn(IsSuper);
+  } else if (CGM.ReturnTypeUsesFPRet(ResultType)) {
+    Fn = (ObjCABI == 2) ? ObjCTypes.getSendFpretFn2(IsSuper)
+      : ObjCTypes.getSendFpretFn(IsSuper);
   } else {
     Fn = (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper)
       : ObjCTypes.getSendFn(IsSuper);
   }
-  assert(Fn && "EmitLegacyMessageSend - unknown API");
-  Fn = llvm::ConstantExpr::getBitCast(Fn,
-                                      llvm::PointerType::getUnqual(FTy));
+  Fn = llvm::ConstantExpr::getBitCast(Fn, llvm::PointerType::getUnqual(FTy));
   return CGF.EmitCall(FnInfo, Fn, Return, ActualArgs);
 }
 
@@ -5295,7 +5283,7 @@
                               FunctionType::ExtInfo());
   llvm::Constant *Fn = 0;
   std::string Name("\01l_");
-  if (CGM.ReturnTypeUsesSret(FnInfo)) {
+  if (CGM.ReturnTypeUsesSRet(FnInfo)) {
 #if 0
     // unlike what is documented. gcc never generates this API!!
     if (Receiver->getType() == ObjCTypes.ObjectPtrTy) {
@@ -5312,14 +5300,9 @@
         Fn = ObjCTypes.getMessageSendStretFixupFn();
         Name += "objc_msgSend_stret_fixup";
       }
-  } else if (!IsSuper && ResultType->isRealFloatingType()) {
-    if (ResultType->isSpecificBuiltinType(BuiltinType::LongDouble)) {
-      Fn = ObjCTypes.getMessageSendFpretFixupFn();
-      Name += "objc_msgSend_fpret_fixup";
-    } else {
-      Fn = ObjCTypes.getMessageSendFixupFn();
-      Name += "objc_msgSend_fixup";
-    }
+  } else if (!IsSuper && CGM.ReturnTypeUsesFPRet(ResultType)) {
+    Fn = ObjCTypes.getMessageSendFpretFixupFn();
+    Name += "objc_msgSend_fpret_fixup";
   } else {
 #if 0
 // unlike what is documented. gcc never generates this API!!

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=108379&r1=108378&r2=108379&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Wed Jul 14 18:39:36 2010
@@ -444,9 +444,13 @@
   /// which only apply to a function definintion.
   void SetLLVMFunctionAttributesForDefinition(const Decl *D, llvm::Function *F);
 
-  /// ReturnTypeUsesSret - Return true iff the given type uses 'sret' when used
+  /// ReturnTypeUsesSRet - Return true iff the given type uses 'sret' when used
   /// as a return type.
-  bool ReturnTypeUsesSret(const CGFunctionInfo &FI);
+  bool ReturnTypeUsesSRet(const CGFunctionInfo &FI);
+
+  /// ReturnTypeUsesSret - Return true iff the given type uses 'fpret' when used
+  /// as a return type.
+  bool ReturnTypeUsesFPRet(QualType ResultType);
 
   /// ConstructAttributeList - Get the LLVM attributes and calling convention to
   /// use for a particular function type.





More information about the cfe-commits mailing list