No more TargetFlags on MO_Register MachineOperands

All,

The code generator operand class, MachineOperand, has an 8-bit TargetFlags field that the individual targets can use as they please. X86 and ARM use it to encode linker magic on symbol operands.

It has been mentioned a couple of times on this list that it is not safe to use TargetFlags on register operands. This is because many target-independent passes are manipulating register operands when the code is in SSA form, and they can't always preserve flags they don't understand.

I am going to add an assertion that no target flags are added to register operands. This will prevent subtle bugs when flags disappear, and it will free up some space in the MachineOperand struct layout.

None of the in-tree targets need this, external targets should probably be using extra immediate operands to encode register flags.

/jakob

All,

The code generator operand class, MachineOperand, has an 8-bit TargetFlags field that the individual targets can use as they please. X86 and ARM use it to encode linker magic on symbol operands.

It has been mentioned a couple of times on this list that it is not safe to use TargetFlags on register operands. This is because many target-independent passes are manipulating register operands when the code is in SSA form, and they can't always preserve flags they don't understand.

I am going to add an assertion that no target flags are added to register operands. This will prevent subtle bugs when flags disappear, and it will free up some space in the MachineOperand struct layout.

None of the in-tree targets need this, external targets should probably be using extra immediate operands to encode register flags.

Hi,

I've been working on replacing the MachineOperand flags in the R600
backend with immediate operands, but I can't figure out how to modify
the instruction patterns to make this work. For example, I have the class:

class R600_1OP <bits<32> inst, string opName, list<dag> pattern,
                InstrItinClass itin = AnyALU> :
  InstR600 <inst,
          (outs R600_Reg32:$dst),
          (ins R600_Reg32:$src, R600_Pred:$p, i32imm:$flags),
          !strconcat(opName, " $dst, $src ($p)"),
          pattern,
          itin
  >;

And an instruction def:

def CEIL : R600_1OP <
  0x12, "CEIL",
  [(set R600_Reg32:$dst, (fceil R600_Reg32:$src))]

;

Tablegen fails to compile this with an error: "Operand $flag does not
appear in the instruction pattern"

Is there some way I can have this pattern initialize the $flag operand
to 0?

Thanks,
Tom

Tom,

From: llvmdev-bounces@cs.uiuc.edu [mailto:llvmdev-bounces@cs.uiuc.edu]
On Behalf Of Owen Anderson
Sent: Tuesday, August 21, 2012 11:37 AM
To: Stellard, Thomas
Cc: llvmdev@cs.illinois.edu
Subject: Re: [LLVMdev] No more TargetFlags on MO_Register
MachineOperands

Tom,

> I've been working on replacing the MachineOperand flags in the R600
> backend with immediate operands, but I can't figure out how to modify
> the instruction patterns to make this work. For example, I have the
class:
>
> class R600_1OP <bits<32> inst, string opName, list<dag> pattern,
> InstrItinClass itin = AnyALU> :
> InstR600 <inst,
> (outs R600_Reg32:$dst),
> (ins R600_Reg32:$src, R600_Pred:$p, i32imm:$flags),
> !strconcat(opName, " $dst, $src ($p)"),
> pattern,
> itin
>> ;
>
> And an instruction def:
>
> def CEIL : R600_1OP <
> 0x12, "CEIL",
> [(set R600_Reg32:$dst, (fceil R600_Reg32:$src))]
>> ;
>
> Tablegen fails to compile this with an error: "Operand $flag does not
> appear in the instruction pattern"
>
> Is there some way I can have this pattern initialize the $flag
operand
> to 0?

The generally accepted way of achieving this is to leave the built-in
pattern on the instruction empty, and to use def : Pat constructs to
provide the default values.

def : Pat<(fceil R600_Reg32:$src), (CEIL R600_Reg32:$src, (i32 0))>;

[Villmow, Micah] Doing this for every instruction is unrealistic.

Not particularly. There are backends already in existence that make heavy use of it. The key is that def : Pat constructs can take advantage of all of the same mechanisms for factoring out commonality that normal patterns can, including multiclasses and ComplexOperands.

--Owen

>
>
>> From: llvmdev-bounces@cs.uiuc.edu [mailto:llvmdev-bounces@cs.uiuc.edu]
>> On Behalf Of Owen Anderson
>> Sent: Tuesday, August 21, 2012 11:37 AM
>> To: Stellard, Thomas
>> Cc: llvmdev@cs.illinois.edu
>> Subject: Re: [LLVMdev] No more TargetFlags on MO_Register
>> MachineOperands
>>
>> Tom,
>>
>> The generally accepted way of achieving this is to leave the built-in
>> pattern on the instruction empty, and to use def : Pat constructs to
>> provide the default values.
>>
>> def : Pat<(fceil R600_Reg32:$src), (CEIL R600_Reg32:$src, (i32 0))>;
>>
> [Villmow, Micah] Doing this for every instruction is unrealistic.

Not particularly. There are backends already in existence that make heavy use of it. The key is that def : Pat constructs can take advantage of all of the same mechanisms for factoring out commonality that normal patterns can, including multiclasses and ComplexOperands.

Would it work to add a new Operand subclass to tablegen called
InstrFlagOperand (or something similar) that had a DefaultOps member, like
PreidcateOperand and OptionalDefOperand?

-Tom

From: Owen Anderson [mailto:resistor@mac.com]
Sent: Wednesday, August 22, 2012 11:41 AM
To: Villmow, Micah
Cc: Stellard, Thomas; llvmdev@cs.illinois.edu
Subject: Re: [LLVMdev] No more TargetFlags on MO_Register
MachineOperands

>
>
>> From: llvmdev-bounces@cs.uiuc.edu [mailto:llvmdev-
bounces@cs.uiuc.edu]
>> On Behalf Of Owen Anderson
>> Sent: Tuesday, August 21, 2012 11:37 AM
>> To: Stellard, Thomas
>> Cc: llvmdev@cs.illinois.edu
>> Subject: Re: [LLVMdev] No more TargetFlags on MO_Register
>> MachineOperands
>>
>> Tom,
>>
>> The generally accepted way of achieving this is to leave the built-
in
>> pattern on the instruction empty, and to use def : Pat constructs to
>> provide the default values.
>>
>> def : Pat<(fceil R600_Reg32:$src), (CEIL R600_Reg32:$src, (i32 0))>;
>>
> [Villmow, Micah] Doing this for every instruction is unrealistic.

Not particularly. There are backends already in existence that make
heavy use of it. The key is that def : Pat constructs can take
advantage of all of the same mechanisms for factoring out commonality
that normal patterns can, including multiclasses and ComplexOperands.

[Villmow, Micah] Can you provide example of it having to occur everywhere? The instruction enum list for my backend 6867 enums long and growing. Now the proposed solution is I have to write a pattern/duplicate every single instruction so I can add a literal operand for every register operand and an extra for every instruction. Instead of just providing 8-16 bits of information that the backend can do whatever it wants with, which seems like a much cleaner and simpler solution.

One way around this is to use a ComplexOperand to represent the combination of the register+immediate. A ComplexOperand is selected via a C++ callback, which has the liberty of doing things like providing a default value for any of its subcomponents.

Tom's idea regarding adding a new tblgen construct for a default-valued immediate is also interesting, though it might be tricky to get it to interact properly with things like the AsmParser.

--Owen