Revert "[llvm][LV] Replace `unsigned VF` with `ElementCount VF` [NFCI]"

Reverting because the commit message doesn't reflect the one agreed on
phabricator at https://reviews.llvm.org/D85794.

This reverts commit c8d2b065b9.
This commit is contained in:
Francesco Petrogalli 2020-08-24 13:49:27 +00:00
parent e1644a3779
commit bad7d6b373
9 changed files with 335 additions and 491 deletions

View File

@ -128,11 +128,6 @@ public:
IntrinsicCostAttributes(Intrinsic::ID Id, const CallBase &CI,
unsigned Factor);
IntrinsicCostAttributes(Intrinsic::ID Id, const CallBase &CI,
ElementCount Factor)
: IntrinsicCostAttributes(Id, CI, Factor.Min) {
assert(!Factor.Scalable);
}
IntrinsicCostAttributes(Intrinsic::ID Id, const CallBase &CI,
unsigned Factor, unsigned ScalarCost);

View File

@ -300,17 +300,13 @@ namespace Intrinsic {
typedef unsigned ID;
}
/// A helper function for converting Scalar types to vector types. If
/// the incoming type is void, we return void. If the EC represents a
/// scalar, we return the scalar type.
inline Type *ToVectorTy(Type *Scalar, ElementCount EC) {
if (Scalar->isVoidTy() || EC.isScalar())
/// A helper function for converting Scalar types to vector types.
/// If the incoming type is void, we return void. If the VF is 1, we return
/// the scalar type.
inline Type *ToVectorTy(Type *Scalar, unsigned VF, bool isScalable = false) {
if (Scalar->isVoidTy() || VF == 1)
return Scalar;
return VectorType::get(Scalar, EC);
}
inline Type *ToVectorTy(Type *Scalar, unsigned VF) {
return ToVectorTy(Scalar, ElementCount::getFixed(VF));
return VectorType::get(Scalar, ElementCount::get(VF, isScalable));
}
/// Identify if the intrinsic is trivially vectorizable.

View File

@ -21,7 +21,6 @@
#include "llvm/ADT/Twine.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/Support/CBindingWrapping.h"
#include "llvm/Support/TypeSize.h"
#include "llvm/Support/YAMLTraits.h"
#include <algorithm>
#include <cstdint>
@ -435,7 +434,6 @@ public:
Argument(StringRef Key, unsigned N);
Argument(StringRef Key, unsigned long N);
Argument(StringRef Key, unsigned long long N);
Argument(StringRef Key, ElementCount EC);
Argument(StringRef Key, bool B) : Key(Key), Val(B ? "true" : "false") {}
Argument(StringRef Key, DebugLoc dl);
};

View File

@ -67,33 +67,8 @@ public:
static ElementCount get(unsigned Min, bool Scalable) {
return {Min, Scalable};
}
/// Printing function.
void print(raw_ostream &OS) const {
if (Scalable)
OS << "vscale x ";
OS << Min;
}
/// Counting predicates.
///
/// Notice that Min = 1 and Scalable = true is considered more than
/// one element.
///
///@{ No elements..
bool isZero() const { return Min == 0; }
/// Exactly one element.
bool isScalar() const { return !Scalable && Min == 1; }
/// One or more elements.
bool isVector() const { return (Scalable && Min != 0) || Min > 1; }
///@}
};
/// Stream operator function for `ElementCount`.
inline raw_ostream &operator<<(raw_ostream &OS, const ElementCount &EC) {
EC.print(OS);
return OS;
}
// This class is used to represent the size of types. If the type is of fixed
// size, it will represent the exact size. If the type is a scalable vector,
// it will represent the known minimum size.

View File

@ -213,13 +213,6 @@ DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key,
unsigned long long N)
: Key(std::string(Key)), Val(utostr(N)) {}
DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key,
ElementCount EC)
: Key(std::string(Key)) {
raw_string_ostream OS(Val);
EC.print(OS);
}
DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, DebugLoc Loc)
: Key(std::string(Key)), Loc(Loc) {
if (Loc) {

View File

@ -172,14 +172,12 @@ public:
/// Information about vectorization costs
struct VectorizationFactor {
// Vector width with best cost
ElementCount Width;
unsigned Width;
// Cost of the loop with that width
unsigned Cost;
// Width 1 means no vectorization, cost 0 means uncomputed cost.
static VectorizationFactor Disabled() {
return {ElementCount::getFixed(1), 0};
}
static VectorizationFactor Disabled() { return {1, 0}; }
bool operator==(const VectorizationFactor &rhs) const {
return Width == rhs.Width && Cost == rhs.Cost;
@ -229,10 +227,7 @@ class LoopVectorizationPlanner {
/// A builder used to construct the current plan.
VPBuilder Builder;
/// The best number of elements of the vector types used in the
/// transformed loop. BestVF = None means that vectorization is
/// disabled.
Optional<ElementCount> BestVF = None;
unsigned BestVF = 0;
unsigned BestUF = 0;
public:
@ -247,14 +242,14 @@ public:
/// Plan how to best vectorize, return the best VF and its cost, or None if
/// vectorization and interleaving should be avoided up front.
Optional<VectorizationFactor> plan(ElementCount UserVF, unsigned UserIC);
Optional<VectorizationFactor> plan(unsigned UserVF, unsigned UserIC);
/// Use the VPlan-native path to plan how to best vectorize, return the best
/// VF and its cost.
VectorizationFactor planInVPlanNativePath(ElementCount UserVF);
VectorizationFactor planInVPlanNativePath(unsigned UserVF);
/// Finalize the best decision and dispose of all other VPlans.
void setBestPlan(ElementCount VF, unsigned UF);
void setBestPlan(unsigned VF, unsigned UF);
/// Generate the IR code for the body of the vectorized loop according to the
/// best selected VPlan.
@ -269,7 +264,7 @@ public:
/// \p Predicate on Range.Start, possibly decreasing Range.End such that the
/// returned value holds for the entire \p Range.
static bool
getDecisionAndClampRange(const std::function<bool(ElementCount)> &Predicate,
getDecisionAndClampRange(const std::function<bool(unsigned)> &Predicate,
VFRange &Range);
protected:

File diff suppressed because it is too large Load Diff

View File

@ -300,8 +300,7 @@ void VPRegionBlock::execute(VPTransformState *State) {
for (unsigned Part = 0, UF = State->UF; Part < UF; ++Part) {
State->Instance->Part = Part;
assert(!State->VF.Scalable && "VF is assumed to be non scalable.");
for (unsigned Lane = 0, VF = State->VF.Min; Lane < VF; ++Lane) {
for (unsigned Lane = 0, VF = State->VF; Lane < VF; ++Lane) {
State->Instance->Lane = Lane;
// Visit the VPBlocks connected to \p this, starting from it.
for (VPBlockBase *Block : RPOT) {
@ -388,7 +387,7 @@ void VPInstruction::generateInstruction(VPTransformState &State,
Value *ScalarBTC = State.get(getOperand(1), {Part, 0});
auto *Int1Ty = Type::getInt1Ty(Builder.getContext());
auto *PredTy = FixedVectorType::get(Int1Ty, State.VF.Min);
auto *PredTy = FixedVectorType::get(Int1Ty, State.VF);
Instruction *Call = Builder.CreateIntrinsic(
Intrinsic::get_active_lane_mask, {PredTy, ScalarBTC->getType()},
{VIVElem0, ScalarBTC}, nullptr, "active.lane.mask");
@ -839,15 +838,14 @@ void VPWidenCanonicalIVRecipe::execute(VPTransformState &State) {
Value *CanonicalIV = State.CanonicalIV;
Type *STy = CanonicalIV->getType();
IRBuilder<> Builder(State.CFG.PrevBB->getTerminator());
ElementCount VF = State.VF;
assert(!VF.Scalable && "the code following assumes non scalables ECs");
Value *VStart = VF.isScalar() ? CanonicalIV
: Builder.CreateVectorSplat(VF.Min, CanonicalIV,
"broadcast");
auto VF = State.VF;
Value *VStart = VF == 1
? CanonicalIV
: Builder.CreateVectorSplat(VF, CanonicalIV, "broadcast");
for (unsigned Part = 0, UF = State.UF; Part < UF; ++Part) {
SmallVector<Constant *, 8> Indices;
for (unsigned Lane = 0; Lane < VF.Min; ++Lane)
Indices.push_back(ConstantInt::get(STy, Part * VF.Min + Lane));
for (unsigned Lane = 0; Lane < VF; ++Lane)
Indices.push_back(ConstantInt::get(STy, Part * VF + Lane));
// If VF == 1, there is only one iteration in the loop above, thus the
// element pushed back into Indices is ConstantInt::get(STy, Part)
Constant *VStep = VF == 1 ? Indices.back() : ConstantVector::get(Indices);

View File

@ -115,7 +115,7 @@ private:
/// The vectorization factor. Each entry in the scalar map contains UF x VF
/// scalar values.
ElementCount VF;
unsigned VF;
/// The vector and scalar map storage. We use std::map and not DenseMap
/// because insertions to DenseMap invalidate its iterators.
@ -126,7 +126,7 @@ private:
public:
/// Construct an empty map with the given unroll and vectorization factors.
VectorizerValueMap(unsigned UF, ElementCount VF) : UF(UF), VF(VF) {}
VectorizerValueMap(unsigned UF, unsigned VF) : UF(UF), VF(VF) {}
/// \return True if the map has any vector entry for \p Key.
bool hasAnyVectorValue(Value *Key) const {
@ -151,14 +151,12 @@ public:
/// \return True if the map has a scalar entry for \p Key and \p Instance.
bool hasScalarValue(Value *Key, const VPIteration &Instance) const {
assert(Instance.Part < UF && "Queried Scalar Part is too large.");
assert(Instance.Lane < VF.Min && "Queried Scalar Lane is too large.");
assert(!VF.Scalable && "VF is assumed to be non scalable.");
assert(Instance.Lane < VF && "Queried Scalar Lane is too large.");
if (!hasAnyScalarValue(Key))
return false;
const ScalarParts &Entry = ScalarMapStorage.find(Key)->second;
assert(Entry.size() == UF && "ScalarParts has wrong dimensions.");
assert(Entry[Instance.Part].size() == VF.Min &&
assert(Entry[Instance.Part].size() == VF &&
"ScalarParts has wrong dimensions.");
return Entry[Instance.Part][Instance.Lane] != nullptr;
}
@ -197,7 +195,7 @@ public:
// TODO: Consider storing uniform values only per-part, as they occupy
// lane 0 only, keeping the other VF-1 redundant entries null.
for (unsigned Part = 0; Part < UF; ++Part)
Entry[Part].resize(VF.Min, nullptr);
Entry[Part].resize(VF, nullptr);
ScalarMapStorage[Key] = Entry;
}
ScalarMapStorage[Key][Instance.Part][Instance.Lane] = Scalar;
@ -236,15 +234,14 @@ struct VPCallback {
/// VPTransformState holds information passed down when "executing" a VPlan,
/// needed for generating the output IR.
struct VPTransformState {
VPTransformState(ElementCount VF, unsigned UF, LoopInfo *LI,
DominatorTree *DT, IRBuilder<> &Builder,
VectorizerValueMap &ValueMap, InnerLoopVectorizer *ILV,
VPCallback &Callback)
VPTransformState(unsigned VF, unsigned UF, LoopInfo *LI, DominatorTree *DT,
IRBuilder<> &Builder, VectorizerValueMap &ValueMap,
InnerLoopVectorizer *ILV, VPCallback &Callback)
: VF(VF), UF(UF), Instance(), LI(LI), DT(DT), Builder(Builder),
ValueMap(ValueMap), ILV(ILV), Callback(Callback) {}
/// The chosen Vectorization and Unroll Factors of the loop being vectorized.
ElementCount VF;
unsigned VF;
unsigned UF;
/// Hold the indices to generate specific scalar instructions. Null indicates
@ -1586,7 +1583,7 @@ class VPlan {
VPBlockBase *Entry;
/// Holds the VFs applicable to this VPlan.
SmallSetVector<ElementCount, 2> VFs;
SmallSet<unsigned, 2> VFs;
/// Holds the name of the VPlan, for printing.
std::string Name;
@ -1650,9 +1647,9 @@ public:
return BackedgeTakenCount;
}
void addVF(ElementCount VF) { VFs.insert(VF); }
void addVF(unsigned VF) { VFs.insert(VF); }
bool hasVF(ElementCount VF) { return VFs.count(VF); }
bool hasVF(unsigned VF) { return VFs.count(VF); }
const std::string &getName() const { return Name; }