aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/llvm/ADT/StringRef.h4
-rw-r--r--lib/Support/StringRef.cpp28
-rw-r--r--lib/Target/X86/SSEDomainFix.cpp4
-rw-r--r--unittests/ADT/StringRefTest.cpp11
-rw-r--r--utils/TableGen/CodeGenTarget.cpp2
-rw-r--r--utils/TableGen/Record.h2
6 files changed, 47 insertions, 4 deletions
diff --git a/include/llvm/ADT/StringRef.h b/include/llvm/ADT/StringRef.h
index ab6358b..33756f6 100644
--- a/include/llvm/ADT/StringRef.h
+++ b/include/llvm/ADT/StringRef.h
@@ -128,6 +128,10 @@ namespace llvm {
/// compare_lower - Compare two strings, ignoring case.
int compare_lower(StringRef RHS) const;
+ /// compare_numeric - Compare two strings, treating sequences of digits as
+ /// numbers.
+ int compare_numeric(StringRef RHS) const;
+
/// \brief Determine the edit distance between this string and another
/// string.
///
diff --git a/lib/Support/StringRef.cpp b/lib/Support/StringRef.cpp
index 2b262dc..ca0f518 100644
--- a/lib/Support/StringRef.cpp
+++ b/lib/Support/StringRef.cpp
@@ -23,6 +23,10 @@ static char ascii_tolower(char x) {
return x;
}
+static bool ascii_isdigit(char x) {
+ return x >= '0' && x <= '9';
+}
+
/// compare_lower - Compare strings, ignoring case.
int StringRef::compare_lower(StringRef RHS) const {
for (size_t I = 0, E = min(Length, RHS.Length); I != E; ++I) {
@@ -37,6 +41,30 @@ int StringRef::compare_lower(StringRef RHS) const {
return Length < RHS.Length ? -1 : 1;
}
+/// compare_numeric - Compare strings, handle embedded numbers.
+int StringRef::compare_numeric(StringRef RHS) const {
+ for (size_t I = 0, E = min(Length, RHS.Length); I != E; ++I) {
+ if (Data[I] == RHS.Data[I])
+ continue;
+ if (ascii_isdigit(Data[I]) && ascii_isdigit(RHS.Data[I])) {
+ // The longer sequence of numbers is larger. This doesn't really handle
+ // prefixed zeros well.
+ for (size_t J = I+1; J != E+1; ++J) {
+ bool ld = J < Length && ascii_isdigit(Data[J]);
+ bool rd = J < RHS.Length && ascii_isdigit(RHS.Data[J]);
+ if (ld != rd)
+ return rd ? -1 : 1;
+ if (!rd)
+ break;
+ }
+ }
+ return Data[I] < RHS.Data[I] ? -1 : 1;
+ }
+ if (Length == RHS.Length)
+ return 0;
+ return Length < RHS.Length ? -1 : 1;
+}
+
// Compute the edit distance between the two given strings.
unsigned StringRef::edit_distance(llvm::StringRef Other,
bool AllowReplacements) {
diff --git a/lib/Target/X86/SSEDomainFix.cpp b/lib/Target/X86/SSEDomainFix.cpp
index 5e80845..dab070e 100644
--- a/lib/Target/X86/SSEDomainFix.cpp
+++ b/lib/Target/X86/SSEDomainFix.cpp
@@ -155,9 +155,7 @@ char SSEDomainFixPass::ID = 0;
/// Translate TRI register number to an index into our smaller tables of
/// interesting registers. Return -1 for boring registers.
int SSEDomainFixPass::RegIndex(unsigned reg) {
- // Registers are sorted lexicographically.
- // We just need them to be consecutive, ordering doesn't matter.
- assert(X86::XMM9 == X86::XMM0+NumRegs-1 && "Unexpected sort");
+ assert(X86::XMM15 == X86::XMM0+NumRegs-1 && "Unexpected sort");
reg -= X86::XMM0;
return reg < NumRegs ? (int) reg : -1;
}
diff --git a/unittests/ADT/StringRefTest.cpp b/unittests/ADT/StringRefTest.cpp
index b0dcb0a..887ba5d 100644
--- a/unittests/ADT/StringRefTest.cpp
+++ b/unittests/ADT/StringRefTest.cpp
@@ -53,6 +53,17 @@ TEST(StringRefTest, StringOps) {
EXPECT_EQ( 1, StringRef("aab").compare("aaa"));
EXPECT_EQ(-1, StringRef("aab").compare("aabb"));
EXPECT_EQ( 1, StringRef("aab").compare("aa"));
+
+ EXPECT_EQ(-1, StringRef("aab").compare_numeric("aad"));
+ EXPECT_EQ( 0, StringRef("aab").compare_numeric("aab"));
+ EXPECT_EQ( 1, StringRef("aab").compare_numeric("aaa"));
+ EXPECT_EQ(-1, StringRef("aab").compare_numeric("aabb"));
+ EXPECT_EQ( 1, StringRef("aab").compare_numeric("aa"));
+ EXPECT_EQ(-1, StringRef("1").compare_numeric("10"));
+ EXPECT_EQ( 0, StringRef("10").compare_numeric("10"));
+ EXPECT_EQ( 0, StringRef("10a").compare_numeric("10a"));
+ EXPECT_EQ( 1, StringRef("2").compare_numeric("1"));
+ EXPECT_EQ( 0, StringRef("llvm_v1i64_ty").compare_numeric("llvm_v1i64_ty"));
}
TEST(StringRefTest, Operators) {
diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp
index 5d45489..3797992 100644
--- a/utils/TableGen/CodeGenTarget.cpp
+++ b/utils/TableGen/CodeGenTarget.cpp
@@ -159,6 +159,7 @@ void CodeGenTarget::ReadRegisters() const {
std::vector<Record*> Regs = Records.getAllDerivedDefinitions("Register");
if (Regs.empty())
throw std::string("No 'Register' subclasses defined!");
+ std::sort(Regs.begin(), Regs.end(), LessRecord());
Registers.reserve(Regs.size());
Registers.assign(Regs.begin(), Regs.end());
@@ -175,6 +176,7 @@ const std::string &CodeGenRegister::getName() const {
void CodeGenTarget::ReadSubRegIndices() const {
SubRegIndices = Records.getAllDerivedDefinitions("SubRegIndex");
+ std::sort(SubRegIndices.begin(), SubRegIndices.end(), LessRecord());
}
void CodeGenTarget::ReadRegisterClasses() const {
diff --git a/utils/TableGen/Record.h b/utils/TableGen/Record.h
index 576d626..8f9fd95 100644
--- a/utils/TableGen/Record.h
+++ b/utils/TableGen/Record.h
@@ -1461,7 +1461,7 @@ public:
///
struct LessRecord {
bool operator()(const Record *Rec1, const Record *Rec2) const {
- return Rec1->getName() < Rec2->getName();
+ return StringRef(Rec1->getName()).compare_numeric(Rec2->getName()) < 0;
}
};