Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

LLVM Backend の紹介

2,079 views

Published on

2018/11/10 コンパイラ勉強会 @Fixstars
の発表資料です。

Published in: Engineering
  • Be the first to comment

LLVM Backend の紹介

  1. 1. è – – –
  2. 2. è –
  3. 3. è – – – int muladd(int a, int b, int c) { return a * b + c; } ; Function Attrs: norecurse nounwind readnone define dso_local i32 @_Z6muladdiii (i32 signext %a, i32 signext %b, i32 signext %c) local_unnamed_addr #0 { entry: %mul = mul nsw i32 %b, %a %add = add nsw i32 %mul, %c ret i32 %add }
  4. 4. è – – –
  5. 5. è è – – • – • •
  6. 6. è – – è – $ llc -view-dag-combine1-dags addmul.c //1回目のCombine前のSelectionDAGを出力 $ llc -view-legalize-dags muladd.c //Legalize前のSelectionDAGを出力 $ llc -view-isel-dags muladd.c //Select前のSelectionDAGを出力 $ llc -view-sched-dags muladd.c //Schedule前のSelectionDAGを出力
  7. 7. uint8_t max(uint8_t a, uint8_t b) { return a > b ? a : b; } define dso_local zeroext i8 @_Z3maxhh (i8 zeroext %a, i8 zeroext %b) local_unnamed_addr #0 { entry: %cmp = icmp ugt i8 %a, %b %cond = select i1 %cmp, i8 %a, i8 %b ret i8 %cond }
  8. 8. è – è – è – è – è –
  9. 9. ISEL: Starting selection on root node: t8: i32 = add nsw t7, t6 ISEL: Starting pattern match Initial Opcode index to 28638 Match failed at index 28642 Continuing at 28689 Match failed at index 28691 Continuing at 28739 Match failed at index 28743 Continuing at 29236 Match failed at index 29239 Continuing at 29747 Match failed at index 29758 Continuing at 29903 Skipped scope entry (due to false predicate) at index 29908, continuing at 29918 Morphed node: t8: i32 = ADDu nsw t7, t6 ISEL: Match complete! è
  10. 10. /* 28634*/ /*SwitchOpcode*/ 4|128,13/*1668*/, TARGET_VAL(ISD::ADD),// ->30306 /* 28638*/ OPC_Scope, 49, /*->28689*/ // 7 children in Scope /* 28640*/ OPC_RecordChild0, // #0 = $rt /* 28641*/ OPC_MoveChild1, /* 28642*/ OPC_CheckOpcode, TARGET_VAL(ISD::SHL), … /* 28689*/ /*Scope*/ 49, /*->28739*/ /* 28690*/ OPC_MoveChild0, /* 28691*/ OPC_CheckOpcode, TARGET_VAL(ISD::SHL), … /* 29918*/ /*Scope*/ 10, /*->29929*/ /* 29919*/ OPC_CheckPatternPredicate, 6, // (Subtarget->hasStandardEncoding()) && (!Subtarget->inMicroMipsMode()) /* 29921*/ OPC_MorphNodeTo1, TARGET_VAL(Mips::ADDu), 0, MVT::i32, 2/*#Ops*/, 0, 1, // Src: (add:{ *:[i32] } GPR32Opnd:{ *:[i32] }:$rs, GPR32Opnd:{ *:[i32] }:$rt) - Complexity = 3 // Dst: (ADDu:{ *:[i32] } GPR32Opnd:{ *:[i32] }:$rs, GPR32Opnd:{ *:[i32] }:$rt) è
  11. 11. è – • • • • • è –
  12. 12. // We have banks of 32 registers each. class MipsReg<bits<16> Enc, string n> : Register<n> { let HWEncoding = Enc; let Namespace = "Mips"; } // Mips CPU Registers. class MipsGPRReg<bits<16> Enc, string n> : MipsReg<Enc, n>; let Namespace = "Mips" in { // General Purpose Registers def ZERO : MipsGPRReg< 0, "zero">, DwarfRegNum<[0]>; def AT : MipsGPRReg< 1, "1">, DwarfRegNum<[1]>; def V0 : MipsGPRReg< 2, "2">, DwarfRegNum<[2]>; def V1 : MipsGPRReg< 3, "3">, DwarfRegNum<[3]>; def A0 : MipsGPRReg< 4, "4">, DwarfRegNum<[4]>; def A1 : MipsGPRReg< 5, "5">, DwarfRegNum<[5]>; def A2 : MipsGPRReg< 6, "6">, DwarfRegNum<[6]>; def A3 : MipsGPRReg< 7, "7">, DwarfRegNum<[7]>; … }
  13. 13. // Generic Mips Format class MipsInst<dag outs, dag ins, string asmstr, list<dag> pattern, InstrItinClass itin, Format f>: Instruction, PredicateControl { field bits<32> Inst; Format Form = f; let Namespace = "Mips"; let Size = 4; bits<6> Opcode = 0; // Top 6 bits are the 'opcode' field let Inst{31-26} = Opcode; let OutOperandList = outs; let InOperandList = ins; let AsmString = asmstr; let Pattern = pattern; let Itinerary = itin; … } … // Mips32/64 Instruction Format class InstSE<dag outs, dag ins, string asmstr, list<dag> pattern, InstrItinClass itin, Format f, string opstr = ""> : MipsInst<outs, ins, asmstr, pattern, itin, f> { let EncodingPredicates = [NotInMips16Mode]; string BaseOpcode = opstr; string Arch; }
  14. 14. //===----------------------------------------------------------------------===// // Format R instruction class in Mips : <|opcode|rs|rt|rd|shamt|funct|> //===----------------------------------------------------------------------===// class FR<bits<6> op, bits<6> _funct, dag outs, dag ins, string asmstr, list<dag> pattern, InstrItinClass itin>: InstSE<outs, ins, asmstr, pattern, itin, FrmR> { bits<5> rd; bits<5> rs; bits<5> rt; bits<5> shamt; bits<6> funct; let Opcode = op; let funct = _funct; let Inst{25-21} = rs; let Inst{20-16} = rt; let Inst{15-11} = rd; let Inst{10-6} = shamt; let Inst{5-0} = funct; }
  15. 15. // Arithmetic and logical instructions with 3 register operands. class ArithLogicR<string opstr, RegisterOperand RO, bit isComm = 0, InstrItinClass Itin = NoItinerary, SDPatternOperator OpNode = null_frag>: InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt), !strconcat(opstr, "¥t$rd, $rs, $rt"), [(set RO:$rd, (OpNode RO:$rs, RO:$rt))], Itin, FrmR, opstr> { let isCommutable = isComm; let isReMaterializable = 1; let TwoOperandAliasConstraint = "$rd = $rs"; } … def ADDu : MMRel, StdMMR6Rel, ArithLogicR<"addu", GPR32Opnd, 1, II_ADDU, add>, ADD_FM<0, 0x21>, ISA_MIPS1;
  16. 16. //===----------------------------------------------------------------------===// // Functional units across Mips chips sets. Based on GCC/Mips backend files. //===----------------------------------------------------------------------===// def ALU : FuncUnit; def IMULDIV : FuncUnit; … //===----------------------------------------------------------------------===// // Instruction Itinerary classes used for Mips //===----------------------------------------------------------------------===// def II_ADDU : InstrItinClass; … //===----------------------------------------------------------------------===// // Mips Generic instruction itineraries. //===----------------------------------------------------------------------===// def MipsGenericItineraries : ProcessorItineraries<[ALU, IMULDIV], [], [ InstrItinData<II_ADDU , [InstrStage<1, [ALU]>]>, InstrItinData<II_MULU , [InstrStage<17, [IMULDIV]>]>, …
  17. 17. def int_x86_avx512_add_ps_512 : GCCBuiltin<"__builtin_ia32_addps512">, Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty, llvm_i32_ty], [IntrNoMem]>; TARGET_BUILTIN(__builtin_ia32_maxps512, "V16fV16fV16fIi", "ncV:512:", "avx512f") _mm512_max_ps(__m512 __A, __m512 __B) { return (__m512) __builtin_ia32_maxps512((__v16sf) __A, (__v16sf) __B, _MM_FROUND_CUR_DIRECTION); } X86_INTRINSIC_DATA(avx512_max_ps_512, INTR_TYPE_2OP, X86ISD::FMAX, X86ISD::FMAX_RND),
  18. 18. è è – – – – –
  19. 19. è
  20. 20. è – – – è –
  21. 21. è – – è è è

×