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