Dear all,
I am looking to output assembly comments in my emitPrologue() function, just for my own readability. Searching for a way to do this found me this thread - http://lists.cs.uiuc.edu/pipermail/llvmdev/2011-October/043722.html, which says that the best way to output comments from somewhere like emitPrologue() is to:
- Create an MDString for the comment.
- Attach it to an LLVM instruction using setMetadata().
- Add a new member to MachineInstr to hold the metadata, and attach it when converting LLVM instructions.
- Update AsmPrinter to read off the metadata and output it as an assembly comment.
Is this the only (and correct) way to do this?
If so, I am having trouble attaching the MDString to an instruction. I am using BuildMI to create my instruction, which only seems to have an “addMetadata()” function rather than “setMetadata()”, and which takes an MDNode instead of an MDString. I attempted to do this as follows:
void XXXFrameLowering::emitPrologue(MachineFunction &MF) const {
…
Value* end_prologue_comment = MDString::get(getGlobalContext(), “end of prologue”);
BuildMI(MBB, MBBI, dl, TII.get(Target::AnInstr), Target::R1).addMetadata(cast(end_prologue_comment));
}
However, it seems an MDString cannot be case to an MDNode this way. How do I go about turning that MDString into an MDNode, and once done how do I add the new member to MachineInstr and attach the metadata to it?
Thanks,
Stephen
So, an update. I have managed to generate comments, although it does create a non-existent instruction. My method is as follows (and I would appreciate any comments on how to do it “better”, although note that this won’t make it into the final code :).)
- I declared a “fake” instruction type to hold comments, ala:
class FakeInst<dag outs, dag ins, string asmstr, list pattern> : Instruction {
field bits<32> Inst;
let Namespace = “XXX”
let Inst{31-0} = 0;
dag OutOperandList = outs;
dag InOperandList = ins;
let AsmString = asmstr;
let Pattern = pattern;
}
- I then defined a comment instruction, ala:
def COMMENT : FakeInst<(outs), (ins Reg:$fake), “; $fake”, >;
- I added the following to printOperand(…) in XXXAsmPrinter.cpp:
switch (MO.getType()) {
…
case MachineOperand::MO_Metadata:
O << cast(MO.getMetadata()->getOperand(0))->getString();
break;
…
}
- Finally, whenever I needed to emit comments I call the following:
MDNode* comment = MDNode::get(getGlobalContext(), ArrayRef<Value*>(MDString::get(getGlobalContext(), “COMMENT HERE”)));
BuildMI(MBB, MBBI, dl, TII.get(XXX::COMMENT)).addMetadata(comment);
So, this seems to work, although it will create an empty instruction (I think). That could probably be cleaned up before MC emission, but I would really just remove the comments anyway. Any suggestions on a better way to do this (or a pointer to some obvious existing solution!) welcome :).
Stephen
You don't need to create new fake instruction. You can attach your comment to any existing machine instruction.
MI->addOperand(MachineOperand::CreateMetadata(comment));