[Mesa-dev] FLAG-DAY: NIR derefs
Rob Clark
robdclark at gmail.com
Thu Mar 15 01:11:53 UTC 2018
On Wed, Mar 14, 2018 at 8:44 PM, Connor Abbott <cwabbott0 at gmail.com> wrote:
> On Wed, Mar 14, 2018 at 6:07 PM, Rob Clark <robdclark at gmail.com> wrote:
>> On Wed, Mar 14, 2018 at 7:42 PM, Connor Abbott <cwabbott0 at gmail.com> wrote:
>>> On Wed, Mar 14, 2018 at 5:05 PM, Rob Clark <robdclark at gmail.com> wrote:
>>>> On Wed, Mar 14, 2018 at 4:58 PM, Connor Abbott <cwabbott0 at gmail.com> wrote:
>>>>> FWIW, the way I imagined doing this was something like:
>>>>>
>>>>> 1. Add nir_deref_instr and nir_deref_type_pointer. At this point, just
>>>>> make everything assert if the base deref isn't a nir_deref_var. This
>>>>> will be a bit of a flag-day, but also very mechanical. It'll also help
>>>>> us catch cases where we don't handle new-style derefs later.
>>>>> 2. Add a pass to flatten nir_deref_type_pointer into
>>>>> nir_deref_type_var if possible (i.e. if there's a clear chain up to
>>>>> the base variable without any phi nodes or whatever). This should
>>>>> always be possible for GLSL, as well as SPIR-V unless
>>>>> KHR_variable_pointers is enabled. We'll use this to avoid too much
>>>>> churn in drivers, passes that haven't been updated, etc. We might also
>>>>> want a pass to do the opposite, for converting passes where we don't
>>>>> want to have codepaths for both forms at once.
>>>>
>>>> btw, does it seem reasonable to assert that deref instruction src's
>>>> are *always* in SSA form? That seems reasonable to me since they will
>>>> be mostly lowered away before the driver sees them (and I think makes
>>>> some of the operation on them easier), and I can't think of any way
>>>> for them *not* to be SSA (since they aren't real instructions).
>>>
>>> I think so... as long as you don't lower locals to regs before
>>> lowering everything to explicit address arithmetic. Although, with the
>>> physical memory model, it's just another source like any other so I'm
>>> not sure if there's a point.
>>>
>>
>> I think w/ phys memory model, we could lower away the deref's before
>> going to regs. That *seems* like a reasonable requirement to me.
>>
>>>>
>>>> If so, my rough thoughts are a deref instruction chain (formed by ssa
>>>> links to previous deref instruction) either start w/
>>>> nir_deref_instr_pointer or nir_deref_instruction_var instructions at
>>>> the head of the list (to start, I guess you could ignore adding the
>>>> nir_deref_instr_pointer instruction and I could add that for
>>>> clover/spirv work). Followed by N links of struct/array deref_link
>>>> instructions that have two ssa src's (one that is previous deref
>>>> instruction and one that is array or struct member offset)
>>>
>>> Why would you need a separate nir_deref_instr_pointer? Do you want to
>>> put information like what type of pointer it is in there? Maybe we
>>> could just make that part of every nir_deref_instr instead?
>>
>> well, in clc you could hypotheticaly do something like:
>>
>> __global struct Foo *f = (struct Foo *)0x1234;
>>
>> so you don't necessarily have a var at the start of your deref chain.
>>
>> More realistic example is:
>>
>> ptr->a.b->c.d
>>
>> which is really two deref chains, first starting at a var, second
>> starting at an ssa ptr (which I think realistically ends up needing to
>> be a fat pointer to deal w/ cl's multiple address spaces[1]), with an
>> intermediate load_global or load_shared intrinsic in between.
>>
>> Anyways, don't want to derail the conversion to deref instructions too
>> much, but I do think we need something different for "var" vs "ptr"
>> (and the nice thing about deref chains is this should be easier to
>> add)
>
> My point was that you don't really need a distinction, as long as
> deref instructions can accept any old pointer. In your second example,
> there would be a struct deref, a load, and then a second struct deref
> using the result of the load. This is similar to how it's done in
> LLVM.
>
I guess that comes down to how we define what a pointer is..
if it is abstract enough to deal with both logical pointers (ie.
something that refers back to a var of some sort) or physical
pointers, I guess that can work.. at this point I'm not too picky
about the color of that bikeshed ;-)
fwiw, on the topic of abstracting deref chains in prep of changing things:
https://github.com/freedreno/mesa/commits/deref-chains
I've gotten approx (I think) about half way thru going thru the
intr->variables[n]->var callsites, and will pick it up in the morning.
I think we need to do similar for nir_tex_instr (but that looks like
only a few call-sites). But as long as we can assume deref chains are
in SSA I think some refactoring like that up front will make the
conversion easier (ie. accessors will be easy to convert over to new
world order).
BR,
-R
More information about the mesa-dev
mailing list