The `acc.cache` operation is currently defined to be associated with a
loop. However, this implementation generates `acc.cache` as a standalone
data entry operation inside the loop body. The `acc.cache` operation
definition should be updated in a future change to reflect this usage.
Key implementation details:
- Add semantic checks to validate cache-specific constraints: at least
one bound must be specified for array sections, and only unit stride
is supported
- Use the shared `gatherDataOperandAddrAndBounds` infrastructure to
generate `acc.bounds` for cache operands, handling single elements
(`arr(i)`), full ranges (`arr(l:u)`), and partial ranges with missing
bounds (`arr(l:)` or `arr(:u)`)
- Set the data clause to `acc_cache` with the `readonly` modifier via
the `modifiers` attribute when the `readonly` clause is present
- Update the symbol map so subsequent lowering uses the cache result
- Insert cache operations after loop iterator setup
- Add symbol scope management for constructs inside `acc.loop`