зеркало из https://github.com/microsoft/clang.git
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 :) git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@109738 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
e2962be11e
Коммит
021c3a349d
|
@ -1226,9 +1226,24 @@ static bool BitsContainNoUserData(QualType Ty, unsigned StartBit,
|
|||
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 @@ Get8ByteTypeAtOffset(const llvm::Type *IRType, unsigned IROffset,
|
|||
}
|
||||
}
|
||||
|
||||
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 =
|
||||
|
|
|
@ -194,3 +194,13 @@ void f28(struct f28c C) {
|
|||
// 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)
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче