[Flang][OpenMP] Run Flang-specific OpenMP MLIR passes in bbc

This patch moves the group of OpenMP MLIR passes using after lowering of
Fortran to MLIR into a pipeline to be shared by `flang-new` and `bbc`.
Currently, the `bbc` tool does not produce the expected FIR for offloading-
enabled OpenMP codes due to not running these passes.

Unit tests exercising these passes are updated to check `bbc` output as well.
This commit is contained in:
Sergio Afonso 2023-09-18 12:19:32 +01:00
parent bf7c490ab7
commit fb4bdf361f
No known key found for this signature in database
GPG Key ID: C14FD2E836DE1CBF
9 changed files with 46 additions and 13 deletions

View File

@ -254,6 +254,24 @@ inline void createHLFIRToFIRPassPipeline(
pm.addPass(hlfir::createConvertHLFIRtoFIRPass());
}
/// Create a pass pipeline for handling certain OpenMP transformations needed
/// prior to FIR lowering.
///
/// WARNING: These passes must be run immediately after the lowering to ensure
/// that the FIR is correct with respect to OpenMP operations/attributes.
///
/// \param pm - MLIR pass manager that will hold the pipeline definition.
/// \param isTargetDevice - Whether code is being generated for a target device
/// rather than the host device.
inline void createOpenMPFIRPassPipeline(
mlir::PassManager &pm, bool isTargetDevice) {
pm.addPass(fir::createOMPMarkDeclareTargetPass());
if (isTargetDevice) {
pm.addPass(fir::createOMPEarlyOutliningPass());
pm.addPass(fir::createOMPFunctionFilteringPass());
}
}
#if !defined(FLANG_EXCLUDE_CODEGEN)
inline void createDebugPasses(
mlir::PassManager &pm, llvm::codegenoptions::DebugInfoKind debugLevel) {

View File

@ -70,6 +70,8 @@
#include <memory>
#include <system_error>
#include "flang/Tools/CLOptions.inc"
using namespace Fortran::frontend;
// Declare plugin extension function declarations.
@ -313,12 +315,10 @@ bool CodeGenAction::beginSourceFileAction() {
if (auto offloadMod = llvm::dyn_cast<mlir::omp::OffloadModuleInterface>(
mlirModule->getOperation()))
isDevice = offloadMod.getIsTargetDevice();
pm.addPass(fir::createOMPMarkDeclareTargetPass());
if (isDevice) {
pm.addPass(fir::createOMPEarlyOutliningPass());
pm.addPass(fir::createOMPFunctionFilteringPass());
}
// WARNING: This pipeline must be run immediately after the lowering to
// ensure that the FIR is correct with respect to OpenMP operations/
// attributes.
fir::createOpenMPFIRPassPipeline(pm, isDevice);
}
pm.enableVerifier(/*verifyPasses=*/true);
@ -651,8 +651,6 @@ void GetSymbolsSourcesAction::executeAction() {
CodeGenAction::~CodeGenAction() = default;
#include "flang/Tools/CLOptions.inc"
static llvm::OptimizationLevel
mapToLevel(const Fortran::frontend::CodeGenOptions &opts) {
switch (opts.OptimizationLevel) {

View File

@ -1,8 +1,10 @@
!This test checks that when compiling an OpenMP program for the target device
!CSE is not done across target op region boundaries. It also checks that when
!compiling for the host CSE is done.
!RUN: %flang_fc1 -fopenmp-is-device -emit-mlir -fopenmp %s -o - | fir-opt -cse | FileCheck %s -check-prefix=CHECK-DEVICE
!RUN: %flang_fc1 -fopenmp-is-target-device -emit-mlir -fopenmp %s -o - | fir-opt -cse | FileCheck %s -check-prefix=CHECK-DEVICE
!RUN: %flang_fc1 -emit-mlir -fopenmp %s -o - | fir-opt -cse | FileCheck %s -check-prefix=CHECK-HOST
!RUN: bbc -fopenmp-is-target-device -emit-fir -fopenmp %s -o - | fir-opt -cse | FileCheck %s -check-prefix=CHECK-DEVICE
!RUN: bbc -emit-fir -fopenmp %s -o - | fir-opt -cse | FileCheck %s -check-prefix=CHECK-HOST
!Constant should be present inside target region.
!CHECK-DEVICE: omp.target
@ -19,7 +21,7 @@ subroutine writeIndex(sum)
integer :: myconst1
integer :: myconst2
myconst1 = 10
!$omp target map(from:new_len)
!$omp target map(from:myconst2)
myconst2 = 10
!$omp end target
sum = myconst2 + myconst2

View File

@ -1,5 +1,7 @@
!RUN: %flang_fc1 -emit-fir -fopenmp %s -o - | FileCheck %s
!RUN: %flang_fc1 -emit-fir -fopenmp -fopenmp-is-device %s -o - | FileCheck %s --check-prefix=DEVICE
!RUN: %flang_fc1 -emit-fir -fopenmp -fopenmp-is-target-device %s -o - | FileCheck %s --check-prefix=DEVICE
!RUN: bbc -emit-fir -fopenmp %s -o - | FileCheck %s
!RUN: bbc -emit-fir -fopenmp -fopenmp-is-target-device %s -o - | FileCheck %s --check-prefix=DEVICE
! CHECK-LABEL: func.func @_QPimplicitly_captured
! CHECK-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>{{.*}}}

View File

@ -1,5 +1,7 @@
!RUN: %flang_fc1 -emit-fir -fopenmp %s -o - | FileCheck %s
!RUN: %flang_fc1 -emit-fir -fopenmp -fopenmp-is-device %s -o - | FileCheck %s --check-prefix=DEVICE
!RUN: bbc -emit-fir -fopenmp %s -o - | FileCheck %s
!RUN: bbc -emit-fir -fopenmp -fopenmp-is-target-device %s -o - | FileCheck %s --check-prefix=DEVICE
! DEVICE-LABEL: func.func @_QPimplicit_capture
! DEVICE-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to)>{{.*}}}

View File

@ -2,6 +2,8 @@
! RUN: %flang_fc1 -fopenmp -emit-mlir %s -o - | FileCheck --check-prefix=MLIR %s
! RUN: %flang_fc1 -fopenmp -fopenmp-is-target-device -emit-llvm %s -o - | FileCheck --check-prefix=LLVM %s
! RUN: %flang_fc1 -fopenmp -fopenmp-is-target-device -emit-mlir %s -o - | FileCheck --check-prefix=MLIR %s
! RUN: bbc -fopenmp -emit-fir %s -o - | FileCheck --check-prefixes=MLIR-HOST,MLIR-ALL %s
! RUN: bbc -fopenmp -fopenmp-is-target-device -emit-fir %s -o - | FileCheck --check-prefixes=MLIR-DEVICE,MLIR-ALL %s
! MLIR: func.func @{{.*}}implicit_invocation() attributes {omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to)>}
! MLIR: return

View File

@ -2,6 +2,8 @@
! RUN: %flang_fc1 -fopenmp -emit-mlir %s -o - | FileCheck --check-prefixes=MLIR-HOST,MLIR-ALL %s
! RUN: %flang_fc1 -fopenmp -fopenmp-is-target-device -emit-llvm %s -o - | FileCheck --check-prefixes=LLVM-DEVICE,LLVM-ALL %s
! RUN: %flang_fc1 -fopenmp -fopenmp-is-target-device -emit-mlir %s -o - | FileCheck --check-prefixes=MLIR-DEVICE,MLIR-ALL %s
! RUN: bbc -fopenmp -emit-fir %s -o - | FileCheck --check-prefixes=MLIR-HOST,MLIR-ALL %s
! RUN: bbc -fopenmp -fopenmp-is-target-device -emit-fir %s -o - | FileCheck --check-prefixes=MLIR-DEVICE,MLIR-ALL %s
! Check that the correct LLVM IR functions are kept for the host and device
! after running the whole set of translation and transformation passes from

View File

@ -1,7 +1,9 @@
!REQUIRES: amdgpu-registered-target
!RUN: %flang_fc1 -triple amdgcn-amd-amdhsa -emit-fir -fopenmp -fopenmp-is-device %s -o - | FileCheck %s
!RUN: %flang_fc1 -triple x86_64-unknown-linux-gnu -emit-fir -fopenmp -fopenmp-is-device %s -o - | FileCheck %s
!RUN: %flang_fc1 -triple amdgcn-amd-amdhsa -emit-fir -fopenmp -fopenmp-is-target-device %s -o - | FileCheck %s
!RUN: %flang_fc1 -triple x86_64-unknown-linux-gnu -emit-fir -fopenmp -fopenmp-is-target-device %s -o - | FileCheck %s
!RUN: bbc -emit-fir -fopenmp -fopenmp-is-target-device %s -o - | FileCheck %s
!RUN: bbc -emit-fir -fopenmp -fopenmp-is-gpu -fopenmp-is-target-device %s -o - | FileCheck %s
!CHECK: func.func @_QPtarget_function

View File

@ -329,6 +329,11 @@ static mlir::LogicalResult convertFortranSourceToMLIR(
// Otherwise run the default passes.
mlir::PassManager pm(mlirModule->getName(),
mlir::OpPassManager::Nesting::Implicit);
if (enableOpenMP)
// WARNING: This pipeline must be run immediately after the lowering to
// ensure that the FIR is correct with respect to OpenMP operations/
// attributes.
fir::createOpenMPFIRPassPipeline(pm, enableOpenMPDevice);
pm.enableVerifier(/*verifyPasses=*/true);
(void)mlir::applyPassManagerCLOptions(pm);
if (passPipeline.hasAnyOccurrences()) {