From patchwork Fri Sep 23 12:49:57 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wang Nan X-Patchwork-Id: 76846 Delivered-To: patch@linaro.org Received: by 10.140.106.72 with SMTP id d66csp552296qgf; Fri, 23 Sep 2016 05:50:55 -0700 (PDT) X-Received: by 10.66.72.40 with SMTP id a8mr12302506pav.15.1474635055891; Fri, 23 Sep 2016 05:50:55 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id gp4si7847626pac.58.2016.09.23.05.50.55; Fri, 23 Sep 2016 05:50:55 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1759380AbcIWMux (ORCPT + 27 others); Fri, 23 Sep 2016 08:50:53 -0400 Received: from szxga01-in.huawei.com ([58.251.152.64]:18937 "EHLO szxga01-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758919AbcIWMuu (ORCPT ); Fri, 23 Sep 2016 08:50:50 -0400 Received: from 172.24.1.136 (EHLO szxeml431-hub.china.huawei.com) ([172.24.1.136]) by szxrg01-dlp.huawei.com (MOS 4.3.7-GA FastPath queued) with ESMTP id DRL70277; Fri, 23 Sep 2016 20:50:23 +0800 (CST) Received: from linux-4hy3.site (10.107.193.248) by szxeml431-hub.china.huawei.com (10.82.67.208) with Microsoft SMTP Server id 14.3.235.1; Fri, 23 Sep 2016 20:50:13 +0800 From: Wang Nan To: , CC: , , , Wang Nan , Arnaldo Carvalho de Melo , He Kuang , Jiri Olsa Subject: [PATCH 10/14] perf clang: Support compile IR to BPF object and add testcase Date: Fri, 23 Sep 2016 12:49:57 +0000 Message-ID: <1474635001-153850-11-git-send-email-wangnan0@huawei.com> X-Mailer: git-send-email 1.8.3.4 In-Reply-To: <1474635001-153850-1-git-send-email-wangnan0@huawei.com> References: <1474635001-153850-1-git-send-email-wangnan0@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.107.193.248] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A0B0203.57E52510.0031, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0, ip=0.0.0.0, so=2013-06-18 04:22:30, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: 0457c2d372b0959f5489efd9ae719677 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org getBPFObjectFromModule() is introduced to use LLVM to convert Module (LLVM IR) to BPF object code. Add new testcase for it. Signed-off-by: Wang Nan Cc: Arnaldo Carvalho de Melo Cc: Alexei Starovoitov Cc: He Kuang Cc: Jiri Olsa --- tools/perf/tests/clang.c | 6 ++++- tools/perf/util/c++/clang-c.h | 1 + tools/perf/util/c++/clang-test.cpp | 33 ++++++++++++++++++-------- tools/perf/util/c++/clang.cpp | 47 ++++++++++++++++++++++++++++++++++++++ tools/perf/util/c++/clang.h | 3 +++ 5 files changed, 80 insertions(+), 10 deletions(-) -- 1.8.3.4 diff --git a/tools/perf/tests/clang.c b/tools/perf/tests/clang.c index 57ee160..2964c06 100644 --- a/tools/perf/tests/clang.c +++ b/tools/perf/tests/clang.c @@ -12,6 +12,10 @@ static struct { .func = test__clang_to_IR, .desc = "Test builtin clang compile C source to IR", }, + { + .func = test__clang_to_obj, + .desc = "Test builtin clang compile C source to ELF object", + }, #endif }; @@ -33,7 +37,7 @@ int test__clang(int i __maybe_unused) return TEST_SKIP; } #else -int test__clang(int i __maybe_unused) +int test__clang(int i) { if (i < 0 || i >= (int)ARRAY_SIZE(clang_testcase_table)) return TEST_FAIL; diff --git a/tools/perf/util/c++/clang-c.h b/tools/perf/util/c++/clang-c.h index dcde4b5..22b3936 100644 --- a/tools/perf/util/c++/clang-c.h +++ b/tools/perf/util/c++/clang-c.h @@ -9,6 +9,7 @@ extern void perf_clang__init(void); extern void perf_clang__cleanup(void); extern int test__clang_to_IR(void); +extern int test__clang_to_obj(void); #ifdef __cplusplus } diff --git a/tools/perf/util/c++/clang-test.cpp b/tools/perf/util/c++/clang-test.cpp index c5546fd..0f30e4d 100644 --- a/tools/perf/util/c++/clang-test.cpp +++ b/tools/perf/util/c++/clang-test.cpp @@ -13,15 +13,13 @@ public: ~perf_clang_scope() {perf_clang__cleanup();} }; -extern "C" { - -int test__clang_to_IR(void) +static std::unique_ptr +__test__clang_to_IR(void) { - perf_clang_scope _scope; unsigned int kernel_version; if (fetch_kernel_version(&kernel_version, NULL, 0)) - return -1; + return std::unique_ptr(nullptr); std::string cflag_kver("-DLINUX_VERSION_CODE=" + std::to_string(kernel_version)); @@ -30,14 +28,31 @@ int test__clang_to_IR(void) perf::getModuleFromSource({cflag_kver.c_str()}, "perf-test.c", test_llvm__bpf_base_prog); + return M; +} + +extern "C" { +int test__clang_to_IR(void) +{ + perf_clang_scope _scope; + + if (!__test__clang_to_IR()) + return -1; + return 0; +} +int test__clang_to_obj(void) +{ + perf_clang_scope _scope; + + auto M = __test__clang_to_IR(); if (!M) return -1; - for (llvm::Function& F : *M) - if (F.getName() == "bpf_func__SyS_epoll_wait") - return 0; - return -1; + auto Buffer = perf::getBPFObjectFromModule(&*M); + if (!Buffer) + return -1; + return 0; } } diff --git a/tools/perf/util/c++/clang.cpp b/tools/perf/util/c++/clang.cpp index f6f6a8c..38dcc14 100644 --- a/tools/perf/util/c++/clang.cpp +++ b/tools/perf/util/c++/clang.cpp @@ -15,6 +15,11 @@ #include "clang/CodeGen/CodeGenAction.h" #include "llvm/IR/Module.h" #include "llvm/Option/Option.h" +#include "llvm/Support/TargetSelect.h" +#include "llvm/Support/TargetRegistry.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetOptions.h" +#include "llvm/IR/LegacyPassManager.h" #include #include "clang.h" @@ -103,6 +108,48 @@ getModuleFromSource(llvm::opt::ArgStringList CFlags, StringRef Path) return getModuleFromSource(std::move(CFlags), Path, VFS); } +std::unique_ptr> +getBPFObjectFromModule(llvm::Module *Module) +{ + using namespace llvm; + + LLVMInitializeBPFTargetInfo(); + LLVMInitializeBPFTarget(); + LLVMInitializeBPFTargetMC(); + LLVMInitializeBPFAsmPrinter(); + + std::string TargetTriple("bpf-pc-linux"); + std::string Error; + const Target* Target = TargetRegistry::lookupTarget(TargetTriple, Error); + if (!Target) { + llvm::errs() << Error; + return std::unique_ptr>(nullptr); + } + + llvm::TargetOptions Opt; + Optional RM = Optional(); + TargetMachine *TargetMachine = + Target->createTargetMachine(TargetTriple, + "generic", "", + Opt, RM); + + Module->setDataLayout(TargetMachine->createDataLayout()); + Module->setTargetTriple(TargetTriple); + + std::unique_ptr> Buffer(new SmallVector()); + raw_svector_ostream ostream(*Buffer); + + legacy::PassManager PM; + if (TargetMachine->addPassesToEmitFile(PM, ostream, + TargetMachine::CGFT_ObjectFile)) { + llvm::errs() << "TargetMachine can't emit a file of this type\n"; + return std::unique_ptr>(nullptr);; + } + PM.run(*Module); + + return std::move(Buffer); +} + } extern "C" { diff --git a/tools/perf/util/c++/clang.h b/tools/perf/util/c++/clang.h index b4fc2a9..dd8b042 100644 --- a/tools/perf/util/c++/clang.h +++ b/tools/perf/util/c++/clang.h @@ -19,5 +19,8 @@ std::unique_ptr getModuleFromSource(opt::ArgStringList CFlags, StringRef Path); +std::unique_ptr> +getBPFObjectFromModule(llvm::Module *Module); + } #endif