aboutsummaryrefslogtreecommitdiff
path: root/flang/lib/Optimizer
diff options
context:
space:
mode:
Diffstat (limited to 'flang/lib/Optimizer')
-rw-r--r--flang/lib/Optimizer/Analysis/AliasAnalysis.cpp57
-rw-r--r--flang/lib/Optimizer/Builder/CUFCommon.cpp23
-rw-r--r--flang/lib/Optimizer/OpenMP/MapInfoFinalization.cpp32
-rw-r--r--flang/lib/Optimizer/Transforms/CUFComputeSharedMemoryOffsetsAndSize.cpp3
-rw-r--r--flang/lib/Optimizer/Transforms/CUFOpConversion.cpp28
5 files changed, 69 insertions, 74 deletions
diff --git a/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp b/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
index 73ddd1f..ef98942 100644
--- a/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
+++ b/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
@@ -27,6 +27,26 @@ using namespace mlir;
#define DEBUG_TYPE "fir-alias-analysis"
+// Inspect for value-scoped Allocate effects and determine whether
+// 'candidate' is a new allocation. Returns SourceKind::Allocate if a
+// MemAlloc effect is attached
+static fir::AliasAnalysis::SourceKind
+classifyAllocateFromEffects(mlir::Operation *op, mlir::Value candidate) {
+ if (!op)
+ return fir::AliasAnalysis::SourceKind::Unknown;
+ auto interface = llvm::dyn_cast<mlir::MemoryEffectOpInterface>(op);
+ if (!interface)
+ return fir::AliasAnalysis::SourceKind::Unknown;
+ llvm::SmallVector<mlir::MemoryEffects::EffectInstance, 4> effects;
+ interface.getEffects(effects);
+ for (mlir::MemoryEffects::EffectInstance &e : effects) {
+ if (mlir::isa<mlir::MemoryEffects::Allocate>(e.getEffect()) &&
+ e.getValue() && e.getValue() == candidate)
+ return fir::AliasAnalysis::SourceKind::Allocate;
+ }
+ return fir::AliasAnalysis::SourceKind::Unknown;
+}
+
//===----------------------------------------------------------------------===//
// AliasAnalysis: alias
//===----------------------------------------------------------------------===//
@@ -535,6 +555,11 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v,
mlir::Operation *instantiationPoint{nullptr};
while (defOp && !breakFromLoop) {
ty = defOp->getResultTypes()[0];
+ // Value-scoped allocation detection via effects.
+ if (classifyAllocateFromEffects(defOp, v) == SourceKind::Allocate) {
+ type = SourceKind::Allocate;
+ break;
+ }
llvm::TypeSwitch<Operation *>(defOp)
.Case<hlfir::AsExprOp>([&](auto op) {
v = op.getVar();
@@ -554,11 +579,6 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v,
defOp = v.getDefiningOp();
}
})
- .Case<fir::AllocaOp, fir::AllocMemOp>([&](auto op) {
- // Unique memory allocation.
- type = SourceKind::Allocate;
- breakFromLoop = true;
- })
.Case<fir::ConvertOp>([&](auto op) {
// Skip ConvertOp's and track further through the operand.
v = op->getOperand(0);
@@ -628,16 +648,23 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v,
type = SourceKind::Global;
} else {
auto def = llvm::cast<mlir::Value>(boxSrc.origin.u);
- // TODO: Add support to fir.allocmem
- if (auto allocOp = def.template getDefiningOp<fir::AllocaOp>()) {
- v = def;
- defOp = v.getDefiningOp();
- type = SourceKind::Allocate;
- } else if (isDummyArgument(def)) {
- defOp = nullptr;
- v = def;
- } else {
- type = SourceKind::Indirect;
+ bool classified = false;
+ if (auto defDefOp = def.getDefiningOp()) {
+ if (classifyAllocateFromEffects(defDefOp, def) ==
+ SourceKind::Allocate) {
+ v = def;
+ defOp = defDefOp;
+ type = SourceKind::Allocate;
+ classified = true;
+ }
+ }
+ if (!classified) {
+ if (isDummyArgument(def)) {
+ defOp = nullptr;
+ v = def;
+ } else {
+ type = SourceKind::Indirect;
+ }
}
}
breakFromLoop = true;
diff --git a/flang/lib/Optimizer/Builder/CUFCommon.cpp b/flang/lib/Optimizer/Builder/CUFCommon.cpp
index cf7588f..461deb8 100644
--- a/flang/lib/Optimizer/Builder/CUFCommon.cpp
+++ b/flang/lib/Optimizer/Builder/CUFCommon.cpp
@@ -9,6 +9,7 @@
#include "flang/Optimizer/Builder/CUFCommon.h"
#include "flang/Optimizer/Builder/FIRBuilder.h"
#include "flang/Optimizer/Dialect/CUF/CUFOps.h"
+#include "flang/Optimizer/Dialect/Support/KindMapping.h"
#include "flang/Optimizer/HLFIR/HLFIROps.h"
#include "mlir/Dialect/Func/IR/FuncOps.h"
#include "mlir/Dialect/LLVMIR/NVVMDialect.h"
@@ -91,3 +92,25 @@ void cuf::genPointerSync(const mlir::Value box, fir::FirOpBuilder &builder) {
}
}
}
+
+int cuf::computeElementByteSize(mlir::Location loc, mlir::Type type,
+ fir::KindMapping &kindMap,
+ bool emitErrorOnFailure) {
+ auto eleTy = fir::unwrapSequenceType(type);
+ if (auto t{mlir::dyn_cast<mlir::IntegerType>(eleTy)})
+ return t.getWidth() / 8;
+ if (auto t{mlir::dyn_cast<mlir::FloatType>(eleTy)})
+ return t.getWidth() / 8;
+ if (auto t{mlir::dyn_cast<fir::LogicalType>(eleTy)})
+ return kindMap.getLogicalBitsize(t.getFKind()) / 8;
+ if (auto t{mlir::dyn_cast<mlir::ComplexType>(eleTy)}) {
+ int elemSize =
+ mlir::cast<mlir::FloatType>(t.getElementType()).getWidth() / 8;
+ return 2 * elemSize;
+ }
+ if (auto t{mlir::dyn_cast<fir::CharacterType>(eleTy)})
+ return kindMap.getCharacterBitsize(t.getFKind()) / 8;
+ if (emitErrorOnFailure)
+ mlir::emitError(loc, "unsupported type");
+ return 0;
+}
diff --git a/flang/lib/Optimizer/OpenMP/MapInfoFinalization.cpp b/flang/lib/Optimizer/OpenMP/MapInfoFinalization.cpp
index d60da89..8382a48 100644
--- a/flang/lib/Optimizer/OpenMP/MapInfoFinalization.cpp
+++ b/flang/lib/Optimizer/OpenMP/MapInfoFinalization.cpp
@@ -943,38 +943,6 @@ class MapInfoFinalizationPass
localBoxAllocas.clear();
deferrableDesc.clear();
- // First, walk `omp.map.info` ops to see if any of them have varPtrs
- // with an underlying type of fir.char<k, ?>, i.e a character
- // with dynamic length. If so, check if they need bounds added.
- func->walk([&](mlir::omp::MapInfoOp op) {
- if (!op.getBounds().empty())
- return;
-
- mlir::Value varPtr = op.getVarPtr();
- mlir::Type underlyingVarType = fir::unwrapRefType(varPtr.getType());
-
- if (!fir::characterWithDynamicLen(underlyingVarType))
- return;
-
- fir::factory::AddrAndBoundsInfo info =
- fir::factory::getDataOperandBaseAddr(
- builder, varPtr, /*isOptional=*/false, varPtr.getLoc());
-
- fir::ExtendedValue extendedValue =
- hlfir::translateToExtendedValue(varPtr.getLoc(), builder,
- hlfir::Entity{info.addr},
- /*continguousHint=*/true)
- .first;
- builder.setInsertionPoint(op);
- llvm::SmallVector<mlir::Value> boundsOps =
- fir::factory::genImplicitBoundsOps<mlir::omp::MapBoundsOp,
- mlir::omp::MapBoundsType>(
- builder, info, extendedValue,
- /*dataExvIsAssumedSize=*/false, varPtr.getLoc());
-
- op.getBoundsMutable().append(boundsOps);
- });
-
// Next, walk `omp.map.info` ops to see if any record members should be
// implicitly mapped.
func->walk([&](mlir::omp::MapInfoOp op) {
diff --git a/flang/lib/Optimizer/Transforms/CUFComputeSharedMemoryOffsetsAndSize.cpp b/flang/lib/Optimizer/Transforms/CUFComputeSharedMemoryOffsetsAndSize.cpp
index 09126e0..a644945 100644
--- a/flang/lib/Optimizer/Transforms/CUFComputeSharedMemoryOffsetsAndSize.cpp
+++ b/flang/lib/Optimizer/Transforms/CUFComputeSharedMemoryOffsetsAndSize.cpp
@@ -41,8 +41,7 @@ namespace {
static bool isAssumedSize(mlir::ValueRange shape) {
if (shape.size() != 1)
return false;
- std::optional<std::int64_t> val = fir::getIntIfConstant(shape[0]);
- if (val && *val == -1)
+ if (llvm::isa_and_nonnull<fir::AssumedSizeExtentOp>(shape[0].getDefiningOp()))
return true;
return false;
}
diff --git a/flang/lib/Optimizer/Transforms/CUFOpConversion.cpp b/flang/lib/Optimizer/Transforms/CUFOpConversion.cpp
index 8d00272..5b1b0a2 100644
--- a/flang/lib/Optimizer/Transforms/CUFOpConversion.cpp
+++ b/flang/lib/Optimizer/Transforms/CUFOpConversion.cpp
@@ -263,28 +263,6 @@ static bool inDeviceContext(mlir::Operation *op) {
return false;
}
-static int computeWidth(mlir::Location loc, mlir::Type type,
- fir::KindMapping &kindMap) {
- auto eleTy = fir::unwrapSequenceType(type);
- if (auto t{mlir::dyn_cast<mlir::IntegerType>(eleTy)})
- return t.getWidth() / 8;
- if (auto t{mlir::dyn_cast<mlir::FloatType>(eleTy)})
- return t.getWidth() / 8;
- if (eleTy.isInteger(1))
- return 1;
- if (auto t{mlir::dyn_cast<fir::LogicalType>(eleTy)})
- return kindMap.getLogicalBitsize(t.getFKind()) / 8;
- if (auto t{mlir::dyn_cast<mlir::ComplexType>(eleTy)}) {
- int elemSize =
- mlir::cast<mlir::FloatType>(t.getElementType()).getWidth() / 8;
- return 2 * elemSize;
- }
- if (auto t{mlir::dyn_cast_or_null<fir::CharacterType>(eleTy)})
- return kindMap.getCharacterBitsize(t.getFKind()) / 8;
- mlir::emitError(loc, "unsupported type");
- return 0;
-}
-
struct CUFAllocOpConversion : public mlir::OpRewritePattern<cuf::AllocOp> {
using OpRewritePattern::OpRewritePattern;
@@ -320,7 +298,7 @@ struct CUFAllocOpConversion : public mlir::OpRewritePattern<cuf::AllocOp> {
mlir::Value bytes;
fir::KindMapping kindMap{fir::getKindMapping(mod)};
if (fir::isa_trivial(op.getInType())) {
- int width = computeWidth(loc, op.getInType(), kindMap);
+ int width = cuf::computeElementByteSize(loc, op.getInType(), kindMap);
bytes =
builder.createIntegerConstant(loc, builder.getIndexType(), width);
} else if (auto seqTy = mlir::dyn_cast_or_null<fir::SequenceType>(
@@ -330,7 +308,7 @@ struct CUFAllocOpConversion : public mlir::OpRewritePattern<cuf::AllocOp> {
mlir::Type structTy = typeConverter->convertType(seqTy.getEleTy());
size = dl->getTypeSizeInBits(structTy) / 8;
} else {
- size = computeWidth(loc, seqTy.getEleTy(), kindMap);
+ size = cuf::computeElementByteSize(loc, seqTy.getEleTy(), kindMap);
}
mlir::Value width =
builder.createIntegerConstant(loc, builder.getIndexType(), size);
@@ -704,7 +682,7 @@ struct CUFDataTransferOpConversion
typeConverter->convertType(fir::unwrapSequenceType(dstTy));
width = dl->getTypeSizeInBits(structTy) / 8;
} else {
- width = computeWidth(loc, dstTy, kindMap);
+ width = cuf::computeElementByteSize(loc, dstTy, kindMap);
}
mlir::Value widthValue = mlir::arith::ConstantOp::create(
rewriter, loc, i64Ty, rewriter.getIntegerAttr(i64Ty, width));