Roman Divacky
2011-Jun-13 15:21 UTC
[LLVMdev] Modifying DAG in TargetLowering::ReplaceNodeResults()
Hi! I am trying to implement va_arg() on ppc32. Everything went smooth, except implementing va_arg() of 64bit int. Since i64 is not a legal type on ppc32 DAGTypeLegalizer::ExpandRes_VAARG() splits the va_arg(i64) into two i32 va_args. The problem with ppc32 va_arg is that it needs special "alignment" of its gpr pointer when the argument is i64. Ie. I need to know if I am lowering va_arg of i64. I tried to tackle this by providing custom lowering for va_arg(i64) that just aligns stuff properly. I do this by adding ISD::VA_ARG handling to PPCTargetLowering::ReplaceNodeResults() where I need to read/increse/write a number in memory while providing nothing in &Results. The problem is that the Chain of the va_arg node needs to be updated but I dont know how to do that. I tried stuff like: SDValue Ops[] = { InChain, VAListPtr, N->getOperand(2), N->getOperand(3) }; SDValue NewNode = DAG.getNode(ISD::VAARG, dl, DAG.getVTList(VT, MVT::Other), Ops, 4); DAG.ReplaceAllUsesWith(N, NewNode.getNode()); // or this variant //DAG.ReplaceAllUsesWith(SDValue(N, 1), NewNode); but that does not work for various reasons (N having more than one value in the first case and N operand 2 not having legal type (i64)). Any idea how to fix this? Or am I doing it completely wrong? roman
Eli Friedman
2011-Jun-13 16:21 UTC
[LLVMdev] Modifying DAG in TargetLowering::ReplaceNodeResults()
On Mon, Jun 13, 2011 at 8:21 AM, Roman Divacky <rdivacky at freebsd.org> wrote:> Hi! > > I am trying to implement va_arg() on ppc32. Everything went smooth, except > implementing va_arg() of 64bit int. Since i64 is not a legal type on ppc32 > DAGTypeLegalizer::ExpandRes_VAARG() splits the va_arg(i64) into two i32 > va_args. > > The problem with ppc32 va_arg is that it needs special "alignment" of its > gpr pointer when the argument is i64. Ie. I need to know if I am lowering > va_arg of i64. > > I tried to tackle this by providing custom lowering for va_arg(i64) that > just aligns stuff properly. I do this by adding ISD::VA_ARG handling to > PPCTargetLowering::ReplaceNodeResults() where I need to read/increse/write > a number in memory while providing nothing in &Results. > > The problem is that the Chain of the va_arg node needs to be updated but > I dont know how to do that. > > I tried stuff like: > > > SDValue Ops[] = { InChain, VAListPtr, N->getOperand(2), N->getOperand(3) }; > SDValue NewNode = DAG.getNode(ISD::VAARG, dl, DAG.getVTList(VT, MVT::Other), Ops, 4); > DAG.ReplaceAllUsesWith(N, NewNode.getNode()); > // or this variant > //DAG.ReplaceAllUsesWith(SDValue(N, 1), NewNode); > > > but that does not work for various reasons (N having more than one value in the first case > and N operand 2 not having legal type (i64)). > > > Any idea how to fix this? Or am I doing it completely wrong?ReplaceNodeResults returns multiple SDValues; you should just be able to return both the new value and new chain, and have everything just work. -Eli
Apparently Analagous Threads
- larger than minimun MTU, forwarding via other node
- Handling node through TargetLowering::LowerOperation vs TargetLowering::ReplaceNodeResults
- Handling node through TargetLowering::LowerOperation vs TargetLowering::ReplaceNodeResults
- [Sparc] vararg double issue on 32 bit Sparc processors
- [LLVMdev] [SafeCode] Unable to build the LLVM from trunk