…ted. (#89998)" (#90250)
This partially reverts commit 7aedd7dc75.
This change removes calls to the deprecated member functions. It does
not mark the functions deprecated yet and does not disable the
deprecation warning in TypeSwitch. This seems to cause problems with
MSVC.
This patch forwards the target CPU and features information from the
Flang frontend to MLIR func.func operation attributes, which are later
used to populate the target_cpu and target_features llvm.func
attributes.
This is achieved in two stages:
1. Introduce the `fir.target_cpu` and `fir.target_features` module
attributes with information from the target machine immediately after
the initial creation of the MLIR module in the lowering bridge.
2. Update the target rewrite flang pass to get this information from the
module and pass it along to all func.func MLIR operations, respectively
as attributes named `target_cpu` and `target_features`. These attributes
will be automatically picked up during Func to LLVM dialect lowering and
used to initialize the corresponding llvm.func named attributes.
The target rewrite and FIR to LLVM lowering passes are updated with the
ability to override these module attributes, and the `CodeGenSpecifics`
optimizer class is augmented to make this information available to
target-specific MLIR transformations.
This completes a full flow by which target CPU and features make it all
the way from compiler options to LLVM IR function attributes.
Derived type passed with VALUE in BIND(C) context must be passed like C
struct and LLVM is not implementing the ABI for this (it is up to the
frontends like clang).
Previous patch #75802 implemented the simple cases where the derived
type have one field, this patch implements the general case. Note that
the generated LLVM IR is compliant from a X86-64 C ABI point of view and
compatible with clang generated assembly, but that it is not guaranteed
to match the LLVM IR signatures generated by clang for the C equivalent
functions because several LLVM IR signatures may lead to the same X86-64
signature.
In the context of C/Fortran interoperability (BIND(C)), it is possible
to give the VALUE attribute to a BIND(C) derived type dummy, which
according to Fortran 2018 18.3.6 - 2. (4) implies that it must be passed
like the equivalent C structure value. The way C structure value are
passed is ABI dependent.
LLVM does not implement the C struct ABI passing for LLVM aggregate type
arguments. It is up to the front-end, like clang is doing, to split the
struct into registers or pass the struct on the stack (llvm "byval") as
required by the target ABI.
So the logic for C struct passing sits in clang. Using it from flang
requires setting up a lot of clang context and to bridge FIR/MLIR
representation to clang AST representation for function signatures (in
both directions). It is a non trivial task.
See
https://stackoverflow.com/questions/39438033/passing-structs-by-value-in-llvm-ir/75002581#75002581.
Since BIND(C) struct are rather limited as opposed to generic C struct
(e.g. no bit fields). It is easier to provide a limited implementation
of it for the case that matter to Fortran.
This patch:
- Updates the generic target rewrite pass to keep track of both the new
argument type and attributes. The motivation for this is to be able to
tell if a previously marshalled argument is passed in memory (it is a C
pointer), or if it is being passed on the stack (has the byval llvm
attributes).
- Adds an entry point in the target specific codegen to marshal struct
arguments, and use it in the generic target rewrite pass.
- Implements limited support for the X86-64 case. So far, the support
allows telling if a struct must be passed in register or on the stack,
and to deal with the stack case. The register case is left TODO in this
patch.
The X86-64 ABI implemented is the System V ABI for AMD64 version 1.0
Previously only a constant reference was stored in the FirOpBuilder.
However, a lot of code was merged using
FirOpBuilder builder{rewriter, getKindMapping(mod)};
This is incorrect because the KindMapping returned will go out of scope
as soon as FirOpBuilder's constructor had run. This led to an infinite
loop running some tests using HLFIR (because the stack space containing
the kind mapping was re-used and corrupted).
One solution would have just been to fix the incorrect call sites,
however, as a large number of these had already made it past review, I
decided to instead change FirOpBuilder to store its own copy of the
KindMapping. This is not costly because nearly every time we construct a
KindMapping is exclusively to construct a FirOpBuilder. To make this
common pattern simpler, I added a new constructor to FirOpBuilder which
calls getKindMapping().
Differential Revision: https://reviews.llvm.org/D151881
This resolves issues with running out of stack on examples like
https://fortran-lang.discourse.group/t/modern-fortran-sample-code/2019/18
reported by @clementval.
When target rewrite creates alloca(s) around a call, we need to insert
stacksave/stackrestore to free the allocated stack. Better performant
code may be achieved by placing the alloca(s) outside of loops,
but the placement has to behave correctly with regards to OpenMP/OpenACC/etc.
dialect operations that have special representation for "private"
objects. This is a concervative fix for correctness issue.
Differential Revision: https://reviews.llvm.org/D149222
After the extraction of the TypeConverter, move the header files
to the include dir so the shared library build is fine.
Reviewed By: PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D147979
BIND(C) subprograms must use the same target ABI as the C processor,
so 1/2-byte int args/rets must be rewritten to use signext attribute.
This change-set also sets fir.bindc_name for the math functions used
during lowering so that they can be fixed up as well (though, currently
none of them needs to be affected).
Differential Revision: https://reviews.llvm.org/D145537
Some conversions were still happening under no-complex/character-conversion
options. This change fixes that and adds a LIT test.
Differential Revision: https://reviews.llvm.org/D143685
Clang uses signext/zeroext attributes for integer arguments shorter than
the default 'int' type on a target. So Flang has to match this for functions
from Fortran runtime and also for BIND(C) routines. This patch implements
ABI adjustments only for Fortran runtime calls. BIND(C) part will be done
separately.
This resolves https://github.com/llvm/llvm-project/issues/58579
Differential Revision: https://reviews.llvm.org/D142677
Reland D139447, D139471 With flang actually working
- FunctionOpInterface: make get/setFunctionType interface methods
This patch removes the concept of a `function_type`-named type attribute
as a requirement for implementors of FunctionOpInterface. Instead, this
type should be provided through two interface methods, `getFunctionType`
and `setFunctionTypeAttr` (*Attr because functions may use different
concrete function types), which should be automatically implemented by
ODS for ops that define a `$function_type` attribute.
This also allows FunctionOpInterface to materialize function types if
they don't carry them in an attribute, for example.
Importantly, all the function "helper" still accept an attribute name to
use in parsing and printing functions, for example.
- FunctionOpInterface: arg and result attrs dispatch to interface
This patch removes the `arg_attrs` and `res_attrs` named attributes as a
requirement for FunctionOpInterface and replaces them with interface
methods for the getters, setters, and removers of the relevent
attributes. This allows operations to use their own storage for the
argument and result attributes.
Reviewed By: jpienaar
Differential Revision: https://reviews.llvm.org/D139736
Clang uses signext/zeroext attributes for integer arguments shorter than
the default 'int' type on a target. So Flang has to match this for functions
from Fortran runtime and also for BIND(C) routines. This patch implements
ABI adjustments only for Fortran runtime calls. BIND(C) part will be done
separately.
This resolves https://github.com/llvm/llvm-project/issues/58579
Differential Revision: https://reviews.llvm.org/D137050
Handle rewriting dispatch operation with complex arguments or
return.
sret will be done in a separate patch.
Reviewed By: jeanPerier, PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D138820
Clang uses signext/zeroext attributes for integer arguments shorter than
the default 'int' type on a target. So Flang has to match this for functions
from Fortran runtime and also for BIND(C) routines. This patch implements
ABI adjustments only for Fortran runtime calls. BIND(C) part will be done
separately.
This resolves https://github.com/llvm/llvm-project/issues/58579
Differential Revision: https://reviews.llvm.org/D137050
The patch introduces the required changes to update the pass declarations and definitions to use the new autogenerated files and allow dropping the old infrastructure.
Reviewed By: mehdi_amini, rriddle
Differential Review: https://reviews.llvm.org/D132838
The patch introduces the required changes to update the pass declarations and definitions to use the new autogenerated files and allow dropping the old infrastructure.
Reviewed By: mehdi_amini, rriddle
Differential Review: https://reviews.llvm.org/D132838
I went over the output of the following mess of a command:
`(ulimit -m 2000000; ulimit -v 2000000; git ls-files -z | parallel --xargs -0 cat | aspell list --mode=none --ignore-case | grep -E '^[A-Za-z][a-z]*$' | sort | uniq -c | sort -n | grep -vE '.{25}' | aspell pipe -W3 | grep : | cut -d' ' -f2 | less)`
and proceeded to spend a few days looking at it to find probable typos
and fixed a few hundred of them in all of the llvm project (note, the
ones I found are not anywhere near all of them, but it seems like a
good start).
Reviewed By: awarzynski, clementval
Differential Revision: https://reviews.llvm.org/D130844
With the transition to opaque pointers, type information has been
transferred to function parameter attributes. This patch adds correct
parsing for some of those arguments and fixes some tests, that
previously used UnitAttr for those.
Differential Revision: https://reviews.llvm.org/D132366
The TargetRewrite pass convert the signature of the function.
In some cases it adds operands to the function to hanlde the result of it.
This patch makes sure the argument attributes present before the conversion
are replaced with the correct arguments after the conversion is performed.
Depends D132113
Reviewed By: vdonaldson
Differential Revision: https://reviews.llvm.org/D132114
The TargetRewrite pass can change the number of argument of a function.
An extra llvm.nest attribute is added and was not set at the correct position
if an extra argument was inserted before.
Reviewed By: PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D132113
FirOpBuilder takes a fir::KindMapping reference. When the getKindMapping()
call is made inside the ctor call, the lifetime of this reference may
be as short as the ctor call (at least with when building flang in
release mode with clang 8). This can cause segfaults when later using
the FirOpBuilder.
Ensure the kindMap passed to the FirOpBuilder ctor is the same as the
FirOpBuilder.
Differential Revision: https://reviews.llvm.org/D129494
Flang C++ Style Guide tells us to avoid .has_value() in the predicate
expressions of control flow statements. I am treating ternary
expressions as control flow statements for the purpose of this patch.
Differential Revision: https://reviews.llvm.org/D128622
This patch is part of the upstreaming effort from fir-dev branch.
Reviewed By: jeanPerier, PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D127634
Co-authored-by: Eric Schweitz <eschweitz@nvidia.com>
Remove a backwards dependence from Optimizer -> Lower by moving Todo.h
to the optimizer and out of lowering.
This patch is part of the upstreaming effort from fir-dev branch.
Co-authored-by: Eric Schweitz <eschweitz@nvidia.com>
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D127292
In FIR, we want to wrap function pointers in a special box known as a
boxproc value. Fortran has a limited form of dynamic scoping
[https://tinyurl.com/2p8v2hw7] between "host procedures" and "internal
procedures". There are a number of implementations possible.
Boxproc typed values abstract away the implementation details of when a
function pointer can be passed directly (as a raw address) and when a
function pointer has to account for the presence of a dynamic scope.
When lowering Fortran syntax to FIR, all function pointers are emboxed
as boxproc values.
When creating LLVM IR, we must strip away the abstraction and produce
low-level LLVM "assembly" code. This patch implements that
transformation as converting the boxproc values to either raw function
pointers or executable trampolines on the stack as needed. The
trampoline then captures the dynamic scope context within an executable
thunk that can be passed instead of the function's raw address.
Some extra handling is required for Fortran functions that return a
character value to deal with LEN values here.
Some of the code in Bridge.cpp and ConvertExpr.cpp and be re-arranged to
faciliate the upstreaming effort.
This patch is part of the upstreaming effort from fir-dev branch.
Reviewed By: jeanPerier, PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D122223
Co-authored-by: mleair <leairmark@gmail.com>
Co-authored-by: Jean Perier <jperier@nvidia.com>
Co-authored-by: Eric Schweitz <eschweitz@nvidia.com>
Co-authored-by: V Donaldson <vdonaldson@nvidia.com>
Co-authored-by: Kiran Chandramohan <kiran.chandramohan@arm.com>
This removes any potential confusion with the `getType` accessors
which correspond to SSA results of an operation, and makes it
clear what the intent is (i.e. to represent the type of the function).
Differential Revision: https://reviews.llvm.org/D121762
Currently, CGOps.h and FIROps.h contain `using namespace mlir;`. Every
file that includes one of these header files (directly and transitively)
will have the MLIR namespace enabled. With name-clashes within
sub-projects (LLVM and MLIR, MLIR and Flang), this is not desired. Also,
it is not possible to "un-use" a namespace once it is "used". Instead,
we should try to limit `using namespace` to implementation files (i.e.
*.cpp).
This patch removes `using namespace mlir;` from header files and adjusts
other files accordingly. In header and TableGen files, extra namespace
qualifier is added when referring to symbols defined in MLIR. Similar
approach is adopted in source files that didn't require many changes. In
files that would require a lot of changes, `using namespace mlir;` is
added instead.
Differential Revision: https://reviews.llvm.org/D120897
The last remaining operations in the standard dialect all revolve around
FuncOp/function related constructs. This patch simply handles the initial
renaming (which by itself is already huge), but there are a large number
of cleanups unlocked/necessary afterwards:
* Removing a bunch of unnecessary dependencies on Func
* Cleaning up the From/ToStandard conversion passes
* Preparing for the move of FuncOp to the Func dialect
See the discussion at https://discourse.llvm.org/t/standard-dialect-the-final-chapter/6061
Differential Revision: https://reviews.llvm.org/D120624
`kEmitAccessorPrefix_Raw ` is being removed, and so updating the
accessors to `kEmitAccessorPrefix_Prefixed`.
Reviewed By: clementval
Differential Revision: https://reviews.llvm.org/D119812
llvm.insertvalue and llvm.extractvalue need LLVM primitive type
for the indexing operands. While upstreaming the TargetRewrite pass the change
was made from i32 to index without knowing this restriction. This patch reverts
back the types used for indexing in the two ops created in this pass.
the error you will receive when lowering to LLVM IR with the current code
is the following:
```
'llvm.insertvalue' op operand #1 must be primitive LLVM type, but got 'index'
```
Reviewed By: jeanPerier, schweitz
Differential Revision: https://reviews.llvm.org/D119253