I-LLVM ngokwembono yeGo

Ukuphuhlisa umqokeleli ngumsebenzi onzima kakhulu. Kodwa, ngethamsanqa, ngophuhliso lweeprojekthi ezifana ne-LLVM, isisombululo sale ngxaki senziwe lula kakhulu, esivumela ukuba nomdwelisi omnye ukuba enze ulwimi olutsha olusondeleyo ekusebenzeni kwi-C. Ukusebenza ne-LLVM kuyinkimbinkimbi yinto yokuba oku inkqubo imelwe sisixa esikhulu sekhowudi, exhotyiswe ngamaxwebhu amancinane . Ukuze uzame ukulungisa le ntsilelo, umbhali wezinto eziphathekayo, inguqulelo esiyipapashayo namhlanje, uya kubonisa imizekelo yekhowudi ebhalwe kwi-Go kwaye ibonise indlela eguqulelwe ngayo kuqala Yiya kwi-SSA, kwaye emva koko kwi-LLVM IR usebenzisa umqokeleli I-TinyGO. Ikhowudi ye-Go SSA kunye ne-LLVM IR ihlelwe kancinane ukuze isuse izinto ezingahambelaniyo neengcaciso ezinikeziweyo apha, ukwenzela ukuba iinkcazo ziqondeke ngakumbi.

I-LLVM ngokwembono yeGo

Umzekelo wokuqala

Umsebenzi wokuqala endiza kuwujonga apha yindlela elula yokongeza amanani:

func myAdd(a, b int) int{
    return a + b
}

Lo msebenzi ulula kakhulu, kwaye, mhlawumbi, akukho nto inokuba lula. Iguqulela kule khowudi ilandelayo yeGo SSA:

func myAdd(a int, b int) int:
entry:
    t0 = a + b                                                    int
    return t0

Ngalo mbono, iingcebiso zodidi lwedatha zibekwe ekunene kwaye zinokuhoywa kwiimeko ezininzi.

Lo mzekelo mncinane sele ukuvumela ukuba ubone undoqo wenkalo enye ye-SSA. Okukuthi, xa uguqulela ikhowudi kwifomu ye-SSA, intetho nganye yahlulahlulwe yaya kutsho kwezona ndawo zisisiseko apho iqulunqwe khona. Kwimeko yethu, umyalelo return a + b, eneneni, imele imisebenzi emibini: ukudibanisa amanani amabini kunye nokubuyisela isiphumo.

Ukongeza, apha ungabona iibhloko ezisisiseko zenkqubo; kule khowudi kukho ibhloko enye kuphela - ibhloko yokungena. Siza kuthetha ngakumbi malunga neebhloko ngezantsi.

Ikhowudi ye-Go SSA iguqulela ngokulula kwi-LLVM IR:

define i64 @myAdd(i64 %a, i64 %b) {
entry:
  %0 = add i64 %a, %b
  ret i64 %0
}

Into onokuthi uyiqaphele kukuba nangona izakhiwo ezahlukeneyo zesyntactic zisetyenziswa apha, ulwakhiwo lomsebenzi alutshintshanga. Ikhowudi ye-LLVM IR inamandla kancinane kunekhowudi ye-Go SSA, efana ne-C. Apha, kwisibhengezo somsebenzi, okokuqala kukho inkcazo yohlobo lwedatha olubuyiselayo, uhlobo lwengxabano lubonakaliswe phambi kwegama lengxabano. Ukongeza, ukwenza lula ukwahlulahlula kwe-IR, amagama amaqumrhu ehlabathi andulelwa sisimboli @, kwaye phambi kwamagama asekuhlaleni kukho uphawu % (umsebenzi ukwathathwa njengequmrhu lehlabathi).

Into enye ekufuneka uyiqaphele malunga nale khowudi kukuba isigqibo sokumelwa kohlobo lweGo int, enokumelwa njengexabiso le-32-bit okanye i-64-bit, ngokuxhomekeke kumqokeleli kunye nethagethi yokuhlanganiswa, yamkelwe xa i-LLVM ivelisa ikhowudi ye-IR. Esi sesinye sezizathu ezininzi zokuba ikhowudi ye-LLVM IR ayikho, njengoko abantu abaninzi becinga, iqonga elizimeleyo. Ikhowudi enjalo, eyenzelwe iqonga elinye, ayinakuthatyathwa kwaye iqulunqelwe elinye iqonga (ngaphandle kokuba ukulungele ukusombulula le ngxaki. ngenkathalo egqithisileyo).

Enye inqaku elinomdla elifanele liphawulwe kukuba uhlobo i64 Asiyonani elipheleleyo esayiniweyo: ayithathi cala ngokumela uphawu lwenani. Ngokuxhomekeke kumyalelo, inokumela zombini amanani asayiniweyo kunye namanani angabhalwanga. Kwimeko yokumelwa komsebenzi wokongezwa, oku akunamsebenzi, ngoko akukho mahluko ekusebenzeni ngamanani asayiniweyo okanye angasayinwanga. Apha ndingathanda ukuqaphela ukuba kulwimi lwe-C, ukuphuphuma kwenani elipheleleyo elisayiniweyo likhokelela kwindlela yokuziphatha engachazwanga, ngoko i-frontend ye-Clang yongeza iflegi kumsebenzi. nsw (akukho zisongelo esayiniweyo), exelela i-LLVM ukuba inokucinga ukuba ukongeza akusayi kuphuphuma.

Oku kunokubaluleka kwezinye izilungiso. Umzekelo, ukongeza amaxabiso amabini i16 kwiplatifti ye-32-bit (enerejista ye-32-bit) ifuna, emva kokongezwa, umsebenzi wokwandisa uphawu ukuze uhlale kuluhlu. i16. Ngenxa yoku, kudla ngokusebenza ngakumbi ukwenza imisebenzi epheleleyo ngokusekwe kubungakanani berejista yomatshini.

Yintoni eyenzekayo ngokulandelayo ngale khowudi ye-IR ayinamdla ukhethekileyo kuthi ngoku. Ikhowudi iphuculwe (kodwa kwimeko yomzekelo olula njengowethu, akukho nto iphuculweyo) kwaye iguqulelwe kwikhowudi yomatshini.

Umzekelo wesibini

Umzekelo olandelayo esiza kujonga kuwo uya kuba nzima ngakumbi. Oko kukuthi, sithetha ngomsebenzi oshwankathela isilayi samanani apheleleyo:

func sum(numbers []int) int {
    n := 0
    for i := 0; i < len(numbers); i++ {
        n += numbers[i]
    }
    return n
}

Le khowudi iguqulela kule khowudi ilandelayo yeGo 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

Apha unokubona ezinye izakhiwo eziqhelekileyo zokumela ikhowudi kwifom ye-SSA. Mhlawumbi eyona nto icacileyo yale khowudi yinto yokuba akukho miyalelo yolawulo lokuqukuqela ecwangcisiweyo. Ukulawula ukuhamba kwezibalo, kukho ukutsiba okunemiqathango kunye nokungenamiqathango, kwaye, ukuba siqwalasela lo myalelo njengomyalelo wokulawula ukuhamba, umyalelo wokubuyisela.

Enyanisweni, apha unokunikela ingqalelo kwinto yokuba inkqubo ayihlulwanga ibe ziibhloko usebenzisa iibrayisi ezigobileyo (njengakwintsapho yeelwimi C). Yahlulwe ngeeleyibhile, ikhumbuza iilwimi zendibano, kwaye inikezelwe ngendlela yeebhloko ezisisiseko. Kwi-SSA, iibhloko ezisisiseko zichazwa njengolandelelwano oludityanisiweyo lwekhowudi eqala ngeleyibhile kwaye iphele ngemiyalelo esisiseko yokugqibezela ibhloko, efana βˆ’ return ΠΈ jump.

Enye ingcaciso enomdla yale khowudi imelwe ngumyalelo phi. Imiyalelo ayiqhelekanga kwaye inokuthatha ixesha ukuyiqonda. khumbula, ukuba S.S.A. imfutshane kwiSabelo esiSingle esiSingle. Oku kubonakaliswa okuphakathi kwekhowudi esetyenziswe ngabaqulunqi, apho inguqu nganye inikwe ixabiso kanye kuphela. Oku kuhle kakhulu ekuboniseni imisebenzi elula efana nomsebenzi wethu myAddeboniswe ngasentla, kodwa ayilungelanga imisebenzi entsonkothileyo njengomsebenzi oxoxwe kweli candelo sum. Ngokukodwa, iinguqu zitshintsha ngexesha lokwenziwa kwe-loop i ΠΈ n.

I-SSA idlula umda wokwabela amaxabiso aguquguqukayo kube kanye usebenzisa into ebizwa ngokuba ngumyalelo phi (igama layo lithatyathwe kwialfabhethi yesiGrike). Inyani kukuba ukuze ukumelwa kwekhowudi ye-SSA kuveliswe kwiilwimi ezinje ngeC, kuya kufuneka ubhenele kumaqhinga athile. Isiphumo sokubiza lo myalelo lixabiso langoku loguqulo (i okanye n), kwaye uluhlu lweebhloko ezisisiseko zisetyenziswa njenge parameters zayo. Ngokomzekelo, qwalasela lo myalelo:

t0 = phi [entry: 0:int, for.body: t6] #n

Intsingiselo yalo ilandelayo: ukuba ibhloko yangaphambili esisiseko yayiyibhloko entry (igalelo), ngoko t0 yinto engatshintshiyo 0, kwaye ukuba ibhloko esisiseko yangaphambili yayi for.body, ngoko kufuneka uthathe ixabiso t6 ukusuka kule block. Konke oku kunokubonakala kungaqondakali, kodwa lo matshini yeyona nto yenza ukuba i-SSA isebenze. Ngokwembono yomntu, konke oku kwenza ukuba ikhowudi ibe nzima ukuyiqonda, kodwa into yokuba ixabiso ngalinye linikezelwe kube kanye kuphela kwenza ukuba uninzi lwazo lube lula kakhulu.

Qaphela ukuba ubhala eyakho i compiler, awuzukufuneka ujongane nolu hlobo lwezinto. Nditsho noClang akavelisi yonke le miyalelo phi, isebenzisa isixhobo alloca (ifana nokusebenza ngeenguqu eziqhelekileyo zendawo). Emva koko, xa uqhuba i-LLVM yokuphumelela ipasi ebizwa um2reg, imiyalelo alloca iguqulelwe kwifomu ye-SSA. I-TinyGo, nangona kunjalo, ifumana igalelo kwi-Go SSA, ethi, ngokulula, sele iguqulelwe kwifom ye-SSA.

Olunye uhlaziyo lweqhekeza lekhowudi ephakathi phantsi kwengqwalasela kukuba ukufikelela kwizinto eziqhekezayo ngesalathiso kubonakaliswe ngendlela yokusebenza kokubala idilesi kunye nokusebenza kokurhoxisa isalathisi esisiphumo. Apha ungabona ukongezwa ngokuthe ngqo kwezigxininisi kwikhowudi ye-IR (umzekelo - 1:int). Kumzekelo kunye nomsebenzi myAdd oku akuzange kusetyenziswe. Ngoku sele sizifumene ezo mpawu endleleni, makhe sijonge ukuba le khowudi iba yintoni xa iguqulelwa kwifom ye-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
}

Apha, njengangaphambili, sinokubona isakhiwo esifanayo, esibandakanya ezinye izakhiwo ze-syntactic. Umzekelo, kwiifowuni phi amaxabiso kunye neelebhile zitshintshiwe. Nangona kunjalo, kukho into apha efanelwe ingqalelo ekhethekileyo.

Ukuqala, apha unokubona utyikityo lomsebenzi owahluke ngokupheleleyo. I-LLVM ayixhasi izilayi, kwaye ngenxa yoko, njenge-optimization, i-TinyGo compiler evelise le khowudi ephakathi yahlula inkcazo yesi sakhiwo sedatha kwiinxalenye. Inokumela izinto ezintathu zesilayi (ptr, len ΠΈ cap) njengesakhiwo (isakhiwo), kodwa ukubamela njengamaqumrhu amathathu ahlukeneyo kuvumela ulungiselelo oluthile. Abanye abaqulunqi banokumela isilayi ngezinye iindlela, ngokuxhomekeke kwiindibano zokubiza imisebenzi yeqonga ekujoliswe kulo.

Enye into enomdla kule khowudi kukusetyenziswa komyalelo getelementptr (idla ngokufinyezwa njenge-GEP).

Lo myalelo usebenza ngezalathisi kwaye usetyenziselwa ukufumana isalathi sento yesilayi. Umzekelo, masiyithelekise nale khowudi ilandelayo ebhalwe ku-C:

int* sliceptr(int *ptr, int index) {
    return &ptr[index];
}

Okanye ngokuhambelana noku kulandelayo:

int* sliceptr(int *ptr, int index) {
    return ptr + index;
}

Eyona nto ibalulekileyo apha kukuba imiyalelo getelementptr ayiwenzi imisebenzi yokurhoxisa. Ibala nje isalathisi esitsha ngokusekwe kwesi sikhoyo. Inokuthathwa njengemiyalelo mul ΠΈ add kwinqanaba le-hardware. Unokufunda ngakumbi malunga nemiyalelo ye-GEP apha.

Enye into enomdla kule khowudi ephakathi kukusetyenziswa komyalelo icmp. Lo ngumyalelo wenjongo jikelele osetyenziswayo ukuphumeza uthelekiso olupheleleyo. Isiphumo sokuphumeza lo myalelo sihlala sixabiso lohlobo i1 - ixabiso elisengqiqweni. Kule meko, uthelekiso lwenziwa kusetyenziswa igama elingundoqo slt (isayinwe ngaphantsi kwe), njengoko sithelekisa amanani amabini amelwe ngaphambili luhlobo int. Ukuba besithelekisa amanani amabini angasayinwanga, besiya kusebenzisa icmp, kwaye igama elingundoqo elisetyenziswe kuthelekiso liya kuba ult. Ukuthelekisa amanani amanqaku adadayo, kusetyenziswa omnye umyalelo, fcmp, esebenza ngendlela efanayo.

Iziphumo

Ndiyakholelwa ukuba kulo mbandela ndigubungele ezona mpawu zibalulekileyo ze-LLVM IR. Ewe, kukho okuninzi ngakumbi apha. Ngokukodwa, ukumelwa okuphakathi kwekhowudi kunokuquka izichasiselo ezininzi ezivumela ukugqithiswa kokulungelelaniswa ukuba kuthathelwe ingqalelo iimpawu ezithile zekhowudi ezaziwa ngumqambi ongenakuchazwa ngenye indlela kwi-IR. Umzekelo, le flegi inbounds Imiyalelo ye-GEP, okanye iiflegi nsw ΠΈ nuw, enokongezwa kwimiyalelo add. Kukwanjalo nakwigama elingundoqo private, ebonisa isilungisi ukuba umsebenzi esiwuphawulayo awusayi kubhekiselwa ngaphandle kweyunithi yoqulunqo lwangoku. Oku kuvumela uninzi lwezinto ezinomdla zokusebenzisa iinkqubo ezihambelanayo ezifana nokuphelisa iimpikiswano ezingasetyenziswanga.

Unokufunda ngakumbi malunga ne-LLVM kwi amaxwebhu, oya kubhekisa kulo rhoqo xa uphuhlisa eyakho i-LLVM-based compiler. Apha ulawulo, ejonga ekuphuhliseni umqokeleli wolwimi olulula kakhulu. Yomibini le mithombo yolwazi iya kuba luncedo kuwe xa usenza owakho umqokeleli.

Bafundi abathandekayo! Ngaba usebenzisa i-LLVM?

I-LLVM ngokwembono yeGo

umthombo: www.habr.com

Yongeza izimvo