NerdPirate
NerdPirate

Reputation: 149

In LLVM, how do I reflect metadata in the assembly file?

Here's the setup: I'm working with LLVM and I have an analysis pass that needs to make some results of the analysis available for later use. These results need to be visible in the final .s file (ARM architecture) that I generate. I then run some scripts on the .s file that do further analysis that use these results but is also dependent on the actual structure of the ASM generated (otherwise I would just use more LLVM passes).

Originally I thought metadata was what I wanted, and I created some simple test function to insert some metadata for each instruction I care about. But I don't know how to make this metadata reflected in the final .s file. Even worse, I cannot figure out how to make the metadata string what I actually want. The "5" you'll see below is never output. Instead I see 46 or 47 in the output.

void addMetadata(Instruction& I) {
    LLVMContext& C = I.getContext();
    MDNode* N = MDNode::get(C, MDString::get(C, "5"));
    I.setMetadata("alias_set", N);

    std::cerr << "Instruction" << std::endl;
    I.dump();
}

Example output:

Instruction
  %30 = load i32* %29, align 4, !dbg !67, !alias_set !46

I've also heard the inline assembly might work, but I don't know if that would allow me to insert comments or labels before a specific IR instruction. If the IR is reordered, then that label or comment would need to follow it wherever it goes. Basically, I just want to see a label or a comment in the .s file with some small amount of information that I want. Does anyone know how to do that? Thanks!

Upvotes: 2

Views: 611

Answers (1)

NerdPirate
NerdPirate

Reputation: 149

On further research, I have found out that you just can't easily do what I'm trying to do with metadata. Debug info is a special case of metadata that is output to assembly files. It turns out that what worked for me was inlining ASM. This would probably be a helpful thing to include as part of the LLVM Metadata class; the ability to dump metadata. What I ended up doing is extracting any metadata I care about and inserting it as inline assembly in front of the instruction. This function will insert assembly comments in front of an instruction, and you can replace @info_you_want_to_output with the string representation of whatever data you care about. Note: @ is generally the start of a comment for ARM assembly. This function uses ATT assembly syntax, but you can replace AD_ATT with AD_Intel if you need Intel syntax.

void insertInfo(Instruction& I)
{
    std::vector<llvm::Type *> AsmArgTypes = {};

    FunctionType *AsmFTy = FunctionType::get(Type::getVoidTy(I.getContext()), AsmArgTypes, false);
    InlineAsm *IA = InlineAsm::get(AsmFTy, std::string("@info_you_want_to_output"), "",
                            /*hasSideEffects*/ true, /*isAlignStack*/ false, InlineAsm::AD_ATT);
    Instruction *newInst = CallInst::Create(IA, "", &I);
}

This is some example output in my ARM assembly (.s) file:

ldr r2, .LCPI0_2
mov r1, r4
@APP
@@info_you_want_to_output
@NO_APP
bl  __cxa_atexit
pop {r4, lr}
mov pc, lr

Note that before and after the inline assembly, it inserts @APP and @NO_APP. I'm not sure what this indicates, but it's easy to ignore. Hope this helps anyone in the future.

Upvotes: 6

Related Questions