Greetings, I am rather new to LLVM, so please excuse my limited knowledge about it. Currently I am trying to modify the X86TargetLowering::LowerCALL method by inserting additional instructions before the call. As far as I understand, nodes are created by calling the getNode method on the DAG. If, for example, I insert the following code Ops.push_back(Chain); Chain = DAG.getNode(ISD::TRAP, DAG.getVTList(MVT::Other), &Ops[0], Ops.size()); then an X86 instruction (namely ud2) appears in the output files compiled by llc. So, is my understanding correct that 1) the Chain determines the ordering of the nodes? 2) the second parameter is a set of return types, i. e. in my example, MVT::Other says that a Chain object will be returned? Now, as soon as I try to generate more complex instructions, I get lost. Say, I want to insert the following instruction mov eax, 42 then the best I can come up with is Ops.push_back(Chain); Ops.push_back(DAG.getRegister(X86::EAX, MVT::i32)); Ops.push_back(DAG.getConstant(42, MVT::i32)); Chain = DAG.getNode(X86::MOV32ri, DAG.getVTList(MVT::Other), &Ops[0], Ops.size()); But there are a few problems: 3) It seems I am not allowed to use concrete X86 instructions here (at least that's what I think llc's error message "cannot yet select" could mean). Is there an appropriate instruction in ISD? I can't find it... 4) Do I get the parameter passing right? Fooling around with other expressions suggests that I get it wrong. 5) What exactly is the meaning of further result types? If I get the new Chain object back, are the other results inside? Could you help me out? Sincerely, Artjom Kochtchi -- View this message in context: http://www.nabble.com/Inserting-nodes-into-SelectionDAG-%28X86%29-tp24211066p24211066.html Sent from the LLVM - Dev mailing list archive at Nabble.com.
On Jun 25, 2009, at 2:05 PM, Artjom K. wrote:> > Greetings, > > I am rather new to LLVM, so please excuse my limited knowledge about > it. > > Currently I am trying to modify the X86TargetLowering::LowerCALL > method by > inserting additional instructions before the call. > As far as I understand, nodes are created by calling the getNode > method on > the DAG. If, for example, I insert the following code > > Ops.push_back(Chain); > Chain = DAG.getNode(ISD::TRAP, DAG.getVTList(MVT::Other), &Ops[0], > Ops.size()); > > then an X86 instruction (namely ud2) appears in the output files > compiled by > llc. > So, is my understanding correct that > 1) the Chain determines the ordering of the nodes?Yes.> 2) the second parameter is a set of return types, i. e. in my example, > MVT::Other says that a Chain object will be returned?'Yes.> > Now, as soon as I try to generate more complex instructions, I get > lost. > Say, I want to insert the following instruction > > mov eax, 42 > > then the best I can come up with is > > Ops.push_back(Chain); > Ops.push_back(DAG.getRegister(X86::EAX, MVT::i32)); > Ops.push_back(DAG.getConstant(42, MVT::i32)); > Chain = DAG.getNode(X86::MOV32ri, DAG.getVTList(MVT::Other), &Ops[0], > Ops.size()); > > But there are a few problems: > 3) It seems I am not allowed to use concrete X86 instructions here > (at least > that's what I think llc's error message "cannot yet select" could > mean). Is > there an appropriate instruction in ISD? I can't find it...Yes. It seems the opcode you want here is ISD::CopyToReg.> 4) Do I get the parameter passing right? Fooling around with other > expressions suggests that I get it wrong.It looks like you have the right idea. For CopyToReg nodes, there's a special getCopyToReg accessor for convenience.> 5) What exactly is the meaning of further result types? If I get the > new > Chain object back, are the other results inside?SDNodes may have multiple results. For example, a LOAD node has two results: the Chain that indicates ordering with respect to other operations which may modify memory, and the actual loaded value. Individual results of an SDNode are identified with SDValue objects. Dan
Thank you for your help. I think I managed to create the instruction I wanted: // mov eax, 41 Chain = DAG.getCopyToReg(Chain, DAG.getRegister(X86::EAX, MVT::i32), DAG.getConstant(41, MVT::i32), InFlag); InFlag = Chain.getValue(1); I don't understand though what InFlag is for. As I read the code, it even remains uninitialized when first passed to some node creation method. Unfortunately I still don't manage to create more sophisticated error free instructions that actually appear in the assembly generated by llc. For example after the CopyToReg instruction, I want to increase eax by 1. In X86 'inc eax' would probably be the way to go, which I try to model by ISD 'addc eax, eax, 1' or something of that sort (it's probably rather 'addc eax, 1'). I've tried all sorts of combinations and ordering of operands I could come up with, but I seem to be missing the point. This is the most complete version: // inc eax Ops.push_back(Chain); Ops.push_back(DAG.getRegister(X86::EAX, MVT::i32)); // rather without target register? Ops.push_back(DAG.getRegister(X86::EAX, MVT::i32)); Ops.push_back(DAG.getConstant(1, MVT::i32)); Ops.push_back(InFlag); Chain = DAG.getNode(ISD::ADDC, DAG.getVTList(MVT::Other, MVT::Flag), &Ops[0], Ops.size()); InFlag = Chain.getValue(1); Usually, llc quits with the error message llc: SelectionDAG.cpp:4417: llvm::SDValue llvm::SelectionDAG::UpdateNodeOperands(llvm::SDValue, llvm::SDValue, llvm::SDValue): Assertion `N->getNumOperands() == 2 && "Update with wrong number of operands"' failed. Omiting the target register or switching operand order seems not to change anything. I'd really appreciate your help on this. Artjom -- View this message in context: http://www.nabble.com/Inserting-nodes-into-SelectionDAG-%28X86%29-tp24211066p24218876.html Sent from the LLVM - Dev mailing list archive at Nabble.com.