2017-09-01 23:37:29 +02:00
|
|
|
//===- SLPVectorizer.h ------------------------------------------*- C++ -*-===//
|
2016-06-15 10:43:40 +02:00
|
|
|
//
|
2019-01-19 09:50:56 +01:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2016-06-15 10:43:40 +02:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// This pass implements the Bottom Up SLP vectorizer. It detects consecutive
|
|
|
|
// stores that can be put together into vector-stores. Next, it attempts to
|
|
|
|
// construct vectorizable tree using the use-def chains. If a profitable tree
|
|
|
|
// was found, the SLP vectorizer performs vectorization on the tree.
|
|
|
|
//
|
|
|
|
// The pass is inspired by the work described in the paper:
|
|
|
|
// "Loop-Aware SLP in GCC" by Ira Rosen, Dorit Nuzman, Ayal Zaks.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2016-07-10 00:56:39 +02:00
|
|
|
#ifndef LLVM_TRANSFORMS_VECTORIZE_SLPVECTORIZER_H
|
|
|
|
#define LLVM_TRANSFORMS_VECTORIZE_SLPVECTORIZER_H
|
2016-06-15 10:43:40 +02:00
|
|
|
|
2017-09-01 23:37:29 +02:00
|
|
|
#include "llvm/ADT/ArrayRef.h"
|
2016-06-15 10:43:40 +02:00
|
|
|
#include "llvm/ADT/MapVector.h"
|
2017-09-01 23:37:29 +02:00
|
|
|
#include "llvm/ADT/None.h"
|
|
|
|
#include "llvm/ADT/SmallVector.h"
|
2016-06-15 10:43:40 +02:00
|
|
|
#include "llvm/IR/PassManager.h"
|
|
|
|
|
|
|
|
namespace llvm {
|
|
|
|
|
2020-09-15 16:23:19 +02:00
|
|
|
class AAResults;
|
2017-09-01 23:37:29 +02:00
|
|
|
class AssumptionCache;
|
|
|
|
class BasicBlock;
|
|
|
|
class CmpInst;
|
|
|
|
class DataLayout;
|
|
|
|
class DemandedBits;
|
|
|
|
class DominatorTree;
|
|
|
|
class Function;
|
2020-09-15 16:23:19 +02:00
|
|
|
class GetElementPtrInst;
|
2017-09-01 23:37:29 +02:00
|
|
|
class InsertElementInst;
|
|
|
|
class InsertValueInst;
|
|
|
|
class Instruction;
|
|
|
|
class LoopInfo;
|
|
|
|
class OptimizationRemarkEmitter;
|
|
|
|
class PHINode;
|
|
|
|
class ScalarEvolution;
|
|
|
|
class StoreInst;
|
|
|
|
class TargetLibraryInfo;
|
|
|
|
class TargetTransformInfo;
|
|
|
|
class Value;
|
|
|
|
|
2016-06-15 10:43:40 +02:00
|
|
|
/// A private "module" namespace for types and utilities used by this pass.
|
|
|
|
/// These are implementation details and should not be used by clients.
|
|
|
|
namespace slpvectorizer {
|
2017-09-01 23:37:29 +02:00
|
|
|
|
2016-06-15 10:43:40 +02:00
|
|
|
class BoUpSLP;
|
2017-09-01 23:37:29 +02:00
|
|
|
|
|
|
|
} // end namespace slpvectorizer
|
2016-06-15 10:43:40 +02:00
|
|
|
|
|
|
|
struct SLPVectorizerPass : public PassInfoMixin<SLPVectorizerPass> {
|
2017-09-01 23:37:29 +02:00
|
|
|
using StoreList = SmallVector<StoreInst *, 8>;
|
|
|
|
using StoreListMap = MapVector<Value *, StoreList>;
|
[SLP] Fix for PR31847: Assertion failed: (isLoopInvariant(Operands[i], L) && "SCEVAddRecExpr operand is not loop-invariant!")
Initially SLP vectorizer replaced all going-to-be-vectorized
instructions with Undef values. It may break ScalarEvaluation and may
cause a crash.
Reworked SLP vectorizer so that it does not replace vectorized
instructions by UndefValue anymore. Instead vectorized instructions are
marked for deletion inside if BoUpSLP class and deleted upon class
destruction.
Reviewers: mzolotukhin, mkuper, hfinkel, RKSimon, davide, spatel
Subscribers: RKSimon, Gerolf, anemet, hans, majnemer, llvm-commits, sanjoy
Differential Revision: https://reviews.llvm.org/D29641
llvm-svn: 373166
2019-09-29 16:18:06 +02:00
|
|
|
using GEPList = SmallVector<GetElementPtrInst *, 8>;
|
|
|
|
using GEPListMap = MapVector<Value *, GEPList>;
|
2016-06-15 10:43:40 +02:00
|
|
|
|
|
|
|
ScalarEvolution *SE = nullptr;
|
|
|
|
TargetTransformInfo *TTI = nullptr;
|
|
|
|
TargetLibraryInfo *TLI = nullptr;
|
2020-09-15 16:23:19 +02:00
|
|
|
AAResults *AA = nullptr;
|
2016-06-15 10:43:40 +02:00
|
|
|
LoopInfo *LI = nullptr;
|
|
|
|
DominatorTree *DT = nullptr;
|
2016-12-19 09:22:17 +01:00
|
|
|
AssumptionCache *AC = nullptr;
|
2016-06-15 10:43:40 +02:00
|
|
|
DemandedBits *DB = nullptr;
|
|
|
|
const DataLayout *DL = nullptr;
|
|
|
|
|
|
|
|
public:
|
|
|
|
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
|
|
|
|
|
|
|
// Glue for old PM.
|
|
|
|
bool runImpl(Function &F, ScalarEvolution *SE_, TargetTransformInfo *TTI_,
|
2020-09-15 16:23:19 +02:00
|
|
|
TargetLibraryInfo *TLI_, AAResults *AA_, LoopInfo *LI_,
|
2017-05-11 19:06:17 +02:00
|
|
|
DominatorTree *DT_, AssumptionCache *AC_, DemandedBits *DB_,
|
|
|
|
OptimizationRemarkEmitter *ORE_);
|
2016-06-15 10:43:40 +02:00
|
|
|
|
|
|
|
private:
|
2018-05-01 17:54:18 +02:00
|
|
|
/// Collect store and getelementptr instructions and organize them
|
2016-06-15 10:43:40 +02:00
|
|
|
/// according to the underlying object of their pointer operands. We sort the
|
|
|
|
/// instructions by their underlying objects to reduce the cost of
|
|
|
|
/// consecutive access queries.
|
|
|
|
///
|
|
|
|
/// TODO: We can further reduce this cost if we flush the chain creation
|
|
|
|
/// every time we run into a memory barrier.
|
|
|
|
void collectSeedInstructions(BasicBlock *BB);
|
|
|
|
|
2018-05-01 17:54:18 +02:00
|
|
|
/// Try to vectorize a chain that starts at two arithmetic instrs.
|
2016-06-15 10:43:40 +02:00
|
|
|
bool tryToVectorizePair(Value *A, Value *B, slpvectorizer::BoUpSLP &R);
|
|
|
|
|
2018-05-01 17:54:18 +02:00
|
|
|
/// Try to vectorize a list of operands.
|
2016-06-15 10:43:40 +02:00
|
|
|
/// \returns true if a value was vectorized.
|
|
|
|
bool tryToVectorizeList(ArrayRef<Value *> VL, slpvectorizer::BoUpSLP &R,
|
2021-03-16 08:23:13 +01:00
|
|
|
bool AllowReorder = false);
|
2016-06-15 10:43:40 +02:00
|
|
|
|
2018-05-01 17:54:18 +02:00
|
|
|
/// Try to vectorize a chain that may start at the operands of \p I.
|
2017-08-02 16:38:07 +02:00
|
|
|
bool tryToVectorize(Instruction *I, slpvectorizer::BoUpSLP &R);
|
2016-06-15 10:43:40 +02:00
|
|
|
|
2018-05-01 17:54:18 +02:00
|
|
|
/// Vectorize the store instructions collected in Stores.
|
2016-06-15 10:43:40 +02:00
|
|
|
bool vectorizeStoreChains(slpvectorizer::BoUpSLP &R);
|
|
|
|
|
2018-05-01 17:54:18 +02:00
|
|
|
/// Vectorize the index computations of the getelementptr instructions
|
2016-06-15 10:43:40 +02:00
|
|
|
/// collected in GEPs.
|
|
|
|
bool vectorizeGEPIndices(BasicBlock *BB, slpvectorizer::BoUpSLP &R);
|
|
|
|
|
2016-11-29 09:21:14 +01:00
|
|
|
/// Try to find horizontal reduction or otherwise vectorize a chain of binary
|
|
|
|
/// operators.
|
|
|
|
bool vectorizeRootInstruction(PHINode *P, Value *V, BasicBlock *BB,
|
|
|
|
slpvectorizer::BoUpSLP &R,
|
2019-11-21 01:00:53 +01:00
|
|
|
TargetTransformInfo *TTI);
|
2016-11-29 09:21:14 +01:00
|
|
|
|
[SLP] General improvements of SLP vectorization process.
Patch tries to improve two-pass vectorization analysis, existing in SLP vectorizer. What it does:
1. Defines key nodes, that are the vectorization roots. Previously vectorization started if StoreInst or ReturnInst is found. For now, the vectorization started for all Instructions with no users and void types (Terminators, StoreInst) + CallInsts.
2. CmpInsts, InsertElementInsts and InsertValueInsts are stored in the
array. This array is processed only after the vectorization of the
first-after-these instructions key node is finished. Vectorization goes
in reverse order to try to vectorize as much code as possible.
Reviewers: mzolotukhin, Ayal, mkuper, gilr, hfinkel, RKSimon
Subscribers: ashahid, anemet, RKSimon, mssimpso, llvm-commits
Differential Revision: https://reviews.llvm.org/D29826
llvm-svn: 310260
2017-08-07 17:25:49 +02:00
|
|
|
/// Try to vectorize trees that start at insertvalue instructions.
|
|
|
|
bool vectorizeInsertValueInst(InsertValueInst *IVI, BasicBlock *BB,
|
|
|
|
slpvectorizer::BoUpSLP &R);
|
2017-09-01 23:37:29 +02:00
|
|
|
|
[SLP] General improvements of SLP vectorization process.
Patch tries to improve two-pass vectorization analysis, existing in SLP vectorizer. What it does:
1. Defines key nodes, that are the vectorization roots. Previously vectorization started if StoreInst or ReturnInst is found. For now, the vectorization started for all Instructions with no users and void types (Terminators, StoreInst) + CallInsts.
2. CmpInsts, InsertElementInsts and InsertValueInsts are stored in the
array. This array is processed only after the vectorization of the
first-after-these instructions key node is finished. Vectorization goes
in reverse order to try to vectorize as much code as possible.
Reviewers: mzolotukhin, Ayal, mkuper, gilr, hfinkel, RKSimon
Subscribers: ashahid, anemet, RKSimon, mssimpso, llvm-commits
Differential Revision: https://reviews.llvm.org/D29826
llvm-svn: 310260
2017-08-07 17:25:49 +02:00
|
|
|
/// Try to vectorize trees that start at insertelement instructions.
|
|
|
|
bool vectorizeInsertElementInst(InsertElementInst *IEI, BasicBlock *BB,
|
|
|
|
slpvectorizer::BoUpSLP &R);
|
2017-09-01 23:37:29 +02:00
|
|
|
|
[SLP] General improvements of SLP vectorization process.
Patch tries to improve two-pass vectorization analysis, existing in SLP vectorizer. What it does:
1. Defines key nodes, that are the vectorization roots. Previously vectorization started if StoreInst or ReturnInst is found. For now, the vectorization started for all Instructions with no users and void types (Terminators, StoreInst) + CallInsts.
2. CmpInsts, InsertElementInsts and InsertValueInsts are stored in the
array. This array is processed only after the vectorization of the
first-after-these instructions key node is finished. Vectorization goes
in reverse order to try to vectorize as much code as possible.
Reviewers: mzolotukhin, Ayal, mkuper, gilr, hfinkel, RKSimon
Subscribers: ashahid, anemet, RKSimon, mssimpso, llvm-commits
Differential Revision: https://reviews.llvm.org/D29826
llvm-svn: 310260
2017-08-07 17:25:49 +02:00
|
|
|
/// Tries to vectorize constructs started from CmpInst, InsertValueInst or
|
|
|
|
/// InsertElementInst instructions.
|
[SLP] Fix for PR31847: Assertion failed: (isLoopInvariant(Operands[i], L) && "SCEVAddRecExpr operand is not loop-invariant!")
Initially SLP vectorizer replaced all going-to-be-vectorized
instructions with Undef values. It may break ScalarEvaluation and may
cause a crash.
Reworked SLP vectorizer so that it does not replace vectorized
instructions by UndefValue anymore. Instead vectorized instructions are
marked for deletion inside if BoUpSLP class and deleted upon class
destruction.
Reviewers: mzolotukhin, mkuper, hfinkel, RKSimon, davide, spatel
Subscribers: RKSimon, Gerolf, anemet, hans, majnemer, llvm-commits, sanjoy
Differential Revision: https://reviews.llvm.org/D29641
llvm-svn: 373166
2019-09-29 16:18:06 +02:00
|
|
|
bool vectorizeSimpleInstructions(SmallVectorImpl<Instruction *> &Instructions,
|
2021-04-01 18:16:31 +02:00
|
|
|
BasicBlock *BB, slpvectorizer::BoUpSLP &R,
|
|
|
|
bool AtTerminator);
|
[SLP] General improvements of SLP vectorization process.
Patch tries to improve two-pass vectorization analysis, existing in SLP vectorizer. What it does:
1. Defines key nodes, that are the vectorization roots. Previously vectorization started if StoreInst or ReturnInst is found. For now, the vectorization started for all Instructions with no users and void types (Terminators, StoreInst) + CallInsts.
2. CmpInsts, InsertElementInsts and InsertValueInsts are stored in the
array. This array is processed only after the vectorization of the
first-after-these instructions key node is finished. Vectorization goes
in reverse order to try to vectorize as much code as possible.
Reviewers: mzolotukhin, Ayal, mkuper, gilr, hfinkel, RKSimon
Subscribers: ashahid, anemet, RKSimon, mssimpso, llvm-commits
Differential Revision: https://reviews.llvm.org/D29826
llvm-svn: 310260
2017-08-07 17:25:49 +02:00
|
|
|
|
2018-05-01 17:54:18 +02:00
|
|
|
/// Scan the basic block and look for patterns that are likely to start
|
2016-06-15 10:43:40 +02:00
|
|
|
/// a vectorization chain.
|
|
|
|
bool vectorizeChainsInBlock(BasicBlock *BB, slpvectorizer::BoUpSLP &R);
|
|
|
|
|
2016-09-02 21:09:50 +02:00
|
|
|
bool vectorizeStoreChain(ArrayRef<Value *> Chain, slpvectorizer::BoUpSLP &R,
|
2019-11-14 20:35:28 +01:00
|
|
|
unsigned Idx);
|
2016-06-15 10:43:40 +02:00
|
|
|
|
2016-09-02 21:09:50 +02:00
|
|
|
bool vectorizeStores(ArrayRef<StoreInst *> Stores, slpvectorizer::BoUpSLP &R);
|
2016-06-15 10:43:40 +02:00
|
|
|
|
|
|
|
/// The store instructions in a basic block organized by base pointer.
|
|
|
|
StoreListMap Stores;
|
|
|
|
|
|
|
|
/// The getelementptr instructions in a basic block organized by base pointer.
|
[SLP] Fix for PR31847: Assertion failed: (isLoopInvariant(Operands[i], L) && "SCEVAddRecExpr operand is not loop-invariant!")
Initially SLP vectorizer replaced all going-to-be-vectorized
instructions with Undef values. It may break ScalarEvaluation and may
cause a crash.
Reworked SLP vectorizer so that it does not replace vectorized
instructions by UndefValue anymore. Instead vectorized instructions are
marked for deletion inside if BoUpSLP class and deleted upon class
destruction.
Reviewers: mzolotukhin, mkuper, hfinkel, RKSimon, davide, spatel
Subscribers: RKSimon, Gerolf, anemet, hans, majnemer, llvm-commits, sanjoy
Differential Revision: https://reviews.llvm.org/D29641
llvm-svn: 373166
2019-09-29 16:18:06 +02:00
|
|
|
GEPListMap GEPs;
|
2016-06-15 10:43:40 +02:00
|
|
|
};
|
2017-09-01 23:37:29 +02:00
|
|
|
|
|
|
|
} // end namespace llvm
|
2016-06-15 10:43:40 +02:00
|
|
|
|
2016-07-10 00:56:39 +02:00
|
|
|
#endif // LLVM_TRANSFORMS_VECTORIZE_SLPVECTORIZER_H
|