What qualifies as High-Level IR and Low-Level IR?

I read many papers that talk about high-level and low-level IR (I even remember some that have mentioned intermediate-level IR). What is the criterion to distinguish an IR between one level or another?

Is there such a thing as a low-level IR for an object-oriented language?

There is no strong definition that I know of, but a first approximation to form a mental model is that a low-level IR manipulates concepts close to the HW, think “raw pointer”, int, float and a set operations that is not too far abstract from the CPU ISA.
A high-level IR will have a type system and an operation set that is further abstracted from the HW in order to model concepts closer to the programming model. An example would be Machine Learning dataflow graph where the basic type is an immutable tensor and the operations are manipulating complete tensors.

1 Like

Thanks for the reply and the example.
So there’s nothing preventing to build an IR which mix low and high level abstractions at the same time right?
Is that what MLIR does?

Yes, more or less, there are limits. For example using LLVM instructions inside a Dataflow graph doesn’t make much sense. Also in general the difficulty to mix-n-match comes to the type system, but if the abstractions are close enough it works.
MLIR is an infrastructure that allows you to build new IRs, and possibly combine them (with the caveat above).