summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYonghong Song <yhs@fb.com>2017-11-16 00:52:30 +0000
committerYonghong Song <yhs@fb.com>2017-11-16 00:52:30 +0000
commit0df1955fdb388964e250c6f3af89fa0e8b3104a6 (patch)
tree0bb09f10e4a84f046fd86dee143e3c1da3902f72
parent64b77007a6d25d832d1ff55939d7eace23e15c6f (diff)
bpf: enable llvm-objdump to print out symbolized jmp target
Add hook in BPF backend so that llvm-objdump can print out the jmp target with label names, e.g., ... if r1 != 2 goto 6 <LBB0_2> ... goto 7 <LBB0_4> ... LBB0_2: ... LBB0_4: ... Signed-off-by: Yonghong Song <yhs@fb.com> Acked-by: Alexei Starovoitov <ast@kernel.org> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@318358 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.cpp34
-rw-r--r--test/CodeGen/BPF/objdump_cond_op.ll69
2 files changed, 103 insertions, 0 deletions
diff --git a/lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.cpp b/lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.cpp
index c8fbc0c2207..5c3bba6e669 100644
--- a/lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.cpp
+++ b/lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.cpp
@@ -15,6 +15,7 @@
#include "BPF.h"
#include "InstPrinter/BPFInstPrinter.h"
#include "MCTargetDesc/BPFMCAsmInfo.h"
+#include "llvm/MC/MCInstrAnalysis.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
@@ -68,6 +69,35 @@ static MCInstPrinter *createBPFMCInstPrinter(const Triple &T,
return nullptr;
}
+namespace {
+
+class BPFMCInstrAnalysis : public MCInstrAnalysis {
+public:
+ explicit BPFMCInstrAnalysis(const MCInstrInfo *Info)
+ : MCInstrAnalysis(Info) {}
+
+ bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size,
+ uint64_t &Target) const override {
+ // The target is the 3rd operand of cond inst and the 1st of uncond inst.
+ int64_t Imm;
+ if (isConditionalBranch(Inst)) {
+ Imm = Inst.getOperand(2).getImm();
+ } else if (isUnconditionalBranch(Inst))
+ Imm = Inst.getOperand(0).getImm();
+ else
+ return false;
+
+ Target = Addr + Size + Imm * Size;
+ return true;
+ }
+};
+
+} // end anonymous namespace
+
+static MCInstrAnalysis *createBPFInstrAnalysis(const MCInstrInfo *Info) {
+ return new BPFMCInstrAnalysis(Info);
+}
+
extern "C" void LLVMInitializeBPFTargetMC() {
for (Target *T :
{&getTheBPFleTarget(), &getTheBPFbeTarget(), &getTheBPFTarget()}) {
@@ -89,6 +119,9 @@ extern "C" void LLVMInitializeBPFTargetMC() {
// Register the MCInstPrinter.
TargetRegistry::RegisterMCInstPrinter(*T, createBPFMCInstPrinter);
+
+ // Register the MC instruction analyzer.
+ TargetRegistry::RegisterMCInstrAnalysis(*T, createBPFInstrAnalysis);
}
// Register the MC code emitter
@@ -114,4 +147,5 @@ extern "C" void LLVMInitializeBPFTargetMC() {
TargetRegistry::RegisterMCAsmBackend(getTheBPFTarget(),
createBPFbeAsmBackend);
}
+
}
diff --git a/test/CodeGen/BPF/objdump_cond_op.ll b/test/CodeGen/BPF/objdump_cond_op.ll
new file mode 100644
index 00000000000..3abbb76ccc9
--- /dev/null
+++ b/test/CodeGen/BPF/objdump_cond_op.ll
@@ -0,0 +1,69 @@
+; RUN: llc -march=bpfel -filetype=obj -o - %s | llvm-objdump -d - | FileCheck %s
+
+; Source Code:
+; int gbl;
+; int test(int a, int b) {
+; if (a == 2) {
+; gbl = gbl * gbl * 2;
+; goto out;
+; }
+; if (a != b) {
+; gbl = gbl * 4;
+; }
+; out:
+; return gbl;
+; }
+
+@gbl = common local_unnamed_addr global i32 0, align 4
+
+define i32 @test(i32, i32) local_unnamed_addr #0 {
+ %3 = icmp eq i32 %0, 2
+ br i1 %3, label %4, label %8
+
+; <label>:4: ; preds = %2
+ %5 = load i32, i32* @gbl, align 4
+ %6 = shl i32 %5, 1
+ %7 = mul i32 %6, %5
+ br label %13
+; CHECK: r1 <<= 32
+; CHECK: r1 >>= 32
+; CHECK: if r1 != 2 goto 6 <LBB0_2>
+
+; <label>:8: ; preds = %2
+ %9 = icmp eq i32 %0, %1
+ %10 = load i32, i32* @gbl, align 4
+ br i1 %9, label %15, label %11
+
+; CHECK: r1 = 0 ll
+; CHECK: r0 = *(u32 *)(r1 + 0)
+; CHECK: r0 *= r0
+; CHECK: r0 <<= 1
+; CHECK: goto 7 <LBB0_4>
+
+; <label>:11: ; preds = %8
+ %12 = shl nsw i32 %10, 2
+ br label %13
+
+; CHECK-LABEL: LBB0_2:
+; CHECK: r3 = 0 ll
+; CHECK: r0 = *(u32 *)(r3 + 0)
+; CHECK: r2 <<= 32
+; CHECK: r2 >>= 32
+; CHECK: if r1 == r2 goto 4 <LBB0_5>
+; CHECK: r0 <<= 2
+
+; <label>:13: ; preds = %4, %11
+ %14 = phi i32 [ %12, %11 ], [ %7, %4 ]
+ store i32 %14, i32* @gbl, align 4
+ br label %15
+; CHECK-LABEL: LBB0_4:
+; CHECK: r1 = 0 ll
+; CHECK: *(u32 *)(r1 + 0) = r0
+
+; <label>:15: ; preds = %8, %13
+ %16 = phi i32 [ %14, %13 ], [ %10, %8 ]
+ ret i32 %16
+; CHECK-LABEL: LBB0_5:
+; CHECK: exit
+}
+attributes #0 = { norecurse nounwind }