/* Ċ Ġ* Ġ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 . backend . kon an . optim izations Ċ Ċ import Ġorg . jetbrains . kotlin . backend . kon an . Direct ed Graph Ċ import Ġorg . jetbrains . kotlin . backend . kon an . Direct ed Graph Node Ċ import Ġorg . jetbrains . kotlin . backend . kon an . Context Ċ import Ġorg . jetbrains . kotlin . backend . kon an . Kon an Config Keys Ċ import Ġorg . jetbrains . kotlin . kon an . target . Compiler Output Kind Ċ Ċ internal Ġclass ĠCall Graph Node ( val Ġgraph : ĠCall Graph , Ġval Ġsymbol : ĠData Flow IR . Function Symbol ) ĊĠĠĠ Ġ: ĠDirect ed Graph Node < Data Flow IR . Function Symbol > Ġ{ ĊĊĠĠĠ Ġoverride Ġval Ġkey Ġget () Ġ= Ġsymbol ĊĊĠĠĠ Ġoverride Ġval Ġdirect Edges : ĠList < Data Flow IR . Function Symbol > Ġby Ġlazy Ġ{ ĊĠĠĠĠĠĠĠ Ġgraph . direct Edges [ symbol ] !!. call Sites ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġit . actual Cal lee Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġgraph . reversed Edges . containsKey ( it ) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġval Ġreversed Edges : ĠList < Data Flow IR . Function Symbol > Ġby Ġlazy Ġ{ ĊĠĠĠĠĠĠĠ Ġgraph . reversed Edges [ symbol ] !! ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġclass ĠCall Site ( val Ġcall : ĠData Flow IR . Node . Call , Ġval Ġactual Cal lee : ĠData Flow IR . Function Symbol ) ĊĊĠĠĠ Ġval Ġcall Sites Ġ= Ġmutable ListOf < Call Site >() Ċ } Ċ Ċ internal Ġclass ĠCall Graph ( val Ġdirect Edges : ĠMap < Data Flow IR . Function Symbol , ĠCall Graph Node >, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġreversed Edges : ĠMap < Data Flow IR . Function Symbol , ĠMutable List < Data Flow IR . Function Symbol >>) ĊĠĠĠ Ġ: ĠDirect ed Graph < Data Flow IR . Function Symbol , ĠCall Graph Node > Ġ{ ĊĊĠĠĠ Ġoverride Ġval Ġnodes Ġget () Ġ= Ġdirect Edges . values ĊĊĠĠĠ Ġoverride Ġfun Ġget ( key : ĠData Flow IR . Function Symbol ) Ġ= Ġdirect Edges [ key ] !! ĊĊĠĠĠ Ġfun Ġadd Edge ( caller : ĠData Flow IR . Function Symbol , Ġcall Site : ĠCall Graph Node . Call Site ) Ġ{ ĊĠĠĠĠĠĠĠ Ġdirect Edges [ caller ] !!. call Sites Ġ+= Ġcall Site ĊĠĠĠĠĠĠĠ Ġreversed Edges [ call Site . actual Cal lee ]?. add ( caller ) ĊĠĠĠ Ġ} Ċ Ċ } Ċ Ċ internal Ġclass ĠCall Graph Builder ( val Ġcontext : ĠContext , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmodule DF G : ĠModule DF G , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexternal Modules DF G : ĠExternal Modules DF G ) Ġ{ ĊĊĠĠĠ Ġprivate Ġval ĠDEBUG Ġ= Ġ 0 ĊĊĠĠĠ Ġprivate Ġinline Ġfun ĠDEBUG _ OUTPUT ( severity : ĠInt , Ġblock : Ġ() Ġ-> ĠUnit ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( DEBUG Ġ> Ġseverity ) Ġblock () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġhas Main Ġ= Ġcontext . config . configuration . get ( Kon an Config Keys . PRO DU CE ) Ġ== ĠCompiler Output Kind . PROGRAM ĊĊĠĠĠ Ġprivate Ġval Ġsymbol Table Ġ= Ġmodule DF G . symbol Table ĊĊĠĠĠ Ġprivate Ġfun ĠData Flow IR . Type . resolved (): ĠData Flow IR . Type . Declared Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( this Ġis ĠData Flow IR . Type . Declared ) Ġreturn Ġthis ĊĠĠĠĠĠĠĠ Ġval Ġhash Ġ= Ġ( this Ġas ĠData Flow IR . Type . External ). hash ĊĠĠĠĠĠĠĠ Ġreturn Ġexternal Modules DF G . public Types [ hash ] Ġ?: Ġerror (" Unable Ġto Ġresolve Ġexported Ġtype Ġ$ hash ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠData Flow IR . Function Symbol . resolved (): ĠData Flow IR . Function Symbol Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( this Ġis ĠData Flow IR . Function Symbol . External ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġexternal Modules DF G . public Functions [ this . hash ] Ġ?: Ġthis ĊĠĠĠĠĠĠĠ Ġreturn Ġthis ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠData Flow IR . Type . Declared . is Subtype Of ( other : ĠData Flow IR . Type . Declared ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġthis Ġ== Ġother Ġ|| Ġthis . super Types . any Ġ{ Ġit . resolved (). is Subtype Of ( other ) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġdirect Edges Ġ= Ġmutable Map Of < Data Flow IR . Function Symbol , ĠCall Graph Node >() ĊĠĠĠ Ġprivate Ġval Ġreversed Edges Ġ= Ġmutable Map Of < Data Flow IR . Function Symbol , ĠMutable List < Data Flow IR . Function Symbol >>() ĊĠĠĠ Ġprivate Ġval Ġcall Graph Ġ= ĠCall Graph ( direct Edges , Ġreversed Edges ) ĊĊĠĠĠ Ġfun Ġbuild (): ĠCall Graph Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġroot Set Ġ= Ġif Ġ( has Main ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠlistOf ( symbol Table . map Function ( context . ir . symbols . entry Point !!. owner ). resolved ()) Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmodule DF G . functions ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġit . key Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . is Global Initializer Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmodule DF G . functions . keys . filter Is Instance < Data Flow IR . Function Symbol . Public >() ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ@ Suppress (" Loop To Call Chain ") ĊĠĠĠĠĠĠĠ Ġfor Ġ( symbol Ġin Ġroot Set ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! direct Edges . containsKey ( symbol )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdfs ( symbol ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġcall Graph ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġdfs ( symbol : ĠData Flow IR . Function Symbol ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġnode Ġ= ĠCall Graph Node ( call Graph , Ġsymbol ) ĊĠĠĠĠĠĠĠ Ġdirect Edges . put ( symbol , Ġnode ) ĊĠĠĠĠĠĠĠ Ġval Ġlist Ġ= Ġmutable ListOf < Data Flow IR . Function Symbol >() ĊĠĠĠĠĠĠĠ Ġreversed Edges . put ( symbol , Ġlist ) ĊĠĠĠĠĠĠĠ Ġval Ġfunction Ġ= Ġmodule DF G . functions [ symbol ] Ġ?: Ġexternal Modules DF G . function DF Gs [ symbol ] ĊĠĠĠĠĠĠĠ Ġval Ġbody Ġ= Ġfunction !!. body ĊĠĠĠĠĠĠĠ Ġbody . nodes . filter Is Instance < Data Flow IR . Node . Call >() ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcal lee Ġ= Ġit . callee . resolved () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcall Graph . add Edge ( symbol , ĠCall Graph Node . Call Site ( it , Ġcal lee )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( callee Ġis ĠData Flow IR . Function Symbol . Declared ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ&& Ġit Ġ! is ĠData Flow IR . Node . Virtual Call ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ&& Ġ! direct Edges . containsKey ( callee )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdfs ( callee ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ }