[IR] Improved performance of IR-based interpreter (upto 23%)

* Introduced a few classes of operations and used them to
  split the monolithic interpreter dispatch switch into
  a switch on operation class with different methods handling
  the operations belonging to a class. This has a few different
  benefits:
  - cuts down the size of the interpreter loop body
  - enables more specialized code for each class of operations
    without generic interpretation overhead across the board
  - lets us manually inline more operations into the interpreter
    loop switch opening the opportunity for more JVM inlining

* Also added some new operation types for a few of the specialized
  call instructions. This also enables us to inline their execution
  in the interpreter loop body.

* Results on a few benchmarks below:
+-----------+---------------------------------+
|           |  OLD       NEW          | AST   |
+-----------+---------------------------------+
| fib_rec   |  6.22 -->  6.05 (0.97x) |  2.70 |
| red_black | 43.14 --> 33.05 (0.77x) | 25.17 |
| richards  |  9.67 -->  8.37 (0.87x) |  5.36 |
| meteor    | 23.00 --> 20.47 (0.89x) | 14.21 |
| neural    | 22.58 --> 20.09 (0.89x) |  9.95 |
| tictactoe | 56.98 --> 52.34 (0.92x) | 38.22 |
+-----------+---------------------------------+

* So, significant speedup on most programs.

* This is a first pass at this approach -- to be experimented with,
  refined, and cleaned up more.