Ịmepụta ihe nchịkọta bụ ọrụ siri ike. Ma, n'ụzọ dị mma, na mmepe nke ọrụ dị ka LLVM, ngwọta nke nsogbu a na-adị mfe nke ukwuu, nke na-enye ohere ọbụna otu mmemme ịmepụta asụsụ ọhụrụ nke dị nso na arụmọrụ na C. Ịrụ ọrụ na LLVM mgbagwoju anya site n'eziokwu na nke a bụ eziokwu. A na-anọchi anya sistemụ site na nnukwu koodu, nke nwere obere akwụkwọ. Iji gbalịa imezi adịghị ike a, onye dere akwụkwọ ahụ, nsụgharị nke anyị na-ebipụta taa, ga-egosipụta ihe atụ nke koodu edere na Go wee gosi ka e si sụgharịa ya na mbụ.
Ihe atụ mbụ
Ọrụ mbụ m ga-elele ebe a bụ usoro dị mfe maka ịgbakwunye ọnụọgụgụ:
func myAdd(a, b int) int{
return a + b
}
Ọrụ a dị nnọọ mfe, ma eleghị anya, ọ dịghị ihe nwere ike ịdị mfe karị. Ọ tụgharịrị n'ime koodu Go SSA a:
func myAdd(a int, b int) int:
entry:
t0 = a + b int
return t0
Site na echiche a, a na-edobe ihe nrịbama ụdị data n'aka nri ma enwere ike ileghara ya anya n'ọtụtụ ọnọdụ.
Obere ihe atụ a na-enye gị ohere ịhụ isi nke otu akụkụ nke SSA. Ya bụ, mgbe ị na-atụgharị koodu ka ọ bụrụ ụdị SSA, a na-agbaji okwu ọ bụla n'ime akụkụ mbụ nke ọ na-ede. N'ọnọdụ anyị, iwu ahụ return a + b
, n'ezie, na-anọchi anya arụmọrụ abụọ: ịgbakwunye ọnụọgụ abụọ na iweghachi nsonaazụ.
Na mgbakwunye, ebe a ị nwere ike ịhụ ihe mgbochi nke mmemme ahụ, na koodu a, e nwere naanị otu ngọngọ - ngọngọ ntinye. Anyị ga-ekwu maka ihe mgbochi n'okpuru.
Koodu Go SSA na-agbanwe ngwa ngwa na LLVM IR:
define i64 @myAdd(i64 %a, i64 %b) {
entry:
%0 = add i64 %a, %b
ret i64 %0
}
Ihe ị nwere ike ịhụ bụ na ọ bụ ezie na a na-eji usoro syntactic dị iche iche eme ihe ebe a, nhazi nke ọrụ ahụ adịghị agbanwe agbanwe. Koodu LLVM IR dị ntakịrị ike karịa koodu Go SSA, dị ka C. N'ebe a, na nkwupụta ọrụ, nke mbụ enwere nkọwa nke ụdị data ọ na-eweghachi, a na-egosipụta ụdị arụmụka tupu aha arụmụka ahụ. Na mgbakwunye, iji mee ka ntụgharị IR dị mfe, aha ụlọ ọrụ zuru ụwa ọnụ na-ebute akara ahụ @
, na n'ihu aha obodo enwere akara %
(a na-ewerekwa ọrụ dị ka ihe zuru ụwa ọnụ).
Otu ihe ị ga-amata gbasara koodu a bụ mkpebi nnochite anya ụdị Go int
, nke enwere ike ịnọchite anya dị ka uru 32-bit ma ọ bụ 64-bit, dabere na mkpokọta na ebumnuche nke mkpokọta, nabatara mgbe LLVM weputara koodu IR. Nke a bụ otu n'ime ọtụtụ ihe kpatara na koodu LLVM IR abụghị, dị ka ọtụtụ ndị mmadụ na-eche, n'elu ikpo okwu kwụụrụ onwe ya. Koodu dị otú ahụ, nke emepụtara maka otu ikpo okwu, enweghị ike iwere ma chịkọta ya maka ikpo okwu ọzọ (ọ gwụla ma ị dabara adaba maka idozi nsogbu a.
Ihe ọzọ na-adọrọ mmasị kwesịrị ịmara bụ ụdị ahụ i64
abụghị integer bịanyere aka n'akwụkwọ: ọ na-anọpụ iche na-anọchi anya akara nke ọnụọgụgụ. Dabere na ntuziaka a, ọ nwere ike ịnọchite anya ma ọnụọgụ ndị mbinye aka na nke etinyeghị aka. N'ihe nnọchiteanya nke ọrụ mgbakwunye, nke a adịghị mkpa, n'ihi ya, ọ dịghị ihe dị iche na-arụ ọrụ na nọmba mbinye aka ma ọ bụ na-edeghị aha. N'ebe a, ọ ga-amasị m ịmara na n'asụsụ C, njupụta ọnụọgụ ọnụọgụ ọnụọgụ na-eduga n'omume a na-akọwapụtaghị, ya mere Clang frontend na-agbakwụnye ọkọlọtọ na ọrụ ahụ. nsw
(enweghị ihe mkpuchi bịanyere aka na ya), nke na-agwa LLVM na ọ nwere ike iche na mgbakwunye anaghị ejupụta.
Nke a nwere ike ịdị mkpa maka ụfọdụ njikarịcha. Dịka ọmụmaatụ, ịgbakwunye ụkpụrụ abụọ i16
n'elu ikpo okwu 32-bit (ya na ndekọ 32-bit) chọrọ, ka agbakwunyere, ọrụ mgbasawanye akara iji nọgide na nso. i16
. N'ihi nke a, ọ na-adịkarị mma ịrụ ọrụ integer dabere na nha ndekọ igwe.
Ihe na-esote na koodu IR a abụghị ihe masịrị anyị ugbu a. A na-emezi koodu ahụ (mana n'ihe banyere ihe atụ dị mfe dị ka nke anyị, ọ dịghị ihe na-eme ka ọ dịkwuo mma) wee gbanwee ghọọ koodu igwe.
Ihe atụ nke abụọ
Ihe atụ na-esote anyị ga-ele anya ga-adị ntakịrị mgbagwoju anya. Ya bụ, anyị na-ekwu maka otu ọrụ na-achịkọta iberi nke integers:
func sum(numbers []int) int {
n := 0
for i := 0; i < len(numbers); i++ {
n += numbers[i]
}
return n
}
Koodu a na-atụgharị gaa na koodu Go SSA a:
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
N'ebe a, ị nwere ike hụlarị ihe owuwu ndị ọzọ maka ịnọchite anya koodu n'ụdị SSA. Ikekwe akụkụ kacha pụta ìhè nke koodu a bụ eziokwu ahụ bụ na ọ nweghị iwu njikwa mgbaba ahaziri ahazi. Iji chịkwaa usoro nke ịgbakọ, enwere naanị ọnọdụ na enweghị ọnọdụ jumps, na, ọ bụrụ na anyị atụle iwu a dị ka iwu iji chịkwaa ọsọ ahụ, iwu nlọghachi.
N'ezie, ebe a ị nwere ike ịṅa ntị n'eziokwu ahụ bụ na anaghị ekewa mmemme ahụ na ngọngọ na-eji ihe nkwado (dị ka ezinụlọ C nke asụsụ). A na-ekewa ya site na akara, na-echetara asụsụ mgbakọ, ma gosipụta ya n'ụdị ngọngọ. Na SSA, a kọwapụtara ngọngọ ndị bụ isi dị ka usoro koodu na-aga n'ihu na-amalite site na akara wee mechie na ntuziaka mmecha ngọngọ, dịka - return
и jump
.
Nkọwa ọzọ na-adọrọ mmasị nke koodu a na-anọchi anya ntụziaka ahụ phi
. Ntuziaka ndị a na-adịghị ahụkebe ma nwee ike iwepụta oge ịghọta. cheta, na myAdd
egosiri n'elu, ma ọ dịghị adabara maka ọrụ mgbagwoju anya dị ka ọrụ a tụlere na ngalaba a sum
. Karịsịa, mgbanwe mgbanwe na-agbanwe n'oge egbu nke loop i
и n
.
SSA na-agafe mmachi na ikenye ụkpụrụ mgbanwe otu ugboro na-eji ihe a na-akpọ ntụziaka phi
(a na-ewepụta aha ya na mkpụrụedemede Greek). Nke bụ eziokwu bụ na ka e wee mepụta koodu SSA maka asụsụ dị ka C, ị ga-emerịrị aghụghọ ụfọdụ. Nsonaazụ nke ịkpọ ntụziaka a bụ uru nke mgbanwe ugbu a (i
ma ọ bụ n
), na a na-eji ndepụta nke ihe mgbochi eme ihe dị ka paramita ya. Dịka ọmụmaatụ, tụlee ntụziaka a:
t0 = phi [entry: 0:int, for.body: t6] #n
Ihe ọ pụtara bụ nke a: ọ bụrụ na ngọngọ ntọala gara aga bụ ngọngọ entry
(ntinye), mgbe ahụ t0
bụ ihe na-adịgide adịgide 0
, ma ọ bụrụ na ngọngọ ntọala gara aga bụ for.body
, mgbe ahụ ịkwesịrị iburu uru ahụ t6
site na ngọngọ a. Nke a nwere ike iyi ihe omimi, mana usoro a bụ ihe na-eme ka SSA rụọ ọrụ. Site n'echiche mmadụ, ihe a niile na-eme ka koodu ahụ sie ike nghọta, ma eziokwu ahụ bụ na e kenyere uru ọ bụla naanị otu ugboro na-eme ka ọtụtụ njikarịcha dị mfe.
Rịba ama na ọ bụrụ na ị na-ede ihe nchịkọta nke gị, ị gaghị enwe ike ime ụdị ihe a. Ọbụna Clang anaghị ewepụta ntuziaka ndị a niile phi
, ọ na-eji usoro alloca
(ọ yiri ịrụ ọrụ na mgbanwe mpaghara nkịtị). Mgbe ahụ, mgbe ị na-agba ọsọ ngafe njikarịcha LLVM akpọrọ alloca
tụgharịrị gaa na ụdị SSA. TinyGo, agbanyeghị, na-enweta ntinye sitere na Go SSA, nke, n'ụzọ dabara adaba, agbanweelarị na ụdị SSA.
Ihe ọhụrụ ọzọ nke iberibe koodu etiti a na-atụle bụ na ohere ịnweta ihe mpempe akwụkwọ site na ndeksi na-anọchi anya ya n'ụdị ọrụ nke ịgbakọ adreesị yana ọrụ nke iwepụ ihe nrịbama na-esi na ya pụta. N'ebe a, ị nwere ike ịhụ ntinye aka ozugbo na koodu IR (dịka ọmụmaatụ - 1:int
). Na ihe atụ na ọrụ myAdd
e jibeghị nke a. Ugbu a anyị enwetala atụmatụ ndị ahụ, ka anyị lelee ihe koodu a na-aghọ mgbe a gbanwere na ụdị 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
}
N'ebe a, dị ka ọ dị na mbụ, anyị nwere ike ịhụ otu nhazi ahụ, nke gụnyere ihe ndị ọzọ syntactic. Dịka ọmụmaatụ, na oku phi
ụkpụrụ na akara aha gbanwere. Otú ọ dị, e nwere ihe ebe a kwesịrị ịṅa ntị pụrụ iche.
Iji malite, ebe a ị nwere ike ịhụ mbinye aka ọrụ dị iche kpamkpam. LLVM anaghị akwado iberi, na n'ihi ya, dị ka njikarịcha, TinyGo compiler nke mepụtara koodu etiti a kewara nkọwa nke usoro data a n'ime akụkụ. Ọ nwere ike ịnọchite anya ihe iberibe atọ (ptr
, len
и cap
) dị ka nhazi (nhazi), ma na-anọchi anya ha dị ka ụlọ ọrụ atọ dị iche iche na-enye ohere maka ụfọdụ njikarịcha. Ndị na-achịkọta ndị ọzọ nwere ike ịnọchite anya iberi ahụ n'ụzọ ndị ọzọ, dabere na nkwekọ ịkpọ oku nke ọrụ ikpo okwu ebumnuche.
Akụkụ ọzọ na-adọrọ mmasị nke koodu a bụ iji ntụziaka ahụ getelementptr
(nke a na-akpọkarị GEP).
Ntuziaka a na-arụ ọrụ na ntụnye aka ma jiri ya nweta ihe nrịbama na mmewere iberi. Dịka ọmụmaatụ, ka anyị jiri ya tụnyere koodu a edere na C:
int* sliceptr(int *ptr, int index) {
return &ptr[index];
}
Ma ọ bụ ya na ihe ndị a dabara na nke a:
int* sliceptr(int *ptr, int index) {
return ptr + index;
}
Ihe kacha mkpa ebe a bụ na ntuziaka getelementptr
anaghị arụ ọrụ nkwụsịtụ. Ọ na-agbakọ akara ọhụrụ dabere na nke dị adị. Enwere ike iwere ya dị ka ntuziaka mul
и add
na ngwaike larịị. Ị nwere ike ịgụkwu gbasara ntuziaka GEP
Akụkụ ọzọ na-adọrọ mmasị nke koodu etiti a bụ iji ntụziaka ahụ icmp
. Nke a bụ nkuzi ebumnuche izugbe ejiri mejuputa ntụnyere intiger. Nsonaazụ nke ntụziaka a bụ mgbe niile uru nke ụdị i1
- ezi uche uru. N'okwu a, a na-eji isi okwu eme ntụnyere slt
(binyere aka na-erughị), ebe anyị na-atụnyere ọnụọgụ abụọ nke ụdị ahụ nọchiri anya mbụ int
. Ọ bụrụ na anyị na-atụnyere integer abụọ na-enweghị nkwekọrịta, mgbe ahụ anyị ga-eji icmp
, na isiokwu ejiri mee ihe na ntụnyere ga-abụ ult
. Iji tụnyere ọnụ ọgụgụ ndị na-ese n'elu mmiri, a na-eji ntụziaka ọzọ. fcmp
, nke na-arụ ọrụ n'otu ụzọ ahụ.
Nsonaazụ
Ekwenyere m na n'ime ihe a, ekpuchiwo m atụmatụ kachasị mkpa nke LLVM IR. N'ezie, e nwere ọtụtụ ihe ọzọ ebe a. Karịsịa, nnochite anya etiti nke koodu ahụ nwere ike ịnwe ọtụtụ nkọwa nke na-enye ohere ịgafe njikarịcha na-eburu n'uche ụfọdụ atụmatụ nke koodu ahụ mara onye nchịkọta nke na-enweghị ike ịkọwa na IR. Dịka ọmụmaatụ, nke a bụ ọkọlọtọ inbounds
Ntuziaka GEP, ma ọ bụ ọkọlọtọ nsw
и nuw
, nke enwere ike ịgbakwunye na ntuziaka add
. Otu na-aga maka isiokwu private
, na-egosi njikarịcha na ọrụ ọ na-akara agaghị ezo aka na mpụga ngalaba mkpokọta ugbu a. Nke a na-enye ohere maka ọtụtụ njikarịcha interprocedural na-adọrọ mmasị dị ka iwepụ arụmụka na-ejighị ya.
Ị nwere ike ịgụ ihe gbasara LLVM n'ime
Ezigbo ndị na-agụ akwụkwọ! Ị na-eji LLVM?
isi: www.habr.com