ααΆααααααΎααααααα·ααΈα
αααααααΊααΆαα·α
αα
ααΆαααααααΆααα½αα ααα»ααααααΆααααΆαααα’ ααΆαα½αααΉαααΆαα’αα·ααααααααααααααΌα
ααΆ LLVM αααααααααΆαα
αααααααα αΆαααααΊααΆαααΆαααΆαααααααΆαααααΆαα αααα’αα»ααααΆαα±ααα’αααααααααααααα·ααΈαααα½αα’αΆα
αααααΎαααΆααΆααααΈααααα·αααααΎαααΆαααΆαα½α C. ααΆαααααΎααΆαααΆαα½α LLVM ααΆαααΆααααα»αααααΆααααααΆαααΆααα·ααααα ααααααααααααΌαααΆαααααΆααααα
ααα½αααα
αααΎααααααααΌα ααααΆαααααα―αααΆααα·α
αα½α
α ααΎααααΈααααΆααΆααααααααΌαα
ααα»α
ααααααΆαααα α’ααααα·αααααααααααΆαα αααααΆααΆααααααααααααΎααααα»αααααα»αααααααααα ααΉααααα αΆαα§ααΆα αααααααΌααααααααααα
αααα»α Go αα·ααααα αΆαααΈααααααααα½αααΆααααΌαααΆαααααααααΆααΎαααααΌααα
ααΆ
α§ααΆα αααααααΌα
αα»αααΆαααααΌαααααααα»αααΉαααΎααα ααΈααα ααΊααΆααααααΆαααΆαααααα½ααααααΆαααααααααααα
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 ααΊααααΆααααΆαααΌα Go SSA ααααα·α
ααααααααΉα C. αα
ααΈααα αα
αααα»αααΆααααααΆααα»αααΆα ααΆααααΌαααΆαααΆααα·αααααΆα’αααΈαααααααα·αααααααααααΆαααα‘αααααα·α ααααααα’αΆαα»αααααααααΌαααΆαα
ααα’α»ααααα αΆααα»ααααααα’αΆαα»αααααα ααΎαααΈαααααα ααΎααααΈααααα½αααΆαααα IR αααααααααα’αααααΆααααααααΌαααΆαααΆααα»αααααα·αα·ααααααααΆ @
α αΎααα
ααΈαα»αααααααααα»ααααα»α ααΆααα·αα·ααααααααΆαα½αα %
(αα»αααΆααα½αααααΌαααΆαα
αΆαααα»αααΆααΆα’αααααΆααααααααα)α
ααΏααα½ααααααααΌαααααααααΆααα’αααΈαααααΌααααααΊααΆααααααα
α
α·αααααααΆααααααα Go int
αααα’αΆα
ααααΌαααΆαααααΆαααΆααααα 32 αααΈα α¬ 64 αααΈα α’αΆαααααααΎα’αααα
ααααα αα·αααααα
ααααΆαα
αααααααααΌαααΆαααα½ααααα
αααααα LLVM αααααΎαααΌα IR α αααααΊααΆα ααα»αααα½ααααα»αα
ααααα ααα»ααααΆα
αααΎααααααΌα LLVM IR αα·αααΌα
αααααα»αααααΆα
αααΎααα·ααα αααα·ααΆα―αααΆαααα ααΌααααααααααααααΌαααΆααααααΎαα‘αΎααααααΆαααααα·ααΆαα½α αα·αα’αΆα
ααααΌαααΆααααα αα·αα
ααααααααααΆαααααα·ααΆαα½ααααααααααα (αα»αααααΆααα’ααααααααα·αααααααΆααααΆααααααααΆααααα αΆααα
α
ααα»α
αα½αα±ααα
αΆααα’αΆαααααααα½ααααααααα½αααααααααΆααααΊααΆαααααα i64
αα·ααααααΆα
ααα½αααααααααΆαα
α»αα αααααααΆααα ααΆα’ααααΆααααΉααααα»ααααααααΆαα±αααααααΆαααααα α’αΆαααααααΎααΆαααααΆα ααΆα’αΆα
ααααΆαα±ααααΆααααααααααΆαα
α»αα αααααααΆ αα·ααα·αααΆαα
α»αα αααααααΆα αααα»αααααΈααααΆαααααααα·ααααα·ααΆαααααααααααα·αααΆααααα αΆααααΌα
ααααααΆαα·αααΆαααΆααα»ααααααααααΆαααα»αααΆαααααΎααΆαααΆαα½αααααααααΆαα
α»αα αααααααΆα¬αα·αααΆαα
α»αα αααααααΆααα αα
ααΈααααααα»αα
ααααααααααΆααααΆαα
αααα»αααΆααΆ C ααΆαααΎαα’αααα
ααα½αααααααααΆαα
α»αα αααααααΆααΆααα
ααα’αΆαααααα·αα·ααΆααααα·αααΆαααααα ααΌα
αααα Clang frontend ααααααααααα
ααααα·ααααα·ααΆαα 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
. ααΆαααααΆαααΊαα·αααααααΆαα α αΎαα’αΆα
α
αααΆααααααααααΎααααΈαααα α
αα
αΆαβααΆ myAdd
ααΆααααα αΆαααΆαααΎ ααα»αααααα·ααααααα·αααααααΆαααα»αααΆααααα»αααααααΆαααΌα
ααΆαα»αααΆααααααΆααα·ααΆααααΆαα
αααα»αααααααααααα sum
. ααΆαα·ααα α’αααααααΆααααααΌαααα‘α»ααααααααα·ααααα·ααααααα·ααα»α i
ΠΈ n
.
SSA ααααααΆαααΉααααααΉαααΎααΆαααααααααααα’ααααααααααααααΎα’αααΈαααααα α
ααΆααΆαααααΆα phi
(αααααααααααΆααααΌαααΆαααα
ααααΈα’αααααααααααα·α) α ααΆααα·αααΊααΆααΎααααΈα±ααααααΆα SSA ααααΌαααααΌαααΆααααααΎααααααΆααααΆααΆααΌα
ααΆ C α’αααααααΌαααααΆααα
αααααα·α
αα½αα
ααα½αα ααααααααααΆαα α
ααΆαααααΆααααααΊααΆααααααα
αα
α»ααααααααα’ααα (i
α¬ n
) α αΎααααααΈαααααα»αααΌαααααΆαααααΌαααΆαααααΎααΆαααΆαααΆααααααααααααΆα ααΆα§ααΆα ααα ααΌααα·α
αΆαααΆααΆαααααΆααααα
t0 = phi [entry: 0:int, for.body: t6] #n
α’ααααααααααααΆααΆαααΌα
ααΆααααααα ααααα·αααΎαααα»αααΌαααααΆαααΈαα»αααΊααΆαααα»α entry
(αααα
αΌα) αααααΆαααα t0
ααΊβααΆβααα 0
α αΎαααααα·αααΎαααα»αααΌαααααΆαααΈαα»αααΊ for.body
αααααΆααααα’αααααααΌαααααααα t6
ααΈαααα»ααααα ααΆααα’αααααα αΆααααΌα
ααΆα’αΆααααααΆαα ααα»ααααααααααΆααααααΊααΆα’αααΈαααααααΎα±αα SSA ααααΎαααΆαα ααΆαααααααααααααα»ααα ααΆααα’αααααααααΎα±ααααΌααα·ααΆαααα ααα»ααααααΆααα·ααααααΆαααααααΈαα½ααααααΌαααΆαααααααααα½αααααααΎα±ααααΆααααααΎαααααα·αααααΆαααΆα
αααΎαααΆααααααΆααααα½αα
α
αααΆαααΆααααα·αααΎα’αααααααααααααα·ααΈα
αααααααααΆαααααα½αααααα’ααα ααΆααααααΆ α’αααααΉααα·αα
αΆαααΆα
ααααααααΆαααΆαα½αααΏααααααααααααα ααΌααααΈαα Clang αααα·ααααααΎαααΆαααααΆαααΆααα’ααααααααα phi
ααΆααααΎααααααΆααα½αα alloca
(ααΆαααα αΆαααααα ααααΉαααΆαααααΎααΆαααΆαα½αα’αααααΌαααααΆαααααααΆ)α αααααΆαααα αααααααΎαααΆα LLVM optimization pass α α
ααΆ alloca
ααΆαααααααααα
ααΆαααααα SSA α αααααΆαααΆαααΆααααα TinyGo ααα½αααΆααααα
αΌαααΈ Go SSA αααααΆααααα½αααααααααα
ααΆαααααα 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 ααααα?
ααααα: www.habr.com