[XLA:GPU] Add support for destructuring collapsing reshapes in symbolic tiles.
[XLA:GPU] Add support for destructuring collapsing reshapes in symbolic tiles.

Take a reshape `[6,8] reshape([48])`. The indexing map going through this\
reshape from output to input would be\
&nbsp;&nbsp;&nbsp;&nbsp;`(d0, d1) -> (d0 * 8 + d1)`.\
Previously to this change, there was no support for extracting sizes and\
strides from a multivariate expression.

Deriving a `size_map` for the indexing map above is as simple as creating a map\
&nbsp;&nbsp;&nbsp;&nbsp;`(s0, s1) -> (s0 * s1)`,\
which is easy enough. However, deriving a `stride_map` for the expression is\
complicated. Conceptually, the stride of the composite expression should\
correspond to the stride of the minormost dimension involved in the reshape\
along which we capture more than a single element.

This holds because there are restrictions on what a valid tiling can be when\
going through a collapse. Let `s` be an `n`-dimensional shape that is fully\
collapsed. In order to be propagated successfully through the collapse, the\
pattern of the tiling of `s` has to look like\
&nbsp;&nbsp;&nbsp;&nbsp;`(1*, partial_dim?, full_dims*, 1*)`\
where `full_dims` are dimensions that are captured completely, and\
`partial_dim` is a dimension that can be captured with an arbitrary tile.\
This restriction is necessary to ensure that the gap between two elements\
captured in the expression is always the same (i.e., the set of elements can\
be described using a single `stride` and is thus a tile).

Based on the above, algorithm for extracting the `stride` could therefore be\
represented as a series of nested `if` statements\
&nbsp;&nbsp;&nbsp;&nbsp;`if size0 != 1 then stride0 else (if size1 != 1 then stride1 else ...)`\
where `{size,stride}i` corresponds to the `i-th` major {size,stride}.

We implement a utility function that allows us to generate `if` statements as\
affine expressions.
