Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions flang/include/flang/Optimizer/Dialect/FIROps.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "mlir/Dialect/LLVMIR/LLVMAttrs.h"
#include "mlir/Interfaces/LoopLikeInterface.h"
#include "mlir/Interfaces/SideEffectInterfaces.h"
#include "mlir/Interfaces/ViewLikeInterface.h"

namespace fir {

Expand Down
18 changes: 14 additions & 4 deletions flang/include/flang/Optimizer/Dialect/FIROps.td
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
include "mlir/Dialect/Arith/IR/ArithBase.td"
include "mlir/Dialect/Arith/IR/ArithOpsInterfaces.td"
include "mlir/Dialect/LLVMIR/LLVMAttrDefs.td"
include "mlir/Interfaces/ViewLikeInterface.td"
include "flang/Optimizer/Dialect/CUF/Attributes/CUFAttr.td"
include "flang/Optimizer/Dialect/FIRDialect.td"
include "flang/Optimizer/Dialect/FIRTypes.td"
Expand Down Expand Up @@ -1730,8 +1731,9 @@ def fir_ArrayMergeStoreOp : fir_Op<"array_merge_store",
// Record and array type operations
//===----------------------------------------------------------------------===//

def fir_ArrayCoorOp : fir_Op<"array_coor",
[NoMemoryEffect, AttrSizedOperandSegments]> {
def fir_ArrayCoorOp
: fir_Op<"array_coor", [NoMemoryEffect, AttrSizedOperandSegments,
ViewLikeOpInterface]> {

let summary = "Find the coordinate of an element of an array";

Expand Down Expand Up @@ -1774,9 +1776,13 @@ def fir_ArrayCoorOp : fir_Op<"array_coor",

let hasVerifier = 1;
let hasCanonicalizer = 1;
let extraClassDeclaration = [{
mlir::Value getViewSource() { return getMemref(); }
}];
}

def fir_CoordinateOp : fir_Op<"coordinate_of", [NoMemoryEffect]> {
def fir_CoordinateOp
: fir_Op<"coordinate_of", [NoMemoryEffect, ViewLikeOpInterface]> {

let summary = "Finds the coordinate (location) of a value in memory";

Expand Down Expand Up @@ -1828,6 +1834,7 @@ def fir_CoordinateOp : fir_Op<"coordinate_of", [NoMemoryEffect]> {
let extraClassDeclaration = [{
constexpr static int32_t kDynamicIndex = std::numeric_limits<int32_t>::min();
CoordinateIndicesAdaptor getIndices();
mlir::Value getViewSource() { return getRef(); }
}];
}

Expand Down Expand Up @@ -2792,7 +2799,8 @@ def fir_VolatileCastOp : fir_SimpleOneResultOp<"volatile_cast", [Pure]> {
let hasFolder = 1;
}

def fir_ConvertOp : fir_SimpleOneResultOp<"convert", [NoMemoryEffect]> {
def fir_ConvertOp
: fir_SimpleOneResultOp<"convert", [NoMemoryEffect, ViewLikeOpInterface]> {
let summary = "encapsulates all Fortran entity type conversions";

let description = [{
Expand Down Expand Up @@ -2830,6 +2838,8 @@ def fir_ConvertOp : fir_SimpleOneResultOp<"convert", [NoMemoryEffect]> {
static bool isPointerCompatible(mlir::Type ty);
static bool canBeConverted(mlir::Type inType, mlir::Type outType);
static bool areVectorsCompatible(mlir::Type inTy, mlir::Type outTy);
mlir::Value getViewSource() { return getValue(); }
bool isSameStart() { return true; }
}];
let hasCanonicalizer = 1;
}
Expand Down
24 changes: 12 additions & 12 deletions flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -559,10 +559,19 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v,
type = SourceKind::Allocate;
breakFromLoop = true;
})
.Case<fir::ConvertOp>([&](auto op) {
// Skip ConvertOp's and track further through the operand.
v = op->getOperand(0);
.Case<mlir::ViewLikeOpInterface>([&](auto op) {
if (isPointerReference(ty))
attributes.set(Attribute::Pointer);
v = op.getViewSource();
defOp = v.getDefiningOp();
// If the source is a box, and the result is not a box,
// then this is one of the box "unpacking" operations,
// so we should set followingData.
if (mlir::isa<fir::BaseBoxType>(v.getType()) &&
!mlir::isa<fir::BaseBoxType>(ty))
followingData = true;
if (!op.isSameStart())
approximateSource = true;
})
.Case<fir::PackArrayOp>([&](auto op) {
// The packed array is not distinguishable from the original
Expand All @@ -578,15 +587,6 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v,
if (mlir::isa<fir::BaseBoxType>(v.getType()))
followBoxData = true;
})
.Case<fir::ArrayCoorOp, fir::CoordinateOp>([&](auto op) {
if (isPointerReference(ty))
attributes.set(Attribute::Pointer);
v = op->getOperand(0);
defOp = v.getDefiningOp();
if (mlir::isa<fir::BaseBoxType>(v.getType()))
followBoxData = true;
approximateSource = true;
})
.Case<fir::EmboxOp, fir::ReboxOp>([&](auto op) {
if (followBoxData) {
v = op->getOperand(0);
Expand Down
41 changes: 27 additions & 14 deletions mlir/include/mlir/Interfaces/ViewLikeInterface.td
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,34 @@ def ViewLikeOpInterface : OpInterface<"ViewLikeOpInterface"> {
}];
let cppNamespace = "::mlir";

let methods = [
InterfaceMethod<
"Returns the source buffer from which the view is created.",
"::mlir::Value", "getViewSource">,
InterfaceMethod<
/*desc=*/[{ Returns the buffer which the view created. }],
/*retTy=*/"::mlir::Value",
/*methodName=*/"getViewDest",
/*args=*/(ins),
/*methodBody=*/"",
/*defaultImplementation=*/[{
let methods =
[InterfaceMethod<
"Returns the source buffer from which the view is created.",
"::mlir::Value", "getViewSource">,
InterfaceMethod<
/*desc=*/[{ Returns the buffer which the view created. }],
/*retTy=*/"::mlir::Value",
/*methodName=*/"getViewDest",
/*args=*/(ins),
/*methodBody=*/"",
/*defaultImplementation=*/[{
return $_op->getResult(0);
}]
>
];
}]>,
InterfaceMethod<
// TBD: should it be generalized into isPartialView that will
// return true in any of these cases?
// 1. Resulting view is a slice view of the source.
// 2. Resulting view's start does not match the source's start.
// 3. Resulting view's end does not match the source's end.
/*desc=*/
[{ Returns true iff the source buffer and the resulting view start at the same "address". }],
/*retTy=*/"bool",
/*methodName=*/"isSameStart",
/*args=*/(ins),
/*methodBody=*/"",
/*defaultImplementation=*/[{
return false;
}]>];
}

def OffsetSizeAndStrideOpInterface : OpInterface<"OffsetSizeAndStrideOpInterface"> {
Expand Down
4 changes: 4 additions & 0 deletions mlir/lib/Analysis/AliasAnalysis/LocalAliasAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,10 @@ static void collectUnderlyingAddressValues(OpResult result, unsigned maxDepth,
// If this is a view, unwrap to the source.
if (ViewLikeOpInterface view = dyn_cast<ViewLikeOpInterface>(op)) {
if (result == view.getViewDest()) {
// TODO: if view.isSameStart() returns false here,
// we have to make sure that further analysis may return
// PartialAlias for all underlying addresses we are going
// to collect from this point up the def-use.
return collectUnderlyingAddressValues(view.getViewSource(), maxDepth,
visited, output);
}
Expand Down
Loading