• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Try-catch blocks IR building
2
3## Overview
4
5Consider the following pandasm code:
6
7```
8.function void RuntimeException.init(RuntimeException a0) <ctor, external>
9
10.function i32 SimpleTryCatch.main() <static> {
11        try_begin_label_0: call.short SimpleTryCatch.foo
12        sta v0
13        try_end_label_0: lda v0
14        return
15        handler_begin_label_0_0: movi v0, 0x0
16        lda v0
17        return
18        handler_begin_label_0_1: movi v0, 0x1
19        lda v0
20        return
21
22.catch RuntimeException, try_begin_label_0, try_end_label_0, handler_begin_label_0_0
23.catch Exception, try_begin_label_0, try_end_label_0, handler_begin_label_0_1
24}
25
26.function i32 SimpleTryCatch.foo() <static> {
27        initobj.short RuntimeException.init
28        sta.obj v0
29        throw v0
30}
31```
32IR for this `main` method is:
33
34```
35            /-----------\
36            | Start bb  |
37            \-----------/
38                |
39                v
40            /-----------\
41            | Try-begin |---------->\------------------>\
42            \-----------/           |                   |
43                |                   |                   |
44                v                   |                   |
45        /---------------\           |                   |
46        | return foo()  |           |                   |
47        \---------------/           |                   |
48                |                   |                   |
49                v                   |                   |
50        /-----------\               |                   |
51        |  Try-end  |-------------->\------------------>\
52        \-----------/               |                   |
53                |                   |                   |
54                |                   v                   v
55                |               /-----------\       /-----------\
56                |               |  return 0 |       |  return 1 |
57                |               \-----------/       \-----------/
58                |                   |                   |
59                |                   v                   |
60                |               /-----------\           |
61                \-------------->|  End bb   |<----------/
62                                \-----------/
63```
64`Try-begin` and `Try-end` - are try boundaries basic blocks. Both of them have one normal control-flow successor and N catch-handlers successors (N is equal 2 in the example: try-block has 2 catch-handlers in the method).
65
66Edges form `Try-end` block to the catch-handlers are needed for correct linear order of basic blocks, since program flow can be jumped to the catch-handler after each throwable instruction, placed between try boundaries.
67
68## IR with unreachable try-end
69
70Consider the following pandasm code:
71
72```
73.record E {}
74
75.function void foo() {
76    return.void
77}
78
79.function u1 main() {
80    movi v0, 0x0
81    mov v2, v0
82try_begin:
83    movi v0, 0x2
84    call.short foo
85    mov.obj v3, v0
86    inci v2, 0x1
87    jmp try_begin
88try_end:
89    lda v2
90    return
91
92.catch E, try_begin, try_end, try_end
93}
94```
95IR for this `main` method is:
96
97```
98                /-----------\
99                | Start bb  |
100                \-----------/
101                      |
102                      v
103                /-----------\
104          /---> | TryBegin  |----------\
105          |     \-----------/          |
106          |           |                |
107          |           v                |
108          |        /-----\             |
109          |        | Try |             |
110          |        \-----/             |
111          |           |                |
112          |           v                v
113          |      /--------\        /-------\
114          \----  | TryEnd |------> | Catch |
115                 \--------/        \-------/
116                                       |
117                                       v
118                                  /--------\
119                                  | End bb |
120                                  \--------/
121```
122
123## Exceptions' meta-info in the IR
124
125`CatchPhi` - pseudo instruction which is added to the `Catch-begin` basic block. Each `CatchPhi` corresponds to the bytecode's virtual register and its inputs are values of these virtual registers in the points where throwable instructions are placed. `CatchPhi` contains vector of throwable instructions in the same order as related inputs.
126
127In the next example `CatchPhi` has 3 inputs: `a0`, `a1`, `a2` and contains vector of 3 throwable instructions: `call foo`, `call foo1`, `call foo2`:
128
129```
130try_begin:
131    movi v0, a0
132    call foo
133    movi v0, a1
134    call foo1
135    movi v0, a2
136    call foo2
137try_end:
138    jmp label
139...
140```
141
142`Try` - pseudo instruction which is added to the `Try-begin` basic block. It contains pointer to the `Try-end` and maps exceptions types to the catch-handlers basic blocks.
143
144In the example from overview section `Try` instruction provides information that `Try-begin`'s second successor is a handler for `RuntimeException` and the third successor is a handler for `Exception`.
145
146## Graph special data-structures for exceptions info
147
148- vector of try-begin blocks in order they are declared in the bytecode;
149- map from each throwable instruction the corresponding catch-handlers;
150
151## Try-catch blocks processing in the RegAlloc for bytecode-optimizer
152
153Currently the folowing algorithm is implemented:
154
155- RegAlloc reserves unique dst-register for each catch-phi in the graph;
156- Before each throwable instruction RegAlloc adds move from related catch-phi's input to the reserved catch-phi's dst-register;
157