[flang] Let FIR AA:getModRef recognize Fortran user procedures late. (#181295)
In order to use FIR AA::getModRef() after `ExternalNameConversion` pass we have to teach it to recognize Fortran user procedures that have already been renamed.
This commit is contained in:
@@ -248,6 +248,15 @@ private:
|
||||
bool symbolMayHaveTargetAttr(mlir::SymbolRefAttr symbol,
|
||||
mlir::Operation *from);
|
||||
|
||||
/// Return true if the given operation is a call to a Fortran user
|
||||
/// procedure.
|
||||
bool isCallToFortranUserProcedure(mlir::Operation *op);
|
||||
|
||||
/// Returns the modify-reference behavior of the given call
|
||||
/// operation `op` on `var`. If `op` is not a fir.call, then
|
||||
/// it returns the conservative ModAndRef result.
|
||||
mlir::ModRefResult getCallModRef(mlir::Operation *op, mlir::Value var);
|
||||
|
||||
/// A map between operations with OpTrait::SymbolTable
|
||||
/// and the SymbolTable objects associated with them.
|
||||
/// TODO: it might be better to initialize just a single SymbolTable
|
||||
|
||||
@@ -495,18 +495,40 @@ static bool isSavedLocal(const fir::AliasAnalysis::Source &src) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool isCallToFortranUserProcedure(fir::CallOp call) {
|
||||
bool AliasAnalysis::isCallToFortranUserProcedure(Operation *op) {
|
||||
fir::CallOp call = dyn_cast<fir::CallOp>(op);
|
||||
if (!call)
|
||||
return false;
|
||||
|
||||
// TODO: indirect calls are excluded by these checks. Maybe some attribute is
|
||||
// needed to flag user calls in this case.
|
||||
if (fir::hasBindcAttr(call))
|
||||
return true;
|
||||
if (std::optional<mlir::SymbolRefAttr> callee = call.getCallee())
|
||||
return fir::NameUniquer::deconstruct(callee->getLeafReference().getValue())
|
||||
.first == fir::NameUniquer::NameKind::PROCEDURE;
|
||||
if (std::optional<SymbolRefAttr> callee = call.getCallee()) {
|
||||
if (fir::NameUniquer::deconstruct(callee->getLeafReference().getValue())
|
||||
.first == fir::NameUniquer::NameKind::PROCEDURE)
|
||||
return true;
|
||||
|
||||
const SymbolTable *symTab = getNearestSymbolTable(call);
|
||||
if (!symTab)
|
||||
return false;
|
||||
|
||||
if (auto funcOp =
|
||||
symTab->lookup<FunctionOpInterface>(callee->getLeafReference()))
|
||||
if (auto name = funcOp->getAttrOfType<StringAttr>(
|
||||
fir::getInternalFuncNameAttrName()))
|
||||
if (fir::NameUniquer::deconstruct(name.getValue()).first ==
|
||||
fir::NameUniquer::NameKind::PROCEDURE)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static ModRefResult getCallModRef(fir::CallOp call, mlir::Value var) {
|
||||
ModRefResult AliasAnalysis::getCallModRef(Operation *op, Value var) {
|
||||
auto call = dyn_cast<fir::CallOp>(op);
|
||||
if (!call)
|
||||
return ModRefResult::getModAndRef();
|
||||
|
||||
// TODO: limit to Fortran functions??
|
||||
// 1. Detect variables that can be accessed indirectly.
|
||||
fir::AliasAnalysis aliasAnalysis;
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
// RUN: fir-opt -pass-pipeline='builtin.module(func.func(test-fir-alias-analysis-modref))' \
|
||||
// RUN: --mlir-disable-threading %s -o /dev/null 2>&1 | FileCheck %s
|
||||
|
||||
// Test that fir.call modref can recognize Fortran user procedures
|
||||
// after ExternalNameConversion pass.
|
||||
|
||||
// CHECK-LABEL: Testing : "test_modref_"
|
||||
// CHECK: callee_procedure -> xx#0: NoModRef
|
||||
func.func @test_modref_() {
|
||||
%0 = fir.dummy_scope : !fir.dscope
|
||||
%1 = fir.alloca f32 {bindc_name = "xx", uniq_name = "_QFtest_modrefExx"}
|
||||
%2 = fir.declare %1 {test.ptr = "xx", uniq_name = "_QFtest_modrefExx"} : (!fir.ref<f32>) -> !fir.ref<f32>
|
||||
fir.call @callee_() {test.ptr = "callee_procedure"} : () -> ()
|
||||
return
|
||||
}
|
||||
func.func private @callee_() attributes {fir.internal_name = "_QPcallee"}
|
||||
Reference in New Issue
Block a user