-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
perf clang: Add builtin clang support ant test case
Add basic clang support in clang.cpp and test__clang() testcase. The first testcase checks if builtin clang is able to generate LLVM IR. tests/clang.c is a proxy. Real testcase resides in utils/c++/clang-test.cpp in c++ and exports C interface to perf test subsystem. Test result: $ perf test -v clang 51: builtin clang support : 51.1: Test builtin clang compile C source to IR : --- start --- test child forked, pid 13215 test child finished with 0 ---- end ---- Test builtin clang support subtest 0: Ok Committer note: Make sure you've enabled CLANG and LLVM builtin support by setting the LIBCLANGLLVM variable on the make command line, e.g.: make LIBCLANGLLVM=1 O=/tmp/build/perf -C tools/perf install-bin Otherwise you'll get this when trying to do the 'perf test' call above: # perf test clang 51: builtin clang support : Skip (not compiled in) # Signed-off-by: Wang Nan <wangnan0@huawei.com> Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Alexei Starovoitov <ast@fb.com> Cc: He Kuang <hekuang@huawei.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Joe Stringer <joe@ovn.org> Cc: Zefan Li <lizefan@huawei.com> Cc: pi3orama@163.com Link: http://lkml.kernel.org/r/20161126070354.141764-11-wangnan0@huawei.com [ Removed "Test" from descriptions, redundant and already removed from all the other entries ] Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
- Loading branch information
Wang Nan
authored and
Arnaldo Carvalho de Melo
committed
Dec 5, 2016
1 parent
d58ac0b
commit 00b8669
Showing
10 changed files
with
218 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
#include "tests.h" | ||
#include "debug.h" | ||
#include "util.h" | ||
#include "c++/clang-c.h" | ||
|
||
static struct { | ||
int (*func)(void); | ||
const char *desc; | ||
} clang_testcase_table[] = { | ||
#ifdef HAVE_LIBCLANGLLVM_SUPPORT | ||
{ | ||
.func = test__clang_to_IR, | ||
.desc = "builtin clang compile C source to IR", | ||
}, | ||
#endif | ||
}; | ||
|
||
int test__clang_subtest_get_nr(void) | ||
{ | ||
return (int)ARRAY_SIZE(clang_testcase_table); | ||
} | ||
|
||
const char *test__clang_subtest_get_desc(int i) | ||
{ | ||
if (i < 0 || i >= (int)ARRAY_SIZE(clang_testcase_table)) | ||
return NULL; | ||
return clang_testcase_table[i].desc; | ||
} | ||
|
||
#ifndef HAVE_LIBCLANGLLVM_SUPPORT | ||
int test__clang(int i __maybe_unused) | ||
{ | ||
return TEST_SKIP; | ||
} | ||
#else | ||
int test__clang(int i __maybe_unused) | ||
{ | ||
if (i < 0 || i >= (int)ARRAY_SIZE(clang_testcase_table)) | ||
return TEST_FAIL; | ||
return clang_testcase_table[i].func(); | ||
} | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
libperf-$(CONFIG_CLANGLLVM) += clang.o | ||
libperf-$(CONFIG_CLANGLLVM) += clang-test.o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
#ifndef PERF_UTIL_CLANG_C_H | ||
#define PERF_UTIL_CLANG_C_H | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
extern void perf_clang__init(void); | ||
extern void perf_clang__cleanup(void); | ||
|
||
extern int test__clang_to_IR(void); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
#include "clang.h" | ||
#include "clang-c.h" | ||
#include "llvm/IR/Function.h" | ||
#include "llvm/IR/LLVMContext.h" | ||
|
||
class perf_clang_scope { | ||
public: | ||
explicit perf_clang_scope() {perf_clang__init();} | ||
~perf_clang_scope() {perf_clang__cleanup();} | ||
}; | ||
|
||
extern "C" { | ||
|
||
int test__clang_to_IR(void) | ||
{ | ||
perf_clang_scope _scope; | ||
|
||
std::unique_ptr<llvm::Module> M = | ||
perf::getModuleFromSource("perf-test.c", | ||
"int myfunc(void) {return 1;}"); | ||
|
||
if (!M) | ||
return -1; | ||
|
||
for (llvm::Function& F : *M) | ||
if (F.getName() == "myfunc") | ||
return 0; | ||
return -1; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
/* | ||
* llvm C frontend for perf. Support dynamically compile C file | ||
* | ||
* Inspired by clang example code: | ||
* http://llvm.org/svn/llvm-project/cfe/trunk/examples/clang-interpreter/main.cpp | ||
* | ||
* Copyright (C) 2016 Wang Nan <wangnan0@huawei.com> | ||
* Copyright (C) 2016 Huawei Inc. | ||
*/ | ||
|
||
#include "clang/CodeGen/CodeGenAction.h" | ||
#include "clang/Frontend/CompilerInvocation.h" | ||
#include "clang/Frontend/CompilerInstance.h" | ||
#include "clang/Frontend/TextDiagnosticPrinter.h" | ||
#include "clang/Tooling/Tooling.h" | ||
#include "llvm/IR/Module.h" | ||
#include "llvm/Option/Option.h" | ||
#include "llvm/Support/ManagedStatic.h" | ||
#include <memory> | ||
|
||
#include "clang.h" | ||
#include "clang-c.h" | ||
|
||
namespace perf { | ||
|
||
static std::unique_ptr<llvm::LLVMContext> LLVMCtx; | ||
|
||
using namespace clang; | ||
|
||
static vfs::InMemoryFileSystem * | ||
buildVFS(StringRef& Name, StringRef& Content) | ||
{ | ||
vfs::InMemoryFileSystem *VFS = new vfs::InMemoryFileSystem(true); | ||
VFS->addFile(Twine(Name), 0, llvm::MemoryBuffer::getMemBuffer(Content)); | ||
return VFS; | ||
} | ||
|
||
static CompilerInvocation * | ||
createCompilerInvocation(StringRef& Path, DiagnosticsEngine& Diags) | ||
{ | ||
llvm::opt::ArgStringList CCArgs { | ||
"-cc1", | ||
"-triple", "bpf-pc-linux", | ||
"-fsyntax-only", | ||
"-ferror-limit", "19", | ||
"-fmessage-length", "127", | ||
"-O2", | ||
"-nostdsysteminc", | ||
"-nobuiltininc", | ||
"-vectorize-loops", | ||
"-vectorize-slp", | ||
"-Wno-unused-value", | ||
"-Wno-pointer-sign", | ||
"-x", "c"}; | ||
CompilerInvocation *CI = tooling::newInvocation(&Diags, CCArgs); | ||
|
||
FrontendOptions& Opts = CI->getFrontendOpts(); | ||
Opts.Inputs.clear(); | ||
Opts.Inputs.emplace_back(Path, IK_C); | ||
return CI; | ||
} | ||
|
||
std::unique_ptr<llvm::Module> | ||
getModuleFromSource(StringRef Name, StringRef Content) | ||
{ | ||
CompilerInstance Clang; | ||
Clang.createDiagnostics(); | ||
|
||
IntrusiveRefCntPtr<vfs::FileSystem> VFS = buildVFS(Name, Content); | ||
Clang.setVirtualFileSystem(&*VFS); | ||
|
||
IntrusiveRefCntPtr<CompilerInvocation> CI = | ||
createCompilerInvocation(Name, Clang.getDiagnostics()); | ||
Clang.setInvocation(&*CI); | ||
|
||
std::unique_ptr<CodeGenAction> Act(new EmitLLVMOnlyAction(&*LLVMCtx)); | ||
if (!Clang.ExecuteAction(*Act)) | ||
return std::unique_ptr<llvm::Module>(nullptr); | ||
|
||
return Act->takeModule(); | ||
} | ||
|
||
} | ||
|
||
extern "C" { | ||
void perf_clang__init(void) | ||
{ | ||
perf::LLVMCtx.reset(new llvm::LLVMContext()); | ||
} | ||
|
||
void perf_clang__cleanup(void) | ||
{ | ||
perf::LLVMCtx.reset(nullptr); | ||
llvm::llvm_shutdown(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
#ifndef PERF_UTIL_CLANG_H | ||
#define PERF_UTIL_CLANG_H | ||
|
||
#include "llvm/ADT/StringRef.h" | ||
#include "llvm/IR/LLVMContext.h" | ||
#include "llvm/IR/Module.h" | ||
#include <memory> | ||
namespace perf { | ||
|
||
using namespace llvm; | ||
|
||
std::unique_ptr<Module> | ||
getModuleFromSource(StringRef Name, StringRef Content); | ||
|
||
} | ||
#endif |