Optimize gradient of `tf.reshape()` when one input dimension is dynamic.
Optimize gradient of `tf.reshape()` when one input dimension is dynamic.

Previously, if there was any unknown dimension in the shape of the input to `tf.reshape()` the gradient function would add a `tf.shape()` op that would introduce a data dependency on the input tensor, potentially keeping it live until the backward pass. However, in most cases* when only one of the input dimensions is unknown (e.g. a dynamic batch size) we can use the ability to pass a wildcard `-1` dimension to the `tf.reshape()` in the gradient function, and eliminate the data dependency.

(* Except when one or more of the input dimensions is 0, in which case the semantics of the wildcard are surprising, and resolve to 1.)
