kadircet created this revision. kadircet added reviewers: kito-cheng, ilya-biryukov. Herald added subscribers: sunshaoce, VincentWu, vkmr, frasercrmck, evandro, luismarques, apazos, sameer.abuasal, s.egerton, Jim, benna, psnobl, jocewei, PkmX, the_o, brucehoult, MartinMosbeck, rogfer01, edward-jones, zzheng, jrtc27, shiva0217, niosHD, sabuasal, simoncook, johnrusso, rbar, asb, arichardson. Herald added a project: All. kadircet requested review of this revision. Herald added subscribers: cfe-commits, pcwang-thead, eopXD, MaskRay. Herald added a project: clang.
As brought up in https://reviews.llvm.org/D124730#inline-1326968, this logic is used in places that are supposed to be thread-safe. Unfortunately putting a single mutex around these maps also wouldn't solve the issue because RVVType itself is mutable. So I see no other option but to drop the caches & pass-by-reference logic completely, this likely has performance implications. Whoever owns this probably should figure out a thread-safe place to store these instead. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D138287 Files: clang/include/clang/Support/RISCVVIntrinsicUtils.h clang/lib/Sema/SemaRISCVVectorLookup.cpp clang/lib/Support/RISCVVIntrinsicUtils.cpp clang/utils/TableGen/RISCVVEmitter.cpp
Index: clang/utils/TableGen/RISCVVEmitter.cpp =================================================================== --- clang/utils/TableGen/RISCVVEmitter.cpp +++ clang/utils/TableGen/RISCVVEmitter.cpp @@ -177,7 +177,7 @@ // Cast pointer operand of vector load intrinsic. for (const auto &I : enumerate(RVVI->getInputTypes())) { - if (I.value()->isPointer()) { + if (I.value().isPointer()) { assert(RVVI->getIntrinsicTypes().front() == -1 && "RVVI should be vector load intrinsic."); OS << " Ops[" << I.index() << "] = Builder.CreateBitCast(Ops["; @@ -342,7 +342,7 @@ printHeaderCode(OS); auto printType = [&](auto T) { - OS << "typedef " << T->getClangBuiltinStr() << " " << T->getTypeStr() + OS << "typedef " << T.getClangBuiltinStr() << " " << T.getTypeStr() << ";\n"; }; Index: clang/lib/Support/RISCVVIntrinsicUtils.cpp =================================================================== --- clang/lib/Support/RISCVVIntrinsicUtils.cpp +++ clang/lib/Support/RISCVVIntrinsicUtils.cpp @@ -803,42 +803,11 @@ return Types; } -// Compute the hash value of RVVType, used for cache the result of computeType. -static uint64_t computeRVVTypeHashValue(BasicType BT, int Log2LMUL, - PrototypeDescriptor Proto) { - // Layout of hash value: - // 0 8 16 24 32 40 - // | Log2LMUL + 3 | BT | Proto.PT | Proto.TM | Proto.VTM | - assert(Log2LMUL >= -3 && Log2LMUL <= 3); - return (Log2LMUL + 3) | (static_cast<uint64_t>(BT) & 0xff) << 8 | - ((uint64_t)(Proto.PT & 0xff) << 16) | - ((uint64_t)(Proto.TM & 0xff) << 24) | - ((uint64_t)(Proto.VTM & 0xff) << 32); -} - -Optional<RVVTypePtr> RVVType::computeType(BasicType BT, int Log2LMUL, +Optional<RVVType> RVVType::computeType(BasicType BT, int Log2LMUL, 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); - // Search first - auto It = LegalTypes.find(Idx); - if (It != LegalTypes.end()) - return &(It->second); - - if (IllegalTypes.count(Idx)) - return llvm::None; - - // Compute type and record the result. RVVType T(BT, Log2LMUL, Proto); - if (T.isValid()) { - // Record legal type index and value. - LegalTypes.insert({Idx, T}); - return &(LegalTypes[Idx]); - } - // Record illegal type index. - IllegalTypes.insert(Idx); + if (T.isValid()) + return T; return llvm::None; } @@ -892,9 +861,9 @@ std::string RVVIntrinsic::getBuiltinTypeStr() const { std::string S; - S += OutputType->getBuiltinStr(); + S += OutputType.getBuiltinStr(); for (const auto &T : InputTypes) { - S += T->getBuiltinStr(); + S += T.getBuiltinStr(); } return S; } @@ -905,7 +874,7 @@ SmallVector<std::string> SuffixStrs; for (auto PD : PrototypeDescriptors) { auto T = RVVType::computeType(Type, Log2LMUL, PD); - SuffixStrs.push_back((*T)->getShortStr()); + SuffixStrs.push_back((*T).getShortStr()); } return join(SuffixStrs, "_"); } Index: clang/lib/Sema/SemaRISCVVectorLookup.cpp =================================================================== --- clang/lib/Sema/SemaRISCVVectorLookup.cpp +++ clang/lib/Sema/SemaRISCVVectorLookup.cpp @@ -354,16 +354,15 @@ bool IsOverload) { ASTContext &Context = S.Context; RVVIntrinsicDef &IDef = IntrinsicList[Index]; - RVVTypes Sigs = IDef.Signature; + RVVTypes &Sigs = IDef.Signature; size_t SigLength = Sigs.size(); - RVVType *ReturnType = Sigs[0]; - QualType RetType = RVVType2Qual(Context, ReturnType); + QualType RetType = RVVType2Qual(Context, &Sigs[0]); SmallVector<QualType, 8> ArgTypes; QualType BuiltinFuncType; // Skip return type, and convert RVVType to QualType for arguments. for (size_t i = 1; i < SigLength; ++i) - ArgTypes.push_back(RVVType2Qual(Context, Sigs[i])); + ArgTypes.push_back(RVVType2Qual(Context, &Sigs[i])); FunctionProtoType::ExtProtoInfo PI( Context.getDefaultCallingConvention(false, false, true)); Index: clang/include/clang/Support/RISCVVIntrinsicUtils.h =================================================================== --- clang/include/clang/Support/RISCVVIntrinsicUtils.h +++ clang/include/clang/Support/RISCVVIntrinsicUtils.h @@ -180,8 +180,7 @@ }; class RVVType; -using RVVTypePtr = RVVType *; -using RVVTypes = std::vector<RVVTypePtr>; +using RVVTypes = std::vector<RVVType>; // This class is compact representation of a valid and invalid RVVType. class RVVType { @@ -284,8 +283,8 @@ static llvm::Optional<RVVTypes> computeTypes(BasicType BT, int Log2LMUL, unsigned NF, llvm::ArrayRef<PrototypeDescriptor> Prototype); - static llvm::Optional<RVVTypePtr> computeType(BasicType BT, int Log2LMUL, - PrototypeDescriptor Proto); + static llvm::Optional<RVVType> computeType(BasicType BT, int Log2LMUL, + PrototypeDescriptor Proto); }; enum PolicyScheme : uint8_t { @@ -315,7 +314,7 @@ bool SupportOverloading; bool HasBuiltinAlias; std::string ManualCodegen; - RVVTypePtr OutputType; // Builtin output type + RVVType OutputType; // Builtin output type RVVTypes InputTypes; // Builtin input types // The types we use to obtain the specific LLVM intrinsic. They are index of // InputTypes. -1 means the return type. @@ -335,7 +334,7 @@ unsigned NF, Policy DefaultPolicy, bool IsPrototypeDefaultTU); ~RVVIntrinsic() = default; - RVVTypePtr getOutputType() const { return OutputType; } + RVVType getOutputType() const { return OutputType; } const RVVTypes &getInputTypes() const { return InputTypes; } llvm::StringRef getBuiltinName() const { return BuiltinName; } llvm::StringRef getName() const { return Name; } @@ -377,13 +376,13 @@ llvm::ArrayRef<PrototypeDescriptor> PrototypeDescriptors); static llvm::SmallVector<PrototypeDescriptor> - computeBuiltinTypes(llvm::ArrayRef<PrototypeDescriptor> Prototype, - bool IsMasked, bool HasMaskedOffOperand, bool HasVL, - unsigned NF, bool IsPrototypeDefaultTU, - PolicyScheme DefaultScheme, - Policy DefaultPolicy = Policy::PolicyNone); + computeBuiltinTypes(llvm::ArrayRef<PrototypeDescriptor> Prototype, + bool IsMasked, bool HasMaskedOffOperand, bool HasVL, + unsigned NF, bool IsPrototypeDefaultTU, + PolicyScheme DefaultScheme, + Policy DefaultPolicy = Policy::PolicyNone); static llvm::SmallVector<Policy> - getSupportedMaskedPolicies(bool HasTailPolicy, bool HasMaskPolicy); + getSupportedMaskedPolicies(bool HasTailPolicy, bool HasMaskPolicy); static void updateNamesAndPolicy(bool IsMasked, bool HasPolicy, bool IsPrototypeDefaultTU, std::string &Name,
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits