使用insertafter()插入LLVM指令

发布于 2025-01-21 11:01:08 字数 1465 浏览 0 评论 0原文

我是LLVM的新手,并且正在进行一些实验,例如插入指令。

我的main.c如下所示:


int foo(int e, int a) {
  int b = a + 1;
  int c = b * 2;
  b = e << 1;
  int d = b / 4;
  return c * d;
}

我使用下面的命令来生成llvm字节码

clang-12 -O0 -Xclang -disable-O0-optnone -emit-llvm -c main.c -o main.bc
opt-12 -S -mem2reg main.bc -o main.ll

字节the the the the the the the the the the

; Function Attrs: noinline nounwind uwtable
define dso_local i32 @foo(i32 %0, i32 %1) #0 {
  %3 = add nsw i32 %1, 1
  %4 = mul nsw i32 %3, 2
  %5 = shl i32 %0, 1
  %6 = sdiv i32 %5, 4
  %7 = mul nsw i32 %4, %6
  ret i32 %7
}


the the the code在第一个指令后使用代码插入指令:

bool runOnBasicBlock(BasicBlock &B) {
    // get the first and second instruction
Instruction &Inst1st = *B.begin();
Instruction *NewInst = BinaryOperator::Create(
        Instruction::Add, Inst1st.getOperand(0), Inst1st.getOperand(0));
NewInst->insertAfter(&Inst1st);
...
}

在运行此通行证后,字节bytecode之后已更改为

; Function Attrs: noinline nounwind uwtable
define dso_local i32 @foo(i32 %0, i32 %1) #0 {
  %3 = add nsw i32 %1, 1
  %4 = add i32 %1, %1
  %5 = mul nsw i32 %4, 2
  %6 = shl i32 %0, 1
  %7 = sdiv i32 %6, 4
  %8 = mul nsw i32 %5, %7
  ret i32 %8
}

似乎插入的指令等于b = a + a;,因此指令%4 = mul nsw i32%3,2被更改为<代码>%5 = MUL NSW I32%4,2 。我不明白原因。有帮助吗?

I'm new to LLVM, and I'm doing some experiments on it such as inserting an instruction.

My main.c is shown below:


int foo(int e, int a) {
  int b = a + 1;
  int c = b * 2;
  b = e << 1;
  int d = b / 4;
  return c * d;
}

I use the command below to generate the LLVM bytecode

clang-12 -O0 -Xclang -disable-O0-optnone -emit-llvm -c main.c -o main.bc
opt-12 -S -mem2reg main.bc -o main.ll

The bytecode is

; Function Attrs: noinline nounwind uwtable
define dso_local i32 @foo(i32 %0, i32 %1) #0 {
  %3 = add nsw i32 %1, 1
  %4 = mul nsw i32 %3, 2
  %5 = shl i32 %0, 1
  %6 = sdiv i32 %5, 4
  %7 = mul nsw i32 %4, %6
  ret i32 %7
}


And I use the code to insert an instruction after the first instruction:

bool runOnBasicBlock(BasicBlock &B) {
    // get the first and second instruction
Instruction &Inst1st = *B.begin();
Instruction *NewInst = BinaryOperator::Create(
        Instruction::Add, Inst1st.getOperand(0), Inst1st.getOperand(0));
NewInst->insertAfter(&Inst1st);
...
}

After I run this pass, the bytecode is changed to

; Function Attrs: noinline nounwind uwtable
define dso_local i32 @foo(i32 %0, i32 %1) #0 {
  %3 = add nsw i32 %1, 1
  %4 = add i32 %1, %1
  %5 = mul nsw i32 %4, 2
  %6 = shl i32 %0, 1
  %7 = sdiv i32 %6, 4
  %8 = mul nsw i32 %5, %7
  ret i32 %8
}

It seems that the inserted instruction is equal to b = a + a;, so the instruction %4 = mul nsw i32 %3, 2 is changed to %5 = mul nsw i32 %4, 2. I cannot understand the reason. Any help?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

甜中书 2025-01-28 11:01:08

众所周知,newInst-&gt; insertafter(&amp; inst1st);从块中制造

int b = a + 1;
int c = b * 2;

以下块,

int b = a + 1, a + a;
int c = b * 2;

因此b删除了上一个值%3 并获取新的值%4,然后进一步mul使用b的新值。

As I know, NewInst->insertAfter(&Inst1st); makes from the block

int b = a + 1;
int c = b * 2;

the following block

int b = a + 1, a + a;
int c = b * 2;

therefore b drops off the previous value %3 and gets the new value %4 and further mul uses that new value of b.

冷默言语 2025-01-28 11:01:08

我无法再现您的输出字节码。您有机会忘记提及什么吗?

这个问题使我很好奇,可以自己尝试。

我使用了与问题相同的c文件,然后使用相同的命令来生成LLVM字节码,唯一的区别是我使用了llvm 16。

正如预期的那样,我得到了与您的初始字节相同的:

; Function Attrs: noinline nounwind uwtable
define dso_local i32 @foo(i32 noundef %e, i32 noundef %a) #0 {
entry:
  %add = add nsw i32 %a, 1
  %mul = mul nsw i32 %add, 2
  %shl = shl i32 %e, 1
  %div = sdiv i32 %shl, 4
  %mul1 = mul nsw i32 %mul, %div
  ret i32 %mul1
}

我使用以下函数使用了以下功能。您提供的代码是在第一个指令之后插入添加说明的代码:

#include "llvm/IR/Instructions.h"
...
PreservedAnalyses FuncPass::run(Function &F, FunctionAnalysisManager &AM) {
  for (auto &B : F) {
    Instruction &Inst1st = *B.begin();
    Instruction *NewInst = BinaryOperator::Create(
        Instruction::Add, Inst1st.getOperand(0), Inst1st.getOperand(0));
    NewInst->insertAfter(&Inst1st);
  }
  return PreservedAnalyses::none();
}

然后我通过上述函数通过了字节码,但是我得到的结果与您的 不同:

; Function Attrs: noinline nounwind uwtable
define dso_local i32 @foo(i32 noundef %e, i32 noundef %a) #0 {
entry:
  %add = add nsw i32 %a, 1
  %0 = add i32 %a, %a
  %mul = mul nsw i32 %add, 2
  %shl = shl i32 %e, 1
  %div = sdiv i32 %shl, 4
  %mul1 = mul nsw i32 %mul, %div
  ret i32 %mul1
}

我的结果字节字节类似于您的,新的添加指令在第一个指令后立即但是,尽管您的输出字节码,但此新添加指令的结果并不能替换下一个指令中的变量b的使用

I could not reproduce your output bytecode. Any chance you forgot to mention something?

This question made me curious enough to try it myself.

I used the same c file as in the question and I used the same commands to generate the LLVM bytecode, the only difference was I used LLVM 16.

As expected I got the same initial bytecode as yours:

; Function Attrs: noinline nounwind uwtable
define dso_local i32 @foo(i32 noundef %e, i32 noundef %a) #0 {
entry:
  %add = add nsw i32 %a, 1
  %mul = mul nsw i32 %add, 2
  %shl = shl i32 %e, 1
  %div = sdiv i32 %shl, 4
  %mul1 = mul nsw i32 %mul, %div
  ret i32 %mul1
}

I wrote the following function pass using the code you provided to insert the add instruction after the first instruction:

#include "llvm/IR/Instructions.h"
...
PreservedAnalyses FuncPass::run(Function &F, FunctionAnalysisManager &AM) {
  for (auto &B : F) {
    Instruction &Inst1st = *B.begin();
    Instruction *NewInst = BinaryOperator::Create(
        Instruction::Add, Inst1st.getOperand(0), Inst1st.getOperand(0));
    NewInst->insertAfter(&Inst1st);
  }
  return PreservedAnalyses::none();
}

Then I ran the bytecode through the above function pass but the result I got was different from yours:

; Function Attrs: noinline nounwind uwtable
define dso_local i32 @foo(i32 noundef %e, i32 noundef %a) #0 {
entry:
  %add = add nsw i32 %a, 1
  %0 = add i32 %a, %a
  %mul = mul nsw i32 %add, 2
  %shl = shl i32 %e, 1
  %div = sdiv i32 %shl, 4
  %mul1 = mul nsw i32 %mul, %div
  ret i32 %mul1
}

My result bytecode, similar to yours, contains the new add instruction right after the first instruction, but despite your output bytecode, the result of this new add instruction does not replace the usage of variable b in the next instruction.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文