Using frameindex in a pattern

Suppose I have a target that does not have register+constant
addressing mode. Then, I have DAG like:

  (store ..., (frameindex))

Targets like SPARC have the following patterns to catch this:

  def ADDRri : ComplexPattern<i32, 2,
    "SelectADDRri", [frameindex], >;
  def STri : F3_2<3, 0b000100,
                 (outs), (ins MEMri:$addr, IntRegs:$src),
                 "st $src, [$addr]",
                 [(store IntRegs:$src, ADDRri:$addr)]>;

Where ADDRri will eventually turn into register+constant
addressing in assembler.

The IA64 target has explicit case in it's Select method
to handle frameindex -- which is fine, but I though I'd
try a fully declarative method, so I've added to sparc
the following:

   def : Pat<(frameindex simm13:$val), (add G0, simm13:$val)>;

(Ignore bogus G0, and '13' -- just for testing). The error
I get this:

   /home/ghost/Build/llvm/Release/bin/tblgen:
   In anonymous.24: frameindex node requires exactly 0 operands!

Is this really as designed, or nobody got around to making frameindex
have an true operand? Any way to achive frameindex->add translation
using a pattern and not C++ code at all?

- Volodya

Suppose I have a target that does not have register+constant
addressing mode. Then, I have DAG like:

  (store ..., (frameindex))

Targets like SPARC have the following patterns to catch this:

  def ADDRri : ComplexPattern<i32, 2,
    "SelectADDRri", [frameindex], >;
  def STri : F3_2<3, 0b000100,
                (outs), (ins MEMri:$addr, IntRegs:$src),
                "st $src, [$addr]",
                [(store IntRegs:$src, ADDRri:$addr)]>;

Where ADDRri will eventually turn into register+constant
addressing in assembler.

The IA64 target has explicit case in it's Select method
to handle frameindex -- which is fine, but I though I'd
try a fully declarative method, so I've added to sparc
the following:

  def : Pat<(frameindex simm13:$val), (add G0, simm13:$val)>;

(Ignore bogus G0, and '13' -- just for testing). The error
I get this:

  /home/ghost/Build/llvm/Release/bin/tblgen:
  In anonymous.24: frameindex node requires exactly 0 operands!

Is this really as designed, or nobody got around to making frameindex
have an true operand? Any way to achive frameindex->add translation
using a pattern and not C++ code at all?

This is as designed. frameindex node is considered a leaf node. The lowering of frameindex into machine instructions is handled late for many (good) reasons, e.g. allowing coloring of frame slots.

Evan

Evan Cheng wrote:

Suppose I have a target that does not have register+constant
addressing mode. Then, I have DAG like:

(store ..., (frameindex))

Targets like SPARC have the following patterns to catch this:

def ADDRri : ComplexPattern<i32, 2,
"SelectADDRri", [frameindex], >;
def STri : F3_2<3, 0b000100,
                (outs), (ins MEMri:$addr, IntRegs:$src),
                "st $src, [$addr]",
                [(store IntRegs:$src, ADDRri:$addr)]>;

Where ADDRri will eventually turn into register+constant
addressing in assembler.

The IA64 target has explicit case in it's Select method
to handle frameindex -- which is fine, but I though I'd
try a fully declarative method, so I've added to sparc
the following:

  def : Pat<(frameindex simm13:$val), (add G0, simm13:$val)>;

(Ignore bogus G0, and '13' -- just for testing). The error
I get this:

  /home/ghost/Build/llvm/Release/bin/tblgen:
  In anonymous.24: frameindex node requires exactly 0 operands!

Is this really as designed, or nobody got around to making frameindex
have an true operand? Any way to achive frameindex->add translation
using a pattern and not C++ code at all?

This is as designed. frameindex node is considered a leaf node. The
lowering of frameindex into machine instructions is handled late

In other words, frameindex is supposed to be carried over to MachineInstruction
level, and finally removed by eliminateFrameIndex, right? How does this agrees
with the fact that Sparc specially handles frameindex using its ADDRri pattern
(using it in patterns for most load/store instructions). Is this for historic
reasons?

for
many (good) reasons, e.g. allowing coloring of frame slots.

What's that -- google is not helpful. Is this rearrangement of
frame slots of minimize access overhead, or pulling data from frame
slots to registers, or what?

- Volodya

Evan Cheng wrote:

Suppose I have a target that does not have register+constant
addressing mode. Then, I have DAG like:

(store ..., (frameindex))

Targets like SPARC have the following patterns to catch this:

def ADDRri : ComplexPattern<i32, 2,
"SelectADDRri", [frameindex], >;
def STri : F3_2<3, 0b000100,
                (outs), (ins MEMri:$addr, IntRegs:$src),
                "st $src, [$addr]",
                [(store IntRegs:$src, ADDRri:$addr)]>;

Where ADDRri will eventually turn into register+constant
addressing in assembler.

The IA64 target has explicit case in it's Select method
to handle frameindex -- which is fine, but I though I'd
try a fully declarative method, so I've added to sparc
the following:

  def : Pat<(frameindex simm13:$val), (add G0, simm13:$val)>;

(Ignore bogus G0, and '13' -- just for testing). The error
I get this:

  /home/ghost/Build/llvm/Release/bin/tblgen:
  In anonymous.24: frameindex node requires exactly 0 operands!

Is this really as designed, or nobody got around to making frameindex
have an true operand? Any way to achive frameindex->add translation
using a pattern and not C++ code at all?

This is as designed. frameindex node is considered a leaf node. The
lowering of frameindex into machine instructions is handled late

In other words, frameindex is supposed to be carried over to MachineInstruction
level, and finally removed by eliminateFrameIndex, right? How does this agrees
with the fact that Sparc specially handles frameindex using its ADDRri pattern
(using it in patterns for most load/store instructions). Is this for historic
reasons?

ADDRri is a ComplexPattern, used to handle selection of multiple nodes that are too complex for tblgen to handle. It's handled by SelectADDRri(). The function is keeping merely translating it to targetframeindex with an offset 0.

for
many (good) reasons, e.g. allowing coloring of frame slots.

What's that -- google is not helpful. Is this rearrangement of
frame slots of minimize access overhead, or pulling data from frame
slots to registers, or what?

Re-arrangement of frame slots to share physical memory locations to reduces stack size.

Evan