LLVM si n'echiche Go

Ị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ụ. Gaa SSA, wee banye na LLVM IR site na iji mkpokọta obereGO. E deziela obere koodu Go SSA na LLVM IR iji wepụ ihe ndị na-adabaghị na nkọwa ndị e nyere ebe a, iji mee ka nkọwa ahụ ghọtakwuo.

LLVM si n'echiche Go

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. na oke nlekọta).

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 S.S.A. dị mkpụmkpụ maka Static Single Assignment. Nke a bụ ihe nnọchianya nke etiti nke koodu nke ndị nchịkọta na-eji, nke a na-ekenye mgbanwe ọ bụla uru naanị otu ugboro. Nke a dị mma maka igosipụta ọrụ dị mfe dị ka ọrụ anyị myAddegosiri 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ọ mem2reg, ntuziaka 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 ebe a.

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 akwụkwọ, nke ị ga-ezo aka mgbe mgbe mgbe ị na-emepụta ihe nchịkọta LLVM nke gị. Ebe a njikwa, nke na-ele anya ịmepụta ihe nchịkọta maka asụsụ dị mfe. Ebe ozi abụọ a ga-abara gị uru mgbe ị na-eke mkpokọta nke gị.

Ezigbo ndị na-agụ akwụkwọ! Ị na-eji LLVM?

LLVM si n'echiche Go

isi: www.habr.com

Tinye a comment