This is an operation which returns the fir.shape for a hlfir.expr.
A hlfir.expr can be defined by:
- A transformational intrinsic (e.g. hlfir.matmul)
- hlfir.as_expr
- hlfir.elemental
hlfir.elemental is easy because there is a compulsory shape operand.
hlfir.as_expr is defined as operating on a variable (defined using a
hlfir.declare). hlfir.declare has an optional shape argument. The
transformational intrinsics do not have an associated shape.
If all extents are known at compile time, the extents for the shape can
be fetched from the hlfir.expr's type. For example, the result of a
hlfir.matmul with arguments who's extents are known at compile time will
have constant extents which can be queried from the type. In this case
the hlfir.shape_of will be canonicalised to a fir.shape operation using
those extents.
If not all extents are known at compile time, shapes have to be read
from boxes after bufferization. In the case of the transformational
intrinsics, the shape read from the result box can be queried from the
hlfir.declare operation for the buffer allocated to that hlfir.expr (via
the hlfir.as_expr).
I think genExprShape cannot be here, this will create circular dependencies in shared library builds. Can't genExprShape use an mlir::OpBuilder &builder instead of a fir::FirOpBuilder, I am not sure the FirOpBuilder specific helpers are used by it, and since a FirOpBuilder inherits from mlir::OpBuilder, it can still be passed to genExprShape.