Add a verification pass that checks live-in values and symbol references within offload regions are legal for the target execution model. When code is offloaded to a device (e.g., GPU), not all values and symbols from the host context are directly accessible. Data must be explicitly mapped via OpenACC data clauses (copyin, create, present etc.), declared with device attributes, or be trivial scalars that can be passed by value. Similarly, symbol references to globals must have proper `declare` attributes or device-resident data attributes. This pass walks operations implementing `OffloadRegionOpInterface`, which includes OpenACC compute constructs (`acc.parallel`, `acc.kernels`, `acc.serial`) as well as GPU operations like `gpu.launch`. For each region, it uses liveness analysis to identify values flowing into the region and checks their validity using the `OpenACCSupport` analysis. Key features: - Validates live-in values against OpenACC data mapping requirements - Validates symbol references for device accessibility - Supports soft-check mode for diagnostic-only verification - Configurable device_type for target-specific behavior
57 lines
1.8 KiB
C++
57 lines
1.8 KiB
C++
//===- FIROpenACCSupportAnalysis.cpp - FIR OpenACCSupport Analysis -------===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file implements the FIR-specific OpenACCSupport analysis.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "flang/Optimizer/OpenACC/Analysis/FIROpenACCSupportAnalysis.h"
|
|
|
|
#include "flang/Optimizer/Builder/Todo.h"
|
|
#include "flang/Optimizer/Dialect/FIRType.h"
|
|
#include "flang/Optimizer/OpenACC/Support/FIROpenACCUtils.h"
|
|
#include "mlir/Dialect/OpenACC/OpenACCUtils.h"
|
|
|
|
using namespace mlir;
|
|
|
|
namespace fir {
|
|
namespace acc {
|
|
|
|
std::string FIROpenACCSupportAnalysis::getVariableName(Value v) {
|
|
return fir::acc::getVariableName(v, /*preferDemangledName=*/true);
|
|
}
|
|
|
|
std::string FIROpenACCSupportAnalysis::getRecipeName(mlir::acc::RecipeKind kind,
|
|
Type type, Value var) {
|
|
return fir::acc::getRecipeName(kind, type, var);
|
|
}
|
|
|
|
mlir::InFlightDiagnostic
|
|
FIROpenACCSupportAnalysis::emitNYI(Location loc, const Twine &message) {
|
|
TODO(loc, message);
|
|
// Should be unreachable, but we return an actual diagnostic
|
|
// to satisfy the interface.
|
|
return mlir::emitError(loc, "not yet implemented: " + message.str());
|
|
}
|
|
|
|
bool FIROpenACCSupportAnalysis::isValidValueUse(Value v, Region ®ion) {
|
|
// First check using the base utility.
|
|
if (mlir::acc::isValidValueUse(v, region))
|
|
return true;
|
|
|
|
// FIR-specific: fir.logical is a trivial scalar type that can be
|
|
// passed by value.
|
|
if (mlir::isa<fir::LogicalType>(v.getType()))
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
} // namespace acc
|
|
} // namespace fir
|