-
Notifications
You must be signed in to change notification settings - Fork 103
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
[CIR][CIRGen] Support undefined initialization attribute #628
Conversation
Same rationale as `cir.continue`, it detaches the representation of the C/C++ `break` statement into a separate operation. This simplifies lowering and verifications related to `break` statements, as well as the definition and lowering of the `cir.yield` operation. ghstack-source-id: 929cf96c3abe51d717c2fa6ca9e0073e42e770c6 Pull Request resolved: llvm#395
This changes the `cir.await` operation to expect a `cir.condition` as the terminator for the ready region. This simplifies the `cir.await` while also simplifying the `cir.yield`. If `cir.condition` holds a true value, then the `cir.await` will continue the coroutine, otherwise, it will suspend its execution. The `cir.condition` op was also updated to allow `cir.await` as its parent operation. ghstack-source-id: 1ebeb2cfbdeff6f289936d16354cba534e093ea7 Pull Request resolved: llvm#396
Instead of having a `cir.yield fallthrough` operation, the default branching behavior of the parent operation is denoted by `cir.yield`. In other words, a `cir.yield` operation in a switch case region represents the default branching behavior of the switch operation, which is a fallthrough. The `cir.yield` operation now represents the default branching behavior of the parent operation's region. For example, in a if-else region, a `cir.yield` operation represents a branch to the exit block. ghstack-source-id: 713c457dfb2228fbdf63ba72dd6396665512bb9d Pull Request resolved: llvm#397
…tcase - Add cir.try_call parsing. - Add block destinations and hookup exception info type. - Properly implement interface methods. Printer is still missing, but coming next.
After some discussions with @sitio-couto, it might be better if we use a simplified version that doesn't take the labels into account just yet. `cir.try_call` should have the same semantics as `cir.break`, in the sense that it needs further expansion when getting rid of structured control flow. Early lowering here would complicate CIR generated code and make it harder to analyse. Further CIR to CIR passes will properly expand this at some point prior to LLVM lowering.
We can now handle more of EHScope::Catch and lay out the skeleton for CIR's version of that, adding tons of asserts for cases not currently handled. As part of this we're able to build the clause list as part of CatchOp based on the handlers, and create allocation for the exception_info type. In the next part (where we currently hit an assert) of this work, the CatchOp will then get its regions populated. Incremental steps into getting basic exceptions to work, not enough for a testcase just yet.
Doesn't do a lot of things compared to LLVM traditional codegen, one more step towards basic exception support. No testcase possible just yet.
- Add an extra CatchOp region to hold fallback (where EH usually resumes or rethrows as part of try/catch). - Emit `cir.resume` on the fallback region. Incremental step into the next assertion, still missing pieces before adding the first testcase.
This commit supports the codegen of wide string literals, including `wchar_t` string literals, `char16_t` string literals, and `char32_t` string literals. I'm not following the proposal in llvm#374. The clang frontend doesn't record the literal string. It only records the encoded code units for wide string literals. So I believe that a dedicated string attribute with an encoding tag as described in llvm#374 may not be that helpful as I thought.
This patch introduces initial support for: ``` pragma omp parallel ``` This patch doesn't add support for any of the `parallel` clauses, including variable privatization; thus, all variables are handled as shared. This PR fixes issue llvm#285.
Adds an interface to generically handle lowering and analysis of loop operations in CIR. It can also perform verification of invariants common to all loop operations. ghstack-source-id: 0e413b14ea063a2b0d75aeaca0af88e547c15277 Pull Request resolved: llvm#405
Leverages the new LoopOpInterface for lowering instead of the LoopOp operation. This is a step towards removing the LoopOp operation. ghstack-source-id: 28c1294833a12669d222a293de76609d2cf19148 Pull Request resolved: llvm#406
Creates a separate C/C++ operation for do-while loops, while keeping the LoopOpInterface to generically handle loops. This simplifies the IR generation and printing/parsing of do-while loops. It also allows us to define it regions in the order that they are executed, which is useful for the lifetime analysis. ghstack-source-id: b4d9517197b8f82ae677dc2684101fe5762b21b7 Pull Request resolved: llvm#407
Creates a separate C/C++ operation for while loops, while keeping the LoopOpInterface to generically handle loops. This simplifies the IR generation and printing/parsing of while loops. ghstack-source-id: 29a6d7530263a4f96dbe6ce3052875831126005d Pull Request resolved: llvm#408
This patch completes the deprecation of the generic `cir.loop` operation by adding a new `cir.for` operation and removing the `cir.loop` op. The new representation removes some bloat and places the regions in order of execution. ghstack-source-id: 886e0dacc632e5809015e2212810d690ef3ec294 Pull Request resolved: llvm#409
…rations More machinery for exceptions. This time around we finally emit a cir.catch and fix the order of emitting operations. This allows a testcase to be added. I also added `CatchParamOp`, which fetches the arguments for the clauses from the !cir.eh_info object. Work coming next: - Dtors. - Use cir.try instead of cir.scope. - Eesume. - Documentation.`
This is currently missing and Debug builds are failing without it.
ghstack-source-id: 855519648a4bf2dced501f96e6de1b9b164d85ad Pull Request resolved: llvm#424
ghstack-source-id: 0706d6bb81b5b8eefb04146719b4443aedb29ab1 Pull Request resolved: llvm#427
One more step towards completing try/catch.
…rface This is prep work for introducing cir.try_call inside cir.try scopes.
One more incremental step towards try/catch: properly use cir.try_call instead of regular cir.call when within a cir.try region.
) This patch adds a new `volatile` tag to the following operations to distinguish volatile loads and stores from normal loads and stores: - `cir.load` - `cir.store` - `cir.get_bitfield` - `cir.set_bitfield` Besides, this patch also updates the CodeGen and LLVMIR lowering code to start emitting CIR and LLVMIR operations with volatile flag.
This is part 3 of implementing vector types and vector operations in ClangIR, issue llvm#284. Create new operation `cir.vec.cmp` which implements the relational comparison operators (`== != < > <= >=`) on vector types. A new operation was created rather than reusing `cir.cmp` because the result is a vector of a signed intergral type, not a `bool`. Add CodeGen and Lowering tests for vector comparisons. Fix the floating-point comparison predicate when lowering to LLVM. To handle NaN values correctly, the comparisons need to be ordered rather than unordered. (Except for `!=`, which needs to be unordered.) For example, "ueq" was changed to "oeq".
Compilation of the following test ``` void foo6(A* a1) { A a2 = (*a1); } ``` fails with. ``` NYI UNREACHABLE executed at /home/huawei/cir/repo/llvm-project/clang/lib/CIR/CodeGen/CIRGenExprAgg.cpp:175! ``` Commit adds required visitor and fixes the issue.
In the original codegen a new type is created for the base class, while in CIR we were rewriting the type being processed (due tp misused pointers). This PR fix this, and also makes CIR codegen even with the original one.
This is a first PR for variable length array support. There are one (or more :) ) ahead. Basically, we already did lot's of preliminary job in order to land VLA in CIR in llvm#367 llvm#346 llvm#340. So now we add initial VLA support itself. Most of the changes are taken from the original codegen, so there is nothing to be scary of) I added just one test, and basically that's all we can test right now. Later, I will add more, from the original codegen tests.
There is [a code path](https://github.com/llvm/clangir/blob/3da10fafac66ff125fb59c602e41ad4b4f5cb382/clang/lib/CodeGen/CGExpr.cpp#L2190) missing the counterpart in CIRGen of vector types. When using compound assignments like `a[0] += a[1]`, this code path is activated and end up with NYI.
The constant initialization isn't related to the pointee. We should be able to write #cir.ptr<-1 : i64> : !cir.ptr<whatever>
…pe (llvm#606) This is the prelude of address space support. Linked issue: llvm#418 . - Add the attribute and implement asm format & type conversion. - Make ops like `cir.global` and `cir.get_global` aware of address space, and solve the latter flag. - Relax the restriction of default alloca address space. Then we can use correct address spaces for languages like OpenCL in future.
…ance without thunk (llvm#569) This PR adds Vtable support for C++ multiple inheritance without thunk. This change contains the CIR codegen and lowering work: 1. `VTableAttr` should allow adding multiple `ArrayAttr` for multi-inheritance. 3. `VTableAddrPointOpLowering` has been fixed for the multi-vtable during the MLIR lowering phase. Example: ```c++ class Mother { virtual void MotherFoo() {} virtual void MotherFoo2() {} } class Father { virtual void FatherFoo() {} } class Child : public Mother, public Father { void MotherFoo() override {} } ``` ```mlir cir.global linkonce_odr @_ZTV5Child = #cir.vtable< {#cir.const_array<[ #cir.ptr<null> : #!cir.ptr<!u8i>, #cir.global_view<@_ZTI5Child> : !cir.ptr<!u8i>, #cir.global_view<@_ZN5Child9MotherFooEv> : !cir.ptr<!u8i>, #cir.global_view<@_ZN6Mother10MotherFoo2Ev> : !cir.ptr<!u8i>]> : !cir.array<!cir.ptr<!u8i> x 4>, #cir.const_array<[ #cir.ptr<-8> : !cir.ptr<!u8i>, #cir.global_view<@_ZTI5Child> : !cir.ptr<!u8i>, #cir.global_view<@_ZN6Father9FatherFooEv> : !cir.ptr<!u8i>] > : !cir.array<!cir.ptr<!u8i> x 3>}> : !ty_anon_struct3 ```
Move it up for visibility, just like the other dialect headers.
Just mimic the table approach from OG codegen, there are thousands of these, it's massive! This doesn't add any new feature yet, continues asserting as before. Coming next: the plan is to reuse the tablegen generated LLVM intrinsics, and pass that down to LLVM lowering.
The alignment is still super conversative but proper support should come next. The added test file also contains a huge pile of builtins we need to support and should allow for incremental support here. Next steps: fix alignement and enable testing for other vld1/vst1 variants.
In this PR I added the support for structural bindings in CIR codegen, to reason `DecompositionDecl` and `BindDecl` properly. Note that since `ArrayInitLoopExpr` is not implemented so binding to arrays is not supported yet.
This commit introduces CIRForOpLowering for lowering to scf. The initial commit only support increment loop with lt or le comparison.
This PR fixes a fail on `llvm_unreachable` for the next case: ``` volatile A vol_a; A foo7() { return vol_a; } ``` Basically, it's just a copy-pasta from the original `code-gen`. Also, I added the `isVolatile` attribute for the `cit.copy` operation
This PR fixes the next bug showed in the example below: ``` typedef int (*fn_t)(); int get42() { return 42; } void foo() { fn_t f = get42; } ``` The function type `fn_t` is generated as the variadic one due to no arg types listed, this is the `codegen` feature. And once we store the function pointer to a real function - a pointer to `get42` here has the expected `i32 ()*` type - we get a verification error, so `bitcast` is needed. The original `codegen` doesn't have it because of opaque pointers used, and had the `bitcast` earlier, long time ago: ``` %f = alloca i32 (...)* store i32 (...)* bitcast (i32 ()* @GET42 to i32 (...)*), i32 (...)** %f ```
This commit introduces SCFPreparePass to 1) Canonicalize IV to LHS of loop comparison For example, transfer `cir.cmp(gt, %bound, %IV)` to `cir.cmp(lt, %IV, %bound)`. So we could use RHS as boundary and use `lt` to determine it's an upper bound. 2) Hoist loop invariant operations in condition block out of loop. The condition block may be generated as following which contains the operations produced upper bound. SCF for loop required loop boundary as input operands. So we might need to hoist the boundary operations out of loop. ``` cir.for : cond { %4 = cir.load %2 : !cir.ptr<!s32i>, !s32i %5 = cir.const #cir.int<100> : !s32i <- upper bound %6 = cir.cmp(lt, %4, %5) : !s32i, !s32i %7 = cir.cast(int_to_bool, %6 : !s32i), !cir.boo cir.condition(%7 } body { ```
Don't hook this up with CIRGen just yet. While here update parsing tests to include `atomic(seq_cst)`.
Load coming next.
…lvm#617) The patch resolves [issue llvm#248](llvm#248). It can be considered a subsequent patch to [llvm#373](llvm#373), where the case of empty strings was processed. The new patch adds processing for non-empty strings that may contain trailing zeros, such as: ``` char big_string[100000] = "123"; ``` That is converted to ``` @big_string = #cir.const_array<"123" : !cir.array<!s8i x 3>, trailing_zeros> : !cir.array<!s8i x 100000> ```
Thanks for the PR, how's is this different from a global without initializers? Seems like the same functionality to me. |
@@ -471,7 +471,7 @@ CIRGenModule::getOrCreateStaticVarDecl(const VarDecl &D, | |||
mlir::Attribute Init = nullptr; | |||
if (Ty.getAddressSpace() == LangAS::opencl_local || | |||
D.hasAttr<CUDASharedAttr>() || D.hasAttr<LoaderUninitializedAttr>()) | |||
llvm_unreachable("OpenCL & CUDA are NYI"); | |||
Init = builder.getUndefAttr(getTypes().ConvertType(Ty)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bcardosolopes I see. On LLVM side, ppl used something like this to setup the __shared__
variables. For the same purpose, can we simply remove this llvm_unreachable
and also remove the line that setting the initializer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That sounds good. Please also add a C/C++ source code test that goes all the way down to LLVM, there are other examples you can look (e.g. clang/test/CIR/CodeGen/atomic.cpp
)
@@ -471,7 +471,7 @@ CIRGenModule::getOrCreateStaticVarDecl(const VarDecl &D, | |||
mlir::Attribute Init = nullptr; | |||
if (Ty.getAddressSpace() == LangAS::opencl_local || | |||
D.hasAttr<CUDASharedAttr>() || D.hasAttr<LoaderUninitializedAttr>()) | |||
llvm_unreachable("OpenCL & CUDA are NYI"); | |||
Init = builder.getUndefAttr(getTypes().ConvertType(Ty)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That sounds good. Please also add a C/C++ source code test that goes all the way down to LLVM, there are other examples you can look (e.g. clang/test/CIR/CodeGen/atomic.cpp
)
Btw, it's possible we might need an undef attribute someday, but up to now we should be good without one! |
@SchrodingerZhu do you plan to resume the work for this PR or should I close for the moment? |
I may not be able to continue on this for now due to conflict. Please close this for now. Thanks! |
This PR adds the capability to initialize
Global
s with undefined values.