Skip to content

Commit a537883

Browse files
Fix further review comments.
Additionally fixed a bug where same argument used twice would not have the store and alloca removed. Add test to check for those instructions being removed.
1 parent 2cf9e6f commit a537883

File tree

2 files changed

+43
-22
lines changed

2 files changed

+43
-22
lines changed

flang/lib/Optimizer/Transforms/ConstantArgumentGlobalisation.cpp

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ namespace fir {
2222
#include "flang/Optimizer/Transforms/Passes.h.inc"
2323
} // namespace fir
2424

25-
#define DEBUG_TYPE "flang-constang-argument-globalisation-opt"
25+
#define DEBUG_TYPE "flang-constant-argument-globalisation-opt"
2626

2727
namespace {
2828
unsigned uniqueLitId = 1;
@@ -45,7 +45,7 @@ class CallOpRewriter : public mlir::OpRewritePattern<fir::CallOp> {
4545
bool needUpdate = false;
4646
fir::FirOpBuilder builder(rewriter, module);
4747
llvm::SmallVector<mlir::Value> newOperands;
48-
llvm::SmallVector<mlir::Operation *> toErase;
48+
llvm::SmallVector<std::pair<mlir::Operation *, mlir::Operation *>> allocas;
4949
for (const mlir::Value &a : callOp.getArgs()) {
5050
auto alloca = mlir::dyn_cast_or_null<fir::AllocaOp>(a.getDefiningOp());
5151
// We can convert arguments that are alloca, and that has
@@ -74,53 +74,45 @@ class CallOpRewriter : public mlir::OpRewritePattern<fir::CallOp> {
7474
}
7575
}
7676

77-
// If we didn't find one signle store, add argument as is, and move on.
77+
// If we didn't find any store, or multiple stores, add argument as is
78+
// and move on.
7879
if (!store) {
7980
newOperands.push_back(a);
8081
continue;
8182
}
8283

8384
LLVM_DEBUG(llvm::dbgs() << " found store " << *store << "\n");
8485

85-
mlir::Operation *constant_def = store->getOperand(0).getDefiningOp();
86-
// Expect constant definition operation or force legalisation of the
87-
// callOp and continue with its next argument
88-
if (!mlir::isa<mlir::arith::ConstantOp>(constant_def)) {
86+
mlir::Operation *definingOp = store->getOperand(0).getDefiningOp();
87+
// If not a constant, add to operands and move on.
88+
if (!mlir::isa<mlir::arith::ConstantOp>(definingOp)) {
8989
// Unable to remove alloca arg
9090
newOperands.push_back(a);
9191
continue;
9292
}
9393

94-
LLVM_DEBUG(llvm::dbgs() << " found define " << *constant_def << "\n");
94+
LLVM_DEBUG(llvm::dbgs() << " found define " << *definingOp << "\n");
9595

9696
std::string globalName =
9797
"_global_const_." + std::to_string(uniqueLitId++);
9898
assert(!builder.getNamedGlobal(globalName) &&
9999
"We should have a unique name here");
100100

101-
unsigned count = 0;
102-
for (mlir::Operation *s : alloca->getUsers())
103-
if (di.dominates(store, s))
104-
++count;
105-
106-
// Delete if dominates itself and one more operation (which should
107-
// be callOp)
108-
if (count == 2)
109-
toErase.push_back(store);
101+
allocas.push_back(std::make_pair(alloca, store));
110102

111103
auto loc = callOp.getLoc();
112104
fir::GlobalOp global = builder.createGlobalConstant(
113105
loc, varTy, globalName,
114106
[&](fir::FirOpBuilder &builder) {
115-
mlir::Operation *cln = constant_def->clone();
107+
mlir::Operation *cln = definingOp->clone();
116108
builder.insert(cln);
117109
mlir::Value val =
118110
builder.createConvert(loc, varTy, cln->getResult(0));
119111
builder.create<fir::HasValueOp>(loc, val);
120112
},
121113
builder.createInternalLinkage());
122-
mlir::Value addr = {builder.create<fir::AddrOfOp>(
123-
loc, global.resultType(), global.getSymbol())};
114+
mlir::Value addr = builder.create<fir::AddrOfOp>(
115+
loc, global.resultType(), global.getSymbol());
124116
newOperands.push_back(addr);
125117
needUpdate = true;
126118
}
@@ -139,8 +131,19 @@ class CallOpRewriter : public mlir::OpRewritePattern<fir::CallOp> {
139131
newOp->setAttrs(callOp->getAttrs());
140132
rewriter.replaceOp(callOp, newOp);
141133

142-
for (auto e : toErase)
143-
rewriter.eraseOp(e);
134+
for (auto a : allocas) {
135+
unsigned count = 0;
136+
137+
for (auto i : a.first->getUsers())
138+
++count;
139+
140+
// If the alloca is only used for a store and the call operand, the
141+
// store is no longer required.
142+
if (count == 1) {
143+
rewriter.eraseOp(a.second);
144+
rewriter.eraseOp(a.first);
145+
}
146+
}
144147
LLVM_DEBUG(llvm::dbgs() << "global constant for " << callOp << " as "
145148
<< newOp << '\n');
146149
return mlir::success();

flang/test/Transforms/constant-argument-globalisation-2.fir

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,21 @@ module {
7878
// CHECK: }
7979

8080
}
81+
82+
// -----
83+
// Check that same argument used twice is converted.
84+
module {
85+
func.func @func(%arg0: !fir.ref<i32>, %arg1: i1) {
86+
%c2_i32 = arith.constant 2 : i32
87+
%addr1 = fir.alloca i32 {adapt.valuebyref}
88+
fir.store %c2_i32 to %addr1 : !fir.ref<i32>
89+
fir.call @sub1(%addr1, %addr1) : (!fir.ref<i32>, !fir.ref<i32>) -> ()
90+
return
91+
}
92+
}
93+
94+
// CHECK-LABEL: func.func @func
95+
// CHECK-NEXT: %[[ARG1:.*]] = fir.address_of([[CONST1:@.*]]) : !fir.ref<i32>
96+
// CHECK-NEXT: %[[ARG2:.*]] = fir.address_of([[CONST2:@.*]]) : !fir.ref<i32>
97+
// CHECK-NEXT: fir.call @sub1(%[[ARG1]], %[[ARG2]])
98+
// CHECK-NEXT: return

0 commit comments

Comments
 (0)