Hello, I just wrote the code like this: BuildMI(BB, NM::CALL, 1) .addExternalSymbol(("_lvksda_control_marker_" + lexical_cast<string>(bb)).c_str()); and got some unexpected string in the assembler output. The problem is that when external symbol is added to MachineInstruction, MachineOperand is created with the char* argument, but the argument is not copied, it's just stored in MachineOperand::symbolName. So, all long as string temporary is destroyed, that pointer points to garbage. I suppose I could handle this by adding function to LLVM module and using .addGlobalValue, but still, is the non-copying behaviour of constructor by design? - Volodya
On Fri, 15 Apr 2005, Vladimir Prus wrote:> Hello, > I just wrote the code like this: > > BuildMI(BB, NM::CALL, 1) > .addExternalSymbol(("_lvksda_control_marker_" > + lexical_cast<string>(bb)).c_str()); > > and got some unexpected string in the assembler output. The problem is > that when external symbol is added to MachineInstruction, MachineOperand > is created with the char* argument, but the argument is not copied, it's > just stored in MachineOperand::symbolName. So, all long as string > temporary is destroyed, that pointer points to garbage. I suppose I > could handle this by adding function to LLVM module and using > .addGlobalValue, but still, is the non-copying behaviour of constructor > by design?Yes, this is by design. MachineOperand is supposed to be a very light-weight union. We actually used to have it carry an std::string around, but this required conditional code to make sure to free it and copy it when neccesary. If you'd like to do this, there are a couple of options: first, you could build the table in the asmprinter, and have the operands point into the string table. Second, you could add the functions to the Module, though that is less appealing (ideally the code generator would not hack on the LLVM module at all... we're not there yet, but slowly getting there). Another thing that might be interesting is the new llvm.pcmarker intrinsic that Andrew recently added. I have no idea if it would be useful to you or not, but... it's documented here: http://llvm.cs.uiuc.edu/docs/LangRef.html#i_pcmarker -Chris -- http://nondot.org/sabre/ http://llvm.cs.uiuc.edu/
On Friday 15 April 2005 18:49, Chris Lattner wrote:> On Fri, 15 Apr 2005, Vladimir Prus wrote: > > Hello, > > I just wrote the code like this: > > > > BuildMI(BB, NM::CALL, 1) > > .addExternalSymbol(("_lvksda_control_marker_" > > + > > lexical_cast<string>(bb)).c_str()); > > > > and got some unexpected string in the assembler output. The problem is > > that when external symbol is added to MachineInstruction, MachineOperand > > is created with the char* argument, but the argument is not copied, it's > > just stored in MachineOperand::symbolName. So, all long as string > > temporary is destroyed, that pointer points to garbage. I suppose I > > could handle this by adding function to LLVM module and using > > .addGlobalValue, but still, is the non-copying behaviour of constructor > > by design? > > Yes, this is by design. MachineOperand is supposed to be a very > light-weight union. We actually used to have it carry an std::string > around, but this required conditional code to make sure to free it and > copy it when neccesary.Yea, could be tricky with union.> If you'd like to do this, there are a couple of options: first, you could > build the table in the asmprinter, and have the operands point into the > string table.Looks reasonable.> Second, you could add the functions to the Module, though > that is less appealing (ideally the code generator would not hack on the > LLVM module at all... we're not there yet, but slowly getting there).Yea, I understand that. That's why I've asked.> Another thing that might be interesting is the new llvm.pcmarker intrinsic > that Andrew recently added. I have no idea if it would be useful to you > or not, but... it's documented here: > http://llvm.cs.uiuc.edu/docs/LangRef.html#i_pcmarkerIn fact, I'm having problems exactly while lowering the pcmarker intrinsic ;-) Need to get in to assembler somehow, and I already have a code that parses assembler and recognised calls to functions with certain name patterns as markers. - Volodya