首先,我是clang / llvm的真正的菜鸟。
但是我试图为某种目的修改clang。
我想在IR代码中为具有一些注释的变量发出Alloca指令时添加元数据。
我注意到CGDecl.cpp中的这个函数:
CodeGenFunction::AutoVarEmission
CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D)
其中包含最后一行:
if (D.hasAttr<AnnotateAttr>())
EmitVarAnnotations(&D, emission.Address);
这看起来像我需要的条件,所以我把它修改为
if (D.hasAttr<AnnotateAttr>()) {
AnnotateAttr* attr = D.getAttr<AnnotateAttr>();
if(attr->getAnnotation() == "_my_custom_annotation_") {
// set metadata...
}
EmitVarAnnotations(&D, emission.Address);
}
我的问题是我不知道如何在此时添加元数据,因为我找不到访问指令的方法
然而,在CGExp.cpp中,我看到了AllocaInstr的构建位置,但此时我无法访问VarDecl,因此我不知道注释是否存在。
无论如何,我尝试在此函数中添加元数据(无条件):
llvm::AllocaInst *CodeGenFunction::CreateIRTemp(QualType Ty,
const Twine &Name) {
llvm::AllocaInst *Alloc = CreateTempAlloca(ConvertType(Ty), Name);
// FIXME: Should we prefer the preferred type alignment here?
CharUnits Align = getContext().getTypeAlignInChars(Ty);
// how to put it conditionaly on the annotation?
llvm::MDNode* node = getRangeForLoadFromType(Ty);
Alloc->setMetadata("_my_custom_metadata", node);
Alloc->setAlignment(Align.getQuantity());
return Alloc;
}
添加setMetadata调用。
但是我没有在生成的IR中看到附加的元数据。
我使用clang -g -S -target i686-pc-win32 -emit-llvm main.cpp -o output.ll
也许我完全错了,但问题是我不掌握clang中的代码生成:)
PS:这是我编译的代码
int main() {
__attribute__ ((annotate("_my_custom_annotation_"))) float a[12];
}
感谢任何帮助!
由于
答案 0 :(得分:2)
if (D.hasAttr<AnnotateAttr>()) {
AnnotateAttr* attr = D.getAttr<AnnotateAttr>();
if(attr->getAnnotation() == "_my_custom_annotation_") {
// set metadata...
}
EmitVarAnnotations(&D, emission.Address);
}
看起来你在正确的地方。事实上,所有EmitAutoVarAlloca
都对不同类型的变量声明进行了特殊处理,但所有声明都以&#34;地址&#34; ({1}}中的指令(<)。
所以你想要做的是:
emission.Address
但是,我建议使用特殊属性将元数据添加到指令中。如果您通过代码进一步阅读,您会发现if (D.hasAttr<AnnotateAttr>()) {
AnnotateAttr* attr = D.getAttr<AnnotateAttr>();
if(attr->getAnnotation() == "_my_custom_annotation_") {
emission.Address->setMetadata(...); // <--- your MDNode goes here
}
EmitVarAnnotations(&D, emission.Address);
}
具有特殊含义,并且您发出的IR可能与预期不符。您可以在AnnotateAttr
文件中添加自定义属性。我建议使用Annotate条目的副本。然后,您可以通过代码关注Attr.td
并在适当的位置添加属性代码,以便通过clang识别和处理它。