[CodeGen] Implement isTriviallyRecursive with StmtVisitor instead of RecursiveASTVisitor

This code doesn't need to traverse types, lambdas, template arguments,
etc to detect trivial recursion. We can do a basic statement traversal
instead. This reduces the time spent compiling CodeGenModule.cpp, the
object file size (mostly reduced debug info), and the final executable
size by a small amount. I measured the exe mostly to check how much of
the overhead is from debug info, object file section headers, etc, vs
actual code.

metric   | before | after | diff
time (s) | 47.4   | 38.5  | -8.9
obj (kb) | 12888  | 12012 | -876
exe (kb) | 86072  | 85996 | -76

llvm-svn: 352232
This commit is contained in:
Reid Kleckner
2019-01-25 19:18:40 +00:00
parent 09197fac59
commit f09c19c896

View File

@@ -33,6 +33,7 @@
#include "clang/AST/Mangle.h"
#include "clang/AST/RecordLayout.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/CharInfo.h"
#include "clang/Basic/CodeGenOptions.h"
@@ -2281,35 +2282,36 @@ static bool HasNonDllImportDtor(QualType T) {
}
namespace {
struct FunctionIsDirectlyRecursive :
public RecursiveASTVisitor<FunctionIsDirectlyRecursive> {
struct FunctionIsDirectlyRecursive
: public ConstStmtVisitor<FunctionIsDirectlyRecursive, bool> {
const StringRef Name;
const Builtin::Context &BI;
bool Result;
FunctionIsDirectlyRecursive(StringRef N, const Builtin::Context &C) :
Name(N), BI(C), Result(false) {
}
typedef RecursiveASTVisitor<FunctionIsDirectlyRecursive> Base;
FunctionIsDirectlyRecursive(StringRef N, const Builtin::Context &C)
: Name(N), BI(C) {}
bool TraverseCallExpr(CallExpr *E) {
bool VisitCallExpr(const CallExpr *E) {
const FunctionDecl *FD = E->getDirectCallee();
if (!FD)
return true;
AsmLabelAttr *Attr = FD->getAttr<AsmLabelAttr>();
if (Attr && Name == Attr->getLabel()) {
Result = true;
return false;
}
AsmLabelAttr *Attr = FD->getAttr<AsmLabelAttr>();
if (Attr && Name == Attr->getLabel())
return true;
unsigned BuiltinID = FD->getBuiltinID();
if (!BuiltinID || !BI.isLibFunction(BuiltinID))
return true;
return false;
StringRef BuiltinName = BI.getName(BuiltinID);
if (BuiltinName.startswith("__builtin_") &&
Name == BuiltinName.slice(strlen("__builtin_"), StringRef::npos)) {
Result = true;
return false;
return true;
}
return true;
return false;
}
bool VisitStmt(const Stmt *S) {
for (const Stmt *Child : S->children())
if (Child && this->Visit(Child))
return true;
return false;
}
};
@@ -2394,8 +2396,8 @@ CodeGenModule::isTriviallyRecursive(const FunctionDecl *FD) {
}
FunctionIsDirectlyRecursive Walker(Name, Context.BuiltinInfo);
Walker.TraverseFunctionDecl(const_cast<FunctionDecl*>(FD));
return Walker.Result;
const Stmt *Body = FD->getBody();
return Body ? Walker.Visit(Body) : false;
}
bool CodeGenModule::shouldEmitFunction(GlobalDecl GD) {