diff --git a/llvm/include/llvm/ADT/STLExtras.h b/llvm/include/llvm/ADT/STLExtras.h index 3f5ea3a5275f3..a810a1c318c42 100644 --- a/llvm/include/llvm/ADT/STLExtras.h +++ b/llvm/include/llvm/ADT/STLExtras.h @@ -1843,6 +1843,13 @@ OutputIt replace_copy(R &&Range, OutputIt Out, const T &OldValue, NewValue); } +/// Provide wrappers to std::replace which take ranges instead of having to pass +/// begin/end explicitly. +template +void replace(R &&Range, const T &OldValue, const T &NewValue) { + return std::replace(adl_begin(Range), adl_end(Range), OldValue, NewValue); +} + /// Provide wrappers to std::move which take ranges instead of having to /// pass begin/end explicitly. template diff --git a/llvm/lib/Object/COFFImportFile.cpp b/llvm/lib/Object/COFFImportFile.cpp index e67b02405a3a1..cc0a5da7e0d16 100644 --- a/llvm/lib/Object/COFFImportFile.cpp +++ b/llvm/lib/Object/COFFImportFile.cpp @@ -705,7 +705,7 @@ Error writeImportLibrary(StringRef ImportName, StringRef Path, Name = std::string(SymbolName); } else { Expected ReplacedName = - replace(SymbolName, E.Name, E.ExtName); + object::replace(SymbolName, E.Name, E.ExtName); if (!ReplacedName) return ReplacedName.takeError(); Name.swap(*ReplacedName); diff --git a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp index 9153645e3d9a1..4bca904e9f38b 100644 --- a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp +++ b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp @@ -29,16 +29,16 @@ CodeGenIntrinsicTable::CodeGenIntrinsicTable(const RecordKeeper &RC) { std::vector IntrProperties = RC.getAllDerivedDefinitions("IntrinsicProperty"); - std::vector DefaultProperties; - for (Record *Rec : IntrProperties) + std::vector DefaultProperties; + for (const Record *Rec : IntrProperties) if (Rec->getValueAsBit("IsDefault")) DefaultProperties.push_back(Rec); std::vector Defs = RC.getAllDerivedDefinitions("Intrinsic"); Intrinsics.reserve(Defs.size()); - for (unsigned I = 0, e = Defs.size(); I != e; ++I) - Intrinsics.push_back(CodeGenIntrinsic(Defs[I], DefaultProperties)); + for (const Record *Def : Defs) + Intrinsics.push_back(CodeGenIntrinsic(Def, DefaultProperties)); llvm::sort(Intrinsics, [](const CodeGenIntrinsic &LHS, const CodeGenIntrinsic &RHS) { @@ -54,52 +54,34 @@ CodeGenIntrinsicTable::CodeGenIntrinsicTable(const RecordKeeper &RC) { Targets.back().Count = Intrinsics.size() - Targets.back().Offset; } -CodeGenIntrinsic::CodeGenIntrinsic(Record *R, - ArrayRef DefaultProperties) { - TheDef = R; - std::string DefName = std::string(R->getName()); +CodeGenIntrinsic::CodeGenIntrinsic(const Record *R, + ArrayRef DefaultProperties) + : TheDef(R) { + StringRef DefName = TheDef->getName(); ArrayRef DefLoc = R->getLoc(); - Properties = 0; - isOverloaded = false; - isCommutative = false; - canThrow = false; - isNoReturn = false; - isNoCallback = false; - isNoSync = false; - isNoFree = false; - isWillReturn = false; - isCold = false; - isNoDuplicate = false; - isNoMerge = false; - isConvergent = false; - isSpeculatable = false; - hasSideEffects = false; - isStrictFP = false; - if (DefName.size() <= 4 || DefName.substr(0, 4) != "int_") + if (!DefName.starts_with("int_")) PrintFatalError(DefLoc, "Intrinsic '" + DefName + "' does not start with 'int_'!"); EnumName = DefName.substr(4); - if (R->getValue( - "ClangBuiltinName")) // Ignore a missing ClangBuiltinName field. - ClangBuiltinName = std::string(R->getValueAsString("ClangBuiltinName")); - if (R->getValue("MSBuiltinName")) // Ignore a missing MSBuiltinName field. - MSBuiltinName = std::string(R->getValueAsString("MSBuiltinName")); + // Ignore a missing ClangBuiltinName field. + ClangBuiltinName = + R->getValueAsOptionalString("ClangBuiltinName").value_or(""); + // Ignore a missing MSBuiltinName field. + MSBuiltinName = R->getValueAsOptionalString("MSBuiltinName").value_or(""); - TargetPrefix = std::string(R->getValueAsString("TargetPrefix")); - Name = std::string(R->getValueAsString("LLVMName")); + TargetPrefix = R->getValueAsString("TargetPrefix"); + Name = R->getValueAsString("LLVMName").str(); if (Name == "") { // If an explicit name isn't specified, derive one from the DefName. - Name = "llvm."; - - for (unsigned i = 0, e = EnumName.size(); i != e; ++i) - Name += (EnumName[i] == '_') ? '.' : EnumName[i]; + Name = "llvm." + EnumName.str(); + llvm::replace(Name, '_', '.'); } else { // Verify it starts with "llvm.". - if (Name.size() <= 5 || Name.substr(0, 5) != "llvm.") + if (!StringRef(Name).starts_with("llvm.")) PrintFatalError(DefLoc, "Intrinsic '" + DefName + "'s name does not start with 'llvm.'!"); } @@ -107,8 +89,8 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R, // If TargetPrefix is specified, make sure that Name starts with // "llvm..". if (!TargetPrefix.empty()) { - if (Name.size() < 6 + TargetPrefix.size() || - Name.substr(5, 1 + TargetPrefix.size()) != (TargetPrefix + ".")) + StringRef Prefix = StringRef(Name).drop_front(5); // Drop llvm. + if (!Prefix.consume_front(TargetPrefix) || !Prefix.starts_with('.')) PrintFatalError(DefLoc, "Intrinsic '" + DefName + "' does not start with 'llvm." + TargetPrefix + ".'!"); @@ -129,7 +111,7 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R, // Parse the intrinsic properties. ListInit *PropList = R->getValueAsListInit("IntrProperties"); for (unsigned i = 0, e = PropList->size(); i != e; ++i) { - Record *Property = PropList->getElementAsRecord(i); + const Record *Property = PropList->getElementAsRecord(i); assert(Property->isSubClassOf("IntrinsicProperty") && "Expected a property!"); @@ -137,7 +119,7 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R, } // Set default properties to true. - setDefaultProperties(R, DefaultProperties); + setDefaultProperties(DefaultProperties); // Also record the SDPatternOperator Properties. Properties = parseSDPatternOperatorProperties(R); @@ -148,16 +130,16 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R, } void CodeGenIntrinsic::setDefaultProperties( - Record *R, ArrayRef DefaultProperties) { + ArrayRef DefaultProperties) { // opt-out of using default attributes. - if (R->getValueAsBit("DisableDefaultAttributes")) + if (TheDef->getValueAsBit("DisableDefaultAttributes")) return; - for (Record *Rec : DefaultProperties) + for (const Record *Rec : DefaultProperties) setProperty(Rec); } -void CodeGenIntrinsic::setProperty(Record *R) { +void CodeGenIntrinsic::setProperty(const Record *R) { if (R->getName() == "IntrNoMem") ME = MemoryEffects::none(); else if (R->getName() == "IntrReadMem") { diff --git a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.h b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.h index 417063a9490ef..19e29af2fa85f 100644 --- a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.h +++ b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.h @@ -26,12 +26,12 @@ class Record; class RecordKeeper; struct CodeGenIntrinsic { - Record *TheDef; // The actual record defining this intrinsic. + const Record *TheDef; // The actual record defining this intrinsic. std::string Name; // The name of the LLVM function "llvm.bswap.i32" - std::string EnumName; // The name of the enum "bswap_i32" - std::string ClangBuiltinName; // Name of the corresponding GCC builtin, or "". - std::string MSBuiltinName; // Name of the corresponding MS builtin, or "". - std::string TargetPrefix; // Target prefix, e.g. "ppc" for t-s intrinsics. + StringRef EnumName; // The name of the enum "bswap_i32" + StringRef ClangBuiltinName; // Name of the corresponding GCC builtin, or "". + StringRef MSBuiltinName; // Name of the corresponding MS builtin, or "". + StringRef TargetPrefix; // Target prefix, e.g. "ppc" for t-s intrinsics. /// This structure holds the return values and parameter values of an /// intrinsic. If the number of return values is > 1, then the intrinsic @@ -43,13 +43,13 @@ struct CodeGenIntrinsic { /// only populated when in the context of a target .td file. When building /// Intrinsics.td, this isn't available, because we don't know the target /// pointer size. - std::vector RetTys; + std::vector RetTys; /// The MVT::SimpleValueType for each parameter type. Note that this list is /// only populated when in the context of a target .td file. When building /// Intrinsics.td, this isn't available, because we don't know the target /// pointer size. - std::vector ParamTys; + std::vector ParamTys; }; IntrinsicSignature IS; @@ -58,54 +58,54 @@ struct CodeGenIntrinsic { MemoryEffects ME = MemoryEffects::unknown(); /// SDPatternOperator Properties applied to the intrinsic. - unsigned Properties; + unsigned Properties = 0; /// This is set to true if the intrinsic is overloaded by its argument /// types. - bool isOverloaded; + bool isOverloaded = false; /// True if the intrinsic is commutative. - bool isCommutative; + bool isCommutative = false; /// True if the intrinsic can throw. - bool canThrow; + bool canThrow = false; /// True if the intrinsic is marked as noduplicate. - bool isNoDuplicate; + bool isNoDuplicate = false; /// True if the intrinsic is marked as nomerge. - bool isNoMerge; + bool isNoMerge = false; /// True if the intrinsic is no-return. - bool isNoReturn; + bool isNoReturn = false; /// True if the intrinsic is no-callback. - bool isNoCallback; + bool isNoCallback = false; /// True if the intrinsic is no-sync. - bool isNoSync; + bool isNoSync = false; /// True if the intrinsic is no-free. - bool isNoFree; + bool isNoFree = false; /// True if the intrinsic is will-return. - bool isWillReturn; + bool isWillReturn = false; /// True if the intrinsic is cold. - bool isCold; + bool isCold = false; /// True if the intrinsic is marked as convergent. - bool isConvergent; + bool isConvergent = false; /// True if the intrinsic has side effects that aren't captured by any /// of the other flags. - bool hasSideEffects; + bool hasSideEffects = false; // True if the intrinsic is marked as speculatable. - bool isSpeculatable; + bool isSpeculatable = false; // True if the intrinsic is marked as strictfp. - bool isStrictFP; + bool isStrictFP = false; enum ArgAttrKind { NoCapture, @@ -139,12 +139,12 @@ struct CodeGenIntrinsic { bool hasProperty(enum SDNP Prop) const { return Properties & (1 << Prop); } - /// Goes through all IntrProperties that have IsDefault - /// value set and sets the property. - void setDefaultProperties(Record *R, ArrayRef DefaultProperties); + /// Goes through all IntrProperties that have IsDefault value set and sets + /// the property. + void setDefaultProperties(ArrayRef DefaultProperties); - /// Helper function to set property \p Name to true; - void setProperty(Record *R); + /// Helper function to set property \p Name to true. + void setProperty(const Record *R); /// Returns true if the parameter at \p ParamIdx is a pointer type. Returns /// false if the parameter is not a pointer, or \p ParamIdx is greater than @@ -155,7 +155,8 @@ struct CodeGenIntrinsic { bool isParamImmArg(unsigned ParamIdx) const; - CodeGenIntrinsic(Record *R, ArrayRef DefaultProperties); + CodeGenIntrinsic(const Record *R, + ArrayRef DefaultProperties = {}); }; class CodeGenIntrinsicTable { @@ -163,7 +164,7 @@ class CodeGenIntrinsicTable { public: struct TargetSet { - std::string Name; + StringRef Name; size_t Offset; size_t Count; }; diff --git a/llvm/utils/TableGen/Basic/SDNodeProperties.cpp b/llvm/utils/TableGen/Basic/SDNodeProperties.cpp index 2aec41aac6257..46babbbc41944 100644 --- a/llvm/utils/TableGen/Basic/SDNodeProperties.cpp +++ b/llvm/utils/TableGen/Basic/SDNodeProperties.cpp @@ -13,9 +13,9 @@ using namespace llvm; -unsigned llvm::parseSDPatternOperatorProperties(Record *R) { +unsigned llvm::parseSDPatternOperatorProperties(const Record *R) { unsigned Properties = 0; - for (Record *Property : R->getValueAsListOfDefs("Properties")) { + for (const Record *Property : R->getValueAsListOfDefs("Properties")) { auto Offset = StringSwitch(Property->getName()) .Case("SDNPCommutative", SDNPCommutative) .Case("SDNPAssociative", SDNPAssociative) diff --git a/llvm/utils/TableGen/Basic/SDNodeProperties.h b/llvm/utils/TableGen/Basic/SDNodeProperties.h index 10d0bb965fbb6..1fe4044edcea2 100644 --- a/llvm/utils/TableGen/Basic/SDNodeProperties.h +++ b/llvm/utils/TableGen/Basic/SDNodeProperties.h @@ -32,7 +32,7 @@ enum SDNP { SDNPWantParent }; -unsigned parseSDPatternOperatorProperties(Record *R); +unsigned parseSDPatternOperatorProperties(const Record *R); } // namespace llvm diff --git a/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp b/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp index 9b9686c627b75..139bf2d821803 100644 --- a/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp +++ b/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp @@ -1314,7 +1314,7 @@ void IntrinsicIDOperandMatcher::emitPredicateOpcodes(MatchTable &Table, Table << MatchTable::Opcode("GIM_CheckIntrinsicID") << MatchTable::Comment("MI") << MatchTable::ULEB128Value(InsnVarID) << MatchTable::Comment("Op") << MatchTable::ULEB128Value(OpIdx) - << MatchTable::NamedValue(2, "Intrinsic::" + II->EnumName) + << MatchTable::NamedValue(2, "Intrinsic::" + II->EnumName.str()) << MatchTable::LineBreak; } @@ -2103,7 +2103,7 @@ void IntrinsicIDRenderer::emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const { Table << MatchTable::Opcode("GIR_AddIntrinsicID") << MatchTable::Comment("MI") << MatchTable::ULEB128Value(InsnID) - << MatchTable::NamedValue(2, "Intrinsic::" + II->EnumName) + << MatchTable::NamedValue(2, "Intrinsic::" + II->EnumName.str()) << MatchTable::LineBreak; } diff --git a/llvm/utils/TableGen/Common/GlobalISel/PatternParser.cpp b/llvm/utils/TableGen/Common/GlobalISel/PatternParser.cpp index 1d6c4c73a2640..82fa3c8f3121f 100644 --- a/llvm/utils/TableGen/Common/GlobalISel/PatternParser.cpp +++ b/llvm/utils/TableGen/Common/GlobalISel/PatternParser.cpp @@ -112,7 +112,7 @@ static const CodeGenIntrinsic *getCodeGenIntrinsic(Record *R) { auto &Ptr = AllIntrinsics[R]; if (!Ptr) - Ptr = std::make_unique(R, std::vector()); + Ptr = std::make_unique(R); return Ptr.get(); } diff --git a/llvm/utils/TableGen/IntrinsicEmitter.cpp b/llvm/utils/TableGen/IntrinsicEmitter.cpp index a7e99fa4c0506..b1307153e9109 100644 --- a/llvm/utils/TableGen/IntrinsicEmitter.cpp +++ b/llvm/utils/TableGen/IntrinsicEmitter.cpp @@ -35,18 +35,18 @@ #include using namespace llvm; -cl::OptionCategory GenIntrinsicCat("Options for -gen-intrinsic-enums"); -cl::opt +static cl::OptionCategory GenIntrinsicCat("Options for -gen-intrinsic-enums"); +static cl::opt IntrinsicPrefix("intrinsic-prefix", cl::desc("Generate intrinsics with this target prefix"), cl::value_desc("target prefix"), cl::cat(GenIntrinsicCat)); namespace { class IntrinsicEmitter { - RecordKeeper &Records; + const RecordKeeper &Records; public: - IntrinsicEmitter(RecordKeeper &R) : Records(R) {} + IntrinsicEmitter(const RecordKeeper &R) : Records(R) {} void run(raw_ostream &OS, bool Enums); @@ -123,7 +123,7 @@ void IntrinsicEmitter::EmitEnumInfo(const CodeGenIntrinsicTable &Ints, std::vector KnownTargets; for (const auto &Target : Ints.Targets) if (!Target.Name.empty()) - KnownTargets.push_back(Target.Name); + KnownTargets.push_back(Target.Name.str()); PrintFatalError("tried to generate intrinsics for unknown target " + IntrinsicPrefix + "\nKnown targets are: " + join(KnownTargets, ", ") + "\n"); @@ -136,12 +136,11 @@ void IntrinsicEmitter::EmitEnumInfo(const CodeGenIntrinsicTable &Ints, std::string UpperPrefix = StringRef(IntrinsicPrefix).upper(); OS << "#ifndef LLVM_IR_INTRINSIC_" << UpperPrefix << "_ENUMS_H\n"; OS << "#define LLVM_IR_INTRINSIC_" << UpperPrefix << "_ENUMS_H\n\n"; - OS << "namespace llvm {\n"; - OS << "namespace Intrinsic {\n"; + OS << "namespace llvm::Intrinsic {\n"; OS << "enum " << UpperPrefix << "Intrinsics : unsigned {\n"; } - OS << "// Enum values for intrinsics\n"; + OS << "// Enum values for intrinsics.\n"; for (unsigned i = Set->Offset, e = Set->Offset + Set->Count; i != e; ++i) { OS << " " << Ints[i].EnumName; @@ -162,8 +161,7 @@ void IntrinsicEmitter::EmitEnumInfo(const CodeGenIntrinsicTable &Ints, OS << "#endif\n\n"; } else { OS << "}; // enum\n"; - OS << "} // namespace Intrinsic\n"; - OS << "} // namespace llvm\n\n"; + OS << "} // namespace llvm::Intrinsic\n\n"; OS << "#endif\n"; } } @@ -171,7 +169,7 @@ void IntrinsicEmitter::EmitEnumInfo(const CodeGenIntrinsicTable &Ints, void IntrinsicEmitter::EmitArgKind(raw_ostream &OS) { if (!IntrinsicPrefix.empty()) return; - OS << "// llvm::Intrinsic::IITDescriptor::ArgKind\n"; + OS << "// llvm::Intrinsic::IITDescriptor::ArgKind.\n"; OS << "#ifdef GET_INTRINSIC_ARGKIND\n"; if (auto RecArgKind = Records.getDef("ArgKind")) { for (auto &RV : RecArgKind->getValues()) @@ -205,7 +203,7 @@ void IntrinsicEmitter::EmitIITInfo(raw_ostream &OS) { void IntrinsicEmitter::EmitTargetInfo(const CodeGenIntrinsicTable &Ints, raw_ostream &OS) { - OS << "// Target mapping\n"; + OS << "// Target mapping.\n"; OS << "#ifdef GET_INTRINSIC_TARGET_DATA\n"; OS << "struct IntrinsicTargetInfo {\n" << " llvm::StringLiteral Name;\n" @@ -222,19 +220,19 @@ void IntrinsicEmitter::EmitTargetInfo(const CodeGenIntrinsicTable &Ints, void IntrinsicEmitter::EmitIntrinsicToNameTable( const CodeGenIntrinsicTable &Ints, raw_ostream &OS) { - OS << "// Intrinsic ID to name table\n"; + OS << "// Intrinsic ID to name table.\n"; OS << "#ifdef GET_INTRINSIC_NAME_TABLE\n"; OS << " // Note that entry #0 is the invalid intrinsic!\n"; - for (unsigned i = 0, e = Ints.size(); i != e; ++i) - OS << " \"" << Ints[i].Name << "\",\n"; + for (const auto &Int : Ints) + OS << " \"" << Int.Name << "\",\n"; OS << "#endif\n\n"; } void IntrinsicEmitter::EmitIntrinsicToOverloadTable( const CodeGenIntrinsicTable &Ints, raw_ostream &OS) { - OS << "// Intrinsic ID to overload bitset\n"; + OS << "// Intrinsic ID to overload bitset.\n"; OS << "#ifdef GET_INTRINSIC_OVERLOAD_TABLE\n"; - OS << "static const uint8_t OTable[] = {\n"; + OS << "static constexpr uint8_t OTable[] = {\n"; OS << " 0"; for (unsigned i = 0, e = Ints.size(); i != e; ++i) { // Add one to the index so we emit a null bit for the invalid #0 intrinsic. @@ -315,7 +313,7 @@ void IntrinsicEmitter::EmitGenerator(const CodeGenIntrinsicTable &Ints, OS << "// Global intrinsic function declaration type table.\n"; OS << "#ifdef GET_INTRINSIC_GENERATOR_GLOBAL\n"; - OS << "static const unsigned IIT_Table[] = {\n "; + OS << "static constexpr unsigned IIT_Table[] = {\n "; for (unsigned i = 0, e = FixedEncodings.size(); i != e; ++i) { if ((i & 7) == 7) @@ -338,7 +336,7 @@ void IntrinsicEmitter::EmitGenerator(const CodeGenIntrinsicTable &Ints, OS << "0\n};\n\n"; // Emit the shared table of register lists. - OS << "static const unsigned char IIT_LongEncodingTable[] = {\n"; + OS << "static constexpr unsigned char IIT_LongEncodingTable[] = {\n"; if (!LongEncodingTable.empty()) LongEncodingTable.emit(OS, printIITEntry); OS << " 255\n};\n\n"; @@ -346,72 +344,44 @@ void IntrinsicEmitter::EmitGenerator(const CodeGenIntrinsicTable &Ints, OS << "#endif\n\n"; // End of GET_INTRINSIC_GENERATOR_GLOBAL } -namespace { -std::optional compareFnAttributes(const CodeGenIntrinsic *L, - const CodeGenIntrinsic *R) { - // Sort throwing intrinsics after non-throwing intrinsics. - if (L->canThrow != R->canThrow) - return R->canThrow; - - if (L->isNoDuplicate != R->isNoDuplicate) - return R->isNoDuplicate; - - if (L->isNoMerge != R->isNoMerge) - return R->isNoMerge; - - if (L->isNoReturn != R->isNoReturn) - return R->isNoReturn; - - if (L->isNoCallback != R->isNoCallback) - return R->isNoCallback; - - if (L->isNoSync != R->isNoSync) - return R->isNoSync; - - if (L->isNoFree != R->isNoFree) - return R->isNoFree; - - if (L->isWillReturn != R->isWillReturn) - return R->isWillReturn; - - if (L->isCold != R->isCold) - return R->isCold; +static bool compareFnAttributes(const CodeGenIntrinsic *L, + const CodeGenIntrinsic *R, bool Default) { + auto TieBoolAttributes = [](const CodeGenIntrinsic *I) -> auto { + // Sort throwing intrinsics after non-throwing intrinsics. + return std::tie(I->canThrow, I->isNoDuplicate, I->isNoMerge, I->isNoReturn, + I->isNoCallback, I->isNoSync, I->isNoFree, I->isWillReturn, + I->isCold, I->isConvergent, I->isSpeculatable, + I->hasSideEffects, I->isStrictFP); + }; - if (L->isConvergent != R->isConvergent) - return R->isConvergent; + auto TieL = TieBoolAttributes(L); + auto TieR = TieBoolAttributes(R); - if (L->isSpeculatable != R->isSpeculatable) - return R->isSpeculatable; - - if (L->hasSideEffects != R->hasSideEffects) - return R->hasSideEffects; - - if (L->isStrictFP != R->isStrictFP) - return R->isStrictFP; + if (TieL != TieR) + return TieL < TieR; // Try to order by readonly/readnone attribute. uint32_t LK = L->ME.toIntValue(); uint32_t RK = R->ME.toIntValue(); if (LK != RK) - return (LK > RK); + return LK > RK; - return std::nullopt; + return Default; } +namespace { struct FnAttributeComparator { bool operator()(const CodeGenIntrinsic *L, const CodeGenIntrinsic *R) const { - return compareFnAttributes(L, R).value_or(false); + return compareFnAttributes(L, R, false); } }; struct AttributeComparator { bool operator()(const CodeGenIntrinsic *L, const CodeGenIntrinsic *R) const { - if (std::optional Res = compareFnAttributes(L, R)) - return *Res; - - // Order by argument attributes. + // Order by argument attributes if function attributes are equal. // This is reliable because each side is already sorted internally. - return (L->ArgumentAttributes < R->ArgumentAttributes); + return compareFnAttributes(L, R, + L->ArgumentAttributes < R->ArgumentAttributes); } }; } // End anonymous namespace @@ -559,7 +529,7 @@ void IntrinsicEmitter::EmitAttributes(const CodeGenIntrinsicTable &Ints, // Emit an array of AttributeList. Most intrinsics will have at least one // entry, for the function itself (index ~1), which is usually nounwind. - OS << " static const uint16_t IntrinsicsToAttributesMap[] = {\n"; + OS << " static constexpr uint16_t IntrinsicsToAttributesMap[] = {\n"; for (unsigned i = 0, e = Ints.size(); i != e; ++i) { const CodeGenIntrinsic &intrinsic = Ints[i]; @@ -624,31 +594,34 @@ void IntrinsicEmitter::EmitAttributes(const CodeGenIntrinsicTable &Ints, void IntrinsicEmitter::EmitIntrinsicToBuiltinMap( const CodeGenIntrinsicTable &Ints, bool IsClang, raw_ostream &OS) { - StringRef CompilerName = (IsClang ? "Clang" : "MS"); - StringRef UpperCompilerName = (IsClang ? "CLANG" : "MS"); - typedef std::map> BIMTy; + StringRef CompilerName = IsClang ? "Clang" : "MS"; + StringRef UpperCompilerName = IsClang ? "CLANG" : "MS"; + // map>. Note that we iterate over + // both maps in the code below. For the inner map, entries need to be emitted + // in the sorted order of `BuiltinName` because we use std::lower_bound to + // search these entries. For the outer map, it doesn't need be be sorted, but + // we use a map to eliminate non-determinism in the emitted code. + typedef std::map> BIMTy; BIMTy BuiltinMap; StringToOffsetTable Table; - for (unsigned i = 0, e = Ints.size(); i != e; ++i) { - const std::string &BuiltinName = - IsClang ? Ints[i].ClangBuiltinName : Ints[i].MSBuiltinName; - if (!BuiltinName.empty()) { - // Get the map for this target prefix. - std::map &BIM = - BuiltinMap[Ints[i].TargetPrefix]; - - if (!BIM.insert(std::pair(BuiltinName, Ints[i].EnumName)).second) - PrintFatalError(Ints[i].TheDef->getLoc(), - "Intrinsic '" + Ints[i].TheDef->getName() + - "': duplicate " + CompilerName + " builtin name!"); - Table.GetOrAddStringOffset(BuiltinName); - } + for (const CodeGenIntrinsic &Int : Ints) { + StringRef BuiltinName = IsClang ? Int.ClangBuiltinName : Int.MSBuiltinName; + if (BuiltinName.empty()) + continue; + // Get the map for this target prefix. + std::map &BIM = BuiltinMap[Int.TargetPrefix]; + + if (!BIM.insert(std::pair(BuiltinName, Int.EnumName)).second) + PrintFatalError(Int.TheDef->getLoc(), + "Intrinsic '" + Int.TheDef->getName() + "': duplicate " + + CompilerName + " builtin name!"); + Table.GetOrAddStringOffset(BuiltinName); } OS << "// Get the LLVM intrinsic that corresponds to a builtin.\n"; OS << "// This is used by the C front-end. The builtin name is passed\n"; OS << "// in as BuiltinName, and a target prefix (e.g. 'ppc') is passed\n"; - OS << "// in as TargetPrefix. The result is assigned to 'IntrinsicID'.\n"; + OS << "// in as TargetPrefix. The result is assigned to 'IntrinsicID'.\n"; OS << "#ifdef GET_LLVM_INTRINSIC_FOR_" << UpperCompilerName << "_BUILTIN\n"; OS << "Intrinsic::ID Intrinsic::getIntrinsicFor" << CompilerName @@ -662,7 +635,7 @@ void IntrinsicEmitter::EmitIntrinsicToBuiltinMap( return; } - OS << " static const char BuiltinNames[] = {\n"; + OS << " static constexpr char BuiltinNames[] = {\n"; Table.EmitCharArray(OS); OS << " };\n\n"; @@ -689,7 +662,7 @@ void IntrinsicEmitter::EmitIntrinsicToBuiltinMap( OS << "{\n"; // Emit the comparisons for this target prefix. - OS << " static const BuiltinEntry " << I.first << "Names[] = {\n"; + OS << " static constexpr BuiltinEntry " << I.first << "Names[] = {\n"; for (const auto &P : I.second) { OS << " {Intrinsic::" << P.second << ", " << Table.GetOrAddStringOffset(P.first) << "}, // " << P.first << "\n"; @@ -703,8 +676,7 @@ void IntrinsicEmitter::EmitIntrinsicToBuiltinMap( OS << " return I->IntrinID;\n"; OS << " }\n"; } - OS << " return "; - OS << "Intrinsic::not_intrinsic;\n"; + OS << " return Intrinsic::not_intrinsic;\n"; OS << "}\n"; OS << "#endif\n\n"; } @@ -721,4 +693,4 @@ static void EmitIntrinsicImpl(RecordKeeper &RK, raw_ostream &OS) { } static TableGen::Emitter::Opt Y("gen-intrinsic-impl", EmitIntrinsicImpl, - "Generate intrinsic information"); + "Generate intrinsic implementation code"); diff --git a/llvm/utils/TableGen/SearchableTableEmitter.cpp b/llvm/utils/TableGen/SearchableTableEmitter.cpp index ac50c9ed2aeba..59ae3bf3daedc 100644 --- a/llvm/utils/TableGen/SearchableTableEmitter.cpp +++ b/llvm/utils/TableGen/SearchableTableEmitter.cpp @@ -125,7 +125,7 @@ class SearchableTableEmitter { else if (BitInit *BI = dyn_cast(I)) return BI->getValue() ? "true" : "false"; else if (Field.IsIntrinsic) - return "Intrinsic::" + getIntrinsic(I).EnumName; + return "Intrinsic::" + getIntrinsic(I).EnumName.str(); else if (Field.IsInstruction) return I->getAsString(); else if (Field.Enum) { @@ -148,8 +148,7 @@ class SearchableTableEmitter { CodeGenIntrinsic &getIntrinsic(Init *I) { std::unique_ptr &Intr = Intrinsics[I]; if (!Intr) - Intr = std::make_unique(cast(I)->getDef(), - std::vector()); + Intr = std::make_unique(cast(I)->getDef()); return *Intr; } diff --git a/polly/lib/Support/GICHelper.cpp b/polly/lib/Support/GICHelper.cpp index 04d422cf99462..027e0194732f4 100644 --- a/polly/lib/Support/GICHelper.cpp +++ b/polly/lib/Support/GICHelper.cpp @@ -143,11 +143,11 @@ static void replace(std::string &str, StringRef find, StringRef replace) { } static void makeIslCompatible(std::string &str) { - replace(str, ".", "_"); - replace(str, "\"", "_"); - replace(str, " ", "__"); - replace(str, "=>", "TO"); - replace(str, "+", "_"); + llvm::replace(str, '.', '_'); + llvm::replace(str, '\"', '_'); + replace(str, StringRef(" "), StringRef("__")); + replace(str, StringRef("=>"), StringRef("TO")); + llvm::replace(str, '+', '_'); } std::string polly::getIslCompatibleName(const std::string &Prefix,