Sarah Thompson
2007-Aug-17 22:50 UTC
[LLVMdev] Inserting trace information during opt transformations
Hi all, In several of the transformations I'm working on I need to embed the logical equivalent of puts/printf/etc. calls inline with code. I am having some difficulties getting the transformation code right. As I understand it, I should be creating a ConstantArray based on the string (in this case I'm taking an instruction, 'disassembling' it to an ostringstream then turning it into a constant array): std::ostringstream instr; (*wp)->print(instr); Constant *itext = ConstantArray::get(instr.str()); This bit seems OK. I am calling a function in my run time system with the signature void mcp_trace_instruction(const char *) by first declaring it inside doInitialization(): virtual bool doInitialization(Module &M) { std::vector<const Type*> args; args.push_back(PointerType::get(Type::Int8Ty)); FunctionType *FT = FunctionType::get(Type::VoidTy, args, false); TraceFunc = M.getOrInsertFunction("mcp_trace_instruction", FT); return true; } then inserting a suitable CallInst instruction new CallInst(TraceFunc, gepinst, "", *wp); Looking at disassembly output from similar code, I can't just pass the constant array directly to the call because I need a GetElementPtrInst conversion. This is the thing I'm having trouble with. My current attempt is: GetElementPtrInst *gepinst = new GetElementPtrInst(itext, ConstantInt::get(Type::Int32Ty, 0), ConstantInt::get(Type::Int32Ty, 0), "", *wp); but it fails as follows: opt -load ~/llvm-tools/mcp-build/Debug/lib/MCPTransforms.so -trace-instructions -lowerselect -lowerallocs -lowergc -lowerinvoke -lowerswitch -reg2mem -insertyieldpoints -trace-memory -o Abort.fbc Abort.bc opt: /usr/local/rse/llvm/src/lib/VMCore/Instructions.cpp:872: const llvm::Type* checkType(const llvm::Type*): Assertion `Ty && "Invalid GetElementPtrInst indices for type!"' failed. opt((anonymous namespace)::PrintStackTrace()+0x15)[0x8346cf5] /lib/tls/libc.so.6(abort+0xe9)[0xbd3209] /lib/tls/libc.so.6(__assert_fail+0x101)[0xbcad91] opt[0x82ec15e] make: *** [Abort.fbc] Aborted The pass that is blowing up is -trace-instructions, which is intended basically just to go through the module inserting mcp_trace_instruction calls before each instruction, before any other modifications are made to the code (I have to trace instructions this way because by the time the other transformations run, I end up with something not very much like the original code). I've tried a few other obvious-looking alternatives, but I seem to be stabbing in the dark. If anyone could suggest the correct GetElementPtrInst configuration I would be very grateful -- I've already wasted a couple of days on this. Thank you in advance, Sarah
Chris Lattner
2007-Aug-19 22:14 UTC
[LLVMdev] Inserting trace information during opt transformations
On Aug 17, 2007, at 3:50 PM, Sarah Thompson wrote:> Hi all, > > In several of the transformations I'm working on I need to embed the > logical equivalent of puts/printf/etc. calls inline with code. I am > having some difficulties getting the transformation code right. As I > understand it, I should be creating a ConstantArray based on the > string > (in this case I'm taking an instruction, 'disassembling' it to an > ostringstream then turning it into a constant array): > > std::ostringstream instr; > (*wp)->print(instr); > Constant *itext = ConstantArray::get(instr.str()); > > This bit seems OK. I am calling a function in my run time system with > the signature > > void mcp_trace_instruction(const char *) > > by first declaring it inside doInitialization(): > > virtual bool doInitialization(Module &M) > { > std::vector<const Type*> args; > args.push_back(PointerType::get(Type::Int8Ty)); > > FunctionType *FT = FunctionType::get(Type::VoidTy, args, false); > TraceFunc = M.getOrInsertFunction("mcp_trace_instruction", FT); > > return true; > } > > then inserting a suitable CallInst instruction > > new CallInst(TraceFunc, gepinst, "", *wp); > > > Looking at disassembly output from similar code, I can't just pass the > constant array directly to the call because I need a GetElementPtrInst > conversion. This is the thing I'm having trouble with. My current > attempt is: > > GetElementPtrInst *gepinst = new GetElementPtrInst(itext, > ConstantInt::get(Type::Int32Ty, 0), > ConstantInt::get(Type::Int32Ty, 0), > "", *wp);Right. The problem here is that you need to create a GlobalVariable to hold the constant array. Something like this should work: itext = new GlobalVariable(itext->getType(), true, GlobalValue::InternalLinkage, itext, "", &M); -Chris