diff options
author | Yonghong Song <yhs@fb.com> | 2017-11-16 00:52:30 +0000 |
---|---|---|
committer | Yonghong Song <yhs@fb.com> | 2017-11-16 00:52:30 +0000 |
commit | 0df1955fdb388964e250c6f3af89fa0e8b3104a6 (patch) | |
tree | 0bb09f10e4a84f046fd86dee143e3c1da3902f72 | |
parent | 64b77007a6d25d832d1ff55939d7eace23e15c6f (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.cpp | 34 | ||||
-rw-r--r-- | test/CodeGen/BPF/objdump_cond_op.ll | 69 |
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 } |