summaryrefslogtreecommitdiff
path: root/flang/lib/Lower/Bridge.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'flang/lib/Lower/Bridge.cpp')
-rw-r--r--flang/lib/Lower/Bridge.cpp101
1 files changed, 66 insertions, 35 deletions
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index f518599125e8..c7e2635230e9 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -11,7 +11,7 @@
//===----------------------------------------------------------------------===//
#include "flang/Lower/Bridge.h"
-#include "DirectivesCommon.h"
+
#include "flang/Common/Version.h"
#include "flang/Lower/Allocatable.h"
#include "flang/Lower/CallInterface.h"
@@ -22,6 +22,7 @@
#include "flang/Lower/ConvertType.h"
#include "flang/Lower/ConvertVariable.h"
#include "flang/Lower/Cuda.h"
+#include "flang/Lower/DirectivesCommon.h"
#include "flang/Lower/HostAssociations.h"
#include "flang/Lower/IO.h"
#include "flang/Lower/IterationSpace.h"
@@ -56,7 +57,7 @@
#include "flang/Optimizer/Support/InternalNames.h"
#include "flang/Optimizer/Transforms/Passes.h"
#include "flang/Parser/parse-tree.h"
-#include "flang/Runtime/iostat.h"
+#include "flang/Runtime/iostat-consts.h"
#include "flang/Semantics/runtime-type-info.h"
#include "flang/Semantics/symbol.h"
#include "flang/Semantics/tools.h"
@@ -556,8 +557,8 @@ public:
return lookupSymbol(sym).getAddr();
}
- fir::ExtendedValue
- symBoxToExtendedValue(const Fortran::lower::SymbolBox &symBox) {
+ fir::ExtendedValue symBoxToExtendedValue(
+ const Fortran::lower::SymbolBox &symBox) override final {
return symBox.match(
[](const Fortran::lower::SymbolBox::Intrinsic &box)
-> fir::ExtendedValue { return box.getAddr(); },
@@ -711,8 +712,8 @@ public:
return bool(shallowLookupSymbol(sym));
}
- bool createHostAssociateVarClone(
- const Fortran::semantics::Symbol &sym) override final {
+ bool createHostAssociateVarClone(const Fortran::semantics::Symbol &sym,
+ bool skipDefaultInit) override final {
mlir::Location loc = genLocation(sym.name());
mlir::Type symType = genType(sym);
const auto *details = sym.detailsIf<Fortran::semantics::HostAssocDetails>();
@@ -769,13 +770,21 @@ public:
// Initialise cloned allocatable
hexv.match(
[&](const fir::MutableBoxValue &box) -> void {
- // Do not process pointers
+ const auto new_box = exv.getBoxOf<fir::MutableBoxValue>();
if (Fortran::semantics::IsPointer(sym.GetUltimate())) {
+ // Establish the pointer descriptors. The rank and type code/size
+ // at least must be set properly for later inquiry of the pointer
+ // to work, and new pointers are always given disassociated status
+ // by flang for safety, even if this is not required by the
+ // language.
+ auto empty = fir::factory::createUnallocatedBox(
+ *builder, loc, new_box->getBoxTy(), box.nonDeferredLenParams(),
+ {});
+ builder->create<fir::StoreOp>(loc, empty, new_box->getAddr());
return;
}
- // Allocate storage for a pointer/allocatble descriptor.
- // No shape/lengths to be passed to the alloca.
- const auto new_box = exv.getBoxOf<fir::MutableBoxValue>();
+ // Copy allocation status of Allocatables, creating new storage if
+ // needed.
// allocate if allocated
mlir::Value isAllocated =
@@ -823,7 +832,22 @@ public:
if_builder.end();
},
[&](const auto &) -> void {
- // Do nothing
+ if (skipDefaultInit)
+ return;
+ // Initialize local/private derived types with default
+ // initialization (Fortran 2023 section 11.1.7.5 and OpenMP 5.2
+ // section 5.3). Pointer and allocatable components, when allowed,
+ // also need to be established so that flang runtime can later work
+ // with them.
+ if (const Fortran::semantics::DeclTypeSpec *declTypeSpec =
+ sym.GetType())
+ if (const Fortran::semantics::DerivedTypeSpec *derivedTypeSpec =
+ declTypeSpec->AsDerived())
+ if (derivedTypeSpec->HasDefaultInitialization(
+ /*ignoreAllocatable=*/false, /*ignorePointer=*/false)) {
+ mlir::Value box = builder->createBox(loc, exv);
+ fir::runtime::genDerivedTypeInitialize(*builder, loc, box);
+ }
});
return bindIfNewSymbol(sym, exv);
@@ -1004,7 +1028,7 @@ public:
fir::FirOpBuilder &getFirOpBuilder() override final { return *builder; }
- mlir::ModuleOp &getModuleOp() override final { return bridge.getModule(); }
+ mlir::ModuleOp getModuleOp() override final { return bridge.getModule(); }
mlir::MLIRContext &getMLIRContext() override final {
return bridge.getMLIRContext();
@@ -1966,9 +1990,9 @@ private:
Fortran::semantics::SemanticsContext &semanticsContext =
bridge.getSemanticsContext();
for (const Fortran::semantics::Symbol *sym : info.localSymList)
- createHostAssociateVarClone(*sym);
+ createHostAssociateVarClone(*sym, /*skipDefaultInit=*/false);
for (const Fortran::semantics::Symbol *sym : info.localInitSymList) {
- createHostAssociateVarClone(*sym);
+ createHostAssociateVarClone(*sym, /*skipDefaultInit=*/true);
const auto *hostDetails =
sym->detailsIf<Fortran::semantics::HostAssocDetails>();
assert(hostDetails && "missing locality spec host symbol");
@@ -1986,6 +2010,9 @@ private:
sym->detailsIf<Fortran::semantics::HostAssocDetails>();
copySymbolBinding(hostDetails->symbol(), *sym);
}
+ // Note that allocatable, types with ultimate components, and type
+ // requiring finalization are forbidden in LOCAL/LOCAL_INIT (F2023 C1130),
+ // so no clean-up needs to be generated for these entities.
}
/// Generate FIR for a DO construct. There are six variants:
@@ -2304,7 +2331,7 @@ private:
assert(!incrementLoopNestInfo.empty() && "empty loop nest");
mlir::Location loc = toLocation();
mlir::arith::IntegerOverflowFlags flags{};
- if (getLoweringOptions().getNSWOnLoopVarInc())
+ if (!getLoweringOptions().getIntegerWrapAround())
flags = bitEnumSet(flags, mlir::arith::IntegerOverflowFlags::nsw);
auto iofAttr = mlir::arith::IntegerOverflowFlagsAttr::get(
builder->getContext(), flags);
@@ -3011,8 +3038,10 @@ private:
fir::getBase(genExprValue(*Fortran::semantics::GetExpr(bounds->upper),
stmtCtx))));
if (bounds->step)
- steps.push_back(fir::getBase(
- genExprValue(*Fortran::semantics::GetExpr(bounds->step), stmtCtx)));
+ steps.push_back(builder->createConvert(
+ crtLoc, idxTy,
+ fir::getBase(genExprValue(
+ *Fortran::semantics::GetExpr(bounds->step), stmtCtx))));
else // If `step` is not present, assume it is `1`.
steps.push_back(builder->createIntegerConstant(loc, idxTy, 1));
@@ -3085,7 +3114,7 @@ private:
}
/// Generate FIR for a SELECT CASE statement.
- /// The selector may have CHARACTER, INTEGER, or LOGICAL type.
+ /// The selector may have CHARACTER, INTEGER, UNSIGNED, or LOGICAL type.
void genFIR(const Fortran::parser::SelectCaseStmt &stmt) {
Fortran::lower::pft::Evaluation &eval = getEval();
Fortran::lower::pft::Evaluation *parentConstruct = eval.parentConstruct;
@@ -3121,6 +3150,10 @@ private:
selector = builder->createConvert(loc, builder->getI1Type(), selector);
}
mlir::Type selectType = selector.getType();
+ if (selectType.isUnsignedInteger())
+ selectType = mlir::IntegerType::get(
+ builder->getContext(), selectType.getIntOrFloatBitWidth(),
+ mlir::IntegerType::SignednessSemantics::Signless);
llvm::SmallVector<mlir::Attribute> attrList;
llvm::SmallVector<mlir::Value> valueList;
llvm::SmallVector<mlir::Block *> blockList;
@@ -3134,9 +3167,10 @@ private:
else if (isLogicalSelector)
valueList.push_back(builder->createConvert(
loc, selectType, createFIRExpr(toLocation(), expr, stmtCtx)));
- else
+ else {
valueList.push_back(builder->createIntegerConstant(
loc, selectType, *Fortran::evaluate::ToInt64(*expr)));
+ }
};
for (Fortran::lower::pft::Evaluation *e = eval.controlSuccessor; e;
e = e->controlSuccessor) {
@@ -4433,7 +4467,8 @@ private:
// lowered.
const bool isWholeAllocatableAssignment =
!userDefinedAssignment && !isInsideHlfirWhere() &&
- Fortran::lower::isWholeAllocatable(assign.lhs);
+ Fortran::lower::isWholeAllocatable(assign.lhs) &&
+ bridge.getLoweringOptions().getReallocateLHS();
const bool isUserDefAssignToPointerOrAllocatable =
userDefinedAssignment &&
firstDummyIsPointerOrAllocatable(*userDefinedAssignment);
@@ -6102,10 +6137,7 @@ void Fortran::lower::LoweringBridge::lower(
}
void Fortran::lower::LoweringBridge::parseSourceFile(llvm::SourceMgr &srcMgr) {
- mlir::OwningOpRef<mlir::ModuleOp> owningRef =
- mlir::parseSourceFile<mlir::ModuleOp>(srcMgr, &context);
- module.reset(new mlir::ModuleOp(owningRef.get().getOperation()));
- owningRef.release();
+ module = mlir::parseSourceFile<mlir::ModuleOp>(srcMgr, &context);
}
Fortran::lower::LoweringBridge::LoweringBridge(
@@ -6172,19 +6204,18 @@ Fortran::lower::LoweringBridge::LoweringBridge(
};
// Create the module and attach the attributes.
- module = std::make_unique<mlir::ModuleOp>(
+ module = mlir::OwningOpRef<mlir::ModuleOp>(
mlir::ModuleOp::create(getPathLocation()));
- assert(module.get() && "module was not created");
- fir::setTargetTriple(*module.get(), triple);
- fir::setKindMapping(*module.get(), kindMap);
- fir::setTargetCPU(*module.get(), targetMachine.getTargetCPU());
- fir::setTuneCPU(*module.get(), targetOpts.cpuToTuneFor);
- fir::setTargetFeatures(*module.get(), targetMachine.getTargetFeatureString());
- fir::support::setMLIRDataLayout(*module.get(),
- targetMachine.createDataLayout());
- fir::setIdent(*module.get(), Fortran::common::getFlangFullVersion());
+ assert(*module && "module was not created");
+ fir::setTargetTriple(*module, triple);
+ fir::setKindMapping(*module, kindMap);
+ fir::setTargetCPU(*module, targetMachine.getTargetCPU());
+ fir::setTuneCPU(*module, targetOpts.cpuToTuneFor);
+ fir::setTargetFeatures(*module, targetMachine.getTargetFeatureString());
+ fir::support::setMLIRDataLayout(*module, targetMachine.createDataLayout());
+ fir::setIdent(*module, Fortran::common::getFlangFullVersion());
if (cgOpts.RecordCommandLine)
- fir::setCommandline(*module.get(), *cgOpts.RecordCommandLine);
+ fir::setCommandline(*module, *cgOpts.RecordCommandLine);
}
void Fortran::lower::genCleanUpInRegionIfAny(