He hana paʻakikī loa ka hoʻomohala ʻana i kahi mea hoʻopili. Akā, ʻoi aku ka maikaʻi, me ka hoʻomohala ʻana o nā papahana e like me LLVM, ua maʻalahi loa ka hoʻonā ʻana i kēia pilikia, e hiki ai i kahi mea polokalamu hoʻokahi ke hana i kahi ʻōlelo hou e kokoke ana i ka hana iā C. ʻO ka hana ʻana me LLVM paʻakikī i ka ʻoiaʻiʻo o kēia. Hōʻike ʻia ka ʻōnaehana e ka nui o nā code, i lako me nā palapala liʻiliʻi. I mea e ho'āʻo ai e hoʻoponopono i kēia hemahema, e hōʻike ana ka mea kākau o ka mea, ka unuhi a mākou e paʻi nei i kēia lā, i nā hiʻohiʻona o nā code i kākau ʻia ma Go a hōʻike i ke ʻano o ka unuhi mua ʻia ʻana i loko.
Laʻana mua
ʻO ka hana mua aʻu e nānā ai ma ʻaneʻi he mīkini maʻalahi no ka hoʻohui ʻana i nā helu:
func myAdd(a, b int) int{
return a + b
}
He mea maʻalahi kēia hana, a, ʻaʻohe mea hiki ke maʻalahi. Unuhi ia i ke code Go SSA penei:
func myAdd(a int, b int) int:
entry:
t0 = a + b int
return t0
Me kēia hōʻike, hoʻonoho ʻia nā ʻano ʻikepili o ka hana ma ka ʻākau a hiki ke nānā ʻole ʻia i ka nui o nā hihia.
Hiki i kēia hiʻohiʻona liʻiliʻi ke ʻike iā ʻoe i ke ʻano o kekahi ʻano o SSA. ʻO ia hoʻi, i ka hoʻololi ʻana i ke code i loko o ke ʻano SSA, ua wāwahi ʻia kēlā me kēia ʻōlelo i nā ʻāpana haʻahaʻa loa i haku ʻia. I kā mākou hihia, ke kauoha return a + b
, ʻoiaʻiʻo, hōʻike i nā hana ʻelua: hoʻohui i ʻelua helu a hoʻihoʻi i ka hopena.
Eia kekahi, ma aneʻi hiki iā ʻoe ke ʻike i nā poloka kumu o ka papahana; ma kēia code aia hoʻokahi poloka - ka poloka komo. E kamaʻilio hou mākou e pili ana i nā poloka ma lalo nei.
Hoʻololi maʻalahi ke code Go SSA i LLVM IR:
define i64 @myAdd(i64 %a, i64 %b) {
entry:
%0 = add i64 %a, %b
ret i64 %0
}
ʻO ka mea āu e ʻike ai, ʻoiai ke hoʻohana ʻia nā ʻano syntactic ʻē aʻe ma aneʻi, ʻaʻole loli ke ʻano o ka hana. ʻOi aku ka ikaika o ka code IR LLVM ma mua o ke code Go SSA, e like me C. Eia, i ka hoʻolaha hana, aia ka wehewehe mua o ke ʻano ʻikepili i hoʻihoʻi ʻia, hōʻike ʻia ke ʻano hoʻopaʻapaʻa ma mua o ka inoa hoʻopaʻapaʻa. Eia kekahi, no ka hoʻomaʻamaʻa ʻana i ka parsing IR, ʻo nā inoa o nā hui honua ma mua o ka hōʻailona @
, a ma mua o nā inoa kūloko he hōʻailona %
(manaʻo ʻia kekahi hana he hui honua).
ʻO kahi mea e hoʻomaopopo ai e pili ana i kēia code ʻo ia ka hoʻoholo hoʻohālikelike ʻano Go int
, hiki ke hōʻike ʻia ma ke ʻano he 32-bit a i ʻole 64-bit waiwai, ma muli o ka compiler a me ka pahuhopu o ka hoʻohui ʻana, ʻae ʻia i ka wā i hana ʻia ai ke code LLVM IR. ʻO kēia kekahi o nā kumu he nui ʻole ʻo LLVM IR code, e like me ka manaʻo o ka poʻe he nui, he kahua kūʻokoʻa. ʻO ia code, i hana ʻia no kahi kahua hoʻokahi, ʻaʻole hiki ke lawe wale ʻia a hōʻuluʻulu ʻia no kahi kahua ʻē aʻe (koe ke kūpono ʻoe no ka hoʻoponopono ʻana i kēia pilikia.
ʻO kekahi mea hoihoi e hoʻomaopopo ʻia ʻo ia ke ʻano i64
ʻaʻole ia he integer i pūlima ʻia: kūʻokoʻa ia ma ke ʻano o ka hōʻike ʻana i ka hōʻailona o ka helu. Ma muli o ke aʻo ʻana, hiki iā ia ke hōʻike i nā helu i hoʻopaʻa ʻia a me nā helu ʻole. I ka hihia o ka hōʻike ʻana i ka hana hoʻohui, ʻaʻohe mea nui kēia, no laila ʻaʻohe ʻokoʻa i ka hana ʻana me nā helu i kau inoa ʻia a i ʻole i hoʻopaʻa ʻia. Maʻaneʻi, makemake wau e hoʻomaopopo i ka ʻōlelo C, ʻo ka hoʻonui ʻana i kahi ʻano helu helu i hoʻopaʻa ʻia e alakaʻi i kahi ʻano ʻike ʻole, no laila e hoʻohui ka Clang frontend i kahi hae i ka hana. nsw
(ʻaʻole i hoʻopaʻa inoa ʻia), ka mea e haʻi iā LLVM hiki iā ia ke manaʻo ʻaʻole e kahe ka hoʻohui.
He mea koʻikoʻi paha kēia no kekahi mau koho. No ka laʻana, hoʻohui i ʻelua mau waiwai i16
ma kahi paepae 32-bit (me nā papa inoa 32-bit) pono, ma hope o ka hoʻohui ʻana, kahi hana hoʻonui hōʻailona i mea e noho ai i ka laulā. i16
. Ma muli o kēia, ʻoi aku ka maikaʻi o ka hana ʻana i nā hana integer e pili ana i ka nui o ka hoʻopaʻa inoa mīkini.
ʻO ka mea e hiki mai ana me kēia code IR ʻaʻole ia he mea hoihoi loa iā mākou i kēia manawa. Hoʻopili ʻia ke code (akā ma ke ʻano o kahi hiʻohiʻona maʻalahi e like me kā mākou, ʻaʻohe mea i hoʻoponopono ʻia) a laila hoʻololi ʻia i code mīkini.
Laʻana lua
ʻO ka hiʻohiʻona aʻe a mākou e nānā ai he mea paʻakikī iki. ʻO ia, ke kamaʻilio nei mākou e pili ana i kahi hana e hōʻuluʻulu i kahi ʻāpana o nā integer:
func sum(numbers []int) int {
n := 0
for i := 0; i < len(numbers); i++ {
n += numbers[i]
}
return n
}
Hoʻololi kēia code i kēia code Go SSA:
func sum(numbers []int) int:
entry:
jump for.loop
for.loop:
t0 = phi [entry: 0:int, for.body: t6] #n int
t1 = phi [entry: 0:int, for.body: t7] #i int
t2 = len(numbers) int
t3 = t1 < t2 bool
if t3 goto for.body else for.done
for.body:
t4 = &numbers[t1] *int
t5 = *t4 int
t6 = t0 + t5 int
t7 = t1 + 1:int int
jump for.loop
for.done:
return t0
Ma ʻaneʻi hiki iā ʻoe ke ʻike hou aku i nā hana maʻamau no ka hōʻike ʻana i ke code ma ke ʻano SSA. ʻO ka hiʻohiʻona maopopo loa paha o kēia code ʻo ia ka ʻoiaʻiʻo ʻaʻohe ʻano kauoha hoʻomalu kahe. No ka hoʻomaluʻana i ka holoʻana o ka heluʻana, aia wale nō ke kūlana a me ka leleʻole, a, inā mākou e noʻonoʻo i kēia kauoha ma keʻano he kauoha e mālama i ke kahe, he kauoha hoʻihoʻi.
ʻO kaʻoiaʻiʻo, hiki iā ʻoe ke hoʻolohe i ka ʻoiaʻiʻo ʻaʻole i māhele ʻia ka papahana i nā poloka me ka hoʻohana ʻana i nā braces curly (e like me ka ʻohana C o nā ʻōlelo). Hoʻokaʻawale ʻia e nā lepili, hoʻomanaʻo i nā ʻōlelo hui, a hōʻike ʻia ma ke ʻano o nā poloka kumu. Ma SSA, ua wehewehe ʻia nā poloka kumu ma ke ʻano he mau kaʻina pili o ke code e hoʻomaka ana me kahi lepili a me ka hoʻopau ʻana me nā ʻōlelo aʻoaʻo hoʻopau kumu, e like me − return
и jump
.
Hōʻike ʻia kekahi kikoʻī hoihoi o kēia code e ke aʻo phi
. ʻAʻole maʻamau nā ʻōlelo aʻo a hiki ke lōʻihi ka manawa e hoʻomaopopo ai. e hoomanao, i kela myAdd
i hōʻike ʻia ma luna, akā ʻaʻole kūpono ia no nā hana paʻakikī e like me ka hana i kūkākūkā ʻia ma kēia ʻāpana sum
. Ma keʻano kūikawā, hoʻololi nā mea hoʻololi i ka wā o ka hoʻokō ʻana i ka loop i
и n
.
Hoʻokaʻawale ʻo SSA i ka palena o ka hāʻawi ʻana i nā waiwai hoʻololi i ka hoʻohana ʻana i kahi ʻōlelo aʻo phi
(Ua lawe ʻia kona inoa mai ka huaʻōlelo Helene). ʻO ka mea ʻoiaʻiʻo, i mea e hana ʻia ai ka hōʻike SSA o ke code no nā ʻōlelo e like me C, pono ʻoe e hoʻohana i kekahi mau hoʻopunipuni. ʻO ka hopena o ke kāhea ʻana i kēia ʻōlelo aʻo ʻo ia ka waiwai o kēia manawa o ka hoʻololi (i
ai ole ia, n
), a hoʻohana ʻia kahi papa inoa o nā poloka kumu e like me kāna mau ʻāpana. No ka laʻana, e noʻonoʻo i kēia ʻōlelo aʻoaʻo:
t0 = phi [entry: 0:int, for.body: t6] #n
Penei kona manaʻo: inā he poloka ka poloka kumu mua entry
(hookomo), alaila t0
he mea mau 0
, a inā ʻo ka poloka kumu mua for.body
, a laila pono ʻoe e lawe i ka waiwai t6
mai keia poloka. He mea pohihihi paha kēia, akā ʻo kēia ka mea e hana ai ka SSA. Mai kahi hiʻohiʻona kanaka, paʻakikī kēia i ka hoʻomaopopo ʻana i ke code, akā ʻo ka ʻoiaʻiʻo o ka hāʻawi ʻia ʻana o kēlā me kēia waiwai i hoʻokahi wale nō e maʻalahi ai nā loiloi he nui.
E hoʻomaopopo inā ʻoe e kākau i kāu mea hoʻopili ponoʻī, ʻaʻole pono ʻoe e hana i kēia ʻano mea. ʻAʻole hana ʻo Clang i kēia mau ʻōlelo aʻoaʻo phi
, hoʻohana ia i kahi mīkini alloca
(e like me ka hana ʻana me nā mea hoʻololi kūloko maʻamau). A laila, i ka wā e holo ana i kahi LLVM optimization pass i kapa ʻia alloca
hoʻololi ʻia i ka palapala SSA. Loaʻa naʻe ʻo TinyGo i ka hoʻokomo ʻana mai Go SSA, ka mea maʻalahi, ua hoʻololi ʻia i ka palapala SSA.
ʻO kekahi mea hou o ka ʻāpana o ka code intermediate e noʻonoʻo ʻia nei, ʻo ke komo ʻana i nā mea ʻāpana e ka index i hōʻike ʻia ma ke ʻano o kahi hana o ka helu ʻana i ka helu wahi a me kahi hana o ka dereferencing i ka pointer hopena. Maanei hiki iā ʻoe ke ʻike i ka hoʻohui pololei o nā mea mau i ka code IR (no ka laʻana - 1:int
). I ka laʻana me ka hana myAdd
ʻaʻole i hoʻohana ʻia kēia. I kēia manawa ua loaʻa iā mākou kēlā mau hiʻohiʻona ma waho o ke ala, e nānā i ke ʻano o kēia code i ka wā e hoʻohuli ʻia ai i ke ʻano LLVM IR:
define i64 @sum(i64* %ptr, i64 %len, i64 %cap) {
entry:
br label %for.loop
for.loop: ; preds = %for.body, %entry
%0 = phi i64 [ 0, %entry ], [ %5, %deref.next ]
%1 = phi i64 [ 0, %entry ], [ %6, %deref.next ]
%2 = icmp slt i64 %1, %len
br i1 %2, label %for.body, label %for.done
for.body: ; preds = %for.loop
%3 = getelementptr i64, i64* %ptr, i64 %1
%4 = load i64, i64* %3
%5 = add i64 %0, %4
%6 = add i64 %1, 1
br label %for.loop
for.done: ; preds = %for.loop
ret i64 %0
}
Maʻaneʻi, e like me ka wā ma mua, hiki iā mākou ke ʻike i ke ʻano like, e komo pū ana me nā hale syntactic ʻē aʻe. Eia kekahi laʻana, ma nā kelepona phi
ua hoʻololi ʻia nā waiwai a me nā lepili. Eia naʻe, aia kekahi mea maʻaneʻi e kūpono i ka nānā kūikawā.
No ka hoʻomaka ʻana, ma aneʻi hiki iā ʻoe ke ʻike i kahi pūlima hana ʻokoʻa loa. ʻAʻole kākoʻo ʻo LLVM i nā ʻāpana, a ʻo ka hopena, ma ke ʻano he optimization, ʻo ka TinyGo compiler nāna i hoʻokumu i kēia code waena i hoʻokaʻawale i ka wehewehe ʻana o kēia ʻano ʻikepili i mau ʻāpana. Hiki iā ia ke hōʻike i ʻekolu ʻāpana ʻāpana (ptr
, len
и cap
) ma ke ʻano he ʻano (struct), akā ʻo ka hōʻike ʻana iā lākou ma ke ʻano he ʻekolu hui kaʻawale e hiki ai i kekahi mau koho. Hiki i nā mea hōʻuluʻulu ʻē aʻe ke hōʻike i ka ʻāpana ma nā ʻano ʻē aʻe, e hilinaʻi ana i nā kaʻina kelepona o nā hana o ka platform target.
ʻO kekahi hiʻohiʻona hoihoi o kēia code ka hoʻohana ʻana i ke aʻo getelementptr
(hoʻopau pinepine ʻia ʻo GEP).
Hana kēia ʻōlelo aʻo me nā kuhikuhi a hoʻohana ʻia no ka loaʻa ʻana o kahi kuhikuhi i kahi mea ʻāpana. No ka laʻana, e hoʻohālikelike kākou me kēia code i kākau ʻia ma C:
int* sliceptr(int *ptr, int index) {
return &ptr[index];
}
A i ʻole me kēia mea like me kēia:
int* sliceptr(int *ptr, int index) {
return ptr + index;
}
ʻO ka mea nui ma ʻaneʻi ʻo ia nā kuhikuhi getelementptr
ʻaʻole ia e hana i nā hana dereferencing. Heluhelu wale ʻo ia i kahi kuhikuhi hou e pili ana i ka mea i loaʻa. Hiki ke lawe ʻia ma ke ʻano he kuhikuhi mul
и add
ma ka pae lako. Hiki iā ʻoe ke heluhelu hou aku e pili ana i nā kuhikuhi GEP
ʻO kekahi hiʻohiʻona hoihoi o kēia code waena ka hoʻohana ʻana i ke aʻo icmp
. He aʻo kumu nui kēia i hoʻohana ʻia e hoʻokō i nā hoʻohālikelike integer. ʻO ka hopena o kēia aʻo ʻana he waiwai mau o ke ʻano i1
— waiwai kūpono. I kēia hihia, hoʻohālikelike ʻia me ka hoʻohana ʻana i ka huaʻōlelo slt
(kakau ʻia ma lalo o), ʻoiai ke hoʻohālikelike nei mākou i ʻelua mau helu i hōʻike mua ʻia e ke ʻano int
. Inā mākou e hoʻohālikelike i ʻelua mau helu helu ʻole, a laila e hoʻohana mākou icmp
, a ʻo ka huaʻōlelo i hoʻohana ʻia ma ka hoʻohālikelike ʻana ult
. No ka hoʻohālikelike ʻana i nā helu lana, hoʻohana ʻia kekahi ʻōlelo aʻo, fcmp
, e hana like ana.
Nā hopena
Ke manaʻoʻiʻo nei au i loko o kēia mea ua uhi au i nā hiʻohiʻona koʻikoʻi o LLVM IR. ʻOiaʻiʻo, nui nā mea hou aku ma ʻaneʻi. ʻO ka mea nui, hiki i ka hōʻike waena o ke code ke loaʻa i nā annotation he nui e hiki ai i ka optimization pass ke noʻonoʻo i kekahi mau hiʻohiʻona o ke code i ʻike ʻia e ka mea hōʻuluʻulu ʻaʻole hiki ke hōʻike ʻia ma IR. Eia kekahi laʻana, he hae kēia inbounds
Nā kuhikuhi GEP, a i ʻole nā hae nsw
и nuw
, hiki ke hoʻohui i nā kuhikuhi add
. Pela no ka huaolelo private
, e hōʻike ana i ka optimizer ʻaʻole e kuhikuhi ʻia ka hana āna i hōʻailona ai ma waho o ka pūʻulu hōʻuluʻulu o kēia manawa. Hāʻawi kēia i ka nui o nā loiloi interprocedural hoihoi e like me ka hoʻopau ʻana i nā hoʻopaʻapaʻa i hoʻohana ʻole ʻia.
Hiki iā ʻoe ke heluhelu hou aʻe e pili ana iā LLVM ma
E nā mea heluhelu aloha! Ke hoʻohana nei ʻoe iā LLVM?
Source: www.habr.com