LLVM InstVisitor - 没有虚拟功能?
LLVM InstVisitor - No Virtual Functions?
我一直在查看他们实现访客模式的 LLVM InstVisitor.h 文件。它们的实现与我在访问者模式中看到的任何东西都大不相同。
在文档中我发现了这个:
To define your own visitor, inherit from this class, specifying your
new type for the 'SubClass' template parameter, and "override" visitXXX
functions in your class. I say "override" because this class is defined
in terms of statically resolved overloading, not virtual functions.
...
Note that this class is specifically designed as a template to avoid
virtual function call overhead. Defining and using an InstVisitor is just
as efficient as having your own switch statement over the instruction
opcode.
我问是因为 说 LLVM 在此实现中使用了访问者模式,但我无法弄清楚为什么它与我见过的任何其他实现如此不同。
文件中的访问者模式是如何使用的?
llvm::InstVisitor
使用 Curiously Recurring Template Pattern (CRTP),这是一种用于执行访问成员函数静态分派的 C++ 习惯用法。
这样,正确的 visitXXX
调用将被静态解析(在编译时),避免了动态虚拟调用解析的额外成本。
这是通过调用这样的东西来工作的:
// The compiler will choose the Derived implementation of visitXXX
// if exists, but will fallback to the Base implementation as Derived
// inherits from Base. All done at compile time.
void Base::do_visit() {
return static_cast<Derived *>(this)->visitXXX();
}
请注意,没有类似 "override" 的机制:如果您无法为一次访问函数匹配确切的函数签名,它将调用基础 class 实现,而不是您自己的实现。
用法示例与文档中解释的完全相同:
struct CountAllocaVisitor : public InstVisitor<CountAllocaVisitor> {
unsigned Count;
CountAllocaVisitor() : Count(0) {}
void visitAllocaInst(AllocaInst &AI) { ++Count; }
};
// And this class would be used like this:
CountAllocaVisitor CAV;
CAV.visit(function);
NumAllocas = CAV.Count;
我一直在查看他们实现访客模式的 LLVM InstVisitor.h 文件。它们的实现与我在访问者模式中看到的任何东西都大不相同。
在文档中我发现了这个:
To define your own visitor, inherit from this class, specifying your new type for the 'SubClass' template parameter, and "override" visitXXX functions in your class. I say "override" because this class is defined in terms of statically resolved overloading, not virtual functions.
...
Note that this class is specifically designed as a template to avoid virtual function call overhead. Defining and using an InstVisitor is just as efficient as having your own switch statement over the instruction opcode.
我问是因为
文件中的访问者模式是如何使用的?
llvm::InstVisitor
使用 Curiously Recurring Template Pattern (CRTP),这是一种用于执行访问成员函数静态分派的 C++ 习惯用法。
这样,正确的 visitXXX
调用将被静态解析(在编译时),避免了动态虚拟调用解析的额外成本。
这是通过调用这样的东西来工作的:
// The compiler will choose the Derived implementation of visitXXX
// if exists, but will fallback to the Base implementation as Derived
// inherits from Base. All done at compile time.
void Base::do_visit() {
return static_cast<Derived *>(this)->visitXXX();
}
请注意,没有类似 "override" 的机制:如果您无法为一次访问函数匹配确切的函数签名,它将调用基础 class 实现,而不是您自己的实现。
用法示例与文档中解释的完全相同:
struct CountAllocaVisitor : public InstVisitor<CountAllocaVisitor> {
unsigned Count;
CountAllocaVisitor() : Count(0) {}
void visitAllocaInst(AllocaInst &AI) { ++Count; }
};
// And this class would be used like this:
CountAllocaVisitor CAV;
CAV.visit(function);
NumAllocas = CAV.Count;