[flang-commits] [flang] [Flang] Extracting internal constants from scalar literals (PR #73829)
Tom Eccles via flang-commits
flang-commits at lists.llvm.org
Thu Dec 7 09:06:36 PST 2023
================
@@ -0,0 +1,209 @@
+//===- ConstExtruder.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
+//
+//===----------------------------------------------------------------------===//
+
+#include "flang/Optimizer/Builder/BoxValue.h"
+#include "flang/Optimizer/Builder/FIRBuilder.h"
+#include "flang/Optimizer/Dialect/FIRDialect.h"
+#include "flang/Optimizer/Dialect/FIROps.h"
+#include "flang/Optimizer/Dialect/FIRType.h"
+#include "flang/Optimizer/Transforms/Passes.h"
+#include "mlir/Dialect/Func/IR/FuncOps.h"
+#include "mlir/IR/Diagnostics.h"
+#include "mlir/IR/Dominance.h"
+#include "mlir/Pass/Pass.h"
+#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
+#include "mlir/Transforms/Passes.h"
+#include "llvm/ADT/TypeSwitch.h"
+#include <atomic>
+
+namespace fir {
+#define GEN_PASS_DEF_CONSTEXTRUDEROPT
+#include "flang/Optimizer/Transforms/Passes.h.inc"
+} // namespace fir
+
+#define DEBUG_TYPE "flang-const-extruder-opt"
+
+namespace {
+std::atomic<int> uniqueLitId = 1;
+
+static bool needsExtrusion(const mlir::Value *a) {
+ if (!a || !a->getDefiningOp())
+ return false;
+
+ // is alloca
+ if (auto alloca = mlir::dyn_cast_or_null<fir::AllocaOp>(a->getDefiningOp())) {
+ // alloca has annotation
+ if (alloca->hasAttr(fir::getAdaptToByRefAttrName())) {
+ for (mlir::Operation *s : alloca.getOperation()->getUsers()) {
+ if (const auto store = mlir::dyn_cast_or_null<fir::StoreOp>(s)) {
+ auto constant_def = store->getOperand(0).getDefiningOp();
+ // Expect constant definition operation
+ if (mlir::isa<mlir::arith::ConstantOp>(constant_def)) {
+ return true;
----------------
tblah wrote:
I think the logic here needs to be stricter. We can only extrude a constant if *every* store to the address is *the same* constant.
I don't think this stops either of these cases:
```
%c1_i32 = arith.constant 1 : i32
%c2_i32 = arith.constant 2 : i32
%addr = fir.alloca i32 : fir.ref<i32>
fir.store %c1_i32 to %addr
fir.store %c2_i32 to %addr
```
```
func.func @func(%arg0: i32, %arg1: i1) {
%c2_i32 = arith.constant 2 : i32
%addr = fir.alloca i32 : fir.ref<i32>
fir.if (%arg1) {
fir.store %c2_i32 to %addr
} else {
fir.store %arg0 to %addr
}
return
}
```
https://github.com/llvm/llvm-project/pull/73829
More information about the flang-commits
mailing list