Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Llvm 如何获取表达式上所有操作数的内存地址_Llvm_Llvm Clang_Llvm 3.0_Llvm Ir - Fatal编程技术网

Llvm 如何获取表达式上所有操作数的内存地址

Llvm 如何获取表达式上所有操作数的内存地址,llvm,llvm-clang,llvm-3.0,llvm-ir,Llvm,Llvm Clang,Llvm 3.0,Llvm Ir,我有一些表达式,如a=b+c-d*e,在LLVM pass的帮助下,我想制作一个如下的字符串 “[b'的十六进制地址][c'的十六进制地址][c'的十六进制地址][d'的十六进制地址][d'的十六进制地址][e'的十六进制地址][操作码*] 首先,记住变量不一定存在于内存中;它们可以存储在寄存器中,也可以完全省略。在LLVM IR的上下文中,这意味着该值将直接从另一个值使用(无存储或加载) 假设所有涉及的变量都需要从内存中加载,我能想到的最简单的方法是定位存储,然后通过操作数向后执行后序DFS,

我有一些表达式,如
a=b+c-d*e
,在LLVM pass的帮助下,我想制作一个如下的字符串

“[b'的十六进制地址][c'的十六进制地址][c'的十六进制地址][d'的十六进制地址][d'的十六进制地址][e'的十六进制地址][操作码*]


首先,记住变量不一定存在于内存中;它们可以存储在寄存器中,也可以完全省略。在LLVM IR的上下文中,这意味着该值将直接从另一个值使用(无存储或加载)

假设所有涉及的变量都需要从内存中加载,我能想到的最简单的方法是定位
存储
,然后通过操作数向后执行后序DFS,记录操作码,并在识别加载时停止。对于您提供的代码段,它应该给您b的负载,然后加上操作码,然后是c的负载,然后减去操作码,等等

现在您已经有了这样一个序列,我想说从中生成字符串的最简单方法是使用动态构建的格式字符串插入对C的
sprintf
的调用,并将找到的指针传递给它(从中加载)

不过,我认为上述问题有两个:

  • 这里有一些固有的模糊性-仅以这种方式访问它们无法区分,例如,
    (b+c-d)*e
    b+(c-d)*e
    。因此,我认为在输入算术指令和离开算术指令时,分别记录“(”和“)”是有意义的

  • 这种方法实际上并不检查所有操作是否都是同一表达式的一部分。所以如果你有
    tmp=b+c;a=tmp-d*e,并且
    tmp
    被优化掉,那么它在IR中的外观将相同。我唯一能想到的强制执行方法是使用调试符号编译并深入挖掘这些符号以识别不同的表达式(尽管我真的不知道这是否可行),或者实际修改Clang以记录表达式边界:\

  • 此方法的伪代码(使用简单的序列处理操作):

    functionPass:
    对于每个指令:
    如果指令被存储:
    processExpression(存储)
    processExpression(存储):
    
    因为您需要地址,所以在编译期间无法完全构造这样的字符串。。。您是否希望将
    printf
    调用注入代码或类似的内容?另外,请记住,您需要确保所有变量都实际驻留在内存中。实际上,我想将此字符串作为参数传递给函数(假设它只在stdout上打印),并且在每个存储指令之前调用此函数。你知道怎么做吗。“use def”在这个场景中有什么用吗?@AbhinashJain当然,但你需要递归调用它-它只给你立即的操作数,而你也需要操作数的操作数,依此类推(直到
    load
    s)。但我将在哪个加载点停止(最近的还是最旧的)?我的意思是在不同的表达式上会有不同数量的操作数,因此也会有不同数量的加载操作。那么,如何有效地使用“use def”来实现这一目的呢?@AbhinashJain我的意思是,在遇到
    加载
    -换句话说,当看到
    加载
    时,添加指向序列的指针,并且不要继续访问
    加载
    的操作数。
    load
    s的数量应该与表达式中变量的数量相同(我在上面的回答中提到了注意事项)。是的,我得到了您的DFS概念,但仍然不确定的是,我如何知道表达式中变量的数量?
    functionPass:
      for each instruction:
        if instruction is store:
          processExpression(store)
    
    processExpression(store):
      sequence <- initialize
      visit(sequence, store.value)
      generateSprintfCallFromSequence(sequence)
    
    visit(sequence, value):
      if value is load:
        sequence.add(load.pointer)
      else if value is binaryop:
        // sequence.add(openingParen)
        visit(sequence, binaryop.operand(0))
        sequence.add(binaryop.opcode)
        visit(sequence, binaryop.operand(1))
        // sequence.add(closingParen);