Compiler construction 将inreg属性添加到LLVM IR函数参数

Compiler construction 将inreg属性添加到LLVM IR函数参数,compiler-construction,llvm,llvm-ir,llvm-c++-api,Compiler Construction,Llvm,Llvm Ir,Llvm C++ Api,我正在使用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::InR

我正在使用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,而不是0。所以应该使用索引1和2,而不是0和1

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

fun->setAttributes(fun->getAttributes().addAttribute(1, ...));
最后,上面有一个简写,就是:

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

在LLVM中管理函数属性非常不方便,因为属性被打包到不可变和全局集合中。为函数参数指定一个属性实际上意味着用一个新属性替换代表所有函数和参数属性的集合

幸运的是,至少有一些助手函数可以使这项工作变得更简单。我建议使用这个方法

Function*fun=cast(M.getOrInsertFunction(“fun”,type));
乐趣->添加属性(1,属性::InReg);
乐趣->添加属性(2,属性::InReg);

请记住,索引0表示函数属性,参数属性从索引1开始。

此注释很有用,但有一个关键部分是错误的:函数属性的索引
-1=~0
(至少在最新的LLVM中是如此)。这可以在
llvm::AttributeList::AttrIndex::FunctionIndex
中看到。索引
0
是为返回值属性保留的。
fun->addAttribute(1, ...);