Skip to content

Commit

Permalink
[RISCV][NFC] Refactor RISC-V vector intrinsic utils.
Browse files Browse the repository at this point in the history
This patch is preparation for D111617, use class/struct/enum rather than
char/StringRef to present internal information as possible, that provide
more compact way to store those info and also easier to
serialize/deserialize.

And also that improve readability of the code, e.g. "v" vs
TypeProfile::Vector.

Differential Revision: https://reviews.llvm.org/D124730
  • Loading branch information
kito-cheng committed May 11, 2022
1 parent 36c3a96 commit 08dbbaf
Show file tree
Hide file tree
Showing 3 changed files with 643 additions and 216 deletions.
167 changes: 149 additions & 18 deletions clang/include/clang/Support/RISCVVIntrinsicUtils.h
Expand Up @@ -9,7 +9,10 @@
#ifndef CLANG_SUPPORT_RISCVVINTRINSICUTILS_H
#define CLANG_SUPPORT_RISCVVINTRINSICUTILS_H

#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitmaskEnum.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include <cstdint>
#include <string>
Expand All @@ -18,9 +21,128 @@
namespace clang {
namespace RISCV {

using BasicType = char;
using VScaleVal = llvm::Optional<unsigned>;

// Modifier for vector type.
enum class VectorTypeModifier : uint8_t {
NoModifier,
Log2EEW3,
Log2EEW4,
Log2EEW5,
Log2EEW6,
FixedSEW8,
FixedSEW16,
FixedSEW32,
FixedSEW64,
LFixedLog2LMULN3,
LFixedLog2LMULN2,
LFixedLog2LMULN1,
LFixedLog2LMUL0,
LFixedLog2LMUL1,
LFixedLog2LMUL2,
LFixedLog2LMUL3,
SFixedLog2LMULN3,
SFixedLog2LMULN2,
SFixedLog2LMULN1,
SFixedLog2LMUL0,
SFixedLog2LMUL1,
SFixedLog2LMUL2,
SFixedLog2LMUL3,
};

// Similar to basic type but used to describe what's kind of type related to
// basic vector type, used to compute type info of arguments.
enum class PrimitiveType : uint8_t {
Invalid,
Scalar,
Vector,
Widening2XVector,
Widening4XVector,
Widening8XVector,
MaskVector,
Void,
SizeT,
Ptrdiff,
UnsignedLong,
SignedLong,
};

// Modifier for type, used for both scalar and vector types.
enum class TypeModifier : uint8_t {
NoModifier = 0,
Pointer = 1 << 0,
Const = 1 << 1,
Immediate = 1 << 2,
UnsignedInteger = 1 << 3,
SignedInteger = 1 << 4,
Float = 1 << 5,
LMUL1 = 1 << 6,
MaxOffset = 6,
LLVM_MARK_AS_BITMASK_ENUM(LMUL1),
};

// TypeProfile is used to compute type info of arguments or return value.
struct TypeProfile {
constexpr TypeProfile() = default;
constexpr TypeProfile(PrimitiveType PT) : PT(static_cast<uint8_t>(PT)) {}
constexpr TypeProfile(PrimitiveType PT, TypeModifier TM)
: PT(static_cast<uint8_t>(PT)), TM(static_cast<uint8_t>(TM)) {}
constexpr TypeProfile(uint8_t PT, uint8_t VTM, uint8_t TM)
: PT(PT), VTM(VTM), TM(TM) {}

uint8_t PT = static_cast<uint8_t>(PrimitiveType::Invalid);
uint8_t VTM = static_cast<uint8_t>(VectorTypeModifier::NoModifier);
uint8_t TM = static_cast<uint8_t>(TypeModifier::NoModifier);

std::string IndexStr() const {
return std::to_string(PT) + "_" + std::to_string(VTM) + "_" +
std::to_string(TM);
};

bool operator!=(const TypeProfile &TP) const {
return TP.PT != PT || TP.VTM != VTM || TP.TM != TM;
}
bool operator>(const TypeProfile &TP) const {
return !(TP.PT <= PT && TP.VTM <= VTM && TP.TM <= TM);
}

static const TypeProfile Mask;
static const TypeProfile Vector;
static const TypeProfile VL;
static llvm::Optional<TypeProfile>
parseTypeProfile(llvm::StringRef PrototypeStr);
};

llvm::SmallVector<TypeProfile> parsePrototypes(llvm::StringRef Prototypes);

// Basic type of vector type.
enum class BasicType : uint8_t {
Unknown = 0,
Int8 = 1 << 0,
Int16 = 1 << 1,
Int32 = 1 << 2,
Int64 = 1 << 3,
Float16 = 1 << 4,
Float32 = 1 << 5,
Float64 = 1 << 6,
MaxOffset = 6,
LLVM_MARK_AS_BITMASK_ENUM(Float64),
};

// Type of vector type.
enum ScalarTypeKind : uint8_t {
Void,
Size_t,
Ptrdiff_t,
UnsignedLong,
SignedLong,
Boolean,
SignedInteger,
UnsignedInteger,
Float,
Invalid,
};

// Exponential LMUL
struct LMULType {
int Log2LMUL;
Expand All @@ -32,20 +154,12 @@ struct LMULType {
LMULType &operator*=(uint32_t RHS);
};

class RVVType;
using RVVTypePtr = RVVType *;
using RVVTypes = std::vector<RVVTypePtr>;

// This class is compact representation of a valid and invalid RVVType.
class RVVType {
enum ScalarTypeKind : uint32_t {
Void,
Size_t,
Ptrdiff_t,
UnsignedLong,
SignedLong,
Boolean,
SignedInteger,
UnsignedInteger,
Float,
Invalid,
};
BasicType BT;
ScalarTypeKind ScalarType = Invalid;
LMULType LMUL;
Expand All @@ -64,8 +178,8 @@ class RVVType {
std::string ShortStr;

public:
RVVType() : RVVType(BasicType(), 0, llvm::StringRef()) {}
RVVType(BasicType BT, int Log2LMUL, llvm::StringRef prototype);
RVVType() : BT(BasicType::Unknown), LMUL(0), Valid(false) {}
RVVType(BasicType BT, int Log2LMUL, const TypeProfile &Profile);

// Return the string representation of a type, which is an encoded string for
// passing to the BUILTIN() macro in Builtins.def.
Expand Down Expand Up @@ -114,7 +228,11 @@ class RVVType {

// Applies a prototype modifier to the current type. The result maybe an
// invalid type.
void applyModifier(llvm::StringRef prototype);
void applyModifier(const TypeProfile &prototype);

void applyLog2EEW(unsigned Log2EEW);
void applyFixedSEW(unsigned NewSEW);
void applyFixedLog2LMUL(int Log2LMUL, bool LargerThan);

// Compute and record a string for legal type.
void initBuiltinStr();
Expand All @@ -124,10 +242,19 @@ class RVVType {
void initTypeStr();
// Compute and record a short name of a type for C/C++ name suffix.
void initShortStr();

public:
/// Compute output and input types by applying different config (basic type
/// and LMUL with type transformers). It also record result of type in legal
/// or illegal set to avoid compute the same config again. The result maybe
/// have illegal RVVType.
static llvm::Optional<RVVTypes>
computeTypes(BasicType BT, int Log2LMUL, unsigned NF,
llvm::ArrayRef<TypeProfile> PrototypeSeq);
static llvm::Optional<RVVTypePtr> computeType(BasicType BT, int Log2LMUL,
TypeProfile Proto);
};

using RVVTypePtr = RVVType *;
using RVVTypes = std::vector<RVVTypePtr>;
using RISCVPredefinedMacroT = uint8_t;

enum RISCVPredefinedMacro : RISCVPredefinedMacroT {
Expand Down Expand Up @@ -206,6 +333,10 @@ class RVVIntrinsic {

// Return the type string for a BUILTIN() macro in Builtins.def.
std::string getBuiltinTypeStr() const;

static std::string
getSuffixStr(BasicType Type, int Log2LMUL,
const llvm::SmallVector<TypeProfile> &TypeProfiles);
};

} // end namespace RISCV
Expand Down

0 comments on commit 08dbbaf

Please sign in to comment.