named types with self-references

Hello,

Can I define a named type ? %rt = {%rt}
llvm-as can parse this definition without errors.

JIT executes '%0 = alloca %rt' as allocating a memory with size 0.
Because the llvm::TargetData::getTypeAllocSize accually returns 0 in
this case. The function that calculates %rt's size is by the
TargetData::getStructLayout, which calculates the a layout of %rt. It
can only returns 0 when the element type %rt is not defined yet, since
the result is infinite otherwise.

Is %rt = {%rt} still a valid or useful type for LLVM IR? %rt = {%rt*},
{ \2 }* or even \1* are definitely good types to represent recursive
data types. In which case do we need %rt = {%rt}?

Thanks

No, that's not (or shouldn't be) a valid type. In this case, zero bytes is correct, but something like %rt = {%rt,i8} has infinite size.

-Chris

Hello,

Can I define a named type ? %rt = {%rt}
llvm-as can parse this definition without errors.

JIT executes '%0 = alloca %rt' as allocating a memory with size 0.
Because the llvm::TargetData::getTypeAllocSize accually returns 0 in
this case. The function that calculates %rt's size is by the
TargetData::getStructLayout, which calculates the a layout of %rt. It
can only returns 0 when the element type %rt is not defined yet, since
the result is infinite otherwise.

Is %rt = {%rt} still a valid or useful type for LLVM IR?

No, that's not (or shouldn't be) a valid type. In this case, zero bytes is correct, but something like %rt = {%rt,i8} has infinite size.

I tried %rt = {%rt,i8}, Its type size is 1. Does ' infinite size' mean
the getTypeAllocSize function may not terminate? I am still using
2.6, whose getStructLayout stops, and assigns 1 as StructSize. Will
2.8 return a larger number?

We could even define
   %rt = {%rt}
   %rt1 = {%rt2}
   %rt2 = {%rt1}
and LLVM can eventually unify all of them to be %rt. If these %rt are
not valid, will any pass of LLVM check and report such types, or this
is supposed to be a requirement of frontends?

I'm sure that TargetData doesn't handle it, because it doesn't make sense. This is equivalent to defining this type in C:

struct foo {
  struct foo a;
  char b;
};

-Chris