package Ġworld . ph ant asm al . ps ol ib . asm . data Flow Analysis Ċ Ċ import Ġmu . Kotlin Logging Ċ import Ġworld . ph ant asm al . ps ol ib . asm .* Ċ import Ġkotlin . math . max Ċ import Ġkotlin . math . min Ċ Ċ private Ġval Ġlogger Ġ= ĠKotlin Logging . logger Ġ{} Ċ Ċ /** Ċ Ġ* ĠComputes Ġthe Ġpossible Ġvalues Ġof Ġa Ġregister Ġright Ġbefore Ġa Ġspecific Ġinstruction . Ċ Ġ*/ Ċ fun Ġget Register Value ( cfg : ĠControl Flow Graph , Ġinstruction : ĠInstruction , Ġregister : ĠInt ): ĠValue Set Ġ{ ĊĠĠĠ Ġrequire ( register Ġin Ġ 0 .. 2 5 5 ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ" register Ġshould Ġbe Ġbetween Ġ 0 Ġand Ġ 2 5 5 , Ġinclusive Ġbut Ġwas Ġ$ register ." ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġblock Ġ= Ġcfg . getBlock For Instruction ( instruction ) ĊĊĠĠĠ Ġreturn ĠRegister Value Finder (). find ( ĊĠĠĠĠĠĠĠ Ġmutable Set Of (), ĊĠĠĠĠĠĠĠ Ġblock , ĊĠĠĠĠĠĠĠ Ġblock . indexOf Instruction ( instruction ), ĊĠĠĠĠĠĠĠ Ġregister ĊĠĠĠ Ġ) Ċ } Ċ Ċ private Ġclass ĠRegister Value Finder Ġ{ ĊĠĠĠ Ġprivate Ġvar Ġiterations Ġ= Ġ 0 ĊĊĠĠĠ Ġ// ĠTODO : ĠDe al Ġwith Ġincorrect Ġargument Ġtypes . ĊĠĠĠ Ġfun Ġfind ( ĊĠĠĠĠĠĠĠ Ġpath : ĠMutable Set < BasicBlock >, ĊĠĠĠĠĠĠĠ Ġblock : ĠBasic Block , ĊĠĠĠĠĠĠĠ Ġend : ĠInt , ĊĠĠĠĠĠĠĠ Ġregister : ĠInt , ĊĠĠĠ Ġ): ĠValue Set Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(++ iterations Ġ> Ġ 1 0 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . warn Ġ{ Ġ" Too Ġmany Ġiterations ." Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠValue Set . all () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġend Ġ- Ġ 1 Ġdown To Ġblock . start ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġinstruction Ġ= Ġblock . segment . instructions [ i ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġargs Ġ= Ġinstruction . args ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( instruction . opcode . code ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOP _ SYNC . code Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠAfter Ġa Ġsync Ġcall , Ġconcurrent Ġcode Ġcould Ġhave Ġmodified Ġthe Ġregister . ĠWe Ġdon 't ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġcheck Ġwhether Ġconcurrent Ġcode Ġ* ever * Ġwrites Ġto Ġthe Ġregister Ġto Ġpossibly ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġcontinue Ġthe Ġanalysis . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠValue Set . all () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOP _ VA _ CALL . code Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġvalue Ġ= Ġva Call ( path , Ġblock , Ġi , Ġregister ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( value . isNotEmpty ()) Ġreturn Ġvalue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOP _ LET . code Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( args [ 0 ]. value Ġ== Ġregister ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfind ( Linked HashSet ( path ), Ġblock , Ġi , Ġ( args [ 1 ] Ġas ĠInt Arg ). value ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOP _ LE TI . code , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOP _ LET B . code , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOP _ LE TW . code , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOP _ SYNC _ LE TI . code , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( args [ 0 ]. value Ġ== Ġregister ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠValue Set . of (( args [ 1 ] Ġas ĠInt Arg ). value ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOP _ SET . code Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( args [ 0 ]. value Ġ== Ġregister ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠValue Set . of ( 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOP _ CLEAR . code Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( args [ 0 ]. value Ġ== Ġregister ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠValue Set . of ( 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOP _ REV . code Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( args [ 0 ]. value Ġ== Ġregister ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprev Vals Ġ= Ġfind ( Linked HashSet ( path ), Ġblock , Ġi , Ġregister ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( prev Vals . size Ġ== Ġ 1 L Ġ&& Ġprev Vals [ 0 ] Ġ== Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠValue Set . of ( 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( 0 Ġin Ġprev Vals ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠValue Set . of Interval ( 0 , Ġ 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠValue Set . of ( 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOP _ AD DI . code Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( args [ 0 ]. value Ġ== Ġregister ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprev Vals Ġ= Ġfind ( Linked HashSet ( path ), Ġblock , Ġi , Ġregister ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprev Vals Ġ+= Ġ( args [ 1 ] Ġas ĠInt Arg ). value ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġprev Vals ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOP _ SUB I . code Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( args [ 0 ]. value Ġ== Ġregister ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprev Vals Ġ= Ġfind ( Linked HashSet ( path ), Ġblock , Ġi , Ġregister ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprev Vals Ġ-= Ġ( args [ 1 ] Ġas ĠInt Arg ). value ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġprev Vals ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOP _ MUL I . code Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( args [ 0 ]. value Ġ== Ġregister ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprev Vals Ġ= Ġfind ( Linked HashSet ( path ), Ġblock , Ġi , Ġregister ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprev Vals Ġ*= Ġ( args [ 1 ] Ġas ĠInt Arg ). value ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġprev Vals ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOP _ DI VI . code Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( args [ 0 ]. value Ġ== Ġregister ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprev Vals Ġ= Ġfind ( Linked HashSet ( path ), Ġblock , Ġi , Ġregister ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprev Vals Ġ/= Ġ( args [ 1 ] Ġas ĠInt Arg ). value ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġprev Vals ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOP _ IF _ ZONE _ CLEAR . code Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( args [ 0 ]. value Ġ== Ġregister ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠValue Set . of Interval ( 0 , Ġ 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOP _ GET _ DIFF L VL . code Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( args [ 0 ]. value Ġ== Ġregister ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠValue Set . of Interval ( 0 , Ġ 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOP _ GET _ SLOT NUMBER . code Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( args [ 0 ]. value Ġ== Ġregister ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠValue Set . of Interval ( 0 , Ġ 3 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOP _ GET _ RANDOM . code Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( args [ 1 ]. value Ġ== Ġregister ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTODO : Ġundefined Ġvalues . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmin Ġ= Ġfind ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLinked HashSet ( path ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġblock , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġi , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( args [ 0 ] Ġas ĠInt Arg ). value ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ). min OrNull () !! ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmax Ġ= Ġmax ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfind ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLinked HashSet ( path ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġblock , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġi , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( args [ 0 ] Ġas ĠInt Arg ). value Ġ+ Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ). max OrNull () !! , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmin Ġ+ Ġ 1 , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠValue Set . of Interval ( min , Ġmax Ġ- Ġ 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOP _ STACK _ PUSH M . code , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOP _ STACK _ PO PM . code , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmin Reg Ġ= Ġ( args [ 0 ] Ġas ĠInt Arg ). value ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmax Reg Ġ= Ġ( args [ 0 ] Ġas ĠInt Arg ). value Ġ+ Ġ( args [ 1 ] Ġas ĠInt Arg ). value ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( register Ġin Ġmin Reg Ġuntil Ġmax Reg ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠValue Set . all () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠAssume Ġany Ġother Ġop codes Ġthat Ġwrite Ġto Ġthe Ġregister Ġcan Ġproduce Ġany Ġvalue . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġparams Ġ= Ġinstruction . opcode . params ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġarg Len Ġ= Ġmin ( args . size , Ġparams . size ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( j Ġin Ġ 0 Ġuntil Ġarg Len ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġparam Ġ= Ġparams [ j ] ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( param . type Ġis ĠReg Type Ġ&& Ġparam . type . registers Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġreg Ref Ġ= Ġ( args [ j ] Ġas ĠInt Arg ). value ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ(( k , Ġreg Param ) Ġin Ġparam . type . registers . with Index ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( reg Param . write Ġ&& Ġreg Ref Ġ+ Ġk Ġ== Ġregister ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠValue Set . all () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġvalues Ġ= ĠValue Set . empty () ĊĠĠĠĠĠĠĠ Ġpath . add ( block ) ĊĊĠĠĠĠĠĠĠ Ġfor Ġ( from Ġin Ġblock . from ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠB ail Ġout Ġfrom Ġloops . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( from Ġin Ġpath ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠValue Set . all () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġvalues . union ( find ( Linked HashSet ( path ), Ġfrom , Ġfrom . end , Ġregister )) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠIf Ġvalues Ġis Ġempty Ġat Ġthis Ġpoint , Ġwe Ġknow Ġnothing Ġever Ġsets Ġthe Ġregister 's Ġvalue Ġfrom ĊĠĠĠĠĠĠĠ Ġ// Ġthis Ġthread Ġor Ġhandler . ĠConcurrent Ġcode Ġcould Ġhave Ġmodified Ġit , Ġwe Ġdon 't Ġyet Ġtry Ġto ĊĠĠĠĠĠĠĠ Ġ// Ġexclude Ġthis Ġpossibility Ġso Ġwe Ġjust Ġreturn Ġall Ġvalues . ĊĠĠĠĠĠĠĠ Ġif Ġ( values . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠValue Set . all () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġvalues ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠAfter Ġa Ġva _ start Ġinstruction , Ġ 0 Ġor Ġmore Ġarg _ push Ġinstructions Ġcan Ġbe Ġused . ĠWhen Ġva _ call Ġis ĊĠĠĠĠ Ġ* Ġexecuted Ġthe Ġvalues Ġon Ġthe Ġstack Ġwill Ġbecome Ġthe Ġvalues Ġof Ġregisters Ġr 1 .. r 7 Ġ( inclusive ) Ġin ĊĠĠĠĠ Ġ* Ġthe Ġorder Ġthat Ġthey Ġwere Ġpushed . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠE . g .: ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġva _ start ĊĠĠĠĠ Ġ* Ġarg _ push l Ġ 1 0 ĊĠĠĠĠ Ġ* Ġarg _ push l Ġ 2 0 ĊĠĠĠĠ Ġ* Ġva _ call Ġ 7 7 7 ĊĠĠĠĠ Ġ* Ġva _ end ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠThis Ġmeans Ġcall Ġ 7 7 7 Ġwith Ġr 1 Ġ= Ġ 1 0 Ġand Ġr 2 Ġ= Ġ 2 0 . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġva Call ( ĊĠĠĠĠĠĠĠ Ġpath : ĠMutable Set < BasicBlock >, ĊĠĠĠĠĠĠĠ Ġblock : ĠBasic Block , ĊĠĠĠĠĠĠĠ Ġva Call Idx : ĠInt , ĊĠĠĠĠĠĠĠ Ġregister : ĠInt , ĊĠĠĠ Ġ): ĠValue Set Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( register Ġ! in Ġ 1 .. 7 ) Ġreturn ĠValue Set . empty () ĊĊĠĠĠĠĠĠĠ Ġvar Ġva Start Idx Ġ= Ġ- 1 ĊĠĠĠĠĠĠĠ Ġval Ġstack Ġ= Ġmutable ListOf < Instruction >() ĊĊĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġblock . start Ġuntil Ġva Call Idx ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġinstruction Ġ= Ġblock . segment . instructions [ i ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġopcode Ġ= Ġinstruction . opcode ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( opcode . code Ġ== ĠOP _ VA _ START . code ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġva Start Idx Ġ= Ġi ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( va Start Idx Ġ!= Ġ- 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( opcode . code ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOP _ ARG _ P US HR . code , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOP _ ARG _ P US HL . code , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOP _ ARG _ PUSH B . code , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOP _ ARG _ PUSH W . code , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOP _ ARG _ PUSH A . code , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOP _ ARG _ P US HO . code , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOP _ ARG _ P US HS . code , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ-> Ġstack . add ( instruction ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( register Ġin Ġ 1 .. stack . size ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġinstruction Ġ= Ġstack [ register Ġ- Ġ 1 ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġarg Ġ= Ġinstruction . args . first () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( instruction . opcode . code ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOP _ ARG _ P US HR . code Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfind ( Linked HashSet ( path ), Ġblock , Ġva Start Idx , Ġ( arg Ġas ĠInt Arg ). value ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOP _ ARG _ P US HL . code , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOP _ ARG _ PUSH B . code , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOP _ ARG _ PUSH W . code , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ-> ĠValue Set . of (( arg Ġas ĠInt Arg ). value ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTODO : ĠDe al Ġwith Ġstrings . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> ĠValue Set . all () Ġ// ĠString Ġor Ġpointer ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠValue Set . of ( 0 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ