17
17
#include " mlir/IR/OpDefinition.h"
18
18
#include " mlir/IR/PatternMatch.h"
19
19
#include " mlir/Transforms/InliningUtils.h"
20
+ #include " llvm/ADT/ScopeExit.h"
20
21
#include " llvm/ADT/SmallBitVector.h"
21
22
#include " llvm/ADT/TypeSwitch.h"
22
23
#include " llvm/Support/Debug.h"
@@ -709,11 +710,19 @@ void mlir::fullyComposeAffineMapAndOperands(AffineMap *map,
709
710
// / Given a list of `OpFoldResult`, build the necessary operations to populate
710
711
// / `actualValues` with values produced by operations. In particular, for any
711
712
// / attribute-typed element in `values`, call the constant materializer
712
- // / associated with the Affine dialect to produce an operation.
713
+ // / associated with the Affine dialect to produce an operation. Do NOT notify
714
+ // / the builder listener about the constant ops being created as they are
715
+ // / intended to be removed after being folded into affine constructs; this is
716
+ // / not suitable for use beyond the Affine dialect.
713
717
static void materializeConstants (OpBuilder &b, Location loc,
714
718
ArrayRef<OpFoldResult> values,
715
719
SmallVectorImpl<Operation *> &constants,
716
720
SmallVectorImpl<Value> &actualValues) {
721
+ OpBuilder::Listener *listener = b.getListener ();
722
+ b.setListener (nullptr );
723
+ auto listenerResetter =
724
+ llvm::make_scope_exit ([listener, &b] { b.setListener (listener); });
725
+
717
726
actualValues.reserve (values.size ());
718
727
auto *dialect = b.getContext ()->getLoadedDialect <AffineDialect>();
719
728
for (OpFoldResult ofr : values) {
@@ -742,7 +751,7 @@ static void materializeConstants(OpBuilder &b, Location loc,
742
751
template <typename OpTy, typename ... Args>
743
752
static std::enable_if_t <OpTy::template hasTrait<OpTrait::OneResult>(),
744
753
OpFoldResult>
745
- createOrFold (RewriterBase &b, Location loc, ValueRange operands,
754
+ createOrFold (OpBuilder &b, Location loc, ValueRange operands,
746
755
Args &&...leadingArguments) {
747
756
// Identify the constant operands and extract their values as attributes.
748
757
// Note that we cannot use the original values directly because the list of
@@ -759,17 +768,30 @@ createOrFold(RewriterBase &b, Location loc, ValueRange operands,
759
768
760
769
// Create the operation and immediately attempt to fold it. On success,
761
770
// delete the operation and prepare the (unmaterialized) value for being
762
- // returned. On failure, return the operation result value.
771
+ // returned. On failure, return the operation result value. Temporarily remove
772
+ // the listener to avoid notifying it when the op is created as it may be
773
+ // removed immediately and there is no way of notifying the caller about that
774
+ // without resorting to RewriterBase.
775
+ //
763
776
// TODO: arguably, the main folder (createOrFold) API should support this use
764
777
// case instead of indiscriminately materializing constants.
778
+ OpBuilder::Listener *listener = b.getListener ();
779
+ b.setListener (nullptr );
780
+ auto listenerResetter =
781
+ llvm::make_scope_exit ([listener, &b] { b.setListener (listener); });
765
782
OpTy op =
766
783
b.create <OpTy>(loc, std::forward<Args>(leadingArguments)..., operands);
767
784
SmallVector<OpFoldResult, 1 > foldResults;
768
785
if (succeeded (op->fold (constantOperands, foldResults)) &&
769
786
!foldResults.empty ()) {
770
- b. eraseOp (op );
787
+ op-> erase ( );
771
788
return foldResults.front ();
772
789
}
790
+
791
+ // Notify the listener now that we definitely know that the operation will
792
+ // persist. Use the original listener stored in the variable.
793
+ if (listener)
794
+ listener->notifyOperationInserted (op);
773
795
return op->getResult (0 );
774
796
}
775
797
@@ -821,8 +843,7 @@ static void composeMultiResultAffineMap(AffineMap &map,
821
843
}
822
844
823
845
OpFoldResult
824
- mlir::makeComposedFoldedAffineApply (RewriterBase &b, Location loc,
825
- AffineMap map,
846
+ mlir::makeComposedFoldedAffineApply (OpBuilder &b, Location loc, AffineMap map,
826
847
ArrayRef<OpFoldResult> operands) {
827
848
assert (map.getNumResults () == 1 && " building affine.apply with !=1 result" );
828
849
@@ -835,21 +856,20 @@ mlir::makeComposedFoldedAffineApply(RewriterBase &b, Location loc,
835
856
// Constants are always folded into affine min/max because they can be
836
857
// represented as constant expressions, so delete them.
837
858
for (Operation *op : constants)
838
- b. eraseOp (op );
859
+ op-> erase ( );
839
860
return result;
840
861
}
841
862
842
863
OpFoldResult
843
- mlir::makeComposedFoldedAffineApply (RewriterBase &b, Location loc,
844
- AffineExpr expr,
864
+ mlir::makeComposedFoldedAffineApply (OpBuilder &b, Location loc, AffineExpr expr,
845
865
ArrayRef<OpFoldResult> operands) {
846
866
return makeComposedFoldedAffineApply (
847
867
b, loc, AffineMap::inferFromExprList (ArrayRef<AffineExpr>{expr}).front (),
848
868
operands);
849
869
}
850
870
851
871
SmallVector<OpFoldResult> mlir::makeComposedFoldedMultiResultAffineApply (
852
- RewriterBase &b, Location loc, AffineMap map,
872
+ OpBuilder &b, Location loc, AffineMap map,
853
873
ArrayRef<OpFoldResult> operands) {
854
874
return llvm::to_vector (llvm::map_range (
855
875
llvm::seq<unsigned >(0 , map.getNumResults ()), [&](unsigned i) {
@@ -866,7 +886,7 @@ Value mlir::makeComposedAffineMin(OpBuilder &b, Location loc, AffineMap map,
866
886
}
867
887
868
888
template <typename OpTy>
869
- static OpFoldResult makeComposedFoldedMinMax (RewriterBase &b, Location loc,
889
+ static OpFoldResult makeComposedFoldedMinMax (OpBuilder &b, Location loc,
870
890
AffineMap map,
871
891
ArrayRef<OpFoldResult> operands) {
872
892
SmallVector<Operation *> constants;
@@ -879,18 +899,18 @@ static OpFoldResult makeComposedFoldedMinMax(RewriterBase &b, Location loc,
879
899
// Constants are always folded into affine min/max because they can be
880
900
// represented as constant expressions, so delete them.
881
901
for (Operation *op : constants)
882
- b. eraseOp (op );
902
+ op-> erase ( );
883
903
return result;
884
904
}
885
905
886
906
OpFoldResult
887
- mlir::makeComposedFoldedAffineMin (RewriterBase &b, Location loc, AffineMap map,
907
+ mlir::makeComposedFoldedAffineMin (OpBuilder &b, Location loc, AffineMap map,
888
908
ArrayRef<OpFoldResult> operands) {
889
909
return makeComposedFoldedMinMax<AffineMinOp>(b, loc, map, operands);
890
910
}
891
911
892
912
OpFoldResult
893
- mlir::makeComposedFoldedAffineMax (RewriterBase &b, Location loc, AffineMap map,
913
+ mlir::makeComposedFoldedAffineMax (OpBuilder &b, Location loc, AffineMap map,
894
914
ArrayRef<OpFoldResult> operands) {
895
915
return makeComposedFoldedMinMax<AffineMaxOp>(b, loc, map, operands);
896
916
}
0 commit comments