@@ -1786,7 +1786,6 @@ static void createNewDynamicSizes(MemRefType oldMemRefType,
1786
1786
}
1787
1787
}
1788
1788
1789
- // TODO: Currently works for static memrefs with a single layout map.
1790
1789
template <typename AllocLikeOp>
1791
1790
LogicalResult mlir::affine::normalizeMemRef (AllocLikeOp *allocOp) {
1792
1791
MemRefType memrefType = allocOp->getType ();
@@ -1799,7 +1798,6 @@ LogicalResult mlir::affine::normalizeMemRef(AllocLikeOp *allocOp) {
1799
1798
// Either memrefType already had an identity map or the map couldn't be
1800
1799
// transformed to an identity map.
1801
1800
return failure ();
1802
-
1803
1801
Value oldMemRef = allocOp->getResult ();
1804
1802
1805
1803
SmallVector<Value, 4 > symbolOperands (allocOp->getSymbolOperands ());
@@ -1819,8 +1817,40 @@ LogicalResult mlir::affine::normalizeMemRef(AllocLikeOp *allocOp) {
1819
1817
b.create <AllocLikeOp>(allocOp->getLoc (), newMemRefType, newDynamicSizes,
1820
1818
allocOp->getAlignmentAttr ());
1821
1819
} else {
1822
- newAlloc = b.create <AllocLikeOp>(allocOp->getLoc (), newMemRefType,
1823
- allocOp->getAlignmentAttr ());
1820
+ mlir::ValueRange dynamicSizes = allocOp->getDynamicSizes ();
1821
+ mlir::ValueRange symbolOperands = allocOp->getSymbolOperands ();
1822
+ ArrayRef<int64_t > newShape = newMemRefType.getShape ();
1823
+ ArrayRef<int64_t > oldShape = memrefType.getShape ();
1824
+ SmallVector<Value> mapOperands (oldShape.size () + symbolOperands.size ());
1825
+ SmallVector<Value> dimensionOperands;
1826
+ unsigned dimId = 0 , symId = 0 ;
1827
+ // Collect all the map operands of `allocOp` (both dynamic sizes and symbol
1828
+ // operands), which will help us to compute the dynamic sizes of the new
1829
+ // alloc op we are going to create.
1830
+ for (unsigned i = 0 , e = oldShape.size (); i < e; i++) {
1831
+ if (oldShape[i] == ShapedType::kDynamic )
1832
+ mapOperands[i] = dynamicSizes[dimId++];
1833
+ else
1834
+ mapOperands[i] =
1835
+ b.create <arith::ConstantIndexOp>(allocOp->getLoc (), oldShape[i]);
1836
+ }
1837
+ for (unsigned i = oldShape.size (), e = mapOperands.size (); i < e; i++)
1838
+ mapOperands[i] = symbolOperands[symId++];
1839
+ // Compute the dynamic sizes operands for the new alloc op. If `newShape` is
1840
+ // dynamic along a dimension, compute its shape using the layout map and
1841
+ // dynamic sizes and symbol operands of the old `allocOp`.
1842
+ for (unsigned i = 0 , e = newShape.size (); i < e; i++) {
1843
+ if (newShape[i] != ShapedType::kDynamic )
1844
+ continue ;
1845
+ AffineExpr resExpr = layoutMap.getResult (i);
1846
+ auto resMap = AffineMap::get (layoutMap.getNumDims (),
1847
+ layoutMap.getNumSymbols (), resExpr);
1848
+ dimensionOperands.push_back (
1849
+ b.create <AffineApplyOp>(allocOp->getLoc (), resMap, mapOperands));
1850
+ }
1851
+ newAlloc =
1852
+ b.create <AllocLikeOp>(allocOp->getLoc (), newMemRefType,
1853
+ dimensionOperands, allocOp->getAlignmentAttr ());
1824
1854
}
1825
1855
// Replace all uses of the old memref.
1826
1856
if (failed (replaceAllMemRefUsesWith (oldMemRef, /* newMemRef=*/ newAlloc,
@@ -1868,11 +1898,8 @@ MemRefType mlir::affine::normalizeMemRefType(MemRefType memrefType) {
1868
1898
1869
1899
// Normalize only static memrefs and dynamic memrefs with a tiled-layout map
1870
1900
// for now.
1871
- // TODO: Normalize the other types of dynamic memrefs.
1872
1901
SmallVector<std::tuple<AffineExpr, unsigned , unsigned >> tileSizePos;
1873
1902
(void )getTileSizePos (layoutMap, tileSizePos);
1874
- if (memrefType.getNumDynamicDims () > 0 && tileSizePos.empty ())
1875
- return memrefType;
1876
1903
1877
1904
// We have a single map that is not an identity map. Create a new memref
1878
1905
// with the right shape and an identity layout map.
@@ -1894,7 +1921,6 @@ MemRefType mlir::affine::normalizeMemRefType(MemRefType memrefType) {
1894
1921
unsigned newRank = layoutMap.getNumResults ();
1895
1922
if (failed (fac.composeMatchingMap (layoutMap)))
1896
1923
return memrefType;
1897
- // TODO: Handle semi-affine maps.
1898
1924
// Project out the old data dimensions.
1899
1925
fac.projectOut (newRank, fac.getNumVars () - newRank - fac.getNumLocalVars ());
1900
1926
SmallVector<int64_t , 4 > newShape (newRank);
@@ -1910,14 +1936,14 @@ MemRefType mlir::affine::normalizeMemRefType(MemRefType memrefType) {
1910
1936
// For a static memref and an affine map with no symbols, this is
1911
1937
// always bounded. However, when we have symbols, we may not be able to
1912
1938
// obtain a constant upper bound. Also, mapping to a negative space is
1913
- // invalid for normalization.
1914
- if (!ubConst.has_value () || *ubConst < 0 ) {
1915
- LLVM_DEBUG (llvm::dbgs ()
1916
- << " can't normalize map due to unknown/invalid upper bound" );
1939
+ // invalid for normalization. If dimension of new memrefType is dynamic,
1940
+ // the value is `ShapedType::kDynamic`.
1941
+ if (!ubConst.has_value ())
1942
+ newShape[d] = ShapedType::kDynamic ;
1943
+ else if (*ubConst >= 0 )
1944
+ newShape[d] = *ubConst + 1 ;
1945
+ else
1917
1946
return memrefType;
1918
- }
1919
- // If dimension of new memrefType is dynamic, the value is -1.
1920
- newShape[d] = *ubConst + 1 ;
1921
1947
}
1922
1948
1923
1949
// Create the new memref type after trivializing the old layout map.
0 commit comments