是否可以在LLVM-IR Pass的每条指令中插入if-else?

问题描述 投票:0回答:1

我是 LLVM-IR Pass 的初学者。 现在我想在每个 IR 指令中插入一个代码片段。 代码片段如下:

if (a==1) func1(); else func2();
a 是一个全局变量。

但是现在我遇到了几个错误,主要是: “指令有假父指针!” “‘main’函数中的基本块没有终止符!”

我需要知道我将这些代码插入到每条指令中的想法是否可行。 感谢您的帮助!

我尝试通过chatgpt解决这个问题,但失败了

我希望有人告诉我这个想法是否可行,我不在乎它有多困难。

`#include "llvm/IR/Constants.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/Pass.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/BasicBlock.h"
using namespace llvm;

namespace {
  struct InsertConditionalCallsPass : public FunctionPass {
    static char ID;
    InsertConditionalCallsPass() : FunctionPass(ID) {}

    bool runOnFunction(Function &F) override {
      Module *M = F.getParent();
      LLVMContext &Context = M->getContext();

      FunctionCallee Func1 = M->getOrInsertFunction("func1", Type::getVoidTy(Context));
      FunctionCallee Func2 = M->getOrInsertFunction("func2", Type::getVoidTy(Context));


      GlobalVariable *VarA = M->getNamedGlobal("a");
      if (!VarA) return false; 

    for (auto BI = F.begin(), BE = F.end(); BI != BE;) {
    BasicBlock &BB = *BI++;
    auto II = BB.begin();


    if (II == BB.end()) continue;


    Instruction *Inst = &*II;
    BasicBlock *OldBB = Inst->getParent();
    BasicBlock *CondBB = OldBB->splitBasicBlock(Inst);
    OldBB->getTerminator()->eraseFromParent();

    BasicBlock *ThenBB = BasicBlock::Create(Context, "then", &F, CondBB);
    BasicBlock *ElseBB = BasicBlock::Create(Context, "else", &F, CondBB);
    BasicBlock *MergeBB = BasicBlock::Create(Context, "ifcont", &F);

    IRBuilder<> Builder(OldBB);
    Value *LoadedA = Builder.CreateLoad(VarA->getType()->getPointerElementType(), VarA);
    Value *Cond = Builder.CreateICmpEQ(LoadedA, Builder.getInt32(1));
    Builder.CreateCondBr(Cond, ThenBB, ElseBB);

    // Then block
    Builder.SetInsertPoint(ThenBB);
    Builder.CreateCall(Func1, {});
    Builder.CreateBr(MergeBB);

    // Else block
    Builder.SetInsertPoint(ElseBB);
    Builder.CreateCall(Func2, {});
    Builder.CreateBr(MergeBB);

    // Merge block
    Builder.SetInsertPoint(MergeBB);
    Builder.CreateBr(CondBB);

    BB.getInstList().splice(MergeBB->begin(), BB.getInstList(), Inst);
    }

      return true;
    }
  };
}

char InsertConditionalCallsPass::ID = 0;
static RegisterPass<InsertConditionalCallsPass> X("insert-conditional-calls", "Insert Conditional Calls in Functions", false, false);
c++ llvm-ir
1个回答
0
投票
#include "llvm/IR/Constants.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/Pass.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/BasicBlock.h"

using namespace llvm;

namespace {
struct InsertConditionalCallsPass : public FunctionPass {
  static char ID;
  InsertConditionalCallsPass() : FunctionPass(ID) {}

  bool runOnFunction(Function &F) override {
    Module *M = F.getParent();
    LLVMContext &Context = M->getContext();

    FunctionCallee Func1 = M->getOrInsertFunction("func1", Type::getVoidTy(Context));
    FunctionCallee Func2 = M->getOrInsertFunction("func2", Type::getVoidTy(Context));

    GlobalVariable *VarA = M->getNamedGlobal("a");
    if (!VarA)
      return false;

    for (auto &BB : F) {
      // Insert at the beginning of each basic block
      IRBuilder<> Builder(&*BB.begin());
      Value *LoadedA = Builder.CreateLoad(VarA->getType()->getPointerElementType(), VarA);
      Value *Cond = Builder.CreateICmpEQ(LoadedA, Builder.getInt32(1));
      Builder.CreateCondBr(Cond, BB.getTerminator()->getSuccessor(0), BB.getTerminator()->getSuccessor(1));

      // Create new blocks and insert calls
      BasicBlock *ThenBB = BasicBlock::Create(Context, "then", &F, BB.getTerminator()->getSuccessor(0));
      BasicBlock *ElseBB = BasicBlock::Create(Context, "else", &F, BB.getTerminator()->getSuccessor(1));
      BasicBlock *MergeBB = BasicBlock::Create(Context, "ifcont", &F);

      Builder.SetInsertPoint(ThenBB);
      Builder.CreateCall(Func1, {});
      Builder.CreateBr(MergeBB);

      Builder.SetInsertPoint(ElseBB);
      Builder.CreateCall(Func2, {});
      Builder.CreateBr(MergeBB);

      Builder.SetInsertPoint(MergeBB);
    }

    return true;
  }
};
}

char InsertConditionalCallsPass::ID = 0;
static RegisterPass<InsertConditionalCallsPass>
    X("insert-conditional-calls", "Insert Conditional Calls in Functions", false, false);

在此更新的技术中,条件调用被插入到每个基本块的开头,从而保持正确的控制流结构。

© www.soinside.com 2019 - 2024. All rights reserved.