34 Commits

Author SHA1 Message Date
harishch4
61bc5f6c73
[Flang]: Fix to bind(C) procs inside BLOCK construct (#82483)
Name mangling is invoked for a bind(C) procedure contained in a block in
a context that does not have access to block ID mapping. Relaxing an
assert to account for this.

Fixes #79408
2024-02-21 19:38:27 +05:30
jeanPerier
b797a6aede
[flang] Lower special bind(c) cases without binding labels (#65758)
1. Deal with BIND(C,NAME="")

BIND(C,NAME="") is different from BIND(C). The latter implies that there
us a binding label which is the Fortran symbol name (no Fortran mangling
must be added like underscores). The former implies there is no binding
label (the name in the object file must be the same as if it there was
no BIND(C) attribute at all).

This is correctly implemented in the front-end, but lowering mistakenly
overrode this in the code dealing with the case where BIND(C) is
inherited from a procedure interface. Handling of  this last case is moved into name
resolution.

2. Deal with BIND(C) internal procedure

Also according to 18.10.2, BIND(C) does not give a p prevent name
resolution from adding a label to them, otherwise,
bindc_internal_proc.f90 was not going through semantics (bogus error
about conflicting global names). Nothing TODO in lowering other than
removing the TODO.
2023-09-26 09:29:37 +02:00
jeanPerier
99a54b839a
[flang] Lower PRIVATE component names safely (#66076)
It is possible for a derived type extending a type with private
components to define components with the same name as the private
components.

This was not properly handled by lowering where several fir.record type
component names could end-up being the same, leading to bad generated
code (only the first component was accessed via fir.field_index, leading
to bad generated code).

This patch handles the situation by adding the derived type mangled name
to private component.
2023-09-18 14:59:56 +02:00
jeanPerier
6ffea74f7c
[flang] Use BIND name, if any, when consolidating common blocks (#65613)
This patch changes how common blocks are aggregated and named in
lowering in order to:

* fix one obvious issue where BIND(C) and non BIND(C) with the same
Fortran name were "merged"

* go further and deal with a derivative where the BIND(C) C name matches
the assembly name of a Fortran common block. This is a bit unspecified
IMHO, but gfortran, ifort, and nvfortran "merge" the common block
without complaints as a linker would have done. This required getting
rid of all the common block mangling early in FIR (\_QC) instead of
leaving that to the phase that emits LLVM from FIR because BIND(C)
common blocks did not have mangled names. Care has to be taken to deal
with the underscoring option of flang-new.

See added flang/test/Lower/HLFIR/common-block-bindc-conflicts.f90 for an
illustration.
2023-09-08 10:43:55 +02:00
Peter Klausler
031b4e5e79
[flang] Support SELECT RANK on allocatables & pointers
Unlike other executable constructs with associating selectors, the
selector of a SELECT RANK construct can have the ALLOCATABLE or POINTER
attribute, and will work as an allocatable or object pointer within
each rank case, so long as there is no RANK(*) case.

Getting this right exposed a correctness risk with the popular
predicate IsAllocatableOrPointer() -- it will be true for procedure
pointers as well as object pointers, and in many contexts, a procedure
pointer should not be acceptable.  So this patch adds the new predicate
IsAllocatableOrObjectPointer(), and updates some call sites of the original
function to use the new one.

Differential Revision: https://reviews.llvm.org/D159043
2023-08-29 14:56:15 -07:00
V Donaldson
04e6129d32 [flang] Separate module procedure variant
Accept "module procedure" (as well as module function/subroutine)
in a separate module procedure definition, such as "bb1" in:

module mm
  interface
    module subroutine mm1
    end subroutine
  end interface
end module

submodule(mm) bb
  interface
    module subroutine bb1
    end subroutine
  end interface
contains
  module procedure mm1
    call bb1
  end procedure
  module procedure bb1
    print*, 'bb1'
  end procedure
end submodule

  use mm
  call mm1
end
2023-08-16 10:07:07 -07:00
V Donaldson
2b12d8350e [flang] Block containing an interface
Name mangling may be invoked for an interface procedure contained in
a block in a context that does not have access to block ID mapping.
Procedures can't be defined inside a block, so name mangling doesn't
need a block map. Relax an assert to account for this.

    block
      interface
        subroutine ss(n) bind(c)
          integer :: n
        end subroutine
      end interface
      call ss(5)
    end block
    end
2023-06-29 13:25:45 -07:00
V Donaldson
6f7a3b0781 [flang] Non-type-bound defined IO lowering
Generate supporting data structures and calls to new runtime IO functions
for defined IO that accesses non-type-bound procedures, such as `wft` in:

module m1
  type t
    integer n
  end type
  interface write(formatted)
    module procedure wft
  end interface
 contains
  subroutine wft(dtv, unit, iotype, v_list, iostat, iomsg)
    class(t), intent(in) :: dtv
    integer, intent(in) :: unit
    character(*), intent(in) :: iotype
    integer, intent(in) :: v_list(:)
    integer, intent(out) :: iostat
    character(*), intent(inout) :: iomsg
    iostat = 0
    write(unit,*,iostat=iostat,iomsg=iomsg) 'wft was called: ', dtv%n
  end subroutine
end module

module m2
 contains
  subroutine test1
    use m1
    print *, 'test1, should call wft: ', t(1)
  end subroutine
  subroutine test2
    use m1, only: t
    print *, 'test2, should not call wft: ', t(2)
  end subroutine
end module

use m1
use m2
call test1
call test2
print *, 'main, should call wft: ', t(3)
end
2023-05-17 09:22:13 -07:00
Slava Zakharin
be5747e516 [flang] Fixed global name creation for literal constants.
The global names were created using a hash based on the address
of std::vector::data address. Since the memory may be reused
by different std::vector's, this may cause non-equivalent
constant expressions to map to the same name. This is what is happening
in the modified flang/test/Lower/constant-literal-mangling.f90 test.

I changed the name creation to use a map between the constant expressions
and corresponding unique names. The uniquing is done using a name counter
in FirConverter. The effect of this change is that the equivalent
constant expressions are now mapped to the same global, and the naming
is "stable" (i.e. it does not change from compilation to compilation).

Though, the issue is not HLFIR specific it was affecting several tests
when using HLFIR lowering.

Differential Revision: https://reviews.llvm.org/D150380
2023-05-12 13:40:22 -07:00
V Donaldson
2c1433453d [flang] Block construct
A block construct is an execution control construct that supports
declaration scopes contained within a parent subprogram scope or another
block scope. (blocks may be nested.) This is implemented by applying
basic scope processing to the block level.

Name uniquing/mangling is extended to support this. The term "block" is
heavily overloaded in Fortran standards. Prior name uniquing used tag `B`
for common block objects. Existing tag choices were modified to free up `B`
for block construct entities, and `C` for common blocks, and resolve
additional issues with other tags. The "old tag -> new tag" changes can
be summarized as:

     -> B  -- block construct -> new
  B  -> C  -- common block
  C  -> YI -- intrinsic type descriptor; not currently generated
  CT -> Y  -- nonintrinsic type descriptor; not currently generated
  G  -> N  -- namelist group
  L  ->    -- block data; not needed -> deleted

Existing name uniquing components consist of a tag followed by a name
from user source code, such as a module, subprogram, or variable name.
Block constructs are different in that they may be anonymous. (Like other
constructs, a block may have a `block-construct-name` that can be used
in exit statements, but this name is optional.) So blocks are given a
numeric compiler-generated preorder index starting with `B1`, `B2`,
and so on, on a per-procedure basis.

Name uniquing is also modified to include component names for all
containing procedures rather than for just the immediate host. This
fixes an existing name clash bug with same-named entities in same-named
host subprograms contained in different-named containing subprograms,
and variations of the bug involving modules and submodules.

F18 clause 9.7.3.1 (Deallocation of allocatable variables) paragraph 1
has a requirement that an allocated, unsaved allocatable local variable
must be deallocated on procedure exit. The following paragraph 2 states:

  When a BLOCK construct terminates, any unsaved allocated allocatable
  local variable of the construct is deallocated.

Similarly, F18 clause 7.5.6.3 (When finalization occurs) paragraph 3
has a requirement that a nonpointer, nonallocatable object must be
finalized on procedure exit. The following paragraph 4 states:

  A nonpointer nonallocatable local variable of a BLOCK construct
  is finalized immediately before it would become undefined due to
  termination of the BLOCK construct.

These deallocation and finalization requirements, along with stack
restoration requirements, require knowledge of block exits. In addition
to normal block termination at an end-block-stmt, a block may be
terminated by executing a branching statement that targets a statement
outside of the block. This includes

Single-target branch statements:
 - goto
 - exit
 - cycle
 - return

Bounded multiple-target branch statements:
 - arithmetic goto
 - IO statement with END, EOR, or ERR specifiers

Unbounded multiple-target branch statements:
 - call with alternate return specs
 - computed goto
 - assigned goto

Lowering code is extended to determine if one of these branches exits
one or more relevant blocks or other constructs, and adds a mechanism to
insert any necessary deallocation, finalization, or stack restoration
code at the source of the branch. For a single-target branch it suffices
to generate the exit code just prior to taking the indicated branch.
Each target of a multiple-target branch must be analyzed individually.
Where necessary, the code must first branch to an intermediate basic
block that contains exit code, followed by a branch to the original target
statement.

This patch implements an `activeConstructStack` construct exit mechanism
that queries a new `activeConstruct` PFT bit to insert stack restoration
code at block exits. It ties in to existing code in ConvertVariable.cpp
routine `instantiateLocal` which has code for finalization, making block
exit finalization on par with subprogram exit finalization. Deallocation
is as yet unimplemented for subprograms or blocks. This may result in
memory leaks for affected objects at either the subprogram or block level.
Deallocation cases can be addressed uniformly for both scopes in a future
patch, presumably with code insertion in routine `instantiateLocal`.

The exit code mechanism is not limited to block construct exits. It is
also available for use with other constructs. In particular, it is used
to replace custom deallocation code for a select case construct character
selector expression where applicable. This functionality is also added
to select type and associate constructs. It is available for use with
other constructs, such as select rank and image control constructs,
if that turns out to be necessary.

Overlapping nonfunctional changes include eliminating "FIR" from some
routine names and eliminating obsolete spaces in comments.
2023-02-28 09:55:10 -08:00
Jean Perier
e5921ef021 [flang][hlfir] Lower associate construct to HLFIR
- always use genExprAddr when lowering to HLFIR: it does not create
  temporary for array sections without vector subscripts, so there is
  no need to have custom logic.

- update mangling to deal with AssocDetailsEntity. Their name is
  required in HLFIR so that it can be added to the hlfir.declare
  that is created for the selector once it is lowered. This should
  allow getting debug info for selector when debug info are generated
  from hlfir.declare.

The rest of associate construct lowering is unchanged and shared with
the current lowering.

This patch also enables select type lowering to work properly, but some
other todos (mainly about parent component references) prevents porting
the tests for now, so this will be done later.

Differential Revision: https://reviews.llvm.org/D144740
2023-02-27 09:05:41 +01:00
Tom Eccles
b8da9c5568 [flang][NFC] Move intrinsic name mangling to IntrinsicCall 5/6
This removes another dependency of IntrinsicCall upon flang/lib/Lower:
making it possible to move IntrinsicCall into flang/lib/Optimizer.

Differential Revision: https://reviews.llvm.org/D143083
2023-02-06 10:33:20 +00:00
Kazu Hirata
0db88db5d9 flang] Remove remaining uses of llvm::Optional (NFC)
This patch removes the unused "using" declaration and removes #include
"llvm/ADT/Optional.h".

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
2023-01-07 22:32:38 -08:00
Kazu Hirata
c09215860f [flang] Use std::optional instead of llvm::Optional (NFC)
This patch replaces (llvm::|)Optional< with std::optional<.  I'll post
a separate patch to remove #include "llvm/ADT/Optional.h".

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
2023-01-07 22:26:48 -08:00
Kazu Hirata
4d4d4785e0 [flang] Add #include <optional> (NFC)
This patch adds #include <optional> to those files containing
llvm::Optional<...> or Optional<...>.

I'll post a separate patch to actually replace llvm::Optional with
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
2023-01-07 20:55:47 -08:00
Jean Perier
2d9b4a50ca [flang][NFC] share Constant<SomeDerived> lowering
A previous patch (https://reviews.llvm.org/D136955) already refactored
intrinsic constant lowering to place in its own file and allow using it from
both the current lowering and the new lowering to HLFIR.

This patch does the same for derived types. The core function
"genStructComponentInInitializer" is moved from ConvertExpr.cpp and
renamed "genInlinedStructureCtorLitImpl" into ConvertConstant.cpp
without significant logic change.

Then, genScalarLit, genArrayLit (and genInlinedArrayLit/genOutlinedArrayLit)
are updated to support derived types.

The core aspect of derived type constant lowering that differs between
the current lowering and the HLFIR update is the way
addresses/initial target descriptors are built when part of a derived
type constant. This part happens in ConvertVariable.cpp (since the
address of a variable is taken in an initializer and is left TODO).

The mangling of derived type global literal constant is fixed: it did not embed
the derived type name and could cause "conflicts" between unrelated
derived types containing the same data. However, the hash remains
unstable between two compilation of the same file. This is not a
correctness issue and would require a lot of work to hash the derived
type constant data without hashing some irrelevant (but not out of bound)
data in the compile time data structure that holds derived type
constants (Constant<SomeDerived>). This may have to be revisited later.

Differential Revision: https://reviews.llvm.org/D140986
2023-01-05 14:45:34 +01:00
V Donaldson
518e6f12f3 [flang] Submodules
A submodule is a program unit that may contain the implementions of procedures
declared in an ancestor module or submodule.

Processing for the equivalence groups and variables declared in a submodule
scope is similar to existing processing for the equivalence groups and
variables in module and procedure scopes. However, module and procedure scopes
are tied directly to code in the Pre-FIR Tree (PFT), whereas processing for a
submodule must have access to an ancestor module scope that is guaranteed
to be present in a .mod file, but is not guaranteed to be in the PFT. This
difference is accommodated by tying processing directly to a front end scope.
Function scopes that can be processed on the fly are done that way; the
resulting variable information is never stored. Module and submodule scopes
whose symbol information may be needed during lowering of any number of module
procedures are instead cached on first use, and reused as needed.

These changes are a direct extension of current code. All module and submodule
variables in scope are processed, whether referenced or not. A possible
alternative would be to instead process symbols only when first used. While
this could ultimately be beneficial, such an approach must account for the
presence of equivalence groups. That information is not currently available
for on-the-fly variable processing.

Some additional changes are needed to include submodules in places where
modules must be considered, and to include separate module procedures in
places where other subprogram variants are considered. There is also a fix
for a bug involving the use of variables in an equivalence group in a
namelist group, which also involves scope processing code.
2022-12-13 13:06:07 -08:00
Kazu Hirata
9a41739565 [flang] Use std::nullopt instead of None (NFC)
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
2022-12-03 12:14:21 -08:00
Valentin Clement
7883900c04
[flang] Lower type-bound procedure call needing dynamic dispatch to fir.dispatch
Lower call with polymorphic entities to fir.dispatch operation. This patch only
focus one lowering with simple scalar polymorphic entities. A follow-up patch
will deal with allocatble, pointer and array of polymorphic entities as they
require box manipulation for the passed-object.

Reviewed By: jeanPerier

Differential Revision: https://reviews.llvm.org/D135649
2022-10-12 15:24:49 +02:00
Kazu Hirata
a8c294d6aa [flang] Remove redundant string initialization (NFC)
Identified with readability-redundant-string-init.
2022-08-14 12:52:01 -07:00
Valentin Clement
1c7889ca4d
[flang] Remove some auto
This patch replaces some `auto` with proper type. This was done in fir-dev
but not upstreamed yet.

This patch is part of the upstreaming effort from fir-dev branch.

Reviewed By: klausler

Differential Revision: https://reviews.llvm.org/D128350
2022-06-22 20:48:01 +02:00
Valentin Clement
10b23ae880
[flang] Handle BINC(C) variables and add TODO for corner cases
- BIND(C) was ignored in lowering for objects (it can be used on
module and common blocks): use the bind name as the fir.global name.

- When an procedure is declared BIND(C) indirectly via an interface,
  it should have a BIND(C) name. This was not the case because
  GetBindName()/bindingName() return nothing in this case: detect this
  case in mangler.cpp and use the symbol name.

Add TODOs for corner cases:

- BIND(C) module variables may be initialized on the C side. This does
  not fit well with the current linkage strategy. Add a TODO until this
  is revisited.

- BIND(C) internal procedures should not have a binding label (see
  Fortran 2018 section 18.10.2 point 2), yet we currently lower them as
  if they were BIND(C) external procedure.
  I think this and the indirect interface case should really be
  handled by symbol.GetBindName instead of adding more logic in
  lowering to deal with this case: add a TODO.

This patch is part of the upstreaming effort from fir-dev branch.

Reviewed By: klausler

Differential Revision: https://reviews.llvm.org/D128340

Co-authored-by: Jean Perier <jperier@nvidia.com>
2022-06-22 20:47:23 +02:00
Valentin Clement
5b66cc1000
[flang][NFC] Move Todo.h from Lower to Optimizer
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
2022-06-10 08:51:05 +02:00
Valentin Clement
c3a7627cac
[flang] Lower more array character cases
This patch adds more lowering and tests for character array assignment/copy.

This patch is part of the upstreaming effort from fir-dev branch.

Depends on D121300

Reviewed By: PeteSteinfeld, schweitz

Differential Revision: https://reviews.llvm.org/D121301

Co-authored-by: Jean Perier <jperier@nvidia.com>
Co-authored-by: Eric Schweitz <eschweitz@nvidia.com>
2022-03-09 19:50:57 +01:00
Valentin Clement
a49bf0ac38
[flang] Lower associate construct
This patch lowers the `associate` construct.

This patch is part of the upstreaming effort from fir-dev branch.

Reviewed By: PeteSteinfeld

Differential Revision: https://reviews.llvm.org/D121239

Co-authored-by: V Donaldson <vdonaldson@nvidia.com>
Co-authored-by: Jean Perier <jperier@nvidia.com>
Co-authored-by: Eric Schweitz <eschweitz@nvidia.com>
2022-03-08 22:09:26 +01:00
Valentin Clement
e641c29f41
[flang] Lower simple scalar assignment
This patch hanlde lowering of simple scalar assignment.

This patch is part of the upstreaming effort from fir-dev branch.

Reviewed By: PeteSteinfeld

Differential Revision: https://reviews.llvm.org/D120058

Co-authored-by: Jean Perier <jperier@nvidia.com>
2022-02-17 18:24:30 +01:00
Peter Klausler
52a1346b78 [flang] Distinguish intrinsic from non-intrinsic modules
For "USE, INTRINSIC", search only for intrinsic modules;
for "USE, NON_INTRINSIC", do not recognize intrinsic modules.
Allow modules of both kinds with the same name to be used in
the same source file (but not in the same scoping unit, a
constraint of the standard that is now enforced).

The symbol table's scope tree now has a single instance of
a scope with a new kind, IntrinsicModules, whose children are
the USE'd intrinsic modules (explicit or not).  This separate
"top-level" scope is a child of the single global scope and
it allows both intrinsic and non-intrinsic modules of the same
name to exist in the symbol table.  Intrinsic modules' scopes'
symbols now have the INTRINSIC attribute set.

The search path directories need to make a distinction between
regular directories and the one(s) that point(s) to intrinsic
modules.  I allow for multiple intrinsic module directories in
the second search path, although only one is needed today.

Differential Revision: https://reviews.llvm.org/D118631
2022-01-31 13:31:27 -08:00
Valentin Clement
62cc6b0da2
[flang][fir] Add support to mangle/deconstruct namelist group name
Add support to create unique name for namelist group and be able to
deconstruct them.

This patch is part of the upstreaming effort from fir-dev branch.

Reviewed By: jeanPerier

Differential Revision: https://reviews.llvm.org/D110331

Co-authored-by: Jean Perier <jperier@nvidia.com>
Co-authored-by: Eric Schweitz <eschweitz@nvidia.com>
2021-09-24 22:10:39 +02:00
Valentin Clement
321be24aa6
Revert "[flang][fir] Add support to mangle/deconstruct namelist group name"
This reverts commit 3593ae4312f6156c9ca50d46cdb55a8dfad782d0.
2021-09-24 18:49:40 +02:00
Valentin Clement
3593ae4312
[flang][fir] Add support to mangle/deconstruct namelist group name
Add support to create unique name for namelist group and be able to
deconstruct them.

This patch is part of the upstreaming effort from fir-dev branch.

Reviewed By: jeanPerier

Differential Revision: https://reviews.llvm.org/D110331

Co-authored-by: Jean Perier <jperier@nvidia.com>
Co-authored-by: Eric Schweitz <eschweitz@nvidia.com>
2021-09-24 14:06:08 +02:00
Eric Schweitz
9da35814e5 [Flang] Changes to mangling code
Call static functions using the class name (fir::NameUniquer).
Add function for mangling derivedTypes.

All the name mangling functions that are ultimately called are
tested in unittests/Optimizer/InternalNamesTest.cpp.

Differential Revision: https://reviews.llvm.org/D99967
2021-04-09 16:42:06 +01:00
Eric Schweitz
5918690255 [flang][NFC] Rename complex type.
This change renames the CplxType class to ComplexType.
2021-02-01 15:31:48 -08:00
Eric Schweitz
24b62f28c5 [flang] Upstreaming intrinsic call lowering.
This module implements the lowering of Fortran intrinsics to the
corresponding calls in support libraries (the Fortran runtime, math
libraries, etc.)

This revision is a tad larger because there are a large number of Fortran
intrinsics and this adds lowering for a fair number of them.

Differential revision: https://reviews.llvm.org/D83355
2020-07-08 07:34:21 -07:00
Eric Schweitz
30db177693 [flang] Upstream the Mangler module from lowering.
This upstreams the internal name mangling used in the bridge to generate
unique names from symbols.

Replace InternalNamesTest with the actual, functional unittest.

Differential revision: https://reviews.llvm.org/D81764
2020-06-16 15:24:13 -07:00