Building an LLVM Backend LLVM 2014 tutorial Fraser Cormack Pierre-André Saulais Codeplay So�ware @codeplayso� October 26, 2014
Introduc�on • LLVM backend crash course, for beginners ▶ How-tos and �ps ▶ Solu�on to common problems • Simple target created for this tutorial ▶ Can be used to see how LLVM works ▶ Can be used as a skeleton to bootstrap new target Fraser Cormack , Pierre-André Saulais Introduc�on 2 / 72
What you need to start • Know a li�le bit about LLVM IR: llvm.org/docs/LangRef.html • xdot.py to visualize graphs when debugging: github.com/jrfonseca/xdot.py • Check out and build our LLVM repo from GitHub: github.com/codeplaysoftware/llvm-leg • Slides from this informa�ve and well-presented talk! Fraser Cormack , Pierre-André Saulais Introduc�on 3 / 72
Overview Part 1: Background Part 2: Crea�ng your own target • Describing the target machine • Describing the instruc�on set Part 3: How-tos for specific tasks • Instruc�on prin�ng • Instruc�on encoding • Selec�on DAG manipula�on Part 4: Troubleshoo�ng and resources Fraser Cormack , Pierre-André Saulais Introduc�on 4 / 72
Part 1 Background Fraser Cormack , Pierre-André Saulais Part 1: Background 5 / 72
Example target: LEG • Simple, RISC-like architecture ▶ Very small subset of ARM • 12 integer registers (32-bit) ▶ r0, r1, ..., r9, sp (stack pointer), lr (return address) • Instruc�ons: ▶ 32-bit arithme�c (add, subtract, mul�ply, mad) ▶ 32-bit register move, 16-bit constant moves ▶ load, store, branch, branch and link Fraser Cormack , Pierre-André Saulais Part 1: Background 6 / 72
Calling conven�on for LEG • How values are passed to/from a func�on • Arguments in r0 (1st), r1 (2nd), …, r3 (4th) ▶ Further arguments passed on the stack • Return value in r0 int foo(int a, int b) { int result = a + b; // r0 + r1 return result; // r0 } ex1.c .foo: add r0, r0, r1 ex1.s b lr Fraser Cormack , Pierre-André Saulais Part 1: Background 7 / 72
LLVM Backend: The big picture • Pipeline structure ▶ Transforms your program many �mes using different stages ▶ Starts target-independent, then gets increasingly target-specific • Different representa�ons are used ▶ Tells you roughly where you are in the pipeline ▶ Different instruc�on namespaces • Check it out (IR and MI only): ▶ llc foo.ll -print-after-all 2>&1 > foo.log IR → Selec�onDAG → MachineDAG → MachineInstr → MCInst Fraser Cormack , Pierre-André Saulais Part 1: Background 8 / 72
A look at an IR module • Linear representa�on • High-level, target-agnos�c ▶ Excep�ons: data layout, triple, intrinsics • Most instruc�ons define values ▶ Typed (e.g. i32 , float , <4 x i32> ) ▶ Defined once (SSA), no registers target datalayout = "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i64:32-f64-..." target triple = "leg" define i32 @foo(i32 %a, i32 %b) { %c = add i32 %a, %b ret i32 %c } ex1b.ll IR → Selec�onDAG → MachineDAG → MachineInstr → MCInst Fraser Cormack , Pierre-André Saulais Part 1: Background 9 / 72
A look at a Selec�onDAG graph • Graph representa�on EntryToken [ID=0] Register %vreg0 [ID=1] Register %vreg1 [ID=2] ch i32 i32 • Opera�ons as nodes ▶ Mostly target-agnos�c 0 1 0 1 CopyFromReg [ORD=1] [ID=4] CopyFromReg [ORD=1] [ID=5] ▶ Seman�cs defined by LLVM i32 ch i32 ch ▶ ISD namespace for opcodes 0 1 Register %R0 [ID=3] ▶ Produce typed value(s) add [ORD=2] [ID=6] i32 i32 • Dependencies as edges 0 2 1 ▶ Data CopyToReg [ORD=3] [ID=7] ▶ Order (”chain”) ch glue ▶ Scheduling (”glue”) 0 1 2 RetFlag [ORD=3] [ID=8] ch IR → Selec�onDAG → MachineDAG → MachineInstr → MCInst Fraser Cormack , Pierre-André Saulais Part 1: Background 10 / 72
A look at a MachineDAG graph • Very similar to Selec�onDAG EntryToken Register %vreg0 Register %vreg1 ch i32 i32 • Target instruc�ons as nodes ▶ Result of instruc�on selec�on 0 1 0 1 ▶ LEG namespace CopyFromReg [ORD=1] CopyFromReg [ORD=1] i32 ch i32 ch • Similar dependencies 0 1 Register %R0 • Similar types ADDrr [ORD=2] i32 i32 0 2 1 CopyToReg [ORD=3] ch glue 1 0 2 RET [ORD=3] ch IR → Selec�onDAG → MachineDAG → MachineInstr → MCInst Fraser Cormack , Pierre-André Saulais Part 1: Background 11 / 72
Before and a�er instruc�on selec�on Before: A�er: EntryToken [ID=0] Register %vreg0 [ID=1] Register %vreg1 [ID=2] EntryToken Register %vreg0 Register %vreg1 ch i32 i32 ch i32 i32 0 1 0 1 0 1 0 1 CopyFromReg [ORD=1] [ID=4] CopyFromReg [ORD=1] [ID=5] CopyFromReg [ORD=1] CopyFromReg [ORD=1] i32 ch i32 ch i32 ch i32 ch 0 1 Register %R0 [ID=3] add [ORD=2] [ID=6] 0 1 i32 Register %R0 i32 ADDrr [ORD=2] i32 i32 0 2 1 CopyToReg [ORD=3] [ID=7] 0 2 1 ch glue CopyToReg [ORD=3] ch glue 0 1 2 RetFlag [ORD=3] [ID=8] ch 1 0 2 RET [ORD=3] ch IR → Selec�onDAG → MachineDAG → MachineInstr → MCInst Fraser Cormack , Pierre-André Saulais Part 1: Background 12 / 72
A look at a MachineInstr block • Untyped, uses register classes instead • Target-specific instruc�ons (LEG namespace) ▶ Few excep�ons (TargetOpcode namespace) BB#0: derived from LLVM BB %entry Live Ins: %R0 %R1 %R0<def> = ADDrr %R0<kill>, %R1<kill> Successors according to CFG: BB#1 ex1/ex1-mi.txt • Kill: last use of a value stored in a register IR → Selec�onDAG → MachineDAG → MachineInstr → MCInst Fraser Cormack , Pierre-André Saulais Part 1: Background 13 / 72
Part 2 Crea�ng your own target Fraser Cormack , Pierre-André Saulais Part 2: Crea�ng your own target 14 / 72
Bits of your ISA you need to describe • Target machine ▶ Registers, register classes ▶ Calling conven�ons • Instruc�on set ▶ Operands and pa�erns ▶ Assembly prin�ng and/or instruc�on encoding ▶ Schedule (not part of this talk) • ... Fraser Cormack , Pierre-André Saulais Part 2: Crea�ng your own target 15 / 72
Part 2: Crea�ng your own target • Describing the target machine • Describing the instruc�on set Fraser Cormack , Pierre-André Saulais Part 2: Crea�ng your own target 16 / 72
TableGen • C++-style syntax • Different set of backends ▶ RegisterInfo, InstrInfo, AsmWriter, ... • TableGen backends generate .inc files ▶ Included by your C++ files • More informa�on: ▶ llvm.org/docs/TableGen/index.html ▶ llvm.org/docs/TableGen/BackEnds.html Fraser Cormack , Pierre-André Saulais Part 2: Crea�ng your own target 17 / 72
Describing registers with TableGen • TableGen provides the ’Register’ class ▶ Can use the ’HWEncoding’ field for encodings • Referenced as “LEG::R0” in C++ class LEGReg<bits<16> Enc, string n> : Register<n> { Let HWEncoding = Enc; let Namespace = "LEG"; } def R0 : LEGReg< 0, "r0" >; ... def SP : LEGReg< 10, "sp" >; LEGRegisterInfo.td Fraser Cormack , Pierre-André Saulais Part 2: Crea�ng your own target 18 / 72
Describing registers with TableGen • Can automate trivial defini�ons foreach i = 0-9 in { def R#i : R<i, "r"#i>; } LEGRegisterInfo.td • Group registers into register classes def GRRegs : RegisterClass<"LEG", [i32], 32, (add SP, (sequence "R%i", 0, 9))>; LEGRegisterInfo.td Fraser Cormack , Pierre-André Saulais Part 2: Crea�ng your own target 19 / 72
Calling conven�on lowering: TableGen def CC_LEG : CallingConv<[ // Promote i8/i16 arguments to i32 CCIfType<[i8, i16], CCPromoteToType<i32>>, // The first 4 arguments are passed in registers CCIfType<[i32], CCAssignToReg<[R0, R1, R2, R3]>>, // Fall-back, and use the stack CCIfType<[i32], CCAssignToStack<4, 4>> ]>; LEGCallingConv.td • Generates func�ons used in ISelLowering via func�on pointers Fraser Cormack , Pierre-André Saulais Part 2: Crea�ng your own target 20 / 72
Calling conven�on lowering: The big picture a b define i32 @foo(i32 %a, i32 %b) { EntryToken [ID=0] Register %vreg0 [ID=1] Register %vreg1 [ID=2] %c = add i32 %a, %b ch i32 i32 ret i32 %c } ex1b.ll 0 1 0 1 CopyFromReg [ORD=1] [ID=4] CopyFromReg [ORD=1] [ID=5] i32 ch i32 ch Two target hooks: 0 1 • LowerFormalArguments() Register %R0 [ID=3] c add [ORD=2] [ID=6] i32 • LowerReturn() i32 0 2 1 CopyToReg [ORD=3] [ID=7] ch glue 0 1 2 RetFlag [ORD=3] [ID=8] ch Fraser Cormack , Pierre-André Saulais Part 2: Crea�ng your own target 21 / 72
Calling conven�on lowering: The big picture LowerFormalArguments() a b • Lowers incoming arguments into EntryToken [ID=0] Register %vreg0 [ID=1] Register %vreg1 [ID=2] ch i32 i32 the DAG LowerReturn() 0 1 0 1 CopyFromReg [ORD=1] [ID=4] CopyFromReg [ORD=1] [ID=5] • Lowers outgoing return values i32 ch i32 ch into the DAG 0 1 Register %R0 [ID=3] add [ORD=2] [ID=6] i32 i32 c 0 2 1 CopyToReg [ORD=3] [ID=7] ch glue 0 1 2 RetFlag [ORD=3] [ID=8] ch Fraser Cormack , Pierre-André Saulais Part 2: Crea�ng your own target 22 / 72
Recommend
More recommend