[PATCH] D100638: [AST][Introspection] Avoid creating temporary strings when comparing LocationCalls.
Stephen Kelly via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Sun Apr 18 06:35:17 PDT 2021
steveire added a comment.
Your implementation is getting very complicated and it requires many comments.
Also, if we get to this point in the execution of `RangeLessThan::operator()`, you're creating and populating two vectors for every two elements contained. I know it's `llvm::SmallVector` and maybe not so expensive etc, but doing something is more expensive than not doing it.
You're trying to sort elements (which have the same location/range) alphabetically according to how it will be sorted after c++ formatting. Sorting according to c++ formatting means sorting incorrectly according to JS/python. This is simple to demonstrate:
TEST(Introspection, SourceLocations_CallContainer3) {
SourceLocationMap slm;
SharedLocationCall Prefix;
auto call1 = llvm::makeIntrusiveRefCnt<LocationCall>(
llvm::makeIntrusiveRefCnt<LocationCall>(
llvm::makeIntrusiveRefCnt<LocationCall>(
Prefix, "dddd"), "eeee", LocationCall::IsCast), "ffff");
auto call2 = llvm::makeIntrusiveRefCnt<LocationCall>(
llvm::makeIntrusiveRefCnt<LocationCall>(
llvm::makeIntrusiveRefCnt<LocationCall>(
Prefix, "dddd"), "gggg", LocationCall::IsCast), "bbbb");
slm.insert(
std::make_pair(SourceLocation(), call1));
slm.insert(
std::make_pair(SourceLocation(), call2));
for (auto& item : slm)
{
llvm::errs() << LocationCallFormatterCpp::format(*item.second) << "\n";
}
for (auto& item : slm)
{
llvm::errs() << LocationCallFormatterSimple::format(*item.second) << "\n";
}
}
output:
dddd().eeee().ffff()
dddd().gggg().bbbb()
dddd().ffff()
dddd().bbbb()
So, the cost of creating two vectors for each invocation of `lessThan` that reaches this point delivers no benefit.
Here is an implementation which does not create those vectors:
diff --git a/clang/lib/Tooling/NodeIntrospection.cpp b/clang/lib/Tooling/NodeIntrospection.cpp
index 8e2d446c3efe..6e846acf9ecf 100644
--- a/clang/lib/Tooling/NodeIntrospection.cpp
+++ b/clang/lib/Tooling/NodeIntrospection.cpp
@@ -40,6 +40,22 @@ std::string LocationCallFormatterCpp::format(const LocationCall &Call) {
return Result;
}
+bool locationLessThan(const LocationCall *LHS, const LocationCall *RHS)
+{
+ if (!LHS && !RHS)
+ return false;
+ if (LHS && !RHS)
+ return true;
+ if (!LHS && RHS)
+ return false;
+ auto compareResult = LHS->name().compare(RHS->name());
+ if (compareResult < 0)
+ return true;
+ if (compareResult > 0)
+ return false;
+ return locationLessThan(LHS->on(), RHS->on());
+}
+
namespace internal {
bool RangeLessThan::operator()(
std::pair<SourceRange, SharedLocationCall> const &LHS,
@@ -54,15 +70,13 @@ bool RangeLessThan::operator()(
else if (LHS.first.getEnd() != RHS.first.getEnd())
return false;
- return LocationCallFormatterCpp::format(*LHS.second) <
- LocationCallFormatterCpp::format(*RHS.second);
+ return locationLessThan(LHS.second.get(), RHS.second.get());
}
bool RangeLessThan::operator()(
std::pair<SourceLocation, SharedLocationCall> const &LHS,
std::pair<SourceLocation, SharedLocationCall> const &RHS) const {
if (LHS.first == RHS.first)
- return LocationCallFormatterCpp::format(*LHS.second) <
- LocationCallFormatterCpp::format(*RHS.second);
+ return locationLessThan(LHS.second.get(), RHS.second.get());
return LHS.first < RHS.first;
}
} // namespace internal
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D100638/new/
https://reviews.llvm.org/D100638
More information about the cfe-commits
mailing list