Skip to content

Conversation

@philnik777
Copy link
Contributor

No description provided.

sitio-couto and others added 30 commits January 28, 2024 20:44
Lowers the particular case where an array of structs is constant-initialized.

ghstack-source-id: f8389d8
Pull Request resolved: llvm#202
Updates the lowering of cir.const to support #cir.const_struct as a
initializer, allowing the initialization of local structs with said
attribute.

ghstack-source-id: cc6c137
Pull Request resolved: llvm#203
Global addresses are constant, so we can initialize them at compile time
using CIR's global_view attribute. This patch adds codegen support for
the initialization of variables with constant global addresses.

Since a builder method was added for global_view, the patch also updates
the codegen of global variables to use it wherever possible.

ghstack-source-id: 513365c
Pull Request resolved: llvm#204
Adds lowering logic for CIR's global_view attributes with no indexes.
This is done by converting the global to a region-initialized LLVM
global operation, where the region returns the address of the global
used in the gloval_view initializer attribute.

ghstack-source-id: a9452ed
Pull Request resolved: llvm#205
Constant initialization of static local arrays would fail due to a
mismatch between the variable and the initializer type size. This patch
fixes the data layout interface implementation for the cir.array type.

A complete array in C/C++ should have its type size in bits equal to
the size of the array times the size of the element type.

ghstack-source-id: 56f3f29
Pull Request resolved: llvm#206
PR llvm#200 broke the vtableAttr usage, as it was not properly refactored
to use ArrayAttr instead of ConstStructAttr to store its members.
This change does the CIR generation for globals initialized by a
constructor call. It currently only covers C++ to CIR generation. The
corresponding LLVM lowering will be in a follow-up commit.

A motivating example is

```
class Init {
  friend class ios_base;

public:
  Init(bool);
  ~Init();

private:
  static bool _S_synced_with_stdio;
};

static Init ioinit(true);
```

Unlike what the default Clang codegen generates LLVM that detaches the
initialization code from the global var definition (like below), we are
taking a different approach that keeps them together, which we think
will make the later dataflow analysis/transform easier.

```
@_ZL8ioinit = internal global %class.Init zeroinitializer, align 1, !dbg !0

define internal void @cxx_global_var_init() #0 section ".text.startup" !dbg !23 {
entry:
  call void @_ZN4InitC2Ev(ptr noundef nonnull align 1 dereferenceable(1) @_ZL8ioinit), !dbg !27
  %0 = call i32 @cxa_atexit(ptr @_ZN4InitD1Ev, ptr @_ZL8ioinit, ptr @dso_handle) llvm#3, !dbg !29
  ret void, !dbg !27
}
```

So on CIR, we have something like:

```
  cir.global "private" internal @_ZL8__ioinit = ctor : !ty_22class2EInit22 {
    %0 = cir.get_global @_ZL8__ioinit : cir.ptr <!ty_22class2EInit22> loc(#loc8)
    %1 = cir.const(#true) : !cir.bool loc(#loc5)
    cir.call @_ZN4InitC1Eb(%0, %1) : (!cir.ptr<!ty_22class2EInit22>, !cir.bool) -> () loc(#loc6)
}
```

The destructor support will also be in a separate change.
This PR fixes lowering for `break/continue`  in loops.
The idea is to replace `cir.yield break` and `cir.yield continue` with
the branch operations to the corresponding blocks. Note, that we need to
ignore nesting loops and don't touch `break` in switch operations. Also,
`yield` from `if` need to be considered only when it's not the loop
`yield` and `continue` in switch is ignored since it's processed in the
loops lowering.

Fixes llvm#160
Essentially emits an LValue for the struct and then passes it as a call
argument.
Enabling IR printing with --mlir-print-ir-after=passName1, passName2.
This requires all CIR passes to be registered at startup time.
Summary:
Setting the Optnone attribute for CIR functions and progating it all the
way down to LLVM IR for those not supposed to be optimized.
…zers (llvm#235)

As a follow up to llvm#197, this change
pre-lowers high-level CIR for global initializers.

High-level CIR:

```
  cir.global "private" internal @_ZL8__ioinit = ctor : !ty_22class2EInit22 {
    %0 = cir.get_global @_ZL8__ioinit : cir.ptr <!ty_22class2EInit22> loc(#loc8)
    %1 = cir.const(#true) : !cir.bool loc(#loc5)
    cir.call @_ZN4InitC1Eb(%0, %1) : (!cir.ptr<!ty_22class2EInit22>, !cir.bool) -> () loc(#loc6)
 }
```

After pre-lowering:

```
   cir.global "private" internal @_ZL8__ioinit =  #cir.zero : !ty_22class2EInit22 {ast = #cir.vardecl.ast}

   cir.func internal private @__cxx_global_var_init() {
     %0 = cir.get_global @_ZL8__ioinit : cir.ptr <!ty_22class2EInit22>
     %1 = cir.const(#true) : !cir.bool
     cir.call @_ZN4InitC1Eb(%0, %1) : (!cir.ptr<!ty_22class2EInit22>, !cir.bool) -> ()
     cir.return
  }

   cir.func private @_GLOBAL__sub_I_static.cpp() {
     cir.call @__cxx_global_var_init() : () -> ()
     cir.return
  }
```


There is still work to be done to fully lower to LLVM. E.g, add
`llvm.global_ctors` global to list all module initializers like
`_GLOBAL__sub_I_static`. This will be handled in a separate change.
cir-tidy has been our custom hack for using clang-tidy. There's no reason it
needs to be that way - add a CIRModule to clang-tidy and make the lifetime
checker its first check. Some of the way this was built was inspired in
CLANG_TIDY_ENABLE_STATIC_ANALYZER

Once we can fully migrate deps from cir-tidy, we should remove it in favor of
this.
…s::options

This unbreaks Linux builds, which points to cycles while using utils::options
from ClangTidy.cpp. We need to find a better way to convey this.
This PR fixes CIR generation for the `switch-case` cases like the
following:
```
case 'a':
default:
 ...
```
or
```
default:
case 'a':
...
```
i.e. when the `default` clause is sub-statement of the `case` one and
vice versa.
Whenever a global array is declared and initialized with fewer elements
than its size, the remaining elements are implicitly initialized with
zero. For aggregates types, such as structs, the initialization is done
through the #cir.zero attribute.

ghstack-source-id: b3d172c
Pull Request resolved: llvm#216
This small improvement allows for a more compact representation of
structs with zero-initialized fields in the C++ codegen.

ghstack-source-id: a3fe0dc
Pull Request resolved: llvm#217
Due to the lack of zeroinitializer support in LLVM, some cases are
tricky to lower #cir.zero. An example is when an array is only partially
initialize with #cir.zero attributes. Since we can't just zeroinitialize
the whole array, the current #cir.zero attribute amend does not suffice.
To simplify the lowering, this patch introduces a new operation that is
solely used to generate zeroinitialize LLVM IR constants.

ghstack-source-id: a3fd40e
Pull Request resolved: llvm#218
Supports lowering for #cir.zero attributes when it appears in aggregate
attributes such as #const.array and #cir.struct.

ghstack-source-id: d26a506
Pull Request resolved: llvm#219
@philnik777 philnik777 changed the title [CIR][Lowering] Add the concept of simple lowering and useit to implement FP intrincis [CIR][Lowering] Add the concept of simple lowering and use it to implement FP intrincis Feb 20, 2024
@Lancern
Copy link
Member

Lancern commented Mar 6, 2024

This is an awesome feature! This is not a blocker for the PR, just some ideas for further development. This feature may be generalized in the future to declare lowering rules more flexibly. Consider the cir.bit family of operations, which has an LLVMIR lowering scheme like the following:

%1 = cir.bit.clz(%0 : !u32i) : !s32i
// %1 = llvm.call_intrinsic "llvm.ctlz.i32"(%0 : i32) : i32 -> i32

%2 = cir.bit.ctz(%0 : !u32i) : !s32i
// %2 = llvm.call_intrinsic "llvm.cttz.i32"(%0 : i32) : i32 -> i32

%3 = cir.bit.popcount(%0 : !u32i) : !s32i
// %3 = llvm.call_intrinsic "llvm.ctpop.i32"(%0 : i32) : i32 -> i32

Basically all cir.bit.* operation will be lowered to an llvm.call_intrinsic operation whose intrin parameter is determined by the CIR operation type.

Stuff in this PR cannot be used to achieve the lowering scheme above because we cannot specify the parameters to the LLVMIR operations. It would be nice if this is added in the future; it would be very useful for lowering compiler intrinsics as shown above.

@bcardosolopes
Copy link
Member

Good point @Lancern, we can definitely extend the mechanism later to also support things that get lowered to llvm.call_intrinsic.

@Lancern
Copy link
Member

Lancern commented Aug 23, 2024

Any progress on this PR?

@bcardosolopes
Copy link
Member

bcardosolopes commented Aug 23, 2024

@philnik777 is probably busy with libc++ work.

@Lancern if you are interested in making progress here, my suggestion:

  1. Cherry-pick his work locally (so as to preserve original authorship) and fix some of the conflicts.
  2. Add your changes on top + previous reviewer feedback.
  3. Take over this PR (assuming that's possible)

I'll then land without squashing so that we can preserve your work and his (assuming we get a final total of 2 commits, his + yours).

@philnik777
Copy link
Contributor Author

Sorry for dropping this. I completely forgot that I had a patch open here. @Lancern if you want to, feel free to take the patch and just add a Co-authored-by: Nikolas Klauser <nikolasklauser@berlin.de> in the commit message.

@Lancern
Copy link
Member

Lancern commented Aug 24, 2024

Let me work on this PR.

@bcardosolopes
Copy link
Member

@philnik777 np, thanks for the clangir contribs so far!

@bcardosolopes
Copy link
Member

This is now tracked in #806, closing

bcardosolopes pushed a commit that referenced this pull request Aug 27, 2024
…ry fp2fp operations (#806)

This PR is the continuation and refinement of PR #434 which is
originally authored by @philnik777 . Does not update it in-place since I
don't have commit access to Nikolas' repo.

This PR basically just rebases #434 onto the latest `main`. I also
updated some naming used in the original PR to keep naming styles
consistent.

Co-authored-by: Nikolas Klauser <nikolasklauser@berlin.de>
Hugobros3 pushed a commit to shady-gang/clangir that referenced this pull request Oct 2, 2024
…ry fp2fp operations (llvm#806)

This PR is the continuation and refinement of PR llvm#434 which is
originally authored by @philnik777 . Does not update it in-place since I
don't have commit access to Nikolas' repo.

This PR basically just rebases llvm#434 onto the latest `main`. I also
updated some naming used in the original PR to keep naming styles
consistent.

Co-authored-by: Nikolas Klauser <nikolasklauser@berlin.de>
smeenai pushed a commit to smeenai/clangir that referenced this pull request Oct 9, 2024
…ry fp2fp operations (llvm#806)

This PR is the continuation and refinement of PR llvm#434 which is
originally authored by @philnik777 . Does not update it in-place since I
don't have commit access to Nikolas' repo.

This PR basically just rebases llvm#434 onto the latest `main`. I also
updated some naming used in the original PR to keep naming styles
consistent.

Co-authored-by: Nikolas Klauser <nikolasklauser@berlin.de>
smeenai pushed a commit to smeenai/clangir that referenced this pull request Oct 9, 2024
…ry fp2fp operations (llvm#806)

This PR is the continuation and refinement of PR llvm#434 which is
originally authored by @philnik777 . Does not update it in-place since I
don't have commit access to Nikolas' repo.

This PR basically just rebases llvm#434 onto the latest `main`. I also
updated some naming used in the original PR to keep naming styles
consistent.

Co-authored-by: Nikolas Klauser <nikolasklauser@berlin.de>
keryell pushed a commit to keryell/clangir that referenced this pull request Oct 19, 2024
…ry fp2fp operations (llvm#806)

This PR is the continuation and refinement of PR llvm#434 which is
originally authored by @philnik777 . Does not update it in-place since I
don't have commit access to Nikolas' repo.

This PR basically just rebases llvm#434 onto the latest `main`. I also
updated some naming used in the original PR to keep naming styles
consistent.

Co-authored-by: Nikolas Klauser <nikolasklauser@berlin.de>
lanza pushed a commit that referenced this pull request Nov 5, 2024
…ry fp2fp operations (#806)

This PR is the continuation and refinement of PR #434 which is
originally authored by @philnik777 . Does not update it in-place since I
don't have commit access to Nikolas' repo.

This PR basically just rebases #434 onto the latest `main`. I also
updated some naming used in the original PR to keep naming styles
consistent.

Co-authored-by: Nikolas Klauser <nikolasklauser@berlin.de>
lanza pushed a commit that referenced this pull request Mar 18, 2025
…ry fp2fp operations (#806)

This PR is the continuation and refinement of PR #434 which is
originally authored by @philnik777 . Does not update it in-place since I
don't have commit access to Nikolas' repo.

This PR basically just rebases #434 onto the latest `main`. I also
updated some naming used in the original PR to keep naming styles
consistent.

Co-authored-by: Nikolas Klauser <nikolasklauser@berlin.de>
terapines-osc-cir pushed a commit to Terapines/clangir that referenced this pull request Sep 2, 2025
…ry fp2fp operations (llvm#806)

This PR is the continuation and refinement of PR llvm#434 which is
originally authored by @philnik777 . Does not update it in-place since I
don't have commit access to Nikolas' repo.

This PR basically just rebases llvm#434 onto the latest `main`. I also
updated some naming used in the original PR to keep naming styles
consistent.

Co-authored-by: Nikolas Klauser <nikolasklauser@berlin.de>
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.