When an array element is extracted from an unlimited polymorphic array, the
emboxing of this element has to retrive the type code and element size from
the initial array. This patch retrive this information through the extracted
type descriptor.
This situation can be found in code like:
```
subroutine sub1(a)
class(*) :: a(:)
select type (x=>a(1))
type is (integer)
x = 10
end select
end subroutine
```
Reviewed By: jeanPerier, PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D141274
In HLFIR, the address of a Fortran entity in lowering must be defined
by an operation that has the FortranVariableOpInterface (it is a sanity
requirement to ensure that the mlir::Value propagated in certain places
of lowering can be reasoned about).
fir.zero_bits does not have this interface and it makes little sense to
add it since it can "zero initialize" more types than just addresses.
Creating an hlfir.declare for null addresses is a bit too much (what
would be the name), and it would be noisy in the IR.
Instead add a small hlfir.null operation whose codegen is simply a
replacement by fir.zero_bits.
It may also later help dealing with the NULL(MOLD) cases in a nicer
way (the current lowering of this uses special handling it).
Differential Revision: https://reviews.llvm.org/D141040
Adding support for ppc64 (big endian) in order to support flang on 64 bit AIX
Reviewed By: clementval, kiranchandramohan
Differential Revision: https://reviews.llvm.org/D138390
Addresses and properties (bounds, length parameters) of host
variables associated in an internal procedure were all passed via
an extra tuple argument of the internal procedure.
This extra tuple is in general an overhead: it must be created and
passed, and require creating thunks when taking the address of the
internal procedure.
This patch allows not using the tuple for host global variables
(from modules, common block, or local saved variables) since they can
be instantiated from the fir.global symbol in the internal procedure
instead.
Add a fir.internal_proc attribute to mlir::FuncOp for internal procedures
so that ArrayValueCopy can still detect internal procedures even if they
do not have a tuple argument.
Differential Revision: https://reviews.llvm.org/D140288
This is a fairly large changeset, but it can be broken into a few
pieces:
- `llvm/Support/*TargetParser*` are all moved from the LLVM Support
component into a new LLVM Component called "TargetParser". This
potentially enables using tablegen to maintain this information, as
is shown in https://reviews.llvm.org/D137517. This cannot currently
be done, as llvm-tblgen relies on LLVM's Support component.
- This also moves two files from Support which use and depend on
information in the TargetParser:
- `llvm/Support/Host.{h,cpp}` which contains functions for inspecting
the current Host machine for info about it, primarily to support
getting the host triple, but also for `-mcpu=native` support in e.g.
Clang. This is fairly tightly intertwined with the information in
`X86TargetParser.h`, so keeping them in the same component makes
sense.
- `llvm/ADT/Triple.h` and `llvm/Support/Triple.cpp`, which contains
the target triple parser and representation. This is very intertwined
with the Arm target parser, because the arm architecture version
appears in canonical triples on arm platforms.
- I moved the relevant unittests to their own directory.
And so, we end up with a single component that has all the information
about the following, which to me seems like a unified component:
- Triples that LLVM Knows about
- Architecture names and CPUs that LLVM knows about
- CPU detection logic for LLVM
Given this, I have also moved `RISCVISAInfo.h` into this component, as
it seems to me to be part of that same set of functionality.
If you get link errors in your components after this patch, you likely
need to add TargetParser into LLVM_LINK_COMPONENTS in CMake.
Differential Revision: https://reviews.llvm.org/D137838
Hlfir.designate was made to support substrings but so far substrings
were not yet lowered to it. Implement support for them.
Differential Revision: https://reviews.llvm.org/D140310
The runtime implementation uses the recurrence relations
`J(n-1, x) = (2.0 / x) * n * J(n, x) - J(n+1, x)`
`Y(n+1, x) = (2.0 / x) * n * Y(n, x) - Y(n-1, x)`
(see https://dlmf.nist.gov/10.74.iv and https://dlmf.nist.gov/10.6.E1).
Although the standard requires that `N1` and `N2` in `BESSEL_JN(N1, N2, x)`
and `BESSEL_YN(N1, N2, x)` be non-negative, this is not checked in the
runtime functions. This is in keeping with some other compilers which also
return some results when `N1` and/or `N2` are negative.
The special case for `x == 0` is handled in different runtime functions
for each of `BESSEL_JN` and `BESSEL_YN`. The lowering code checks for this
case and inserts the checks and the appropriate runtime calls in FIR.
The existing tests for the two intrinsics was modified to keep the style
consistent with the additional lowering tests that were added.
This will implement evaluate::SetLength where the length of
a character entity is changed (with trimming and padding).
Differential Revision: https://reviews.llvm.org/D140219
The motivation is to have it accessible in HLFIROps.cpp to
use it in hlfir.set_length builder to build the result length
type as best as possible.
Differential Revision: https://reviews.llvm.org/D140214
std::optional::value() has undesired exception checking semantics and is
unavailable in older Xcode (see _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS). The
call sites block std::optional migration.
This is part of an effort to migrate from llvm::Optional to
std::optional. This patch changes the way mlir-tblgen generates .inc
files, and modifies tests and documentation appropriately. It is a "no
compromises" patch, and doesn't leave the user with an unpleasant mix of
llvm::Optional and std::optional.
A non-trivial change has been made to ControlFlowInterfaces to split one
constructor into two, relating to a build failure on Windows.
See also: https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
Signed-off-by: Ramkumar Ramachandra <r@artagnon.com>
Differential Revision: https://reviews.llvm.org/D138934
Lower procedure ref to user defined elemental procedure when:
- there are no arguments that may be dynamically optional
- for functions, the result has no length parameters
- the reference can be unordered
- there are not character by value arguments
This uses the recently added hlfir.elemental operation and tools.
The "core" of the argument preparation is shared between elemental
and non elemental calls (genUserCalls is code moved without any
functional changes)
Differential Revision: https://reviews.llvm.org/D140118
The defining op of HLFIR variables is expected to be visible
in most cases, but HLFIR codegen won't rely on it from a correctness
point of view.
This patch allows building a fir.shape from an hlfir::Entity does not
have a visible FortranVariabeInterface defining op.
Differential Revision: https://reviews.llvm.org/D140099
Without any optimization or when it cannot be optimized before
bufferization, an hlfir.elemental lowers to an array temporary.
Its codegen consists in:
- allocating a temp given the type, shape, and length parameter arguments.
- generating a loop nest given the elemental shape
- inlining the body of the elemental inside the loops, and replacing the
yield_element by an assignment to an element of the temp.
Differential Revision: https://reviews.llvm.org/D140093
Lower binary and unary elemental operations with an array argument
using hlfir.elemental, hlfir.yield_element, and hlfir.apply.
Concat implementation, which is a binary operation, is moved to a
BinaryOp struct so that it can leverage this new code.
This patch implements the "not yet implemented: character array
expression temp with dynamic length" TODO of the current lowering
by splitting the result length computation from the result value
computation. That way, the result length computation can be done
before lowering the operation to an hlfir.elemental, and the length
of the hlfir.elemental is known and storage for it can later be
allocated.
It adds a DesignatorOp builder to make "dumb" indexing (without triplets,
component, substrings or derived type component ref) easier since indexing
needs to be generated for array variables in elemental expression (in
the added hlfir::genElementAt helper).
Differential Revision: https://reviews.llvm.org/D140040
In SELECT TYPE, within the block following TYPE IS, the associating entity is not polymorphic.
It has the type named in the type guard and other properties taken from the
selector. Within the block following a CLASS IS type guard statement, the
associating entity is polymorphic and has the declared type named in the type
guard statement.
This patch makes sure the associating entity matches the selector if it is
an array, a pointer or an allocatable.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D140017
Exponentiation is lowered to either math::FPowI or Fortran runtime
call (in case of --math-runtime=precise).
MathToFuncs convertor will convert math::FPowI operations with
exponent width >32 to calls of outlined implementations and otherwise
will leave the operation to MathToLLVM convertor.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D139806
Power functions are implemented as linkonce_odr scalar functions
for FPowI operations met in a module.
Vector form of FPowI is linearized into a sequence of calls
of the scalar functions.
Option {min-width-of-fpowi-exponent} controls which FPowI operations
are converted by MathToFuncs: if the width of the exponent's integer
type is less than the specified value, then the operation is not converted.
Flang will specify {min-width-of-fpowi-exponent=33} to make sure that
math::FPowI operations with exponent wider than 32 bits will be converted
by MathToFuncs, and operations with more narrow exponent will be left
for MathToLLVM to convert them to LLVM::PowIOp.
Reviewed By: Mogball
Differential Revision: https://reviews.llvm.org/D139804
When emboxing an entity to a polymorphic box, use the input type to
compute the type code and element size as the box type is too generic.
When reboxing a polymorphic box, get this information from the input
box.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D139916
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
This patch adds support for lowering intrinsics that have no dynamic
optionality aspects to handle and that requires argument to be lowered
to value, addr, or box.
It uses the current intrinsic lowering framework that can be re-used in
HLFIR to start with. HLFIR operations for charater/transformational
intrinsics will be added as needed from an optimization point of view.
The current approach will still create temporary variables for their
value directly in lowering.
Later patch will still need to add:
- support for dynamically optional arguments
- inquires
- "moving" the in memory computation of character and transformational
intrinsics to hlfir.expr. This is not needed from a semantic point of
view, but will help optimizing and will probably be required inside
hlfir.elemental returning characters so that the returned element
type is an hlfir.expr and match the result type of later hlfir.apply.
Differential Revision: https://reviews.llvm.org/D139613
hlfir.as_expr allows taking a value from a character, derived type,
or array expressions. This will allow implementing parentheses.
Combining as_expr + hlfir.associate will allow creating a variable copy
into a new temporary variable.
A later patch will add the ability to "move" a variable into an
expression (to give ownership of the variable storage to the expression,
with the commitment that the variable will not be used anymore).
Differential Revision: https://reviews.llvm.org/D139519
This supports the codegen for global procedure pointer in BoxedProcedure
pass. Reset the boxproc type.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D138273
This supports the codegen for procedure pointer component in
BoxedProcedure pass. Also fix the FIR in ProcedurePointer.md so that
all the cases can be run using `tco` to generate the LLVM IR.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D136842
The verifier of fir.emboxchar accepts `fir.char<kind, constant>` types,
but its codegen failed because of a missing cast. It is convenient and
safe to not require making the cast in FIR, so add it in codegen.
Differential Revision: https://reviews.llvm.org/D139514
Add the default unoptimized implementation implementation
of hlfir.assign. It relies on the runtime for array assignment
and always makes a temp of the right hand side for arrays.
Assignment optimization will be done when all HLFIR pieces are in place
and aliasing analysis is available.
Differential Revision: https://reviews.llvm.org/D139426
In some cases, the base type is already a fir.box type. This patch updates
the code to set the result box type to fir.box<T>, where T is the type
of the allocated temp.
This was reported in https://github.com/llvm/llvm-project/issues/59342
Reviewed By: jeanPerier, tblah
Differential Revision: https://reviews.llvm.org/D139401
For now at least, the plan is to keep hlfir.expr usage limited as
sub-expression operand, assignment rhs, and a few other contexts (
e.g. Associate statements). The rest of lowering (statements lowering
in the bridge) will still expect to get and manipulate characters and
arrays in memory. That means that hlfir.expr must be converted to
variable in converter.genExprAddr/converter.genExprBox.
This is done using an hlfir.associate, and generating the related
hlfir.end_associate in the statement context.
hlfir::getFirBase of is updated to avoid bringing in the HLFIR
fir.boxchar/fir.box into FIR when the entity was created with
hlfir::AssociateOp.
Differential Revision: https://reviews.llvm.org/D139328
When generating character assignment operations, the generic code
generates some code to handle truncation and padding when the length
differ at runtime. A bypass already exists when the length are compile
time constant and match, but it was not used for the trivial case where
the RHS and LHS length is the same SSA value. In such case, even though,
the length is not know at compile time, it is known to be the same.
This will simplify the code creating character temporaries from a
variable in HLFIR that will use this assignment code.
Note that this probably has little impact on performance (llvm may be clever enough
to later catch that for us). But it makes the generated IR a lot more readable at
little cost.
Differential Revision: https://reviews.llvm.org/D139330
The implementation follows the pattern used in comparable intrinsics.
Change the runtime API for Norm2 so it does not expect a mask argument
since the Norm2 intrinsic does not accept a mask in Fortran.
Differential Revision: https://reviews.llvm.org/D138150
This patch mechanically replaces None with std::nullopt where the
compiler would warn if None were deprecated. The intent is to reduce
the amount of manual work required in migrating from Optional to
std::optional.
This is part of an effort to migrate from llvm::Optional to
std::optional:
https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716