================
@@ -32,6 +33,50 @@ namespace mlir {
namespace {
+/// Simplify `cir.load` that loads from an alloca marked as "constant".
+///
+/// For example:
+///
+/// %0 = cir.alloca "x" align(4) const : !cir.ptr<!s32i>
+/// cir.store %init, %0 : !s32i, !cir.ptr<!s32i>
+/// %1 = cir.load %0 : !cir.ptr<!s32i>
+///
+/// All uses of the load above could be replaced with the SSA value `%init`.
+struct SimplifyConstantLoad : public OpRewritePattern<LoadOp> {
+ using OpRewritePattern<LoadOp>::OpRewritePattern;
+ LogicalResult matchAndRewrite(LoadOp op,
+ PatternRewriter &rewriter) const override {
+ // Volatile or atomic loads should not be simplified.
+ if (op.getIsVolatile() || op.getMemOrder())
+ return mlir::failure();
+
+ auto allocaOp = op.getAddr().getDefiningOp<cir::AllocaOp>();
+ if (!allocaOp || !allocaOp.getConstant())
+ return mlir::failure();
+
+ cir::StoreOp initStoreOp;
----------------
erichkeane wrote:
This whole loop here was quite confusing to me on first read thru. It seems to
really be a 'find-first-of' plus a 'if (find-second-of) return failure'?
What about:
```
auto isStoreToAlloca = [&](const mlir::OpOperand &use) { return
isa<cir::StoreOp>(use.getOwner()) && use.getOperandNumber() !=
cir::StoreOp::odsIndex_addr; };
mlir::UseRange uses = allocaOp->getUses();
auto firstStore = llvm::find_if(uses, isStoreToAlloca);
if (firstStore == uses.end())
return mlir::failure();
if (uses.end() != std::find_if(std::next(firstStore), uses.end(),
isStoreToAlloca))
return mlir::failure();
cir::StoreOp initStoreOp = cast<cir::StoreOp>(*firstStore);
```
??
The complexity of the loop/dependence between runs is a bit much for me.
(though the 'getOperandNumber' bit is a little subtle, I'd like an
explaination?).
https://github.com/llvm/llvm-project/pull/212284
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits