[LLVMdev] keeping instructions in order and hidden dependencies

Hal Finkel hfinkel at anl.gov
Sun Feb 17 06:28:47 PST 2013


----- Original Message -----
> From: "Cameron Zwarich" <zwarich at apple.com>
> To: "Reed Kotler" <rkotler at mips.com>
> Cc: llvmdev at cs.uiuc.edu
> Sent: Sunday, February 17, 2013 1:49:46 AM
> Subject: Re: [LLVMdev] keeping instructions in order and hidden dependencies
> 
> You are trying to do a few different things here, and a uniform
> solution may not work for all of them. For a fixed instruction
> sequence, e.g. a special kind of move-and-branch sequence used for
> tail calls, you probably want a pseudo. If you are trying to combine
> arbitrary instructions together, e.g. Thumb IT blocks, you probably
> want to use bundles, even if the sequences are a fixed length. I
> think bundles might work well for your delay slots. Bundles will
> force instructions to stay together in sequence, and there is really
> no other way to do this with arbitrary instructions.
> 
> If you have a compare instruction that generates a flag and a branch
> instruction that uses it, you want to model this dependency with an
> unallocatable physical register, e.g. the CPSR on ARM:
> 
> // Condition code registers.
> def CCR : RegisterClass<"ARM", [i32], 32, (add CPSR)> {
>   let CopyCost = -1;  // Don't allow copying of status registers.
>   let isAllocatable = 0;
> }
> 
> This will require you to mark defs and uses (and kills), but if
> you're using it purely inside of a single basic block you won't have
> to worry about it too much. If you have instructions that may only
> generate this dependency in certain circumstances, you can use
> implicit def/use operands, which can be added to any MachineInstr
> even if the register is not part of the normal def/use list. If you
> need the instructions to always be adjacent and not simply satisfy a
> physical register dependency, then you'll have to use pseudos or
> bundles.
> 
> For long/short jump optimizations you probably want to optimistically
> assume that all jumps are short and add a pass to relax them prior
> to asm emission, but I don't know the exact constraints of MIPS. On
> ARM this is done as part of the constant island pass.

If you'd like other examples, for PowerPC this is done in PPCBranchSelector.cpp, and Hexagon does something similar in HexagonFixupHwLoops.cpp.

 -Hal

> 
> I CC'd Jim because he's the expert on the ARM constant island
> formation and he can give you some advice from experience there. I
> have always avoided that code. :-)
> 
> Cameron
> 
> On Feb 16, 2013, at 9:20 PM, Reed Kotler <rkotler at mips.com> wrote:
> 
> > One of my reasons for lowering things early is that I need to get
> > an accurate count of the size of things.
> > 
> > Some of the pseudos even have instructions like compare immediate,
> > which in Mips 16 has two forms depending on the magnitude of the
> > immediate field.
> > 
> > Though I suppose it's possible to leave things as a pseudo and
> > calculate their size, though I'm not sure where I could store the
> > result.
> > 
> > I need the size for long/short jump optimization, constant islands,
> > delay slot filling (on mips16 you can't put a 32 bit instruction
> > in a delay slot) and other things.
> > 
> > I have not used bundles.
> > 
> > Is the idea that I could create a bundle and insert the
> > instructions in the bundle and then they are guaranteed to stay
> > together?
> > 
> > On 02/16/2013 09:09 PM, Cameron Zwarich wrote:
> >> AFAIK, You have two choices: use a pseudo that is lowered into
> >> separate instructions later as part of asm emission, or use MI
> >> bundles. The former is generally what existing targets use for
> >> this sort of thing, but perhaps the second would work better for
> >> you.
> >> 
> >> Cameron
> >> 
> >> On Feb 16, 2013, at 8:37 PM, Reed Kotler <rkotler at mips.com> wrote:
> >> 
> >>> Some of my pseudos do conditional branch .+4 and such.
> >>> 
> >>> I don't want the instruction scheduler to get creative on me.
> >>> 
> >>> On 02/16/2013 07:20 PM, reed kotler wrote:
> >>>> I have some pseudos that I am expanding in the Mips 16 port.
> >>>> Currently
> >>>> they are blasted in one chunk as a multi line instruction
> >>>> sequence but I
> >>>> am changing the code now to expand them
> >>>> after register allocation.
> >>>> 
> >>>> They are essentially macros and I need to make sure, at this
> >>>> time at
> >>>> least, that the individual instructions are not reordered or
> >>>> moved around.
> >>>> 
> >>>> There are dependencies sometimes between the instructions that
> >>>> I'm not
> >>>> sure how to tell LLVM about.
> >>>> 
> >>>> For example, this first one is a two instruction macro where
> >>>> register T8
> >>>> is implicitly set by the first instruction and used by the
> >>>> second
> >>>> instruction.
> >>>> 
> >>>> T8 is not a mips16 registers but some instructions use it
> >>>> implicitly and
> >>>> it can function as
> >>>> a condition code register.
> >>>> 
> >>>> In this first case, I do a compare (CMP) and the result sets T8
> >>>> and then
> >>>> the branch instruction following it uses this as if it were a
> >>>> condition
> >>>> code register.
> >>>> 
> >>>> Maybe I can just set first instruction as defining T8 and the
> >>>> second as
> >>>> using it for the last time.
> >>>> 
> >>>> Without this expansion, this is not an issue.
> >>>> 
> >>>> At some future time it might be possible to reuse this condition
> >>>> register later and move it around but for now I'm not needing
> >>>> that
> >>>> optimization.
> >>>> 
> >>>> Tia.
> >>>> 
> >>>> Reed
> >>> 
> >>> 
> >>> _______________________________________________
> >>> LLVM Developers mailing list
> >>> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> >>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
> > 
> > 
> 
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
> 



More information about the llvm-dev mailing list