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
Maybe Matching 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