зеркало из https://github.com/microsoft/clang-1.git
Step forward with supporting of ARM homogenous aggregates:
- Handle unions - Handle C++ classes git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@154664 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
51b92401c9
Коммит
eaf856db5d
|
@ -419,16 +419,37 @@ void CodeGenTypes::GetExpandedTypes(QualType type,
|
|||
uint64_t NumElts = AT->getSize().getZExtValue();
|
||||
for (uint64_t Elt = 0; Elt < NumElts; ++Elt)
|
||||
GetExpandedTypes(AT->getElementType(), expandedTypes);
|
||||
} else if (const RecordType *RT = type->getAsStructureType()) {
|
||||
} else if (const RecordType *RT = type->getAs<RecordType>()) {
|
||||
const RecordDecl *RD = RT->getDecl();
|
||||
assert(!RD->hasFlexibleArrayMember() &&
|
||||
"Cannot expand structure with flexible array.");
|
||||
for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
|
||||
i != e; ++i) {
|
||||
const FieldDecl *FD = *i;
|
||||
assert(!FD->isBitField() &&
|
||||
"Cannot expand structure with bit-field members.");
|
||||
GetExpandedTypes(FD->getType(), expandedTypes);
|
||||
if (RD->isUnion()) {
|
||||
// Unions can be here only in degenerative cases - all the fields are same
|
||||
// after flattening. Thus we have to use the "largest" field.
|
||||
const FieldDecl *LargestFD = 0;
|
||||
CharUnits UnionSize = CharUnits::Zero();
|
||||
|
||||
for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
|
||||
i != e; ++i) {
|
||||
const FieldDecl *FD = *i;
|
||||
assert(!FD->isBitField() &&
|
||||
"Cannot expand structure with bit-field members.");
|
||||
CharUnits FieldSize = getContext().getTypeSizeInChars(FD->getType());
|
||||
if (UnionSize < FieldSize) {
|
||||
UnionSize = FieldSize;
|
||||
LargestFD = FD;
|
||||
}
|
||||
}
|
||||
if (LargestFD)
|
||||
GetExpandedTypes(LargestFD->getType(), expandedTypes);
|
||||
} else {
|
||||
for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
|
||||
i != e; ++i) {
|
||||
const FieldDecl *FD = *i;
|
||||
assert(!FD->isBitField() &&
|
||||
"Cannot expand structure with bit-field members.");
|
||||
GetExpandedTypes(FD->getType(), expandedTypes);
|
||||
}
|
||||
}
|
||||
} else if (const ComplexType *CT = type->getAs<ComplexType>()) {
|
||||
llvm::Type *EltTy = ConvertType(CT->getElementType());
|
||||
|
@ -453,16 +474,40 @@ CodeGenFunction::ExpandTypeFromArgs(QualType Ty, LValue LV,
|
|||
LValue LV = MakeAddrLValue(EltAddr, EltTy);
|
||||
AI = ExpandTypeFromArgs(EltTy, LV, AI);
|
||||
}
|
||||
} else if (const RecordType *RT = Ty->getAsStructureType()) {
|
||||
} else if (const RecordType *RT = Ty->getAs<RecordType>()) {
|
||||
RecordDecl *RD = RT->getDecl();
|
||||
for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
|
||||
i != e; ++i) {
|
||||
FieldDecl *FD = *i;
|
||||
QualType FT = FD->getType();
|
||||
if (RD->isUnion()) {
|
||||
// Unions can be here only in degenerative cases - all the fields are same
|
||||
// after flattening. Thus we have to use the "largest" field.
|
||||
const FieldDecl *LargestFD = 0;
|
||||
CharUnits UnionSize = CharUnits::Zero();
|
||||
|
||||
// FIXME: What are the right qualifiers here?
|
||||
LValue LV = EmitLValueForField(Addr, FD, 0);
|
||||
AI = ExpandTypeFromArgs(FT, LV, AI);
|
||||
for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
|
||||
i != e; ++i) {
|
||||
const FieldDecl *FD = *i;
|
||||
assert(!FD->isBitField() &&
|
||||
"Cannot expand structure with bit-field members.");
|
||||
CharUnits FieldSize = getContext().getTypeSizeInChars(FD->getType());
|
||||
if (UnionSize < FieldSize) {
|
||||
UnionSize = FieldSize;
|
||||
LargestFD = FD;
|
||||
}
|
||||
}
|
||||
if (LargestFD) {
|
||||
// FIXME: What are the right qualifiers here?
|
||||
LValue LV = EmitLValueForField(Addr, LargestFD, 0);
|
||||
AI = ExpandTypeFromArgs(LargestFD->getType(), LV, AI);
|
||||
}
|
||||
} else {
|
||||
for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
|
||||
i != e; ++i) {
|
||||
FieldDecl *FD = *i;
|
||||
QualType FT = FD->getType();
|
||||
|
||||
// FIXME: What are the right qualifiers here?
|
||||
LValue LV = EmitLValueForField(Addr, FD, 0);
|
||||
AI = ExpandTypeFromArgs(FT, LV, AI);
|
||||
}
|
||||
}
|
||||
} else if (const ComplexType *CT = Ty->getAs<ComplexType>()) {
|
||||
QualType EltTy = CT->getElementType();
|
||||
|
@ -1760,26 +1805,38 @@ void CodeGenFunction::ExpandTypeToArgs(QualType Ty, RValue RV,
|
|||
EltRV = EmitLoadOfLValue(LV);
|
||||
ExpandTypeToArgs(EltTy, EltRV, Args, IRFuncTy);
|
||||
}
|
||||
} else if (const RecordType *RT = Ty->getAsStructureType()) {
|
||||
} else if (const RecordType *RT = Ty->getAs<RecordType>()) {
|
||||
RecordDecl *RD = RT->getDecl();
|
||||
assert(RV.isAggregate() && "Unexpected rvalue during struct expansion");
|
||||
llvm::Value *Addr = RV.getAggregateAddr();
|
||||
for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
|
||||
i != e; ++i) {
|
||||
FieldDecl *FD = *i;
|
||||
QualType FT = FD->getType();
|
||||
|
||||
// FIXME: What are the right qualifiers here?
|
||||
LValue LV = EmitLValueForField(Addr, FD, 0);
|
||||
RValue FldRV;
|
||||
if (FT->isAnyComplexType())
|
||||
// FIXME: Volatile?
|
||||
FldRV = RValue::getComplex(LoadComplexFromAddr(LV.getAddress(), false));
|
||||
else if (CodeGenFunction::hasAggregateLLVMType(FT))
|
||||
FldRV = LV.asAggregateRValue();
|
||||
else
|
||||
FldRV = EmitLoadOfLValue(LV);
|
||||
ExpandTypeToArgs(FT, FldRV, Args, IRFuncTy);
|
||||
|
||||
if (RD->isUnion()) {
|
||||
const FieldDecl *LargestFD = 0;
|
||||
CharUnits UnionSize = CharUnits::Zero();
|
||||
|
||||
for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
|
||||
i != e; ++i) {
|
||||
const FieldDecl *FD = *i;
|
||||
assert(!FD->isBitField() &&
|
||||
"Cannot expand structure with bit-field members.");
|
||||
CharUnits FieldSize = getContext().getTypeSizeInChars(FD->getType());
|
||||
if (UnionSize < FieldSize) {
|
||||
UnionSize = FieldSize;
|
||||
LargestFD = FD;
|
||||
}
|
||||
}
|
||||
if (LargestFD) {
|
||||
RValue FldRV = EmitRValueForField(Addr, LargestFD);
|
||||
ExpandTypeToArgs(LargestFD->getType(), FldRV, Args, IRFuncTy);
|
||||
}
|
||||
} else {
|
||||
for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
|
||||
i != e; ++i) {
|
||||
FieldDecl *FD = *i;
|
||||
|
||||
RValue FldRV = EmitRValueForField(Addr, FD);
|
||||
ExpandTypeToArgs(FD->getType(), FldRV, Args, IRFuncTy);
|
||||
}
|
||||
}
|
||||
} else if (Ty->isAnyComplexType()) {
|
||||
ComplexPairTy CV = RV.getComplexVal();
|
||||
|
|
|
@ -2378,6 +2378,19 @@ LValue CodeGenFunction::EmitMaterializeTemporaryExpr(
|
|||
return MakeAddrLValue(RV.getScalarVal(), E->getType());
|
||||
}
|
||||
|
||||
RValue CodeGenFunction::EmitRValueForField(llvm::Value *Addr,
|
||||
const FieldDecl *FD) {
|
||||
QualType FT = FD->getType();
|
||||
// FIXME: What are the right qualifiers here?
|
||||
LValue LV = EmitLValueForField(Addr, FD, 0);
|
||||
if (FT->isAnyComplexType())
|
||||
// FIXME: Volatile?
|
||||
return RValue::getComplex(LoadComplexFromAddr(LV.getAddress(), false));
|
||||
else if (CodeGenFunction::hasAggregateLLVMType(FT))
|
||||
return LV.asAggregateRValue();
|
||||
|
||||
return EmitLoadOfLValue(LV);
|
||||
}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Expression Emission
|
||||
|
|
|
@ -2104,6 +2104,8 @@ public:
|
|||
LValue EmitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E);
|
||||
LValue EmitOpaqueValueLValue(const OpaqueValueExpr *e);
|
||||
|
||||
RValue EmitRValueForField(llvm::Value *Addr, const FieldDecl *FD);
|
||||
|
||||
class ConstantEmission {
|
||||
llvm::PointerIntPair<llvm::Constant*, 1, bool> ValueAndIsReference;
|
||||
ConstantEmission(llvm::Constant *C, bool isReference)
|
||||
|
|
|
@ -2527,19 +2527,16 @@ void ARMABIInfo::computeInfo(CGFunctionInfo &FI) const {
|
|||
static bool isHomogeneousAggregate(QualType Ty, const Type *&Base,
|
||||
ASTContext &Context,
|
||||
uint64_t *HAMembers = 0) {
|
||||
uint64_t Members;
|
||||
uint64_t Members = 0;
|
||||
if (const ConstantArrayType *AT = Context.getAsConstantArrayType(Ty)) {
|
||||
if (!isHomogeneousAggregate(AT->getElementType(), Base, Context, &Members))
|
||||
return false;
|
||||
Members *= AT->getSize().getZExtValue();
|
||||
} else if (const RecordType *RT = Ty->getAs<RecordType>()) {
|
||||
const RecordDecl *RD = RT->getDecl();
|
||||
if (RD->isUnion() || RD->hasFlexibleArrayMember())
|
||||
if (RD->hasFlexibleArrayMember())
|
||||
return false;
|
||||
if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
|
||||
if (!CXXRD->isAggregate())
|
||||
return false;
|
||||
}
|
||||
|
||||
Members = 0;
|
||||
for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
|
||||
i != e; ++i) {
|
||||
|
@ -2547,7 +2544,9 @@ static bool isHomogeneousAggregate(QualType Ty, const Type *&Base,
|
|||
uint64_t FldMembers;
|
||||
if (!isHomogeneousAggregate(FD->getType(), Base, Context, &FldMembers))
|
||||
return false;
|
||||
Members += FldMembers;
|
||||
|
||||
Members = (RD->isUnion() ?
|
||||
std::max(Members, FldMembers) : Members + FldMembers);
|
||||
}
|
||||
} else {
|
||||
Members = 1;
|
||||
|
@ -2584,7 +2583,8 @@ static bool isHomogeneousAggregate(QualType Ty, const Type *&Base,
|
|||
// Homogeneous Aggregates can have at most 4 members of the base type.
|
||||
if (HAMembers)
|
||||
*HAMembers = Members;
|
||||
return (Members <= 4);
|
||||
|
||||
return (Members > 0 && Members <= 4);
|
||||
}
|
||||
|
||||
ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty) const {
|
||||
|
@ -2609,8 +2609,10 @@ ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty) const {
|
|||
if (getABIKind() == ARMABIInfo::AAPCS_VFP) {
|
||||
// Homogeneous Aggregates need to be expanded.
|
||||
const Type *Base = 0;
|
||||
if (isHomogeneousAggregate(Ty, Base, getContext()))
|
||||
if (isHomogeneousAggregate(Ty, Base, getContext())) {
|
||||
assert(Base && "Base class should be set for homogeneous aggregate");
|
||||
return ABIArgInfo::getExpand();
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, pass by coercing to a structure of the appropriate size.
|
||||
|
@ -2776,9 +2778,11 @@ ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy) const {
|
|||
// Check for homogeneous aggregates with AAPCS-VFP.
|
||||
if (getABIKind() == AAPCS_VFP) {
|
||||
const Type *Base = 0;
|
||||
if (isHomogeneousAggregate(RetTy, Base, getContext()))
|
||||
if (isHomogeneousAggregate(RetTy, Base, getContext())) {
|
||||
assert(Base && "Base class should be set for homogeneous aggregate");
|
||||
// Homogeneous Aggregates are returned directly.
|
||||
return ABIArgInfo::getDirect();
|
||||
}
|
||||
}
|
||||
|
||||
// Aggregates <= 4 bytes are returned in r0; other aggregates
|
||||
|
|
Загрузка…
Ссылка в новой задаче