package Ġorg . jetbrains . research . k fg . builder . cfg Ċ Ċ import Ġorg . jetbrains . research . k fg . Class Manager Ċ import Ġorg . jetbrains . research . k fg . ir . BasicBlock Ċ import Ġorg . jetbrains . research . k fg . ir . Body Block Ċ import Ġorg . jetbrains . research . k fg . ir . Method Ċ import Ġorg . jetbrains . research . k fg . ir . value . Value Ċ import Ġorg . jetbrains . research . k fg . ir . value . instruction . Instruction Ċ import Ġorg . jetbrains . research . k fg . ir . value . instruction . Return Inst Ċ import Ġorg . jetbrains . research . k fg . type . Integral Ċ import Ġorg . jetbrains . research . k fg . type . Type Ċ import Ġorg . jetbrains . research . k fg . type . merge Types Ċ import Ġorg . jetbrains . research . k fg . visitor . Method Visitor Ċ import Ġorg . jetbrains . research . k the l per . assert . kt assert Ċ import Ġorg . jetbrains . research . k the l per . logging . log Ċ import Ġkotlin . math . abs Ċ Ċ class ĠRet val Builder ( override Ġval Ġcm : ĠClass Manager ) Ġ: ĠMethod Visitor Ġ{ ĊĠĠĠ Ġprivate Ġval Ġreturn Values Ġ= Ġhash Map Of < BasicBlock , ĠReturn Inst >() ĊĊĠĠĠ Ġoverride Ġfun Ġcleanup () Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Values . clear () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġvisit Return Inst ( inst : ĠReturn Inst ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġbb Ġ= Ġinst . parent ĊĠĠĠĠĠĠĠ Ġreturn Values [ bb ] Ġ= Ġinst ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġvisit ( method : ĠMethod ) Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . visit ( method ) ĊĠĠĠĠĠĠĠ Ġif Ġ( return Values . size Ġ<= Ġ 1 ) Ġreturn ĊĊĊĠĠĠĠĠĠĠ Ġval Ġreturn Block Ġ= ĠBody Block (" bb . return ") ĊĊĠĠĠĠĠĠĠ Ġval Ġin com ings Ġ= Ġhash Map Of < BasicBlock , ĠValue >() ĊĠĠĠĠĠĠĠ Ġfor Ġ(( bb , Ġreturn Inst ) Ġin Ġreturn Values ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbb . remove ( return Inst ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbb . add Success or ( return Block ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Block . add Pre decessor ( bb ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( return Inst . has ReturnValue ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġin com ings [ bb ] Ġ= Ġreturn Inst . returnValue ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġjump Ġ= Ġinstructions . get Jump ( return Block ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġjump . location Ġ= Ġreturn Inst . location ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbb Ġ+= Ġjump ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġinstructions Ġ= Ġarray ListOf < Instruction >() ĊĠĠĠĠĠĠĠ Ġval Ġreturn Instruction Ġ= Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmethod . returnType . is Void Ġ-> Ġthis . instructions . get Return () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtype Ġ= Ġmerge Types ( types , Ġin com ings . values . map Ġ{ Ġit . type Ġ}. toSet ()) Ġ?: Ġmethod . returnType ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġretval Ġ= Ġthis . instructions . get Phi (" retval ", Ġtype , Ġin com ings ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinstructions . add ( retval ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠreturnValue Ġ= Ġwhen Ġ( type ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmethod . returnType Ġ-> Ġretval ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠIntegr al Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmethod Ret Type Ġ= Ġmethod . returnType ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġkt assert ( method Ret Type Ġis ĠIntegr al ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . error (" Return Ġvalue Ġtype Ġis Ġintegral Ġand Ġmethod Ġreturn Ġtype Ġis Ġ${ method . returnType }") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġif Ġreturn Ġtype Ġis ĠInt Ġand Ġreturn Ġvalue Ġtype Ġis ĠLong Ġ( or Ġvice Ġvers a ), Ġwe Ġneed Ġcasting ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġotherwise Ġit 's Ġfine ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( abs ( type . bit Size Ġ- Ġmethod Ret Type . bit Size ) Ġ>= ĠType . WORD ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġretval Cast ed Ġ= Ġthis . instructions . get Cast (" retval . cast ed ", Ġmethod . returnType , Ġretval ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinstructions . add ( retval Cast ed ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġretval Cast ed ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġretval ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġretval Cast ed Ġ= Ġthis . instructions . get Cast (" retval . cast ed ", Ġmethod . returnType , Ġretval ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinstructions . add ( retval Cast ed ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġretval Cast ed ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis . instructions . get Return ( returnValue ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġinstructions . add ( return Instruction ) ĊĠĠĠĠĠĠĠ Ġreturn Block . addAll (* instructions . to Typed Array ()) ĊĠĠĠĠĠĠĠ Ġmethod . add ( return Block ) ĊĠĠĠ Ġ} Ċ }