[SLP] Make DataLayout a member variable.

llvm-svn: 263656
This commit is contained in:
Chad Rosier 2016-03-16 19:48:42 +00:00
parent 56fabf9b55
commit fea398188c
1 changed files with 35 additions and 38 deletions

View File

@ -368,10 +368,11 @@ public:
BoUpSLP(Function *Func, ScalarEvolution *Se, TargetTransformInfo *Tti,
TargetLibraryInfo *TLi, AliasAnalysis *Aa, LoopInfo *Li,
DominatorTree *Dt, AssumptionCache *AC, DemandedBits *DB)
DominatorTree *Dt, AssumptionCache *AC, DemandedBits *DB,
const DataLayout *DL)
: NumLoadsWantToKeepOrder(0), NumLoadsWantToChangeOrder(0), F(Func),
SE(Se), TTI(Tti), TLI(TLi), AA(Aa), LI(Li), DT(Dt), AC(AC), DB(DB),
Builder(Se->getContext()) {
DL(DL), Builder(Se->getContext()) {
CodeMetrics::collectEphemeralValues(F, AC, EphValues);
}
@ -925,6 +926,7 @@ private:
DominatorTree *DT;
AssumptionCache *AC;
DemandedBits *DB;
const DataLayout *DL;
/// Instruction builder to construct the vectorized tree.
IRBuilder<> Builder;
@ -1176,11 +1178,10 @@ void BoUpSLP::buildTree_rec(ArrayRef<Value *> VL, unsigned Depth) {
// loading/storing it as an i8 struct. If we vectorize loads/stores from
// such a struct we read/write packed bits disagreeing with the
// unvectorized version.
const DataLayout &DL = F->getParent()->getDataLayout();
Type *ScalarTy = VL[0]->getType();
if (DL.getTypeSizeInBits(ScalarTy) !=
DL.getTypeAllocSizeInBits(ScalarTy)) {
if (DL->getTypeSizeInBits(ScalarTy) !=
DL->getTypeAllocSizeInBits(ScalarTy)) {
BS.cancelScheduling(VL);
newTreeEntry(VL, false);
DEBUG(dbgs() << "SLP: Gathering loads of non-packed type.\n");
@ -1196,8 +1197,8 @@ void BoUpSLP::buildTree_rec(ArrayRef<Value *> VL, unsigned Depth) {
return;
}
if (!isConsecutiveAccess(VL[i], VL[i + 1], DL, *SE)) {
if (VL.size() == 2 && isConsecutiveAccess(VL[1], VL[0], DL, *SE)) {
if (!isConsecutiveAccess(VL[i], VL[i + 1], *DL, *SE)) {
if (VL.size() == 2 && isConsecutiveAccess(VL[1], VL[0], *DL, *SE)) {
++NumLoadsWantToChangeOrder;
}
BS.cancelScheduling(VL);
@ -1366,10 +1367,9 @@ void BoUpSLP::buildTree_rec(ArrayRef<Value *> VL, unsigned Depth) {
return;
}
case Instruction::Store: {
const DataLayout &DL = F->getParent()->getDataLayout();
// Check if the stores are consecutive or of we need to swizzle them.
for (unsigned i = 0, e = VL.size() - 1; i < e; ++i)
if (!isConsecutiveAccess(VL[i], VL[i + 1], DL, *SE)) {
if (!isConsecutiveAccess(VL[i], VL[i + 1], *DL, *SE)) {
BS.cancelScheduling(VL);
newTreeEntry(VL, false);
DEBUG(dbgs() << "SLP: Non-consecutive store.\n");
@ -1872,8 +1872,6 @@ int BoUpSLP::getGatherCost(ArrayRef<Value *> VL) {
void BoUpSLP::reorderAltShuffleOperands(ArrayRef<Value *> VL,
SmallVectorImpl<Value *> &Left,
SmallVectorImpl<Value *> &Right) {
const DataLayout &DL = F->getParent()->getDataLayout();
// Push left and right operands of binary operation into Left and Right
for (unsigned i = 0, e = VL.size(); i < e; ++i) {
Left.push_back(cast<Instruction>(VL[i])->getOperand(0));
@ -1887,10 +1885,11 @@ void BoUpSLP::reorderAltShuffleOperands(ArrayRef<Value *> VL,
if (LoadInst *L1 = dyn_cast<LoadInst>(Right[j + 1])) {
Instruction *VL1 = cast<Instruction>(VL[j]);
Instruction *VL2 = cast<Instruction>(VL[j + 1]);
if (VL1->isCommutative() && isConsecutiveAccess(L, L1, DL, *SE)) {
if (VL1->isCommutative() && isConsecutiveAccess(L, L1, *DL, *SE)) {
std::swap(Left[j], Right[j]);
continue;
} else if (VL2->isCommutative() && isConsecutiveAccess(L, L1, DL, *SE)) {
} else if (VL2->isCommutative() &&
isConsecutiveAccess(L, L1, *DL, *SE)) {
std::swap(Left[j + 1], Right[j + 1]);
continue;
}
@ -1901,10 +1900,11 @@ void BoUpSLP::reorderAltShuffleOperands(ArrayRef<Value *> VL,
if (LoadInst *L1 = dyn_cast<LoadInst>(Left[j + 1])) {
Instruction *VL1 = cast<Instruction>(VL[j]);
Instruction *VL2 = cast<Instruction>(VL[j + 1]);
if (VL1->isCommutative() && isConsecutiveAccess(L, L1, DL, *SE)) {
if (VL1->isCommutative() && isConsecutiveAccess(L, L1, *DL, *SE)) {
std::swap(Left[j], Right[j]);
continue;
} else if (VL2->isCommutative() && isConsecutiveAccess(L, L1, DL, *SE)) {
} else if (VL2->isCommutative() &&
isConsecutiveAccess(L, L1, *DL, *SE)) {
std::swap(Left[j + 1], Right[j + 1]);
continue;
}
@ -2034,8 +2034,6 @@ void BoUpSLP::reorderInputsAccordingToOpcode(ArrayRef<Value *> VL,
if (SplatRight || SplatLeft)
return;
const DataLayout &DL = F->getParent()->getDataLayout();
// Finally check if we can get longer vectorizable chain by reordering
// without breaking the good operand order detected above.
// E.g. If we have something like-
@ -2054,7 +2052,7 @@ void BoUpSLP::reorderInputsAccordingToOpcode(ArrayRef<Value *> VL,
for (unsigned j = 0; j < VL.size() - 1; ++j) {
if (LoadInst *L = dyn_cast<LoadInst>(Left[j])) {
if (LoadInst *L1 = dyn_cast<LoadInst>(Right[j + 1])) {
if (isConsecutiveAccess(L, L1, DL, *SE)) {
if (isConsecutiveAccess(L, L1, *DL, *SE)) {
std::swap(Left[j + 1], Right[j + 1]);
continue;
}
@ -2062,7 +2060,7 @@ void BoUpSLP::reorderInputsAccordingToOpcode(ArrayRef<Value *> VL,
}
if (LoadInst *L = dyn_cast<LoadInst>(Right[j])) {
if (LoadInst *L1 = dyn_cast<LoadInst>(Left[j + 1])) {
if (isConsecutiveAccess(L, L1, DL, *SE)) {
if (isConsecutiveAccess(L, L1, *DL, *SE)) {
std::swap(Left[j + 1], Right[j + 1]);
continue;
}
@ -2158,7 +2156,6 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E) {
return Gather(E->Scalars, VecTy);
}
const DataLayout &DL = F->getParent()->getDataLayout();
unsigned Opcode = getSameOpcode(E->Scalars);
switch (Opcode) {
@ -2355,7 +2352,7 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E) {
unsigned Alignment = LI->getAlignment();
LI = Builder.CreateLoad(VecPtr);
if (!Alignment) {
Alignment = DL.getABITypeAlignment(ScalarLoadTy);
Alignment = DL->getABITypeAlignment(ScalarLoadTy);
}
LI->setAlignment(Alignment);
E->VectorizedValue = LI;
@ -2386,7 +2383,7 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E) {
ExternalUser(SI->getPointerOperand(), cast<User>(VecPtr), 0));
if (!Alignment) {
Alignment = DL.getABITypeAlignment(SI->getValueOperand()->getType());
Alignment = DL->getABITypeAlignment(SI->getValueOperand()->getType());
}
S->setAlignment(Alignment);
E->VectorizedValue = S;
@ -3133,12 +3130,10 @@ void BoUpSLP::scheduleBlock(BlockScheduling *BS) {
}
unsigned BoUpSLP::getVectorElementSize(Value *V) {
auto &DL = F->getParent()->getDataLayout();
// If V is a store, just return the width of the stored value without
// traversing the expression tree. This is the common case.
if (auto *Store = dyn_cast<StoreInst>(V))
return DL.getTypeSizeInBits(Store->getValueOperand()->getType());
return DL->getTypeSizeInBits(Store->getValueOperand()->getType());
// If V is not a store, we can traverse the expression tree to find loads
// that feed it. The type of the loaded value may indicate a more suitable
@ -3166,7 +3161,7 @@ unsigned BoUpSLP::getVectorElementSize(Value *V) {
// If the current instruction is a load, update MaxWidth to reflect the
// width of the loaded value.
else if (isa<LoadInst>(I))
MaxWidth = std::max<unsigned>(MaxWidth, DL.getTypeSizeInBits(Ty));
MaxWidth = std::max<unsigned>(MaxWidth, DL->getTypeSizeInBits(Ty));
// Otherwise, we need to visit the operands of the instruction. We only
// handle the interesting cases from buildTree here. If an operand is an
@ -3187,7 +3182,7 @@ unsigned BoUpSLP::getVectorElementSize(Value *V) {
// If we didn't encounter a memory access in the expression tree, or if we
// gave up for some reason, just return the width of V.
if (!MaxWidth || FoundUnknownInst)
return DL.getTypeSizeInBits(V->getType());
return DL->getTypeSizeInBits(V->getType());
// Otherwise, return the maximum width we found.
return MaxWidth;
@ -3265,8 +3260,6 @@ static bool collectValuesToDemote(Value *V, SmallPtrSetImpl<Value *> &Expr,
}
void BoUpSLP::computeMinimumValueSizes() {
auto &DL = F->getParent()->getDataLayout();
// If there are no external uses, the expression tree must be rooted by a
// store. We can't demote in-memory values, so there is nothing to do here.
if (ExternalUses.empty())
@ -3334,11 +3327,11 @@ void BoUpSLP::computeMinimumValueSizes() {
// We start by looking at each entry that can be demoted. We compute the
// maximum bit width required to store the scalar by using ValueTracking to
// compute the number of high-order bits we can truncate.
if (MaxBitWidth == DL.getTypeSizeInBits(TreeRoot[0]->getType())) {
if (MaxBitWidth == DL->getTypeSizeInBits(TreeRoot[0]->getType())) {
MaxBitWidth = 8u;
for (auto *Scalar : ToDemote) {
auto NumSignBits = ComputeNumSignBits(Scalar, DL, 0, AC, 0, DT);
auto NumTypeBits = DL.getTypeSizeInBits(Scalar->getType());
auto NumSignBits = ComputeNumSignBits(Scalar, *DL, 0, AC, 0, DT);
auto NumTypeBits = DL->getTypeSizeInBits(Scalar->getType());
MaxBitWidth = std::max<unsigned>(NumTypeBits - NumSignBits, MaxBitWidth);
}
}
@ -3385,6 +3378,12 @@ struct SLPVectorizer : public FunctionPass {
DominatorTree *DT;
AssumptionCache *AC;
DemandedBits *DB;
const DataLayout *DL;
bool doInitialization(Module &M) override {
DL = &M.getDataLayout();
return false;
}
bool runOnFunction(Function &F) override {
if (skipOptnoneFunction(F))
@ -3430,7 +3429,7 @@ struct SLPVectorizer : public FunctionPass {
// Use the bottom up slp vectorizer to construct chains that start with
// store instructions.
BoUpSLP R(&F, SE, TTI, TLI, AA, LI, DT, AC, DB);
BoUpSLP R(&F, SE, TTI, TLI, AA, LI, DT, AC, DB, DL);
// A general note: the vectorizer must use BoUpSLP::eraseInstruction() to
// delete instructions.
@ -3611,7 +3610,6 @@ bool SLPVectorizer::vectorizeStores(ArrayRef<StoreInst *> Stores,
// all of the pairs of stores that follow each other.
SmallVector<unsigned, 16> IndexQueue;
for (unsigned i = 0, e = Stores.size(); i < e; ++i) {
const DataLayout &DL = Stores[i]->getModule()->getDataLayout();
IndexQueue.clear();
// If a store has multiple consecutive store candidates, search Stores
// array according to the sequence: from i+1 to e, then from i-1 to 0.
@ -3624,7 +3622,7 @@ bool SLPVectorizer::vectorizeStores(ArrayRef<StoreInst *> Stores,
IndexQueue.push_back(j - 1);
for (auto &k : IndexQueue) {
if (isConsecutiveAccess(Stores[i], Stores[k], DL, *SE)) {
if (isConsecutiveAccess(Stores[i], Stores[k], *DL, *SE)) {
Tails.insert(Stores[k]);
Heads.insert(Stores[i]);
ConsecutiveChain[Stores[i]] = Stores[k];
@ -3673,7 +3671,6 @@ void SLPVectorizer::collectSeedInstructions(BasicBlock *BB) {
Stores.clear();
GEPs.clear();
NumStores = NumGEPs = 0;
const DataLayout &DL = BB->getModule()->getDataLayout();
// Visit the store and getelementptr instructions in BB and organize them in
// Stores and GEPs according to the underlying objects of their pointer
@ -3687,7 +3684,7 @@ void SLPVectorizer::collectSeedInstructions(BasicBlock *BB) {
continue;
if (!isValidElementType(SI->getValueOperand()->getType()))
continue;
Stores[GetUnderlyingObject(SI->getPointerOperand(), DL)].push_back(SI);
Stores[GetUnderlyingObject(SI->getPointerOperand(), *DL)].push_back(SI);
++NumStores;
}
@ -3700,7 +3697,7 @@ void SLPVectorizer::collectSeedInstructions(BasicBlock *BB) {
continue;
if (!isValidElementType(Idx->getType()))
continue;
GEPs[GetUnderlyingObject(GEP->getPointerOperand(), DL)].push_back(GEP);
GEPs[GetUnderlyingObject(GEP->getPointerOperand(), *DL)].push_back(GEP);
++NumGEPs;
}
}