  The trend towards specialization of software and hardware - fuelled by the
end of Moore's law and the still accelerating interest in domain-specific
computing, such as machine learning - forces us to radically rethink our
compiler designs. The era of a universal compiler framework built around a
single one-size-fits-all intermediate representation (IR) is over. This
realization has sparked the creation of the MLIR compiler framework that
empowers compiler engineers to design and integrate IRs capturing specific
abstractions. MLIR provides a generic framework for SSA-based IRs, but it
doesn't help us to decide how we should design IRs that are easy to develop, to
work with and to combine into working compilers.
  To address the challenge of IR design, we advocate for a language-oriented
compiler design that understands IRs as formal programming languages and
enforces their correct use via an accompanying type system. We argue that
programming language techniques directly guide extensible IR designs and
provide a formal framework to reason about transforming between multiple IRs.
In this paper, we discuss the design of the Shine compiler that compiles the
high-level functional pattern-based data-parallel language RISE via a hybrid
functional-imperative intermediate language to C, OpenCL, and OpenMP.
  We compare our work directly with the closely related pattern-based Lift IR
and compiler. We demonstrate that our language-oriented compiler design results
in a more robust and predictable compiler that is extensible at various
abstraction levels. Our experimental evaluation shows that this compiler design
is able to generate high-performance GPU code.
