【问题标题】:Adding the inreg attribute to LLVM IR function parameters将 inreg 属性添加到 LLVM IR 函数参数
【发布时间】:2016-02-07 20:31:35
【问题描述】:

我正在使用 LLVM,我想使用 API 重新创建一段 IR:

declare void @fun(i32* inreg, i32 inreg)

但我似乎无法让它真正做到。

我目前的尝试是:

Function* fun = cast<Function>(M.getOrInsertFunction("fun",type));

((fun -> getAttributes()).getParamAttributes(0)).addAttribute(c,0,Attribute::InReg);

((fun -> getAttributes()).getParamAttributes(1)).addAttribute(c,0,Attribute::InReg);

这段代码在第 1 行之后实际上没有做任何事情,第 2 行和第 3 行被完全忽略,我在 IR 输出中得到的只是:

declare void @fun(i32* , i32 )

如何让它正常工作?

【问题讨论】:

    标签: compiler-construction llvm llvm-ir llvm-c++-api


    【解决方案1】:

    在 LLVM 中管理函数属性非常不方便,因为属性被打包到不可变和全局集合中。将属性分配给函数参数实际上意味着将表示所有函数和参数属性的集合替换为新的。

    幸运的是,至少有一些辅助函数可以让这项工作变得更容易一些。我建议使用llvm::Function::addAttribute() 方法。

    Function* fun = cast<Function>(M.getOrInsertFunction("fun", type));
    fun->addAttribute(1, Attribute::InReg);
    fun->addAttribute(2, Attribute::InReg);
    

    记住索引0代表function属性,argument属性从索引1开始。

    【讨论】:

    • 这条评论很有用,但有一个关键部分是错误的:函数属性有索引-1 = ~0(至少在最新的 LLVM 中)。这可以在llvm::AttributeList::AttrIndex::FunctionIndex 中看到。索引0 保留用于返回值属性。
    【解决方案2】:

    您的代码 sn-p 存在三个问题。

    首先,第一个参数的索引是 1,而不是 0。所以你应该使用索引 1 和 2,而不是 0 和 1。

    其次,addAttribute() 不会修改其接收者,而是返回一个新集合。因此,更改属性的正确方法是:

    fun->setAttributes(fun->getAttributes().addAttribute(1, ...));
    

    最后,上面有一个简写,就是要做的:

    fun->addAttribute(1, ...);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多