Post Increment Indirect Move Instructions

Hi,

       We have an architecture where the indirect move instruction implicitly increments the pointer
value after the move. We have Instruction format and pattern for this type of instructions.

How to encode the information that the pointer is incremented?

Thanks and regards,
Shashidhar

Hi,

       We have an architecture where the indirect move instruction
implicitly increments the pointer
value after the move. We have Instruction format and pattern for this
type of instructions.

How to encode the information that the pointer is incremented?

As you seem to be aware, LLVM has patterns specifically to match pre/post increment loads and stores (post_store). In your *ISelLowering.cpp file, you'll need to call setIndexedLoadAction(ISD::POST_INC, <type>, Legal), and the same for setIndexedStoreAction. Then you'll need to implement a getPostIndexedAddressParts function in that same file (you can look in the ARM backend for an example). If you can select your indirect moves using TableGen patterns, then you can probably use the post_store pattern.

-Hal

Hi Hal,

     Our Architecture has indirect move instruction which increments the pointer implicitly and the target only has i8 type values. So the load of i16 will be converted to two i8 target loads wherein after the first load instruction, the pointer to the first i8 address will automatically increment to point to the next i8 value. So the post increment nature is in the Target. A normal i16 indirect load need to be converted to two post increment load. SDNodes can be used to define only one value and so the Selection DAG cannot to used to encode the information that the pointer has been incremented.

I think the description that you mentioned will transform the addition/subtraction of a pointer and/from a constant into a pointer and an offset(Please correct me if i am wrong). We are doing this transformation in the Lowering of the Loads and stores.

Does the Machine Instruction class provides any way to encode this information?

Thanks for your help.

Regards,
Shashidhar

Hi Hal,

     Our Architecture has indirect move instruction which increments
     the
pointer implicitly and the target only has i8 type values. So the
load
of i16 will be converted to two i8 target loads wherein after the
first
load instruction, the pointer to the first i8 address will
automatically
increment to point to the next i8 value. So the post increment nature
is
in the Target. A normal i16 indirect load need to be converted to two
post increment load. SDNodes can be used to define only one value and
so
the Selection DAG cannot to used to encode the information that the
pointer has been incremented.

This is not true. SDNodes can have multiple values. Load SD nodes can have different addressing modes (PRE_INC, POST_INC, etc.) and for PRE_INC and POST_INC, the SDNode returns multiple values. If you look in lib/CodeGen/SelectionDAG/DAGCombiner.cpp in DAGCombiner::CombineToPostIndexedLoadStore you can see how post-increment stores are normally generated (and how to deal with multi-valued nodes).

I think the description that you mentioned will transform the
addition/subtraction of a pointer and/from a constant into a pointer
and
an offset(Please correct me if i am wrong). We are doing this
transformation in the Lowering of the Loads and stores.

That's correct. You're situation seems to be slightly different from the case that the infrastructure normally handles. Nevertheless, it seems like you're trying to get some kind of interaction with an optimization pass. If so, what are you looking to achieve? In general, if you're looking to interact with the DAGCombine simplifications, then you should somehow transform your loads into POST_INC loads. You can also introduce target-specific DAGCombine code, or a MI-level peephole pass.

Does the Machine Instruction class provides any way to encode this
information?

No, at the MI level, we can currently only encode that there is a constraint that some input operand must be the same as some output operand. For example, the PowerPC backend has a pre-increment store encoded like this:

def STDUX : XForm_8<31, 181, (outs ptr_rc_nor0:$ea_res), (ins g8rc:$rS, memrr:$dst),
                    "stdux $rS, $dst", LdStSTDU, []>,
                    RegConstraint<"$dst.ptrreg = $ea_res">, NoEncode<"$ea_res">;
}

def : Pat<(pre_store i64:$rS, iPTR:$ptrreg, iPTR:$ptroff),
          (STDUX $rS, $ptrreg, $ptroff)>;

Note that the instruction has a pseudo-output operand $ea_res which is constrained and not encoded. You are correct, however, that this does not encode any information on the relationship between the input and output value. That is done only at the SDAG level.

-Hal

Hi Hal,

Hi Hal,

      Our Architecture has indirect move instruction which increments
      the
pointer implicitly and the target only has i8 type values. So the
load
of i16 will be converted to two i8 target loads wherein after the
first
load instruction, the pointer to the first i8 address will
automatically
increment to point to the next i8 value. So the post increment nature
is
in the Target. A normal i16 indirect load need to be converted to two
post increment load. SDNodes can be used to define only one value and
so
the Selection DAG cannot to used to encode the information that the
pointer has been incremented.

This is not true. SDNodes can have multiple values. Load SD nodes can have different addressing modes (PRE_INC, POST_INC, etc.) and for PRE_INC and POST_INC, the SDNode returns multiple values. If you look in lib/CodeGen/SelectionDAG/DAGCombiner.cpp in DAGCombiner::CombineToPostIndexedLoadStore you can see how post-increment stores are normally generated (and how to deal with multi-valued nodes).

I think the description that you mentioned will transform the
addition/subtraction of a pointer and/from a constant into a pointer
and
an offset(Please correct me if i am wrong). We are doing this
transformation in the Lowering of the Loads and stores.

That's correct. You're situation seems to be slightly different from the case that the infrastructure normally handles. Nevertheless, it seems like you're trying to get some kind of interaction with an optimization pass. If so, what are you looking to achieve? In general, if you're looking to interact with the DAGCombine simplifications, then you should somehow transform your loads into POST_INC loads. You can also introduce target-specific DAGCombine code, or a MI-level peephole pass.

     Our architecture has a Post increment Indirect Move Instruction (MVI) which loads 1 Byte data from memory to Accumulator. It is of the form :

        MVI A, [BBh] ;

Here location BBh is a pointer and its value will be incremented after the MVI Instruction. So after one MVI Instruction the pointer now points to the next Byte of data. Any pointer load whether its 1 Byte, 2 Bytes, 4 Bytes has to use set of MVI Instruction. We have to generate that many number of MVI Instructions and the pointer gets incremented after every instruction. I need a way to encode the information that the Pointer is incremented so the next MVI instruction if they need to load from offset 1 will know that the pointer is currently pointing to offset 1 and need not increment pointer explicitly.
How to encode this information in SelectionDAG?

No, i am not trying to interact with DAGCombine or do any optimization(not yet).

Thanks and regards,
Shashidhar

Hi Hal,

>> Hi Hal,
>>
>>
>> Our Architecture has indirect move instruction which
>> increments
>> the
>> pointer implicitly and the target only has i8 type values. So the
>> load
>> of i16 will be converted to two i8 target loads wherein after the
>> first
>> load instruction, the pointer to the first i8 address will
>> automatically
>> increment to point to the next i8 value. So the post increment
>> nature
>> is
>> in the Target. A normal i16 indirect load need to be converted to
>> two
>> post increment load. SDNodes can be used to define only one value
>> and
>> so
>> the Selection DAG cannot to used to encode the information that
>> the
>> pointer has been incremented.
> This is not true. SDNodes can have multiple values. Load SD nodes
> can have different addressing modes (PRE_INC, POST_INC, etc.) and
> for PRE_INC and POST_INC, the SDNode returns multiple values. If
> you look in lib/CodeGen/SelectionDAG/DAGCombiner.cpp in
> DAGCombiner::CombineToPostIndexedLoadStore you can see how
> post-increment stores are normally generated (and how to deal with
> multi-valued nodes).
>
>> I think the description that you mentioned will transform the
>> addition/subtraction of a pointer and/from a constant into a
>> pointer
>> and
>> an offset(Please correct me if i am wrong). We are doing this
>> transformation in the Lowering of the Loads and stores.
> That's correct. You're situation seems to be slightly different
> from the case that the infrastructure normally handles.
> Nevertheless, it seems like you're trying to get some kind of
> interaction with an optimization pass. If so, what are you looking
> to achieve? In general, if you're looking to interact with the
> DAGCombine simplifications, then you should somehow transform your
> loads into POST_INC loads. You can also introduce target-specific
> DAGCombine code, or a MI-level peephole pass.

     Our architecture has a Post increment Indirect Move Instruction
(MVI) which loads 1 Byte data from memory to Accumulator. It is of
the
form :

        MVI A, [BBh] ;

Here location BBh is a pointer and its value will be incremented
after
the MVI Instruction. So after one MVI Instruction the pointer now
points
to the next Byte of data. Any pointer load whether its 1 Byte, 2
Bytes,
4 Bytes has to use set of MVI Instruction. We have to generate that
many
number of MVI Instructions and the pointer gets incremented after
every
instruction. I need a way to encode the information that the Pointer
is
incremented so the next MVI instruction if they need to load from
offset
1 will know that the pointer is currently pointing to offset 1 and
need
not increment pointer explicitly.
How to encode this information in SelectionDAG?

My recommendation, to start, is to mark your loads for custom lowering in your *ISelLowering.cpp file (using setOperationAction(..., Custom)), and mark your POST_INC indexed loads as legal. Then, when you lower your loads (*TargetLowering::LowerOperation will be called for each of them), turn them into a sequence of indexed (POST_INC) loads (see DAGCombiner::CombineToPostIndexedLoadStore for an example of how to create such nodes). Then just match the legal post-inc loads in your .td file.

-Hal