You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

LLVM Pass中如何识别并提取指令的非常量操作数

在LLVM Pass中区分常量操作数与变量操作数并提取变量

嗨,我来帮你搞定这个LLVM Pass里的操作数判断问题!针对你给出的%res = add i32 4, %var这条指令,要提取其中的变量操作数%var,核心就是利用LLVM的类型系统来区分常量和非常量操作数——毕竟所有的常量数值/右值都会继承自LLVM的Constant类,而变量或者指令生成的临时值则不会。

核心思路

LLVM里所有的常量(比如整数常量4、浮点数常量、常量表达式等)都是Constant类的子类,而我们要找的变量操作数(比如%var,可能是栈分配的变量、函数参数、或者其他指令的输出)则属于非Constant类型的Value实例。所以只需要判断操作数是否是Constant的实例,就能过滤掉常量,留下变量。

代码示例

下面是一个简单的Function Pass示例,专门处理Add指令并提取其中的变量操作数:

#include "llvm/IR/Instructions.h"
#include "llvm/Passes/PassPlugin.h"
#include "llvm/Passes/PassBuilder.h"

using namespace llvm;

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

  bool runOnFunction(Function &F) override {
    // 遍历函数里的每个基本块
    for (BasicBlock &BB : F) {
      // 遍历基本块里的每个指令
      for (Instruction &I : BB) {
        // 判断当前指令是不是加法指令
        if (auto *AddInst = dyn_cast<AddInst>(&I)) {
          errs() << "处理加法指令: " << I << "\n";
          // 遍历加法指令的所有操作数
          for (unsigned int OpIdx = 0; OpIdx < AddInst->getNumOperands(); ++OpIdx) {
            Value *Operand = AddInst->getOperand(OpIdx);
            // 判断操作数是否不是常量
            if (!isa<Constant>(Operand)) {
              errs() << "找到变量操作数: " << *Operand << "\n";
              // 这里可以添加你需要的提取逻辑,比如记录这个操作数的信息
            }
          }
        }
      }
    }
    // 返回false表示没有修改IR
    return false;
  }
};

char ExtractVarOperandPass::ID = 0;

extern "C" LLVM_ATTRIBUTE_WEAK PassPluginLibraryInfo llvmGetPassPluginInfo() {
  return {
    LLVM_PLUGIN_API_VERSION, "ExtractVarOperandPass", "v0.1",
    [](PassBuilder &PB) {
      PB.registerPipelineParsingCallback(
        [](StringRef Name, FunctionPassManager &FPM, ArrayRef<PassBuilder::PipelineElement>) {
          if (Name == "extract-var-operand") {
            FPM.addPass(ExtractVarOperandPass());
            return true;
          }
          return false;
        }
      );
    }
  };
}

关键细节解释

  1. isa<Constant>(Operand):这是LLVM提供的类型判断模板,用来检查一个Value指针是否指向Constant类(或其子类)的实例。如果返回true,说明是常量;返回false,就是我们要找的变量操作数。
  2. 更精细的判断(可选):如果你需要区分不同类型的常量(比如只排除整数常量),可以用isa<ConstantInt>(Operand)来精准判断;如果要找的是栈分配的变量,可以进一步判断isa<AllocaInst>(Operand),不过根据你的需求,!isa<Constant>已经足够过滤所有常量数值/右值。
  3. 变量操作数的类型:非常量的操作数可能是Argument(函数参数)、AllocaInst(栈变量)、LoadInst(从内存加载的变量),或者其他指令的输出(比如另一个加法指令的结果)——这些都属于我们要保留的“变量”范畴。

内容的提问来源于stack exchange,提问作者Einiemand

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:18:36