Как генерировать метаданные для LLVM IR?

#c #llvm #llvm-ir

#c #llvm #llvm-ir

Вопрос:

Я пытаюсь сгенерировать метаданные для созданного мною LLVM IR. Я хочу сгенерировать метаданные вида :

 !nvvm.annotations = !{!0}
!0 = metadata !{void ()* @foo, metadata !"kernel", i32 1}
 

Где foo — это функция в моем LLVM IR. Прямо сейчас я могу генерировать только метаданные вида:

 !nvvm.annotations = !{!0}

!0 = !{!"kernel"}
 

Я использовал следующий код для приведенной выше генерации метаданных.

 char metaDataArgument[512];
sprintf(metaDataArgument, "%s", pipelineKernelName);
llvm::NamedMDNode *nvvmMetadataNode =  LLVMModule->getOrInsertNamedMetadata("nvvm.annotations");
llvm::MDNode *MDNOdeNVVM = llvm::MDNode::get(*context, llvm::MDString::get(*context, "kernel"));
nvvmMetadataNode->addOperand(MDNOdeNVVM);
 

Может кто-нибудь сказать мне, как изменить приведенный выше код для генерации метаданных требуемой формы

Ответ №1:

Ваши метаданные будут представлять собой кортеж из 3 элементов.

  • Первое — это глобальное значение, которое переносится при вставке в иерархию метаданных как «ValueAsMetadata» (мы можем использовать подкласс Constant, поскольку GlobalValues являются постоянными).
  • Второй — это строка MDString, вы получили это.
  • Последний из них обернут как ConstantAsMetadata .

Это должно выглядеть примерно так:

 SmallVector<Metadata *, 32> Ops; // Tuple operands
GlobalValue *Foo = Mod.getNamedValue("foo");
if (!Foo) report_fatal_error("Expected foo..");

Ops.push_back(llvm::ValueAsMetadata::getConstant(Foo));
Ops.push_back(llvm::MDString::get(*context, "kernel"));

// get constant i32 1
Type *I32Ty = Type::getInt32Ty(*context);
Contant *One = ConstantInt::get(I32Ty, 1);
Ops.push_back(llvm::ValueAsMetadata::getConstant(One));

auto *Node =  MDTuple::get(Context, Ops);