[Mlir-commits] [mlir] 0031c7f - Implement some micro-optimizations for Identifier. NFC
Chris Lattner
llvmlistbot at llvm.org
Sat Apr 11 21:49:01 PDT 2020
Author: Chris Lattner
Date: 2020-04-11T21:48:52-07:00
New Revision: 0031c7f7dab5489934fc97c783fedbd49a377323
URL: https://github.com/llvm/llvm-project/commit/0031c7f7dab5489934fc97c783fedbd49a377323
DIFF: https://github.com/llvm/llvm-project/commit/0031c7f7dab5489934fc97c783fedbd49a377323.diff
LOG: Implement some micro-optimizations for Identifier. NFC
Summary:
Identifier doesn't maintain a length, so every time strref() is called,
it does a strlen. In the case of comparisons, this isn't necessary:
there is no need to scan a string to get its length, then rescan it to
do the comparison. Just done one comparison.
This also moves some assertions in Identifier::get as another
microoptimization for 'assertions enabled' modes.
Reviewers: rriddle!
Subscribers: mehdi_amini, rriddle, jpienaar, burmako, shauheen, antiagainst, nicolasvasilache, arpith-jacob, mgester, lucyrfox, liufengdb, Joonsoo, grosul1, frgossen, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D77958
Added:
Modified:
mlir/include/mlir/IR/Identifier.h
mlir/lib/IR/Attributes.cpp
mlir/lib/IR/MLIRContext.cpp
Removed:
################################################################################
diff --git a/mlir/include/mlir/IR/Identifier.h b/mlir/include/mlir/IR/Identifier.h
index f3aead4a2f70..fae92facc4d1 100644
--- a/mlir/include/mlir/IR/Identifier.h
+++ b/mlir/include/mlir/IR/Identifier.h
@@ -50,7 +50,12 @@ class Identifier {
unsigned size() const { return ::strlen(pointer); }
/// Return true if this identifier is the specified string.
- bool is(StringRef string) const { return strref().equals(string); }
+ bool is(StringRef string) const {
+ // Note: this can't use memcmp, because memcmp doesn't guarantee that it
+ // will stop reading both buffers if one is shorter than the other.
+ return strncmp(pointer, string.data(), string.size()) == 0 &&
+ pointer[string.size()] == '\0';
+ }
const char *begin() const { return pointer; }
const char *end() const { return pointer + size(); }
diff --git a/mlir/lib/IR/Attributes.cpp b/mlir/lib/IR/Attributes.cpp
index 4526d7dc10be..6829e8a82569 100644
--- a/mlir/lib/IR/Attributes.cpp
+++ b/mlir/lib/IR/Attributes.cpp
@@ -87,7 +87,7 @@ bool BoolAttr::getValue() const { return getImpl()->value; }
/// NamedAttributes.
static int compareNamedAttributes(const NamedAttribute *lhs,
const NamedAttribute *rhs) {
- return lhs->first.strref().compare(rhs->first.strref());
+ return strcmp(lhs->first.data(), rhs->first.data());
}
DictionaryAttr DictionaryAttr::get(ArrayRef<NamedAttribute> value,
@@ -111,7 +111,7 @@ DictionaryAttr DictionaryAttr::get(ArrayRef<NamedAttribute> value,
"DictionaryAttr element names must be unique");
// Don't invoke a general sort for two element case.
- if (value[0].first.strref() > value[1].first.strref()) {
+ if (compareNamedAttributes(&value[0], &value[1]) > 0) {
storage.push_back(value[1]);
storage.push_back(value[0]);
value = storage;
@@ -121,7 +121,7 @@ DictionaryAttr DictionaryAttr::get(ArrayRef<NamedAttribute> value,
// Check to see they are sorted already.
bool isSorted = true;
for (unsigned i = 0, e = value.size() - 1; i != e; ++i) {
- if (value[i].first.strref() > value[i + 1].first.strref()) {
+ if (compareNamedAttributes(&value[i], &value[i + 1]) > 0) {
isSorted = false;
break;
}
@@ -152,8 +152,13 @@ ArrayRef<NamedAttribute> DictionaryAttr::getValue() const {
/// Return the specified attribute if present, null otherwise.
Attribute DictionaryAttr::get(StringRef name) const {
ArrayRef<NamedAttribute> values = getValue();
- auto compare = [](NamedAttribute attr, StringRef name) {
- return attr.first.strref() < name;
+ auto compare = [](NamedAttribute attr, StringRef name) -> bool {
+ // This is correct even when attr.first.data()[name.size()] is not a zero
+ // string terminator, because we only care about a less than comparison.
+ // This can't use memcmp, because it doesn't guarantee that it will stop
+ // reading both buffers if one is shorter than the other, even if there is
+ // a
diff erence.
+ return strncmp(attr.first.data(), name.data(), name.size()) < 0;
};
auto it = llvm::lower_bound(values, name, compare);
return it != values.end() && it->first.is(name) ? it->second : Attribute();
diff --git a/mlir/lib/IR/MLIRContext.cpp b/mlir/lib/IR/MLIRContext.cpp
index 1623122df39c..a3534bc62ace 100644
--- a/mlir/lib/IR/MLIRContext.cpp
+++ b/mlir/lib/IR/MLIRContext.cpp
@@ -493,10 +493,6 @@ const AbstractOperation *AbstractOperation::lookup(StringRef opName,
/// Return an identifier for the specified string.
Identifier Identifier::get(StringRef str, MLIRContext *context) {
- assert(!str.empty() && "Cannot create an empty identifier");
- assert(str.find('\0') == StringRef::npos &&
- "Cannot create an identifier with a nul character");
-
auto &impl = context->getImpl();
{ // Check for an existing identifier in read-only mode.
@@ -506,6 +502,13 @@ Identifier Identifier::get(StringRef str, MLIRContext *context) {
return Identifier(it->getKeyData());
}
+ // Check invariants after seeing if we already have something in the
+ // identifier table - if we already had it in the table, then it already
+ // passed invariant checks.
+ assert(!str.empty() && "Cannot create an empty identifier");
+ assert(str.find('\0') == StringRef::npos &&
+ "Cannot create an identifier with a nul character");
+
// Acquire a writer-lock so that we can safely create the new instance.
llvm::sys::SmartScopedWriter<true> contextLock(impl.identifierMutex);
auto it = impl.identifiers.insert({str, char()}).first;
More information about the Mlir-commits
mailing list