Hello All,
in the past two days I’ve been trying implementing a MachineFunctionPass that recognizes certain inline assemly by reading its asm string, and place function calls before and after them. I chose MachineFunctionPass instead of FunctionPass because I believe inline asm is target-related and lives better with MachineFunction.
Here is my attempt, other necessary code to invoke the pass is omitted.
bool myPass::runOnMachineFunction(MachineFunction &MF){
for(MachineBasicBlock &MBB:MF)
for(auto I=MBB.begin(), E=MBB.end(); I!=E; ++I){
MachineInst *MI= &*I;
if (MI->isInlineAsm()){
LLVM_DEBUG(dbgs() << "found an inlined asm with " <<MI->getNumOperands()<<"operands\n" );
ExternalSymbolSDNode op1 = cast<ExternalSymbolSDNode>(MI->getOperand(1));
StringRef asmstr(op1.getSymbol());
LLVM_DEBUG(dbgs()<<asmstr);
}
}
}
However, this code hardly compile and always triggers Coredump by printing. I believe this is caused by a wrong casting from MachineOperand to ExternalSymbolSDNode.
The document that I refer to is this doxgen page that says the #1 operand of inlineAsm node is a ExternalSymbolSDNode which has a pointer to the asm string. Also this page that says I can use getSymbol to obtain a const char* pointing to the asm string.
The source code I test is the following RISCV code
int fesetenv(const unsigned *envp)
{
unsigned fscr = *envp;
asm volatile("fscsr %0" :: "r"(fcsr));
return 0;
}
I’ve tried llc --print-after-isel and see that the asm is converted to
INLINEASM&“fscsr $0” [sideeffect] [attdialect], $0;[reguse:GPR], %1;gpr, !8
I’ve also tried --view-isel-dag and see that the inlineasm node do have a #1 operand TargetExternalSymbol ‘fscsr $0’.
The infomation is there but I cannot retrieve it. Do you have any advices Thanks!
best, zhaozhaozhao