haskell symposium 2010: an llvm backend for ghc

24
AN LLVM BACKEND FOR GHC David Terei & Manuel Chakravarty University of New South Wales Haskell Symposium 2010 Baltimore, USA, 30 th Sep

Upload: dterei

Post on 11-May-2015

917 views

Category:

Technology


1 download

DESCRIPTION

Slides from talk at Haskell Symposium 2010, on an LLVM backend for GHC.

TRANSCRIPT

Page 1: Haskell Symposium 2010: An LLVM backend for GHC

AN LLVM BACKEND

FOR GHC

David Terei & Manuel Chakravarty

University of New South Wales

Haskell Symposium 2010

Baltimore, USA, 30th Sep

Page 2: Haskell Symposium 2010: An LLVM backend for GHC

What is ‘An LLVM Backend’?

• Low Level Virtual Machine

• Backend Compiler framework

• Designed to be used by compiler developers, not

by software developers

• Open Source

• Heavily sponsored by Apple

Page 3: Haskell Symposium 2010: An LLVM backend for GHC

Motivation

• Simplify

• Reduce ongoing work

• Outsource!

• Performance

• Improve run-time

Page 4: Haskell Symposium 2010: An LLVM backend for GHC

Example

0

200

400

600

800

1000

1200

1400

1600

1800

2000

LLVM C NCG

Run-time (ms) collat :: Int -> Word32 -> Int

collat c 1 = c

collat c n | even n =

collat (c+1) $ n `div` 2

| otherwise =

collat (c+1) $ 3 * n + 1

pmax x n = x `max` (collat 1 n, n)

main = print $ foldl pmax (1,1)

[2..1000000]

Different, updated run-times compared to paper

Page 5: Haskell Symposium 2010: An LLVM backend for GHC

Competitors

C Backend (C)

• GNU C Dependency

• Badly supported on

platforms such as Windows

• Use a Mangler on

assembly code

• Slow compilation speed

• Takes twice as long as the

NCG

Native Code Generator (NCG)

• Huge amount of work

• Very limited portability

• Does very little

optimisation work

Page 6: Haskell Symposium 2010: An LLVM backend for GHC

GHC’s Compilation Pipeline

Core STG Cmm

C

NCG

LLVM Language, Abstract Machine, Machine Configuration

Heap, Stack, Registers

Page 7: Haskell Symposium 2010: An LLVM backend for GHC

Compiling to LLVM

Won’t be covering, see paper for full details:

• Why from Cmm and not from STG/Core

• LLVM, C-- & Cmm languages

• Dealing with LLVM’s SSA form

• LLVM type system

Will be covering:

• Handling the STG Registers

• Handling GHC’s Table-Next-To-Code optimisation

Page 8: Haskell Symposium 2010: An LLVM backend for GHC

Handling the STG Registers STG Register X86 Register

Base ebx

Heap Pointer edi

Stack Pointer ebp

R1 esi

Implement either by:

• In memory

• Pin to hardware registers

NCG?

• Register allocator permanently stores STG registers in

hardware

C Backend?

• Uses GNU C extension (global register variables) to

also permanently store STG registers in hardware

Page 9: Haskell Symposium 2010: An LLVM backend for GHC

Handling the STG Registers

STG Register X86 Register

Base ebx

Heap Pointer edi

Stack Pointer ebp

R1 esi

define f ghc_cc (Base, Hp, Sp, R1) {

tail call g ghc_cc (Base, Hp’, Sp’, R1’);

return void;

}

LLVM handles by implementing a new calling convention:

Page 10: Haskell Symposium 2010: An LLVM backend for GHC

Handling the STG Registers

• Issue: If implemented naively then all the STG registers

have a live range of the entire function.

• Some of the STG registers can never be scratched (e.g

Sp, Hp…) but many can (e.g R2, R3…).

• We need to somehow tell LLVM when we no longer care

about an STG register, otherwise it will spill and reload the

register across calls to C land for example.

Page 11: Haskell Symposium 2010: An LLVM backend for GHC

Handling the STG Registers • We handle this by storing undef into the STG register

when it is no longer needed. We manually scratch them.

define f ghc_cc (Base, Hp, Sp, R1, R2, R3, R4) {

store undef %R2

store undef %R3

store undef %R4

call c_cc sin(double %f22);

tail call ghc_cc g(Base,Hp’,Sp’,R1’,R2’,R3’,R4’);

return void;

}

Page 12: Haskell Symposium 2010: An LLVM backend for GHC

Handling Tables-Next-To-Code

Un-optimised Layout Optimised Layout

How to implement in LLVM?

Page 13: Haskell Symposium 2010: An LLVM backend for GHC

Handling Tables-Next-To-Code Use GNU Assembler sub-section feature.

• Allows code/data to be put into numbered sub-section

• Sub-sections are appended together in order

• Table in <n>, entry code in <n+1>

.text 12 sJ8_info: movl ... movl ... jmp ... [...] .text 11 sJ8_info_itable: .long ... .long 0 .long 327712

Page 14: Haskell Symposium 2010: An LLVM backend for GHC

Handling Tables-Next-To-Code

LLVM Mangler

• 180 lines of Haskell (half

is documentation)

• Needed only for OS X

C Mangler

• 2,000 lines of Perl

• Needed for every platform

Page 15: Haskell Symposium 2010: An LLVM backend for GHC

Evaluation: Simplicity

0

5000

10000

15000

20000

25000

LLVM C NCG

Code Size LLVM

• Half of code is representation of

LLVM language

C

• Compiler: 1,100 lines

• C Headers: 2,000 lines

• Perl Mangler: 2,000 lines

NCG

• Shared component: 8,000 lines

• Platform specific: 4,000 – 5,000

for X86, SPARC, PowerPC

Page 16: Haskell Symposium 2010: An LLVM backend for GHC

Evaluation: Performance

Nofib:

• Egalitarian benchmark

suite, everything is equal

• Memory bound, little

room for optimisation

once at Cmm stage

-0.5

0

0.5

1

1.5

2

2.5

3

NCG C

Run-time against LLVM (%)

Page 17: Haskell Symposium 2010: An LLVM backend for GHC

Repa Performance

0

2

4

6

8

10

12

14

16

Matrix Mult Laplace FFT

runtimes (s)

LLVM

NCG

Page 18: Haskell Symposium 2010: An LLVM backend for GHC

Compile Times, Object Sizes

-80

-60

-40

-20

0

20

40

60

NCG C

Compile Times Vs LLVM

-14

-12

-10

-8

-6

-4

-2

0

NCG C

Object Sizes Vs LLVM

Page 19: Haskell Symposium 2010: An LLVM backend for GHC

Result

• LLVM Backend is simpler.

• LLVM Backend is as fast or faster.

• LLVM developers now work for GHC!

Page 20: Haskell Symposium 2010: An LLVM backend for GHC

Get It

• LLVM

• Our calling convention has been accepted upstream!

• Included in LLVM since version 2.7

http://llvm.org

• GHC

• In HEAD

• Should be released in GHC 7.0

• Send me any programs that are slower!

Page 21: Haskell Symposium 2010: An LLVM backend for GHC

Questions?

Page 22: Haskell Symposium 2010: An LLVM backend for GHC

Why from Cmm?

A lot less work then from STG/Core

But…

Couldn’t you do a better job from STG/Core?

Doubtful…

Easier to fix any deficiencies in Cmm representation and

code generator

Page 23: Haskell Symposium 2010: An LLVM backend for GHC

Dealing with SSA

LLVM language is SSA form:

• Each variable can only be assigned to once

• Immutable

How do we handle converting mutable Cmm variables?

• Allocate a stack slot for each Cmm variable

• Use load and stores for reads and writes

• Use ‘mem2reg’ llvm optimisation pass

• This converts our stack allocation to LLVM variables instead that

properly obeys the SSA requirement

Page 24: Haskell Symposium 2010: An LLVM backend for GHC

Type Systems?

LLVM language has a fairly high level type system

• Strings, Arrays, Pointers…

When combined with SSA form, great for development

• 15 bug fixes required after backend finished to get test

suite to pass

• 10 of those were motivated by type system errors

• Some could have been fairly difficult (e.g returning pointer

instead of value)