@@ -1956,81 +1956,128 @@ void AIRSplitL2MemrefForBufferConstraintPass::runOnOperation() {
1956
1956
air::renumberMemcpyIfOps (&func.getBody ());
1957
1957
}
1958
1958
1959
- // Experimental: This pattern forces all memrefs allocated within the air.herd
1960
- // to be L1.
1961
- struct ForceL1MemrefInHerdPattern : public OpRewritePattern <memref::AllocOp> {
1962
- using OpRewritePattern<memref::AllocOp>::OpRewritePattern;
1959
+ // Experimental pattern to override the memory space of `memref.alloc`
1960
+ // operations when they appear inside a specified parent scope (e.g. herd,
1961
+ // segment).
1962
+ struct OverrideMemorySpacePattern : public OpRewritePattern <memref::AllocOp> {
1963
+ OverrideMemorySpacePattern (MLIRContext *ctx, StringRef scope, int memSpace)
1964
+ : OpRewritePattern<memref::AllocOp>(ctx), clScope(scope),
1965
+ clMemorySpace (memSpace) {}
1963
1966
1964
1967
LogicalResult matchAndRewrite (memref::AllocOp alloc,
1965
1968
PatternRewriter &rewriter) const override {
1966
- auto parentHerdOp = alloc->getParentOfType <air::HerdOp>();
1967
- if (!parentHerdOp)
1969
+ Operation *parent = nullptr ;
1970
+
1971
+ if (clScope == " herd" )
1972
+ parent = alloc->getParentOfType <air::HerdOp>();
1973
+ else if (clScope == " segment" )
1974
+ parent = alloc->getParentOfType <air::SegmentOp>();
1975
+ else if (clScope == " launch" )
1976
+ parent = alloc->getParentOfType <air::LaunchOp>();
1977
+ else
1978
+ return alloc->emitOpError (
1979
+ " Invalid clScope value: expected one of herd/segment/launch" );
1980
+
1981
+ if (!parent)
1968
1982
return failure ();
1969
1983
1970
- auto memref = dyn_cast<MemRefType>(alloc.getMemref ().getType ());
1971
- if (!memref )
1984
+ auto memrefTy = dyn_cast<MemRefType>(alloc.getMemref ().getType ());
1985
+ if (!memrefTy )
1972
1986
return failure ();
1973
- if (memref .getMemorySpaceAsInt () == ( int )air::MemorySpace::L1 )
1987
+ if (( int )memrefTy .getMemorySpaceAsInt () == clMemorySpace )
1974
1988
return failure ();
1975
1989
1976
1990
auto newMemrefType =
1977
- MemRefType::get (memref .getShape (), memref .getElementType (),
1978
- memref .getLayout ().getAffineMap (),
1979
- rewriter.getI32IntegerAttr (( int )air::MemorySpace::L1 ));
1991
+ MemRefType::get (memrefTy .getShape (), memrefTy .getElementType (),
1992
+ memrefTy .getLayout ().getAffineMap (),
1993
+ rewriter.getI32IntegerAttr (clMemorySpace ));
1980
1994
1981
1995
rewriter.replaceOpWithNewOp <memref::AllocOp>(alloc, newMemrefType);
1982
1996
1983
1997
return success ();
1984
1998
}
1999
+
2000
+ private:
2001
+ StringRef clScope; // Parent operation type to match
2002
+ int clMemorySpace; // Target memory space value to assign
1985
2003
};
1986
- struct correctMemrefSubviewIOMemorySpaces
1987
- : public OpRewritePattern<memref::SubViewOp> {
1988
- using OpRewritePattern<memref::SubViewOp>::OpRewritePattern;
1989
2004
1990
- LogicalResult matchAndRewrite (memref::SubViewOp subview,
1991
- PatternRewriter &rewriter) const override {
1992
- auto srcTy = dyn_cast<MemRefType>(subview.getViewSource ().getType ());
1993
- auto destTy = dyn_cast<MemRefType>(subview.getResult ().getType ());
1994
-
1995
- auto subviewOutputType =
1996
- llvm::cast<MemRefType>(memref::SubViewOp::inferResultType (
1997
- srcTy, subview.getMixedOffsets (), subview.getMixedSizes (),
1998
- subview.getMixedStrides ()));
1999
- if (destTy == subviewOutputType)
2000
- return failure ();
2005
+ // Pattern to correct memory spaces of view-like operations within a given
2006
+ // scope, following the application of OverrideMemorySpacePattern.
2007
+ template <typename OpTy>
2008
+ struct correctViewLikeOpIOMemorySpacesInScope : public OpRewritePattern <OpTy> {
2009
+ using OpRewritePattern<OpTy>::OpRewritePattern;
2001
2010
2002
- rewriter.replaceOpWithNewOp <memref::SubViewOp>(
2003
- subview, subviewOutputType, subview.getViewSource (),
2004
- subview.getMixedOffsets (), subview.getMixedSizes (),
2005
- subview.getMixedStrides ());
2011
+ LogicalResult matchAndRewrite (OpTy IFAOp,
2012
+ PatternRewriter &rewriter) const override {
2006
2013
2014
+ if (!IFAOp->template hasTrait <OpTrait::IsIsolatedFromAbove>())
2015
+ return failure ();
2016
+ llvm::DenseMap<ViewLikeOpInterface, SmallVector<OpResult>> viewLikeOpsToRes;
2017
+ IFAOp->template walk ([&](ViewLikeOpInterface viewLike) {
2018
+ auto srcTy = dyn_cast<MemRefType>(viewLike.getViewSource ().getType ());
2019
+ if (!srcTy)
2020
+ return ;
2021
+ for (auto res : viewLike->getResults ()) {
2022
+ auto destTy = dyn_cast<MemRefType>(res.getType ());
2023
+ if (!destTy)
2024
+ return ;
2025
+ if (srcTy.getMemorySpaceAsInt () == destTy.getMemorySpaceAsInt ())
2026
+ continue ;
2027
+ viewLikeOpsToRes[viewLike].push_back (res);
2028
+ }
2029
+ });
2030
+ for (auto [viewLike, results] : viewLikeOpsToRes) {
2031
+ for (OpResult res : results) {
2032
+ auto srcTy = dyn_cast<MemRefType>(viewLike.getViewSource ().getType ());
2033
+ auto destTy = dyn_cast<MemRefType>(res.getType ());
2034
+ MemRefType::Builder builder (destTy);
2035
+ builder.setMemorySpace (srcTy.getMemorySpace ());
2036
+ rewriter.modifyOpInPlace (viewLike, [&]() { res.setType (builder); });
2037
+ }
2038
+ }
2007
2039
return success ();
2008
2040
}
2009
2041
};
2010
2042
2011
- // An experimental pass forcing all memrefs allocated within an air.herd to have
2012
- // memory space L1 .
2013
- class AIRForceL1MemrefInHerdPass
2014
- : public air::impl::AIRForceL1MemrefInHerdPassBase <
2015
- AIRForceL1MemrefInHerdPass > {
2043
+ // An experimental pass forcing all memrefs allocated within a specified air
2044
+ // code region to have the specified memory space.
2045
+ class AIROverrideMemRefMemorySpacePass
2046
+ : public air::impl::AIROverrideMemRefMemorySpaceBase <
2047
+ AIROverrideMemRefMemorySpacePass > {
2016
2048
2017
2049
public:
2018
- AIRForceL1MemrefInHerdPass () = default ;
2019
- AIRForceL1MemrefInHerdPass (const AIRForceL1MemrefInHerdPass &pass){};
2050
+ AIROverrideMemRefMemorySpacePass () = default ;
2051
+ AIROverrideMemRefMemorySpacePass (
2052
+ const AIROverrideMemRefMemorySpacePass &pass){};
2053
+ AIROverrideMemRefMemorySpacePass (
2054
+ const ::xilinx::air::AIROverrideMemRefMemorySpaceOptions &options)
2055
+ : AIROverrideMemRefMemorySpaceBase(options) {}
2020
2056
2021
2057
void runOnOperation () override ;
2022
2058
2023
2059
private:
2024
2060
};
2025
2061
2026
- void AIRForceL1MemrefInHerdPass ::runOnOperation () {
2062
+ void AIROverrideMemRefMemorySpacePass ::runOnOperation () {
2027
2063
func::FuncOp funcOp = getOperation ();
2028
2064
MLIRContext *context = &getContext ();
2029
2065
2030
2066
RewritePatternSet patterns (context);
2031
- patterns.add <ForceL1MemrefInHerdPattern, correctMemrefSubviewIOMemorySpaces>(
2032
- context);
2067
+ patterns.add <OverrideMemorySpacePattern>(context, clScope, clMemorySpace);
2033
2068
(void )applyPatternsGreedily (funcOp, std::move (patterns));
2069
+ RewritePatternSet fixResTypePatterns (context);
2070
+ if (clScope == " herd" ) {
2071
+ fixResTypePatterns.add <correctViewLikeOpIOMemorySpacesInScope<air::HerdOp>>(
2072
+ context);
2073
+ } else if (clScope == " segment" ) {
2074
+ fixResTypePatterns
2075
+ .add <correctViewLikeOpIOMemorySpacesInScope<air::SegmentOp>>(context);
2076
+ } else if (clScope == " launch" ) {
2077
+ fixResTypePatterns
2078
+ .add <correctViewLikeOpIOMemorySpacesInScope<air::LaunchOp>>(context);
2079
+ }
2080
+ (void )applyPatternsGreedily (funcOp, std::move (fixResTypePatterns));
2034
2081
}
2035
2082
2036
2083
} // anonymous namespace
@@ -2092,8 +2139,12 @@ std::unique_ptr<Pass> createAIRSplitL2MemrefForBufferConstraintPass() {
2092
2139
return std::make_unique<AIRSplitL2MemrefForBufferConstraintPass>();
2093
2140
}
2094
2141
2095
- std::unique_ptr<Pass> createAIRForceL1MemrefInHerdPass () {
2096
- return std::make_unique<AIRForceL1MemrefInHerdPass>();
2142
+ std::unique_ptr<Pass> createAIROverrideMemRefMemorySpacePass () {
2143
+ return std::make_unique<AIROverrideMemRefMemorySpacePass>();
2144
+ }
2145
+ std::unique_ptr<Pass> createAIROverrideMemRefMemorySpacePass (
2146
+ AIROverrideMemRefMemorySpaceOptions options) {
2147
+ return std::make_unique<AIROverrideMemRefMemorySpacePass>(options);
2097
2148
}
2098
2149
2099
2150
} // namespace air
0 commit comments