[flang-commits] [flang] [flang] Add -O flag to tco (PR #151869)
via flang-commits
flang-commits at lists.llvm.org
Mon Aug 4 06:35:25 PDT 2025
https://github.com/parabola94 updated https://github.com/llvm/llvm-project/pull/151869
>From 94f6eb3f9e3c6a646ef5ce1520f55305c42dbca0 Mon Sep 17 00:00:00 2001
From: parabola94 <heavybaby5000 at toki.waseda.jp>
Date: Sun, 3 Aug 2025 22:35:49 +0900
Subject: [PATCH 1/2] [flang] Add -O flag to tco
At the moment, there is no established way to emit LLVM IR before optimization in LLVM.
tco can partially does, but the optimization level is fixed to 2.
This patch adds -O flag to tco.
Note that this is not completely equivalent to the frontend option.
tco does not accept -O without number and the default value is not 0 but 2.
---
flang/test/Driver/tco-test-gen.fir | 9 ++++----
flang/tools/tco/tco.cpp | 35 ++++++++++++++++++++++++++++--
2 files changed, 38 insertions(+), 6 deletions(-)
diff --git a/flang/test/Driver/tco-test-gen.fir b/flang/test/Driver/tco-test-gen.fir
index 38d4e50ecf3aa..ec566488e32dd 100644
--- a/flang/test/Driver/tco-test-gen.fir
+++ b/flang/test/Driver/tco-test-gen.fir
@@ -1,5 +1,6 @@
// RUN: tco -emit-final-mlir %s | FileCheck %s --check-prefixes=CHECK,AA,CMPLX
// RUN: tco -emit-final-mlir -enable-aa=false %s | FileCheck %s --check-prefixes=CHECK,NOAA,CMPLX
+// RUN: tco -emit-final-mlir -O0 -enable-aa %s | FileCheck %s --check-prefixes=CHECK,NOAA,CMPLX
// RUN: tco -emit-final-mlir -simplify-mlir %s | FileCheck %s --check-prefixes=CHECK,AA,SIMPLE
// RUN: tco -emit-final-mlir -enable-aa=false -simplify-mlir %s | FileCheck %s --check-prefixes=CHECK,NOAA,SIMPLE
// RUN: tco -test-gen %s | FileCheck %s --check-prefixes=CHECK,NOAA,SIMPLE
@@ -37,10 +38,10 @@ func.func @_QPtest(%arg0: !fir.ref<i32> {fir.bindc_name = "num"}, %arg1: !fir.re
}
// CHECK-LABEL: llvm.func @_QPtest(
-// CHECK-SAME: %[[ARG0:.*]]: !llvm.ptr {fir.bindc_name = "num", llvm.nocapture},
-// CHECK-SAME: %[[ARG1:.*]]: !llvm.ptr {fir.bindc_name = "lb", llvm.nocapture},
-// CHECK-SAME: %[[ARG2:.*]]: !llvm.ptr {fir.bindc_name = "ub", llvm.nocapture},
-// CHECK-SAME: %[[ARG3:.*]]: !llvm.ptr {fir.bindc_name = "step", llvm.nocapture}) {
+// CHECK-SAME: %[[ARG0:.*]]: !llvm.ptr {fir.bindc_name = "num"{{[^}]*}}},
+// CHECK-SAME: %[[ARG1:.*]]: !llvm.ptr {fir.bindc_name = "lb"{{[^}]*}}},
+// CHECK-SAME: %[[ARG2:.*]]: !llvm.ptr {fir.bindc_name = "ub"{{[^}]*}}},
+// CHECK-SAME: %[[ARG3:.*]]: !llvm.ptr {fir.bindc_name = "step"{{[^}]*}}}) {
// CMPLX: %[[VAL_0:.*]] = llvm.mlir.constant(1 : i64) : i64
// CMPLX: %[[VAL_1:.*]] = llvm.alloca %[[VAL_0]] x i32 {bindc_name = "i"} : (i64) -> !llvm.ptr
diff --git a/flang/tools/tco/tco.cpp b/flang/tools/tco/tco.cpp
index d8daf8769cb21..b6d7c142c19df 100644
--- a/flang/tools/tco/tco.cpp
+++ b/flang/tools/tco/tco.cpp
@@ -51,6 +51,12 @@ static cl::opt<bool> emitFir("emit-fir",
cl::desc("Parse and pretty-print the input"),
cl::init(false));
+static cl::opt<unsigned>
+ OptLevel("O",
+ cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] "
+ "(default = '-O2')"),
+ cl::Prefix, cl::init(2));
+
static cl::opt<std::string> targetTriple("target",
cl::desc("specify a target triple"),
cl::init("native"));
@@ -96,6 +102,22 @@ static void printModule(mlir::ModuleOp mod, raw_ostream &output) {
output << mod << '\n';
}
+static std::optional<llvm::OptimizationLevel>
+getOptimizationLevel(unsigned level) {
+ switch (level) {
+ default:
+ return std::nullopt;
+ case 0:
+ return llvm::OptimizationLevel::O0;
+ case 1:
+ return llvm::OptimizationLevel::O1;
+ case 2:
+ return llvm::OptimizationLevel::O2;
+ case 3:
+ return llvm::OptimizationLevel::O3;
+ }
+}
+
// compile a .fir file
static llvm::LogicalResult
compileFIR(const mlir::PassPipelineCLParser &passPipeline) {
@@ -157,9 +179,18 @@ compileFIR(const mlir::PassPipelineCLParser &passPipeline) {
if (mlir::failed(passPipeline.addToPipeline(pm, errorHandler)))
return mlir::failure();
} else {
- MLIRToLLVMPassPipelineConfig config(llvm::OptimizationLevel::O2);
+ std::optional<llvm::OptimizationLevel> level =
+ getOptimizationLevel(OptLevel);
+ if (!level) {
+ errs() << "Error invalid optimization level\n";
+ return mlir::failure();
+ }
+ MLIRToLLVMPassPipelineConfig config(*level);
+ // TODO: config.StackArrays should be set here?
config.EnableOpenMP = true; // assume the input contains OpenMP
- config.AliasAnalysis = enableAliasAnalysis && !testGeneratorMode;
+ config.AliasAnalysis =
+ OptLevel > 0 && enableAliasAnalysis && !testGeneratorMode;
+ config.LoopVersioning = OptLevel > 2;
if (codeGenLLVM) {
// Run only CodeGen passes.
fir::createDefaultFIRCodeGenPassPipeline(pm, config);
>From d78b6b66bde08a84d73bd97ef37d0b48267d99e9 Mon Sep 17 00:00:00 2001
From: parabola94 <heavybaby5000 at toki.waseda.jp>
Date: Mon, 4 Aug 2025 22:34:26 +0900
Subject: [PATCH 2/2] -O0 does not affect TBAA
---
flang/test/Driver/tco-test-gen.fir | 9 ++++-----
flang/tools/tco/tco.cpp | 3 +--
2 files changed, 5 insertions(+), 7 deletions(-)
diff --git a/flang/test/Driver/tco-test-gen.fir b/flang/test/Driver/tco-test-gen.fir
index ec566488e32dd..38d4e50ecf3aa 100644
--- a/flang/test/Driver/tco-test-gen.fir
+++ b/flang/test/Driver/tco-test-gen.fir
@@ -1,6 +1,5 @@
// RUN: tco -emit-final-mlir %s | FileCheck %s --check-prefixes=CHECK,AA,CMPLX
// RUN: tco -emit-final-mlir -enable-aa=false %s | FileCheck %s --check-prefixes=CHECK,NOAA,CMPLX
-// RUN: tco -emit-final-mlir -O0 -enable-aa %s | FileCheck %s --check-prefixes=CHECK,NOAA,CMPLX
// RUN: tco -emit-final-mlir -simplify-mlir %s | FileCheck %s --check-prefixes=CHECK,AA,SIMPLE
// RUN: tco -emit-final-mlir -enable-aa=false -simplify-mlir %s | FileCheck %s --check-prefixes=CHECK,NOAA,SIMPLE
// RUN: tco -test-gen %s | FileCheck %s --check-prefixes=CHECK,NOAA,SIMPLE
@@ -38,10 +37,10 @@ func.func @_QPtest(%arg0: !fir.ref<i32> {fir.bindc_name = "num"}, %arg1: !fir.re
}
// CHECK-LABEL: llvm.func @_QPtest(
-// CHECK-SAME: %[[ARG0:.*]]: !llvm.ptr {fir.bindc_name = "num"{{[^}]*}}},
-// CHECK-SAME: %[[ARG1:.*]]: !llvm.ptr {fir.bindc_name = "lb"{{[^}]*}}},
-// CHECK-SAME: %[[ARG2:.*]]: !llvm.ptr {fir.bindc_name = "ub"{{[^}]*}}},
-// CHECK-SAME: %[[ARG3:.*]]: !llvm.ptr {fir.bindc_name = "step"{{[^}]*}}}) {
+// CHECK-SAME: %[[ARG0:.*]]: !llvm.ptr {fir.bindc_name = "num", llvm.nocapture},
+// CHECK-SAME: %[[ARG1:.*]]: !llvm.ptr {fir.bindc_name = "lb", llvm.nocapture},
+// CHECK-SAME: %[[ARG2:.*]]: !llvm.ptr {fir.bindc_name = "ub", llvm.nocapture},
+// CHECK-SAME: %[[ARG3:.*]]: !llvm.ptr {fir.bindc_name = "step", llvm.nocapture}) {
// CMPLX: %[[VAL_0:.*]] = llvm.mlir.constant(1 : i64) : i64
// CMPLX: %[[VAL_1:.*]] = llvm.alloca %[[VAL_0]] x i32 {bindc_name = "i"} : (i64) -> !llvm.ptr
diff --git a/flang/tools/tco/tco.cpp b/flang/tools/tco/tco.cpp
index b6d7c142c19df..36939802f55a6 100644
--- a/flang/tools/tco/tco.cpp
+++ b/flang/tools/tco/tco.cpp
@@ -188,8 +188,7 @@ compileFIR(const mlir::PassPipelineCLParser &passPipeline) {
MLIRToLLVMPassPipelineConfig config(*level);
// TODO: config.StackArrays should be set here?
config.EnableOpenMP = true; // assume the input contains OpenMP
- config.AliasAnalysis =
- OptLevel > 0 && enableAliasAnalysis && !testGeneratorMode;
+ config.AliasAnalysis = enableAliasAnalysis && !testGeneratorMode;
config.LoopVersioning = OptLevel > 2;
if (codeGenLLVM) {
// Run only CodeGen passes.
More information about the flang-commits
mailing list