Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

higher level representation for initlist #777

Open
bcardosolopes opened this issue Aug 7, 2024 · 4 comments
Open

higher level representation for initlist #777

bcardosolopes opened this issue Aug 7, 2024 · 4 comments
Labels
enhancement New feature or request good first issue Good for newcomers

Comments

@bcardosolopes
Copy link
Member

It would be nice in the future to have a cir.initlist thing - a higher level representation for this (we even have a specialized AST node). Right now it would be really hard to recognize something came from an initializer list if we lower it this early. LoweringPrepare would then lower to what we currently get as of this PR.

Originally posted by @bcardosolopes in #764 (review)

@bcardosolopes bcardosolopes added the good first issue Good for newcomers label Aug 7, 2024
@HerrCai0907
Copy link
Contributor

HerrCai0907 commented Aug 23, 2024

I want to work for this. Should I start with create a cir.initlist type firstly?

@bcardosolopes
Copy link
Member Author

I want to work for this. Should I start with create a cir.initlist type firstly?

Thanks for your interest. We probably want a cir.initlist operation (not a type).

The first step is to look at the testcases introduced in #764 and propose (with some mocked up CIR example) how that operation would look like - we can discuss it here in this issue.

You can optionally post a draft PR with your initial take so you can play with it a bit, but talking about how it might look like is the more important part for now

@HerrCai0907
Copy link
Contributor

We can create cir.initlist to "store" initExpr to a defined address.

namespace std {
template <class b> class initializer_list {
  const b *array_start;
  const b *array_end;
};
template <class b> void f(initializer_list<b>) { ; }
void test() { f({1, 2, 3, 4, 5}); }
} // namespace std

C++ AST looks like this, which means we construct std::initializer_list with array. And we construct array by cir.initlist

CXXStdInitializerListExpr 0x13f8670d0 'initializer_list<int>':'class std::initializer_list<int>'
`-MaterializeTemporaryExpr 0x13f8670b8 'const int[5]' xvalue
  `-InitListExpr 0x13f867050 'const int[5]'
      %0 = cir.alloca !ty_22std3A3Ainitializer_list3Cint3E22, !cir.ptr<!ty_22std3A3Ainitializer_list3Cint3E22>, ["agg.tmp0"] {alignment = 8 : i64} loc(#loc23)
// allocate tmp array to store initlist.
      %1 = cir.alloca !cir.array<!s32i x 5>, !cir.ptr<!cir.array<!s32i x 5>>, ["ref.tmp0"] {alignment = 4 : i64} loc(#loc23)

// use cir.initlist to initialize tmp array.
      %2 = cir.const #cir.int<1> : !s32i loc(#loc12)
      %3 = cir.const #cir.int<2> : !s32i loc(#loc13)
      %4 = cir.const #cir.int<3> : !s32i loc(#loc14)
      %5 = cir.const #cir.int<4> : !s32i loc(#loc15)
      %6 = cir.const #cir.int<5> : !s32i loc(#loc16)
      cir.initlist(%2, %3, %4, %5, %6 : !s32i, !s32i, !s32i, !s32i, !s32i), %1 : <!cir.array<!s32i x 5>> loc(#loc23)

// prepare std::initializer_list with start and end ptr.
      %7 = cir.get_member %0[0] {name = "array_start"} : !cir.ptr<!ty_22std3A3Ainitializer_list3Cint3E22> -> !cir.ptr<!cir.ptr<!s32i>> loc(#loc17)
      %8 = cir.cast(bitcast, %7 : !cir.ptr<!cir.ptr<!s32i>>), !cir.ptr<!cir.ptr<!cir.array<!s32i x 5>>> loc(#loc17)
      cir.store %1, %8 : !cir.ptr<!cir.array<!s32i x 5>>, !cir.ptr<!cir.ptr<!cir.array<!s32i x 5>>> loc(#loc23)
      %9 = cir.const #cir.int<5> : !u64i loc(#loc23)
      %10 = cir.get_member %0[1] {name = "array_end"} : !cir.ptr<!ty_22std3A3Ainitializer_list3Cint3E22> -> !cir.ptr<!cir.ptr<!s32i>> loc(#loc18)
      %11 = cir.ptr_stride(%1 : !cir.ptr<!cir.array<!s32i x 5>>, %9 : !u64i), !cir.ptr<!cir.array<!s32i x 5>> loc(#loc23)
      %12 = cir.cast(bitcast, %10 : !cir.ptr<!cir.ptr<!s32i>>), !cir.ptr<!cir.ptr<!cir.array<!s32i x 5>>> loc(#loc18)
      cir.store %11, %12 : !cir.ptr<!cir.array<!s32i x 5>>, !cir.ptr<!cir.ptr<!cir.array<!s32i x 5>>> loc(#loc23)

      %13 = cir.load %0 : !cir.ptr<!ty_22std3A3Ainitializer_list3Cint3E22>, !ty_22std3A3Ainitializer_list3Cint3E22 loc(#loc8)
      cir.call @_ZSt1fIiEvSt16initializer_listIT_E(%13) : (!ty_22std3A3Ainitializer_list3Cint3E22) -> () loc(#loc8)

@HerrCai0907
Copy link
Contributor

I am not sure whether we should to use a same instruction to initialize array and struct. Because the input and output will be different. array's initialize list must have a common type but struct don't.

@bcardosolopes bcardosolopes added the enhancement New feature or request label Sep 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

2 participants