Go ๊ด€์ ์—์„œ ๋ณธ LLVM

์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ๊ฐœ๋ฐœํ•˜๋Š” ๊ฒƒ์€ ๋งค์šฐ ์–ด๋ ค์šด ์ž‘์—…์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‹คํ–‰์Šค๋Ÿฝ๊ฒŒ๋„ LLVM๊ณผ ๊ฐ™์€ ํ”„๋กœ์ ํŠธ์˜ ๊ฐœ๋ฐœ๋กœ ์ด ๋ฌธ์ œ์— ๋Œ€ํ•œ ํ•ด๊ฒฐ์ฑ…์ด ํฌ๊ฒŒ ๋‹จ์ˆœํ™”๋˜์–ด ๋‹จ์ผ ํ”„๋กœ๊ทธ๋ž˜๋จธ๋ผ๋„ ์„ฑ๋Šฅ์ด C์— ๊ฐ€๊นŒ์šด ์ƒˆ๋กœ์šด ์–ธ์–ด๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‹œ์Šคํ…œ์€ ๋ฌธ์„œ๊ฐ€ ๊ฑฐ์˜ ์—†๋Š” ์—„์ฒญ๋‚œ ์–‘์˜ ์ฝ”๋“œ๋กœ ํ‘œํ˜„๋ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋‹จ์ ์„ ๋ฐ”๋กœ์žก๊ธฐ ์œ„ํ•ด ์˜ค๋Š˜ ์šฐ๋ฆฌ๊ฐ€ ๋ฒˆ์—ญํ•œ ์ž๋ฃŒ์˜ ์ €์ž๋Š” Go๋กœ ์ž‘์„ฑ๋œ ์ฝ”๋“œ์˜ ์˜ˆ๋ฅผ ๋ณด์—ฌ์ฃผ๊ณ  ์ด๊ฒƒ์ด ์ฒ˜์Œ์œผ๋กœ ์–ด๋–ป๊ฒŒ ๋ฒˆ์—ญ๋˜๋Š”์ง€ ๋ณด์—ฌ์ค„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. SSA๋กœ ์ด๋™, ๊ทธ๋ฆฌ๊ณ  ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ LLVM IR์—์„œ ํƒ€์ด๋‹ˆ๊ณ . Go SSA ๋ฐ LLVM IR ์ฝ”๋“œ๋Š” ์„ค๋ช…์„ ๋” ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๊ฒŒ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ์—ฌ๊ธฐ์— ์ œ๊ณต๋œ ์„ค๋ช…๊ณผ ๊ด€๋ จ์ด ์—†๋Š” ํ•ญ๋ชฉ์„ ์ œ๊ฑฐํ•˜๋„๋ก ์•ฝ๊ฐ„ ํŽธ์ง‘๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

Go ๊ด€์ ์—์„œ ๋ณธ LLVM

์ฒซ ๋ฒˆ์งธ ์˜ˆ

์—ฌ๊ธฐ์„œ ์‚ดํŽด๋ณผ ์ฒซ ๋ฒˆ์งธ ํ•จ์ˆ˜๋Š” ์ˆซ์ž๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฐ„๋‹จํ•œ ๋ฉ”์ปค๋‹ˆ์ฆ˜์ž…๋‹ˆ๋‹ค.

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

์ด ๊ธฐ๋Šฅ์€ ๋งค์šฐ ๊ฐ„๋‹จํ•˜๋ฉฐ ์•„๋งˆ๋„ ์ด๋ณด๋‹ค ๋” ๊ฐ„๋‹จํ•œ ๊ฒƒ์€ ์—†์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋Š” ๋‹ค์Œ Go SSA ์ฝ”๋“œ๋กœ ๋ณ€ํ™˜๋ฉ๋‹ˆ๋‹ค.

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

์ด ๋ณด๊ธฐ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฐ์ดํ„ฐ ์œ ํ˜• ํžŒํŠธ๊ฐ€ ์˜ค๋ฅธ์ชฝ์— ๋ฐฐ์น˜๋˜๋ฉฐ ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ๋ฌด์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ์ž‘์€ ์˜ˆ๋ฅผ ํ†ตํ•ด ์ด๋ฏธ SSA์˜ ํ•œ ์ธก๋ฉด์˜ ๋ณธ์งˆ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰, ์ฝ”๋“œ๋ฅผ SSA ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜ํ•  ๋•Œ ๊ฐ ํ‘œํ˜„์‹์€ ๊ตฌ์„ฑ๋˜๋Š” ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ๋ถ€๋ถ„์œผ๋กœ ๊ตฌ๋ถ„๋ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ์˜ ๊ฒฝ์šฐ ๋ช…๋ น์€ return a + b๋Š” ์‹ค์ œ๋กœ ๋‘ ๊ฐœ์˜ ์ˆซ์ž๋ฅผ ๋”ํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋‘ ๊ฐ€์ง€ ์ž‘์—…์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

๋˜ํ•œ ์—ฌ๊ธฐ์„œ๋Š” ํ”„๋กœ๊ทธ๋žจ์˜ ๊ธฐ๋ณธ ๋ธ”๋ก์„ ๋ณผ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด ์ฝ”๋“œ์—๋Š” ์ž…๋ ฅ ๋ธ”๋ก์ด๋ผ๋Š” ๋‹จ ํ•˜๋‚˜์˜ ๋ธ”๋ก๋งŒ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜์—์„œ ๋ธ”๋ก์— ๋Œ€ํ•ด ๋” ์ž์„ธํžˆ ์ด์•ผ๊ธฐํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

Go SSA ์ฝ”๋“œ๋Š” LLVM IR๋กœ ์‰ฝ๊ฒŒ ๋ณ€ํ™˜๋ฉ๋‹ˆ๋‹ค.

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

์—ฌ๊ธฐ์„œ ์•Œ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์€ ๋‹ค์–‘ํ•œ ๊ตฌ๋ฌธ ๊ตฌ์กฐ๊ฐ€ ์‚ฌ์šฉ๋˜๋”๋ผ๋„ ํ•จ์ˆ˜์˜ ๊ตฌ์กฐ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. LLVM IR ์ฝ”๋“œ๋Š” C์™€ ์œ ์‚ฌํ•˜๊ฒŒ Go SSA ์ฝ”๋“œ๋ณด๋‹ค ์•ฝ๊ฐ„ ๋” ๊ฐ•๋ ฅํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ํ•จ์ˆ˜ ์„ ์–ธ์—๋Š” ๋จผ์ € ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฐ์ดํ„ฐ ์œ ํ˜•์— ๋Œ€ํ•œ ์„ค๋ช…์ด ์žˆ์œผ๋ฉฐ ์ธ์ˆ˜ ์œ ํ˜•์€ ์ธ์ˆ˜ ์ด๋ฆ„ ์•ž์— ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ IR ๊ตฌ๋ฌธ ๋ถ„์„์„ ๋‹จ์ˆœํ™”ํ•˜๊ธฐ ์œ„ํ•ด ์ „์—ญ ์—”ํ„ฐํ‹ฐ ์ด๋ฆ„ ์•ž์— ๊ธฐํ˜ธ๊ฐ€ ๋ถ™์Šต๋‹ˆ๋‹ค. @, ์ง€์—ญ ์ด๋ฆ„ ์•ž์— ๊ธฐํ˜ธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค % (ํ•จ์ˆ˜๋Š” ์ „์—ญ ์—”ํ„ฐํ‹ฐ๋กœ๋„ ๊ฐ„์ฃผ๋ฉ๋‹ˆ๋‹ค).

์ด ์ฝ”๋“œ์—์„œ ์ฃผ๋ชฉํ•ด์•ผ ํ•  ์ ์€ Go์˜ ์œ ํ˜• ํ‘œํ˜„ ๊ฒฐ์ •์ด int์ปดํŒŒ์ผ๋Ÿฌ์™€ ์ปดํŒŒ์ผ ๋Œ€์ƒ์— ๋”ฐ๋ผ 32๋น„ํŠธ ๋˜๋Š” 64๋น„ํŠธ ๊ฐ’์œผ๋กœ ํ‘œ์‹œ๋  ์ˆ˜ ์žˆ๋Š” ๋Š” LLVM์ด IR ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ํ—ˆ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด ์ƒ๊ฐํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ LLVM IR ์ฝ”๋“œ๊ฐ€ ํ”Œ๋žซํผ ๋…๋ฆฝ์ ์ด์ง€ ์•Š์€ ๋งŽ์€ ์ด์œ  ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค. ํ•œ ํ”Œ๋žซํผ์šฉ์œผ๋กœ ์ƒ์„ฑ๋œ ์ด๋Ÿฌํ•œ ์ฝ”๋“œ๋Š” ๋‹ค๋ฅธ ํ”Œ๋žซํผ์šฉ์œผ๋กœ ๊ฐ„๋‹จํžˆ ๊ฐ€์ ธ์™€์„œ ์ปดํŒŒ์ผํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค(์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐ ์ ํ•ฉํ•˜์ง€ ์•Š์€ ํ•œ). ๊ทน๋„์˜ ์ฃผ์˜๋ฅผ ๊ธฐ์šธ์—ฌ).

์ฃผ๋ชฉํ• ๋งŒํ•œ ๋˜ ๋‹ค๋ฅธ ํฅ๋ฏธ๋กœ์šด ์ ์€ ์œ ํ˜•์ด i64 ๋ถ€ํ˜ธ ์žˆ๋Š” ์ •์ˆ˜๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. ์ˆซ์ž์˜ ๋ถ€ํ˜ธ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์ธก๋ฉด์—์„œ ์ค‘๋ฆฝ์ ์ž…๋‹ˆ๋‹ค. ๋ช…๋ น์–ด์— ๋”ฐ๋ผ ๋ถ€ํ˜ธ ์žˆ๋Š” ์ˆซ์ž์™€ ๋ถ€ํ˜ธ ์—†๋Š” ์ˆซ์ž๋ฅผ ๋ชจ๋‘ ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ง์…ˆ ์—ฐ์‚ฐ์˜ ํ‘œํ˜„์˜ ๊ฒฝ์šฐ์—๋Š” ์ด๊ฒƒ์ด ์ค‘์š”ํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ๋ถ€ํ˜ธ ์žˆ๋Š” ์ˆซ์ž๋‚˜ ๋ถ€ํ˜ธ ์—†๋Š” ์ˆซ์ž๋กœ ์ž‘์—…ํ•˜๋Š”๋ฐ ์ฐจ์ด๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” C ์–ธ์–ด์—์„œ ๋ถ€ํ˜ธ ์žˆ๋Š” ์ •์ˆ˜ ๋ณ€์ˆ˜๋ฅผ ์˜ค๋ฒ„ํ”Œ๋กœํ•˜๋ฉด ์ •์˜๋˜์ง€ ์•Š์€ ๋™์ž‘์ด ๋ฐœ์ƒํ•˜๋ฏ€๋กœ Clang ํ”„๋ŸฐํŠธ์—”๋“œ๊ฐ€ ์ž‘์—…์— ํ”Œ๋ž˜๊ทธ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค๋Š” ์ ์— ์ฃผ๋ชฉํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. nsw (์„œ๋ช…๋œ ๋žฉ ์—†์Œ) ์ด๋Š” ์ถ”๊ฐ€๊ฐ€ ์˜ค๋ฒ„ํ”Œ๋กœ๋˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ๊ฐ€์ •ํ•  ์ˆ˜ ์žˆ์Œ์„ LLVM์— ์•Œ๋ ค์ค๋‹ˆ๋‹ค.

์ด๋Š” ์ผ๋ถ€ ์ตœ์ ํ™”์— ์ค‘์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋‘ ๊ฐœ์˜ ๊ฐ’์„ ์ถ”๊ฐ€ํ•˜๋ฉด i16 32๋น„ํŠธ ํ”Œ๋žซํผ(32๋น„ํŠธ ๋ ˆ์ง€์Šคํ„ฐ ์‚ฌ์šฉ)์—์„œ๋Š” ์ถ”๊ฐ€ ํ›„ ๋ฒ”์œ„ ๋‚ด์— ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๋ถ€ํ˜ธ ํ™•์žฅ ์ž‘์—…์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. i16. ์ด ๋•Œ๋ฌธ์— ๊ธฐ๊ณ„ ๋ ˆ์ง€์Šคํ„ฐ ํฌ๊ธฐ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ •์ˆ˜ ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์ด ๋” ํšจ์œจ์ ์ธ ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค.

์ด IR ์ฝ”๋“œ๋กœ ๋‹ค์Œ์— ๋ฌด์Šจ ์ผ์ด ์ผ์–ด๋‚ ์ง€๋Š” ํ˜„์žฌ ์šฐ๋ฆฌ์—๊ฒŒ ํŠน๋ณ„ํ•œ ๊ด€์‹ฌ์ด ์•„๋‹™๋‹ˆ๋‹ค. ์ฝ”๋“œ๋Š” ์ตœ์ ํ™”๋œ ๋‹ค์Œ(๊ทธ๋Ÿฌ๋‚˜ ์šฐ๋ฆฌ์™€ ๊ฐ™์€ ๊ฐ„๋‹จํ•œ ์˜ˆ์ œ์˜ ๊ฒฝ์šฐ ์•„๋ฌด๊ฒƒ๋„ ์ตœ์ ํ™”๋˜์ง€ ์•Š์Œ) ๊ธฐ๊ณ„์–ด ์ฝ”๋“œ๋กœ ๋ณ€ํ™˜๋ฉ๋‹ˆ๋‹ค.

๋‘ ๋ฒˆ์งธ ์˜ˆ

์šฐ๋ฆฌ๊ฐ€ ์‚ดํŽด๋ณผ ๋‹ค์Œ ์˜ˆ๋Š” ์ข€ ๋” ๋ณต์žกํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ฆ‰, ์šฐ๋ฆฌ๋Š” ์ •์ˆ˜ ์กฐ๊ฐ์„ ํ•ฉํ•˜๋Š” ํ•จ์ˆ˜์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

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

์ด ์ฝ”๋“œ๋Š” ๋‹ค์Œ 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

์—ฌ๊ธฐ์„œ๋Š” SSA ํ˜•์‹์œผ๋กœ ์ฝ”๋“œ๋ฅผ ํ‘œํ˜„ํ•˜๋Š” ์ผ๋ฐ˜์ ์ธ ๊ตฌ์„ฑ์„ ๋” ๋งŽ์ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋งˆ๋„ ์ด ์ฝ”๋“œ์˜ ๊ฐ€์žฅ ๋ถ„๋ช…ํ•œ ํŠน์ง•์€ ๊ตฌ์กฐํ™”๋œ ํ๋ฆ„ ์ œ์–ด ๋ช…๋ น์ด ์—†๋‹ค๋Š” ์‚ฌ์‹ค์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ณ„์‚ฐ์˜ ํ๋ฆ„์„ ์ œ์–ดํ•˜๋ ค๋ฉด ์กฐ๊ฑด๋ถ€ ์ ํ”„์™€ ๋ฌด์กฐ๊ฑด ์ ํ”„๋งŒ ์žˆ๊ณ , ์ด ๋ช…๋ น์„ ํ๋ฆ„ ์ œ์–ด ๋ช…๋ น์œผ๋กœ ๊ฐ„์ฃผํ•˜๋ฉด ๋ฐ˜ํ™˜ ๋ช…๋ น์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์‹ค์ œ๋กœ ์—ฌ๊ธฐ์„œ๋Š” ํ”„๋กœ๊ทธ๋žจ์ด ์ค‘๊ด„ํ˜ธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ธ”๋ก์œผ๋กœ ๊ตฌ๋ถ„๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์‚ฌ์‹ค์— ์ฃผ๋ชฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(C ์–ธ์–ด ๊ณ„์—ด์—์„œ์™€ ๊ฐ™์ด). ์–ด์…ˆ๋ธ”๋ฆฌ ์–ธ์–ด๋ฅผ ์—ฐ์ƒ์‹œํ‚ค๋Š” ๋ผ๋ฒจ๋ณ„๋กœ ๋‚˜๋ˆ„์–ด ๊ธฐ๋ณธ ๋ธ”๋ก ํ˜•ํƒœ๋กœ ํ‘œํ˜„๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. SSA์—์„œ ๊ธฐ๋ณธ ๋ธ”๋ก์€ ๋ ˆ์ด๋ธ”๋กœ ์‹œ์ž‘ํ•˜๊ณ  ๊ธฐ๋ณธ ๋ธ”๋ก ์™„์„ฑ ๋ช…๋ น์œผ๋กœ ๋๋‚˜๋Š” ์—ฐ์†์ ์ธ ์ฝ”๋“œ ์‹œํ€€์Šค๋กœ ์ •์˜๋ฉ๋‹ˆ๋‹ค. return ะธ jump.

์ด ์ฝ”๋“œ์˜ ๋˜ ๋‹ค๋ฅธ ํฅ๋ฏธ๋กœ์šด ์„ธ๋ถ€ ์‚ฌํ•ญ์€ ๋‹ค์Œ ๋ช…๋ น์–ด๋กœ ํ‘œํ˜„๋ฉ๋‹ˆ๋‹ค. phi. ์ง€์นจ์€ ๋งค์šฐ ํŠน์ดํ•˜๋ฉฐ ์ดํ•ดํ•˜๋Š” ๋ฐ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ์–ต SSA ์ •์  ๋‹จ์ผ ํ• ๋‹น์˜ ์•ฝ์ž์ž…๋‹ˆ๋‹ค. ์ด๋Š” ๊ฐ ๋ณ€์ˆ˜์— ํ•œ ๋ฒˆ๋งŒ ๊ฐ’์ด ํ• ๋‹น๋˜๋Š” ์ปดํŒŒ์ผ๋Ÿฌ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ์ฝ”๋“œ์˜ ์ค‘๊ฐ„ ํ‘œํ˜„์ž…๋‹ˆ๋‹ค. ์ด๋Š” ์šฐ๋ฆฌ ํ•จ์ˆ˜์™€ ๊ฐ™์€ ๊ฐ„๋‹จํ•œ ํ•จ์ˆ˜๋ฅผ ํ‘œํ˜„ํ•˜๋Š” ๋ฐ ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค. myAdd์œ„์— ๋‚˜์™€ ์žˆ์ง€๋งŒ ์ด ์„น์…˜์—์„œ ์„ค๋ช…ํ•˜๋Š” ํ•จ์ˆ˜์™€ ๊ฐ™์€ ๋” ๋ณต์žกํ•œ ํ•จ์ˆ˜์—๋Š” ์ ํ•ฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. sum. ํŠนํžˆ ๋ฃจํ”„ ์‹คํ–‰ ์ค‘์— ๋ณ€์ˆ˜๊ฐ€ ๋ณ€๊ฒฝ๋ฉ๋‹ˆ๋‹ค. i ะธ n.

SSA๋Š” ์†Œ์œ„ ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ณ€์ˆ˜ ๊ฐ’์„ ํ•œ ๋ฒˆ ํ• ๋‹นํ•˜๋Š” ์ œํ•œ์„ ์šฐํšŒํ•ฉ๋‹ˆ๋‹ค. phi (๊ทธ ์ด๋ฆ„์€ ๊ทธ๋ฆฌ์Šค ์•ŒํŒŒ๋ฒณ์—์„œ ๋”ฐ์™”์Šต๋‹ˆ๋‹ค). ์‚ฌ์‹ค C์™€ ๊ฐ™์€ ์–ธ์–ด์— ๋Œ€ํ•ด SSA ์ฝ”๋“œ ํ‘œํ˜„์„ ์ƒ์„ฑํ•˜๋ ค๋ฉด ๋ช‡ ๊ฐ€์ง€ ํŠธ๋ฆญ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ช…๋ น์–ด๋ฅผ ํ˜ธ์ถœํ•œ ๊ฒฐ๊ณผ๋Š” ๋ณ€์ˆ˜์˜ ํ˜„์žฌ ๊ฐ’(i ๋˜๋Š” n), ๊ธฐ๋ณธ ๋ธ”๋ก์˜ ๋ชฉ๋ก์ด ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ ์ง€์นจ์„ ๊ณ ๋ คํ•ด๋ณด์„ธ์š”.

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

๊ทธ ์˜๋ฏธ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ด์ „ ๊ธฐ๋ณธ ๋ธ”๋ก์ด ๋ธ”๋ก์ด์—ˆ๋˜ ๊ฒฝ์šฐ entry (์ž…๋ ฅ), ๊ทธ๋Ÿฐ ๋‹ค์Œ t0 ์ƒ์ˆ˜์ด๋‹ค 0, ๊ทธ๋ฆฌ๊ณ  ์ด์ „ ๊ธฐ๋ณธ ๋ธ”๋ก์ด for.body, ๊ทธ๋Ÿฐ ๋‹ค์Œ ๊ฐ’์„ ๊ฐ€์ ธ์™€์•ผ ํ•ฉ๋‹ˆ๋‹ค. t6 ์ด ๋ธ”๋ก์—์„œ. ์ด ๋ชจ๋“  ๊ฒƒ์ด ๋งค์šฐ ์‹ ๋น„์Šค๋Ÿฌ์›Œ ๋ณด์ผ ์ˆ˜ ์žˆ์ง€๋งŒ ์ด ๋ฉ”์ปค๋‹ˆ์ฆ˜์ด SSA๋ฅผ ์ž‘๋™ํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ธ๊ฐ„์˜ ๊ด€์ ์—์„œ ๋ณด๋ฉด ์ด ๋ชจ๋“  ๊ฒƒ์ด ์ฝ”๋“œ๋ฅผ ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ต๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ฐ ๊ฐ’์ด ํ•œ ๋ฒˆ๋งŒ ํ• ๋‹น๋œ๋‹ค๋Š” ์‚ฌ์‹ค์€ ๋งŽ์€ ์ตœ์ ํ™”๋ฅผ ํ›จ์”ฌ ์‰ฝ๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

์ž์‹ ๋งŒ์˜ ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ์ผ๋ฐ˜์ ์œผ๋กœ ์ด๋Ÿฐ ์ข…๋ฅ˜์˜ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. Clang์กฐ์ฐจ๋„ ์ด๋Ÿฌํ•œ ๋ช…๋ น์–ด๋ฅผ ๋ชจ๋‘ ์ƒ์„ฑํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. phi, ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค alloca (์ผ๋ฐ˜์ ์ธ ์ง€์—ญ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๊ณผ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค). ๊ทธ๋Ÿฐ ๋‹ค์Œ LLVM ์ตœ์ ํ™” ํŒจ์Šค๋ฅผ ์‹คํ–‰ํ•  ๋•Œ mem2reg, ์ง€์นจ alloca SSA ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ TinyGo๋Š” ํŽธ๋ฆฌํ•˜๊ฒŒ๋„ ์ด๋ฏธ SSA ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜๋œ Go SSA๋กœ๋ถ€ํ„ฐ ์ž…๋ ฅ์„ ๋ฐ›์Šต๋‹ˆ๋‹ค.

๊ณ ๋ ค ์ค‘์ธ ์ค‘๊ฐ„ ์ฝ”๋“œ ์กฐ๊ฐ์˜ ๋˜ ๋‹ค๋ฅธ ํ˜์‹ ์€ ์ธ๋ฑ์Šค์— ์˜ํ•œ ์Šฌ๋ผ์ด์Šค ์š”์†Œ์— ๋Œ€ํ•œ ์•ก์„ธ์Šค๊ฐ€ ์ฃผ์†Œ๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” ์ž‘์—…๊ณผ ๊ฒฐ๊ณผ ํฌ์ธํ„ฐ๋ฅผ ์—ญ์ฐธ์กฐํ•˜๋Š” ์ž‘์—…์˜ ํ˜•ํƒœ๋กœ ํ‘œํ˜„๋œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” IR ์ฝ”๋“œ์— ์ƒ์ˆ˜๊ฐ€ ์ง์ ‘ ์ถ”๊ฐ€๋˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์˜ˆ: - 1:int). ํ•จ์ˆ˜๊ฐ€ ํฌํ•จ๋œ ์˜ˆ์—์„œ myAdd ์ด๊ฒƒ์€ ์‚ฌ์šฉ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์ด์ œ ์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ฑฐํ–ˆ์œผ๋ฏ€๋กœ ์ด ์ฝ”๋“œ๊ฐ€ 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
}

์—ฌ๊ธฐ์„œ๋Š” ์ด์ „๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋‹ค๋ฅธ ๊ตฌ๋ฌธ ๊ตฌ์กฐ๋ฅผ ํฌํ•จํ•˜๋Š” ๋™์ผํ•œ ๊ตฌ์กฐ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ํ†ตํ™” ์ค‘ phi ๊ฐ’๊ณผ ๋ผ๋ฒจ์ด ๋ฐ”๋€Œ์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์—ฌ๊ธฐ์„œ ํŠน๋ณ„ํžˆ ์ฃผ๋ชฉํ•ด์•ผ ํ•  ์ ์ด ์žˆ๋‹ค.

์šฐ์„  ์—ฌ๊ธฐ์—์„œ ์™„์ „ํžˆ ๋‹ค๋ฅธ ๊ธฐ๋Šฅ ์„œ๋ช…์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. LLVM์€ ์Šฌ๋ผ์ด์Šค๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š์œผ๋ฉฐ ๊ฒฐ๊ณผ์ ์œผ๋กœ ์ตœ์ ํ™”๋ฅผ ์œ„ํ•ด ์ด ์ค‘๊ฐ„ ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•œ TinyGo ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์ด ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ์— ๋Œ€ํ•œ ์„ค๋ช…์„ ์—ฌ๋Ÿฌ ๋ถ€๋ถ„์œผ๋กœ ๋ถ„ํ• ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์„ธ ๊ฐœ์˜ ์Šฌ๋ผ์ด์Šค ์š”์†Œ๋ฅผ ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(ptr, len ะธ cap)๋ฅผ ๊ตฌ์กฐ(struct)๋กœ ๋‚˜ํƒ€๋‚ด์ง€๋งŒ ์ด๋ฅผ ์„ธ ๊ฐœ์˜ ๋ณ„๋„ ์—”ํ„ฐํ‹ฐ๋กœ ํ‘œ์‹œํ•˜๋ฉด ์ผ๋ถ€ ์ตœ์ ํ™”๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๋Œ€์ƒ ํ”Œ๋žซํผ ํ•จ์ˆ˜์˜ ํ˜ธ์ถœ ๊ทœ์น™์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ๋ฐฉ์‹์œผ๋กœ ์Šฌ๋ผ์ด์Šค๋ฅผ ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ์ฝ”๋“œ์˜ ๋˜ ๋‹ค๋ฅธ ํฅ๋ฏธ๋กœ์šด ํŠน์ง•์€ ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. getelementptr (ํ”ํžˆ GEP๋กœ ์•ฝ์นญํ•จ)

์ด ๋ช…๋ น์–ด๋Š” ํฌ์ธํ„ฐ์™€ ํ•จ๊ป˜ ์ž‘๋™ํ•˜๋ฉฐ ์Šฌ๋ผ์ด์Šค ์š”์†Œ์— ๋Œ€ํ•œ ํฌ์ธํ„ฐ๋ฅผ ์–ป๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด C๋กœ ์ž‘์„ฑ๋œ ๋‹ค์Œ ์ฝ”๋“œ์™€ ๋น„๊ตํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

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

๋˜๋Š” ๋‹ค์Œ๊ณผ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.

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

์—ฌ๊ธฐ์„œ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ฒƒ์€ ์ง€์นจ์ž…๋‹ˆ๋‹ค. getelementptr ์—ญ์ฐธ์กฐ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‹จ์ง€ ๊ธฐ์กด ํฌ์ธํ„ฐ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ƒˆ ํฌ์ธํ„ฐ๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค. ์ง€์นจ์œผ๋กœ ๋ฐ›์•„ ๋“ค์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. mul ะธ add ํ•˜๋“œ์›จ์–ด ์ˆ˜์ค€์—์„œ. GEP ์ง€์นจ์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์•Œ์•„๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—.

์ด ์ค‘๊ฐ„ ์ฝ”๋“œ์˜ ๋˜ ๋‹ค๋ฅธ ํฅ๋ฏธ๋กœ์šด ํŠน์ง•์€ ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. icmp. ์ด๋Š” ์ •์ˆ˜ ๋น„๊ต๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ๋ฒ”์šฉ ๋ช…๋ น์–ด์ž…๋‹ˆ๋‹ค. ์ด ๋ช…๋ น์–ด์˜ ๊ฒฐ๊ณผ๋Š” ํ•ญ์ƒ ์œ ํ˜•์˜ ๊ฐ’์ž…๋‹ˆ๋‹ค. i1 โ€” ๋…ผ๋ฆฌ๊ฐ’. ์ด ๊ฒฝ์šฐ ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋น„๊ต๊ฐ€ ์ด๋ฃจ์–ด์ง‘๋‹ˆ๋‹ค. slt (๋ณด๋‹ค ์ž‘๊ฒŒ ๋ถ€ํ˜ธ ์žˆ์Œ), ์ด์ „์— ์œ ํ˜•์œผ๋กœ ํ‘œ์‹œ๋˜์—ˆ๋˜ ๋‘ ์ˆซ์ž๋ฅผ ๋น„๊ตํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. int. ๋‘ ๊ฐœ์˜ ๋ถ€ํ˜ธ ์—†๋Š” ์ •์ˆ˜๋ฅผ ๋น„๊ตํ•˜๋Š” ๊ฒฝ์šฐ ๋‹ค์Œ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. icmp, ๋น„๊ต์— ์‚ฌ์šฉ๋œ ํ‚ค์›Œ๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ult. ๋ถ€๋™ ์†Œ์ˆ˜์  ์ˆซ์ž๋ฅผ ๋น„๊ตํ•˜๋ ค๋ฉด ๋‹ค๋ฅธ ๋ช…๋ น์–ด๊ฐ€ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. fcmp, ๋น„์Šทํ•œ ๋ฐฉ์‹์œผ๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

๊ฒฐ๊ณผ

๋‚˜๋Š” ์ด ์ž๋ฃŒ์—์„œ LLVM IR์˜ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ธฐ๋Šฅ์„ ๋‹ค๋ฃจ์—ˆ๋‹ค๊ณ  ๋ฏฟ์Šต๋‹ˆ๋‹ค. ๋ฌผ๋ก  ์—ฌ๊ธฐ์—๋Š” ๋” ๋งŽ์€ ๊ฒƒ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ํŠนํžˆ, ์ฝ”๋“œ์˜ ์ค‘๊ฐ„ ํ‘œํ˜„์—๋Š” IR์—์„œ ๋‹ฌ๋ฆฌ ํ‘œํ˜„ํ•  ์ˆ˜ ์—†๋Š” ์ปดํŒŒ์ผ๋Ÿฌ์— ์•Œ๋ ค์ง„ ์ฝ”๋“œ์˜ ํŠน์ • ๊ธฐ๋Šฅ์„ ๊ณ ๋ คํ•˜๊ธฐ ์œ„ํ•œ ์ตœ์ ํ™” ํŒจ์Šค๋ฅผ ํ—ˆ์šฉํ•˜๋Š” ๋งŽ์€ ์ฃผ์„์ด ํฌํ•จ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์ด๊ฒƒ์€ ํ”Œ๋ž˜๊ทธ์ž…๋‹ˆ๋‹ค. inbounds GEP ๋ช…๋ น ๋˜๋Š” ํ”Œ๋ž˜๊ทธ nsw ะธ nuw, ์ง€์นจ์— ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Œ add. ํ‚ค์›Œ๋“œ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€ private, ํ‘œ์‹œํ•˜๋Š” ํ•จ์ˆ˜๊ฐ€ ํ˜„์žฌ ์ปดํŒŒ์ผ ๋‹จ์œ„ ์™ธ๋ถ€์—์„œ ์ฐธ์กฐ๋˜์ง€ ์•Š์Œ์„ ์ตœ์ ํ™” ํ”„๋กœ๊ทธ๋žจ์— ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ์ธ์ˆ˜ ์ œ๊ฑฐ์™€ ๊ฐ™์€ ํฅ๋ฏธ๋กœ์šด ํ”„๋กœ์‹œ์ € ๊ฐ„ ์ตœ์ ํ™”๊ฐ€ ๊ฐ€๋Šฅํ•ด์ง‘๋‹ˆ๋‹ค.

LLVM์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋‹ค์Œ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์„ ์  ์„œ๋ฅ˜ ๋น„์น˜, ์ž์ฒด LLVM ๊ธฐ๋ฐ˜ ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ๊ฐœ๋ฐœํ•  ๋•Œ ์ž์ฃผ ์ฐธ์กฐํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ ์ง€๋„๋ ฅ, ๋งค์šฐ ๊ฐ„๋‹จํ•œ ์–ธ์–ด์šฉ ์ปดํŒŒ์ผ๋Ÿฌ ๊ฐœ๋ฐœ์„ ์‚ดํŽด๋ด…๋‹ˆ๋‹ค. ์ด ๋‘ ๊ฐ€์ง€ ์ •๋ณด ์†Œ์Šค๋Š” ์ž์‹ ๋งŒ์˜ ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ๋งŒ๋“ค ๋•Œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

๋…์ž ์—ฌ๋Ÿฌ๋ถ„! LLVM์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‚˜์š”?

Go ๊ด€์ ์—์„œ ๋ณธ LLVM

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€