On Sep 29, 2007, at 2:57 PM, Andreas Fredriksson
<deplinenoise at gmail.com> wrote:
> On 9/25/07, Evan Cheng <evan.cheng at apple.com> wrote:
>>> Hi Evan,
>>> wouldn't this generate fairly terrible code if each address
register
>>> use has to be preceded by instructions to make an address register
>>> hold the right value?
>>
>> No. I would suggest doing this as a instruction selection post pass.
>> It would operate on DAGs so you still get the benefit of SDNode CSE,
>> etc. Scheduling and register allocation happen later.
>>
>> Let me clarify. Write "generic" instructions, i.e. those that
use /
>> def DR32, with patterns. So right after isel, all the DAG nodes will
>> be of the dx variant, e.g. ADD_32_dx_dx. Also write AR instruction
>> variants such as ADDA_32_dx. These do not have patterns so they
>> aren't used during selection. Add a post pass to replace load /
store
>> operands by replacing them with identical nodes except for the
>> "correct" opcodes.
>>
>> I think this mechanism will work. There is probably a cleaner
>> solution. But I am not seeing it right now.
>
> Hi Evan,
> as per your suggestion on IRC I've tried creating a "shadow
group" of
> registers in my data register class that aren't allocatable and map to
> the address registers; this allows me to deal with everything as data
> registers. Integer and FP code without loads and stores work fine with
> this scheme, and simple memory operations using global addresses work
> nicely as well.
Very nice.
>
>
> There are a couple of gotchas I keep running into though;
>
> 1) My ABI requires the two first pointer arguments to go into address
> registers A0, A1. I can't seem to express this in the cc td
> description, because there are no MVTs for pointers. Is there a way
> around that? This leads to pointer arguments entering functions in
> data registers because they are simply i32's.
>
> If I lower the calling convention stuff manually rather than relying
> on the generated CC analyzer, how do I determine that a formal
> argument I'm about to receive or pack together is supposed to be used
> as a pointer so I can stick it in an address register?
I'd suggest custom lowering for now. Again use data registers during
lowering and fix them during the isel post pass if the parameters are
used as pointers. Do you think that would work?
>
>
> 2) How do I implement getPointerRegClass() in my TargetInstrInfo
> subtype? Returning the proper thing (the address register class) makes
> the instruction scheduler very unhappy and it asserts complaining that
> the register classes don't agree (which they don't, obviously,
because
> everything has been selected as data register instructions).
>
> Returning the data register class generates a bunch of illegal moves,
> such as move.l 8(d0), d1. Here, d0 has to be an address register. The
> root cause of this is instructions that get emitted with the
> M_LOOK_UP_PTR_REG_CLASS flag, because I have a ptr_rc in my address
> mode selection patterns for loads and stores.
I think it should return DR register class. My theory is if all the
nodes are already fixed right after selection, scheduling and
allocation should just work.
>
>
> Also, I'm uncertain as to how this custom DR->AR op replacer pass
fits
> into this whole soup and where it is supposed to happen, as I'm still
> pretty clueless with llvm internals. :)
It should happen right after selection and before scheduling (i.e. in
InstructionSelectionBasicBlock before it calls ScheduleAndEmitDAG). I
would suggest you focusing on getting this down before you start
worrying about the downstream passes.
Evan
>
>
> Thanks,
> Andreas
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev