Re-do the backends
- Re-architect the backend (hopefully for the last time!)
- CPU backend
- "RT" backend (generates async-await Rust code to call device functions)
- Supports product, summation, and array types as "memory objects", supports arbitrary addressing (with no implicit clone assumption)
- Unforkify pass, fork split pass (for easier codegen)