[clang][RISCV][NFC] Prevent data race in RVVType::computeType
Introduce a RVVTypeCache to hold the cache instead of using a local static variable to maintain a cache. Also made construct of RVVType to private, make sure that could be only created by a cache manager. Reviewed By: sammccall Differential Revision: https://reviews.llvm.org/D138429
This commit is contained in:
parent
7fbdee3e29
commit
3fe89be801
|
@ -15,7 +15,9 @@
|
||||||
#include "llvm/ADT/SmallVector.h"
|
#include "llvm/ADT/SmallVector.h"
|
||||||
#include "llvm/ADT/StringRef.h"
|
#include "llvm/ADT/StringRef.h"
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
@ -182,9 +184,12 @@ struct LMULType {
|
||||||
class RVVType;
|
class RVVType;
|
||||||
using RVVTypePtr = RVVType *;
|
using RVVTypePtr = RVVType *;
|
||||||
using RVVTypes = std::vector<RVVTypePtr>;
|
using RVVTypes = std::vector<RVVTypePtr>;
|
||||||
|
class RVVTypeCache;
|
||||||
|
|
||||||
// This class is compact representation of a valid and invalid RVVType.
|
// This class is compact representation of a valid and invalid RVVType.
|
||||||
class RVVType {
|
class RVVType {
|
||||||
|
friend class RVVTypeCache;
|
||||||
|
|
||||||
BasicType BT;
|
BasicType BT;
|
||||||
ScalarTypeKind ScalarType = Invalid;
|
ScalarTypeKind ScalarType = Invalid;
|
||||||
LMULType LMUL;
|
LMULType LMUL;
|
||||||
|
@ -204,10 +209,9 @@ class RVVType {
|
||||||
|
|
||||||
enum class FixedLMULType { LargerThan, SmallerThan };
|
enum class FixedLMULType { LargerThan, SmallerThan };
|
||||||
|
|
||||||
public:
|
|
||||||
RVVType() : BT(BasicType::Unknown), LMUL(0), Valid(false) {}
|
|
||||||
RVVType(BasicType BT, int Log2LMUL, const PrototypeDescriptor &Profile);
|
RVVType(BasicType BT, int Log2LMUL, const PrototypeDescriptor &Profile);
|
||||||
|
|
||||||
|
public:
|
||||||
// Return the string representation of a type, which is an encoded string for
|
// Return the string representation of a type, which is an encoded string for
|
||||||
// passing to the BUILTIN() macro in Builtins.def.
|
// passing to the BUILTIN() macro in Builtins.def.
|
||||||
const std::string &getBuiltinStr() const { return BuiltinStr; }
|
const std::string &getBuiltinStr() const { return BuiltinStr; }
|
||||||
|
@ -275,16 +279,24 @@ private:
|
||||||
void initTypeStr();
|
void initTypeStr();
|
||||||
// Compute and record a short name of a type for C/C++ name suffix.
|
// Compute and record a short name of a type for C/C++ name suffix.
|
||||||
void initShortStr();
|
void initShortStr();
|
||||||
|
};
|
||||||
|
|
||||||
|
// This class is used to manage RVVType, RVVType should only created by this
|
||||||
|
// class, also provided thread-safe cache capability.
|
||||||
|
class RVVTypeCache {
|
||||||
|
private:
|
||||||
|
std::unordered_map<uint64_t, RVVType> LegalTypes;
|
||||||
|
std::set<uint64_t> IllegalTypes;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// Compute output and input types by applying different config (basic type
|
/// Compute output and input types by applying different config (basic type
|
||||||
/// and LMUL with type transformers). It also record result of type in legal
|
/// 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
|
/// or illegal set to avoid compute the same config again. The result maybe
|
||||||
/// have illegal RVVType.
|
/// have illegal RVVType.
|
||||||
static llvm::Optional<RVVTypes>
|
llvm::Optional<RVVTypes>
|
||||||
computeTypes(BasicType BT, int Log2LMUL, unsigned NF,
|
computeTypes(BasicType BT, int Log2LMUL, unsigned NF,
|
||||||
llvm::ArrayRef<PrototypeDescriptor> Prototype);
|
llvm::ArrayRef<PrototypeDescriptor> Prototype);
|
||||||
static llvm::Optional<RVVTypePtr> computeType(BasicType BT, int Log2LMUL,
|
llvm::Optional<RVVTypePtr> computeType(BasicType BT, int Log2LMUL,
|
||||||
PrototypeDescriptor Proto);
|
PrototypeDescriptor Proto);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -373,7 +385,7 @@ public:
|
||||||
std::string getBuiltinTypeStr() const;
|
std::string getBuiltinTypeStr() const;
|
||||||
|
|
||||||
static std::string
|
static std::string
|
||||||
getSuffixStr(BasicType Type, int Log2LMUL,
|
getSuffixStr(RVVTypeCache &TypeCache, BasicType Type, int Log2LMUL,
|
||||||
llvm::ArrayRef<PrototypeDescriptor> PrototypeDescriptors);
|
llvm::ArrayRef<PrototypeDescriptor> PrototypeDescriptors);
|
||||||
|
|
||||||
static llvm::SmallVector<PrototypeDescriptor>
|
static llvm::SmallVector<PrototypeDescriptor>
|
||||||
|
|
|
@ -132,6 +132,7 @@ class RISCVIntrinsicManagerImpl : public sema::RISCVIntrinsicManager {
|
||||||
private:
|
private:
|
||||||
Sema &S;
|
Sema &S;
|
||||||
ASTContext &Context;
|
ASTContext &Context;
|
||||||
|
RVVTypeCache TypeCache;
|
||||||
|
|
||||||
// List of all RVV intrinsic.
|
// List of all RVV intrinsic.
|
||||||
std::vector<RVVIntrinsicDef> IntrinsicList;
|
std::vector<RVVIntrinsicDef> IntrinsicList;
|
||||||
|
@ -247,16 +248,16 @@ void RISCVIntrinsicManagerImpl::InitIntrinsicList() {
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Optional<RVVTypes> Types =
|
Optional<RVVTypes> Types =
|
||||||
RVVType::computeTypes(BaseType, Log2LMUL, Record.NF, ProtoSeq);
|
TypeCache.computeTypes(BaseType, Log2LMUL, Record.NF, ProtoSeq);
|
||||||
|
|
||||||
// Ignored to create new intrinsic if there are any illegal types.
|
// Ignored to create new intrinsic if there are any illegal types.
|
||||||
if (!Types.has_value())
|
if (!Types.has_value())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
std::string SuffixStr =
|
std::string SuffixStr = RVVIntrinsic::getSuffixStr(
|
||||||
RVVIntrinsic::getSuffixStr(BaseType, Log2LMUL, SuffixProto);
|
TypeCache, BaseType, Log2LMUL, SuffixProto);
|
||||||
std::string OverloadedSuffixStr = RVVIntrinsic::getSuffixStr(
|
std::string OverloadedSuffixStr = RVVIntrinsic::getSuffixStr(
|
||||||
BaseType, Log2LMUL, OverloadedSuffixProto);
|
TypeCache, BaseType, Log2LMUL, OverloadedSuffixProto);
|
||||||
|
|
||||||
// Create non-masked intrinsic.
|
// Create non-masked intrinsic.
|
||||||
InitRVVIntrinsic(Record, SuffixStr, OverloadedSuffixStr, false, *Types,
|
InitRVVIntrinsic(Record, SuffixStr, OverloadedSuffixStr, false, *Types,
|
||||||
|
@ -271,7 +272,7 @@ void RISCVIntrinsicManagerImpl::InitIntrinsicList() {
|
||||||
BasicProtoSeq, /*IsMasked=*/false,
|
BasicProtoSeq, /*IsMasked=*/false,
|
||||||
/*HasMaskedOffOperand=*/false, Record.HasVL, Record.NF,
|
/*HasMaskedOffOperand=*/false, Record.HasVL, Record.NF,
|
||||||
Record.IsPrototypeDefaultTU, UnMaskedPolicyScheme, P);
|
Record.IsPrototypeDefaultTU, UnMaskedPolicyScheme, P);
|
||||||
Optional<RVVTypes> PolicyTypes = RVVType::computeTypes(
|
Optional<RVVTypes> PolicyTypes = TypeCache.computeTypes(
|
||||||
BaseType, Log2LMUL, Record.NF, PolicyPrototype);
|
BaseType, Log2LMUL, Record.NF, PolicyPrototype);
|
||||||
InitRVVIntrinsic(Record, SuffixStr, OverloadedSuffixStr,
|
InitRVVIntrinsic(Record, SuffixStr, OverloadedSuffixStr,
|
||||||
/*IsMask=*/false, *PolicyTypes, UnMaskedHasPolicy,
|
/*IsMask=*/false, *PolicyTypes, UnMaskedHasPolicy,
|
||||||
|
@ -282,7 +283,7 @@ void RISCVIntrinsicManagerImpl::InitIntrinsicList() {
|
||||||
continue;
|
continue;
|
||||||
// Create masked intrinsic.
|
// Create masked intrinsic.
|
||||||
Optional<RVVTypes> MaskTypes =
|
Optional<RVVTypes> MaskTypes =
|
||||||
RVVType::computeTypes(BaseType, Log2LMUL, Record.NF, ProtoMaskSeq);
|
TypeCache.computeTypes(BaseType, Log2LMUL, Record.NF, ProtoMaskSeq);
|
||||||
InitRVVIntrinsic(Record, SuffixStr, OverloadedSuffixStr, true,
|
InitRVVIntrinsic(Record, SuffixStr, OverloadedSuffixStr, true,
|
||||||
*MaskTypes, MaskedHasPolicy, Policy::PolicyNone,
|
*MaskTypes, MaskedHasPolicy, Policy::PolicyNone,
|
||||||
Record.IsPrototypeDefaultTU);
|
Record.IsPrototypeDefaultTU);
|
||||||
|
@ -295,7 +296,7 @@ void RISCVIntrinsicManagerImpl::InitIntrinsicList() {
|
||||||
BasicProtoSeq, /*IsMasked=*/true, Record.HasMaskedOffOperand,
|
BasicProtoSeq, /*IsMasked=*/true, Record.HasMaskedOffOperand,
|
||||||
Record.HasVL, Record.NF, Record.IsPrototypeDefaultTU,
|
Record.HasVL, Record.NF, Record.IsPrototypeDefaultTU,
|
||||||
MaskedPolicyScheme, P);
|
MaskedPolicyScheme, P);
|
||||||
Optional<RVVTypes> PolicyTypes = RVVType::computeTypes(
|
Optional<RVVTypes> PolicyTypes = TypeCache.computeTypes(
|
||||||
BaseType, Log2LMUL, Record.NF, PolicyPrototype);
|
BaseType, Log2LMUL, Record.NF, PolicyPrototype);
|
||||||
InitRVVIntrinsic(Record, SuffixStr, OverloadedSuffixStr,
|
InitRVVIntrinsic(Record, SuffixStr, OverloadedSuffixStr,
|
||||||
/*IsMask=*/true, *PolicyTypes, MaskedHasPolicy, P,
|
/*IsMask=*/true, *PolicyTypes, MaskedHasPolicy, P,
|
||||||
|
|
|
@ -16,8 +16,6 @@
|
||||||
#include "llvm/ADT/Twine.h"
|
#include "llvm/ADT/Twine.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <set>
|
|
||||||
#include <unordered_map>
|
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
|
@ -786,7 +784,7 @@ void RVVType::applyFixedLog2LMUL(int Log2LMUL, enum FixedLMULType Type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<RVVTypes>
|
Optional<RVVTypes>
|
||||||
RVVType::computeTypes(BasicType BT, int Log2LMUL, unsigned NF,
|
RVVTypeCache::computeTypes(BasicType BT, int Log2LMUL, unsigned NF,
|
||||||
ArrayRef<PrototypeDescriptor> Prototype) {
|
ArrayRef<PrototypeDescriptor> Prototype) {
|
||||||
// LMUL x NF must be less than or equal to 8.
|
// LMUL x NF must be less than or equal to 8.
|
||||||
if ((Log2LMUL >= 1) && (1 << Log2LMUL) * NF > 8)
|
if ((Log2LMUL >= 1) && (1 << Log2LMUL) * NF > 8)
|
||||||
|
@ -816,11 +814,8 @@ static uint64_t computeRVVTypeHashValue(BasicType BT, int Log2LMUL,
|
||||||
((uint64_t)(Proto.VTM & 0xff) << 32);
|
((uint64_t)(Proto.VTM & 0xff) << 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<RVVTypePtr> RVVType::computeType(BasicType BT, int Log2LMUL,
|
Optional<RVVTypePtr> RVVTypeCache::computeType(BasicType BT, int Log2LMUL,
|
||||||
PrototypeDescriptor Proto) {
|
PrototypeDescriptor Proto) {
|
||||||
// Concat BasicType, LMUL and Proto as key
|
|
||||||
static std::unordered_map<uint64_t, RVVType> LegalTypes;
|
|
||||||
static std::set<uint64_t> IllegalTypes;
|
|
||||||
uint64_t Idx = computeRVVTypeHashValue(BT, Log2LMUL, Proto);
|
uint64_t Idx = computeRVVTypeHashValue(BT, Log2LMUL, Proto);
|
||||||
// Search first
|
// Search first
|
||||||
auto It = LegalTypes.find(Idx);
|
auto It = LegalTypes.find(Idx);
|
||||||
|
@ -834,8 +829,9 @@ Optional<RVVTypePtr> RVVType::computeType(BasicType BT, int Log2LMUL,
|
||||||
RVVType T(BT, Log2LMUL, Proto);
|
RVVType T(BT, Log2LMUL, Proto);
|
||||||
if (T.isValid()) {
|
if (T.isValid()) {
|
||||||
// Record legal type index and value.
|
// Record legal type index and value.
|
||||||
LegalTypes.insert({Idx, T});
|
std::pair<std::unordered_map<uint64_t, RVVType>::iterator, bool>
|
||||||
return &(LegalTypes[Idx]);
|
InsertResult = LegalTypes.insert({Idx, T});
|
||||||
|
return &(InsertResult.first->second);
|
||||||
}
|
}
|
||||||
// Record illegal type index.
|
// Record illegal type index.
|
||||||
IllegalTypes.insert(Idx);
|
IllegalTypes.insert(Idx);
|
||||||
|
@ -900,11 +896,11 @@ std::string RVVIntrinsic::getBuiltinTypeStr() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string RVVIntrinsic::getSuffixStr(
|
std::string RVVIntrinsic::getSuffixStr(
|
||||||
BasicType Type, int Log2LMUL,
|
RVVTypeCache &TypeCache, BasicType Type, int Log2LMUL,
|
||||||
llvm::ArrayRef<PrototypeDescriptor> PrototypeDescriptors) {
|
llvm::ArrayRef<PrototypeDescriptor> PrototypeDescriptors) {
|
||||||
SmallVector<std::string> SuffixStrs;
|
SmallVector<std::string> SuffixStrs;
|
||||||
for (auto PD : PrototypeDescriptors) {
|
for (auto PD : PrototypeDescriptors) {
|
||||||
auto T = RVVType::computeType(Type, Log2LMUL, PD);
|
auto T = TypeCache.computeType(Type, Log2LMUL, PD);
|
||||||
SuffixStrs.push_back((*T)->getShortStr());
|
SuffixStrs.push_back((*T)->getShortStr());
|
||||||
}
|
}
|
||||||
return join(SuffixStrs, "_");
|
return join(SuffixStrs, "_");
|
||||||
|
|
|
@ -95,6 +95,7 @@ public:
|
||||||
class RVVEmitter {
|
class RVVEmitter {
|
||||||
private:
|
private:
|
||||||
RecordKeeper &Records;
|
RecordKeeper &Records;
|
||||||
|
RVVTypeCache TypeCache;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RVVEmitter(RecordKeeper &R) : Records(R) {}
|
RVVEmitter(RecordKeeper &R) : Records(R) {}
|
||||||
|
@ -349,7 +350,7 @@ void RVVEmitter::createHeader(raw_ostream &OS) {
|
||||||
constexpr int Log2LMULs[] = {-3, -2, -1, 0, 1, 2, 3};
|
constexpr int Log2LMULs[] = {-3, -2, -1, 0, 1, 2, 3};
|
||||||
// Print RVV boolean types.
|
// Print RVV boolean types.
|
||||||
for (int Log2LMUL : Log2LMULs) {
|
for (int Log2LMUL : Log2LMULs) {
|
||||||
auto T = RVVType::computeType(BasicType::Int8, Log2LMUL,
|
auto T = TypeCache.computeType(BasicType::Int8, Log2LMUL,
|
||||||
PrototypeDescriptor::Mask);
|
PrototypeDescriptor::Mask);
|
||||||
if (T)
|
if (T)
|
||||||
printType(T.value());
|
printType(T.value());
|
||||||
|
@ -358,10 +359,10 @@ void RVVEmitter::createHeader(raw_ostream &OS) {
|
||||||
for (char I : StringRef("csil")) {
|
for (char I : StringRef("csil")) {
|
||||||
BasicType BT = ParseBasicType(I);
|
BasicType BT = ParseBasicType(I);
|
||||||
for (int Log2LMUL : Log2LMULs) {
|
for (int Log2LMUL : Log2LMULs) {
|
||||||
auto T = RVVType::computeType(BT, Log2LMUL, PrototypeDescriptor::Vector);
|
auto T = TypeCache.computeType(BT, Log2LMUL, PrototypeDescriptor::Vector);
|
||||||
if (T) {
|
if (T) {
|
||||||
printType(T.value());
|
printType(T.value());
|
||||||
auto UT = RVVType::computeType(
|
auto UT = TypeCache.computeType(
|
||||||
BT, Log2LMUL,
|
BT, Log2LMUL,
|
||||||
PrototypeDescriptor(BaseTypeModifier::Vector,
|
PrototypeDescriptor(BaseTypeModifier::Vector,
|
||||||
VectorTypeModifier::NoModifier,
|
VectorTypeModifier::NoModifier,
|
||||||
|
@ -372,7 +373,7 @@ void RVVEmitter::createHeader(raw_ostream &OS) {
|
||||||
}
|
}
|
||||||
OS << "#if defined(__riscv_zvfh)\n";
|
OS << "#if defined(__riscv_zvfh)\n";
|
||||||
for (int Log2LMUL : Log2LMULs) {
|
for (int Log2LMUL : Log2LMULs) {
|
||||||
auto T = RVVType::computeType(BasicType::Float16, Log2LMUL,
|
auto T = TypeCache.computeType(BasicType::Float16, Log2LMUL,
|
||||||
PrototypeDescriptor::Vector);
|
PrototypeDescriptor::Vector);
|
||||||
if (T)
|
if (T)
|
||||||
printType(T.value());
|
printType(T.value());
|
||||||
|
@ -381,7 +382,7 @@ void RVVEmitter::createHeader(raw_ostream &OS) {
|
||||||
|
|
||||||
OS << "#if (__riscv_v_elen_fp >= 32)\n";
|
OS << "#if (__riscv_v_elen_fp >= 32)\n";
|
||||||
for (int Log2LMUL : Log2LMULs) {
|
for (int Log2LMUL : Log2LMULs) {
|
||||||
auto T = RVVType::computeType(BasicType::Float32, Log2LMUL,
|
auto T = TypeCache.computeType(BasicType::Float32, Log2LMUL,
|
||||||
PrototypeDescriptor::Vector);
|
PrototypeDescriptor::Vector);
|
||||||
if (T)
|
if (T)
|
||||||
printType(T.value());
|
printType(T.value());
|
||||||
|
@ -390,7 +391,7 @@ void RVVEmitter::createHeader(raw_ostream &OS) {
|
||||||
|
|
||||||
OS << "#if (__riscv_v_elen_fp >= 64)\n";
|
OS << "#if (__riscv_v_elen_fp >= 64)\n";
|
||||||
for (int Log2LMUL : Log2LMULs) {
|
for (int Log2LMUL : Log2LMULs) {
|
||||||
auto T = RVVType::computeType(BasicType::Float64, Log2LMUL,
|
auto T = TypeCache.computeType(BasicType::Float64, Log2LMUL,
|
||||||
PrototypeDescriptor::Vector);
|
PrototypeDescriptor::Vector);
|
||||||
if (T)
|
if (T)
|
||||||
printType(T.value());
|
printType(T.value());
|
||||||
|
@ -553,14 +554,15 @@ void RVVEmitter::createRVVIntrinsics(
|
||||||
for (int Log2LMUL : Log2LMULList) {
|
for (int Log2LMUL : Log2LMULList) {
|
||||||
BasicType BT = ParseBasicType(I);
|
BasicType BT = ParseBasicType(I);
|
||||||
Optional<RVVTypes> Types =
|
Optional<RVVTypes> Types =
|
||||||
RVVType::computeTypes(BT, Log2LMUL, NF, Prototype);
|
TypeCache.computeTypes(BT, Log2LMUL, NF, Prototype);
|
||||||
// Ignored to create new intrinsic if there are any illegal types.
|
// Ignored to create new intrinsic if there are any illegal types.
|
||||||
if (!Types)
|
if (!Types)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto SuffixStr = RVVIntrinsic::getSuffixStr(BT, Log2LMUL, SuffixDesc);
|
auto SuffixStr =
|
||||||
auto OverloadedSuffixStr =
|
RVVIntrinsic::getSuffixStr(TypeCache, BT, Log2LMUL, SuffixDesc);
|
||||||
RVVIntrinsic::getSuffixStr(BT, Log2LMUL, OverloadedSuffixDesc);
|
auto OverloadedSuffixStr = RVVIntrinsic::getSuffixStr(
|
||||||
|
TypeCache, BT, Log2LMUL, OverloadedSuffixDesc);
|
||||||
// Create a unmasked intrinsic
|
// Create a unmasked intrinsic
|
||||||
Out.push_back(std::make_unique<RVVIntrinsic>(
|
Out.push_back(std::make_unique<RVVIntrinsic>(
|
||||||
Name, SuffixStr, OverloadedName, OverloadedSuffixStr, IRName,
|
Name, SuffixStr, OverloadedName, OverloadedSuffixStr, IRName,
|
||||||
|
@ -576,7 +578,7 @@ void RVVEmitter::createRVVIntrinsics(
|
||||||
/*HasMaskedOffOperand=*/false, HasVL, NF,
|
/*HasMaskedOffOperand=*/false, HasVL, NF,
|
||||||
IsPrototypeDefaultTU, UnMaskedPolicyScheme, P);
|
IsPrototypeDefaultTU, UnMaskedPolicyScheme, P);
|
||||||
Optional<RVVTypes> PolicyTypes =
|
Optional<RVVTypes> PolicyTypes =
|
||||||
RVVType::computeTypes(BT, Log2LMUL, NF, PolicyPrototype);
|
TypeCache.computeTypes(BT, Log2LMUL, NF, PolicyPrototype);
|
||||||
Out.push_back(std::make_unique<RVVIntrinsic>(
|
Out.push_back(std::make_unique<RVVIntrinsic>(
|
||||||
Name, SuffixStr, OverloadedName, OverloadedSuffixStr, IRName,
|
Name, SuffixStr, OverloadedName, OverloadedSuffixStr, IRName,
|
||||||
/*IsMask=*/false, /*HasMaskedOffOperand=*/false, HasVL,
|
/*IsMask=*/false, /*HasMaskedOffOperand=*/false, HasVL,
|
||||||
|
@ -588,7 +590,7 @@ void RVVEmitter::createRVVIntrinsics(
|
||||||
continue;
|
continue;
|
||||||
// Create a masked intrinsic
|
// Create a masked intrinsic
|
||||||
Optional<RVVTypes> MaskTypes =
|
Optional<RVVTypes> MaskTypes =
|
||||||
RVVType::computeTypes(BT, Log2LMUL, NF, Prototype);
|
TypeCache.computeTypes(BT, Log2LMUL, NF, Prototype);
|
||||||
Out.push_back(std::make_unique<RVVIntrinsic>(
|
Out.push_back(std::make_unique<RVVIntrinsic>(
|
||||||
Name, SuffixStr, OverloadedName, OverloadedSuffixStr, MaskedIRName,
|
Name, SuffixStr, OverloadedName, OverloadedSuffixStr, MaskedIRName,
|
||||||
/*IsMasked=*/true, HasMaskedOffOperand, HasVL, MaskedPolicyScheme,
|
/*IsMasked=*/true, HasMaskedOffOperand, HasVL, MaskedPolicyScheme,
|
||||||
|
@ -603,7 +605,7 @@ void RVVEmitter::createRVVIntrinsics(
|
||||||
BasicPrototype, /*IsMasked=*/true, HasMaskedOffOperand, HasVL,
|
BasicPrototype, /*IsMasked=*/true, HasMaskedOffOperand, HasVL,
|
||||||
NF, IsPrototypeDefaultTU, MaskedPolicyScheme, P);
|
NF, IsPrototypeDefaultTU, MaskedPolicyScheme, P);
|
||||||
Optional<RVVTypes> PolicyTypes =
|
Optional<RVVTypes> PolicyTypes =
|
||||||
RVVType::computeTypes(BT, Log2LMUL, NF, PolicyPrototype);
|
TypeCache.computeTypes(BT, Log2LMUL, NF, PolicyPrototype);
|
||||||
Out.push_back(std::make_unique<RVVIntrinsic>(
|
Out.push_back(std::make_unique<RVVIntrinsic>(
|
||||||
Name, SuffixStr, OverloadedName, OverloadedSuffixStr,
|
Name, SuffixStr, OverloadedName, OverloadedSuffixStr,
|
||||||
MaskedIRName, /*IsMasked=*/true, HasMaskedOffOperand, HasVL,
|
MaskedIRName, /*IsMasked=*/true, HasMaskedOffOperand, HasVL,
|
||||||
|
|
Loading…
Reference in New Issue