/* Ċ Ġ* ĠCopyright Ġ 2 0 1 0 - 2 0 1 7 ĠJetBrains Ġs . r . o . Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ Ċ package Ġorg . jetbrains . kotlin . codegen . optimization . box ing Ċ Ċ import Ġorg . jetbrains . kotlin . codegen . optimization . common . Fast Method Analyzer Ċ import Ġorg . jetbrains . kotlin . codegen . optimization . common . find Previous OrNull Ċ import Ġorg . jetbrains . kotlin . codegen . optimization . transformer . Method Transformer Ċ import Ġorg . jetbrains . org . object web . asm . Op codes Ċ import Ġorg . jetbrains . org . object web . asm . tree .* Ċ Ċ class ĠStack P ee ph ole Optim izations Transformer Ġ: ĠMethod Transformer () Ġ{ ĊĠĠĠ Ġoverride Ġfun Ġtransform ( internal ClassName : ĠString , Ġmethod Node : ĠMethod Node ) Ġ{ ĊĠĠĠĠĠĠĠ Ġwhile Ġ( true ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! transform Once ( method Node )) Ġbreak ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġtransform Once ( method Node : ĠMethod Node ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġinstructions Ġ= Ġmethod Node . instructions ĊĠĠĠĠĠĠĠ Ġvar Ġchanged Ġ= Ġfalse ĊĊĠĠĠĠĠĠĠ Ġval Ġis Merge Node Ġ= ĠFast Method Analyzer . find Merge Nodes ( method Node ) ĊĊĠĠĠĠĠĠĠ Ġfun ĠAbstract Insn Node . previous Mean ing ful () Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfind Previous OrNull Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . opcode Ġ!= ĠOp codes . NOP Ġ&& Ġit . type Ġ!= ĠAbstract Insn Node . LINE Ġ&& ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( it . type Ġ!= ĠAbstract Insn Node . LABEL Ġ|| Ġis Merge Node [ instructions . indexOf ( it )]) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġvar Ġinsn : ĠAbstract Insn Node ? ĊĠĠĠĠĠĠĠ Ġvar Ġnext Ġ= Ġinstructions . first ĊĠĠĠĠĠĠĠ Ġwhile Ġ( next Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinsn Ġ= Ġnext ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnext Ġ= Ġinsn . next ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprev Ġ= Ġinsn . previous Mean ing ful () Ġ?: Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( insn . opcode ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOp codes . POP Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprev . is Elimin ated By Pop () Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinstructions . set ( insn , ĠIn sn Node ( Op codes . NOP )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinstructions . set ( prev , ĠIn sn Node ( Op codes . NOP )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchanged Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprev . opcode Ġ== ĠOp codes . DUP _ X 1 Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinstructions . set ( insn , ĠIn sn Node ( Op codes . NOP )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinstructions . set ( prev , ĠIn sn Node ( Op codes . SWAP )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchanged Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOp codes . SWAP Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprev 2 Ġ= Ġprev . previous Mean ing ful () Ġ?: Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( prev . is Pure Push Of Size 1 () Ġ&& Ġprev 2 . is Pure Push Of Size 1 ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinstructions . set ( insn , ĠIn sn Node ( Op codes . NOP )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinstructions . set ( prev , Ġprev 2 . clone ( empty Map ())) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinstructions . set ( prev 2 , Ġprev . clone ( empty Map ())) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchanged Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOp codes . I 2 L Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( prev . opcode ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOp codes . ICON ST _ 0 Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinstructions . set ( insn , ĠIn sn Node ( Op codes . NOP )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinstructions . set ( prev , ĠIn sn Node ( Op codes . L CONST _ 0 )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchanged Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOp codes . ICON ST _ 1 Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinstructions . set ( insn , ĠIn sn Node ( Op codes . NOP )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinstructions . set ( prev , ĠIn sn Node ( Op codes . L CONST _ 1 )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchanged Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOp codes . POP 2 Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( prev . is Elimin ated By Pop 2 ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinstructions . set ( insn , ĠIn sn Node ( Op codes . NOP )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinstructions . set ( prev , ĠIn sn Node ( Op codes . NOP )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchanged Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprev 2 Ġ= Ġprev . previous Mean ing ful () Ġ?: Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( prev . is Elimin ated By Pop () Ġ&& Ġprev 2 . is Elimin ated By Pop ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinstructions . set ( insn , ĠIn sn Node ( Op codes . NOP )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinstructions . set ( prev , ĠIn sn Node ( Op codes . NOP )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinstructions . set ( prev 2 , ĠIn sn Node ( Op codes . NOP )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchanged Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġchanged ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠAbstract Insn Node . is Elimin ated By Pop () Ġ= ĊĠĠĠĠĠĠĠ Ġis Pure Push Of Size 1 () Ġ|| ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġopcode Ġ== ĠOp codes . DUP ĊĊĠĠĠ Ġprivate Ġfun ĠAbstract Insn Node . is Pure Push Of Size 1 (): ĠBoolean Ġ= ĊĠĠĠĠĠĠĠ Ġ! is L dc Of Size 2 () Ġ&& Ġ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġopcode Ġin ĠOp codes . AC ON ST _ NULL .. Op codes . F CONST _ 2 Ġ|| ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġopcode Ġin ĠOp codes . B IP USH .. Op codes . I LOAD Ġ|| ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġopcode Ġ== ĠOp codes . F LOAD Ġ|| ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġopcode Ġ== ĠOp codes . AL O AD Ġ|| ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Unit Instance () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠ Ġprivate Ġfun ĠAbstract Insn Node . is Elimin ated By Pop 2 () Ġ= ĊĠĠĠĠĠĠĠ Ġis Pure Push Of Size 2 () Ġ|| ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġopcode Ġ== ĠOp codes . DUP 2 ĊĊĠĠĠ Ġprivate Ġfun ĠAbstract Insn Node . is Pure Push Of Size 2 (): ĠBoolean Ġ= ĊĠĠĠĠĠĠĠ Ġis L dc Of Size 2 () Ġ|| ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġopcode Ġ== ĠOp codes . L CONST _ 0 Ġ|| Ġopcode Ġ== ĠOp codes . L CONST _ 1 Ġ|| ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġopcode Ġ== ĠOp codes . D CONST _ 0 Ġ|| Ġopcode Ġ== ĠOp codes . D CONST _ 1 Ġ|| ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġopcode Ġ== ĠOp codes . L LOAD Ġ|| ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġopcode Ġ== ĠOp codes . D LOAD ĊĊĠĠĠ Ġprivate Ġfun ĠAbstract Insn Node . is L dc Of Size 2 (): ĠBoolean Ġ= ĊĠĠĠĠĠĠĠ Ġopcode Ġ== ĠOp codes . L DC Ġ&& Ġthis Ġis ĠL dc Insn Node Ġ&& Ġ( this . cst Ġis ĠDouble Ġ|| Ġthis . cst Ġis ĠLong ) Ċ } ĊĊ