Type Legalizer Question.

All the sub methods called inside ExpandIntegerOperand like ExpandInOp_STORE etc have access to the expanded operands map.

Why they aren’t passed to target LowerOperation? A target may also want to use the already expanded Lo and Hi parts.

  • Sanjiv

You don't really need access to the map; just use build an
EXTRACT_ELEMENT node, and legalize will take care of the mapping for
you.

-Eli

> All the sub methods called inside ExpandIntegerOperand like
ExpandInOp_STORE
> etc have access to the expanded operands map.
>
> Why they aren't passed to target LowerOperation? A target may also

want

to
> use the already expanded Lo and Hi parts.

You don't really need access to the map; just use build an
EXTRACT_ELEMENT node, and legalize will take care of the mapping for
you.

-Eli

Thanks.
I have another query related to type legalizer.
Can a target ignore certain nodes during legalize? Probably a hook for
target that can be called inside IgnoreNodeResults ()?

We want to keep certain nodes illegal, especially the pointer nodes.
Our target has 16-bit pointer and a few 16-bit insns to perform
arithmetic.
Rest of the stuff is 8-bit so we want to use legalizer to expand them.

- Sanjiv

Hi,

I have another query related to type legalizer.
Can a target ignore certain nodes during legalize? Probably a hook for
target that can be called inside IgnoreNodeResults ()?

while this could be done, I don't like the idea of doing an end-run
around the whole type legalization infrastructure. So you would have
to come up with a pretty convincing argument as to why this can't be
done another way!

We want to keep certain nodes illegal, especially the pointer nodes.
Our target has 16-bit pointer and a few 16-bit insns to perform
arithmetic.
Rest of the stuff is 8-bit so we want to use legalizer to expand them.

I think x86-32 is capable of doing a small number of 64 bit operations.
I wonder how they are handled/generated given that i64 is not a legal type?

Ciao,

Duncan.

Hi,

> I have another query related to type legalizer.
> Can a target ignore certain nodes during legalize? Probably a hook for
> target that can be called inside IgnoreNodeResults ()?

while this could be done, I don't like the idea of doing an end-run
around the whole type legalization infrastructure. So you would have
to come up with a pretty convincing argument as to why this can't be
done another way!

> We want to keep certain nodes illegal, especially the pointer nodes.
> Our target has 16-bit pointer and a few 16-bit insns to perform
> arithmetic.
> Rest of the stuff is 8-bit so we want to use legalizer to expand them.

I think x86-32 is capable of doing a small number of 64 bit operations.
I wonder how they are handled/generated given that i64 is not a legal type?

They might be using DAGCombine to convert the operations back to 64-bit.
Also, the pointer is still a legal type (i32) in X86-32.

In our case the pointers themselves are illegal (i16). We have 16-bit
registers that can only hold pointers during indirect addressing. All
other operations and registers are 8-bit. So we still want to expand
everything to 8-bit but still keep the pointer nodes as an i16 node, a
pair that in turn holds the expanded parts.

- Sanjiv

Hi,

I have another query related to type legalizer.
Can a target ignore certain nodes during legalize? Probably a hook for
target that can be called inside IgnoreNodeResults ()?

while this could be done, I don't like the idea of doing an end-run
around the whole type legalization infrastructure. So you would have
to come up with a pretty convincing argument as to why this can't be
done another way!

We want to keep certain nodes illegal, especially the pointer nodes.
Our target has 16-bit pointer and a few 16-bit insns to perform
arithmetic.
Rest of the stuff is 8-bit so we want to use legalizer to expand them.

I think x86-32 is capable of doing a small number of 64 bit operations.
I wonder how they are handled/generated given that i64 is not a legal type?

They might be using DAGCombine to convert the operations back to 64-bit.
Also, the pointer is still a legal type (i32) in X86-32.

In our case the pointers themselves are illegal (i16). We have 16-bit
registers that can only hold pointers during indirect addressing. All
other operations and registers are 8-bit. So we still want to expand
everything to 8-bit but still keep the pointer nodes as an i16 node, a
pair that in turn holds the expanded parts.

So you have a i16 register class which makes the type legal. You can make loads and stores legal (can you?). But you will have to custom lower all other i16 operations. This will work, but it requires a lot of target specific code.

Evan

So you have a i16 register class which makes the type legal. You can
make loads and stores legal (can you?). But you will have to custom
lower all other i16 operations. This will work, but it requires a lot
of target specific code.

True. If we add the i16 reg class we will need to write a lot of target specific code.
To avoid that our idea was not to tell the legalizer about the i16 regclass and let it expand everything but ignore the pointers.

- Sanjiv

>> Hi,
>>
>>> I have another query related to type legalizer.
>>> Can a target ignore certain nodes during legalize? Probably a hook
>>> for
>>> target that can be called inside IgnoreNodeResults ()?
>>
>> while this could be done, I don't like the idea of doing an end-run
>> around the whole type legalization infrastructure. So you would have
>> to come up with a pretty convincing argument as to why this can't be
>> done another way!
>>
>>> We want to keep certain nodes illegal, especially the pointer nodes.
>>> Our target has 16-bit pointer and a few 16-bit insns to perform
>>> arithmetic.
>>> Rest of the stuff is 8-bit so we want to use legalizer to expand
>>> them.
>>
>> I think x86-32 is capable of doing a small number of 64 bit
>> operations.
>> I wonder how they are handled/generated given that i64 is not a
>> legal type?
>>
> They might be using DAGCombine to convert the operations back to 64-
> bit.
> Also, the pointer is still a legal type (i32) in X86-32.
>
> In our case the pointers themselves are illegal (i16). We have 16-bit
> registers that can only hold pointers during indirect addressing. All
> other operations and registers are 8-bit. So we still want to expand
> everything to 8-bit but still keep the pointer nodes as an i16 node, a
> pair that in turn holds the expanded parts.

So you have a i16 register class which makes the type legal. You can
make loads and stores legal (can you?). But you will have to custom
lower all other i16 operations. This will work, but it requires a lot
of target specific code.

Evan

These i16 regs are actually pairs of 8-bit regs, So the other way for us
is to have only 8-bit regclass and to use custom nodes for load/store
that hold both the hi and lo parts of the pointer.

- Sanjiv

So you have a i16 register class which makes the type legal. You can
make loads and stores legal (can you?). But you will have to custom
lower all other i16 operations. This will work, but it requires a lot
of target specific code.

True. If we add the i16 reg class we will need to write a lot of target specific code.
To avoid that our idea was not to tell the legalizer about the i16 regclass and let it expand everything but ignore the pointers.

You can try just marking all i16 operations, other than load and store, as "expand". Would that work?

Evan

Won't work; LLVM expects at least some basic operations, like add, to
be legal in legal register types.

-Eli

That sounds like a bug, not a feature.

-Chris

>>
>>
>>>
>>>>
>>>> So you have a i16 register class which makes the type legal. You
>>>> can
>>>> make loads and stores legal (can you?). But you will have to custom
>>>> lower all other i16 operations. This will work, but it requires a
>>>> lot
>>>> of target specific code.
>>>
>>> True. If we add the i16 reg class we will need to write a lot of
>>> target specific code.
>>> To avoid that our idea was not to tell the legalizer about the i16
>>> regclass and let it expand everything but ignore the pointers.
>>
>> You can try just marking all i16 operations, other than load and
>> store, as "expand". Would that work?
>
> Won't work; LLVM expects at least some basic operations, like add, to
> be legal in legal register types.

That sounds like a bug, not a feature.
-Chris

The -enable-legalize-types infrastructure is entirely based upon
getVTAction (), so it will be completely ignored once we have i16
regclass,
ditto with ExpandOp of LegalizeDAG.
And LegalizeDAG::LegalizeOp() allows very few things to be auto expanded.

-Sanjiv

> Won't work; LLVM expects at least some basic operations, like add,

to

> be legal in legal register types.

That sounds like a bug, not a feature.

-Chris

I think the reason behind this behavior in llvm is the pointer
calculations.
When it comes to expanding operands, llvm does not have any case defined
for load (because its only operand is a pointer) and it asserts if it
finds out that the pointer of store needs to be expanded...

For all other targets, whatever register is used for pointer, that
register can also be part of a legal operation of its own size.
However, the problem with our target is that it allows only 8 bit
calculations but also provides 16 bit pointers (2 8 bits)

A.

So you have a i16 register class which makes the type legal. You
can
make loads and stores legal (can you?). But you will have to custom
lower all other i16 operations. This will work, but it requires a
lot
of target specific code.

True. If we add the i16 reg class we will need to write a lot of
target specific code.
To avoid that our idea was not to tell the legalizer about the i16
regclass and let it expand everything but ignore the pointers.

You can try just marking all i16 operations, other than load and
store, as "expand". Would that work?

Won't work; LLVM expects at least some basic operations, like add, to
be legal in legal register types.

That sounds like a bug, not a feature.
-Chris

The -enable-legalize-types infrastructure is entirely based upon
getVTAction (), so it will be completely ignored once we have i16
regclass,

I suspected that. But I wonder if that's going to be the approach or is this something we want to change.

ditto with ExpandOp of LegalizeDAG.
And LegalizeDAG::LegalizeOp() allows very few things to be auto expanded.

Really?! ExpandOp handles quite a lot of cases. And you can always add the ones you need. Most of them share the same mechanism (and common code).

Evan

Sure, I understand what you're saying. My point was that features are added to LLVM on demand, and no targets in mainline need the ability to expand pointer operands. Because nothing has needed it, noone has added it.

This doesn't mean that LLVM shouldn't support targets that need this functionality, just that it doesn't yet. I'd really like to see LLVM expand to support these targets in a first-class way without hacks!

-Chris

>>>> You can try just marking all i16 operations, other than load and
>>>> store, as "expand". Would that work?
>>>
>>> Won't work; LLVM expects at least some basic operations, like add,
>>> to
>>> be legal in legal register types.
>>
>> That sounds like a bug, not a feature.
>> -Chris
>
> The -enable-legalize-types infrastructure is entirely based upon
> getVTAction (), so it will be completely ignored once we have i16
> regclass,

I suspected that. But I wonder if that's going to be the approach or
is this something we want to change.

Even after VT is legal, is it possible to check if the target still
wants the result of this operation to be expanded?

>
> ditto with ExpandOp of LegalizeDAG.
> And LegalizeDAG::LegalizeOp() allows very few things to be auto
> expanded.

Really?! ExpandOp handles quite a lot of cases. And you can always add
the ones you need. Most of them share the same mechanism (and common
code).

ExpandOp is called only if getVTAction() returns ::Expand, and also we
have

  assert(getTypeAction(VT) == Expand && "Not an expanded type!");

right in the beginning of the ExpandOp() function.

- Sanjiv

You can try just marking all i16 operations, other than load and
store, as “expand”. Would that work?

Won’t work; LLVM expects at least some basic operations, like add,
to
be legal in legal register types.

That sounds like a bug, not a feature.
-Chris

The -enable-legalize-types infrastructure is entirely based upon
getVTAction (), so it will be completely ignored once we have i16
regclass,

I suspected that. But I wonder if that’s going to be the approach or
is this something we want to change.

Even after VT is legal, is it possible to check if the target still
wants the result of this operation to be expanded?

What I meant is that illegal types are always expanded (based on getVTAction) besides the ones in which target is
interested (based on setOperationAction ). So shouldn’t the type legalizer consider both? Does this make sense?

  • Sanjiv

ditto with ExpandOp of LegalizeDAG.
And LegalizeDAG::LegalizeOp() allows very few things to be auto
expanded.

Really?! ExpandOp handles quite a lot of cases. And you can always add
the ones you need. Most of them share the same mechanism (and common
code).

ExpandOp is called only if getVTAction() returns ::Expand, and also we
have

assert(getTypeAction(VT) == Expand && “Not an expanded type!”);

right in the beginning of the ExpandOp() function.

  • Sanjiv