[cfe-commits] r147520 - /cfe/trunk/lib/CodeGen/TargetInfo.cpp

Akira Hatanaka ahatanaka at mips.com
Tue Jan 3 19:34:42 PST 2012


Author: ahatanak
Date: Tue Jan  3 21:34:42 2012
New Revision: 147520

URL: http://llvm.org/viewvc/llvm-project?rev=147520&view=rev
Log:
Have functions return structures smaller than 128-bit in registers if ABI
is either N32 or N64. 

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

Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=147520&r1=147519&r2=147520&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Tue Jan  3 21:34:42 2012
@@ -3041,6 +3041,7 @@
   bool IsO32;
   unsigned MinABIStackAlignInBytes;
   llvm::Type* HandleStructTy(QualType Ty) const;
+  llvm::Type* returnAggregateInRegs(QualType RetTy, uint64_t Size) const;
 public:
   MipsABIInfo(CodeGenTypes &CGT, bool _IsO32) :
     ABIInfo(CGT), IsO32(_IsO32), MinABIStackAlignInBytes(IsO32 ? 4 : 8) {}
@@ -3157,14 +3158,64 @@
           ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
 }
 
+llvm::Type*
+MipsABIInfo::returnAggregateInRegs(QualType RetTy, uint64_t Size) const {
+  const RecordType *RT = RetTy->getAsStructureType();
+  SmallVector<llvm::Type*, 2> RTList;
+
+  if (RT) {
+    const RecordDecl *RD = RT->getDecl();
+    RecordDecl::field_iterator b = RD->field_begin(), e = RD->field_end(), i;
+
+    for (i = b; (i != e) && (std::distance(b, i) < 2); ++i) {
+      const BuiltinType *BT = (*i)->getType()->getAs<BuiltinType>();
+
+      if (!BT || !BT->isFloatingPoint())
+        break;
+
+      switch (BT->getKind()) {
+      case BuiltinType::Float:
+        RTList.push_back(llvm::Type::getFloatTy(getVMContext()));
+        break;
+      case BuiltinType::Double:
+        RTList.push_back(llvm::Type::getDoubleTy(getVMContext()));
+        break;
+      case BuiltinType::LongDouble:
+        RTList.push_back(llvm::Type::getFP128Ty(getVMContext()));
+        break;
+      default:
+        assert(false && "Unexpexted floating point type.");
+      }
+    }
+
+    if (i == e)
+      return llvm::StructType::get(getVMContext(), RTList,
+                                   RD->hasAttr<PackedAttr>());
+
+    RTList.clear();
+  }
+
+  RTList.push_back(llvm::IntegerType::get(getVMContext(),
+                                          std::min(Size, (uint64_t)64)));
+  if (Size > 64)
+    RTList.push_back(llvm::IntegerType::get(getVMContext(), Size - 64));
+
+  return llvm::StructType::get(getVMContext(), RTList);
+}
+
 ABIArgInfo MipsABIInfo::classifyReturnType(QualType RetTy) const {
   if (RetTy->isVoidType())
     return ABIArgInfo::getIgnore();
 
   if (isAggregateTypeForABI(RetTy)) {
-    if ((IsO32 && RetTy->isAnyComplexType()) ||
-        (!IsO32 && (getContext().getTypeSize(RetTy) <= 128)))
-      return ABIArgInfo::getDirect();
+    uint64_t Size = getContext().getTypeSize(RetTy);
+    if (Size <= 128) {
+      if (RetTy->isAnyComplexType())
+        return ABIArgInfo::getDirect();
+
+      if (!IsO32)
+        return ABIArgInfo::getDirect(returnAggregateInRegs(RetTy, Size));
+    }
 
     return ABIArgInfo::getIndirect(0);
   }





More information about the cfe-commits mailing list