【问题标题】:Basic block in LLVM IR seems broken in assembly codesLLVM IR 中的基本块似乎在汇编代码中被破坏
【发布时间】:2019-10-29 23:23:15
【问题描述】:

我通过llvm pass在基本块的第一条和最后一条指令中添加了调试信息,然后我成功找到了我在汇编代码中添加的信息。但是第一条指令和最后一条指令的信息数量不同。

我想知道结果是否正确,如果正确,为什么数字不同以及如何正确获取汇编代码中块的边界?

我的通行证代码

  bool runOnFunction(Function &F) override {
    unsigned start = 2333;
    unsigned end = 23333;
    MDNode *N = F.getMetadata("dbg");
    for (BasicBlock &B : F) {
      errs() << "Hello: ";
      Instruction *I = B.getFirstNonPHI();
      DebugLoc loc = DebugLoc::get(start, 0, N);
      if (loc && I!=NULL) {
        I->setDebugLoc(loc);
      } else {
        errs() << "start error";
      }
      I = B.getTerminator();
      loc = DebugLoc::get(end, 1, N);
      if (loc && I!= NULL) {
        I->setDebugLoc(loc);
      } else {
        errs() << "end error";
      }
      errs() << "\n";
    }
    return true;
  }
};
} 

它运行没有任何错误。部分结果:

# %bb.2:                                # %for.body
                                        #   in Loop: Header=BB0_1 Depth=1
    .loc    1 2333 0                # myls.c:2333:0
    movl    -4(%ebp), %eax
.Ltmp4:
    .loc    1 71 14                 # myls.c:71:14
    movl    %eax, -8(%ebp)
.Ltmp5:
.LBB0_3:                                # %for.cond1
                                        #   Parent Loop BB0_1 Depth=1
                                        # =>  This Inner Loop Header: Depth=2
    .loc    1 2333 0                # myls.c:2333:0
    movl    -8(%ebp), %eax
.Ltmp6:
    .loc    1 71 18                 # myls.c:71:18
    cmpl    n, %eax
.Ltmp7:
    .loc    1 23333 1               # myls.c:23333:1
    jge .LBB0_13

......

LBB2_10:                               # %sw.epilog
    .loc    1 23333 1               # myls.c:23333:1
    jmp .LBB2_11
.LBB2_11:                               # %while.cond
                                        # =>This Inner Loop Header: Depth=1
    .loc    1 162 13                # myls.c:162:13
    cmpl    $0, -164(%ebp)
    .loc    1 23333 1               # myls.c:23333:1
    jl  .LBB2_20
# %bb.12:                               # %while.body
                                        #   in Loop: Header=BB2_11 Depth=1
.Ltmp75:
    .loc    1 164 14                # myls.c:164:14
    movl    -136(%ebp), %eax
    .loc    1 164 28 is_stmt 0      # myls.c:164:28
    movl    -164(%ebp), %ecx
                                        # kill: def $cl killed $ecx
    .loc    1 164 25                # myls.c:164:25
    movl    $1, %edx
    shll    %cl, %edx
    .loc    1 164 22                # myls.c:164:22
    andl    %edx, %eax
    cmpl    $0, %eax
.Ltmp76:
    .loc    1 23333 1 is_stmt 1     # myls.c:23333:1
    je  .LBB2_18

我发现233323333不匹配,233323333的数字是不同架构的汇编代码不同。我使用 opt 运行我的 pass 和 llc 来获取汇编代码。

感谢每一个帮助。

【问题讨论】:

  • 尝试-print-after-all 选项以了解何时删除带有调试信息的说明。
  • 您可能希望在您的通行证中分析统计数据。获取您检测的第一条指令的计数,以及最后一条指令的计数。另外,你要确保基本块的第一条和最后一条指令不相同

标签: llvm llvm-ir


【解决方案1】:

我认为问题在于优化。在您通过后,IR 会进行其他几轮优化,这些优化更改了基本块并消除了一些指令。

你可能有一个来自LLVM page的注册函数

static llvm::RegisterStandardPasses Y(
    llvm::PassManagerBuilder::EP_EarlyAsPossible,
    [](const llvm::PassManagerBuilder &Builder,
       llvm::legacy::PassManagerBase &PM) { PM.add(new Hello()); });

尝试使用EP_OptimizerLast 而不是EP_EarlyAsPossible。这会将您的通行证作为最后一个优化器运行。

另一种选择是使用EP_EnabledOnOptLevel0 并将opt 与-O0 一起使用。

您可以在此page 中查找标志


使用-emit-llvm*.ll 中生成 LLVM IR 可能会有所帮助。您的代码对 IR 所做的事情更加明显

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-04
    • 2011-06-20
    • 1970-01-01
    • 2020-12-12
    • 1970-01-01
    • 2021-07-05
    • 2019-08-07
    相关资源
    最近更新 更多