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][OpenMP] Implementation of critical directive #675

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

Conversation

eZWALT
Copy link
Contributor

@eZWALT eZWALT commented Jun 10, 2024

This patch aims to implement the critical directive as part of the ongoing development of OpenMP directives inside of CIR. Thanks in advance!

YazZz1k and others added 30 commits January 31, 2024 23:40
Support \_\_extension\_\_ keyword in CIRGen
This PR adds support for section("$name") attribute
Support missing zero initialization of Bools
)

Compiling the given c-code

```
void foo() {
  int      i [2][1] = { { 1 }, { 0 } };
  long int li[2][1] = { { 1 }, { 0 } };
  float    fl[2][1] = { { 1 }, { 0 } };
  double   d [2][1] = { { 1 }, { 0 } };
}
```

leads to compilation error

```
unknown element in ConstArrayAttr
UNREACHABLE executed at /home/huawei/cir/repo/van/llvm-project/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp:951!
```

PR implements conversion the cir.zero attr to dense constant and fixed
this error.
This PR introduces CIR CodeGen support for `dynamic_cast`.

The full feature set of `dynamic_cast` is not fully implemented in this
PR as it's already pretty large. This PR only include support for
downcasting and sidecasting a pointer or reference. `dynamic_cast<void
*>` is not yet implemented.
Initial support for the following builtins:
```
__builtin_expect
__builtin_expect_with_probability
__builtin_unpredictable
```
This PR supports codegen for this builtins on "-O0" compilation
pipeline.
Support for ConditionalOperator inside the if condition stmt
This patch adds CIRGen for downcasting a pointer to the complete object
through `dynamic_cast<void *>`.

Together with llvm#426 , the full functionality of `dynamic_cast` should be
supported in CIRGen after this PR merges.
This PR adds support for constant arrays with trailing zeros.

The original `CodeGen` does the following: once a constant array contain
trailing zeros, a struct with two members is generated: initialized
elements and `zeroinitializer` for the remaining part. And depending on
some conditions, `memset` or `memcpy` are emitted. In the latter case a
global const array is created.
Well, we may go this way, but it requires us to implement
[features](https://github.com/llvm/clangir/blob/main/clang/lib/CIR/CodeGen/CIRGenDecl.cpp#L182)
that are not implemented yet.

Another option is to add one more parameter to the `constArrayAttr` and
utilize it during the lowering. So far I chose this way, but if you have
any doubts, we can discuss here. So we just emit constant array as
usually and once there are trailing zeros, lower this arrray (i.e. an
attribute) as a value.

I added a couple of tests and will add more, once we agree on the
approach. So far I marked the PR as a draft one.
…nters (llvm#400)

This also adds a missing check whether the pointer returned from
`memchr` is null and changes the result to `last` in that case.
Emit the false-branch of the consteval if statement, if any.
Originally, the location associated with a function is checked to be an
`mlir::FileLineColLoc` before the function is lowered to an LLVMIR
FuncOp. However, runtime function declarations do not have such
locations. This patch further allows `mlir::UnknownLoc` to be associated
with a function.
This PR adds a support for const structs with bitfields.
Now only global structs are supported, the support of the local ones can
be added more or less easily - there is one ugly thing need to be done
though)

So .. what is all about.
First of all - as usually, I'm sorry for the big PR. But it's hard to
break it down to peaces. The good news is that in the same time it's a
copy-pasta from the original codegen, no surprises here. Basically, the
most hard place to read is `ConstantAggregateBuilder::addBits` copied
with minimum of changes.

The main problem - and frankly speaking I have no idea why it's done
this way in the original codegen - is that the data layout is different
for such structures, I mean literally another type is used. For
instance, the code:
```
struct T {
  int X : 15;
  int Y : 6;
  unsigned Z : 9;
  int W;
};

struct T GV = { 1, 5, 256, -1};
```
is represented in LLVM IR (with no CIR enabled) as:

```
%struct.T = type { i32, i32 }
%struct.Inner = type { i8, i32 }

@gv = dso_local global { i8, i8, i8, i8, i32 } ...
```
i.e. the global var `GV` is looks like a struct of single bytes (up to
the last field, which is not a btfield).
And my guess is that we want to have the same behavior in CIR. So we do.

The main problem is that we have to treat the same data differently -
and this is why one additional `bitcast` is needed when we create a
global var. Actually, there was a comment there - and I really wonder
where it came from. But anyways, I don't really like this and don't see
any good workaround here. Well, maybe we may add a kind of map in order
to store the correspondence between types and do a bitcast more wisely.
The same is true for the const structs with bitfields defined locally.
The minimal bug repro:
```
#include <stdbool.h>
#include <stdint.h>
void bar() {
  bool x = true;
  uint8_t y = (uint8_t)x;
}
```
Fails on verification stage:
```
loc("repro.c":5:24): error: integer width of the output type is smaller or equal to the integer width of the input type
fatal error: error in backend: The pass manager failed to lower CIR to LLVMIR dialect!
```
The problem is that in some cases lowering from CIR emits the invalid
zext operation. PR fixes this issue by emitting the llvm.bitcast instead
of llvm.zext in such cases.
The change is taken from original codegen.
The issue is that the CIR codegen assumes that function pointer is
always result of cir.load op.
But it isn't true because the funcion pointer may be result of other
operations (f.e cir.call).
This PR adds support for global compound literals.
The implementation is almost the same as in original codegen. But the
original codegen can reuse the value of emitted compound literal global
variable in case then the init expression of new variable and this
variable are the same.
It's easy to implement this feature. But I can't find any test-case then
this feature will be applied. So I decided to ignore this optimization
opportunity to avoid mistakes.
Here is the next step in VLA support.
Basically, these changes handle different expressions, like `int
(*a[5])[n]` or `sizeof(a[n])`.

I took tests from the original `codegen` - they don't check anything,
just verify we don't fail.

There is still an issue with a proper cleanup - there are cases when
`stack_save` doesn't dominate a corresponded `stack_restore`. For
example in the next example:

```
void test(unsigned x) {
  while (1) {
    char a[x];
    if (x > 5)
      break;
      x;
  }
}
```
Look like `break` here doesn't lead to `stack_restore`. But I would say
this is less related to VLA, though probably I need to fix this as well.
This PR fixes the issue connected with folding a simple boolean
expresion pattern (f.e. `0 && RHS = 0`).
The problem is that the scalar expression emitter always creates a
`cir.bool` attribute as a result of expression. But in some cases the
result expression should be a `cir.int` attr.
The change is taken from the original llvm codegen.
Originally those are only used for debug info generation, so get a bit more
specific on what's missing here.
When replacing the no-proto functions with it's real definition, codegen
assumes that only `cir.call` operation may use the replaced function.
Such behaviour leads to compilation error because of the
`cir.get_global` op can also use the function to get pointer to
function.
This PR adds handle the case with `cir.get_global` operation and fixes
the issue.
sitio-couto and others added 27 commits May 30, 2024 16:08
This patch adds a new CallConvLowering pass that aims to lower the
calling conventions of the functions in the module. It also includes a
new Clang command line option to enable it. Also, it is considered a
part of the lowering prepare set of passes, as it is unlikely to be used
elsewhere in the pipeline.

Since this will be dealing with ABI/Target-specific information, it
requires AST info. For this reason, it can only be executed through the
clang driver or cc1 tool for now as CIR does not encode AST info.

This pass is disabled by default and can be enabled by passing the flag
`-fclangir-call-conv-lowering`. Once this pass is more mature, it should
be enabled by default as a required step to lower to LLVM Dialect.
This PR adds the following operations for the builtin binary fp2fp
functions:

  - `cir.copysign` for `__builtin_copysign`;
  - `cir.fmax` for `__builtin_fmax`;
  - `cir.fmin` for `__builtin_fmin`;
  - `cir.fmod` for `__builtin_fmod`;
  - `cir.pow` for `__builtin_pow`.

This PR also includes CIRGen support for these new operations.
…uncOp (llvm#641)

CIRGlobalValueInterface inherits from mlir::Symbol as it should, and
GlobalOp and FuncOp now has interface mlir::Symbol through
CIRGlobalValueInterface

and this PR basically make function isDeclarationForLinker into the
CIRGlobalValueInterface interface. We also change some call sites of
isDeclaration to use CIRGlobalValueInterface when its appropriate.
…#645)

This pr adds cir.bit.clz and cir.bit.ctz lowering to MLIR passes and
test files.
I will complete the lowering of other `cir.bit` operations in subsequent
PRs.
Now that alignment computation is correct for neon, add more neon types
for load/store.
mlir::cir::ZeroInitConstOp was replaced with llvm.mlir.zero

resolves [llvm#627](llvm#627)
Close llvm#633.

This patch introduces `-fclangir-analysis-only` option to allow the
users to consume the AST to the CIR (and potential analysis passes, this
can be done by specifying `-Xclang -fclangir-lifetime-check=""` now or
some default value in following patches) and also generating the LLVM IR
by the traditional code gen path. This will be helpful to use CIR with
real world projects without worrying the correctness and completeness of
CIR CodeGen part.
This pr adds cir.bit.ffs cir.bit.parity cir.bit.clrsb cir.bit.popcount
lowering to MLIR passes and test files.
This PR adds support for  atomic `__sync_fetch_and_add`.

Basically it's a copy-pasta from the original `codegen`.
The only thing that I doubt about is what exact operation I need to
create in CIR. The first approach I used was to create `AtomicRMW`
operation in CIR. But as far as I see I can use the existing
`AtomicFetch` instead. Is it correct? or it's better to add a new op
here?
Moves all feature guarding static methods into a to a single header
file, centralizing the tracking of missing features in a common place
regardless of where it impacts the compilation pipeline. It also moves
the feature guarding logic into CIR's root include folder so that any
CIR library may use it.
Make lowering result of case range smart.

Resolve llvm#632
)

This patch adds LLVM lowering support for unary fp2fp builtins.

Those builtins that should be lowered to runtime function calls are
lowered to such calls during lowering prepare. Other builtins are
lowered to LLVM intrinsic calls during LLVM lowering.
This patch adds a new TargetLowering library that intends to add supoort
for lowering CIR code to target specific CIR code. It is largely based
on the original codegen library used to lower AST nodes to ABI/Target
-specific LLVM IR instructions. Because of this, each file has a comment
specifying the original codegen file that inspired the new file. The
idea is that anyone who wishes to expand this library can look at the
original codegen file to understand how to implement the new feature.

In some cases, CIRGen defers the handling of ABI/target-specific details
for a later stage in the pipeline. One reason for this is to keep the
intermediate representation on a higher-level, which makes it easier to
reason about and to perform optimizations. However, we still need to
lower such representation to a target-specific format at some point.
Some examples are ctor/dtors and calling conventions, which are not
fully handled by CIRGen. The new library will be responsible for these
lowerings.

Some files are empty but will eventually be used and a few getters and
methods where added to avoid unused warnings. Missing features in this
library are tracked in a dedicated MissingFeature.h header.
Resolve llvm#532 .

Support CIRGen of `ExtVectorElementExpr` that includes swizzle `v.xyx`
and subscription `v.s0`.
This reverts commit f4d538f.

It's causing a circular dependency in shared lib builds. See llvm#655
Without this patch, CIR CodeGen continue to generate in the same block
after `cir.break` and `cir.continue`, which would cause verification
error because `cir.break` and `cir.continue` should appear at the end of
blocks.

This patch creates a new dangling block after generating `cir.break` and
`cir.continue` to fix the issue.

This will fix llvm#323.
* New `CastKind::addrspace_cast` for `cir.cast`
* `TargetCIRGenInfo::performAddrSpaceCast` helper for non-constant
values only
* CIRGen for address space casting of pointers and references
* Lowering to LLVM
)

This PR adds support for ` __sync_bool_compare_and_swap` and `
__sync_val_compare_and_swap`.
…f.condition, scf.while (llvm#636)

This pr intruduces CIRConditionLowering and CIRWhileLowering for
lowering to scf.
This pr introduces CIRIfOpLowering for lowering cir.if to scf.if
Assumptions about values having a defining op can be misleading when block
arguments are involved.
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.

None yet