LLVM Code Generation
Felix Dietze & Richard Musiol
2014-07-21
- allow questions
see handout
int add(intx , inty ) { returnx +y ; }
define i64 @add(i64%x , i64%y ) #0 {%x.addr = alloca i64, align 4%y.addr = alloca i64, align 4 store i64%x , i64*%x.addr , align 4 store i64%y , i64*%y.addr , align 4%0 = load i64*%x.addr , align 4%1 = load i64*%y.addr , align 4%add = add nsw i64%0 ,%1 ret i64%add }
define i64 @add(i64%x , i64%y ) #0 {%add = add nsw i64%y ,%x ret i64%add }
%vreg1 = COPY%RSI %vreg2 = COPY%RDI %vreg2 = ADD64rr%vreg2 ,%vreg1 %RAX = COPY%vreg2 RET%RAX
%vreg1 →%RSI %vreg2 →%RDI %RDI = ADD64rr%RDI ,%RSI %RAX = COPY%RDI RET%RAX
_add: addq%rsi ,%rdi movq%rdi ,%rax ret
long add(longx , longy ) { returnx +y + 42; }
_add: leaq 42(%rdi ,%rsi ),%rax ret
void test() { volatile intx ; volatile longy ; volatile longz ;x =42 ; // 32 bit ← 32 bity =42 ; // 64 bit ← 32 bitz =42000000000000 ; // 64 bit ← 64 bit }
MOV32mi<fi#0> , 1, %noreg, 0, %noreg,42 ; MOV64mi32<fi#1> , 1, %noreg, 0, %noreg,42 ; %vreg0 = MOV64ri42000000000000 ; MOV64mr<fi#2> , 1, %noreg, 0, %noreg, %vreg0; RET
MOV32m i <fi#0>, 1, %noreg, 0, %noreg, 42; MOV64m i 32 <fi#1>, 1, %noreg, 0, %noreg, 42; %vreg0 = MOV64r i 42000000000000; MOV64m r <fi#2>, 1, %noreg, 0, %noreg, %vreg0; RET
defMOV32mi : Ii32< 0xC7, MRM0m, (outs), (ins i32mem:$dst, i32imm:$src), "mov{l}\t{$src, $dst|$dst, $src}", [(store (i32 imm:$src), addr:$dst)], IIC_MOV_MEM >, OpSize32;
static const unsigned char MatcherTable[] = { OPC_SwitchOpcode, 40|128, 104, TARGET_VAL(ISD::STORE ), [...] OPC_SwitchType, 26, MVT::i64, [...] /*SwitchType*/ 24, MVT::i8, [...] /*SwitchType*/ 24, MVT::i16, [...] /*SwitchType*/ 24, MVT::i32 , OPC_MoveParent, OPC_RecordChild2, OPC_CheckPredicate, 4, [...] OPC_MorphNodeTo, TARGET_VAL(X86::MOV32mi ), [...]
void test(int* out, int* in, int* a0, int* a1, int* a2, int* a3, int* a4, int* a5, int* a6) { for(int i = 0; i < 10; i++) { int v0 = a0[i]; int v1 = a1[i]; int v2 = a2[i]; int v3 = a3[i]; int v4 = a4[i]; int v5 = a5[i]; // int v6 = a6[i];
int in0 = in[0]; int in1 = in[1]; int in2 = in[2]; int in3 = in[3]; int in4 = in[4]; int in5 = in[5]; // int in6 = in[6];
int sum = 0; sum += v0 * in0; sum += v1 * in1; sum += v2 * in2; sum += v3 * in3; sum += v4 * in4; sum += v5 * in5; // sum += v6 * in6; out[i] = sum; } }
movl (%rsi), %r14d movl 4(%rsi), %ebp movl 8(%rsi), %ebx movl 12(%rsi), %r15d movl 16(%rsi), %r12d movl 20(%rsi), %r13d imull (%rdx,%rax), %r14d imull (%rcx,%rax), %ebp addl %r14d, %ebp imull (%r8,%rax), %ebx addl %ebp, %ebx imull (%r9,%rax), %r15d addl %ebx, %r15d imull (%r11,%rax), %r12d addl %r15d, %r12d imull (%r10,%rax), %r13d addl %r12d, %r13d movl %r13d, (%rdi,%rax)
void test(int* out, int* in, int* a0, int* a1, int* a2, int* a3, int* a4, int* a5, int* a6) { for(int i = 0; i < 10; i++) { int v0 = a0[i]; int v1 = a1[i]; int v2 = a2[i]; int v3 = a3[i]; int v4 = a4[i]; int v5 = a5[i]; int v6 = a6[i];
int in0 = in[0]; int in1 = in[1]; int in2 = in[2]; int in3 = in[3]; int in4 = in[4]; int in5 = in[5]; int in6 = in[6];
int sum = 0; sum += v0 * in0; sum += v1 * in1; sum += v2 * in2; sum += v3 * in3; sum += v4 * in4; sum += v5 * in5; sum += v6 * in6; out[i] = sum; } }
movl (%rsi), %ebp movl 4(%rsi), %ebx imull (%rdx,%rax), %ebp imull (%rcx,%rax), %ebx addl %ebp, %ebxmovl 8(%rsi), %ebp imull (%r8,%rax), %ebp addl %ebx, %ebpmovl 12(%rsi), %ebx imull (%r9,%rax), %ebx addl %ebp, %ebxmovl 16(%rsi), %ebp imull (%r14,%rax), %ebp addl %ebx, %ebpmovl 20(%rsi), %ebx imull (%r11,%rax), %ebx addl %ebp, %ebxmovl 24(%rsi), %ebp imull (%r10,%rax), %ebp addl %ebx, %ebp movl %ebp, (%rdi,%rax)
Space | Forward |
---|---|
Left, Down, Page Down | Next slide |
Right, Up, Page Up | Previous slide |
P | Open presenter console |
H | Toggle this help |