forked from OSchip/llvm-project
Unpack array of all sizes in InstCombine
Summary: This is another step toward improving fca support. This unpack load of array in a series of load to array's elements. Reviewers: chandlerc, joker.eph, majnemer, reames, hfinkel Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D15890 llvm-svn: 262521
This commit is contained in:
parent
dce8d8b3f1
commit
7cd3fe7db6
|
@ -574,13 +574,46 @@ static Instruction *unpackLoadToAggregate(InstCombiner &IC, LoadInst &LI) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto *AT = dyn_cast<ArrayType>(T)) {
|
if (auto *AT = dyn_cast<ArrayType>(T)) {
|
||||||
// If the array only have one element, we unpack.
|
auto *ET = AT->getElementType();
|
||||||
if (AT->getNumElements() == 1) {
|
auto NumElements = AT->getNumElements();
|
||||||
LoadInst *NewLoad = combineLoadToNewType(IC, LI, AT->getElementType(),
|
if (NumElements == 1) {
|
||||||
".unpack");
|
LoadInst *NewLoad = combineLoadToNewType(IC, LI, ET, ".unpack");
|
||||||
return IC.replaceInstUsesWith(LI, IC.Builder->CreateInsertValue(
|
return IC.replaceInstUsesWith(LI, IC.Builder->CreateInsertValue(
|
||||||
UndefValue::get(T), NewLoad, 0, LI.getName()));
|
UndefValue::get(T), NewLoad, 0, Name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const DataLayout &DL = IC.getDataLayout();
|
||||||
|
auto EltSize = DL.getTypeAllocSize(ET);
|
||||||
|
auto Align = LI.getAlignment();
|
||||||
|
if (!Align)
|
||||||
|
Align = DL.getABITypeAlignment(T);
|
||||||
|
|
||||||
|
SmallString<16> LoadName = Name;
|
||||||
|
LoadName += ".unpack";
|
||||||
|
SmallString<16> EltName = Name;
|
||||||
|
EltName += ".elt";
|
||||||
|
|
||||||
|
auto *Addr = LI.getPointerOperand();
|
||||||
|
auto *IdxType = Type::getInt64Ty(T->getContext());
|
||||||
|
auto *Zero = ConstantInt::get(IdxType, 0);
|
||||||
|
|
||||||
|
Value *V = UndefValue::get(T);
|
||||||
|
uint64_t Offset = 0;
|
||||||
|
for (uint64_t i = 0; i < NumElements; i++) {
|
||||||
|
Value *Indices[2] = {
|
||||||
|
Zero,
|
||||||
|
ConstantInt::get(IdxType, i),
|
||||||
|
};
|
||||||
|
auto *Ptr = IC.Builder->CreateInBoundsGEP(AT, Addr, makeArrayRef(Indices),
|
||||||
|
EltName);
|
||||||
|
auto *L = IC.Builder->CreateAlignedLoad(Ptr, MinAlign(Align, Offset),
|
||||||
|
LoadName);
|
||||||
|
V = IC.Builder->CreateInsertValue(V, L, i);
|
||||||
|
Offset += EltSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
V->setName(Name);
|
||||||
|
return IC.replaceInstUsesWith(LI, V);
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
|
@ -137,6 +137,27 @@ define %B @structB(%B* %b.ptr) {
|
||||||
ret %B %1
|
ret %B %1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
define [2 x %B] @loadArrayOfB([2 x %B]* %ab.ptr) {
|
||||||
|
; CHECK-LABEL: loadArrayOfB
|
||||||
|
; CHECK-NEXT: [[GEP1:%[a-z0-9\.]+]] = getelementptr inbounds [2 x %B], [2 x %B]* %ab.ptr, i64 0, i64 0, i32 0
|
||||||
|
; CHECK-NEXT: [[LOAD1:%[a-z0-9\.]+]] = load i8*, i8** [[GEP1]], align 8
|
||||||
|
; CHECK-NEXT: [[IV1:%[a-z0-9\.]+]] = insertvalue %B undef, i8* [[LOAD1]], 0
|
||||||
|
; CHECK-NEXT: [[GEP2:%[a-z0-9\.]+]] = getelementptr inbounds [2 x %B], [2 x %B]* %ab.ptr, i64 0, i64 0, i32 1
|
||||||
|
; CHECK-NEXT: [[LOAD2:%[a-z0-9\.]+]] = load i64, i64* [[GEP2]], align 8
|
||||||
|
; CHECK-NEXT: [[IV2:%[a-z0-9\.]+]] = insertvalue %B [[IV1]], i64 [[LOAD2]], 1
|
||||||
|
; CHECK-NEXT: [[IV3:%[a-z0-9\.]+]] = insertvalue [2 x %B] undef, %B [[IV2]], 0
|
||||||
|
; CHECK-NEXT: [[GEP3:%[a-z0-9\.]+]] = getelementptr inbounds [2 x %B], [2 x %B]* %ab.ptr, i64 0, i64 1, i32 0
|
||||||
|
; CHECK-NEXT: [[LOAD3:%[a-z0-9\.]+]] = load i8*, i8** [[GEP3]], align 8
|
||||||
|
; CHECK-NEXT: [[IV4:%[a-z0-9\.]+]] = insertvalue %B undef, i8* [[LOAD3]], 0
|
||||||
|
; CHECK-NEXT: [[GEP4:%[a-z0-9\.]+]] = getelementptr inbounds [2 x %B], [2 x %B]* %ab.ptr, i64 0, i64 1, i32 1
|
||||||
|
; CHECK-NEXT: [[LOAD4:%[a-z0-9\.]+]] = load i64, i64* [[GEP4]], align 8
|
||||||
|
; CHECK-NEXT: [[IV5:%[a-z0-9\.]+]] = insertvalue %B [[IV4]], i64 [[LOAD4]], 1
|
||||||
|
; CHECK-NEXT: [[IV6:%[a-z0-9\.]+]] = insertvalue [2 x %B] [[IV3]], %B [[IV5]], 1
|
||||||
|
; CHECK-NEXT: ret [2 x %B] [[IV6]]
|
||||||
|
%1 = load [2 x %B], [2 x %B]* %ab.ptr, align 8
|
||||||
|
ret [2 x %B] %1
|
||||||
|
}
|
||||||
|
|
||||||
%struct.S = type <{ i8, %struct.T }>
|
%struct.S = type <{ i8, %struct.T }>
|
||||||
%struct.T = type { i32, i32 }
|
%struct.T = type { i32, i32 }
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue