Rafael EspĂndola
2006-May-31 10:51 UTC
[LLVMdev] [RFC, ARM] expanding RET to CopyToReg;BRIND
> > Why it is named RETFLAG? > > Historical reason. Originally we didn't have nodes that could > *optionally* have an input flag. A better design, e.g. on PPC would be to > have a PPCISD::RET node, which takes an optional input flag, and always > lower RET to it.I See. I will try to always lower to "(mov)*;bx lr" on ARM.> Flag in the SelectionDAG stuff is so named because it was originally used > for condition codes. However, it has since grown to mean "keep these two > nodes always together". In the case of return, you want the scheduler to > produce code like this (on PPC):That clarifies a lot! Thanks.> ... > R3 = outval_virtreg > blr > > not like this: > > ... > R3 = outval_virtreg > ... > blr > > So the copy and blr are flagged together. > > Another case where flags are useful are for things like the X86 variable > shift instruction. There the shift amount is required to be in the CL > register, so we generate code like this: > > > CL = shamt_virtreg > X = shl Y, CL > > We don't want the copy and shift to wander apart from each other (e.g. we > don't want another shift to get scheduled in between them), so we flag > them together. In practice, these copies usually get coallesced away.In the second case shl explicitly uses CL. Shouldn't the register allocator be smart enough to avoid scheduling an instruction that destroys CL in between them? In the first case, what do you think about making it possible for an instruction to optionally depend on a value? That is, make blr depend on R3 or R3/R4 depending on the type of the return value. Something like a = DAG.getNode(ISD::BRIND, MVT::Other, Copy, LR); a.addUse(PPC::R3)> -ChrisThanks, Rafael
On Wed, 31 May 2006, [UTF-8] Rafael Esp?ndola wrote:>> We don't want the copy and shift to wander apart from each other (e.g. we >> don't want another shift to get scheduled in between them), so we flag >> them together. In practice, these copies usually get coallesced away. > In the second case shl explicitly uses CL. Shouldn't the register > allocator be smart enough to avoid scheduling an instruction that > destroys CL in between them?Right, the register allocator sees that. The problem is the scheduler: we have to represent the dependence between the copy and the shift in a way that can be expressed in the dependence dag. We do this with a flag edge.> In the first case, what do you think about making it possible for an > instruction to optionally depend on a value? That is, make blr depend > on R3 or R3/R4 depending on the type of the return value. Something > like > a = DAG.getNode(ISD::BRIND, MVT::Other, Copy, LR); > a.addUse(PPC::R3)You can play games like that, but I wouldn't suggest it. It's better to just force the copy to be inserted in the right place. When the register allocator runs, it does know about register lifetimes and other constraints, and knows that R3/R4 are live out (as indicated by MF.addLiveOut(...) ). -Chris -- http://nondot.org/sabre/ http://llvm.org/
Rafael EspĂndola
2006-May-31 19:58 UTC
[LLVMdev] [RFC, ARM] expanding RET to CopyToReg;BRIND
On 5/31/06, Chris Lattner <sabre at nondot.org> wrote:> On Wed, 31 May 2006, [UTF-8] Rafael Esp?ndola wrote: > >> We don't want the copy and shift to wander apart from each other (e.g. we > >> don't want another shift to get scheduled in between them), so we flag > >> them together. In practice, these copies usually get coallesced away. > > In the second case shl explicitly uses CL. Shouldn't the register > > allocator be smart enough to avoid scheduling an instruction that > > destroys CL in between them? > > Right, the register allocator sees that. The problem is the scheduler: we > have to represent the dependence between the copy and the shift in a way > that can be expressed in the dependence dag. We do this with a flag edge.Sorry. I meant the scheduler. There is a data dependency already. One instruction defines CL. The other one uses it.> > In the first case, what do you think about making it possible for an > > instruction to optionally depend on a value? That is, make blr depend > > on R3 or R3/R4 depending on the type of the return value. Something > > like > > a = DAG.getNode(ISD::BRIND, MVT::Other, Copy, LR); > > a.addUse(PPC::R3) > > You can play games like that, but I wouldn't suggest it. It's better to > just force the copy to be inserted in the right place. When the register > allocator runs, it does know about register lifetimes and other > constraints, and knows that R3/R4 are live out (as indicated by > MF.addLiveOut(...) ).I am going to use the Flag by now :-) I was just thinking that the imposed restriction is stronger then necessary. For example, it might be valid to reorder R3 = ... R4 = ... blr into R4 = .. R3 = ... blr> -ChrisThanks once more, Rafael
Maybe Matching Threads
- [LLVMdev] [RFC, ARM] expanding RET to CopyToReg;BRIND
- [LLVMdev] [RFC, ARM] expanding RET to CopyToReg;BRIND
- [LLVMdev] [RFC, ARM] expanding RET to CopyToReg;BRIND
- [LLVMdev] [RFC, ARM] expanding RET to CopyToReg;BRIND
- [LLVMdev] adding an optional flag edge to a BRIND node