SlideShare a Scribd company logo
LLVM Backend Porting
Outline
• LLVM Coding Standards
• Let cmake recognize new target
• Let LLVM recognize new target triple
• Add new target ELF defines
• Create backend folder for new target
• Add TargetMachine class
• Target description file
• Tablegen tool
• Register class target description
• Calling convention
• Instruction Info target description
• Create TargetInfo
• Register Target classes
Outline
• Add Instruction Selection Pass
• Declare TargetLowering class
• Lowering Arguments
• InstrInfo C functions
• RegisterInfo C functions
• Add FrameLowering class
• Add Instruction printer
• Add Assembly Parser
• Add Code Emitter
• Add Assembler Backend
LLVM Coding Standards
• 1. Don’t use Tab
– Different editor treat tab differently
• 2. no space in function call
– E.g. “A()” not “A{space}()”
• 3. Space before ()
• 4. Don’t exceed 80 column each line
• More detail please reference
– http://llvm.org/docs/CodingStandards.html
Let cmake recognize new target
• Modify cmake/config-ix.cmake
E.g.
elseif (LLVM_NATIVE_ARCH MATCHES "arm")
set(LLVM_NATIVE_ARCH ARM)
Let LLVM recognize new target triple
• Modify include/llvm/ADT/Triple.h
– Add new target in “class Triple”
• Modify lib/Support/Triple.cpp
– Add new target in following functions
• getArchTypeName
• getArchTypePrefix
• getArchTypeForLLVMName
• parseArch
• getDefaultFormat
• getArchPointerBitWidth
• get32BitArchVariant
• get64BitArchVariant
• getBigEndianArchVariant
• isLittleEndian
Let LLVM recognize new target triple
• Add new target triple test case
– Modify unittests/ADT/TripleTest.cpp
Add new target ELF defines
• Modify include/llvm/Object/ELFObjectFile.h
– Add new target in following functions
• getFileFormatName
• getArch
• Modify include/llvm/Object/RelocVisitor.h
– Let “class RelocVisitor” recognize new target 32/64
data relocation type case Triple::mipsel:
case Triple::mips:
switch (RelocType) {
case llvm::ELF::R_MIPS_32:
return visitELF_MIPS_32(R, Value);
default:
HasError = true;
return RelocToApply();
}
Add new target ELF defines
• Add new target ELF relocation type in
– include/llvm/Support/ELFRelocs/TARGET.def
• Include the TARGET.def in
– include/llvm/Support/ELF.h
– lib/Object/ELF.cpp
– lib/ObjectYAML/ELFYAML.cpp
• Add EM_TARGET in
– tools/llvm-readobj/ELFDumper.cpp
– tools/llvm-objdump/llvm-objdump.cpp
– lib/ObjectYAML/ELFYAML.cpp
Create backend folder for new target
• mkdir lib/Target/{target name}
• Add new target in llvm/CMakeLists.txt
– LLVM_ALL_TARGETS
• Add new target in lib/Target/LLVMBuild.txt
• Add Target ISA information in
– docs/CompilerWriterInfo.rst
• Create target CMakeLists.txt and
LLVMBuild.txt
– In lib/Target/{target name}
Defined TargetMachine class
• TargetMachine class
– Primary interface to the complete machine
description for the target machine.
– All target-specific information should be
accessible through this interface.
• Defined target specific TargetMachine class
– Including triple/cpu/datalayout …
– Have helper function to access
• Subtarget/RegisterInfo/InstrInfo/.. classess
Target description files
• LLVM use Target description files to describe
backend target
– Most of the backend will split target description to
several *.td and include in {target name}.td
– Add following line in lib/Target/{target
name}/CMakeLists.txt
• set(LLVM_TARGET_DEFINITIONS {target name}.td)
– Let build system could get target description files
Tablegen tool
• LLVM use Tablegen to transfer target
description files to target relative classes
– Add tablegen commands in lib/Target/{taget
name}/CMakeLists.txt to generate relative classes
E.g. tablegen(LLVM {target}GenRegisterInfo.inc -gen-register-info)
Generate {target }GenRegisterInfo class
All {target}Gen*.inc files will be generated in build folder
build/lib/Target/{target name}
Register class target description
• All the basic target class are defined in
– llvm/include/llvm/Target/Target.td
• Defined target register class
class MipsReg<bits<16> Enc, string n> : Register<n> {
let HWEncoding = Enc;
let Namespace = "Mips";
}
Enc would be the register number encoding when
emit binary.
Enc type must be bits<16>
which is the type HWEncoding in Register class defined in Target.td
Register class target description
• Define registers for the target
• Define register class for the targets
let Namespace = "Mips" in {
// General Purpose Registers
def ZERO : MipsGPRReg< 0, "zero">, DwarfRegNum<[0]>;
def AT : MipsGPRReg< 1, "1">, DwarfRegNum<[1]>;
DwarfRegNum<num>, num would be the register number
represented in debug info.
def GPR : RegisterClass<"ARM", [i32], 32, (add (sequence "R%u", 0, 12),
SP, LR, PC)>
RegisterClass <namespace, type, alignment, register list>
Register list will effect register allocation order
Calling Convention
• Basic calling convention relative class defined in
– llvm/include/llvm/Target/TargetCallingConv.td
• Primary Calling convention class
– CallingConv<actions>
– actions are calling convention rules
def CC_ARM_APCS : CallingConv<[
// Handles byval parameters.
CCIfByVal<CCPassByVal<4, 4>>,
// if the argument is pass by value, setting size and alignment to 4
CCIfType<[i1, i8, i16], CCPromoteToType<i32>>,
// promote i1, i8, i16 type to i32
// Handle all vector types as either f64
CCIfType<[v1i64, v2i32, v4i16, v8i8, v2f32], CCBitConvertToType<f64>>,
// convert v1i64, v2i32, v4i16, v8i8, v2f32 type arguments to f64 type
Calling Convention
CCIfType<[f64, v2f64], CCCustom<"CC_ARM_APCS_Custom_f64">>,
// use customize calling convention rule function for f64, v2f64 type
CCIfType<[f32], CCBitConvertToType<i32>>,
// convert f32 type to i32
CCIfType<[i32], CCAssignToReg<[R0, R1, R2, R3]>>,
// specify argument registers
CCIfType<[i32], CCAssignToStack<4, 4>>,
// specify stack size and alignment when i32 type assign to stack
CCIfType<[i64], CCAssignToRegWithShadow<[R0, R2], [R1, R3]>>,
// if assign R0 then also clobber R1 for i64 type argument
def CSR_O32 : CalleeSavedRegs<(add (sequence "D%u", 15, 10), RA, FP,
(sequence "S%u", 7, 0))>;
Defined callee save registers
Instruction Info target description
• Defined target generic instruction
– inherent from Instruction class defined in Target.td
– Must specify following item
• OutOperandList
– Output operands dag
• InOperandList
– Input operands dag
• Pattern
– Dag pattern for instruction matching
• AsmString
– Assembly print in *.s
• bits<insn_bit_num> Inst
– Instruction encoding
Instruction Info target description
• Defined target generic instruction
– Most of the target define it’s generic instruction
and instruction format in {target}InstrFormat.td
// Generic MSP430 Format
class MSP430Inst<dag outs, dag ins, SizeVal sz, Format f,
string asmstr> : Instruction {
field bits<16> Inst;
let Namespace = "MSP430";
dag OutOperandList = outs;
dag InOperandList = ins;
…
let AsmString = asmstr;
}
Instruction Info target description
• Defined instruction format// MSP430 Double Operand (Format I) Instructions
class IForm<bits<4> opcode, DestMode dest, bit bw, SourceMode src, SizeVal sz,
dag outs, dag ins, string asmstr, list<dag> pattern>
: MSP430Inst<outs, ins, sz, DoubleOpFrm, asmstr> {
let Pattern = pattern;
DestMode ad = dest;
SourceMode as = src;
let Inst{12-15} = opcode;
let Inst{7} = ad.Value;
let Inst{6} = bw;
let Inst{4-5} = as.Value;
}
// 8 bit IForm instructions
class IForm8<bits<4> opcode, DestMode dest, SourceMode src, SizeVal sz,
dag outs, dag ins, string asmstr, list<dag> pattern>
: IForm<opcode, dest, 1, src, sz, outs, ins, asmstr, pattern>;
IForm8 <- IForm <- MSP430Inst
inherent
Instruction Info target description
• Define instructions by instruction format patterns
– Specify input/output/match pattern/assembly for the instruction
– Defined in {target}InstrInfo.td
let mayLoad = 1, hasExtraDefRegAllocReq = 1, Constraints = "$base = $base_wb" in {
def MOV8rm_POST : IForm8<0x0, DstReg, SrcPostInc, Size2Bytes,
(outs GR8:$dst, GR16:$base_wb), (ins GR16:$base),
"mov.bt{@$base+, $dst}", []>;
def MOVZX16rr8 : I8rr<0x0,
(outs GR16:$dst), (ins GR8:$src),
"mov.bt{$src, $dst}",
[(set GR16:$dst, (zext GR8:$src))]>;
Instruction Info target description
• Define target specific SDNode
namespace llvm {
namespace MipsISD {
enum NodeType : unsigned {
// Start the numbering from where ISD NodeType finishes.
FIRST_NUMBER = ISD::BUILTIN_OP_END,
…
// Return
Ret, MipsISelLowering.h
// Return
def MipsRet : SDNode<"MipsISD::Ret", SDTNone,
[SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
def RetRA : PseudoSE<(outs), (ins), [(MipsRet)]>;
MipsInstrInfo.td
SDNode attribute
Defined in Target.td
Instruction Info target description
• Define target specific “complex pattern”
//===----------------------------------------------------------------------===//
// MSP430 Complex Pattern Definitions.
//===----------------------------------------------------------------------===//
def addr : ComplexPattern<iPTR, 2, "SelectAddr", [], []>;
def Bm : I16rm<0, (outs), (ins memsrc:$brdst),
"brt$brdst",
[(brind (load addr:$brdst))]>;
Defined SelectAddr in MSP430ISelDAGToDAG.cpp
For target specific operand matching
Instruction Info target description
• Define Pat<> pattern
– Directly transfer specific DAG to target instruction
// extload
def : Pat<(extloadi16i8 addr:$src), (MOVZX16rm8 addr:$src)>;
def : Pat<(and GR16:$src, 255), (ZEXT16r GR16:$src)>;
Instruction Info target description
• High level semantics of the instruction
– Each instruction pattern could specify high-level
semantic defined in Target.td
– Will influence optimization result
– E.g.
• IsReturn, isBranch, isBarrirer
– Would influence branch relative optimization
Create TargetInfo
• Declare Target class
– Create TargetInfo folder
– Add {target}TargetInfo.cpp
– Target class defined in
include/llvm/Support/TargetRegistry.h
– Which is the primary target hook to get/set all
backend target information
Register Target classes
• Define LLVMInitialize{target}TargetMC ()
– Create MCTargetDesc folder
– Add {target}MCTargetDesc.*
– Register following classes you need for the target
• AsmInfo
• InstrInfo
• RegisterInfo
• Subtargetinfo
• InstrPrinter
• MCCodeEmitter
• MCAsmBackend
Register Target classes
• How to invoke LLVMInitialize{target}TargetMC
() for register backend
– Build system will create “Targets.def” according to
your configuration in build folder
– And then frontend will invoke “InitializeAllTargets”
• Which will invoke LLVMInitialize{target}TargetMC()
according to Targets.def
Add Instruction Selection Pass
• Generate {target}GenDAGISel.inc in build folder
– According *.td files
– Add tablegen(LLVM {target}GenDAGISel.inc -gen-dag-
isel) in CmakeLists.txt
• To enable the file generation
• Add {target}ISelDAGToDAG.cpp
– Add the compile file in CmakeLists.txt
– Add create{target}ISelDag() to create selection pass
– addPass(create{target}ISelDag(),..) in
{target}TargetMachine.cpp to insert the pass to pass
pipeline
Add Instruction Selection Pass
• Declare {target}DAGToDAGISel in
{target}ISelDAGToDAG.cpp
– This file will contain target specific instruction selection for
complex pattern operands
• E.g. bool MSP430DAGToDAGISel::SelectAddr(…)
– The class provide ::Select()
• Could do target custom selection
– E.g. generate post_inc load/store instruction
– The invoke flow would be
• Call Select() if there have custom selection, do custom selection
• Use tablegen file “{target}GenDAGISel.inc” to select instruction
– If the instruction have complex pattern
» Call the instruction specify in {target}ISelDAGToDAG.cpp
Declare TargetLowering class
• The class have 3 major task
– Lowering type
• Transfer data type to the target could support
– E.g. Promote ZEXTLOAD for i1 to i32
– Lowering operation
• Transfer the operation to the target could support
– Lowering arguments
• Specify how target ABI pass/store arguments
– Inline assembly support
Declare TargetLowering class
• Lowering operation
– Setting setOperationAction for the operations
• Actions could be
• Legal
– The operation target support and don’t need other transfer
• Expand
– The target could support but need llvm generic code to
expand the operation
• Custom
– Use target specific operation lowering function
Lowering Arguments
• Lower argument functions
– Contain in TargetLowering class
– LowerFormalArguments
• Specify how callee get arguments
– LowerReturn
• Specify how callee return value
– LowerCall
• specify how caller passing arguments
• Specify how caller get return value
Lowering Arguments
• LowerFormalArguments
– Declare CCState class
• The calling convention state class use to record
argument state
• Call AnalyzeFormalArguments
– CCState member function
– Passing calling convention rule as argument
» The calling convention rule define in
{target}CallingConv.td
» So {target}ISelLowering.cpp have to include
“{target}GenCallingConv.inc”
– The function will return argument state
» Pass by register or stack
Lowering Arguments
• LowerFormalArguments
– According to AnalyzeFormalArguments() result
– Have to generate operations (DAGs) handle
• 1. copy physical register to virtual register
– If passing by register
• 2. insert load from stack
– If passing by stack
• 3. push variable arguments passing by register to the
stack
– Let va_arg could access elements continuous on stack
• 4. handle call by value
InstrInfo C functions
• For the Instruction Info that are hard to present by *.td
– We could define in {target}InstrInfo.cpp
– Declare {target}InstrInfo class
• Inherent from {target}GenInstrInfo class
– Generate by tablegen
– Need include “{target}GenInstrInfo.inc”
» Add tablegen(LLVM {target}GenInstrInfo.inc -gen-instr-info) in
CMakeLists.txt
– Add functions for target to generate following semantic
• storeRegToStackSlot
• loadRegFromStackSlot
• copyPhysReg
InstrInfo C functions
• InstrInfo helper functions for branch relative
optimization
– insertBranch
• How target insert branch
– removeBranch
• How target remove branches
– analyzeBranch
• Return branch’s
– True target basic block
– False target basic block
– Branch condition
• Could also do
– Remove redundant instructions after unconditional jump
• More detail could reference the comments in
– include/llvm/Target/TargetInstrInfo.h
RegisterInfo C functions
• Define {target}RegisterInfo class
– Inherent by {target}GenRegisterInfo class
• Generate by tablegen
• Need include “{target}GenRegisterInfo.inc”
– Add tablegen(LLVM {target}GenRegisterInfo.inc -gen-register-info)
in CMakeLists.txt
• Helper functions need to defined for the target
– getCalleeSavedRegs
• Return callee save registers list
– getCallPreservedMask
• Return callee save register mask
• Use to generate mask to identify which registers live time
could cross call
RegisterInfo C functions
• Helper functions need to defined for the
target
– getReservedRegs
• Setting the reserve registers which not allow for
register allocation
– getPointerRegClass
• Return register class which could contain pointer
– getFrameRegister
• Return frame pointer for the target
RegisterInfo C functions
• Helper functions need to defined for the
target
– eliminateFrameIndex
• Eliminate the instruction contain “frame index” to base
+ offset after register allocation
• Expand the instruction if single instruction couldn’t
contain the offset
Add FrameLowering class
• Define target FrameLowering class
– The class constructor defined
• Frame growing direction (up/down)
• Stack alignment
• Local area offset from stack pointer
• Helper functions need to define for the target
– emitPrologue
– emitEpilogue
– spillCalleeSavedRegisters
– restoreCalleeSavedRegisters
– getFrameIndexReference
• Given frame index
• Return base register and offset
– hasFP
Add Instruction printer
• Mkdir InstPrinter
– Add {target}InstPrinter.* and CMakeLists.txt LLVMBuild.txt
• Declare {target}InstPrinter class
– Inherent from MCInstPrinter class
• Main entry function is printInst()
– Which will call printInstruction()
» printInstruction() autogenerated by tblgen
» Need include “{target}GenAsmWriter.inc“
– Add create{target}MCInstPrinter
• Register the instruction printer in {target}MCTargetDesc.cpp
– Add print operand helper function for complex pattern
• Need setting PrintMethod to specific printer function in *.td
Add Assembly Parser
• Mkdir AsmParser
– Add {target}AsmParser.* and CMakeLists.txt
LLVMBuild.txt
• Declare {target}AsmParser class
– Inherent from MCTargetAsmParser class
• Declare {target}Operand class
– Inherent from MCParsedAsmOperand
– To record the operand parsing result
Add Assembly Parser
• Implement ParseInstruction()
– Entry function to Parse assembly code
• Call parseOperand to parse each operand
– Call MatchOperandParserImpl()
» Autogenerated by tablegen
• Need include “{target}GenAsmMatcher.inc”
– Could also implement other custom parsing function
» E.g. parser function for RegisterList operand
– Record the parsing result to a operand vector
Add Assembly Parser
• Implement MatchAndEmitInstruction ()
– Match the instruction and emit instructon
• Call MatchInstructionImpl()
– Autogenerated by tablegen
» Need include “{target}GenAsmMatcher.inc”
– Pass operands vector and assembly name as argument
– Return Match_Success if the target could support the assembly
instruction
• Add helper function for parsing complex pattern
• Need setting ParserMatchClass to specific parsing function in
*.td
Add Code Emitter
• Add {target} MCCodeEmitter.* in MCTargetDesc folder
• Declare {target}MCCodeEmitter class
– Inherent from MCCodeEmitter class
• Add create{target}MCCodeEmitter
– Register the code emitter in {target}MCTargetDesc.cpp
– Main entry function “encodeInstruction”
• Will call getBinaryCodeForInstr ()
– Autogenerated by tablegen
» Need include “{target} GenMCCodeEmitter.inc”
– Add helper function for parsing complex pattern
• Need setting EncoderMethod to specific encode function in *.td
Add Code Emitter
• Insert relocation type
– For symbol don’t know address until linking
• We need to insert relocation type
• E.g. Function call from different compile unit
• Insert the fixup type for the relocation
– Insert the fixup type in function call operand encoding
method
– It will transform to relative relocation type later
• Define target specific fixup type
– In MCTargetDesc/{target}FixupKinds.h
Add Assembler Backend
• Add {target}AsmBackend.* in MCTargetDesc
folder
• Declare {target}AsmBackend class
– Inherent from MCAsmBackend
– Add member functions
• Add create{target}MCAsmBackend
– Register in {target}MCTargetDesc.cpp
• getFixupKindInfo()
– Given fixup kind, return fixup kind info
– Setting FKF_IsPCRel for pc-relative branch fixup
» This kind fixup can resolve by assembler it self
Add Assembler Backend
• Declare {target}AsmBackend class
– Add member functions
• processFixupValue ()
– For the fixup kind could resolve by the assembler
» E.g. Branch target in the function
» Some target branch encode may need shift
• E.g. branch range is (1<<10) and must 2 byte
alignment
• Encoding in 9 bits
• Need right shift 1 before encoding
• applyFixup()
– For the fixup kind could resolve by the assembler
– Write back the fixup value to the instruction binary
Add Assembler Backend
• Add {target}ELFObjectWriter.cpp
– Declare {target}ELFObjectWriter class
• Inherent from MCELFObjectTargetWriter class
– Add member functions
• needsRelocateWithSymbol()
– Given relocation type
– Return true for the relocation type need to be inserted for the
symbol access
• getRelocType ()
– Given fixup kind
– return relative relocation type

More Related Content

PPTX
LLVM Instruction Selection
PDF
LLVM Register Allocation (2nd Version)
PDF
Instruction Combine in LLVM
PDF
LLVM Register Allocation
PPT
Gcc porting
PDF
How to write a TableGen backend
PDF
Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015
PDF
DWARF Data Representation
LLVM Instruction Selection
LLVM Register Allocation (2nd Version)
Instruction Combine in LLVM
LLVM Register Allocation
Gcc porting
How to write a TableGen backend
Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015
DWARF Data Representation

What's hot (20)

PDF
A whirlwind tour of the LLVM optimizer
PPT
linux device driver
PDF
Play with FILE Structure - Yet Another Binary Exploit Technique
PDF
Valgrind tutorial
PDF
JVM code reading -- C2
PPTX
快快樂樂SIMD
PDF
LLVM Backend の紹介
PDF
Faster packet processing in Linux: XDP
PPT
PDF
Linux Kernel - Virtual File System
PDF
Character drivers
PDF
Pwning in c++ (basic)
PDF
Linux : PSCI
PDF
from Binary to Binary: How Qemu Works
PDF
LAS16-501: Introduction to LLVM - Projects, Components, Integration, Internals
PDF
Kernel Recipes 2017 - Understanding the Linux kernel via ftrace - Steven Rostedt
PDF
BPF - in-kernel virtual machine
PPTX
Memory model
PDF
Introduction to CMake
PDF
Handling inline assembly in Clang and LLVM
A whirlwind tour of the LLVM optimizer
linux device driver
Play with FILE Structure - Yet Another Binary Exploit Technique
Valgrind tutorial
JVM code reading -- C2
快快樂樂SIMD
LLVM Backend の紹介
Faster packet processing in Linux: XDP
Linux Kernel - Virtual File System
Character drivers
Pwning in c++ (basic)
Linux : PSCI
from Binary to Binary: How Qemu Works
LAS16-501: Introduction to LLVM - Projects, Components, Integration, Internals
Kernel Recipes 2017 - Understanding the Linux kernel via ftrace - Steven Rostedt
BPF - in-kernel virtual machine
Memory model
Introduction to CMake
Handling inline assembly in Clang and LLVM
Ad

Similar to LLVM Backend Porting (20)

PPTX
PPTX
Big Data Day LA 2015 - Compiling DSLs for Diverse Execution Environments by Z...
PDF
Create your own PHP extension, step by step - phpDay 2012 Verona
PDF
7986-lect 7.pdf
PDF
0100_Embeded_C_CompilationProcess.pdf
ODP
Writing MySQL UDFs
PPTX
C_Progragramming_language_Tutorial_ppt_f.pptx
PDF
External Language Stored Procedures for MySQL
PPTX
NASM Introduction.pptx
PPTX
C programming language tutorial
PDF
NativeBoost
PPTX
Python_Functions_Unit1.pptx
PPTX
Introduction to c
PPT
Linux Device Driver for Writing a real world driver for embedded Linux
PPT
Unit 4
PDF
The Ring programming language version 1.3 book - Part 60 of 88
PPTX
GCC RTL and Machine Description
PPTX
Functions and Arraysfgdfgdfgdfgdfgdg.pptx
PPTX
Meta Object Protocols
PDF
WCTF 2018 binja Editorial
Big Data Day LA 2015 - Compiling DSLs for Diverse Execution Environments by Z...
Create your own PHP extension, step by step - phpDay 2012 Verona
7986-lect 7.pdf
0100_Embeded_C_CompilationProcess.pdf
Writing MySQL UDFs
C_Progragramming_language_Tutorial_ppt_f.pptx
External Language Stored Procedures for MySQL
NASM Introduction.pptx
C programming language tutorial
NativeBoost
Python_Functions_Unit1.pptx
Introduction to c
Linux Device Driver for Writing a real world driver for embedded Linux
Unit 4
The Ring programming language version 1.3 book - Part 60 of 88
GCC RTL and Machine Description
Functions and Arraysfgdfgdfgdfgdfgdg.pptx
Meta Object Protocols
WCTF 2018 binja Editorial
Ad

Recently uploaded (20)

PPTX
2. Earth - The Living Planet Module 2ELS
PDF
HPLC-PPT.docx high performance liquid chromatography
PDF
IFIT3 RNA-binding activity primores influenza A viruz infection and translati...
PPTX
Cell Membrane: Structure, Composition & Functions
PDF
The scientific heritage No 166 (166) (2025)
PDF
Placing the Near-Earth Object Impact Probability in Context
PPTX
Microbiology with diagram medical studies .pptx
PPTX
Introduction to Fisheries Biotechnology_Lesson 1.pptx
PPTX
TOTAL hIP ARTHROPLASTY Presentation.pptx
PDF
bbec55_b34400a7914c42429908233dbd381773.pdf
PPTX
microscope-Lecturecjchchchchcuvuvhc.pptx
PPT
The World of Physical Science, • Labs: Safety Simulation, Measurement Practice
PPTX
2Systematics of Living Organisms t-.pptx
PDF
. Radiology Case Scenariosssssssssssssss
PPT
protein biochemistry.ppt for university classes
PPTX
INTRODUCTION TO EVS | Concept of sustainability
PDF
Biophysics 2.pdffffffffffffffffffffffffff
PDF
Formation of Supersonic Turbulence in the Primordial Star-forming Cloud
PPTX
7. General Toxicologyfor clinical phrmacy.pptx
PPTX
famous lake in india and its disturibution and importance
2. Earth - The Living Planet Module 2ELS
HPLC-PPT.docx high performance liquid chromatography
IFIT3 RNA-binding activity primores influenza A viruz infection and translati...
Cell Membrane: Structure, Composition & Functions
The scientific heritage No 166 (166) (2025)
Placing the Near-Earth Object Impact Probability in Context
Microbiology with diagram medical studies .pptx
Introduction to Fisheries Biotechnology_Lesson 1.pptx
TOTAL hIP ARTHROPLASTY Presentation.pptx
bbec55_b34400a7914c42429908233dbd381773.pdf
microscope-Lecturecjchchchchcuvuvhc.pptx
The World of Physical Science, • Labs: Safety Simulation, Measurement Practice
2Systematics of Living Organisms t-.pptx
. Radiology Case Scenariosssssssssssssss
protein biochemistry.ppt for university classes
INTRODUCTION TO EVS | Concept of sustainability
Biophysics 2.pdffffffffffffffffffffffffff
Formation of Supersonic Turbulence in the Primordial Star-forming Cloud
7. General Toxicologyfor clinical phrmacy.pptx
famous lake in india and its disturibution and importance

LLVM Backend Porting

  • 2. Outline • LLVM Coding Standards • Let cmake recognize new target • Let LLVM recognize new target triple • Add new target ELF defines • Create backend folder for new target • Add TargetMachine class • Target description file • Tablegen tool • Register class target description • Calling convention • Instruction Info target description • Create TargetInfo • Register Target classes
  • 3. Outline • Add Instruction Selection Pass • Declare TargetLowering class • Lowering Arguments • InstrInfo C functions • RegisterInfo C functions • Add FrameLowering class • Add Instruction printer • Add Assembly Parser • Add Code Emitter • Add Assembler Backend
  • 4. LLVM Coding Standards • 1. Don’t use Tab – Different editor treat tab differently • 2. no space in function call – E.g. “A()” not “A{space}()” • 3. Space before () • 4. Don’t exceed 80 column each line • More detail please reference – http://llvm.org/docs/CodingStandards.html
  • 5. Let cmake recognize new target • Modify cmake/config-ix.cmake E.g. elseif (LLVM_NATIVE_ARCH MATCHES "arm") set(LLVM_NATIVE_ARCH ARM)
  • 6. Let LLVM recognize new target triple • Modify include/llvm/ADT/Triple.h – Add new target in “class Triple” • Modify lib/Support/Triple.cpp – Add new target in following functions • getArchTypeName • getArchTypePrefix • getArchTypeForLLVMName • parseArch • getDefaultFormat • getArchPointerBitWidth • get32BitArchVariant • get64BitArchVariant • getBigEndianArchVariant • isLittleEndian
  • 7. Let LLVM recognize new target triple • Add new target triple test case – Modify unittests/ADT/TripleTest.cpp
  • 8. Add new target ELF defines • Modify include/llvm/Object/ELFObjectFile.h – Add new target in following functions • getFileFormatName • getArch • Modify include/llvm/Object/RelocVisitor.h – Let “class RelocVisitor” recognize new target 32/64 data relocation type case Triple::mipsel: case Triple::mips: switch (RelocType) { case llvm::ELF::R_MIPS_32: return visitELF_MIPS_32(R, Value); default: HasError = true; return RelocToApply(); }
  • 9. Add new target ELF defines • Add new target ELF relocation type in – include/llvm/Support/ELFRelocs/TARGET.def • Include the TARGET.def in – include/llvm/Support/ELF.h – lib/Object/ELF.cpp – lib/ObjectYAML/ELFYAML.cpp • Add EM_TARGET in – tools/llvm-readobj/ELFDumper.cpp – tools/llvm-objdump/llvm-objdump.cpp – lib/ObjectYAML/ELFYAML.cpp
  • 10. Create backend folder for new target • mkdir lib/Target/{target name} • Add new target in llvm/CMakeLists.txt – LLVM_ALL_TARGETS • Add new target in lib/Target/LLVMBuild.txt • Add Target ISA information in – docs/CompilerWriterInfo.rst • Create target CMakeLists.txt and LLVMBuild.txt – In lib/Target/{target name}
  • 11. Defined TargetMachine class • TargetMachine class – Primary interface to the complete machine description for the target machine. – All target-specific information should be accessible through this interface. • Defined target specific TargetMachine class – Including triple/cpu/datalayout … – Have helper function to access • Subtarget/RegisterInfo/InstrInfo/.. classess
  • 12. Target description files • LLVM use Target description files to describe backend target – Most of the backend will split target description to several *.td and include in {target name}.td – Add following line in lib/Target/{target name}/CMakeLists.txt • set(LLVM_TARGET_DEFINITIONS {target name}.td) – Let build system could get target description files
  • 13. Tablegen tool • LLVM use Tablegen to transfer target description files to target relative classes – Add tablegen commands in lib/Target/{taget name}/CMakeLists.txt to generate relative classes E.g. tablegen(LLVM {target}GenRegisterInfo.inc -gen-register-info) Generate {target }GenRegisterInfo class All {target}Gen*.inc files will be generated in build folder build/lib/Target/{target name}
  • 14. Register class target description • All the basic target class are defined in – llvm/include/llvm/Target/Target.td • Defined target register class class MipsReg<bits<16> Enc, string n> : Register<n> { let HWEncoding = Enc; let Namespace = "Mips"; } Enc would be the register number encoding when emit binary. Enc type must be bits<16> which is the type HWEncoding in Register class defined in Target.td
  • 15. Register class target description • Define registers for the target • Define register class for the targets let Namespace = "Mips" in { // General Purpose Registers def ZERO : MipsGPRReg< 0, "zero">, DwarfRegNum<[0]>; def AT : MipsGPRReg< 1, "1">, DwarfRegNum<[1]>; DwarfRegNum<num>, num would be the register number represented in debug info. def GPR : RegisterClass<"ARM", [i32], 32, (add (sequence "R%u", 0, 12), SP, LR, PC)> RegisterClass <namespace, type, alignment, register list> Register list will effect register allocation order
  • 16. Calling Convention • Basic calling convention relative class defined in – llvm/include/llvm/Target/TargetCallingConv.td • Primary Calling convention class – CallingConv<actions> – actions are calling convention rules def CC_ARM_APCS : CallingConv<[ // Handles byval parameters. CCIfByVal<CCPassByVal<4, 4>>, // if the argument is pass by value, setting size and alignment to 4 CCIfType<[i1, i8, i16], CCPromoteToType<i32>>, // promote i1, i8, i16 type to i32 // Handle all vector types as either f64 CCIfType<[v1i64, v2i32, v4i16, v8i8, v2f32], CCBitConvertToType<f64>>, // convert v1i64, v2i32, v4i16, v8i8, v2f32 type arguments to f64 type
  • 17. Calling Convention CCIfType<[f64, v2f64], CCCustom<"CC_ARM_APCS_Custom_f64">>, // use customize calling convention rule function for f64, v2f64 type CCIfType<[f32], CCBitConvertToType<i32>>, // convert f32 type to i32 CCIfType<[i32], CCAssignToReg<[R0, R1, R2, R3]>>, // specify argument registers CCIfType<[i32], CCAssignToStack<4, 4>>, // specify stack size and alignment when i32 type assign to stack CCIfType<[i64], CCAssignToRegWithShadow<[R0, R2], [R1, R3]>>, // if assign R0 then also clobber R1 for i64 type argument def CSR_O32 : CalleeSavedRegs<(add (sequence "D%u", 15, 10), RA, FP, (sequence "S%u", 7, 0))>; Defined callee save registers
  • 18. Instruction Info target description • Defined target generic instruction – inherent from Instruction class defined in Target.td – Must specify following item • OutOperandList – Output operands dag • InOperandList – Input operands dag • Pattern – Dag pattern for instruction matching • AsmString – Assembly print in *.s • bits<insn_bit_num> Inst – Instruction encoding
  • 19. Instruction Info target description • Defined target generic instruction – Most of the target define it’s generic instruction and instruction format in {target}InstrFormat.td // Generic MSP430 Format class MSP430Inst<dag outs, dag ins, SizeVal sz, Format f, string asmstr> : Instruction { field bits<16> Inst; let Namespace = "MSP430"; dag OutOperandList = outs; dag InOperandList = ins; … let AsmString = asmstr; }
  • 20. Instruction Info target description • Defined instruction format// MSP430 Double Operand (Format I) Instructions class IForm<bits<4> opcode, DestMode dest, bit bw, SourceMode src, SizeVal sz, dag outs, dag ins, string asmstr, list<dag> pattern> : MSP430Inst<outs, ins, sz, DoubleOpFrm, asmstr> { let Pattern = pattern; DestMode ad = dest; SourceMode as = src; let Inst{12-15} = opcode; let Inst{7} = ad.Value; let Inst{6} = bw; let Inst{4-5} = as.Value; } // 8 bit IForm instructions class IForm8<bits<4> opcode, DestMode dest, SourceMode src, SizeVal sz, dag outs, dag ins, string asmstr, list<dag> pattern> : IForm<opcode, dest, 1, src, sz, outs, ins, asmstr, pattern>; IForm8 <- IForm <- MSP430Inst inherent
  • 21. Instruction Info target description • Define instructions by instruction format patterns – Specify input/output/match pattern/assembly for the instruction – Defined in {target}InstrInfo.td let mayLoad = 1, hasExtraDefRegAllocReq = 1, Constraints = "$base = $base_wb" in { def MOV8rm_POST : IForm8<0x0, DstReg, SrcPostInc, Size2Bytes, (outs GR8:$dst, GR16:$base_wb), (ins GR16:$base), "mov.bt{@$base+, $dst}", []>; def MOVZX16rr8 : I8rr<0x0, (outs GR16:$dst), (ins GR8:$src), "mov.bt{$src, $dst}", [(set GR16:$dst, (zext GR8:$src))]>;
  • 22. Instruction Info target description • Define target specific SDNode namespace llvm { namespace MipsISD { enum NodeType : unsigned { // Start the numbering from where ISD NodeType finishes. FIRST_NUMBER = ISD::BUILTIN_OP_END, … // Return Ret, MipsISelLowering.h // Return def MipsRet : SDNode<"MipsISD::Ret", SDTNone, [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; def RetRA : PseudoSE<(outs), (ins), [(MipsRet)]>; MipsInstrInfo.td SDNode attribute Defined in Target.td
  • 23. Instruction Info target description • Define target specific “complex pattern” //===----------------------------------------------------------------------===// // MSP430 Complex Pattern Definitions. //===----------------------------------------------------------------------===// def addr : ComplexPattern<iPTR, 2, "SelectAddr", [], []>; def Bm : I16rm<0, (outs), (ins memsrc:$brdst), "brt$brdst", [(brind (load addr:$brdst))]>; Defined SelectAddr in MSP430ISelDAGToDAG.cpp For target specific operand matching
  • 24. Instruction Info target description • Define Pat<> pattern – Directly transfer specific DAG to target instruction // extload def : Pat<(extloadi16i8 addr:$src), (MOVZX16rm8 addr:$src)>; def : Pat<(and GR16:$src, 255), (ZEXT16r GR16:$src)>;
  • 25. Instruction Info target description • High level semantics of the instruction – Each instruction pattern could specify high-level semantic defined in Target.td – Will influence optimization result – E.g. • IsReturn, isBranch, isBarrirer – Would influence branch relative optimization
  • 26. Create TargetInfo • Declare Target class – Create TargetInfo folder – Add {target}TargetInfo.cpp – Target class defined in include/llvm/Support/TargetRegistry.h – Which is the primary target hook to get/set all backend target information
  • 27. Register Target classes • Define LLVMInitialize{target}TargetMC () – Create MCTargetDesc folder – Add {target}MCTargetDesc.* – Register following classes you need for the target • AsmInfo • InstrInfo • RegisterInfo • Subtargetinfo • InstrPrinter • MCCodeEmitter • MCAsmBackend
  • 28. Register Target classes • How to invoke LLVMInitialize{target}TargetMC () for register backend – Build system will create “Targets.def” according to your configuration in build folder – And then frontend will invoke “InitializeAllTargets” • Which will invoke LLVMInitialize{target}TargetMC() according to Targets.def
  • 29. Add Instruction Selection Pass • Generate {target}GenDAGISel.inc in build folder – According *.td files – Add tablegen(LLVM {target}GenDAGISel.inc -gen-dag- isel) in CmakeLists.txt • To enable the file generation • Add {target}ISelDAGToDAG.cpp – Add the compile file in CmakeLists.txt – Add create{target}ISelDag() to create selection pass – addPass(create{target}ISelDag(),..) in {target}TargetMachine.cpp to insert the pass to pass pipeline
  • 30. Add Instruction Selection Pass • Declare {target}DAGToDAGISel in {target}ISelDAGToDAG.cpp – This file will contain target specific instruction selection for complex pattern operands • E.g. bool MSP430DAGToDAGISel::SelectAddr(…) – The class provide ::Select() • Could do target custom selection – E.g. generate post_inc load/store instruction – The invoke flow would be • Call Select() if there have custom selection, do custom selection • Use tablegen file “{target}GenDAGISel.inc” to select instruction – If the instruction have complex pattern » Call the instruction specify in {target}ISelDAGToDAG.cpp
  • 31. Declare TargetLowering class • The class have 3 major task – Lowering type • Transfer data type to the target could support – E.g. Promote ZEXTLOAD for i1 to i32 – Lowering operation • Transfer the operation to the target could support – Lowering arguments • Specify how target ABI pass/store arguments – Inline assembly support
  • 32. Declare TargetLowering class • Lowering operation – Setting setOperationAction for the operations • Actions could be • Legal – The operation target support and don’t need other transfer • Expand – The target could support but need llvm generic code to expand the operation • Custom – Use target specific operation lowering function
  • 33. Lowering Arguments • Lower argument functions – Contain in TargetLowering class – LowerFormalArguments • Specify how callee get arguments – LowerReturn • Specify how callee return value – LowerCall • specify how caller passing arguments • Specify how caller get return value
  • 34. Lowering Arguments • LowerFormalArguments – Declare CCState class • The calling convention state class use to record argument state • Call AnalyzeFormalArguments – CCState member function – Passing calling convention rule as argument » The calling convention rule define in {target}CallingConv.td » So {target}ISelLowering.cpp have to include “{target}GenCallingConv.inc” – The function will return argument state » Pass by register or stack
  • 35. Lowering Arguments • LowerFormalArguments – According to AnalyzeFormalArguments() result – Have to generate operations (DAGs) handle • 1. copy physical register to virtual register – If passing by register • 2. insert load from stack – If passing by stack • 3. push variable arguments passing by register to the stack – Let va_arg could access elements continuous on stack • 4. handle call by value
  • 36. InstrInfo C functions • For the Instruction Info that are hard to present by *.td – We could define in {target}InstrInfo.cpp – Declare {target}InstrInfo class • Inherent from {target}GenInstrInfo class – Generate by tablegen – Need include “{target}GenInstrInfo.inc” » Add tablegen(LLVM {target}GenInstrInfo.inc -gen-instr-info) in CMakeLists.txt – Add functions for target to generate following semantic • storeRegToStackSlot • loadRegFromStackSlot • copyPhysReg
  • 37. InstrInfo C functions • InstrInfo helper functions for branch relative optimization – insertBranch • How target insert branch – removeBranch • How target remove branches – analyzeBranch • Return branch’s – True target basic block – False target basic block – Branch condition • Could also do – Remove redundant instructions after unconditional jump • More detail could reference the comments in – include/llvm/Target/TargetInstrInfo.h
  • 38. RegisterInfo C functions • Define {target}RegisterInfo class – Inherent by {target}GenRegisterInfo class • Generate by tablegen • Need include “{target}GenRegisterInfo.inc” – Add tablegen(LLVM {target}GenRegisterInfo.inc -gen-register-info) in CMakeLists.txt • Helper functions need to defined for the target – getCalleeSavedRegs • Return callee save registers list – getCallPreservedMask • Return callee save register mask • Use to generate mask to identify which registers live time could cross call
  • 39. RegisterInfo C functions • Helper functions need to defined for the target – getReservedRegs • Setting the reserve registers which not allow for register allocation – getPointerRegClass • Return register class which could contain pointer – getFrameRegister • Return frame pointer for the target
  • 40. RegisterInfo C functions • Helper functions need to defined for the target – eliminateFrameIndex • Eliminate the instruction contain “frame index” to base + offset after register allocation • Expand the instruction if single instruction couldn’t contain the offset
  • 41. Add FrameLowering class • Define target FrameLowering class – The class constructor defined • Frame growing direction (up/down) • Stack alignment • Local area offset from stack pointer • Helper functions need to define for the target – emitPrologue – emitEpilogue – spillCalleeSavedRegisters – restoreCalleeSavedRegisters – getFrameIndexReference • Given frame index • Return base register and offset – hasFP
  • 42. Add Instruction printer • Mkdir InstPrinter – Add {target}InstPrinter.* and CMakeLists.txt LLVMBuild.txt • Declare {target}InstPrinter class – Inherent from MCInstPrinter class • Main entry function is printInst() – Which will call printInstruction() » printInstruction() autogenerated by tblgen » Need include “{target}GenAsmWriter.inc“ – Add create{target}MCInstPrinter • Register the instruction printer in {target}MCTargetDesc.cpp – Add print operand helper function for complex pattern • Need setting PrintMethod to specific printer function in *.td
  • 43. Add Assembly Parser • Mkdir AsmParser – Add {target}AsmParser.* and CMakeLists.txt LLVMBuild.txt • Declare {target}AsmParser class – Inherent from MCTargetAsmParser class • Declare {target}Operand class – Inherent from MCParsedAsmOperand – To record the operand parsing result
  • 44. Add Assembly Parser • Implement ParseInstruction() – Entry function to Parse assembly code • Call parseOperand to parse each operand – Call MatchOperandParserImpl() » Autogenerated by tablegen • Need include “{target}GenAsmMatcher.inc” – Could also implement other custom parsing function » E.g. parser function for RegisterList operand – Record the parsing result to a operand vector
  • 45. Add Assembly Parser • Implement MatchAndEmitInstruction () – Match the instruction and emit instructon • Call MatchInstructionImpl() – Autogenerated by tablegen » Need include “{target}GenAsmMatcher.inc” – Pass operands vector and assembly name as argument – Return Match_Success if the target could support the assembly instruction • Add helper function for parsing complex pattern • Need setting ParserMatchClass to specific parsing function in *.td
  • 46. Add Code Emitter • Add {target} MCCodeEmitter.* in MCTargetDesc folder • Declare {target}MCCodeEmitter class – Inherent from MCCodeEmitter class • Add create{target}MCCodeEmitter – Register the code emitter in {target}MCTargetDesc.cpp – Main entry function “encodeInstruction” • Will call getBinaryCodeForInstr () – Autogenerated by tablegen » Need include “{target} GenMCCodeEmitter.inc” – Add helper function for parsing complex pattern • Need setting EncoderMethod to specific encode function in *.td
  • 47. Add Code Emitter • Insert relocation type – For symbol don’t know address until linking • We need to insert relocation type • E.g. Function call from different compile unit • Insert the fixup type for the relocation – Insert the fixup type in function call operand encoding method – It will transform to relative relocation type later • Define target specific fixup type – In MCTargetDesc/{target}FixupKinds.h
  • 48. Add Assembler Backend • Add {target}AsmBackend.* in MCTargetDesc folder • Declare {target}AsmBackend class – Inherent from MCAsmBackend – Add member functions • Add create{target}MCAsmBackend – Register in {target}MCTargetDesc.cpp • getFixupKindInfo() – Given fixup kind, return fixup kind info – Setting FKF_IsPCRel for pc-relative branch fixup » This kind fixup can resolve by assembler it self
  • 49. Add Assembler Backend • Declare {target}AsmBackend class – Add member functions • processFixupValue () – For the fixup kind could resolve by the assembler » E.g. Branch target in the function » Some target branch encode may need shift • E.g. branch range is (1<<10) and must 2 byte alignment • Encoding in 9 bits • Need right shift 1 before encoding • applyFixup() – For the fixup kind could resolve by the assembler – Write back the fixup value to the instruction binary
  • 50. Add Assembler Backend • Add {target}ELFObjectWriter.cpp – Declare {target}ELFObjectWriter class • Inherent from MCELFObjectTargetWriter class – Add member functions • needsRelocateWithSymbol() – Given relocation type – Return true for the relocation type need to be inserted for the symbol access • getRelocType () – Given fixup kind – return relative relocation type