Skip to content

Commit

Permalink
[flang] Enable alias tags pass by default (#73111)
Browse files Browse the repository at this point in the history
Enable by default for optimization levels higher than 0 (same behavior
as clang).

For simplicity, only forward the flag to the frontend driver when it
contradicts what is implied by the optimization level.

Since #72903 there are now no
known performance regressions.
  • Loading branch information
tblah committed Nov 27, 2023
1 parent 9539cbf commit caba031
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 21 deletions.
20 changes: 20 additions & 0 deletions clang/lib/Driver/ToolChains/Flang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,26 @@ void Flang::addCodegenOptions(const ArgList &Args,
if (shouldLoopVersion(Args))
CmdArgs.push_back("-fversion-loops-for-stride");

Arg *aliasAnalysis = Args.getLastArg(options::OPT_falias_analysis,
options::OPT_fno_alias_analysis);
// only pass on the argument if it does not match that implied by the
// optimization level: so if optimization is requested, only forward
// -fno-alias-analysis. If optimization is not requested, only forward
// -falias-analysis.
Arg *optLevel =
Args.getLastArg(options::OPT_Ofast, options::OPT_O, options::OPT_O4);
if (aliasAnalysis) {
bool faliasAnalysis =
aliasAnalysis->getOption().matches(options::OPT_falias_analysis);
if (optLevel && !faliasAnalysis) {
CmdArgs.push_back("-fno-alias-analysis");
} else {
if (faliasAnalysis)
// requested alias analysis but no optimization enabled
CmdArgs.push_back("-falias-analysis");
}
}

Args.addAllArgs(CmdArgs, {options::OPT_flang_experimental_hlfir,
options::OPT_flang_deprecated_no_hlfir,
options::OPT_flang_experimental_polymorphism,
Expand Down
6 changes: 3 additions & 3 deletions flang/include/flang/Tools/CLOptions.inc
Original file line number Diff line number Diff line change
Expand Up @@ -158,10 +158,10 @@ inline void addDebugFoundationPass(mlir::PassManager &pm) {
}

inline void addFIRToLLVMPass(
mlir::PassManager &pm, llvm::OptimizationLevel optLevel = defaultOptLevel) {
mlir::PassManager &pm, const MLIRToLLVMPassPipelineConfig &config) {
fir::FIRToLLVMPassOptions options;
options.ignoreMissingTypeDescriptors = ignoreMissingTypeDescriptors;
options.applyTBAA = optLevel.isOptimizingForSpeed();
options.applyTBAA = config.AliasAnalysis;
options.forceUnifiedTBAATree = useOldAliasTags;
addPassConditionally(pm, disableFirToLlvmIr,
[&]() { return fir::createFIRToLLVMPass(options); });
Expand Down Expand Up @@ -311,7 +311,7 @@ inline void createDefaultFIRCodeGenPassPipeline(
if (config.VScaleMin != 0)
pm.addPass(fir::createVScaleAttrPass({config.VScaleMin, config.VScaleMax}));

fir::addFIRToLLVMPass(pm, config.OptLevel);
fir::addFIRToLLVMPass(pm, config);
}

/// Create a pass pipeline for lowering from MLIR to LLVM IR
Expand Down
10 changes: 6 additions & 4 deletions flang/lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,10 +242,12 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts,
clang::driver::options::OPT_fno_loop_versioning, false))
opts.LoopVersioning = 1;

opts.AliasAnalysis =
args.hasFlag(clang::driver::options::OPT_falias_analysis,
clang::driver::options::OPT_fno_alias_analysis,
/*default=*/false);
opts.AliasAnalysis = opts.OptimizationLevel > 0;
if (auto *arg =
args.getLastArg(clang::driver::options::OPT_falias_analysis,
clang::driver::options::OPT_fno_alias_analysis))
opts.AliasAnalysis =
arg->getOption().matches(clang::driver::options::OPT_falias_analysis);

for (auto *a : args.filtered(clang::driver::options::OPT_fpass_plugin_EQ))
opts.LLVMPassPlugins.push_back(a->getValue());
Expand Down
16 changes: 15 additions & 1 deletion flang/test/Driver/falias-analysis.f90
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,26 @@
! See flang/test/Fir/tbaa-codegen.fir for a test that the output is correct

! RUN: %flang -c -emit-llvm -falias-analysis %s -o - | llvm-dis | FileCheck %s --check-prefix=CHECK-AA --check-prefix=CHECK-ALL
! RUN: %flang -c -emit-llvm -falias-analysis -fno-alias-analysis %s -o - | llvm-dis | FileCheck %s --check-prefix=CHECK-NOAA --check-prefix=CHECK-ALL
! RUN: %flang -c -emit-llvm -Ofast %s -o - | llvm-dis | FileCheck %s --check-prefix=CHECK-AA --check-prefix=CHECK-ALL
! RUN: %flang -c -emit-llvm -O3 %s -o - | llvm-dis | FileCheck %s --check-prefix=CHECK-AA --check-prefix=CHECK-ALL
! RUN: %flang -c -emit-llvm -O2 %s -o - | llvm-dis | FileCheck %s --check-prefix=CHECK-AA --check-prefix=CHECK-ALL
! RUN: %flang -c -emit-llvm -O1 %s -o - | llvm-dis | FileCheck %s --check-prefix=CHECK-AA --check-prefix=CHECK-ALL

! RUN: %flang -c -emit-llvm -O0 %s -o - | llvm-dis | FileCheck %s --check-prefix=CHECK-NOAA --check-prefix=CHECK-ALL
! RUN: %flang -c -emit-llvm -Ofast -fno-alias-analysis %s -o - | llvm-dis | FileCheck %s --check-prefix=CHECK-NOAA --check-prefix=CHECK-ALL
! RUN: %flang -c -emit-llvm -fno-alias-analysis -Ofast %s -o - | llvm-dis | FileCheck %s --check-prefix=CHECK-NOAA --check-prefix=CHECK-ALL
! RUN: %flang -c -emit-llvm %s -o - | llvm-dis | FileCheck %s --check-prefix=CHECK-NOAA --check-prefix=CHECK-ALL
! RUN: %flang -c -emit-llvm -falias-analysis -fno-alias-analysis %s -o - | llvm-dis | FileCheck %s --check-prefix=CHECK-NOAA --check-prefix=CHECK-ALL

! RUN: %flang -fc1 -emit-llvm -falias-analysis %s -o - | FileCheck %s --check-prefix=CHECK-AA --check-prefix=CHECK-ALL
! RUN: %flang -fc1 -emit-llvm -O3 %s -o - | FileCheck %s --check-prefix=CHECK-AA --check-prefix=CHECK-ALL
! RUN: %flang -fc1 -emit-llvm -O2 %s -o - | FileCheck %s --check-prefix=CHECK-AA --check-prefix=CHECK-ALL
! RUN: %flang -fc1 -emit-llvm -O1 %s -o - | FileCheck %s --check-prefix=CHECK-AA --check-prefix=CHECK-ALL

! RUN: %flang -fc1 -emit-llvm -O0 %s -o - | FileCheck %s --check-prefix=CHECK-NOAA --check-prefix=CHECK-ALL
! RUN: %flang -fc1 -emit-llvm -falias-analysis -fno-alias-analysis %s -o - | FileCheck %s --check-prefix=CHECK-NOAA --check-prefix=CHECK-ALL
! RUN: %flang -fc1 -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-NOAA --check-prefix=CHECK-ALL
! RUN: %flang -fc1 -emit-llvm -O3 -fno-alias-analysis %s -o - | FileCheck %s --check-prefix=CHECK-NOAA --check-prefix=CHECK-ALL

subroutine simple(a)
integer, intent(inout) :: a(:)
Expand Down
2 changes: 2 additions & 0 deletions flang/test/Driver/mlir-pass-pipeline.f90
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@

! ALL-NEXT: 'func.func' Pipeline
! ALL-NEXT: PolymorphicOpConversion
! O2-NEXT: AddAliasTags
! O2-NEXT: 'func.func' Pipeline
! ALL-NEXT: CFGConversion

! ALL-NEXT: SCFToControlFlow
Expand Down
22 changes: 9 additions & 13 deletions flang/test/Driver/optimization-remark.f90
Original file line number Diff line number Diff line change
Expand Up @@ -41,28 +41,24 @@
! Once we start filtering, this is reduced to 1 one of the loop passes.

! PASS-REGEX-LOOP-ONLY-NOT: optimization-remark.f90:77:7: remark: hoisting load [-Rpass=licm]
! PASS-REGEX-LOOP-ONLY: optimization-remark.f90:83:5: remark: Loop deleted because it is invariant [-Rpass=loop-delete]
! PASS-REGEX-LOOP-ONLY: optimization-remark.f90:79:5: remark: Loop deleted because it is invariant [-Rpass=loop-delete]

! MISSED-REGEX-LOOP-ONLY-NOT: optimization-remark.f90:77:7: remark: failed to hoist load with loop-invariant address because load is conditionally executed [-Rpass-missed=licm]
! MISSED-REGEX-LOOP-ONLY: optimization-remark.f90:76:4: remark: loop not vectorized [-Rpass-missed=loop-vectorize]
! MISSED-REGEX-LOOP-ONLY: optimization-remark.f90:72:4: remark: loop not vectorized [-Rpass-missed=loop-vectorize]


! ANALYSIS-REGEX-LOOP-ONLY: optimization-remark.f90:79:7: remark: loop not vectorized: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
! ANALYSIS-REGEX-LOOP-ONLY: Unknown data dependence. Memory location is the same as accessed at optimization-remark.f90:78:7 [-Rpass-analysis=loop-vectorize]
! ANALYSIS-REGEX-LOOP-ONLY: optimization-remark.f90:73:7: remark: loop not vectorized: cannot identify array bounds [-Rpass-analysis=loop-vectorize]
! ANALYSIS-REGEX-LOOP-ONLY-NOT: remark: {{.*}}: IR instruction count changed from {{[0-9]+}} to {{[0-9]+}}; Delta: {{-?[0-9]+}} [-Rpass-analysis=size-info]

! PASS: optimization-remark.f90:77:7: remark: hoisting load [-Rpass=licm]
! PASS: optimization-remark.f90:83:5: remark: Loop deleted because it is invariant [-Rpass=loop-delete]
! PASS: optimization-remark.f90:79:5: remark: Loop deleted because it is invariant [-Rpass=loop-delete]

! MISSED: optimization-remark.f90:77:7: remark: failed to hoist load with loop-invariant address because load is conditionally executed [-Rpass-missed=licm]
! MISSED: optimization-remark.f90:76:4: remark: loop not vectorized [-Rpass-missed=loop-vectorize]
! MISSED-NOT: optimization-remark.f90:79:7: remark: loop not vectorized: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
! MISSED: optimization-remark.f90:73:7: remark: failed to move load with loop-invariant address because the loop may invalidate its value [-Rpass-missed=licm]
! MISSED: optimization-remark.f90:72:4: remark: loop not vectorized [-Rpass-missed=loop-vectorize]
! MISSED-NOT: optimization-remark.f90:75:7: remark: loop not vectorized: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
! MISSED-NOT: Unknown data dependence. Memory location is the same as accessed at optimization-remark.f90:78:7 [-Rpass-analysis=loop-vectorize]

! ANALYSIS: optimization-remark.f90:79:7: remark: loop not vectorized: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
! ANALYSIS: Unknown data dependence. Memory location is the same as accessed at optimization-remark.f90:78:7 [-Rpass-analysis=loop-vectorize]
! ANALYSIS: remark: {{.*}}: IR instruction count changed from {{[0-9]+}} to {{[0-9]+}}; Delta: {{-?[0-9]+}} [-Rpass-analysis=size-info]
! ANALYSIS-NOT: optimization-remark.f90:77:7: remark: failed to hoist load with loop-invariant address because load is conditionally executed [-Rpass-missed=licm]
! ANALYSIS: optimization-remark.f90:74:7: remark: loop not vectorized: unsafe dependent memory operations in loop.
! ANALYSIS: remark: {{.*}} instructions in function [-Rpass-analysis=asm-printer]

subroutine swap_real(a1, a2)
implicit none
Expand Down
4 changes: 4 additions & 0 deletions flang/test/Fir/basic-program.fir
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ func.func @_QQmain() {

// PASSES-NEXT: 'func.func' Pipeline
// PASSES-NEXT: PolymorphicOpConversion

// PASSES-NEXT: AddAliasTags

// PASSES-NEXT: 'func.func' Pipeline
// PASSES-NEXT: CFGConversion

// PASSES-NEXT: SCFToControlFlow
Expand Down
1 change: 1 addition & 0 deletions flang/tools/tco/tco.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ compileFIR(const mlir::PassPipelineCLParser &passPipeline) {
return mlir::failure();
} else {
MLIRToLLVMPassPipelineConfig config(llvm::OptimizationLevel::O2);
config.AliasAnalysis = true; // enabled when optimizing for speed
if (codeGenLLVM) {
// Run only CodeGen passes.
fir::createDefaultFIRCodeGenPassPipeline(pm, config);
Expand Down

0 comments on commit caba031

Please sign in to comment.