Базовый блок в LLVM IR кажется неработающим в кодах сборки - PullRequest
0 голосов
/ 24 октября 2019

Я добавляю отладочную информацию в первую и последнюю инструкцию базовых блоков с помощью команды llvm pass, а затем успешно нахожу информацию, которую добавляю в коды сборки. Но номера информации первой инструкции и последней инструкции различны.

Я хочу знать, правильный ли результат, и если он правильный, почему числа разные и как правильно получить границу блока в ассемблерном коде?

Код моего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

Я считаю 2333 и 23333 не совпадающими, а числа 2333 и 23333 различаются по ассемблерному коду для разных архитектур. Я использую opt для запуска моего пропуска и llc для получения кода сборки.

Я ценю любую помощь.

1 Ответ

0 голосов
/ 29 октября 2019

Я думаю, что проблема с оптимизацией. После вашего прохождения IR проходит другие раунды оптимизации, которые изменили основные блоки и устранили некоторые инструкции.

Возможно, у вас есть функция регистра, подобная следующей на странице LLVM

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.

Вы можете посмотреть флаги в этом страница


Может быть полезно использовать -emit-llvm для генерации IR LLVM в *.ll. Более ясно, что ваш код сделал с IR

...