/* Ċ Ġ* ĠCopyright Ġ 2 0 1 0 - 2 0 2 1 ĠJetBrains Ġs . r . o . Ġand ĠKotlin ĠProgramming ĠLanguage Ġcontributors . Ċ Ġ* ĠUse Ġof Ġthis Ġsource Ġcode Ġis Ġgoverned Ġby Ġthe ĠApache Ġ 2 . 0 Ġlicense Ġthat Ġcan Ġbe Ġfound Ġin Ġthe Ġlicense / LICENSE . txt Ġfile . Ċ Ġ*/ Ċ Ċ package Ġorg . jetbrains . kotlin . backend . kon an . llvm Ċ Ċ import Ġkotlinx . c interop . alloc Array Ċ import Ġkotlinx . c interop . get Ċ import Ġkotlinx . c interop . mem Scoped Ċ import Ġllvm .* Ċ import Ġorg . jetbrains . kotlin . backend . kon an . Context Ċ import Ġorg . jetbrains . kotlin . backend . kon an . Runtime Names Ċ import Ġorg . jetbrains . kotlin . backend . kon an . ir . llvm Symbol Origin Ċ import Ġorg . jetbrains . kotlin . descriptors . kon an . Compiled K lib Module Origin Ċ import Ġorg . jetbrains . kotlin . ir . declarations . Ir Constructor Ċ import Ġorg . jetbrains . kotlin . ir . declarations . Ir Function Ċ import Ġorg . jetbrains . kotlin . ir . types . is Nothing Ċ import Ġorg . jetbrains . kotlin . ir . util . has Annotation Ċ import Ġorg . jetbrains . kotlin . ir . util . is Suspend Ċ import Ġorg . jetbrains . kotlin . ir . util . is Throwable Ċ Ċ /** Ċ Ġ* ĠAdd Ġattributes Ġto ĠLLVM Ġfunction Ġdeclaration Ġand Ġits Ġinvocation . Ċ Ġ*/ Ċ interface ĠL l vm Function Attribute Provider Ġ{ ĊĠĠĠ Ġfun Ġadd Call Site Attributes ( call Site : ĠLLVM Value Ref ) ĊĊĠĠĠ Ġfun Ġadd Function Attributes ( function : ĠLLVM Value Ref ) ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġfun Ġmake Empty (): ĠL l vm Function Attribute Provider Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠDummy Ll vm Function Attribute Provider ĊĊĠĠĠĠĠĠĠ Ġfun Ġcopy From External ( external Function : ĠLLVM Value Ref ): ĠL l vm Function Attribute Provider Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠL l vm Function Attributes Cop ier ( external Function ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġobject ĠDummy Ll vm Function Attribute Provider Ġ: ĠL l vm Function Attribute Provider Ġ{ ĊĠĠĠ Ġoverride Ġfun Ġadd Call Site Attributes ( call Site : ĠLLVM Value Ref ) Ġ{} ĊĊĠĠĠ Ġoverride Ġfun Ġadd Function Attributes ( function : ĠLLVM Value Ref ) Ġ{} Ċ } Ċ Ċ /** Ċ Ġ* ĠCop ies Ġattributes Ġfrom Ġthe Ġgiven Ġ[ external Function ]. Ċ Ġ* ĠThis Ġis Ġuseful Ġwhen Ġthe Ġ[ external Function ] Ġis Ġdeclared Ġin Ġthe Ġanother ĠLLVM Ġmodule , Ċ Ġ* Ġand Ġwe Ġwant Ġto Ġcreate Ġan Ġexternal Ġdeclaration Ġfor Ġit . Ċ Ġ*/ Ċ private Ġclass ĠL l vm Function Attributes Cop ier ( private Ġval Ġexternal Function : ĠLLVM Value Ref ) Ġ: ĠL l vm Function Attribute Provider Ġ{ ĊĊĠĠĠ Ġprivate Ġval Ġparams Count : ĠInt Ġby Ġlazy Ġ{ ĠLLVM Count Params ( external Function ) Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġattributes For Call Site : ĠList < List < LLVM Attribute Ref >> Ġby Ġlazy Ġ{ ĊĠĠĠĠĠĠĠ Ġattributes For Function Declaration . map Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWe Ġdon 't Ġneed Ġattributes Ġlike Ġcorrectly - rounded - divide - sqrt - fp - math Ġor Ġless - prec ise - fp mad Ġat Ġcalls ites . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠSo Ġlet 's Ġtake Ġonly Ġenum Ġand Ġinteger Ġattributes , Ġshould Ġbe Ġenough Ġto Ġgenerate Ġcorrect Ġcalls . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit . filter Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThis Ġfunction Ġis Ġactually Ġmore Ġlike Ġ" is Ġenum ĠOR Ġint Ġattribute ". ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLLVM Is Enum Attribute ( it ) Ġ!= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġattributes For Function Declaration : ĠList < List < LLVM Attribute Ref >> Ġby Ġlazy Ġ{ ĊĠĠĠĠĠĠĠ Ġmem Scoped Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresult Ġ= Ġmutable ListOf < List < LLVM Attribute Ref >>() ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( index Ġin ĠLLVM Attribute Function Index .. params Count ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcount Ġ= ĠLLVM Get Attribute Count AtIndex ( external Function , Ġindex ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġattributes Buffer Ġ= Ġalloc Array < LLVM Attribute Ref Var >( count ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLLVM Get Attributes AtIndex ( external Function , Ġindex , Ġattributes Buffer ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresult Ġ+= Ġ( 0 Ġuntil Ġcount ). map Ġ{ Ġattributes Buffer [ it ] !! Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresult ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġadd Call Site Attributes ( call Site : ĠLLVM Value Ref ) Ġ{ ĊĠĠĠĠĠĠĠ Ġattributes For Call Site . with Index (). forEach Ġ{ Ġ( list Index , Ġattribute List ) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġattribute List . forEach Ġ{ Ġattribute Ref Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLLVM Add Call Site Attribute ( call Site , ĠLLVM Attribute Function Index Ġ+ Ġlist Index , Ġattribute Ref ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġadd Function Attributes ( function : ĠLLVM Value Ref ) Ġ{ ĊĠĠĠĠĠĠĠ Ġattributes For Function Declaration . with Index (). forEach Ġ{ Ġ( list Index , Ġattribute List ) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġattribute List . forEach Ġ{ Ġattribute Ref Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLLVM Add Attribute AtIndex ( function , ĠLLVM Attribute Function Index Ġ+ Ġlist Index , Ġattribute Ref ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġfun Ġadd Call Site Attributes AtIndex ( context : ĠLLVM Context Ref , Ġcall Site : ĠLLVM Value Ref , Ġindex : ĠInt , Ġattributes : ĠList < Ll vm Attribute >) Ġ{ ĊĠĠĠ Ġattributes . forEach Ġ{ Ġattribute Ġ-> ĊĠĠĠĠĠĠĠ Ġval Ġllvm Attribute Ref Ġ= Ġcreate Ll vm Enum Attribute ( context , Ġattribute . as Attribute Kind Id ()) ĊĠĠĠĠĠĠĠ ĠLLVM Add Call Site Attribute ( call Site , Ġindex , Ġllvm Attribute Ref ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġfun Ġadd Declaration Attributes AtIndex ( context : ĠLLVM Context Ref , Ġfunction : ĠLLVM Value Ref , Ġindex : ĠInt , Ġattributes : ĠList < Ll vm Attribute >) Ġ{ ĊĠĠĠ Ġattributes . forEach Ġ{ Ġattribute Ġ-> ĊĠĠĠĠĠĠĠ Ġval Ġllvm Attribute Ref Ġ= Ġcreate Ll vm Enum Attribute ( context , Ġattribute . as Attribute Kind Id ()) ĊĠĠĠĠĠĠĠ ĠLLVM Add Attribute AtIndex ( function , Ġindex , Ġllvm Attribute Ref ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠLLVM Ġfunction 's Ġsignature , Ġen ric hed Ġwith Ġattributes . Ċ Ġ*/ Ċ internal Ġopen Ġclass ĠL l vm Function Signature ( ĊĠĠĠĠĠĠĠ Ġval ĠreturnType : ĠL l vm Ret Type , ĊĠĠĠĠĠĠĠ Ġval Ġparameter Types : ĠList < Ll vm Param Type > Ġ= Ġempty List (), ĊĠĠĠĠĠĠĠ Ġval Ġis Var arg : ĠBoolean Ġ= Ġfalse , ĊĠĠĠĠĠĠĠ Ġval Ġfunction Attributes : ĠList < Ll vm Function Attribute > Ġ= Ġempty List (), Ċ ) Ġ: ĠL l vm Function Attribute Provider Ġ{ ĊĊĠĠĠ Ġconstructor ( ir Function : ĠIr Function , Ġcontext Utils : ĠContext Utils ) Ġ: Ġthis ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠreturnType Ġ= Ġcontext Utils . get Ll vm Function ReturnType ( ir Function ), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġparameter Types Ġ= Ġcontext Utils . get Ll vm Function Parameter Types ( ir Function ), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfunction Attributes Ġ= Ġinfer Function Attributes ( context Utils , Ġir Function ), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Var arg Ġ= Ġfalse , ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġval Ġllvm FunctionType Ġby Ġlazy Ġ{ ĊĠĠĠĠĠĠĠ Ġfunction Type ( returnType . llvm Type , Ġis Var arg , Ġparameter Types . map Ġ{ Ġit . llvm Type Ġ}) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġadd Call Site Attributes ( call Site : ĠLLVM Value Ref ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcaller Ġ= ĠLLVM Get BasicBlock Parent ( LLVM Get Instruction Parent ( call Site )) ĊĠĠĠĠĠĠĠ Ġval Ġllvm Context Ġ= ĠLLVM Get Module Context ( LLVM Get Global Parent ( caller )) !! ĊĠĠĠĠĠĠĠ Ġadd Call Site Attributes AtIndex ( llvm Context , Ġcall Site , ĠLLVM Attribute Function Index , Ġfunction Attributes ) ĊĠĠĠĠĠĠĠ Ġadd Call Site Attributes AtIndex ( llvm Context , Ġcall Site , ĠLLVM Attribute Return Index , ĠreturnType . attributes ) ĊĠĠĠĠĠĠĠ Ġrepeat ( parameter Types . count ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd Call Site Attributes AtIndex ( llvm Context , Ġcall Site , Ġit Ġ+ Ġ 1 , Ġparameter Types [ it ]. attributes ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġadd Function Attributes ( function : ĠLLVM Value Ref ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġllvm Context Ġ= ĠLLVM Get Module Context ( LLVM Get Global Parent ( function )) !! ĊĠĠĠĠĠĠĠ Ġadd Declaration Attributes AtIndex ( llvm Context , Ġfunction , ĠLLVM Attribute Function Index , Ġfunction Attributes ) ĊĠĠĠĠĠĠĠ Ġadd Declaration Attributes AtIndex ( llvm Context , Ġfunction , ĠLLVM Attribute Return Index , ĠreturnType . attributes ) ĊĠĠĠĠĠĠĠ Ġrepeat ( parameter Types . count ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd Declaration Attributes AtIndex ( llvm Context , Ġfunction , Ġit Ġ+ Ġ 1 , Ġparameter Types [ it ]. attributes ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠProt otype Ġof Ġa ĠLLVM Ġfunction Ġthat Ġis Ġnot Ġtied Ġto Ġa Ġspecific ĠLLVM Ġmodule . Ċ Ġ*/ Ċ internal Ġclass ĠL l vm Function Proto ( ĊĠĠĠĠĠĠĠ Ġval Ġname : ĠString , ĊĠĠĠĠĠĠĠ ĠreturnType : ĠL l vm Ret Type , ĊĠĠĠĠĠĠĠ Ġparameter Types : ĠList < Ll vm Param Type > Ġ= Ġempty List (), ĊĠĠĠĠĠĠĠ Ġfunction Attributes : ĠList < Ll vm Function Attribute > Ġ= Ġempty List (), ĊĠĠĠĠĠĠĠ Ġval Ġorigin : ĠComp iled K lib Module Origin , ĊĠĠĠĠĠĠĠ Ġis Var arg : ĠBoolean Ġ= Ġfalse , ĊĠĠĠĠĠĠĠ Ġval Ġindependent : ĠBoolean Ġ= Ġfalse , Ċ ) Ġ: ĠL l vm Function Signature ( returnType , Ġparameter Types , Ġis Var arg , Ġfunction Attributes ) Ġ{ ĊĠĠĠ Ġconstructor ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġname : ĠString , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsignature : ĠL l vm Function Signature , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġorigin : ĠComp iled K lib Module Origin , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġindependent : ĠBoolean Ġ= Ġfalse , ĊĠĠĠ Ġ) Ġ: Ġthis ( name , Ġsignature . returnType , Ġsignature . parameter Types , Ġsignature . function Attributes , Ġorigin , Ġsignature . is Var arg , Ġindependent ) ĊĊĠĠĠ Ġconstructor ( ir Function : ĠIr Function , Ġsymbol Name : ĠString , Ġcontext Utils : ĠContext Utils ) Ġ: Ġthis ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġname Ġ= Ġsymbol Name , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠreturnType Ġ= Ġcontext Utils . get Ll vm Function ReturnType ( ir Function ), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġparameter Types Ġ= Ġcontext Utils . get Ll vm Function Parameter Types ( ir Function ), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfunction Attributes Ġ= Ġinfer Function Attributes ( context Utils , Ġir Function ), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġorigin Ġ= Ġir Function . llvm Symbol Origin , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġindependent Ġ= Ġir Function . has Annotation ( Runtime Names . independent ) ĊĠĠĠ Ġ) Ċ } Ċ Ċ private Ġfun Ġmust Not Inline ( context : ĠContext , Ġir Function : ĠIr Function ): ĠBoolean Ġ{ ĊĠĠĠ Ġif Ġ( context . should Contain Location Debug Info ()) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( ir Function Ġis ĠIr Constructor Ġ&& Ġir Function . is Primary Ġ&& Ġir Function . returnType . is Throwable ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTo Ġsimplify Ġskipping Ġthis Ġconstructor Ġwhen Ġscanning Ġcall Ġstack Ġin ĠKotlin _ getCurrent StackTrace . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġreturn Ġfalse Ċ } Ċ Ċ private Ġfun Ġinfer Function Attributes ( context Utils : ĠContext Utils , Ġir Function : ĠIr Function ): ĠList < Ll vm Function Attribute > Ġ= ĊĠĠĠĠĠĠĠ Ġmutable ListOf < Ll vm Function Attribute >(). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġsuspend Ġfunction Ġcan Ġreturn Ġvalue Ġin Ġcase Ġof ĠCOR OUT INE _ SUS PEN DED . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( ir Function . returnType . is Nothing () Ġ&& Ġ! ir Function . is Suspend ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġadd ( Ll vm Function Attribute . No Return ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( must Not Inline ( context Utils . context , Ġir Function )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġadd ( Ll vm Function Attribute . No Inline ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ}