Skip some unnecessary type checks.
Summary: Skip some unnecessary type checks wrt DynTypedNodes. Add DynTypedNode::getUnchecked() to skip the runtime check when the type is known. Speed up DynTypedNode::operator== by using isSame() instead of isBaseOf(). Skip the type check in MatcherInterface<T>::matches(). All calls come from DynTypedMatcher::matches(), which already did the type check. This change speeds up our clang-tidy benchmark by ~4%. Reviewers: klimek Subscribers: klimek, cfe-commits Differential Revision: http://reviews.llvm.org/D6468 llvm-svn: 223134
This commit is contained in:
parent
54b7d334c7
commit
b6f0a83f41
|
@ -145,6 +145,8 @@ private:
|
|||
template <class T> struct KindToKindId {
|
||||
static const NodeKindId Id = NKI_None;
|
||||
};
|
||||
template <class T>
|
||||
struct KindToKindId<const T> : KindToKindId<T> {};
|
||||
|
||||
/// \brief Per kind info.
|
||||
struct KindInfo {
|
||||
|
@ -221,6 +223,14 @@ public:
|
|||
return BaseConverter<T>::get(NodeKind, Storage.buffer);
|
||||
}
|
||||
|
||||
/// \brief Retrieve the stored node as type \c T.
|
||||
///
|
||||
/// Similar to \c get(), but asserts that the type is what we are expecting.
|
||||
template <typename T>
|
||||
const T &getUnchecked() const {
|
||||
return BaseConverter<T>::getUnchecked(NodeKind, Storage.buffer);
|
||||
}
|
||||
|
||||
ASTNodeKind getNodeKind() const { return NodeKind; }
|
||||
|
||||
/// \brief Returns a pointer that identifies the stored AST node.
|
||||
|
@ -251,14 +261,15 @@ public:
|
|||
return getMemoizationData() < Other.getMemoizationData();
|
||||
}
|
||||
bool operator==(const DynTypedNode &Other) const {
|
||||
if (!NodeKind.isBaseOf(Other.NodeKind) &&
|
||||
!Other.NodeKind.isBaseOf(NodeKind))
|
||||
// DynTypedNode::create() stores the exact kind of the node in NodeKind.
|
||||
// If they contain the same node, their NodeKind must be the same.
|
||||
if (!NodeKind.isSame(Other.NodeKind))
|
||||
return false;
|
||||
|
||||
// FIXME: Implement for other types.
|
||||
if (ASTNodeKind::getFromNodeKind<QualType>().isBaseOf(NodeKind)) {
|
||||
return *get<QualType>() == *Other.get<QualType>();
|
||||
}
|
||||
if (ASTNodeKind::getFromNodeKind<QualType>().isSame(NodeKind))
|
||||
return getUnchecked<QualType>() == Other.getUnchecked<QualType>();
|
||||
|
||||
assert(getMemoizationData() && Other.getMemoizationData());
|
||||
return getMemoizationData() == Other.getMemoizationData();
|
||||
}
|
||||
|
@ -274,10 +285,14 @@ private:
|
|||
/// \brief Converter that uses dyn_cast<T> from a stored BaseT*.
|
||||
template <typename T, typename BaseT> struct DynCastPtrConverter {
|
||||
static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
|
||||
if (ASTNodeKind::getFromNodeKind<BaseT>().isBaseOf(NodeKind))
|
||||
return dyn_cast<T>(*reinterpret_cast<BaseT *const *>(Storage));
|
||||
if (ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind))
|
||||
return cast<T>(*reinterpret_cast<BaseT *const *>(Storage));
|
||||
return nullptr;
|
||||
}
|
||||
static const T &getUnchecked(ASTNodeKind NodeKind, const char Storage[]) {
|
||||
assert(ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind));
|
||||
return *cast<T>(*reinterpret_cast<BaseT *const *>(Storage));
|
||||
}
|
||||
static DynTypedNode create(const BaseT &Node) {
|
||||
DynTypedNode Result;
|
||||
Result.NodeKind = ASTNodeKind::getFromNode(Node);
|
||||
|
@ -294,6 +309,10 @@ private:
|
|||
return *reinterpret_cast<T *const *>(Storage);
|
||||
return nullptr;
|
||||
}
|
||||
static const T &getUnchecked(ASTNodeKind NodeKind, const char Storage[]) {
|
||||
assert(ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind));
|
||||
return **reinterpret_cast<T *const *>(Storage);
|
||||
}
|
||||
static DynTypedNode create(const T &Node) {
|
||||
DynTypedNode Result;
|
||||
Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
|
||||
|
@ -310,6 +329,10 @@ private:
|
|||
return reinterpret_cast<const T *>(Storage);
|
||||
return nullptr;
|
||||
}
|
||||
static const T &getUnchecked(ASTNodeKind NodeKind, const char Storage[]) {
|
||||
assert(ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind));
|
||||
return *reinterpret_cast<const T *>(Storage);
|
||||
}
|
||||
static DynTypedNode create(const T &Node) {
|
||||
DynTypedNode Result;
|
||||
Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
|
||||
|
|
|
@ -218,10 +218,7 @@ public:
|
|||
bool dynMatches(const ast_type_traits::DynTypedNode &DynNode,
|
||||
ASTMatchFinder *Finder,
|
||||
BoundNodesTreeBuilder *Builder) const override {
|
||||
if (const T *Node = DynNode.get<T>()) {
|
||||
return matches(*Node, Finder, Builder);
|
||||
}
|
||||
return false;
|
||||
return matches(DynNode.getUnchecked<T>(), Finder, Builder);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue