https://github.com/Radu2k updated https://github.com/llvm/llvm-project/pull/74598
>From fda39a4d196c6cdafe3ee42358c962ef0173aaca Mon Sep 17 00:00:00 2001 From: Radu2k <radu.sala...@arm.com> Date: Wed, 6 Dec 2023 14:39:24 +0000 Subject: [PATCH 01/16] Pass to add frame pointer attribute --- .../include/flang/Frontend/CodeGenOptions.def | 1 + .../flang/Optimizer/Transforms/Passes.h | 8 ++ .../flang/Optimizer/Transforms/Passes.td | 17 ++++ flang/include/flang/Tools/CLOptions.inc | 4 + flang/include/flang/Tools/CrossToolHelpers.h | 2 + flang/lib/Frontend/CompilerInvocation.cpp | 13 +++ flang/lib/Optimizer/Transforms/CMakeLists.txt | 1 + .../lib/Optimizer/Transforms/FunctionAttr.cpp | 97 +++++++++++++++++++ flang/test/Driver/func-attr.f90 | 12 +++ .../test/Driver/mlir-debug-pass-pipeline.f90 | 2 + flang/test/Driver/mlir-pass-pipeline.f90 | 2 + flang/test/Driver/save-mlir-temps.f90 | 4 +- flang/test/Fir/basic-program.fir | 2 + flang/test/Fir/box-offset-codegen.fir | 8 +- flang/test/Fir/polymorphic.fir | 8 +- flang/test/Fir/tbaa-codegen.fir | 2 +- flang/test/Fir/tbaa-codegen2.fir | 2 +- 17 files changed, 173 insertions(+), 12 deletions(-) create mode 100644 flang/lib/Optimizer/Transforms/FunctionAttr.cpp create mode 100644 flang/test/Driver/func-attr.f90 diff --git a/flang/include/flang/Frontend/CodeGenOptions.def b/flang/include/flang/Frontend/CodeGenOptions.def index 72e7bdab12a14d..774f225974d7ea 100644 --- a/flang/include/flang/Frontend/CodeGenOptions.def +++ b/flang/include/flang/Frontend/CodeGenOptions.def @@ -38,6 +38,7 @@ CODEGENOPT(Underscoring, 1, 1) ENUM_CODEGENOPT(RelocationModel, llvm::Reloc::Model, 3, llvm::Reloc::PIC_) ///< Name of the relocation model to use. ENUM_CODEGENOPT(DebugInfo, llvm::codegenoptions::DebugInfoKind, 4, llvm::codegenoptions::NoDebugInfo) ///< Level of debug info to generate ENUM_CODEGENOPT(VecLib, llvm::driver::VectorLibrary, 3, llvm::driver::VectorLibrary::NoLibrary) ///< Vector functions library to use +ENUM_CODEGENOPT(FramePointer, llvm::FramePointerKind, 2, llvm::FramePointerKind::None) /// frame-pointer: all,non-leaf,none #undef CODEGENOPT #undef ENUM_CODEGENOPT diff --git a/flang/include/flang/Optimizer/Transforms/Passes.h b/flang/include/flang/Optimizer/Transforms/Passes.h index 92bc7246eca700..c5f09fc2581bd3 100644 --- a/flang/include/flang/Optimizer/Transforms/Passes.h +++ b/flang/include/flang/Optimizer/Transforms/Passes.h @@ -12,6 +12,7 @@ #include "flang/Optimizer/Dialect/FIROps.h" #include "mlir/Pass/Pass.h" #include "mlir/Pass/PassRegistry.h" +#include "llvm/Support/CodeGen.h" #include <memory> namespace mlir { @@ -83,6 +84,13 @@ std::unique_ptr<mlir::Pass> createVScaleAttrPass(); std::unique_ptr<mlir::Pass> createVScaleAttrPass(std::pair<unsigned, unsigned> vscaleAttr); +struct FunctionAttrTypes{ + llvm::FramePointerKind framePointerKind; +}; + +std::unique_ptr<mlir::Pass> createFunctionAttrPass(); +std::unique_ptr<mlir::Pass> createFunctionAttrPass(FunctionAttrTypes &functionAttr); + // declarative passes #define GEN_PASS_REGISTRATION #include "flang/Optimizer/Transforms/Passes.h.inc" diff --git a/flang/include/flang/Optimizer/Transforms/Passes.td b/flang/include/flang/Optimizer/Transforms/Passes.td index c3768fd2d689c1..eddf94e162e9c9 100644 --- a/flang/include/flang/Optimizer/Transforms/Passes.td +++ b/flang/include/flang/Optimizer/Transforms/Passes.td @@ -349,4 +349,21 @@ def VScaleAttr : Pass<"vscale-attr", "mlir::func::FuncOp"> { let constructor = "::fir::createVScaleAttrPass()"; } +def FunctionAttr : Pass<"function-attr", "mlir::func::FuncOp"> { + let summary = "Enhance functions with different attributes"; + let description = [{ This feature introduces a general attribute aimed at customizing function characteristics. + Options include: + Add "frame-pointer" attribute to functions: Set an attribute for the frame pointer on functions, to enable + the compiler, to avoid saving the frame pointer in a register in functions where it is unnecessary. + This eliminates the need for instructions to save, establish, and restore frame pointers, while also freeing up an additional register in numerous functions. + However, this approach can make debugging unfeasible on certain machines. + }]; + let options = [ + Option<"framePointerKind", "frame-pointer", + "mlir::LLVM::framePointerKind::FramePointerKind", /*default=*/"mlir::LLVM::framePointerKind::FramePointerKind{}", + "frame pointer">, + ]; + let constructor = "::fir::createFunctionAttrPass()"; +} + #endif // FLANG_OPTIMIZER_TRANSFORMS_PASSES diff --git a/flang/include/flang/Tools/CLOptions.inc b/flang/include/flang/Tools/CLOptions.inc index d3e4dc6cd4a243..3494e588b34606 100644 --- a/flang/include/flang/Tools/CLOptions.inc +++ b/flang/include/flang/Tools/CLOptions.inc @@ -311,6 +311,10 @@ inline void createDefaultFIRCodeGenPassPipeline( if (config.VScaleMin != 0) pm.addPass(fir::createVScaleAttrPass({config.VScaleMin, config.VScaleMax})); + fir::FunctionAttrTypes functionAttrs; + functionAttrs.framePointerKind = config.FramePointerKind; + pm.addPass(fir::createFunctionAttrPass(functionAttrs)); + fir::addFIRToLLVMPass(pm, config); } diff --git a/flang/include/flang/Tools/CrossToolHelpers.h b/flang/include/flang/Tools/CrossToolHelpers.h index ddec70fa9824c5..e8722ebf77cd19 100644 --- a/flang/include/flang/Tools/CrossToolHelpers.h +++ b/flang/include/flang/Tools/CrossToolHelpers.h @@ -35,6 +35,7 @@ struct MLIRToLLVMPassPipelineConfig { LoopVersioning = opts.LoopVersioning; DebugInfo = opts.getDebugInfo(); AliasAnalysis = opts.AliasAnalysis; + FramePointerKind = opts.getFramePointer(); } llvm::OptimizationLevel OptLevel; ///< optimisation level @@ -44,6 +45,7 @@ struct MLIRToLLVMPassPipelineConfig { bool AliasAnalysis = false; ///< Add TBAA tags to generated LLVMIR llvm::codegenoptions::DebugInfoKind DebugInfo = llvm::codegenoptions::NoDebugInfo; ///< Debug info generation. + llvm::FramePointerKind FramePointerKind; unsigned VScaleMin = 0; ///< SVE vector range minimum. unsigned VScaleMax = 0; ///< SVE vector range maximum. }; diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index b3f32bb241d068..a89a93c2d3197e 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -245,6 +245,19 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts, opts.AliasAnalysis = opts.OptimizationLevel > 0; + if (const llvm::opt::Arg *a = + args.getLastArg(clang::driver::options::OPT_mframe_pointer_EQ)) { + llvm::StringRef s = a->getValue(); + assert(s == "none" || s == "non-leaf"|| s == "all"); + if (s == "none") + opts.setFramePointer(llvm::FramePointerKind::None); + else + if (s == "non-leaf") + opts.setFramePointer(llvm::FramePointerKind::NonLeaf); + else + opts.setFramePointer(llvm::FramePointerKind::All); + } + for (auto *a : args.filtered(clang::driver::options::OPT_fpass_plugin_EQ)) opts.LLVMPassPlugins.push_back(a->getValue()); diff --git a/flang/lib/Optimizer/Transforms/CMakeLists.txt b/flang/lib/Optimizer/Transforms/CMakeLists.txt index 03b67104a93b57..fc067ad3585395 100644 --- a/flang/lib/Optimizer/Transforms/CMakeLists.txt +++ b/flang/lib/Optimizer/Transforms/CMakeLists.txt @@ -20,6 +20,7 @@ add_flang_library(FIRTransforms OMPFunctionFiltering.cpp OMPMarkDeclareTarget.cpp VScaleAttr.cpp + FunctionAttr.cpp DEPENDS FIRDialect diff --git a/flang/lib/Optimizer/Transforms/FunctionAttr.cpp b/flang/lib/Optimizer/Transforms/FunctionAttr.cpp new file mode 100644 index 00000000000000..dd7e3947f09e54 --- /dev/null +++ b/flang/lib/Optimizer/Transforms/FunctionAttr.cpp @@ -0,0 +1,97 @@ +//===- FunctionAttr.cpp -------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +/// \file +/// This pass adds a `vscale_range` attribute to function definitions. +/// The attribute is used for scalable vector operations on Arm processors +/// and should only be run on processors that support this feature. [It is +/// likely harmless to run it on something else, but it is also not valuable]. +//===----------------------------------------------------------------------===// + +#include "flang/ISO_Fortran_binding_wrapper.h" +#include "flang/Optimizer/Builder/BoxValue.h" +#include "flang/Optimizer/Builder/FIRBuilder.h" +#include "flang/Optimizer/Builder/Runtime/Inquiry.h" +#include "flang/Optimizer/Dialect/FIRDialect.h" +#include "flang/Optimizer/Dialect/FIROps.h" +#include "flang/Optimizer/Dialect/FIRType.h" +#include "flang/Optimizer/Dialect/Support/FIRContext.h" +#include "flang/Optimizer/Dialect/Support/KindMapping.h" +#include "flang/Optimizer/Transforms/Passes.h" +#include "mlir/Dialect/LLVMIR/LLVMAttrs.h" +#include "mlir/Dialect/LLVMIR/LLVMDialect.h" +#include "mlir/IR/Matchers.h" +#include "mlir/IR/TypeUtilities.h" +#include "mlir/Pass/Pass.h" +#include "mlir/Transforms/DialectConversion.h" +#include "mlir/Transforms/GreedyPatternRewriteDriver.h" +#include "mlir/Transforms/RegionUtils.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" + +#include <algorithm> + +namespace fir { +#define GEN_PASS_DECL_FUNCTIONATTR +#define GEN_PASS_DEF_FUNCTIONATTR +#include "flang/Optimizer/Transforms/Passes.h.inc" +} // namespace fir + +#define DEBUG_TYPE "func-attr" + +namespace { + +class FunctionAttrPass : public fir::impl::FunctionAttrBase<FunctionAttrPass> { +public: + FunctionAttrPass(const fir::FunctionAttrOptions &options) { + framePointerKind = options.framePointerKind; + } + FunctionAttrPass() { + + } + void runOnOperation() override; +}; + +} // namespace + +void FunctionAttrPass::runOnOperation() { + LLVM_DEBUG(llvm::dbgs() << "=== Begin " DEBUG_TYPE " ===\n"); + mlir::func::FuncOp func = getOperation(); + + LLVM_DEBUG(llvm::dbgs() << "Func-name:" << func.getSymName() << "\n"); + + auto context = &getContext(); + + func->setAttr("frame_pointer", mlir::LLVM::FramePointerKindAttr::get( context, framePointerKind )); + + LLVM_DEBUG(llvm::dbgs() << "=== End " DEBUG_TYPE " ===\n"); +} + +std::unique_ptr<mlir::Pass> fir::createFunctionAttrPass(fir::FunctionAttrTypes &functionAttr) { + FunctionAttrOptions opts; + + // Frame pointer + switch (functionAttr.framePointerKind) { + case llvm::FramePointerKind::None: + opts.framePointerKind = mlir::LLVM::framePointerKind::symbolizeFramePointerKind(0).value(); + break; + case llvm::FramePointerKind::NonLeaf: + opts.framePointerKind = mlir::LLVM::framePointerKind::symbolizeFramePointerKind(1).value(); + break; + case llvm::FramePointerKind::All: + opts.framePointerKind = mlir::LLVM::framePointerKind::symbolizeFramePointerKind(2).value(); + break; + } + + return std::make_unique<FunctionAttrPass>(opts); +} + +std::unique_ptr<mlir::Pass> fir::createFunctionAttrPass() { + return std::make_unique<FunctionAttrPass>(); +} diff --git a/flang/test/Driver/func-attr.f90 b/flang/test/Driver/func-attr.f90 new file mode 100644 index 00000000000000..10fe4657746e44 --- /dev/null +++ b/flang/test/Driver/func-attr.f90 @@ -0,0 +1,12 @@ +! RUN: %flang_fc1 -triple aarch64-none-none -mframe-pointer=none -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-NONEFP +! RUN: %flang_fc1 -triple aarch64-none-none -mframe-pointer=non-leaf -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-NONLEAFFP +! RUN: %flang_fc1 -triple aarch64-none-none -mframe-pointer=all -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-ALLFP + +! CHECK-LABEL: @func_() #0 +subroutine func +end subroutine func + +! CHECK-NONEFP: attributes #0 = { "frame-pointer"="none" } +! CHECK-NONLEAFFP: attributes #0 = { "frame-pointer"="non-leaf" } +! CHECK-ALLFP: attributes #0 = { "frame-pointer"="all" } + diff --git a/flang/test/Driver/mlir-debug-pass-pipeline.f90 b/flang/test/Driver/mlir-debug-pass-pipeline.f90 index a3ff416f4d7795..701537b339de9f 100644 --- a/flang/test/Driver/mlir-debug-pass-pipeline.f90 +++ b/flang/test/Driver/mlir-debug-pass-pipeline.f90 @@ -82,5 +82,7 @@ ! ALL-NEXT: ExternalNameConversion ! DEBUG-NEXT: AddDebugFoundation ! NO-DEBUG-NOT: AddDebugFoundation +! ALL-NEXT: 'func.func' Pipeline +! ALL-NEXT: FunctionAttr ! ALL-NEXT: FIRToLLVMLowering ! ALL-NOT: LLVMIRLoweringPass diff --git a/flang/test/Driver/mlir-pass-pipeline.f90 b/flang/test/Driver/mlir-pass-pipeline.f90 index 3d8c42f123e2eb..f0dcf68195c4be 100644 --- a/flang/test/Driver/mlir-pass-pipeline.f90 +++ b/flang/test/Driver/mlir-pass-pipeline.f90 @@ -73,5 +73,7 @@ ! ALL-NEXT: (S) 0 num-dce'd - Number of operations eliminated ! ALL-NEXT: TargetRewrite ! ALL-NEXT: ExternalNameConversion +! ALL-NEXT: 'func.func' Pipeline +! ALL-NEXT: FunctionAttr ! ALL-NEXT: FIRToLLVMLowering ! ALL-NOT: LLVMIRLoweringPass diff --git a/flang/test/Driver/save-mlir-temps.f90 b/flang/test/Driver/save-mlir-temps.f90 index 50bc83030caa91..1c8935fbd7aac9 100644 --- a/flang/test/Driver/save-mlir-temps.f90 +++ b/flang/test/Driver/save-mlir-temps.f90 @@ -51,9 +51,9 @@ ! Content to check from the MLIR outputs !-------------------------- ! MLIR-FIR-NOT: llvm.func -! MLIR-FIR: func.func @{{.*}}main() { +! MLIR-FIR: func.func @{{.*}}main(){{.*}}{ ! MLIR-FIR-NOT: func.func -! MLIR-LLVMIR: llvm.func @{{.*}}main() { +! MLIR-LLVMIR: llvm.func @{{.*}}main(){{.*}}{ end program diff --git a/flang/test/Fir/basic-program.fir b/flang/test/Fir/basic-program.fir index d8a9e74c318ce1..601e34ee04c275 100644 --- a/flang/test/Fir/basic-program.fir +++ b/flang/test/Fir/basic-program.fir @@ -80,5 +80,7 @@ func.func @_QQmain() { // PASSES-NEXT: CodeGenRewrite // PASSES-NEXT: (S) 0 num-dce'd - Number of operations eliminated // PASSES-NEXT: TargetRewrite +// PASSES-NEXT: 'func.func' Pipeline +// PASSES-NEXT: FunctionAttr // PASSES-NEXT: FIRToLLVMLowering // PASSES-NEXT: LLVMIRLoweringPass diff --git a/flang/test/Fir/box-offset-codegen.fir b/flang/test/Fir/box-offset-codegen.fir index 600555cd94cea3..389ceebcc065c2 100644 --- a/flang/test/Fir/box-offset-codegen.fir +++ b/flang/test/Fir/box-offset-codegen.fir @@ -7,7 +7,7 @@ func.func @scalar_addr(%scalar : !fir.ref<!fir.box<!fir.type<t>>>) -> !fir.llvm_ return %addr : !fir.llvm_ptr<!fir.ref<!fir.type<t>>> } // CHECK-LABEL: define ptr @scalar_addr( -// CHECK-SAME: ptr %[[BOX:.*]]) { +// CHECK-SAME: ptr %[[BOX:.*]]){{.*}}{ // CHECK: %[[VAL_0:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] }, ptr %[[BOX]], i32 0, i32 0 // CHECK: ret ptr %[[VAL_0]] @@ -16,7 +16,7 @@ func.func @scalar_tdesc(%scalar : !fir.ref<!fir.box<!fir.type<t>>>) -> !fir.llvm return %tdesc : !fir.llvm_ptr<!fir.tdesc<!fir.type<t>>> } // CHECK-LABEL: define ptr @scalar_tdesc( -// CHECK-SAME: ptr %[[BOX:.*]]) { +// CHECK-SAME: ptr %[[BOX:.*]]){{.*}}{ // CHECK: %[[VAL_0:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] }, ptr %[[BOX]], i32 0, i32 7 // CHECK: ret ptr %[[VAL_0]] @@ -25,7 +25,7 @@ func.func @array_addr(%array : !fir.ref<!fir.class<!fir.ptr<!fir.array<?x!fir.ty return %addr : !fir.llvm_ptr<!fir.ptr<!fir.array<?x!fir.type<t>>>> } // CHECK-LABEL: define ptr @array_addr( -// CHECK-SAME: ptr %[[BOX:.*]]) { +// CHECK-SAME: ptr %[[BOX:.*]]){{.*}}{ // CHECK: %[[VAL_0:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] }, ptr %[[BOX]], i32 0, i32 0 // CHECK: ret ptr %[[VAL_0]] @@ -34,6 +34,6 @@ func.func @array_tdesc(%array : !fir.ref<!fir.class<!fir.ptr<!fir.array<?x!fir.t return %tdesc : !fir.llvm_ptr<!fir.tdesc<!fir.type<t>>> } // CHECK-LABEL: define ptr @array_tdesc( -// CHECK-SAME: ptr %[[BOX:.*]]) { +// CHECK-SAME: ptr %[[BOX:.*]]){{.*}}{ // CHECK: %[[VAL_0:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] }, ptr %[[BOX]], i32 0, i32 8 // CHECK: ret ptr %[[VAL_0]] diff --git a/flang/test/Fir/polymorphic.fir b/flang/test/Fir/polymorphic.fir index ce8e43b0be6565..ecdcdeb5753106 100644 --- a/flang/test/Fir/polymorphic.fir +++ b/flang/test/Fir/polymorphic.fir @@ -10,7 +10,7 @@ func.func @_QMpolymorphic_testPtest_allocate_unlimited_polymorphic_non_derived() return } -// CHECK-LABEL: define void @_QMpolymorphic_testPtest_allocate_unlimited_polymorphic_non_derived() { +// CHECK-LABEL: define void @_QMpolymorphic_testPtest_allocate_unlimited_polymorphic_non_derived(){{.*}}{ // CHECK: %[[MEM:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] } // CHECK: %[[DESC:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] }, i64 1 // CHECK: store { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] } { ptr null, i64 0, i32 20180515, i8 0, i8 -1, i8 1, i8 1, ptr null, [1 x i64] undef }, ptr %[[MEM]] @@ -87,7 +87,7 @@ func.func @_QMunlimitedPsub1(%arg0: !fir.class<!fir.array<?xnone>> {fir.bindc_na } // CHECK-LABEL: define void @_QMunlimitedPsub1( -// CHECK-SAME: ptr %[[ARRAY:.*]]) { +// CHECK-SAME: ptr %[[ARRAY:.*]]){{.*}}{ // CHECK: %[[BOX:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] } // CHECK: %{{.}} = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] }, ptr %[[ARRAY]], i32 0, i32 7, i32 0, i32 2 // CHECK: %[[TYPE_DESC_GEP:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] }, ptr %[[ARRAY]], i32 0, i32 8 @@ -151,7 +151,7 @@ func.func @_QQmain() { return } -// CHECK-LABEL: define void @_QQmain() { +// CHECK-LABEL: define void @_QQmain(){{.*}}{ // CHECK: %[[CLASS_NONE:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] } // CHECK: %[[DESC:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] }, i64 1 // CHECK: store { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] } { ptr @_QMmod1Ea, i64 ptrtoint (ptr getelementptr (%_QMmod1TtK2, ptr null, i32 1) to i64), i32 20180515, i8 0, i8 42, i8 1, i8 1, ptr @_QMmod1E.dt.t.2, [1 x i64] undef }, ptr %[[CLASS_NONE]], align 8 @@ -175,7 +175,7 @@ func.func @_QMmod2Pinitp(%arg0: !fir.ref<!fir.class<!fir.ptr<none>>> {fir.bindc_ func.func private @_FortranAPointerAssociate(!fir.ref<!fir.box<none>>, !fir.box<none>) -> none attributes {fir.runtime} // CHECK-LABEL: define void @_QMmod2Pinitp( -// CHECK-SAME: ptr %[[ARG0:.*]]) { +// CHECK-SAME: ptr %[[ARG0:.*]]){{.*}}{ // CHECK: %[[ALLOCA_CLASS_NONE:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] } // CHECK: %[[LOAD:.*]] = load { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] }, ptr %[[ARG0]] // CHECK: store { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] } %[[LOAD]], ptr %[[ALLOCA_CLASS_NONE]] diff --git a/flang/test/Fir/tbaa-codegen.fir b/flang/test/Fir/tbaa-codegen.fir index fd0eb9c7304ee3..87bb15c0fea6ca 100644 --- a/flang/test/Fir/tbaa-codegen.fir +++ b/flang/test/Fir/tbaa-codegen.fir @@ -28,7 +28,7 @@ module attributes {fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.targ } // CHECK-LABEL: define void @_QPsimple( -// CHECK-SAME: ptr %[[ARG0:.*]]) { +// CHECK-SAME: ptr %[[ARG0:.*]]){{.*}}{ // [...] // load a(2): // CHECK: %[[VAL20:.*]] = getelementptr i8, ptr %{{.*}}, i64 %{{.*}} diff --git a/flang/test/Fir/tbaa-codegen2.fir b/flang/test/Fir/tbaa-codegen2.fir index d73a7b96a5386e..e649c06731c6ba 100644 --- a/flang/test/Fir/tbaa-codegen2.fir +++ b/flang/test/Fir/tbaa-codegen2.fir @@ -60,7 +60,7 @@ module attributes {fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.targ } } // CHECK-LABEL: define void @_QPfunc( -// CHECK-SAME: ptr %[[ARG0:.*]]) { +// CHECK-SAME: ptr %[[ARG0:.*]]){{.*}}{ // [...] // CHECK: %[[VAL5:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, ptr %[[ARG0]], i32 0, i32 7, i32 0, i32 0 // box access: >From 85b8de68497babe9c8bf65e085faa06b4ab6ef6b Mon Sep 17 00:00:00 2001 From: Radu2k <radu.sala...@arm.com> Date: Wed, 6 Dec 2023 15:48:30 +0000 Subject: [PATCH 02/16] Fix formatting issues --- .../flang/Optimizer/Transforms/Passes.h | 7 +++--- flang/lib/Frontend/CompilerInvocation.cpp | 9 +++---- .../lib/Optimizer/Transforms/FunctionAttr.cpp | 25 +++++++++++-------- 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/flang/include/flang/Optimizer/Transforms/Passes.h b/flang/include/flang/Optimizer/Transforms/Passes.h index c5f09fc2581bd3..6010b6cd23405f 100644 --- a/flang/include/flang/Optimizer/Transforms/Passes.h +++ b/flang/include/flang/Optimizer/Transforms/Passes.h @@ -84,12 +84,13 @@ std::unique_ptr<mlir::Pass> createVScaleAttrPass(); std::unique_ptr<mlir::Pass> createVScaleAttrPass(std::pair<unsigned, unsigned> vscaleAttr); -struct FunctionAttrTypes{ - llvm::FramePointerKind framePointerKind; +struct FunctionAttrTypes { + llvm::FramePointerKind framePointerKind; }; std::unique_ptr<mlir::Pass> createFunctionAttrPass(); -std::unique_ptr<mlir::Pass> createFunctionAttrPass(FunctionAttrTypes &functionAttr); +std::unique_ptr<mlir::Pass> +createFunctionAttrPass(FunctionAttrTypes &functionAttr); // declarative passes #define GEN_PASS_REGISTRATION diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index a89a93c2d3197e..e9348a72b29895 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -248,14 +248,13 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts, if (const llvm::opt::Arg *a = args.getLastArg(clang::driver::options::OPT_mframe_pointer_EQ)) { llvm::StringRef s = a->getValue(); - assert(s == "none" || s == "non-leaf"|| s == "all"); + assert(s == "none" || s == "non-leaf" || s == "all"); if (s == "none") opts.setFramePointer(llvm::FramePointerKind::None); + else if (s == "non-leaf") + opts.setFramePointer(llvm::FramePointerKind::NonLeaf); else - if (s == "non-leaf") - opts.setFramePointer(llvm::FramePointerKind::NonLeaf); - else - opts.setFramePointer(llvm::FramePointerKind::All); + opts.setFramePointer(llvm::FramePointerKind::All); } for (auto *a : args.filtered(clang::driver::options::OPT_fpass_plugin_EQ)) diff --git a/flang/lib/Optimizer/Transforms/FunctionAttr.cpp b/flang/lib/Optimizer/Transforms/FunctionAttr.cpp index dd7e3947f09e54..26ddb52ae75328 100644 --- a/flang/lib/Optimizer/Transforms/FunctionAttr.cpp +++ b/flang/lib/Optimizer/Transforms/FunctionAttr.cpp @@ -52,9 +52,7 @@ class FunctionAttrPass : public fir::impl::FunctionAttrBase<FunctionAttrPass> { FunctionAttrPass(const fir::FunctionAttrOptions &options) { framePointerKind = options.framePointerKind; } - FunctionAttrPass() { - - } + FunctionAttrPass() {} void runOnOperation() override; }; @@ -67,31 +65,36 @@ void FunctionAttrPass::runOnOperation() { LLVM_DEBUG(llvm::dbgs() << "Func-name:" << func.getSymName() << "\n"); auto context = &getContext(); - - func->setAttr("frame_pointer", mlir::LLVM::FramePointerKindAttr::get( context, framePointerKind )); + + func->setAttr("frame_pointer", mlir::LLVM::FramePointerKindAttr::get( + context, framePointerKind)); LLVM_DEBUG(llvm::dbgs() << "=== End " DEBUG_TYPE " ===\n"); } -std::unique_ptr<mlir::Pass> fir::createFunctionAttrPass(fir::FunctionAttrTypes &functionAttr) { +std::unique_ptr<mlir::Pass> +fir::createFunctionAttrPass(fir::FunctionAttrTypes &functionAttr) { FunctionAttrOptions opts; - // Frame pointer + // Frame pointer switch (functionAttr.framePointerKind) { case llvm::FramePointerKind::None: - opts.framePointerKind = mlir::LLVM::framePointerKind::symbolizeFramePointerKind(0).value(); + opts.framePointerKind = + mlir::LLVM::framePointerKind::symbolizeFramePointerKind(0).value(); break; case llvm::FramePointerKind::NonLeaf: - opts.framePointerKind = mlir::LLVM::framePointerKind::symbolizeFramePointerKind(1).value(); + opts.framePointerKind = + mlir::LLVM::framePointerKind::symbolizeFramePointerKind(1).value(); break; case llvm::FramePointerKind::All: - opts.framePointerKind = mlir::LLVM::framePointerKind::symbolizeFramePointerKind(2).value(); + opts.framePointerKind = + mlir::LLVM::framePointerKind::symbolizeFramePointerKind(2).value(); break; } return std::make_unique<FunctionAttrPass>(opts); } - + std::unique_ptr<mlir::Pass> fir::createFunctionAttrPass() { return std::make_unique<FunctionAttrPass>(); } >From 6e443501327d67d932307dc140b459fff1f3fe15 Mon Sep 17 00:00:00 2001 From: Radu2k <radu.sala...@arm.com> Date: Thu, 7 Dec 2023 10:05:25 +0000 Subject: [PATCH 03/16] Minor changes to address review comments --- flang/include/flang/Optimizer/Transforms/Passes.td | 8 +++++--- flang/include/flang/Tools/CrossToolHelpers.h | 3 ++- flang/lib/Optimizer/Transforms/FunctionAttr.cpp | 6 +++--- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/flang/include/flang/Optimizer/Transforms/Passes.td b/flang/include/flang/Optimizer/Transforms/Passes.td index eddf94e162e9c9..2078f37b5e65eb 100644 --- a/flang/include/flang/Optimizer/Transforms/Passes.td +++ b/flang/include/flang/Optimizer/Transforms/Passes.td @@ -353,9 +353,11 @@ def FunctionAttr : Pass<"function-attr", "mlir::func::FuncOp"> { let summary = "Enhance functions with different attributes"; let description = [{ This feature introduces a general attribute aimed at customizing function characteristics. Options include: - Add "frame-pointer" attribute to functions: Set an attribute for the frame pointer on functions, to enable - the compiler, to avoid saving the frame pointer in a register in functions where it is unnecessary. - This eliminates the need for instructions to save, establish, and restore frame pointers, while also freeing up an additional register in numerous functions. + Add "frame-pointer" attribute to functions: Set an attribute for the frame + pointer on functions, to avoid saving the frame pointer in a register in + functions where it is unnecessary. + This eliminates the need for instructions to save, establish, and restore + frame pointers, while also freeing up an additional register in numerous functions. However, this approach can make debugging unfeasible on certain machines. }]; let options = [ diff --git a/flang/include/flang/Tools/CrossToolHelpers.h b/flang/include/flang/Tools/CrossToolHelpers.h index e8722ebf77cd19..11f6735049f704 100644 --- a/flang/include/flang/Tools/CrossToolHelpers.h +++ b/flang/include/flang/Tools/CrossToolHelpers.h @@ -45,7 +45,8 @@ struct MLIRToLLVMPassPipelineConfig { bool AliasAnalysis = false; ///< Add TBAA tags to generated LLVMIR llvm::codegenoptions::DebugInfoKind DebugInfo = llvm::codegenoptions::NoDebugInfo; ///< Debug info generation. - llvm::FramePointerKind FramePointerKind; + llvm::FramePointerKind FramePointerKind = + llvm::FramePointerKind::None; unsigned VScaleMin = 0; ///< SVE vector range minimum. unsigned VScaleMax = 0; ///< SVE vector range maximum. }; diff --git a/flang/lib/Optimizer/Transforms/FunctionAttr.cpp b/flang/lib/Optimizer/Transforms/FunctionAttr.cpp index 26ddb52ae75328..1c6238dec5063d 100644 --- a/flang/lib/Optimizer/Transforms/FunctionAttr.cpp +++ b/flang/lib/Optimizer/Transforms/FunctionAttr.cpp @@ -80,15 +80,15 @@ fir::createFunctionAttrPass(fir::FunctionAttrTypes &functionAttr) { switch (functionAttr.framePointerKind) { case llvm::FramePointerKind::None: opts.framePointerKind = - mlir::LLVM::framePointerKind::symbolizeFramePointerKind(0).value(); + mlir::LLVM::framePointerKind::FramePointerKind::None; break; case llvm::FramePointerKind::NonLeaf: opts.framePointerKind = - mlir::LLVM::framePointerKind::symbolizeFramePointerKind(1).value(); + mlir::LLVM::framePointerKind::FramePointerKind::NonLeaf; break; case llvm::FramePointerKind::All: opts.framePointerKind = - mlir::LLVM::framePointerKind::symbolizeFramePointerKind(2).value(); + mlir::LLVM::framePointerKind::FramePointerKind::All; break; } >From 34ea42a5a6ce511976f3121f76b3c3297db076cb Mon Sep 17 00:00:00 2001 From: Radu2k <radu.sala...@arm.com> Date: Thu, 7 Dec 2023 10:14:02 +0000 Subject: [PATCH 04/16] Resolve format issues --- flang/include/flang/Tools/CrossToolHelpers.h | 2 +- flang/lib/Optimizer/Transforms/FunctionAttr.cpp | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/flang/include/flang/Tools/CrossToolHelpers.h b/flang/include/flang/Tools/CrossToolHelpers.h index 11f6735049f704..81835713469737 100644 --- a/flang/include/flang/Tools/CrossToolHelpers.h +++ b/flang/include/flang/Tools/CrossToolHelpers.h @@ -46,7 +46,7 @@ struct MLIRToLLVMPassPipelineConfig { llvm::codegenoptions::DebugInfoKind DebugInfo = llvm::codegenoptions::NoDebugInfo; ///< Debug info generation. llvm::FramePointerKind FramePointerKind = - llvm::FramePointerKind::None; + llvm::FramePointerKind::None; ///< Add frame pointer to functions. unsigned VScaleMin = 0; ///< SVE vector range minimum. unsigned VScaleMax = 0; ///< SVE vector range maximum. }; diff --git a/flang/lib/Optimizer/Transforms/FunctionAttr.cpp b/flang/lib/Optimizer/Transforms/FunctionAttr.cpp index 1c6238dec5063d..967164c7394c82 100644 --- a/flang/lib/Optimizer/Transforms/FunctionAttr.cpp +++ b/flang/lib/Optimizer/Transforms/FunctionAttr.cpp @@ -87,8 +87,7 @@ fir::createFunctionAttrPass(fir::FunctionAttrTypes &functionAttr) { mlir::LLVM::framePointerKind::FramePointerKind::NonLeaf; break; case llvm::FramePointerKind::All: - opts.framePointerKind = - mlir::LLVM::framePointerKind::FramePointerKind::All; + opts.framePointerKind = mlir::LLVM::framePointerKind::FramePointerKind::All; break; } >From 574e247b9e3709794f693587fe1efe0610ee4ef9 Mon Sep 17 00:00:00 2001 From: Radu2k <radu.sala...@arm.com> Date: Fri, 8 Dec 2023 13:51:06 +0000 Subject: [PATCH 05/16] Implement code review suggestions for framePointerKind attribute handling --- .../flang/Optimizer/Transforms/Passes.h | 4 +- .../flang/Optimizer/Transforms/Passes.td | 2 +- flang/include/flang/Tools/CLOptions.inc | 14 +++-- flang/lib/Frontend/CompilerInvocation.cpp | 20 +++++--- .../lib/Optimizer/Transforms/FunctionAttr.cpp | 51 +++---------------- flang/test/Driver/fixed-free-detection.f90 | 2 +- flang/test/Driver/func-attr.f90 | 2 +- flang/test/Driver/mlir-pass-pipeline.f90 | 2 - flang/test/Fir/basic-program.fir | 2 - 9 files changed, 37 insertions(+), 62 deletions(-) diff --git a/flang/include/flang/Optimizer/Transforms/Passes.h b/flang/include/flang/Optimizer/Transforms/Passes.h index 6010b6cd23405f..76dc3d3291f94d 100644 --- a/flang/include/flang/Optimizer/Transforms/Passes.h +++ b/flang/include/flang/Optimizer/Transforms/Passes.h @@ -12,7 +12,7 @@ #include "flang/Optimizer/Dialect/FIROps.h" #include "mlir/Pass/Pass.h" #include "mlir/Pass/PassRegistry.h" -#include "llvm/Support/CodeGen.h" +#include "mlir/Dialect/LLVMIR/LLVMAttrs.h" #include <memory> namespace mlir { @@ -85,7 +85,7 @@ std::unique_ptr<mlir::Pass> createVScaleAttrPass(std::pair<unsigned, unsigned> vscaleAttr); struct FunctionAttrTypes { - llvm::FramePointerKind framePointerKind; + mlir::LLVM::framePointerKind::FramePointerKind framePointerKind = mlir::LLVM::framePointerKind::FramePointerKind::None; }; std::unique_ptr<mlir::Pass> createFunctionAttrPass(); diff --git a/flang/include/flang/Optimizer/Transforms/Passes.td b/flang/include/flang/Optimizer/Transforms/Passes.td index 2078f37b5e65eb..bd80fed63c5499 100644 --- a/flang/include/flang/Optimizer/Transforms/Passes.td +++ b/flang/include/flang/Optimizer/Transforms/Passes.td @@ -350,7 +350,7 @@ def VScaleAttr : Pass<"vscale-attr", "mlir::func::FuncOp"> { } def FunctionAttr : Pass<"function-attr", "mlir::func::FuncOp"> { - let summary = "Enhance functions with different attributes"; + let summary = "This is a generic pass that adds function attributes that are expected at the LLVM IR level"; let description = [{ This feature introduces a general attribute aimed at customizing function characteristics. Options include: Add "frame-pointer" attribute to functions: Set an attribute for the frame diff --git a/flang/include/flang/Tools/CLOptions.inc b/flang/include/flang/Tools/CLOptions.inc index 3494e588b34606..903e42fbd7b50d 100644 --- a/flang/include/flang/Tools/CLOptions.inc +++ b/flang/include/flang/Tools/CLOptions.inc @@ -10,6 +10,7 @@ /// debugging the test tools. This file must be included into the tool. #include "mlir/Conversion/SCFToControlFlow/SCFToControlFlow.h" +#include "mlir/Dialect/LLVMIR/LLVMAttrs.h" #include "mlir/Pass/PassManager.h" #include "mlir/Transforms/GreedyPatternRewriteDriver.h" #include "mlir/Transforms/Passes.h" @@ -310,10 +311,17 @@ inline void createDefaultFIRCodeGenPassPipeline( if (config.VScaleMin != 0) pm.addPass(fir::createVScaleAttrPass({config.VScaleMin, config.VScaleMax})); - + + // Add function attributes fir::FunctionAttrTypes functionAttrs; - functionAttrs.framePointerKind = config.FramePointerKind; - pm.addPass(fir::createFunctionAttrPass(functionAttrs)); + + if (config.FramePointerKind != llvm::FramePointerKind::None) { + if (config.FramePointerKind == llvm::FramePointerKind::NonLeaf) + functionAttrs.framePointerKind = mlir::LLVM::framePointerKind::FramePointerKind::NonLeaf; + else functionAttrs.framePointerKind = mlir::LLVM::framePointerKind::FramePointerKind::All; + + pm.addPass(fir::createFunctionAttrPass(functionAttrs)); + } fir::addFIRToLLVMPass(pm, config); } diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index e9348a72b29895..39e3738614a852 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -248,13 +248,21 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts, if (const llvm::opt::Arg *a = args.getLastArg(clang::driver::options::OPT_mframe_pointer_EQ)) { llvm::StringRef s = a->getValue(); - assert(s == "none" || s == "non-leaf" || s == "all"); - if (s == "none") + + if (!(s=="none" || s=="no-leaf" || s=="all")) { + const auto debugWarningId = diags.getCustomDiagID( + clang::DiagnosticsEngine::Warning, "Frame pointer: %0"); + diags.Report(debugWarningId).AddString(a->getValue()); + } + + if (s == "none") { opts.setFramePointer(llvm::FramePointerKind::None); - else if (s == "non-leaf") - opts.setFramePointer(llvm::FramePointerKind::NonLeaf); - else - opts.setFramePointer(llvm::FramePointerKind::All); + } else { + if (s == "non-leaf") + opts.setFramePointer(llvm::FramePointerKind::NonLeaf); + else + opts.setFramePointer(llvm::FramePointerKind::All); + } } for (auto *a : args.filtered(clang::driver::options::OPT_fpass_plugin_EQ)) diff --git a/flang/lib/Optimizer/Transforms/FunctionAttr.cpp b/flang/lib/Optimizer/Transforms/FunctionAttr.cpp index 967164c7394c82..04429df241b95b 100644 --- a/flang/lib/Optimizer/Transforms/FunctionAttr.cpp +++ b/flang/lib/Optimizer/Transforms/FunctionAttr.cpp @@ -8,34 +8,10 @@ //===----------------------------------------------------------------------===// /// \file -/// This pass adds a `vscale_range` attribute to function definitions. -/// The attribute is used for scalable vector operations on Arm processors -/// and should only be run on processors that support this feature. [It is -/// likely harmless to run it on something else, but it is also not valuable]. -//===----------------------------------------------------------------------===// - -#include "flang/ISO_Fortran_binding_wrapper.h" -#include "flang/Optimizer/Builder/BoxValue.h" -#include "flang/Optimizer/Builder/FIRBuilder.h" -#include "flang/Optimizer/Builder/Runtime/Inquiry.h" -#include "flang/Optimizer/Dialect/FIRDialect.h" -#include "flang/Optimizer/Dialect/FIROps.h" -#include "flang/Optimizer/Dialect/FIRType.h" -#include "flang/Optimizer/Dialect/Support/FIRContext.h" -#include "flang/Optimizer/Dialect/Support/KindMapping.h" +/// This is a generic pass for adding attributes to functions. +//===----------------------------------------------------------------------== #include "flang/Optimizer/Transforms/Passes.h" #include "mlir/Dialect/LLVMIR/LLVMAttrs.h" -#include "mlir/Dialect/LLVMIR/LLVMDialect.h" -#include "mlir/IR/Matchers.h" -#include "mlir/IR/TypeUtilities.h" -#include "mlir/Pass/Pass.h" -#include "mlir/Transforms/DialectConversion.h" -#include "mlir/Transforms/GreedyPatternRewriteDriver.h" -#include "mlir/Transforms/RegionUtils.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/raw_ostream.h" - -#include <algorithm> namespace fir { #define GEN_PASS_DECL_FUNCTIONATTR @@ -64,10 +40,10 @@ void FunctionAttrPass::runOnOperation() { LLVM_DEBUG(llvm::dbgs() << "Func-name:" << func.getSymName() << "\n"); - auto context = &getContext(); - - func->setAttr("frame_pointer", mlir::LLVM::FramePointerKindAttr::get( - context, framePointerKind)); + mlir::MLIRContext* context = &getContext(); + if (framePointerKind != mlir::LLVM::framePointerKind::FramePointerKind::None) + func->setAttr("frame_pointer", mlir::LLVM::FramePointerKindAttr::get( + context, framePointerKind)); LLVM_DEBUG(llvm::dbgs() << "=== End " DEBUG_TYPE " ===\n"); } @@ -75,21 +51,8 @@ void FunctionAttrPass::runOnOperation() { std::unique_ptr<mlir::Pass> fir::createFunctionAttrPass(fir::FunctionAttrTypes &functionAttr) { FunctionAttrOptions opts; - // Frame pointer - switch (functionAttr.framePointerKind) { - case llvm::FramePointerKind::None: - opts.framePointerKind = - mlir::LLVM::framePointerKind::FramePointerKind::None; - break; - case llvm::FramePointerKind::NonLeaf: - opts.framePointerKind = - mlir::LLVM::framePointerKind::FramePointerKind::NonLeaf; - break; - case llvm::FramePointerKind::All: - opts.framePointerKind = mlir::LLVM::framePointerKind::FramePointerKind::All; - break; - } + opts.framePointerKind = functionAttr.framePointerKind; return std::make_unique<FunctionAttrPass>(opts); } diff --git a/flang/test/Driver/fixed-free-detection.f90 b/flang/test/Driver/fixed-free-detection.f90 index c2deef73f39a0b..75a10b7af85e08 100644 --- a/flang/test/Driver/fixed-free-detection.f90 +++ b/flang/test/Driver/fixed-free-detection.f90 @@ -25,5 +25,5 @@ ! MULTIPLEFORMS:program freeform ! MULTIPLEFORMS-NOT:programfixedform ! MULTIPLEFORMS-NEXT:end -! MULTIPLEFORMS-NEXT:programfixedform +! MULTIPLEFORMS:programfixedform ! MULTIPLEFORMS-NOT:program freeform diff --git a/flang/test/Driver/func-attr.f90 b/flang/test/Driver/func-attr.f90 index 10fe4657746e44..2ee87b52c5958d 100644 --- a/flang/test/Driver/func-attr.f90 +++ b/flang/test/Driver/func-attr.f90 @@ -6,7 +6,7 @@ subroutine func end subroutine func -! CHECK-NONEFP: attributes #0 = { "frame-pointer"="none" } +! CHECK-NONEFP: attributes #0 = {{{.*}}} ! CHECK-NONLEAFFP: attributes #0 = { "frame-pointer"="non-leaf" } ! CHECK-ALLFP: attributes #0 = { "frame-pointer"="all" } diff --git a/flang/test/Driver/mlir-pass-pipeline.f90 b/flang/test/Driver/mlir-pass-pipeline.f90 index f0dcf68195c4be..3d8c42f123e2eb 100644 --- a/flang/test/Driver/mlir-pass-pipeline.f90 +++ b/flang/test/Driver/mlir-pass-pipeline.f90 @@ -73,7 +73,5 @@ ! ALL-NEXT: (S) 0 num-dce'd - Number of operations eliminated ! ALL-NEXT: TargetRewrite ! ALL-NEXT: ExternalNameConversion -! ALL-NEXT: 'func.func' Pipeline -! ALL-NEXT: FunctionAttr ! ALL-NEXT: FIRToLLVMLowering ! ALL-NOT: LLVMIRLoweringPass diff --git a/flang/test/Fir/basic-program.fir b/flang/test/Fir/basic-program.fir index 601e34ee04c275..d8a9e74c318ce1 100644 --- a/flang/test/Fir/basic-program.fir +++ b/flang/test/Fir/basic-program.fir @@ -80,7 +80,5 @@ func.func @_QQmain() { // PASSES-NEXT: CodeGenRewrite // PASSES-NEXT: (S) 0 num-dce'd - Number of operations eliminated // PASSES-NEXT: TargetRewrite -// PASSES-NEXT: 'func.func' Pipeline -// PASSES-NEXT: FunctionAttr // PASSES-NEXT: FIRToLLVMLowering // PASSES-NEXT: LLVMIRLoweringPass >From fac406c186df384efc421896b59215fd796464c1 Mon Sep 17 00:00:00 2001 From: Radu2k <radu.sala...@arm.com> Date: Fri, 8 Dec 2023 14:03:05 +0000 Subject: [PATCH 06/16] Fix format issues --- flang/include/flang/Optimizer/Transforms/Passes.h | 5 +++-- flang/lib/Frontend/CompilerInvocation.cpp | 10 +++++----- flang/lib/Optimizer/Transforms/FunctionAttr.cpp | 4 ++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/flang/include/flang/Optimizer/Transforms/Passes.h b/flang/include/flang/Optimizer/Transforms/Passes.h index 76dc3d3291f94d..6970da8698ae84 100644 --- a/flang/include/flang/Optimizer/Transforms/Passes.h +++ b/flang/include/flang/Optimizer/Transforms/Passes.h @@ -10,9 +10,9 @@ #define FORTRAN_OPTIMIZER_TRANSFORMS_PASSES_H #include "flang/Optimizer/Dialect/FIROps.h" +#include "mlir/Dialect/LLVMIR/LLVMAttrs.h" #include "mlir/Pass/Pass.h" #include "mlir/Pass/PassRegistry.h" -#include "mlir/Dialect/LLVMIR/LLVMAttrs.h" #include <memory> namespace mlir { @@ -85,7 +85,8 @@ std::unique_ptr<mlir::Pass> createVScaleAttrPass(std::pair<unsigned, unsigned> vscaleAttr); struct FunctionAttrTypes { - mlir::LLVM::framePointerKind::FramePointerKind framePointerKind = mlir::LLVM::framePointerKind::FramePointerKind::None; + mlir::LLVM::framePointerKind::FramePointerKind framePointerKind = + mlir::LLVM::framePointerKind::FramePointerKind::None; }; std::unique_ptr<mlir::Pass> createFunctionAttrPass(); diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index 39e3738614a852..ec8dae13292fc2 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -248,11 +248,11 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts, if (const llvm::opt::Arg *a = args.getLastArg(clang::driver::options::OPT_mframe_pointer_EQ)) { llvm::StringRef s = a->getValue(); - - if (!(s=="none" || s=="no-leaf" || s=="all")) { - const auto debugWarningId = diags.getCustomDiagID( - clang::DiagnosticsEngine::Warning, "Frame pointer: %0"); - diags.Report(debugWarningId).AddString(a->getValue()); + + if (!(s == "none" || s == "no-leaf" || s == "all")) { + const auto debugWarningId = diags.getCustomDiagID( + clang::DiagnosticsEngine::Warning, "Frame pointer: %0"); + diags.Report(debugWarningId).AddString(a->getValue()); } if (s == "none") { diff --git a/flang/lib/Optimizer/Transforms/FunctionAttr.cpp b/flang/lib/Optimizer/Transforms/FunctionAttr.cpp index 04429df241b95b..f3d2ae9071ee13 100644 --- a/flang/lib/Optimizer/Transforms/FunctionAttr.cpp +++ b/flang/lib/Optimizer/Transforms/FunctionAttr.cpp @@ -40,10 +40,10 @@ void FunctionAttrPass::runOnOperation() { LLVM_DEBUG(llvm::dbgs() << "Func-name:" << func.getSymName() << "\n"); - mlir::MLIRContext* context = &getContext(); + mlir::MLIRContext *context = &getContext(); if (framePointerKind != mlir::LLVM::framePointerKind::FramePointerKind::None) func->setAttr("frame_pointer", mlir::LLVM::FramePointerKindAttr::get( - context, framePointerKind)); + context, framePointerKind)); LLVM_DEBUG(llvm::dbgs() << "=== End " DEBUG_TYPE " ===\n"); } >From a675d75becb0fcebe162416fb71d7fd3329acdda Mon Sep 17 00:00:00 2001 From: Radu2k <radu.sala...@arm.com> Date: Fri, 8 Dec 2023 14:11:32 +0000 Subject: [PATCH 07/16] Fix more whitespace format issues --- flang/include/flang/Tools/CLOptions.inc | 17 ++++++++++------- flang/include/flang/Tools/CrossToolHelpers.h | 2 +- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/flang/include/flang/Tools/CLOptions.inc b/flang/include/flang/Tools/CLOptions.inc index 903e42fbd7b50d..23719685f80a1b 100644 --- a/flang/include/flang/Tools/CLOptions.inc +++ b/flang/include/flang/Tools/CLOptions.inc @@ -311,15 +311,18 @@ inline void createDefaultFIRCodeGenPassPipeline( if (config.VScaleMin != 0) pm.addPass(fir::createVScaleAttrPass({config.VScaleMin, config.VScaleMax})); - - // Add function attributes + + // Add function attributes fir::FunctionAttrTypes functionAttrs; - if (config.FramePointerKind != llvm::FramePointerKind::None) { - if (config.FramePointerKind == llvm::FramePointerKind::NonLeaf) - functionAttrs.framePointerKind = mlir::LLVM::framePointerKind::FramePointerKind::NonLeaf; - else functionAttrs.framePointerKind = mlir::LLVM::framePointerKind::FramePointerKind::All; - + if (config.FramePointerKind != llvm::FramePointerKind::None) { + if (config.FramePointerKind == llvm::FramePointerKind::NonLeaf) + functionAttrs.framePointerKind = + mlir::LLVM::framePointerKind::FramePointerKind::NonLeaf; + else + functionAttrs.framePointerKind = + mlir::LLVM::framePointerKind::FramePointerKind::All; + pm.addPass(fir::createFunctionAttrPass(functionAttrs)); } diff --git a/flang/include/flang/Tools/CrossToolHelpers.h b/flang/include/flang/Tools/CrossToolHelpers.h index 81835713469737..b346b30b158aec 100644 --- a/flang/include/flang/Tools/CrossToolHelpers.h +++ b/flang/include/flang/Tools/CrossToolHelpers.h @@ -45,7 +45,7 @@ struct MLIRToLLVMPassPipelineConfig { bool AliasAnalysis = false; ///< Add TBAA tags to generated LLVMIR llvm::codegenoptions::DebugInfoKind DebugInfo = llvm::codegenoptions::NoDebugInfo; ///< Debug info generation. - llvm::FramePointerKind FramePointerKind = + llvm::FramePointerKind FramePointerKind = llvm::FramePointerKind::None; ///< Add frame pointer to functions. unsigned VScaleMin = 0; ///< SVE vector range minimum. unsigned VScaleMax = 0; ///< SVE vector range maximum. >From 104c3d480d30b407fed3d092b82a882081a9be2d Mon Sep 17 00:00:00 2001 From: Radu2k <radu.sala...@arm.com> Date: Fri, 8 Dec 2023 14:18:00 +0000 Subject: [PATCH 08/16] Fix more whitespace format issues in CLOptions.inc --- flang/include/flang/Tools/CLOptions.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flang/include/flang/Tools/CLOptions.inc b/flang/include/flang/Tools/CLOptions.inc index 23719685f80a1b..96d3869cd09391 100644 --- a/flang/include/flang/Tools/CLOptions.inc +++ b/flang/include/flang/Tools/CLOptions.inc @@ -314,10 +314,10 @@ inline void createDefaultFIRCodeGenPassPipeline( // Add function attributes fir::FunctionAttrTypes functionAttrs; - + if (config.FramePointerKind != llvm::FramePointerKind::None) { if (config.FramePointerKind == llvm::FramePointerKind::NonLeaf) - functionAttrs.framePointerKind = + functionAttrs.framePointerKind = mlir::LLVM::framePointerKind::FramePointerKind::NonLeaf; else functionAttrs.framePointerKind = >From 11e3a3adc5ba598268b3a70a209fc3bb926d5864 Mon Sep 17 00:00:00 2001 From: Radu2k <radu.sala...@arm.com> Date: Fri, 8 Dec 2023 15:15:42 +0000 Subject: [PATCH 09/16] Change CompilerInvocation.cpp no-leaf typo --- flang/lib/Frontend/CompilerInvocation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index ec8dae13292fc2..74bf419b31c2cb 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -249,7 +249,7 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts, args.getLastArg(clang::driver::options::OPT_mframe_pointer_EQ)) { llvm::StringRef s = a->getValue(); - if (!(s == "none" || s == "no-leaf" || s == "all")) { + if (!(s == "none" || s == "non-leaf" || s == "all")) { const auto debugWarningId = diags.getCustomDiagID( clang::DiagnosticsEngine::Warning, "Frame pointer: %0"); diags.Report(debugWarningId).AddString(a->getValue()); >From 0a3fbcaaa1b8f20c5e1f88252fd27acf561aa0bb Mon Sep 17 00:00:00 2001 From: Radu2k <radu.sala...@arm.com> Date: Fri, 8 Dec 2023 16:59:46 +0000 Subject: [PATCH 10/16] Fix 'test the debug pass pipeline' issue for frame pointer --- flang/test/Driver/fixed-free-detection.f90 | 14 +++++++------- flang/test/Driver/mlir-debug-pass-pipeline.f90 | 18 ++++++++---------- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/flang/test/Driver/fixed-free-detection.f90 b/flang/test/Driver/fixed-free-detection.f90 index 75a10b7af85e08..8975349557ba2f 100644 --- a/flang/test/Driver/fixed-free-detection.f90 +++ b/flang/test/Driver/fixed-free-detection.f90 @@ -5,16 +5,16 @@ !-------------------------- ! FLANG DRIVER (flang) !-------------------------- -! RUN: %flang -E -Xflang -fno-reformat %S/Inputs/free-form-test.f90 2>&1 | FileCheck %s --check-prefix=FREEFORM -! RUN: %flang -E -Xflang -fno-reformat %S/Inputs/fixed-form-test.f 2>&1 | FileCheck %s --check-prefix=FIXEDFORM -! RUN: %flang -E -Xflang -fno-reformat %S/Inputs/free-form-test.f90 %S/Inputs/fixed-form-test.f 2>&1 | FileCheck %s --check-prefix=MULTIPLEFORMS +! RUN: %flang -fomit-frame-pointer -E -Xflang -fno-reformat %S/Inputs/free-form-test.f90 2>&1 | FileCheck %s --check-prefix=FREEFORM +! RUN: %flang -fomit-frame-pointer -E -Xflang -fno-reformat %S/Inputs/fixed-form-test.f 2>&1 | FileCheck %s --check-prefix=FIXEDFORM +! RUN: %flang -fomit-frame-pointer -E -Xflang -fno-reformat %S/Inputs/free-form-test.f90 %S/Inputs/fixed-form-test.f 2>&1 | FileCheck %s --check-prefix=MULTIPLEFORMS !----------------------------------------- ! FRONTEND FLANG DRIVER (flang_fc1) !----------------------------------------- -! RUN: %flang_fc1 -E -fno-reformat %S/Inputs/free-form-test.f90 2>&1 | FileCheck %s --check-prefix=FREEFORM -! RUN: %flang_fc1 -E -fno-reformat %S/Inputs/fixed-form-test.f 2>&1 | FileCheck %s --check-prefix=FIXEDFORM -! RUN: %flang_fc1 -E -fno-reformat %S/Inputs/free-form-test.f90 %S/Inputs/fixed-form-test.f 2>&1 | FileCheck %s --check-prefix=MULTIPLEFORMS +! RUN: %flang_fc1 -mframe-pointer=none -E -fno-reformat %S/Inputs/free-form-test.f90 2>&1 | FileCheck %s --check-prefix=FREEFORM +! RUN: %flang_fc1 -mframe-pointer=none -E -fno-reformat %S/Inputs/fixed-form-test.f 2>&1 | FileCheck %s --check-prefix=FIXEDFORM +! RUN: %flang_fc1 -mframe-pointer=none -E -fno-reformat %S/Inputs/free-form-test.f90 %S/Inputs/fixed-form-test.f 2>&1 | FileCheck %s --check-prefix=MULTIPLEFORMS ! FREEFORM:program freeform ! FREEFORM-NOT:programfixedform @@ -25,5 +25,5 @@ ! MULTIPLEFORMS:program freeform ! MULTIPLEFORMS-NOT:programfixedform ! MULTIPLEFORMS-NEXT:end -! MULTIPLEFORMS:programfixedform +! MULTIPLEFORMS-NEXT:programfixedform ! MULTIPLEFORMS-NOT:program freeform diff --git a/flang/test/Driver/mlir-debug-pass-pipeline.f90 b/flang/test/Driver/mlir-debug-pass-pipeline.f90 index 701537b339de9f..6d602d6edab229 100644 --- a/flang/test/Driver/mlir-debug-pass-pipeline.f90 +++ b/flang/test/Driver/mlir-debug-pass-pipeline.f90 @@ -1,14 +1,14 @@ ! Test the debug pass pipeline -! RUN: %flang -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline -o /dev/null %s 2>&1 | FileCheck --check-prefixes=ALL,NO-DEBUG %s +! RUN: %flang -fomit-frame-pointer -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline -o /dev/null %s 2>&1 | FileCheck --check-prefixes=ALL,NO-DEBUG %s -! RUN: %flang -g0 -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline %s -o /dev/null 2>&1 | FileCheck --check-prefixes=ALL,NO-DEBUG %s -! RUN: %flang -g -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline %s -o /dev/null 2>&1 | FileCheck --check-prefixes=ALL,DEBUG %s -! RUN: %flang -g1 -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline %s -o /dev/null 2>&1 | FileCheck --check-prefixes=ALL,DEBUG %s -! RUN: %flang -gline-tables-only -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline %s -o /dev/null 2>&1 | FileCheck --check-prefixes=ALL,DEBUG %s -! RUN: %flang -gline-directives-only -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline %s -o /dev/null 2>&1 | FileCheck --check-prefixes=ALL,DEBUG,DEBUG-DIRECTIVES %s -! RUN: %flang -g2 -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline %s -o /dev/null 2>&1 | FileCheck --check-prefixes=ALL,DEBUG,DEBUG-CONSTRUCT %s -! RUN: %flang -g3 -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline %s -o /dev/null 2>&1 | FileCheck --check-prefixes=ALL,DEBUG,DEBUG-CONSTRUCT %s +! RUN: %flang -fomit-frame-pointer -g0 -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline %s -o /dev/null 2>&1 | FileCheck --check-prefixes=ALL,NO-DEBUG %s +! RUN: %flang -fomit-frame-pointer -g -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline %s -o /dev/null 2>&1 | FileCheck --check-prefixes=ALL,DEBUG %s +! RUN: %flang -fomit-frame-pointer -g1 -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline %s -o /dev/null 2>&1 | FileCheck --check-prefixes=ALL,DEBUG %s +! RUN: %flang -fomit-frame-pointer -gline-tables-only -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline %s -o /dev/null 2>&1 | FileCheck --check-prefixes=ALL,DEBUG %s +! RUN: %flang -fomit-frame-pointer -gline-directives-only -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline %s -o /dev/null 2>&1 | FileCheck --check-prefixes=ALL,DEBUG,DEBUG-DIRECTIVES %s +! RUN: %flang -fomit-frame-pointer -g2 -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline %s -o /dev/null 2>&1 | FileCheck --check-prefixes=ALL,DEBUG,DEBUG-CONSTRUCT %s +! RUN: %flang -fomit-frame-pointer -g3 -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline %s -o /dev/null 2>&1 | FileCheck --check-prefixes=ALL,DEBUG,DEBUG-CONSTRUCT %s ! RUN: not %flang_fc1 -debug-info-kind=invalid -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline %s -o /dev/null 2>&1 | FileCheck --check-prefixes=DEBUG-ERR %s @@ -82,7 +82,5 @@ ! ALL-NEXT: ExternalNameConversion ! DEBUG-NEXT: AddDebugFoundation ! NO-DEBUG-NOT: AddDebugFoundation -! ALL-NEXT: 'func.func' Pipeline -! ALL-NEXT: FunctionAttr ! ALL-NEXT: FIRToLLVMLowering ! ALL-NOT: LLVMIRLoweringPass >From a7887f1e6d8feef72ab4e6acd48e6e758bc9f2ee Mon Sep 17 00:00:00 2001 From: Radu2k <radu.sala...@arm.com> Date: Mon, 11 Dec 2023 16:33:10 +0000 Subject: [PATCH 11/16] Adjust code based on code review --- flang/include/flang/Frontend/CodeGenOptions.def | 2 +- flang/lib/Frontend/CompilerInvocation.cpp | 14 ++++++-------- flang/test/Driver/fixed-free-detection.f90 | 12 ++++++------ flang/test/Driver/func-attr.f90 | 12 +++++++++--- 4 files changed, 22 insertions(+), 18 deletions(-) diff --git a/flang/include/flang/Frontend/CodeGenOptions.def b/flang/include/flang/Frontend/CodeGenOptions.def index 774f225974d7ea..f6bf83439cdc7d 100644 --- a/flang/include/flang/Frontend/CodeGenOptions.def +++ b/flang/include/flang/Frontend/CodeGenOptions.def @@ -38,7 +38,7 @@ CODEGENOPT(Underscoring, 1, 1) ENUM_CODEGENOPT(RelocationModel, llvm::Reloc::Model, 3, llvm::Reloc::PIC_) ///< Name of the relocation model to use. ENUM_CODEGENOPT(DebugInfo, llvm::codegenoptions::DebugInfoKind, 4, llvm::codegenoptions::NoDebugInfo) ///< Level of debug info to generate ENUM_CODEGENOPT(VecLib, llvm::driver::VectorLibrary, 3, llvm::driver::VectorLibrary::NoLibrary) ///< Vector functions library to use -ENUM_CODEGENOPT(FramePointer, llvm::FramePointerKind, 2, llvm::FramePointerKind::None) /// frame-pointer: all,non-leaf,none +ENUM_CODEGENOPT(FramePointer, llvm::FramePointerKind, 2, llvm::FramePointerKind::None) ///<Enable the usage of frame pointers #undef CODEGENOPT #undef ENUM_CODEGENOPT diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index 74bf419b31c2cb..ff14f707fabd56 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -251,18 +251,16 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts, if (!(s == "none" || s == "non-leaf" || s == "all")) { const auto debugWarningId = diags.getCustomDiagID( - clang::DiagnosticsEngine::Warning, "Frame pointer: %0"); + clang::DiagnosticsEngine::Error, "Frame pointer: %0"); diags.Report(debugWarningId).AddString(a->getValue()); } - if (s == "none") { + if (s == "none") opts.setFramePointer(llvm::FramePointerKind::None); - } else { - if (s == "non-leaf") - opts.setFramePointer(llvm::FramePointerKind::NonLeaf); - else - opts.setFramePointer(llvm::FramePointerKind::All); - } + else if (s == "non-leaf") + opts.setFramePointer(llvm::FramePointerKind::NonLeaf); + else + opts.setFramePointer(llvm::FramePointerKind::All); } for (auto *a : args.filtered(clang::driver::options::OPT_fpass_plugin_EQ)) diff --git a/flang/test/Driver/fixed-free-detection.f90 b/flang/test/Driver/fixed-free-detection.f90 index 8975349557ba2f..c2deef73f39a0b 100644 --- a/flang/test/Driver/fixed-free-detection.f90 +++ b/flang/test/Driver/fixed-free-detection.f90 @@ -5,16 +5,16 @@ !-------------------------- ! FLANG DRIVER (flang) !-------------------------- -! RUN: %flang -fomit-frame-pointer -E -Xflang -fno-reformat %S/Inputs/free-form-test.f90 2>&1 | FileCheck %s --check-prefix=FREEFORM -! RUN: %flang -fomit-frame-pointer -E -Xflang -fno-reformat %S/Inputs/fixed-form-test.f 2>&1 | FileCheck %s --check-prefix=FIXEDFORM -! RUN: %flang -fomit-frame-pointer -E -Xflang -fno-reformat %S/Inputs/free-form-test.f90 %S/Inputs/fixed-form-test.f 2>&1 | FileCheck %s --check-prefix=MULTIPLEFORMS +! RUN: %flang -E -Xflang -fno-reformat %S/Inputs/free-form-test.f90 2>&1 | FileCheck %s --check-prefix=FREEFORM +! RUN: %flang -E -Xflang -fno-reformat %S/Inputs/fixed-form-test.f 2>&1 | FileCheck %s --check-prefix=FIXEDFORM +! RUN: %flang -E -Xflang -fno-reformat %S/Inputs/free-form-test.f90 %S/Inputs/fixed-form-test.f 2>&1 | FileCheck %s --check-prefix=MULTIPLEFORMS !----------------------------------------- ! FRONTEND FLANG DRIVER (flang_fc1) !----------------------------------------- -! RUN: %flang_fc1 -mframe-pointer=none -E -fno-reformat %S/Inputs/free-form-test.f90 2>&1 | FileCheck %s --check-prefix=FREEFORM -! RUN: %flang_fc1 -mframe-pointer=none -E -fno-reformat %S/Inputs/fixed-form-test.f 2>&1 | FileCheck %s --check-prefix=FIXEDFORM -! RUN: %flang_fc1 -mframe-pointer=none -E -fno-reformat %S/Inputs/free-form-test.f90 %S/Inputs/fixed-form-test.f 2>&1 | FileCheck %s --check-prefix=MULTIPLEFORMS +! RUN: %flang_fc1 -E -fno-reformat %S/Inputs/free-form-test.f90 2>&1 | FileCheck %s --check-prefix=FREEFORM +! RUN: %flang_fc1 -E -fno-reformat %S/Inputs/fixed-form-test.f 2>&1 | FileCheck %s --check-prefix=FIXEDFORM +! RUN: %flang_fc1 -E -fno-reformat %S/Inputs/free-form-test.f90 %S/Inputs/fixed-form-test.f 2>&1 | FileCheck %s --check-prefix=MULTIPLEFORMS ! FREEFORM:program freeform ! FREEFORM-NOT:programfixedform diff --git a/flang/test/Driver/func-attr.f90 b/flang/test/Driver/func-attr.f90 index 2ee87b52c5958d..f5cbc48813e3ec 100644 --- a/flang/test/Driver/func-attr.f90 +++ b/flang/test/Driver/func-attr.f90 @@ -2,11 +2,17 @@ ! RUN: %flang_fc1 -triple aarch64-none-none -mframe-pointer=non-leaf -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-NONLEAFFP ! RUN: %flang_fc1 -triple aarch64-none-none -mframe-pointer=all -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-ALLFP -! CHECK-LABEL: @func_() #0 +! CHECK-NONEFP-LABEL: @func_() { + +! CHECK-NONLEAFFP-LABEL: @func_() +! CHECK-NONLEAFFP-SAME: #0 + +! CHECK-ALLFP-LABEL: @func_() +! CHECK-ALLFP-SAME: #0 + subroutine func end subroutine func -! CHECK-NONEFP: attributes #0 = {{{.*}}} +! CHECK-NONEFP-NOT: attributes #0 = { "frame-pointer"="{{.*}}" } ! CHECK-NONLEAFFP: attributes #0 = { "frame-pointer"="non-leaf" } ! CHECK-ALLFP: attributes #0 = { "frame-pointer"="all" } - >From cef574b100fd77fbf04a2758435ded41228b1570 Mon Sep 17 00:00:00 2001 From: Radu2k <radu.sala...@arm.com> Date: Wed, 20 Dec 2023 08:43:04 +0000 Subject: [PATCH 12/16] Make further appropriate syntax and test adjustments --- flang/include/flang/Frontend/CodeGenOptions.def | 2 +- flang/include/flang/Optimizer/Transforms/Passes.td | 5 +++-- flang/lib/Optimizer/Transforms/FunctionAttr.cpp | 4 ++-- flang/test/Driver/frame-pointer-forwarding.f90 | 11 +++++++---- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/flang/include/flang/Frontend/CodeGenOptions.def b/flang/include/flang/Frontend/CodeGenOptions.def index f6bf83439cdc7d..9d03ec88a56b8a 100644 --- a/flang/include/flang/Frontend/CodeGenOptions.def +++ b/flang/include/flang/Frontend/CodeGenOptions.def @@ -38,7 +38,7 @@ CODEGENOPT(Underscoring, 1, 1) ENUM_CODEGENOPT(RelocationModel, llvm::Reloc::Model, 3, llvm::Reloc::PIC_) ///< Name of the relocation model to use. ENUM_CODEGENOPT(DebugInfo, llvm::codegenoptions::DebugInfoKind, 4, llvm::codegenoptions::NoDebugInfo) ///< Level of debug info to generate ENUM_CODEGENOPT(VecLib, llvm::driver::VectorLibrary, 3, llvm::driver::VectorLibrary::NoLibrary) ///< Vector functions library to use -ENUM_CODEGENOPT(FramePointer, llvm::FramePointerKind, 2, llvm::FramePointerKind::None) ///<Enable the usage of frame pointers +ENUM_CODEGENOPT(FramePointer, llvm::FramePointerKind, 2, llvm::FramePointerKind::None) ///< Enable the usage of frame pointers #undef CODEGENOPT #undef ENUM_CODEGENOPT diff --git a/flang/include/flang/Optimizer/Transforms/Passes.td b/flang/include/flang/Optimizer/Transforms/Passes.td index bd80fed63c5499..79ebd59377a3db 100644 --- a/flang/include/flang/Optimizer/Transforms/Passes.td +++ b/flang/include/flang/Optimizer/Transforms/Passes.td @@ -350,7 +350,7 @@ def VScaleAttr : Pass<"vscale-attr", "mlir::func::FuncOp"> { } def FunctionAttr : Pass<"function-attr", "mlir::func::FuncOp"> { - let summary = "This is a generic pass that adds function attributes that are expected at the LLVM IR level"; + let summary = "This is a generic pass that adds function attributes expected at LLVM IR level"; let description = [{ This feature introduces a general attribute aimed at customizing function characteristics. Options include: Add "frame-pointer" attribute to functions: Set an attribute for the frame @@ -362,7 +362,8 @@ def FunctionAttr : Pass<"function-attr", "mlir::func::FuncOp"> { }]; let options = [ Option<"framePointerKind", "frame-pointer", - "mlir::LLVM::framePointerKind::FramePointerKind", /*default=*/"mlir::LLVM::framePointerKind::FramePointerKind{}", + "mlir::LLVM::framePointerKind::FramePointerKind", + /*default=*/"mlir::LLVM::framePointerKind::FramePointerKind{}", "frame pointer">, ]; let constructor = "::fir::createFunctionAttrPass()"; diff --git a/flang/lib/Optimizer/Transforms/FunctionAttr.cpp b/flang/lib/Optimizer/Transforms/FunctionAttr.cpp index f3d2ae9071ee13..55b908ba5d8613 100644 --- a/flang/lib/Optimizer/Transforms/FunctionAttr.cpp +++ b/flang/lib/Optimizer/Transforms/FunctionAttr.cpp @@ -1,4 +1,4 @@ -//===- FunctionAttr.cpp -------------------------------------------------===// +//===- FunctionAttr.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -9,7 +9,7 @@ //===----------------------------------------------------------------------===// /// \file /// This is a generic pass for adding attributes to functions. -//===----------------------------------------------------------------------== +//===----------------------------------------------------------------------===// #include "flang/Optimizer/Transforms/Passes.h" #include "mlir/Dialect/LLVMIR/LLVMAttrs.h" diff --git a/flang/test/Driver/frame-pointer-forwarding.f90 b/flang/test/Driver/frame-pointer-forwarding.f90 index fd615987f82f4c..19e43720651fde 100644 --- a/flang/test/Driver/frame-pointer-forwarding.f90 +++ b/flang/test/Driver/frame-pointer-forwarding.f90 @@ -1,9 +1,12 @@ ! Test that flang-new forwards -fno-omit-frame-pointer and -fomit-frame-pointer Flang frontend -! RUN: %flang -fno-omit-frame-pointer --target=x86-none-none -fsyntax-only -### %s -o %t 2>&1 | FileCheck %s -! CHECK: "-mframe-pointer=all" +! RUN: %flang --target=aarch64-none-none -fsyntax-only -### %s -o %t 2>&1 | FileCheck %s --check-prefix=CHECK-NOVALUE +! CHECK-NOVALUE: "-mframe-pointer=non-leaf" + +! RUN: %flang -fomit-frame-pointer --target=aarch64-none-none -fsyntax-only -### %s -o %t 2>&1 | FileCheck %s --check-prefix=CHECK-NONEFP +! CHECK-NONEFP: "-mframe-pointer=none" ! RUN: %flang -fno-omit-frame-pointer --target=aarch64-none-none -fsyntax-only -### %s -o %t 2>&1 | FileCheck %s --check-prefix=CHECK-NONLEAFFP ! CHECK-NONLEAFFP: "-mframe-pointer=non-leaf" -! RUN: %flang -fomit-frame-pointer --target=aarch64-none-none -fsyntax-only -### %s -o %t 2>&1 | FileCheck %s --check-prefix=CHECK-NONEFP -! CHECK-NONEFP: "-mframe-pointer=none" +! RUN: %flang -fno-omit-frame-pointer --target=x86-none-none -fsyntax-only -### %s -o %t 2>&1 | FileCheck %s --check-prefix=CHECK-ALLFP +! CHECK-ALLFP: "-mframe-pointer=all" >From bcd307965f3ecddddb577269426ea518a4e8814c Mon Sep 17 00:00:00 2001 From: Radu2k <radu.sala...@arm.com> Date: Thu, 21 Dec 2023 10:48:35 +0000 Subject: [PATCH 13/16] Replace if/else with StringSwitch and add appropriate test case --- flang/lib/Frontend/CompilerInvocation.cpp | 22 +++++++++++----------- flang/test/Driver/func-attr.f90 | 11 ++++++++--- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index ff14f707fabd56..3a5b0945c11f71 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -245,22 +245,22 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts, opts.AliasAnalysis = opts.OptimizationLevel > 0; + // -mframe-pointer=none/non-leaf/all option. if (const llvm::opt::Arg *a = args.getLastArg(clang::driver::options::OPT_mframe_pointer_EQ)) { - llvm::StringRef s = a->getValue(); + std::optional<llvm::FramePointerKind> val = + llvm::StringSwitch<std::optional<llvm::FramePointerKind>>(a->getValue()) + .Case("none", llvm::FramePointerKind::None) + .Case("non-leaf", llvm::FramePointerKind::NonLeaf) + .Case("all", llvm::FramePointerKind::All) + .Default(std::nullopt); - if (!(s == "none" || s == "non-leaf" || s == "all")) { - const auto debugWarningId = diags.getCustomDiagID( - clang::DiagnosticsEngine::Error, "Frame pointer: %0"); - diags.Report(debugWarningId).AddString(a->getValue()); + if (!val.has_value()) { + diags.Report(clang::diag::err_drv_invalid_value) + << a->getAsString(args) << a->getValue(); } - - if (s == "none") - opts.setFramePointer(llvm::FramePointerKind::None); - else if (s == "non-leaf") - opts.setFramePointer(llvm::FramePointerKind::NonLeaf); else - opts.setFramePointer(llvm::FramePointerKind::All); + opts.setFramePointer(val.value()); } for (auto *a : args.filtered(clang::driver::options::OPT_fpass_plugin_EQ)) diff --git a/flang/test/Driver/func-attr.f90 b/flang/test/Driver/func-attr.f90 index f5cbc48813e3ec..dddb8cde52ff1c 100644 --- a/flang/test/Driver/func-attr.f90 +++ b/flang/test/Driver/func-attr.f90 @@ -1,6 +1,9 @@ -! RUN: %flang_fc1 -triple aarch64-none-none -mframe-pointer=none -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-NONEFP -! RUN: %flang_fc1 -triple aarch64-none-none -mframe-pointer=non-leaf -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-NONLEAFFP -! RUN: %flang_fc1 -triple aarch64-none-none -mframe-pointer=all -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-ALLFP +! Test that -mframe-pointer can accept only specific values. + +! RUN: %flang_fc1 -triple aarch64-none-none -mframe-pointer=none -emit-llvm -o - %s 2>&1| FileCheck %s --check-prefix=CHECK-NONEFP +! RUN: %flang_fc1 -triple aarch64-none-none -mframe-pointer=non-leaf -emit-llvm -o - %s 2>&1| FileCheck %s --check-prefix=CHECK-NONLEAFFP +! RUN: %flang_fc1 -triple aarch64-none-none -mframe-pointer=all -emit-llvm -o - %s 2>&1| FileCheck %s --check-prefix=CHECK-ALLFP +! RUN: not %flang_fc1 -triple aarch64-none-none -mframe-pointer=wrongval -emit-llvm -o - %s 2>&1| FileCheck %s --check-prefix=CHECK-WRONGVALUEFP ! CHECK-NONEFP-LABEL: @func_() { @@ -16,3 +19,5 @@ end subroutine func ! CHECK-NONEFP-NOT: attributes #0 = { "frame-pointer"="{{.*}}" } ! CHECK-NONLEAFFP: attributes #0 = { "frame-pointer"="non-leaf" } ! CHECK-ALLFP: attributes #0 = { "frame-pointer"="all" } + +! CHECK-WRONGVALUEFP:error: invalid value 'wrongval' in '-mframe-pointer=wrongval' >From 461db3f3c8a55220a1597de8f2251398a5ba1cfe Mon Sep 17 00:00:00 2001 From: Radu2k <radu.sala...@arm.com> Date: Thu, 21 Dec 2023 11:05:43 +0000 Subject: [PATCH 14/16] Fix format issues --- flang/lib/Frontend/CompilerInvocation.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index 3a5b0945c11f71..8569c068564fa9 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -249,17 +249,16 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts, if (const llvm::opt::Arg *a = args.getLastArg(clang::driver::options::OPT_mframe_pointer_EQ)) { std::optional<llvm::FramePointerKind> val = - llvm::StringSwitch<std::optional<llvm::FramePointerKind>>(a->getValue()) - .Case("none", llvm::FramePointerKind::None) - .Case("non-leaf", llvm::FramePointerKind::NonLeaf) - .Case("all", llvm::FramePointerKind::All) - .Default(std::nullopt); + llvm::StringSwitch<std::optional<llvm::FramePointerKind>>(a->getValue()) + .Case("none", llvm::FramePointerKind::None) + .Case("non-leaf", llvm::FramePointerKind::NonLeaf) + .Case("all", llvm::FramePointerKind::All) + .Default(std::nullopt); if (!val.has_value()) { diags.Report(clang::diag::err_drv_invalid_value) - << a->getAsString(args) << a->getValue(); - } - else + << a->getAsString(args) << a->getValue(); + } else opts.setFramePointer(val.value()); } >From af006628b237591d3e13b60c058e8479e0ca6aa0 Mon Sep 17 00:00:00 2001 From: Radu2k <radu.sala...@arm.com> Date: Thu, 21 Dec 2023 11:54:57 +0000 Subject: [PATCH 15/16] Fix Passes.td 80 characters formatting limit --- flang/include/flang/Optimizer/Transforms/Passes.td | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/flang/include/flang/Optimizer/Transforms/Passes.td b/flang/include/flang/Optimizer/Transforms/Passes.td index 79ebd59377a3db..e3c45d41f04cc7 100644 --- a/flang/include/flang/Optimizer/Transforms/Passes.td +++ b/flang/include/flang/Optimizer/Transforms/Passes.td @@ -350,15 +350,16 @@ def VScaleAttr : Pass<"vscale-attr", "mlir::func::FuncOp"> { } def FunctionAttr : Pass<"function-attr", "mlir::func::FuncOp"> { - let summary = "This is a generic pass that adds function attributes expected at LLVM IR level"; - let description = [{ This feature introduces a general attribute aimed at customizing function characteristics. + let summary = "Pass that adds function attributes expected at LLVM IR level"; + let description = [{ This feature introduces a general attribute aimed at + customizing function characteristics. Options include: Add "frame-pointer" attribute to functions: Set an attribute for the frame pointer on functions, to avoid saving the frame pointer in a register in - functions where it is unnecessary. - This eliminates the need for instructions to save, establish, and restore - frame pointers, while also freeing up an additional register in numerous functions. - However, this approach can make debugging unfeasible on certain machines. + functions where it is unnecessary. This eliminates the need for + instructions to save, establish, and restore frame pointers, while also + freeing up an additional register in numerous functions. However, this + approach can make debugging unfeasible on certain machines. }]; let options = [ Option<"framePointerKind", "frame-pointer", >From 9e3758c756a22f5304692183638b9164bcc0c990 Mon Sep 17 00:00:00 2001 From: Radu2k <radu.sala...@arm.com> Date: Wed, 27 Dec 2023 10:42:18 +0000 Subject: [PATCH 16/16] Fix review comments --- flang/test/Driver/frame-pointer-forwarding.f90 | 8 ++++---- flang/test/Driver/func-attr.f90 | 2 +- flang/test/Driver/mlir-debug-pass-pipeline.f90 | 18 +++++++++--------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/flang/test/Driver/frame-pointer-forwarding.f90 b/flang/test/Driver/frame-pointer-forwarding.f90 index 19e43720651fde..751494cc6a6017 100644 --- a/flang/test/Driver/frame-pointer-forwarding.f90 +++ b/flang/test/Driver/frame-pointer-forwarding.f90 @@ -1,12 +1,12 @@ ! Test that flang-new forwards -fno-omit-frame-pointer and -fomit-frame-pointer Flang frontend ! RUN: %flang --target=aarch64-none-none -fsyntax-only -### %s -o %t 2>&1 | FileCheck %s --check-prefix=CHECK-NOVALUE -! CHECK-NOVALUE: "-mframe-pointer=non-leaf" +! CHECK-NOVALUE: "-fc1"{{.*}}"-mframe-pointer=non-leaf" ! RUN: %flang -fomit-frame-pointer --target=aarch64-none-none -fsyntax-only -### %s -o %t 2>&1 | FileCheck %s --check-prefix=CHECK-NONEFP -! CHECK-NONEFP: "-mframe-pointer=none" +! CHECK-NONEFP: "-fc1"{{.*}}"-mframe-pointer=none" ! RUN: %flang -fno-omit-frame-pointer --target=aarch64-none-none -fsyntax-only -### %s -o %t 2>&1 | FileCheck %s --check-prefix=CHECK-NONLEAFFP -! CHECK-NONLEAFFP: "-mframe-pointer=non-leaf" +! CHECK-NONLEAFFP: "-fc1"{{.*}}"-mframe-pointer=non-leaf" ! RUN: %flang -fno-omit-frame-pointer --target=x86-none-none -fsyntax-only -### %s -o %t 2>&1 | FileCheck %s --check-prefix=CHECK-ALLFP -! CHECK-ALLFP: "-mframe-pointer=all" +! CHECK-ALLFP: "-fc1"{{.*}}"-mframe-pointer=all" diff --git a/flang/test/Driver/func-attr.f90 b/flang/test/Driver/func-attr.f90 index dddb8cde52ff1c..a29ff21d90374c 100644 --- a/flang/test/Driver/func-attr.f90 +++ b/flang/test/Driver/func-attr.f90 @@ -1,4 +1,4 @@ -! Test that -mframe-pointer can accept only specific values. +! Test that -mframe-pointer can accept only specific values and when given an invalid value, check it raises an error. ! RUN: %flang_fc1 -triple aarch64-none-none -mframe-pointer=none -emit-llvm -o - %s 2>&1| FileCheck %s --check-prefix=CHECK-NONEFP ! RUN: %flang_fc1 -triple aarch64-none-none -mframe-pointer=non-leaf -emit-llvm -o - %s 2>&1| FileCheck %s --check-prefix=CHECK-NONLEAFFP diff --git a/flang/test/Driver/mlir-debug-pass-pipeline.f90 b/flang/test/Driver/mlir-debug-pass-pipeline.f90 index 6d602d6edab229..45b1717d7187db 100644 --- a/flang/test/Driver/mlir-debug-pass-pipeline.f90 +++ b/flang/test/Driver/mlir-debug-pass-pipeline.f90 @@ -1,14 +1,14 @@ ! Test the debug pass pipeline -! RUN: %flang -fomit-frame-pointer -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline -o /dev/null %s 2>&1 | FileCheck --check-prefixes=ALL,NO-DEBUG %s +! RUN: %flang -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline -o /dev/null %s 2>&1 | FileCheck --check-prefixes=ALL,NO-DEBUG %s -! RUN: %flang -fomit-frame-pointer -g0 -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline %s -o /dev/null 2>&1 | FileCheck --check-prefixes=ALL,NO-DEBUG %s -! RUN: %flang -fomit-frame-pointer -g -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline %s -o /dev/null 2>&1 | FileCheck --check-prefixes=ALL,DEBUG %s -! RUN: %flang -fomit-frame-pointer -g1 -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline %s -o /dev/null 2>&1 | FileCheck --check-prefixes=ALL,DEBUG %s -! RUN: %flang -fomit-frame-pointer -gline-tables-only -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline %s -o /dev/null 2>&1 | FileCheck --check-prefixes=ALL,DEBUG %s -! RUN: %flang -fomit-frame-pointer -gline-directives-only -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline %s -o /dev/null 2>&1 | FileCheck --check-prefixes=ALL,DEBUG,DEBUG-DIRECTIVES %s -! RUN: %flang -fomit-frame-pointer -g2 -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline %s -o /dev/null 2>&1 | FileCheck --check-prefixes=ALL,DEBUG,DEBUG-CONSTRUCT %s -! RUN: %flang -fomit-frame-pointer -g3 -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline %s -o /dev/null 2>&1 | FileCheck --check-prefixes=ALL,DEBUG,DEBUG-CONSTRUCT %s +! RUN: %flang -g0 -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline %s -o /dev/null 2>&1 | FileCheck --check-prefixes=ALL,NO-DEBUG %s +! RUN: %flang -g -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline %s -o /dev/null 2>&1 | FileCheck --check-prefixes=ALL,DEBUG %s +! RUN: %flang -g1 -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline %s -o /dev/null 2>&1 | FileCheck --check-prefixes=ALL,DEBUG %s +! RUN: %flang -gline-tables-only -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline %s -o /dev/null 2>&1 | FileCheck --check-prefixes=ALL,DEBUG %s +! RUN: %flang -gline-directives-only -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline %s -o /dev/null 2>&1 | FileCheck --check-prefixes=ALL,DEBUG,DEBUG-DIRECTIVES %s +! RUN: %flang -g2 -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline %s -o /dev/null 2>&1 | FileCheck --check-prefixes=ALL,DEBUG,DEBUG-CONSTRUCT %s +! RUN: %flang -g3 -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline %s -o /dev/null 2>&1 | FileCheck --check-prefixes=ALL,DEBUG,DEBUG-CONSTRUCT %s ! RUN: not %flang_fc1 -debug-info-kind=invalid -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline %s -o /dev/null 2>&1 | FileCheck --check-prefixes=DEBUG-ERR %s @@ -82,5 +82,5 @@ ! ALL-NEXT: ExternalNameConversion ! DEBUG-NEXT: AddDebugFoundation ! NO-DEBUG-NOT: AddDebugFoundation -! ALL-NEXT: FIRToLLVMLowering +! ALL: FIRToLLVMLowering ! ALL-NOT: LLVMIRLoweringPass _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits