Skip to content

Commit

Permalink
[flang] Implement derived type description table encoding
Browse files Browse the repository at this point in the history
Define Fortran derived types that describe the characteristics
of derived types, and instantiations of parameterized derived
types, that are of relevance to the runtime language support
library.  Define a suite of corresponding C++ structure types
for the runtime library to use to interpret instances of the
descriptions.

Create instances of these description types in Semantics as
static initializers for compiler-created objects in the scopes
that define or instantiate user derived types.

Delete obsolete code from earlier attempts to package runtime
type information.

Differential Revision: https://reviews.llvm.org/D92802
  • Loading branch information
klausler committed Dec 8, 2020
1 parent 3e86fbc commit 4fede8b
Show file tree
Hide file tree
Showing 25 changed files with 1,775 additions and 349 deletions.
2 changes: 1 addition & 1 deletion flang/docs/RuntimeTypeInfo.md
Expand Up @@ -216,7 +216,7 @@ So the derived type information for a defined assignment needs to
comprise:
* address(es) of the subroutine
* whether the first, second, or both arguments are descriptors
* whether the subroutine is elemental
* whether the subroutine is elemental (necessarily also impure)

### User defined derived type I/O

Expand Down
38 changes: 38 additions & 0 deletions flang/include/flang/Semantics/runtime-type-info.h
@@ -0,0 +1,38 @@
//===-- include/flang/Semantics/runtime-type-info.h -------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

// BuildRuntimeDerivedTypeTables() translates the scopes of derived types
// and parameterized derived type instantiations into the type descriptions
// defined in module/__fortran_type_info.f90, packaging these descriptions
// as static initializers for compiler-created objects.

#ifndef FORTRAN_SEMANTICS_RUNTIME_TYPE_INFO_H_
#define FORTRAN_SEMANTICS_RUNTIME_TYPE_INFO_H_

#include <set>
#include <string>

namespace llvm {
class raw_ostream;
}

namespace Fortran::semantics {
class Scope;
class SemanticsContext;
class Symbol;

struct RuntimeDerivedTypeTables {
Scope *schemata{nullptr};
std::set<std::string> names;
};

RuntimeDerivedTypeTables BuildRuntimeDerivedTypeTables(SemanticsContext &);

void Dump(llvm::raw_ostream &, const RuntimeDerivedTypeTables &);
} // namespace Fortran::semantics
#endif // FORTRAN_SEMANTICS_RUNTIME_TYPE_INFO_H_
17 changes: 14 additions & 3 deletions flang/include/flang/Semantics/scope.h
Expand Up @@ -197,8 +197,11 @@ class Scope {

std::size_t size() const { return size_; }
void set_size(std::size_t size) { size_ = size; }
std::size_t alignment() const { return alignment_; }
void set_alignment(std::size_t alignment) { alignment_ = alignment; }
std::optional<std::size_t> alignment() const { return alignment_; }

void SetAlignment(std::size_t n) {
alignment_ = std::max(alignment_.value_or(0), n);
}

ImportKind GetImportKind() const;
// Names appearing in IMPORT statements in this scope
Expand Down Expand Up @@ -242,11 +245,18 @@ class Scope {

void InstantiateDerivedTypes(SemanticsContext &);

const Symbol *runtimeDerivedTypeDescription() const {
return runtimeDerivedTypeDescription_;
}
void set_runtimeDerivedTypeDescription(const Symbol &symbol) {
runtimeDerivedTypeDescription_ = &symbol;
}

private:
Scope &parent_; // this is enclosing scope, not extended derived type base
const Kind kind_;
std::size_t size_{0}; // size in bytes
std::size_t alignment_{0}; // required alignment in bytes
std::optional<std::size_t> alignment_; // required alignment in bytes
parser::CharBlock sourceRange_;
Symbol *const symbol_; // if not null, symbol_->scope() == this
std::list<Scope> children_;
Expand All @@ -261,6 +271,7 @@ class Scope {
DerivedTypeSpec *derivedTypeSpec_{nullptr}; // dTS->scope() == this
parser::Message::Reference instantiationContext_;
bool hasSAVE_{false}; // scope has a bare SAVE statement
const Symbol *runtimeDerivedTypeDescription_{nullptr};
// When additional data members are added to Scope, remember to
// copy them, if appropriate, in InstantiateDerivedType().

Expand Down
1 change: 1 addition & 0 deletions flang/lib/Semantics/CMakeLists.txt
Expand Up @@ -36,6 +36,7 @@ add_flang_library(FortranSemantics
resolve-names-utils.cpp
resolve-names.cpp
rewrite-parse-tree.cpp
runtime-type-info.cpp
scope.cpp
semantics.cpp
symbol.cpp
Expand Down
11 changes: 8 additions & 3 deletions flang/lib/Semantics/compute-offsets.cpp
Expand Up @@ -85,12 +85,16 @@ void ComputeOffsetsHelper::DoScope(Scope &scope) {
if (scope.symbol() && scope.IsParameterizedDerivedType()) {
return; // only process instantiations of parameterized derived types
}
if (scope.alignment().has_value()) {
return; // prevent infinite recursion in error cases
}
scope.SetAlignment(0);
// Build dependents_ from equivalences: symbol -> symbol+offset
for (const EquivalenceSet &set : scope.equivalenceSets()) {
DoEquivalenceSet(set);
}
offset_ = 0;
alignment_ = 0;
alignment_ = 1;
// Compute a base symbol and overall block size for each
// disjoint EQUIVALENCE storage sequence.
for (auto &[symbol, dep] : dependents_) {
Expand Down Expand Up @@ -128,7 +132,7 @@ void ComputeOffsetsHelper::DoScope(Scope &scope) {
}
}
scope.set_size(offset_);
scope.set_alignment(alignment_);
scope.SetAlignment(alignment_);
// Assign offsets in COMMON blocks.
for (auto &pair : scope.commonBlocks()) {
DoCommonBlock(*pair.second);
Expand Down Expand Up @@ -357,8 +361,9 @@ auto ComputeOffsetsHelper::GetElementSize(const Symbol &symbol)
}
} else if (const DerivedTypeSpec * derived{type->AsDerived()}) {
if (derived->scope()) {
DoScope(*const_cast<Scope *>(derived->scope()));
result.size = derived->scope()->size();
result.alignment = derived->scope()->alignment();
result.alignment = derived->scope()->alignment().value_or(0);
}
} else {
DIE("not intrinsic or derived");
Expand Down

0 comments on commit 4fede8b

Please sign in to comment.