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

[CIR][CIRGen] Support CodeGen for vbase constructors #624

Open
wants to merge 1,567 commits into
base: main
Choose a base branch
from

Conversation

Laity000
Copy link
Contributor

@Laity000 Laity000 commented May 22, 2024

  1. Add new cir.vtt.address_point op for visiting the element of VTT to initialize the virtual pointer.
  2. Implement getVirtualBaseClassOffset method which provides a virtual offset to adjust to the actual virtual pointer in virtual base.
  3. Follow the original clang CodeGen scheme for the implementation of most other parts.

bcardosolopes and others added 30 commits January 10, 2024 17:13
….scope

Incremental work, test coming soon. This code path isn't exercised just yet.
Silly mistake introduced in previous commit.
This will be used for any calls happening inside try regions.

More refactoring. For now it's incremental work, still some mileage to cover
before I can introduce a testcase. The current implementation mimics cir.call,
pieces are going to change in following commits.
The next step for inline assembly. Sorry, maybe it looks too big on the
first glance. And it's kind of hard to extract something well-grained
from the code and introduce it as a separate PR, but I try.

Actually there is nothing really interesting done here, and the next
will (I hope :) ) simplify your review process.

1) In this PR we introduce operand's constraints and the task is to
collect them (and maybe transform a little)
2) There are two big functions copy-pasted from the traditional
`Codegen` and I doubt they need to be reviewed.
3) We still don't do anything CIR-specific. Basically, we just work with
strings in the same way like traditional `Codegen` does.
4) We just iterate over the input and output operands and collect the
constraints
5) We still follow to the traditional `CodeGen` and don't do anything
new, except a separate function that collects constraints infos in the
very beginning of the `buildStmt`.

Also, I renamed `AsmDialect` to `AsmFlavor` as you asked in llvm#326
This PR fixes CIR lowering for the next case.

```
void foo() {
    struct {
        int a;
        int b;
    } a[1] = {{0,1}};
}
```
Note, we don't create attribute here and lower such const arrays as
values.
When introducing attribute `#cir.int`, the constant type verification is
not updated. If a `cir.const` operation produces an integral constant
from a `#cir.int` attribute, the integer's type is not verified:

```mlir
%1 = cir.const(#cir.int<0> : !cir.int<s, 8>) : !cir.int<u, 8>
// Not verified: !cir.int<s, 8> differs from !cir.int<u, 8>
```

The corresponding test is also wrong but fail to be detected.

This patch fixes this issue.
This is part 2 of implementing vector types and vector operations in
ClangIR, issue llvm#284.

Create new operation `cir.vec.insert`, which changes one element of an
existing vector object and returns the modified vector object. The input
and output vectors are prvalues; this operation does not touch memory.
The assembly format and the order of the arguments match that of
llvm.insertelement in the LLVM dialect, since the operations have
identical semantics.

Implement vector element lvalues in class `LValue`, adding member
functions `getVectorAddress()`, `getVectorPointer()`, `getVectorIdx()`,
and `MakeVectorElt(...)`.

The assembly format for operation `cir.vec.extract` was changed to match
that of llvm.extractelement in the LLVM dialect, since the operations
have identical semantics.

These two features, `cir.vec.insert` and vector element lvalues, are
used to implement `v[n] = e`, where `v` is a vector. This is a little
tricky, because `v[n]` isn't really an lvalue, as its address cannot be
taken. The only place it can be used as an lvalue is on the left-hand
side of an assignment.

Implement unary operators on vector objects (except for logical not on a
vector mask, which will be covered in a future commit for boolean
vectors). The code for lowering cir.unary for all types, in
`CIRUnaryOpLowering::matchAndRewrite`, was largely rewritten. Support
for unary `+` on non-vector pointer types was added. (It was already
supported and tested in AST->ClangIR CodeGen, but was missing from
ClangIR->LLVM Dialect lowering.)

Add tests for all binary vector arithmetic operations other than
relational operators and shift operators. There were all working after
the previous vector types commit, but only addition had beet tested at
the time.

Co-authored-by: Bruno Cardoso Lopes <[email protected]>
Detaches the representation of the C/C++ `continue` statement into a
separate operation. This simplifies mostly lowering and verifications
related to `continue` statements, as well as the definition and lowering
of the `cir.yield` operation.

A few checks regarding region terminators were also removed from the
lowering stage, since they are already enforced by MLIR.

ghstack-source-id: 1810a48ada88fe7ef5638b0758a2298d9cfbdb8b
Pull Request resolved: llvm#394
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.`
bcardosolopes and others added 16 commits May 9, 2024 15:33
…m#594)

Same as void pointers `void *`, we treat function pointer arithmetic as
`GEP i8`, according to the original behavior of clang
([godbolt](https://godbolt.org/z/EMdvfdTe7)).
This PR adds two new CIR floating-point types, namely `!cir.f16` and
`!cir.bf16`, to represent the float16 format and bfloat format,
respectively.

This PR converts the clang extension type `_Float16` to `!cir.f16`, and
converts the clang extension type `__bf16` type to `!cir.bf16`. The type
conversion for clang extension type `__fp16` is not included in this PR
since it requires additional work during CIRGen.

Only CIRGen is implemented here, LLVMIR lowering / MLIR lowering should
come next.
The empty file `clang/asf` was introduced in
e7e05a8. It looks like an accident.
In this PR, we support for dereferencing void pointers as a GNU C
extension. This include two modification:
- In CIRGen, we support to build ReturnStmt with void return type.
- In LowerToLLVM, we support to lower CIR load with void result type to
LLVM.

It's a part of llvm#579, since I would
like to split it to two tasks:
- support pointer arithmetic for function types (llvm#594)
- **support to dereference void pointer (this PR)**
This patch ensures that only the pretty-print version of function param
and result attributes is printed. The tailing dictionary attributes are
no longer printed.

It also ensures some FuncOp tests are properly validating both parsing
and printing.
…ue (llvm#608)

Seems the FIXME has been solved since I've confirmed that these CHECK
can pass now.

Remove the FIXME and recover these CHECK.
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.
1. Add new `cir.vtt.address_point` op for visiting the element of VTT to initialize the virtual pointer.
2. Implement `getVirtualBaseClassOffset` method which provides a virtual offset to adjust to actual virtual pointers in virtual base.
3. Follows the original clang CodeGen scheme for the implementation of most other parts.
@Laity000 Laity000 changed the title [CIR][CodeGen] Support CodeGen for vbase constructors [CIR][CIRGen] Support CodeGen for vbase constructors May 25, 2024
@Laity000
Copy link
Contributor Author

Laity000 commented Jun 5, 2024

Could you review this PR when you have some free time? @bcardosolopes

@bcardosolopes
Copy link
Member

Looking at it this week! Thanks

@bcardosolopes
Copy link
Member

@Laity000, one thing you'd need to add: "LLVM" checks as part of the testcase, you can see examples in some other tests (e.g. clang/test/CIR/CodeGen/abstract-cond.c).

We also just rebased against upstream, you need to update the PR too!

@bcardosolopes
Copy link
Member

ping :)

smeenai added a commit to smeenai/clangir that referenced this pull request Sep 4, 2024
This is a straightforward adaption from CodeGen. I checked the uses of
the Delegating arg that's passed in various places, and it only appears
to be used by virtual inheritance, which should be handled by
llvm#624.
@bcardosolopes
Copy link
Member

@smeenai if you want to take this over, you can cherry-pick @Laity000 commit and add any necessary fix on top

bcardosolopes pushed a commit that referenced this pull request Sep 9, 2024
This is a straightforward adaption from CodeGen. I checked the uses of
the Delegating arg that's passed in various places, and it only appears
to be used by virtual inheritance, which should be handled by
#624.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.