diff options
Diffstat (limited to 'clang/utils/TableGen')
-rw-r--r-- | clang/utils/TableGen/SveEmitter.cpp | 110 | ||||
-rw-r--r-- | clang/utils/TableGen/TableGen.cpp | 12 | ||||
-rw-r--r-- | clang/utils/TableGen/TableGenBackends.h | 4 |
3 files changed, 123 insertions, 3 deletions
diff --git a/clang/utils/TableGen/SveEmitter.cpp b/clang/utils/TableGen/SveEmitter.cpp index af2dcf6..553c7a3 100644 --- a/clang/utils/TableGen/SveEmitter.cpp +++ b/clang/utils/TableGen/SveEmitter.cpp @@ -243,7 +243,9 @@ public: /// Return the name, mangled with type information. The name is mangled for /// ClassS, so will add type suffixes such as _u32/_s32. - std::string getMangledName() const { return mangleName(ClassS); } + std::string getMangledName(ClassKind CK = ClassS) const { + return mangleName(CK); + } /// As above, but mangles the LLVM name instead. std::string getMangledLLVMName() const { return mangleLLVMName(); } @@ -309,6 +311,7 @@ private: StringMap<uint64_t> FlagTypes; StringMap<uint64_t> MergeTypes; StringMap<uint64_t> ImmCheckTypes; + std::vector<llvm::StringRef> ImmCheckTypeNames; public: SVEEmitter(const RecordKeeper &R) : Records(R) { @@ -320,8 +323,15 @@ public: FlagTypes[RV->getNameInitAsString()] = RV->getValueAsInt("Value"); for (auto *RV : Records.getAllDerivedDefinitions("MergeType")) MergeTypes[RV->getNameInitAsString()] = RV->getValueAsInt("Value"); - for (auto *RV : Records.getAllDerivedDefinitions("ImmCheckType")) - ImmCheckTypes[RV->getNameInitAsString()] = RV->getValueAsInt("Value"); + for (auto *RV : Records.getAllDerivedDefinitions("ImmCheckType")) { + auto [it, inserted] = ImmCheckTypes.try_emplace( + RV->getNameInitAsString(), RV->getValueAsInt("Value")); + if (!inserted) + llvm_unreachable("Duplicate imm check"); + if ((size_t)it->second >= ImmCheckTypeNames.size()) + ImmCheckTypeNames.resize((size_t)it->second + 1); + ImmCheckTypeNames[it->second] = it->first(); + } } /// Returns the enum value for the immcheck type @@ -340,6 +350,13 @@ public: llvm_unreachable("Unsupported flag"); } + /// Returns the name for the immcheck type + StringRef getImmCheckForEnumValue(unsigned Id) { + if ((size_t)Id < ImmCheckTypeNames.size()) + return ImmCheckTypeNames[Id]; + llvm_unreachable("Unsupported imm check"); + } + // Returns the SVETypeFlags for a given value and mask. uint64_t encodeFlag(uint64_t V, StringRef MaskName) const { auto It = FlagTypes.find(MaskName); @@ -389,6 +406,9 @@ public: /// Emit all the __builtin prototypes and code needed by Sema. void createBuiltins(raw_ostream &o); + /// Emit all the __builtin prototypes in JSON format. + void createBuiltinsJSON(raw_ostream &o); + /// Emit all the information needed to map builtin -> LLVM IR intrinsic. void createCodeGenMap(raw_ostream &o); @@ -1552,6 +1572,82 @@ void SVEEmitter::createBuiltins(raw_ostream &OS) { OS << "#endif // GET_SVE_BUILTIN_INFOS\n\n"; } +void SVEEmitter::createBuiltinsJSON(raw_ostream &OS) { + SmallVector<std::unique_ptr<Intrinsic>, 128> Defs; + std::vector<const Record *> RV = Records.getAllDerivedDefinitions("Inst"); + for (auto *R : RV) + createIntrinsic(R, Defs); + + OS << "[\n"; + bool FirstDef = true; + + for (auto &Def : Defs) { + std::vector<std::string> Flags; + + if (Def->isFlagSet(getEnumValueForFlag("IsStreaming"))) + Flags.push_back("streaming-only"); + else if (Def->isFlagSet(getEnumValueForFlag("IsStreamingCompatible"))) + Flags.push_back("streaming-compatible"); + else if (Def->isFlagSet(getEnumValueForFlag("VerifyRuntimeMode"))) + Flags.push_back("feature-dependent"); + + if (Def->isFlagSet(getEnumValueForFlag("IsInZA")) || + Def->isFlagSet(getEnumValueForFlag("IsOutZA")) || + Def->isFlagSet(getEnumValueForFlag("IsInOutZA"))) + Flags.push_back("requires-za"); + + if (Def->isFlagSet(getEnumValueForFlag("IsInZT0")) || + Def->isFlagSet(getEnumValueForFlag("IsOutZT0")) || + Def->isFlagSet(getEnumValueForFlag("IsInOutZT0"))) + Flags.push_back("requires-zt"); + + if (!FirstDef) + OS << ",\n"; + + OS << "{ "; + OS << "\"guard\": \"" << Def->getSVEGuard() << "\","; + OS << "\"streaming_guard\": \"" << Def->getSMEGuard() << "\","; + OS << "\"flags\": \""; + + for (size_t I = 0; I < Flags.size(); ++I) { + if (I != 0) + OS << ','; + OS << Flags[I]; + } + + OS << "\",\"builtin\": \""; + + std::string BuiltinName = Def->getMangledName(Def->getClassKind()); + + OS << Def->getReturnType().str() << " " << BuiltinName << "("; + for (unsigned I = 0; I < Def->getTypes().size() - 1; ++I) { + if (I != 0) + OS << ", "; + + SVEType ParamType = Def->getParamType(I); + + // These are ImmCheck'd but their type names are sufficiently clear. + if (ParamType.isPredicatePattern() || ParamType.isPrefetchOp()) { + OS << ParamType.str(); + continue; + } + + // Pass ImmCheck information by pretending it's a type. + auto Iter = llvm::find_if(Def->getImmChecks(), [I](const auto &Chk) { + return (unsigned)Chk.getImmArgIdx() == I; + }); + if (Iter != Def->getImmChecks().end()) + OS << getImmCheckForEnumValue(Iter->getKind()); + else + OS << ParamType.str(); + } + OS << ");\" }"; + FirstDef = false; + } + + OS << "\n]\n"; +} + void SVEEmitter::createCodeGenMap(raw_ostream &OS) { std::vector<const Record *> RV = Records.getAllDerivedDefinitions("Inst"); SmallVector<std::unique_ptr<Intrinsic>, 128> Defs; @@ -1937,6 +2033,10 @@ void EmitSveBuiltins(const RecordKeeper &Records, raw_ostream &OS) { SVEEmitter(Records).createBuiltins(OS); } +void EmitSveBuiltinsJSON(const RecordKeeper &Records, raw_ostream &OS) { + SVEEmitter(Records).createBuiltinsJSON(OS); +} + void EmitSveBuiltinCG(const RecordKeeper &Records, raw_ostream &OS) { SVEEmitter(Records).createCodeGenMap(OS); } @@ -1965,6 +2065,10 @@ void EmitSmeBuiltins(const RecordKeeper &Records, raw_ostream &OS) { SVEEmitter(Records).createSMEBuiltins(OS); } +void EmitSmeBuiltinsJSON(const RecordKeeper &Records, raw_ostream &OS) { + SVEEmitter(Records).createBuiltinsJSON(OS); +} + void EmitSmeBuiltinCG(const RecordKeeper &Records, raw_ostream &OS) { SVEEmitter(Records).createSMECodeGenMap(OS); } diff --git a/clang/utils/TableGen/TableGen.cpp b/clang/utils/TableGen/TableGen.cpp index df14955..866040d 100644 --- a/clang/utils/TableGen/TableGen.cpp +++ b/clang/utils/TableGen/TableGen.cpp @@ -89,12 +89,14 @@ enum ActionType { GenArmMveBuiltinAliases, GenArmSveHeader, GenArmSveBuiltins, + GenArmSveBuiltinsJSON, GenArmSveBuiltinCG, GenArmSveTypeFlags, GenArmSveRangeChecks, GenArmSveStreamingAttrs, GenArmSmeHeader, GenArmSmeBuiltins, + GenArmSmeBuiltinsJSON, GenArmSmeBuiltinCG, GenArmSmeRangeChecks, GenArmSmeStreamingAttrs, @@ -266,6 +268,8 @@ cl::opt<ActionType> Action( "Generate arm_sve.h for clang"), clEnumValN(GenArmSveBuiltins, "gen-arm-sve-builtins", "Generate arm_sve_builtins.inc for clang"), + clEnumValN(GenArmSveBuiltinsJSON, "gen-arm-sve-builtins-json", + "Generate arm_sve_buitins.json"), clEnumValN(GenArmSveBuiltinCG, "gen-arm-sve-builtin-codegen", "Generate arm_sve_builtin_cg_map.inc for clang"), clEnumValN(GenArmSveTypeFlags, "gen-arm-sve-typeflags", @@ -278,6 +282,8 @@ cl::opt<ActionType> Action( "Generate arm_sme.h for clang"), clEnumValN(GenArmSmeBuiltins, "gen-arm-sme-builtins", "Generate arm_sme_builtins.inc for clang"), + clEnumValN(GenArmSmeBuiltinsJSON, "gen-arm-sme-builtins-json", + "Generate arm_sme_buitins.json"), clEnumValN(GenArmSmeBuiltinCG, "gen-arm-sme-builtin-codegen", "Generate arm_sme_builtin_cg_map.inc for clang"), clEnumValN(GenArmSmeRangeChecks, "gen-arm-sme-sema-rangechecks", @@ -551,6 +557,9 @@ bool ClangTableGenMain(raw_ostream &OS, const RecordKeeper &Records) { case GenArmSveBuiltins: EmitSveBuiltins(Records, OS); break; + case GenArmSveBuiltinsJSON: + EmitSveBuiltinsJSON(Records, OS); + break; case GenArmSveBuiltinCG: EmitSveBuiltinCG(Records, OS); break; @@ -569,6 +578,9 @@ bool ClangTableGenMain(raw_ostream &OS, const RecordKeeper &Records) { case GenArmSmeBuiltins: EmitSmeBuiltins(Records, OS); break; + case GenArmSmeBuiltinsJSON: + EmitSmeBuiltinsJSON(Records, OS); + break; case GenArmSmeBuiltinCG: EmitSmeBuiltinCG(Records, OS); break; diff --git a/clang/utils/TableGen/TableGenBackends.h b/clang/utils/TableGen/TableGenBackends.h index e017571..fa49dcd 100644 --- a/clang/utils/TableGen/TableGenBackends.h +++ b/clang/utils/TableGen/TableGenBackends.h @@ -140,6 +140,8 @@ void EmitImmCheckTypes(const llvm::RecordKeeper &Records, llvm::raw_ostream &OS); void EmitSveHeader(const llvm::RecordKeeper &Records, llvm::raw_ostream &OS); void EmitSveBuiltins(const llvm::RecordKeeper &Records, llvm::raw_ostream &OS); +void EmitSveBuiltinsJSON(const llvm::RecordKeeper &Records, + llvm::raw_ostream &OS); void EmitSveBuiltinCG(const llvm::RecordKeeper &Records, llvm::raw_ostream &OS); void EmitSveTypeFlags(const llvm::RecordKeeper &Records, llvm::raw_ostream &OS); void EmitSveRangeChecks(const llvm::RecordKeeper &Records, @@ -149,6 +151,8 @@ void EmitSveStreamingAttrs(const llvm::RecordKeeper &Records, void EmitSmeHeader(const llvm::RecordKeeper &Records, llvm::raw_ostream &OS); void EmitSmeBuiltins(const llvm::RecordKeeper &Records, llvm::raw_ostream &OS); +void EmitSmeBuiltinsJSON(const llvm::RecordKeeper &Records, + llvm::raw_ostream &OS); void EmitSmeBuiltinCG(const llvm::RecordKeeper &Records, llvm::raw_ostream &OS); void EmitSmeRangeChecks(const llvm::RecordKeeper &Records, llvm::raw_ostream &OS); |