[cfe-commits] r109790 - /cfe/trunk/lib/CodeGen/TargetInfo.cpp
Chris Lattner
sabre at nondot.org
Thu Jul 29 11:39:32 PDT 2010
Author: lattner
Date: Thu Jul 29 13:39:32 2010
New Revision: 109790
URL: http://llvm.org/viewvc/llvm-project?rev=109790&view=rev
Log:
Implement the clang-side of detection for when to pass as
<2 x float> instead of double. This works but can't be turned
on until I teach codegen to pass <2 x float> as one XMM register
instead of two.
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=109790&r1=109789&r2=109790&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Thu Jul 29 13:39:32 2010
@@ -1297,6 +1297,35 @@
return false;
}
+/// ContainsFloatAtOffset - Return true if the specified LLVM IR type has a
+/// float member at the specified offset. For example, {int,{float}} has a
+/// float at offset 4. It is conservatively correct for this routine to return
+/// false.
+static bool ContainsFloatAtOffset(const llvm::Type *IRType, unsigned IROffset,
+ const llvm::TargetData &TD) {
+ // Base case if we find a float.
+ if (IROffset == 0 && IRType->isFloatTy())
+ return true;
+
+ // If this is a struct, recurse into the field at the specified offset.
+ if (const llvm::StructType *STy = dyn_cast<llvm::StructType>(IRType)) {
+ const llvm::StructLayout *SL = TD.getStructLayout(STy);
+ unsigned Elt = SL->getElementContainingOffset(IROffset);
+ IROffset -= SL->getElementOffset(Elt);
+ return ContainsFloatAtOffset(STy->getElementType(Elt), IROffset, TD);
+ }
+
+ // If this is an array, recurse into the field at the specified offset.
+ if (const llvm::ArrayType *ATy = dyn_cast<llvm::ArrayType>(IRType)) {
+ const llvm::Type *EltTy = ATy->getElementType();
+ unsigned EltSize = TD.getTypeAllocSize(EltTy);
+ IROffset -= IROffset/EltSize*EltSize;
+ return ContainsFloatAtOffset(EltTy, IROffset, TD);
+ }
+
+ return false;
+}
+
/// GetSSETypeAtOffset - Return a type that will be passed by the backend in the
/// low 8 bytes of an XMM register, corresponding to the SSE class.
@@ -1310,9 +1339,16 @@
SourceOffset*8+64, getContext()))
return llvm::Type::getFloatTy(getVMContext());
- // FIXME: <2 x float> doesn't pass as one XMM register yet. Don't enable this
- // code until it does.
- //return llvm::VectorType::get(llvm::Type::getFloatTy(getVMContext()), 2);
+ // We want to pass as <2 x float> if the LLVM IR type contains a float at
+ // offset+0 and offset+4. Walk the LLVM IR type to find out if this is the
+ // case.
+ if (ContainsFloatAtOffset(IRType, IROffset, getTargetData()) &&
+ ContainsFloatAtOffset(IRType, IROffset+4, getTargetData())) {
+ // FIXME: <2 x float> doesn't pass as one XMM register yet. Don't enable
+ // this code until it does.
+ //return llvm::VectorType::get(llvm::Type::getFloatTy(getVMContext()), 2);
+
+ }
return llvm::Type::getDoubleTy(getVMContext());
}
More information about the cfe-commits
mailing list