diff options
Diffstat (limited to 'docs')
67 files changed, 7173 insertions, 1358 deletions
diff --git a/docs/AMDGPUUsage.rst b/docs/AMDGPUUsage.rst index 34a9b6011d40c..0824eb86650ae 100644 --- a/docs/AMDGPUUsage.rst +++ b/docs/AMDGPUUsage.rst @@ -8,6 +8,8 @@ Introduction The AMDGPU back-end provides ISA code generation for AMD GPUs, starting with the R600 family up until the current Volcanic Islands (GCN Gen 3). +Refer to `AMDGPU section in Architecture & Platform Information for Compiler Writers <CompilerWriterInfo.html#amdgpu>`_ +for additional documentation. Conventions =========== @@ -35,96 +37,241 @@ OpenCL standard. Assembler ========= -The assembler is currently considered experimental. +AMDGPU backend has LLVM-MC based assembler which is currently in development. +It supports Southern Islands ISA, Sea Islands and Volcanic Islands. -For syntax examples look in test/MC/AMDGPU. +This document describes general syntax for instructions and operands. For more +information about instructions, their semantics and supported combinations +of operands, refer to one of Instruction Set Architecture manuals. -Below some of the currently supported features (modulo bugs). These -all apply to the Southern Islands ISA, Sea Islands and Volcanic Islands -are also supported but may be missing some instructions and have more bugs: +An instruction has the following syntax (register operands are +normally comma-separated while extra operands are space-separated): -DS Instructions ---------------- -All DS instructions are supported. +*<opcode> <register_operand0>, ... <extra_operand0> ...* -FLAT Instructions ------------------- -These instructions are only present in the Sea Islands and Volcanic Islands -instruction set. All FLAT instructions are supported for these architectures -MUBUF Instructions ------------------- -All non-atomic MUBUF instructions are supported. +Operands +-------- -SMRD Instructions ------------------ -Only the s_load_dword* SMRD instructions are supported. +The following syntax for register operands is supported: -SOP1 Instructions ------------------ -All SOP1 instructions are supported. +* SGPR registers: s0, ... or s[0], ... +* VGPR registers: v0, ... or v[0], ... +* TTMP registers: ttmp0, ... or ttmp[0], ... +* Special registers: exec (exec_lo, exec_hi), vcc (vcc_lo, vcc_hi), flat_scratch (flat_scratch_lo, flat_scratch_hi) +* Special trap registers: tba (tba_lo, tba_hi), tma (tma_lo, tma_hi) +* Register pairs, quads, etc: s[2:3], v[10:11], ttmp[5:6], s[4:7], v[12:15], ttmp[4:7], s[8:15], ... +* Register lists: [s0, s1], [ttmp0, ttmp1, ttmp2, ttmp3] +* Register index expressions: v[2*2], s[1-1:2-1] +* 'off' indicates that an operand is not enabled -SOP2 Instructions ------------------ -All SOP2 instructions are supported. +The following extra operands are supported: -SOPC Instructions ------------------ -All SOPC instructions are supported. +* offset, offset0, offset1 +* idxen, offen bits +* glc, slc, tfe bits +* waitcnt: integer or combination of counter values +* VOP3 modifiers: -SOPP Instructions ------------------ + - abs (\| \|), neg (\-) -Unless otherwise mentioned, all SOPP instructions that have one or more -operands accept integer operands only. No verification is performed -on the operands, so it is up to the programmer to be familiar with the -range or acceptable values. +* DPP modifiers: + + - row_shl, row_shr, row_ror, row_rol + - row_mirror, row_half_mirror, row_bcast + - wave_shl, wave_shr, wave_ror, wave_rol, quad_perm + - row_mask, bank_mask, bound_ctrl + +* SDWA modifiers: + + - dst_sel, src0_sel, src1_sel (BYTE_N, WORD_M, DWORD) + - dst_unused (UNUSED_PAD, UNUSED_SEXT, UNUSED_PRESERVE) + - abs, neg, sext + +DS Instructions Examples +------------------------ + +.. code-block:: nasm -s_waitcnt -^^^^^^^^^ + ds_add_u32 v2, v4 offset:16 + ds_write_src2_b64 v2 offset0:4 offset1:8 + ds_cmpst_f32 v2, v4, v6 + ds_min_rtn_f64 v[8:9], v2, v[4:5] -s_waitcnt accepts named arguments to specify which memory counter(s) to -wait for. + +For full list of supported instructions, refer to "LDS/GDS instructions" in ISA Manual. + +FLAT Instruction Examples +-------------------------- .. code-block:: nasm - ; Wait for all counters to be 0 - s_waitcnt 0 + flat_load_dword v1, v[3:4] + flat_store_dwordx3 v[3:4], v[5:7] + flat_atomic_swap v1, v[3:4], v5 glc + flat_atomic_cmpswap v1, v[3:4], v[5:6] glc slc + flat_atomic_fmax_x2 v[1:2], v[3:4], v[5:6] glc - ; Equivalent to s_waitcnt 0. Counter names can also be delimited by - ; '&' or ','. - s_waitcnt vmcnt(0) expcnt(0) lgkcmt(0) +For full list of supported instructions, refer to "FLAT instructions" in ISA Manual. - ; Wait for vmcnt counter to be 1. - s_waitcnt vmcnt(1) +MUBUF Instruction Examples +--------------------------- + +.. code-block:: nasm -VOP1, VOP2, VOP3, VOPC Instructions ------------------------------------ + buffer_load_dword v1, off, s[4:7], s1 + buffer_store_dwordx4 v[1:4], v2, ttmp[4:7], s1 offen offset:4 glc tfe + buffer_store_format_xy v[1:2], off, s[4:7], s1 + buffer_wbinvl1 + buffer_atomic_inc v1, v2, s[8:11], s4 idxen offset:4 slc -All 32-bit and 64-bit encodings should work. +For full list of supported instructions, refer to "MUBUF Instructions" in ISA Manual. -The assembler will automatically detect which encoding size to use for -VOP1, VOP2, and VOPC instructions based on the operands. If you want to force -a specific encoding size, you can add an _e32 (for 32-bit encoding) or -_e64 (for 64-bit encoding) suffix to the instruction. Most, but not all -instructions support an explicit suffix. These are all valid assembly -strings: +SMRD/SMEM Instruction Examples +------------------------------- .. code-block:: nasm - v_mul_i32_i24 v1, v2, v3 - v_mul_i32_i24_e32 v1, v2, v3 - v_mul_i32_i24_e64 v1, v2, v3 + s_load_dword s1, s[2:3], 0xfc + s_load_dwordx8 s[8:15], s[2:3], s4 + s_load_dwordx16 s[88:103], s[2:3], s4 + s_dcache_inv_vol + s_memtime s[4:5] + +For full list of supported instructions, refer to "Scalar Memory Operations" in ISA Manual. + +SOP1 Instruction Examples +-------------------------- + +.. code-block:: nasm + + s_mov_b32 s1, s2 + s_mov_b64 s[0:1], 0x80000000 + s_cmov_b32 s1, 200 + s_wqm_b64 s[2:3], s[4:5] + s_bcnt0_i32_b64 s1, s[2:3] + s_swappc_b64 s[2:3], s[4:5] + s_cbranch_join s[4:5] + +For full list of supported instructions, refer to "SOP1 Instructions" in ISA Manual. + +SOP2 Instruction Examples +------------------------- + +.. code-block:: nasm + + s_add_u32 s1, s2, s3 + s_and_b64 s[2:3], s[4:5], s[6:7] + s_cselect_b32 s1, s2, s3 + s_andn2_b32 s2, s4, s6 + s_lshr_b64 s[2:3], s[4:5], s6 + s_ashr_i32 s2, s4, s6 + s_bfm_b64 s[2:3], s4, s6 + s_bfe_i64 s[2:3], s[4:5], s6 + s_cbranch_g_fork s[4:5], s[6:7] + +For full list of supported instructions, refer to "SOP2 Instructions" in ISA Manual. + +SOPC Instruction Examples +-------------------------- + +.. code-block:: nasm + + s_cmp_eq_i32 s1, s2 + s_bitcmp1_b32 s1, s2 + s_bitcmp0_b64 s[2:3], s4 + s_setvskip s3, s5 + +For full list of supported instructions, refer to "SOPC Instructions" in ISA Manual. -Assembler Directives --------------------- +SOPP Instruction Examples +-------------------------- + +.. code-block:: nasm + + s_barrier + s_nop 2 + s_endpgm + s_waitcnt 0 ; Wait for all counters to be 0 + s_waitcnt vmcnt(0) & expcnt(0) & lgkmcnt(0) ; Equivalent to above + s_waitcnt vmcnt(1) ; Wait for vmcnt counter to be 1. + s_sethalt 9 + s_sleep 10 + s_sendmsg 0x1 + s_sendmsg sendmsg(MSG_INTERRUPT) + s_trap 1 + +For full list of supported instructions, refer to "SOPP Instructions" in ISA Manual. + +Unless otherwise mentioned, little verification is performed on the operands +of SOPP Instrucitons, so it is up to the programmer to be familiar with the +range or acceptable values. + +Vector ALU Instruction Examples +------------------------------- + +For vector ALU instruction opcodes (VOP1, VOP2, VOP3, VOPC, VOP_DPP, VOP_SDWA), +the assembler will automatically use optimal encoding based on its operands. +To force specific encoding, one can add a suffix to the opcode of the instruction: + +* _e32 for 32-bit VOP1/VOP2/VOPC +* _e64 for 64-bit VOP3 +* _dpp for VOP_DPP +* _sdwa for VOP_SDWA + +VOP1/VOP2/VOP3/VOPC examples: + +.. code-block:: nasm + + v_mov_b32 v1, v2 + v_mov_b32_e32 v1, v2 + v_nop + v_cvt_f64_i32_e32 v[1:2], v2 + v_floor_f32_e32 v1, v2 + v_bfrev_b32_e32 v1, v2 + v_add_f32_e32 v1, v2, v3 + v_mul_i32_i24_e64 v1, v2, 3 + v_mul_i32_i24_e32 v1, -3, v3 + v_mul_i32_i24_e32 v1, -100, v3 + v_addc_u32 v1, s[0:1], v2, v3, s[2:3] + v_max_f16_e32 v1, v2, v3 + +VOP_DPP examples: + +.. code-block:: nasm + + v_mov_b32 v0, v0 quad_perm:[0,2,1,1] + v_sin_f32 v0, v0 row_shl:1 row_mask:0xa bank_mask:0x1 bound_ctrl:0 + v_mov_b32 v0, v0 wave_shl:1 + v_mov_b32 v0, v0 row_mirror + v_mov_b32 v0, v0 row_bcast:31 + v_mov_b32 v0, v0 quad_perm:[1,3,0,1] row_mask:0xa bank_mask:0x1 bound_ctrl:0 + v_add_f32 v0, v0, |v0| row_shl:1 row_mask:0xa bank_mask:0x1 bound_ctrl:0 + v_max_f16 v1, v2, v3 row_shl:1 row_mask:0xa bank_mask:0x1 bound_ctrl:0 + +VOP_SDWA examples: + +.. code-block:: nasm + + v_mov_b32 v1, v2 dst_sel:BYTE_0 dst_unused:UNUSED_PRESERVE src0_sel:DWORD + v_min_u32 v200, v200, v1 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:BYTE_1 src1_sel:DWORD + v_sin_f32 v0, v0 dst_unused:UNUSED_PAD src0_sel:WORD_1 + v_fract_f32 v0, |v0| dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1 + v_cmpx_le_u32 vcc, v1, v2 src0_sel:BYTE_2 src1_sel:WORD_0 + +For full list of supported instructions, refer to "Vector ALU instructions". + +HSA Code Object Directives +-------------------------- + +AMDGPU ABI defines auxiliary data in output code object. In assembly source, +one can specify them with assembler directives. .hsa_code_object_version major, minor ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ *major* and *minor* are integers that specify the version of the HSA code -object that will be generated by the assembler. This value will be stored -in an entry of the .note section. +object that will be generated by the assembler. .hsa_code_object_isa [major, minor, stepping, vendor, arch] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -135,12 +282,14 @@ set architecture (ISA) version of the assembly program. *vendor* and *arch* are quoted strings. *vendor* should always be equal to "AMD" and *arch* should always be equal to "AMDGPU". -If no arguments are specified, then the assembler will derive the ISA version, -*vendor*, and *arch* from the value of the -mcpu option that is passed to the -assembler. +By default, the assembler will derive the ISA version, *vendor*, and *arch* +from the value of the -mcpu option that is passed to the assembler. + +.amdgpu_hsa_kernel (name) +^^^^^^^^^^^^^^^^^^^^^^^^^ -ISA version, *vendor*, and *arch* will all be stored in a single entry of the -.note section. +This directives specifies that the symbol with given name is a kernel entry point +(label) and the object should contain corresponding symbol of type STT_AMDGPU_HSA_KERNEL. .amd_kernel_code_t ^^^^^^^^^^^^^^^^^^ @@ -165,13 +314,12 @@ used. The default value for all keys is 0, with the following exceptions: The *.amd_kernel_code_t* directive must be placed immediately after the function label and before any instructions. -For a full list of amd_kernel_code_t keys, see the examples in -test/CodeGen/AMDGPU/hsa.s. For an explanation of the meanings of the different -keys, see the comments in lib/Target/AMDGPU/AmdKernelCodeT.h +For a full list of amd_kernel_code_t keys, refer to AMDGPU ABI document, +comments in lib/Target/AMDGPU/AmdKernelCodeT.h and test/CodeGen/AMDGPU/hsa.s. Here is an example of a minimal amd_kernel_code_t specification: -.. code-block:: nasm +.. code-block:: none .hsa_code_object_version 1,0 .hsa_code_object_isa diff --git a/docs/AliasAnalysis.rst b/docs/AliasAnalysis.rst index 097f7bf75cbcd..02b749ffb9181 100644 --- a/docs/AliasAnalysis.rst +++ b/docs/AliasAnalysis.rst @@ -702,6 +702,12 @@ algorithm will have a lower number of may aliases). Memory Dependence Analysis ========================== +.. note:: + + We are currently in the process of migrating things from + ``MemoryDependenceAnalysis`` to :doc:`MemorySSA`. Please try to use + that instead. + If you're just looking to be a client of alias analysis information, consider using the Memory Dependence Analysis interface instead. MemDep is a lazy, caching layer on top of alias analysis that is able to answer the question of diff --git a/docs/BitCodeFormat.rst b/docs/BitCodeFormat.rst index ffa2176325275..3c9aa1010704c 100644 --- a/docs/BitCodeFormat.rst +++ b/docs/BitCodeFormat.rst @@ -534,15 +534,13 @@ LLVM IR is defined with the following blocks: * 9 --- `PARAMATTR_BLOCK`_ --- This enumerates the parameter attributes. -* 10 --- `TYPE_BLOCK`_ --- This describes all of the types in the module. +* 10 --- `PARAMATTR_GROUP_BLOCK`_ --- This describes the attribute group table. * 11 --- `CONSTANTS_BLOCK`_ --- This describes constants for a module or function. * 12 --- `FUNCTION_BLOCK`_ --- This describes a function body. -* 13 --- `TYPE_SYMTAB_BLOCK`_ --- This describes the type symbol table. - * 14 --- `VALUE_SYMTAB_BLOCK`_ --- This describes a value symbol table. * 15 --- `METADATA_BLOCK`_ --- This describes metadata items. @@ -550,6 +548,8 @@ LLVM IR is defined with the following blocks: * 16 --- `METADATA_ATTACHMENT`_ --- This contains records associating metadata with function instruction values. +* 17 --- `TYPE_BLOCK`_ --- This describes all of the types in the module. + .. _MODULE_BLOCK: MODULE_BLOCK Contents @@ -562,8 +562,8 @@ block may contain the following sub-blocks: * `BLOCKINFO`_ * `PARAMATTR_BLOCK`_ +* `PARAMATTR_GROUP_BLOCK`_ * `TYPE_BLOCK`_ -* `TYPE_SYMTAB_BLOCK`_ * `VALUE_SYMTAB_BLOCK`_ * `CONSTANTS_BLOCK`_ * `FUNCTION_BLOCK`_ @@ -596,7 +596,7 @@ will be encoded as 1. For example, instead of -.. code-block:: llvm +.. code-block:: none #n = load #n-1 #n+1 = icmp eq #n, #const0 @@ -604,7 +604,7 @@ For example, instead of version 1 will encode the instructions as -.. code-block:: llvm +.. code-block:: none #n = load #1 #n+1 = icmp eq #1, (#n+1)-#const0 @@ -880,6 +880,23 @@ Entries within ``PARAMATTR_BLOCK`` are constructed to ensure that each is unique PARAMATTR_CODE_ENTRY Record ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +``[ENTRY, attrgrp0, attrgrp1, ...]`` + +The ``ENTRY`` record (code 2) contains a variable number of values describing a +unique set of function parameter attributes. Each *attrgrp* value is used as a +key with which to look up an entry in the the attribute group table described +in the ``PARAMATTR_GROUP_BLOCK`` block. + +.. _PARAMATTR_CODE_ENTRY_OLD: + +PARAMATTR_CODE_ENTRY_OLD Record +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. note:: + This is a legacy encoding for attributes, produced by LLVM versions 3.2 and + earlier. It is guaranteed to be understood by the current LLVM version, as + specified in the :ref:`IR backwards compatibility` policy. + ``[ENTRY, paramidx0, attr0, paramidx1, attr1...]`` The ``ENTRY`` record (code 1) contains an even number of values describing a @@ -914,12 +931,120 @@ following interpretation: * bits 37-39: ``alignstack n``, represented as the logarithm base 2 of the requested alignment, plus 1 +.. _PARAMATTR_GROUP_BLOCK: + +PARAMATTR_GROUP_BLOCK Contents +------------------------------ + +The ``PARAMATTR_GROUP_BLOCK`` block (id 10) contains a table of entries +describing the attribute groups present in the module. These entries can be +referenced within ``PARAMATTR_CODE_ENTRY`` entries. + +.. _PARAMATTR_GRP_CODE_ENTRY: + +PARAMATTR_GRP_CODE_ENTRY Record +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``[ENTRY, grpid, paramidx, attr0, attr1, ...]`` + +The ``ENTRY`` record (code 3) contains *grpid* and *paramidx* values, followed +by a variable number of values describing a unique group of attributes. The +*grpid* value is a unique key for the attribute group, which can be referenced +within ``PARAMATTR_CODE_ENTRY`` entries. The *paramidx* value indicates which +set of attributes is represented, with 0 representing the return value +attributes, 0xFFFFFFFF representing function attributes, and other values +representing 1-based function parameters. + +Each *attr* is itself represented as a variable number of values: + +``kind, key [, ...], [value [, ...]]`` + +Each attribute is either a well-known LLVM attribute (possibly with an integer +value associated with it), or an arbitrary string (possibly with an arbitrary +string value associated with it). The *kind* value is an integer code +distinguishing between these possibilities: + +* code 0: well-known attribute +* code 1: well-known attribute with an integer value +* code 3: string attribute +* code 4: string attribute with a string value + +For well-known attributes (code 0 or 1), the *key* value is an integer code +identifying the attribute. For attributes with an integer argument (code 1), +the *value* value indicates the argument. + +For string attributes (code 3 or 4), the *key* value is actually a variable +number of values representing the bytes of a null-terminated string. For +attributes with a string argument (code 4), the *value* value is similarly a +variable number of values representing the bytes of a null-terminated string. + +The integer codes are mapped to well-known attributes as follows. + +* code 1: ``align(<n>)`` +* code 2: ``alwaysinline`` +* code 3: ``byval`` +* code 4: ``inlinehint`` +* code 5: ``inreg`` +* code 6: ``minsize`` +* code 7: ``naked`` +* code 8: ``nest`` +* code 9: ``noalias`` +* code 10: ``nobuiltin`` +* code 11: ``nocapture`` +* code 12: ``noduplicates`` +* code 13: ``noimplicitfloat`` +* code 14: ``noinline`` +* code 15: ``nonlazybind`` +* code 16: ``noredzone`` +* code 17: ``noreturn`` +* code 18: ``nounwind`` +* code 19: ``optsize`` +* code 20: ``readnone`` +* code 21: ``readonly`` +* code 22: ``returned`` +* code 23: ``returns_twice`` +* code 24: ``signext`` +* code 25: ``alignstack(<n>)`` +* code 26: ``ssp`` +* code 27: ``sspreq`` +* code 28: ``sspstrong`` +* code 29: ``sret`` +* code 30: ``sanitize_address`` +* code 31: ``sanitize_thread`` +* code 32: ``sanitize_memory`` +* code 33: ``uwtable`` +* code 34: ``zeroext`` +* code 35: ``builtin`` +* code 36: ``cold`` +* code 37: ``optnone`` +* code 38: ``inalloca`` +* code 39: ``nonnull`` +* code 40: ``jumptable`` +* code 41: ``dereferenceable(<n>)`` +* code 42: ``dereferenceable_or_null(<n>)`` +* code 43: ``convergent`` +* code 44: ``safestack`` +* code 45: ``argmemonly`` +* code 46: ``swiftself`` +* code 47: ``swifterror`` +* code 48: ``norecurse`` +* code 49: ``inaccessiblememonly`` +* code 50: ``inaccessiblememonly_or_argmemonly`` +* code 51: ``allocsize(<EltSizeParam>[, <NumEltsParam>])`` +* code 52: ``writeonly`` + +.. note:: + The ``allocsize`` attribute has a special encoding for its arguments. Its two + arguments, which are 32-bit integers, are packed into one 64-bit integer value + (i.e. ``(EltSizeParam << 32) | NumEltsParam``), with ``NumEltsParam`` taking on + the sentinel value -1 if it is not specified. + .. _TYPE_BLOCK: TYPE_BLOCK Contents ------------------- -The ``TYPE_BLOCK`` block (id 10) contains records which constitute a table of +The ``TYPE_BLOCK`` block (id 17) contains records which constitute a table of type operator entries used to represent types referenced within an LLVM module. Each record (with the exception of `NUMENTRY`_) generates a single type table entry, which may be referenced by 0-based index from instructions, @@ -983,8 +1108,9 @@ TYPE_CODE_OPAQUE Record ``[OPAQUE]`` -The ``OPAQUE`` record (code 6) adds an ``opaque`` type to the type table. Note -that distinct ``opaque`` types are not unified. +The ``OPAQUE`` record (code 6) adds an ``opaque`` type to the type table, with +a name defined by a previously encountered ``STRUCT_NAME`` record. Note that +distinct ``opaque`` types are not unified. TYPE_CODE_INTEGER Record ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -1007,13 +1133,18 @@ operand fields are * *address space*: If supplied, the target-specific numbered address space where the pointed-to object resides. Otherwise, the default address space is zero. -TYPE_CODE_FUNCTION Record -^^^^^^^^^^^^^^^^^^^^^^^^^ +TYPE_CODE_FUNCTION_OLD Record +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -``[FUNCTION, vararg, ignored, retty, ...paramty... ]`` +.. note:: + This is a legacy encoding for functions, produced by LLVM versions 3.0 and + earlier. It is guaranteed to be understood by the current LLVM version, as + specified in the :ref:`IR backwards compatibility` policy. -The ``FUNCTION`` record (code 9) adds a function type to the type table. The -operand fields are +``[FUNCTION_OLD, vararg, ignored, retty, ...paramty... ]`` + +The ``FUNCTION_OLD`` record (code 9) adds a function type to the type table. +The operand fields are * *vararg*: Non-zero if the type represents a varargs function @@ -1025,19 +1156,6 @@ operand fields are * *paramty*: Zero or more type indices representing the parameter types of the function -TYPE_CODE_STRUCT Record -^^^^^^^^^^^^^^^^^^^^^^^ - -``[STRUCT, ispacked, ...eltty...]`` - -The ``STRUCT`` record (code 10) adds a struct type to the type table. The -operand fields are - -* *ispacked*: Non-zero if the type represents a packed structure - -* *eltty*: Zero or more type indices representing the element types of the - structure - TYPE_CODE_ARRAY Record ^^^^^^^^^^^^^^^^^^^^^^ @@ -1093,6 +1211,64 @@ TYPE_CODE_METADATA Record The ``METADATA`` record (code 16) adds a ``metadata`` type to the type table. +TYPE_CODE_X86_MMX Record +^^^^^^^^^^^^^^^^^^^^^^^^ + +``[X86_MMX]`` + +The ``X86_MMX`` record (code 17) adds an ``x86_mmx`` type to the type table. + +TYPE_CODE_STRUCT_ANON Record +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``[STRUCT_ANON, ispacked, ...eltty...]`` + +The ``STRUCT_ANON`` record (code 18) adds a literal struct type to the type +table. The operand fields are + +* *ispacked*: Non-zero if the type represents a packed structure + +* *eltty*: Zero or more type indices representing the element types of the + structure + +TYPE_CODE_STRUCT_NAME Record +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``[STRUCT_NAME, ...string...]`` + +The ``STRUCT_NAME`` record (code 19) contains a variable number of values +representing the bytes of a struct name. The next ``OPAQUE`` or +``STRUCT_NAMED`` record will use this name. + +TYPE_CODE_STRUCT_NAMED Record +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``[STRUCT_NAMED, ispacked, ...eltty...]`` + +The ``STRUCT_NAMED`` record (code 20) adds an identified struct type to the +type table, with a name defined by a previously encountered ``STRUCT_NAME`` +record. The operand fields are + +* *ispacked*: Non-zero if the type represents a packed structure + +* *eltty*: Zero or more type indices representing the element types of the + structure + +TYPE_CODE_FUNCTION Record +^^^^^^^^^^^^^^^^^^^^^^^^^ + +``[FUNCTION, vararg, retty, ...paramty... ]`` + +The ``FUNCTION`` record (code 21) adds a function type to the type table. The +operand fields are + +* *vararg*: Non-zero if the type represents a varargs function + +* *retty*: The type index of the function's return type + +* *paramty*: Zero or more type indices representing the parameter types of the + function + .. _CONSTANTS_BLOCK: CONSTANTS_BLOCK Contents @@ -1114,26 +1290,6 @@ contain the following sub-blocks: * `VALUE_SYMTAB_BLOCK`_ * `METADATA_ATTACHMENT`_ -.. _TYPE_SYMTAB_BLOCK: - -TYPE_SYMTAB_BLOCK Contents --------------------------- - -The ``TYPE_SYMTAB_BLOCK`` block (id 13) contains entries which map between -module-level named types and their corresponding type indices. - -.. _TST_CODE_ENTRY: - -TST_CODE_ENTRY Record -^^^^^^^^^^^^^^^^^^^^^ - -``[ENTRY, typeid, ...string...]`` - -The ``ENTRY`` record (code 1) contains a variable number of values, with the -first giving the type index of the designated type, and the remaining values -giving the character codes of the type name. Each entry corresponds to a single -named type. - .. _VALUE_SYMTAB_BLOCK: VALUE_SYMTAB_BLOCK Contents diff --git a/docs/BranchWeightMetadata.rst b/docs/BranchWeightMetadata.rst index 6cbcb0f0fb241..9e61d232d74b5 100644 --- a/docs/BranchWeightMetadata.rst +++ b/docs/BranchWeightMetadata.rst @@ -29,7 +29,7 @@ Supported Instructions Metadata is only assigned to the conditional branches. There are two extra operands for the true and the false branch. -.. code-block:: llvm +.. code-block:: none !0 = metadata !{ metadata !"branch_weights", @@ -43,7 +43,7 @@ operands for the true and the false branch. Branch weights are assigned to every case (including the ``default`` case which is always case #0). -.. code-block:: llvm +.. code-block:: none !0 = metadata !{ metadata !"branch_weights", @@ -56,7 +56,7 @@ is always case #0). Branch weights are assigned to every destination. -.. code-block:: llvm +.. code-block:: none !0 = metadata !{ metadata !"branch_weights", diff --git a/docs/CMake.rst b/docs/CMake.rst index 5d57bc98596b3..28b6ea3959b8c 100644 --- a/docs/CMake.rst +++ b/docs/CMake.rst @@ -186,6 +186,8 @@ CMake manual, or execute ``cmake --help-variable VARIABLE_NAME``. Sets the build type for ``make``-based generators. Possible values are Release, Debug, RelWithDebInfo and MinSizeRel. If you are using an IDE such as Visual Studio, you should use the IDE settings to set the build type. + Be aware that Release and RelWithDebInfo are not using the same optimization + level on most platform. **CMAKE_INSTALL_PREFIX**:PATH Path where LLVM will be installed if "make install" is invoked or the @@ -336,6 +338,14 @@ LLVM-specific variables will not be used. If the variable for an external project does not point to a valid path, then that project will not be built. +**LLVM_ENABLE_PROJECTS**:STRING + Semicolon-separated list of projects to build, or *all* for building all + (clang, libcxx, libcxxabi, lldb, compiler-rt, lld, polly) projects. + This flag assumes that projects are checked out side-by-side and not nested, + i.e. clang needs to be in parallel of llvm instead of nested in `llvm/tools`. + This feature allows to have one build for only LLVM and another for clang+llvm + using the same source checkout. + **LLVM_EXTERNAL_PROJECTS**:STRING Semicolon-separated list of additional external projects to build as part of llvm. For each project LLVM_EXTERNAL_<NAME>_SOURCE_DIR have to be specified @@ -358,6 +368,10 @@ LLVM-specific variables Enable building with zlib to support compression/uncompression in LLVM tools. Defaults to ON. +**LLVM_ENABLE_DIA_SDK**:BOOL + Enable building with MSVC DIA SDK for PDB debugging support. Available + only with MSVC. Defaults to ON. + **LLVM_USE_SANITIZER**:STRING Define the sanitizer used to build LLVM binaries and tests. Possible values are ``Address``, ``Memory``, ``MemoryWithOrigins``, ``Undefined``, ``Thread``, @@ -431,6 +445,11 @@ LLVM-specific variables Uses .svg files instead of .png files for graphs in the Doxygen output. Defaults to OFF. +**LLVM_INSTALL_DOXYGEN_HTML_DIR**:STRING + The path to install Doxygen-generated HTML documentation to. This path can + either be absolute or relative to the CMAKE_INSTALL_PREFIX. Defaults to + `share/doc/llvm/doxygen-html`. + **LLVM_ENABLE_SPHINX**:BOOL If specified, CMake will search for the ``sphinx-build`` executable and will make the ``SPHINX_OUTPUT_HTML`` and ``SPHINX_OUTPUT_MAN`` CMake options available. @@ -456,6 +475,16 @@ LLVM-specific variables If enabled then sphinx documentation warnings will be treated as errors. Defaults to ON. +**LLVM_INSTALL_SPHINX_HTML_DIR**:STRING + The path to install Sphinx-generated HTML documentation to. This path can + either be absolute or relative to the CMAKE_INSTALL_PREFIX. Defaults to + `share/doc/llvm/html`. + +**LLVM_INSTALL_OCAMLDOC_HTML_DIR**:STRING + The path to install OCamldoc-generated HTML documentation to. This path can + either be absolute or relative to the CMAKE_INSTALL_PREFIX. Defaults to + `share/doc/llvm/ocaml-html`. + **LLVM_CREATE_XCODE_TOOLCHAIN**:BOOL OS X Only: If enabled CMake will generate a target named 'install-xcode-toolchain'. This target will create a directory at diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt index eaa175062b614..ad2178dc5875f 100644 --- a/docs/CMakeLists.txt +++ b/docs/CMakeLists.txt @@ -93,8 +93,11 @@ if (LLVM_ENABLE_DOXYGEN) endif() if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY) - install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doxygen/html - DESTINATION docs/html) + # ./ suffix is needed to copy the contents of html directory without + # appending html/ into LLVM_INSTALL_DOXYGEN_HTML_DIR. + install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doxygen/html/. + COMPONENT doxygen-html + DESTINATION "${LLVM_INSTALL_DOXYGEN_HTML_DIR}") endif() endif() endif() @@ -115,7 +118,7 @@ if (LLVM_ENABLE_SPHINX) endif() list(FIND LLVM_BINDINGS_LIST ocaml uses_ocaml) -if( NOT uses_ocaml LESS 0 ) +if( NOT uses_ocaml LESS 0 AND LLVM_ENABLE_OCAMLDOC ) set(doc_targets ocaml_llvm ocaml_llvm_all_backends @@ -154,7 +157,10 @@ if( NOT uses_ocaml LESS 0 ) add_dependencies(ocaml_doc ${doc_targets}) if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY) - install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/ocamldoc/html - DESTINATION docs/ocaml/html) + # ./ suffix is needed to copy the contents of html directory without + # appending html/ into LLVM_INSTALL_OCAMLDOC_HTML_DIR. + install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/ocamldoc/html/. + COMPONENT ocamldoc-html + DESTINATION "${LLVM_INSTALL_OCAMLDOC_HTML_DIR}") endif() endif() diff --git a/docs/CMakePrimer.rst b/docs/CMakePrimer.rst index 034779022142a..1e3a09e4d98ab 100644 --- a/docs/CMakePrimer.rst +++ b/docs/CMakePrimer.rst @@ -246,11 +246,11 @@ In general CMake if blocks work the way you'd expect: .. code-block:: cmake if(<condition>) - .. do stuff + message("do stuff") elseif(<condition>) - .. do other stuff + message("do other stuff") else() - .. do other other stuff + message("do other other stuff") endif() The single most important thing to know about CMake's if blocks coming from a C @@ -265,7 +265,7 @@ The most common form of the CMake ``foreach`` block is: .. code-block:: cmake foreach(var ...) - .. do stuff + message("do stuff") endforeach() The variable argument portion of the ``foreach`` block can contain dereferenced diff --git a/docs/CodeGenerator.rst b/docs/CodeGenerator.rst index 2f5a27c00af38..6e5a54a592cee 100644 --- a/docs/CodeGenerator.rst +++ b/docs/CodeGenerator.rst @@ -2396,7 +2396,7 @@ the following exceptions. Callee saved registers are spilled after the frame is created. This allows the llvm epilog/prolog support to be common with other targets. The base pointer callee saved register r31 is saved in the TOC slot of linkage area. This simplifies allocation of space for the base pointer and -makes it convenient to locate programatically and during debugging. +makes it convenient to locate programmatically and during debugging. Dynamic Allocation ^^^^^^^^^^^^^^^^^^ @@ -2682,15 +2682,19 @@ Following notations are used for specifying relocation calculations: AMDGPU Backend generates *Elf64_Rela* relocation records with the following supported relocation types: - ===================== ===== ========== ==================== - Relocation type Value Field Calculation - ===================== ===== ========== ==================== - ``R_AMDGPU_NONE`` 0 ``none`` ``none`` - ``R_AMDGPU_ABS32_LO`` 1 ``word32`` (S + A) & 0xFFFFFFFF - ``R_AMDGPU_ABS32_HI`` 2 ``word32`` (S + A) >> 32 - ``R_AMDGPU_ABS64`` 3 ``word64`` S + A - ``R_AMDGPU_REL32`` 4 ``word32`` S + A - P - ``R_AMDGPU_REL64`` 5 ``word64`` S + A - P - ``R_AMDGPU_ABS32`` 6 ``word32`` S + A - ``R_AMDGPU_GOTPCREL`` 7 ``word32`` G + GOT + A - P - ===================== ===== ========== ==================== + ========================== ===== ========== ============================== + Relocation type Value Field Calculation + ========================== ===== ========== ============================== + ``R_AMDGPU_NONE`` 0 ``none`` ``none`` + ``R_AMDGPU_ABS32_LO`` 1 ``word32`` (S + A) & 0xFFFFFFFF + ``R_AMDGPU_ABS32_HI`` 2 ``word32`` (S + A) >> 32 + ``R_AMDGPU_ABS64`` 3 ``word64`` S + A + ``R_AMDGPU_REL32`` 4 ``word32`` S + A - P + ``R_AMDGPU_REL64`` 5 ``word64`` S + A - P + ``R_AMDGPU_ABS32`` 6 ``word32`` S + A + ``R_AMDGPU_GOTPCREL`` 7 ``word32`` G + GOT + A - P + ``R_AMDGPU_GOTPCREL32_LO`` 8 ``word32`` (G + GOT + A - P) & 0xFFFFFFFF + ``R_AMDGPU_GOTPCREL32_HI`` 9 ``word32`` (G + GOT + A - P) >> 32 + ``R_AMDGPU_REL32_LO`` 10 ``word32`` (S + A - P) & 0xFFFFFFFF + ``R_AMDGPU_REL32_HI`` 11 ``word32`` (S + A - P) >> 32 + ========================== ===== ========== ============================== diff --git a/docs/CodingStandards.rst b/docs/CodingStandards.rst index 91faadffea62e..722718bf4f163 100644 --- a/docs/CodingStandards.rst +++ b/docs/CodingStandards.rst @@ -83,7 +83,8 @@ Supported C++11 Language and Library Features While LLVM, Clang, and LLD use C++11, not all features are available in all of the toolchains which we support. The set of features supported for use in LLVM -is the intersection of those supported in MSVC 2013, GCC 4.7, and Clang 3.1. +is the intersection of those supported in the minimum requirements described +in the :doc:`GettingStarted` page, section `Software`. The ultimate definition of this set is what build bots with those respective toolchains accept. Don't argue with the build bots. However, we have some guidance below to help you know what to expect. @@ -126,17 +127,12 @@ unlikely to be supported by our host compilers. * Variadic templates: N2242_ * Explicit conversion operators: N2437_ * Defaulted and deleted functions: N2346_ - - * But not defaulted move constructors or move assignment operators, MSVC 2013 - cannot synthesize them. * Initializer lists: N2627_ * Delegating constructors: N1986_ * Default member initializers (non-static data member initializers): N2756_ - * Only use these for scalar members that would otherwise be left - uninitialized. Non-scalar members generally have appropriate default - constructors, and MSVC 2013 has problems when braced initializer lists are - involved. + * Feel free to use these wherever they make sense and where the `=` + syntax is allowed. Don't use braced initialization syntax. .. _N2118: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2118.html .. _N2439: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2439.htm @@ -188,7 +184,7 @@ you hit a type trait which doesn't work we can then add support to LLVM's traits header to emulate it. .. _the libstdc++ manual: - http://gcc.gnu.org/onlinedocs/gcc-4.7.3/libstdc++/manual/manual/status.html#status.iso.2011 + http://gcc.gnu.org/onlinedocs/gcc-4.8.0/libstdc++/manual/manual/status.html#status.iso.2011 Other Languages --------------- @@ -267,7 +263,7 @@ code can be distributed under and should not be modified in any way. The main body is a ``doxygen`` comment (identified by the ``///`` comment marker instead of the usual ``//``) describing the purpose of the file. The -first sentence or a passage beginning with ``\brief`` is used as an abstract. +first sentence (or a passage beginning with ``\brief``) is used as an abstract. Any additional information should be separated by a blank line. If an algorithm is being implemented or something tricky is going on, a reference to the paper where it is published should be included, as well as any notes or @@ -309,8 +305,10 @@ useful to use C style (``/* */``) comments however: #. When writing a source file that is used by a tool that only accepts C style comments. -To comment out a large block of code, use ``#if 0`` and ``#endif``. These nest -properly and are better behaved in general than C style comments. +Commenting out large blocks of code is discouraged, but if you really have to do +this (for documentation purposes or as a suggestion for debug printing), use +``#if 0`` and ``#endif``. These nest properly and are better behaved in general +than C style comments. Doxygen Use in Documentation Comments ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -320,8 +318,9 @@ comment. Include descriptive paragraphs for all public interfaces (public classes, member and non-member functions). Don't just restate the information that can -be inferred from the API name. The first sentence or a paragraph beginning -with ``\brief`` is used as an abstract. Put detailed discussion into separate +be inferred from the API name. The first sentence (or a paragraph beginning +with ``\brief``) is used as an abstract. Try to use a single sentence as the +``\brief`` adds visual clutter. Put detailed discussion into separate paragraphs. To refer to parameter names inside a paragraph, use the ``\p name`` command. @@ -349,7 +348,7 @@ A documentation comment that uses all Doxygen features in a preferred way: .. code-block:: c++ - /// \brief Does foo and bar. + /// Does foo and bar. /// /// Does not do foo the usual way if \p Baz is true. /// @@ -451,7 +450,7 @@ listed. We prefer these ``#include``\s to be listed in this order: #. Main Module Header #. Local/Private Headers -#. ``llvm/...`` +#. LLVM project/subproject headers (``clang/...``, ``lldb/...``, ``llvm/...``, etc) #. System ``#include``\s and each category should be sorted lexicographically by the full path. @@ -464,6 +463,16 @@ that the header does not have any hidden dependencies which are not explicitly ``#include``\d in the header, but should be. It is also a form of documentation in the ``.cpp`` file to indicate where the interfaces it implements are defined. +LLVM project and subproject headers should be grouped from most specific to least +specific, for the same reasons described above. For example, LLDB depends on +both clang and LLVM, and clang depends on LLVM. So an LLDB source file should +include ``lldb`` headers first, followed by ``clang`` headers, followed by +``llvm`` headers, to reduce the possibility (for example) of an LLDB header +accidentally picking up a missing include due to the previous inclusion of that +header in the main source file or some earlier header file. clang should +similarly include its own headers before including llvm headers. This rule +applies to all LLVM subprojects. + .. _fit into 80 columns: Source Code Width @@ -1156,7 +1165,7 @@ Here are some examples of good and bad names: // kind of factories. }; - Vehicle MakeVehicle(VehicleType Type) { + Vehicle makeVehicle(VehicleType Type) { VehicleMaker M; // Might be OK if having a short life-span. Tire Tmp1 = M.makeTire(); // Bad -- 'Tmp1' provides no information. Light Headlight = M.makeLight("head"); // Good -- descriptive. diff --git a/docs/CommandGuide/lit.rst b/docs/CommandGuide/lit.rst index b2da58ec02c13..7fc3455ddf690 100644 --- a/docs/CommandGuide/lit.rst +++ b/docs/CommandGuide/lit.rst @@ -324,6 +324,9 @@ executed, two important global variables are predefined: on the pipe fail. If this is not desired, setting this variable to false makes the test fail only if the last command in the pipe fails. + **available_features** A set of features that can be used in `XFAIL`, + `REQUIRES`, and `UNSUPPORTED` directives. + TEST DISCOVERY ~~~~~~~~~~~~~~ diff --git a/docs/CommandGuide/llvm-cov.rst b/docs/CommandGuide/llvm-cov.rst index 946b125a4529f..4c0354c0d608f 100644 --- a/docs/CommandGuide/llvm-cov.rst +++ b/docs/CommandGuide/llvm-cov.rst @@ -24,6 +24,7 @@ COMMANDS * :ref:`gcov <llvm-cov-gcov>` * :ref:`show <llvm-cov-show>` * :ref:`report <llvm-cov-report>` +* :ref:`export <llvm-cov-export>` .. program:: llvm-cov gcov @@ -166,14 +167,14 @@ SHOW COMMAND SYNOPSIS ^^^^^^^^ -:program:`llvm-cov show` [*options*] -instr-profile *PROFILE* *BIN* [*SOURCES*] +:program:`llvm-cov show` [*options*] -instr-profile *PROFILE* *BIN* [*-object BIN,...*] [[*-object BIN*]] [*SOURCES*] DESCRIPTION ^^^^^^^^^^^ -The :program:`llvm-cov show` command shows line by line coverage of a binary -*BIN* using the profile data *PROFILE*. It can optionally be filtered to only -show the coverage for the files listed in *SOURCES*. +The :program:`llvm-cov show` command shows line by line coverage of the +binaries *BIN*,... using the profile data *PROFILE*. It can optionally be +filtered to only show the coverage for the files listed in *SOURCES*. To use :program:`llvm-cov show`, you need a program that is compiled with instrumentation to emit profile and coverage data. To build such a program with @@ -182,7 +183,7 @@ flags. If linking with the ``clang`` driver, pass ``-fprofile-instr-generate`` to the link stage to make sure the necessary runtime libraries are linked in. The coverage information is stored in the built executable or library itself, -and this is what you should pass to :program:`llvm-cov show` as the *BIN* +and this is what you should pass to :program:`llvm-cov show` as a *BIN* argument. The profile data is generated by running this instrumented program normally. When the program exits it will write out a raw profile file, typically called ``default.profraw``, which can be converted to a format that @@ -240,6 +241,11 @@ OPTIONS Use the specified output format. The supported formats are: "text", "html". +.. option:: -tab-size=<TABSIZE> + + Replace tabs with <TABSIZE> spaces when preparing reports. Currently, this is + only supported for the html format. + .. option:: -output-dir=PATH Specify a directory to write coverage reports into. If the directory does not @@ -286,14 +292,14 @@ REPORT COMMAND SYNOPSIS ^^^^^^^^ -:program:`llvm-cov report` [*options*] -instr-profile *PROFILE* *BIN* [*SOURCES*] +:program:`llvm-cov report` [*options*] -instr-profile *PROFILE* *BIN* [*-object BIN,...*] [[*-object BIN*]] [*SOURCES*] DESCRIPTION ^^^^^^^^^^^ -The :program:`llvm-cov report` command displays a summary of the coverage of a -binary *BIN* using the profile data *PROFILE*. It can optionally be filtered to -only show the coverage for the files listed in *SOURCES*. +The :program:`llvm-cov report` command displays a summary of the coverage of +the binaries *BIN*,... using the profile data *PROFILE*. It can optionally be +filtered to only show the coverage for the files listed in *SOURCES*. If no source files are provided, a summary line is printed for each file in the coverage data. If any files are provided, summaries are shown for each function @@ -315,3 +321,35 @@ OPTIONS It is an error to specify an architecture that is not included in the universal binary or to use an architecture that does not match a non-universal binary. + +.. program:: llvm-cov export + +.. _llvm-cov-export: + +EXPORT COMMAND +-------------- + +SYNOPSIS +^^^^^^^^ + +:program:`llvm-cov export` [*options*] -instr-profile *PROFILE* *BIN* [*-object BIN,...*] [[*-object BIN*]] + +DESCRIPTION +^^^^^^^^^^^ + +The :program:`llvm-cov export` command exports regions, functions, expansions, +and summaries of the coverage of the binaries *BIN*,... using the profile data +*PROFILE* as JSON. + +For information on compiling programs for coverage and generating profile data, +see :ref:`llvm-cov-show`. + +OPTIONS +^^^^^^^ + +.. option:: -arch=<name> + + If the covered binary is a universal binary, select the architecture to use. + It is an error to specify an architecture that is not included in the + universal binary or to use an architecture that does not match a + non-universal binary. diff --git a/docs/CommandGuide/llvm-profdata.rst b/docs/CommandGuide/llvm-profdata.rst index f5508b5b2b8f2..bae0ff7d4ce07 100644 --- a/docs/CommandGuide/llvm-profdata.rst +++ b/docs/CommandGuide/llvm-profdata.rst @@ -106,6 +106,11 @@ OPTIONS conjunction with -instr. Defaults to false, since it can inhibit compiler optimization during PGO. +.. option:: -num-threads=N, -j=N + + Use N threads to perform profile merging. When N=0, llvm-profdata auto-detects + an appropriate number of threads to use. This is the default. + EXAMPLES ^^^^^^^^ Basic Usage diff --git a/docs/CommandLine.rst b/docs/CommandLine.rst index 556c302501e25..a660949881a48 100644 --- a/docs/CommandLine.rst +++ b/docs/CommandLine.rst @@ -355,8 +355,7 @@ library fill it in with the appropriate level directly, which is used like this: clEnumVal(g , "No optimizations, enable debugging"), clEnumVal(O1, "Enable trivial optimizations"), clEnumVal(O2, "Enable default optimizations"), - clEnumVal(O3, "Enable expensive optimizations"), - clEnumValEnd)); + clEnumVal(O3, "Enable expensive optimizations"))); ... if (OptimizationLevel >= O2) doPartialRedundancyElimination(...); @@ -364,8 +363,7 @@ library fill it in with the appropriate level directly, which is used like this: This declaration defines a variable "``OptimizationLevel``" of the "``OptLevel``" enum type. This variable can be assigned any of the values that -are listed in the declaration (Note that the declaration list must be terminated -with the "``clEnumValEnd``" argument!). The CommandLine library enforces that +are listed in the declaration. The CommandLine library enforces that the user can only specify one of the options, and it ensure that only valid enum values can be specified. The "``clEnumVal``" macros ensure that the command line arguments matched the enum values. With this option added, our help output @@ -401,8 +399,7 @@ program. Because of this, we can alternatively write this example like this: clEnumValN(Debug, "g", "No optimizations, enable debugging"), clEnumVal(O1 , "Enable trivial optimizations"), clEnumVal(O2 , "Enable default optimizations"), - clEnumVal(O3 , "Enable expensive optimizations"), - clEnumValEnd)); + clEnumVal(O3 , "Enable expensive optimizations"))); ... if (OptimizationLevel == Debug) outputDebugInfo(...); @@ -436,8 +433,7 @@ the code looks like this: cl::values( clEnumValN(nodebuginfo, "none", "disable debug information"), clEnumVal(quick, "enable quick debug information"), - clEnumVal(detailed, "enable detailed debug information"), - clEnumValEnd)); + clEnumVal(detailed, "enable detailed debug information"))); This definition defines an enumerated command line variable of type "``enum DebugLev``", which works exactly the same way as before. The difference here is @@ -498,8 +494,7 @@ Then define your "``cl::list``" variable: clEnumVal(dce , "Dead Code Elimination"), clEnumVal(constprop , "Constant Propagation"), clEnumValN(inlining, "inline", "Procedure Integration"), - clEnumVal(strip , "Strip Symbols"), - clEnumValEnd)); + clEnumVal(strip , "Strip Symbols"))); This defines a variable that is conceptually of the type "``std::vector<enum Opts>``". Thus, you can access it with standard vector @@ -558,8 +553,7 @@ Reworking the above list example, we could replace `cl::list`_ with `cl::bits`_: clEnumVal(dce , "Dead Code Elimination"), clEnumVal(constprop , "Constant Propagation"), clEnumValN(inlining, "inline", "Procedure Integration"), - clEnumVal(strip , "Strip Symbols"), - clEnumValEnd)); + clEnumVal(strip , "Strip Symbols"))); To test to see if ``constprop`` was specified, we can use the ``cl:bits::isSet`` function: @@ -967,11 +961,10 @@ This section describes the basic attributes that you can specify on options. .. _cl::values: * The **cl::values** attribute specifies the string-to-value mapping to be used - by the generic parser. It takes a **clEnumValEnd terminated** list of - (option, value, description) triplets that specify the option name, the value - mapped to, and the description shown in the ``-help`` for the tool. Because - the generic parser is used most frequently with enum values, two macros are - often useful: + by the generic parser. It takes a list of (option, value, description) + triplets that specify the option name, the value mapped to, and the + description shown in the ``-help`` for the tool. Because the generic parser + is used most frequently with enum values, two macros are often useful: #. The **clEnumVal** macro is used as a nice simple way to specify a triplet for an enum. This macro automatically makes the option name be the same as @@ -1296,8 +1289,7 @@ Here is an example of how the function could be used: int main(int argc, char **argv) { cl::OptionCategory AnotherCategory("Some options"); - StringMap<cl::Option*> Map; - cl::getRegisteredOptions(Map); + StringMap<cl::Option*> &Map = cl::getRegisteredOptions(); //Unhide useful option and put it in a different category assert(Map.count("print-all-options") > 0); diff --git a/docs/CompileCudaWithLLVM.rst b/docs/CompileCudaWithLLVM.rst index f57839cec9615..af681aeead662 100644 --- a/docs/CompileCudaWithLLVM.rst +++ b/docs/CompileCudaWithLLVM.rst @@ -1,6 +1,6 @@ -=================================== -Compiling CUDA C/C++ with LLVM -=================================== +========================= +Compiling CUDA with clang +========================= .. contents:: :local: @@ -8,104 +8,54 @@ Compiling CUDA C/C++ with LLVM Introduction ============ -This document contains the user guides and the internals of compiling CUDA -C/C++ with LLVM. It is aimed at both users who want to compile CUDA with LLVM -and developers who want to improve LLVM for GPUs. This document assumes a basic -familiarity with CUDA. Information about CUDA programming can be found in the +This document describes how to compile CUDA code with clang, and gives some +details about LLVM and clang's CUDA implementations. + +This document assumes a basic familiarity with CUDA. Information about CUDA +programming can be found in the `CUDA programming guide <http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html>`_. -How to Build LLVM with CUDA Support -=================================== - -CUDA support is still in development and works the best in the trunk version -of LLVM. Below is a quick summary of downloading and building the trunk -version. Consult the `Getting Started -<http://llvm.org/docs/GettingStarted.html>`_ page for more details on setting -up LLVM. - -#. Checkout LLVM - - .. code-block:: console - - $ cd where-you-want-llvm-to-live - $ svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm - -#. Checkout Clang +Compiling CUDA Code +=================== - .. code-block:: console +Prerequisites +------------- - $ cd where-you-want-llvm-to-live - $ cd llvm/tools - $ svn co http://llvm.org/svn/llvm-project/cfe/trunk clang +CUDA is supported in llvm 3.9, but it's still in active development, so we +recommend you `compile clang/LLVM from HEAD +<http://llvm.org/docs/GettingStarted.html>`_. -#. Configure and build LLVM and Clang +Before you build CUDA code, you'll need to have installed the appropriate +driver for your nvidia GPU and the CUDA SDK. See `NVIDIA's CUDA installation +guide <https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html>`_ +for details. Note that clang `does not support +<https://llvm.org/bugs/show_bug.cgi?id=26966>`_ the CUDA toolkit as installed +by many Linux package managers; you probably need to install nvidia's package. - .. code-block:: console +You will need CUDA 7.0, 7.5, or 8.0 to compile with clang. - $ cd where-you-want-llvm-to-live - $ mkdir build - $ cd build - $ cmake [options] .. - $ make +CUDA compilation is supported on Linux, and on MacOS as of XXXX-XX-XX. Windows +support is planned but not yet in place. -How to Compile CUDA C/C++ with LLVM -=================================== +Invoking clang +-------------- -We assume you have installed the CUDA driver and runtime. Consult the `NVIDIA -CUDA installation guide -<https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html>`_ if -you have not. - -Suppose you want to compile and run the following CUDA program (``axpy.cu``) -which multiplies a ``float`` array by a ``float`` scalar (AXPY). - -.. code-block:: c++ - - #include <iostream> - - __global__ void axpy(float a, float* x, float* y) { - y[threadIdx.x] = a * x[threadIdx.x]; - } +Invoking clang for CUDA compilation works similarly to compiling regular C++. +You just need to be aware of a few additional flags. - int main(int argc, char* argv[]) { - const int kDataLen = 4; +You can use `this <https://gist.github.com/855e277884eb6b388cd2f00d956c2fd4>`_ +program as a toy example. Save it as ``axpy.cu``. (Clang detects that you're +compiling CUDA code by noticing that your filename ends with ``.cu``. +Alternatively, you can pass ``-x cuda``.) - float a = 2.0f; - float host_x[kDataLen] = {1.0f, 2.0f, 3.0f, 4.0f}; - float host_y[kDataLen]; - - // Copy input data to device. - float* device_x; - float* device_y; - cudaMalloc(&device_x, kDataLen * sizeof(float)); - cudaMalloc(&device_y, kDataLen * sizeof(float)); - cudaMemcpy(device_x, host_x, kDataLen * sizeof(float), - cudaMemcpyHostToDevice); - - // Launch the kernel. - axpy<<<1, kDataLen>>>(a, device_x, device_y); - - // Copy output data to host. - cudaDeviceSynchronize(); - cudaMemcpy(host_y, device_y, kDataLen * sizeof(float), - cudaMemcpyDeviceToHost); - - // Print the results. - for (int i = 0; i < kDataLen; ++i) { - std::cout << "y[" << i << "] = " << host_y[i] << "\n"; - } - - cudaDeviceReset(); - return 0; - } - -The command line for compilation is similar to what you would use for C++. +To build and run, run the following commands, filling in the parts in angle +brackets as described below: .. code-block:: console - $ clang++ axpy.cu -o axpy --cuda-gpu-arch=<GPU arch> \ - -L<CUDA install path>/<lib64 or lib> \ + $ clang++ axpy.cu -o axpy --cuda-gpu-arch=<GPU arch> \ + -L<CUDA install path>/<lib64 or lib> \ -lcudart_static -ldl -lrt -pthread $ ./axpy y[0] = 2 @@ -113,43 +63,37 @@ The command line for compilation is similar to what you would use for C++. y[2] = 6 y[3] = 8 -``<CUDA install path>`` is the root directory where you installed CUDA SDK, -typically ``/usr/local/cuda``. ``<GPU arch>`` is `the compute capability of -your GPU <https://developer.nvidia.com/cuda-gpus>`_. For example, if you want -to run your program on a GPU with compute capability of 3.5, you should specify -``--cuda-gpu-arch=sm_35``. +On MacOS, replace `-lcudart_static` with `-lcudart`; otherwise, you may get +"CUDA driver version is insufficient for CUDA runtime version" errors when you +run your program. -Detecting clang vs NVCC -======================= +* ``<CUDA install path>`` -- the directory where you installed CUDA SDK. + Typically, ``/usr/local/cuda``. -Although clang's CUDA implementation is largely compatible with NVCC's, you may -still want to detect when you're compiling CUDA code specifically with clang. + Pass e.g. ``-L/usr/local/cuda/lib64`` if compiling in 64-bit mode; otherwise, + pass e.g. ``-L/usr/local/cuda/lib``. (In CUDA, the device code and host code + always have the same pointer widths, so if you're compiling 64-bit code for + the host, you're also compiling 64-bit code for the device.) -This is tricky, because NVCC may invoke clang as part of its own compilation -process! For example, NVCC uses the host compiler's preprocessor when -compiling for device code, and that host compiler may in fact be clang. +* ``<GPU arch>`` -- the `compute capability + <https://developer.nvidia.com/cuda-gpus>`_ of your GPU. For example, if you + want to run your program on a GPU with compute capability of 3.5, specify + ``--cuda-gpu-arch=sm_35``. -When clang is actually compiling CUDA code -- rather than being used as a -subtool of NVCC's -- it defines the ``__CUDA__`` macro. ``__CUDA_ARCH__`` is -defined only in device mode (but will be defined if NVCC is using clang as a -preprocessor). So you can use the following incantations to detect clang CUDA -compilation, in host and device modes: - -.. code-block:: c++ - - #if defined(__clang__) && defined(__CUDA__) && !defined(__CUDA_ARCH__) - // clang compiling CUDA code, host mode. - #endif + Note: You cannot pass ``compute_XX`` as an argument to ``--cuda-gpu-arch``; + only ``sm_XX`` is currently supported. However, clang always includes PTX in + its binaries, so e.g. a binary compiled with ``--cuda-gpu-arch=sm_30`` would be + forwards-compatible with e.g. ``sm_35`` GPUs. - #if defined(__clang__) && defined(__CUDA__) && defined(__CUDA_ARCH__) - // clang compiling CUDA code, device mode. - #endif + You can pass ``--cuda-gpu-arch`` multiple times to compile for multiple archs. -Both clang and nvcc define ``__CUDACC__`` during CUDA compilation. You can -detect NVCC specifically by looking for ``__NVCC__``. +The `-L` and `-l` flags only need to be passed when linking. When compiling, +you may also need to pass ``--cuda-path=/path/to/cuda`` if you didn't install +the CUDA SDK into ``/usr/local/cuda``, ``/usr/local/cuda-7.0``, or +``/usr/local/cuda-7.5``. Flags that control numerical code -================================= +--------------------------------- If you're using GPUs, you probably care about making numerical code run fast. GPU hardware allows for more control over numerical operations than most CPUs, @@ -188,70 +132,425 @@ Flags you may wish to tweak include: This is implied by ``-ffast-math``. +Standard library support +======================== + +In clang and nvcc, most of the C++ standard library is not supported on the +device side. + +``<math.h>`` and ``<cmath>`` +---------------------------- + +In clang, ``math.h`` and ``cmath`` are available and `pass +<https://github.com/llvm-mirror/test-suite/blob/master/External/CUDA/math_h.cu>`_ +`tests +<https://github.com/llvm-mirror/test-suite/blob/master/External/CUDA/cmath.cu>`_ +adapted from libc++'s test suite. + +In nvcc ``math.h`` and ``cmath`` are mostly available. Versions of ``::foof`` +in namespace std (e.g. ``std::sinf``) are not available, and where the standard +calls for overloads that take integral arguments, these are usually not +available. + +.. code-block:: c++ + + #include <math.h> + #include <cmath.h> + + // clang is OK with everything in this function. + __device__ void test() { + std::sin(0.); // nvcc - ok + std::sin(0); // nvcc - error, because no std::sin(int) override is available. + sin(0); // nvcc - same as above. + + sinf(0.); // nvcc - ok + std::sinf(0.); // nvcc - no such function + } + +``<std::complex>`` +------------------ + +nvcc does not officially support ``std::complex``. It's an error to use +``std::complex`` in ``__device__`` code, but it often works in ``__host__ +__device__`` code due to nvcc's interpretation of the "wrong-side rule" (see +below). However, we have heard from implementers that it's possible to get +into situations where nvcc will omit a call to an ``std::complex`` function, +especially when compiling without optimizations. + +As of 2016-11-16, clang supports ``std::complex`` without these caveats. It is +tested with libstdc++ 4.8.5 and newer, but is known to work only with libc++ +newer than 2016-11-16. + +``<algorithm>`` +--------------- + +In C++14, many useful functions from ``<algorithm>`` (notably, ``std::min`` and +``std::max``) become constexpr. You can therefore use these in device code, +when compiling with clang. + +Detecting clang vs NVCC from code +================================= + +Although clang's CUDA implementation is largely compatible with NVCC's, you may +still want to detect when you're compiling CUDA code specifically with clang. + +This is tricky, because NVCC may invoke clang as part of its own compilation +process! For example, NVCC uses the host compiler's preprocessor when +compiling for device code, and that host compiler may in fact be clang. + +When clang is actually compiling CUDA code -- rather than being used as a +subtool of NVCC's -- it defines the ``__CUDA__`` macro. ``__CUDA_ARCH__`` is +defined only in device mode (but will be defined if NVCC is using clang as a +preprocessor). So you can use the following incantations to detect clang CUDA +compilation, in host and device modes: + +.. code-block:: c++ + + #if defined(__clang__) && defined(__CUDA__) && !defined(__CUDA_ARCH__) + // clang compiling CUDA code, host mode. + #endif + + #if defined(__clang__) && defined(__CUDA__) && defined(__CUDA_ARCH__) + // clang compiling CUDA code, device mode. + #endif + +Both clang and nvcc define ``__CUDACC__`` during CUDA compilation. You can +detect NVCC specifically by looking for ``__NVCC__``. + +Dialect Differences Between clang and nvcc +========================================== + +There is no formal CUDA spec, and clang and nvcc speak slightly different +dialects of the language. Below, we describe some of the differences. + +This section is painful; hopefully you can skip this section and live your life +blissfully unaware. + +Compilation Models +------------------ + +Most of the differences between clang and nvcc stem from the different +compilation models used by clang and nvcc. nvcc uses *split compilation*, +which works roughly as follows: + + * Run a preprocessor over the input ``.cu`` file to split it into two source + files: ``H``, containing source code for the host, and ``D``, containing + source code for the device. + + * For each GPU architecture ``arch`` that we're compiling for, do: + + * Compile ``D`` using nvcc proper. The result of this is a ``ptx`` file for + ``P_arch``. + + * Optionally, invoke ``ptxas``, the PTX assembler, to generate a file, + ``S_arch``, containing GPU machine code (SASS) for ``arch``. + + * Invoke ``fatbin`` to combine all ``P_arch`` and ``S_arch`` files into a + single "fat binary" file, ``F``. + + * Compile ``H`` using an external host compiler (gcc, clang, or whatever you + like). ``F`` is packaged up into a header file which is force-included into + ``H``; nvcc generates code that calls into this header to e.g. launch + kernels. + +clang uses *merged parsing*. This is similar to split compilation, except all +of the host and device code is present and must be semantically-correct in both +compilation steps. + + * For each GPU architecture ``arch`` that we're compiling for, do: + + * Compile the input ``.cu`` file for device, using clang. ``__host__`` code + is parsed and must be semantically correct, even though we're not + generating code for the host at this time. + + The output of this step is a ``ptx`` file ``P_arch``. + + * Invoke ``ptxas`` to generate a SASS file, ``S_arch``. Note that, unlike + nvcc, clang always generates SASS code. + + * Invoke ``fatbin`` to combine all ``P_arch`` and ``S_arch`` files into a + single fat binary file, ``F``. + + * Compile ``H`` using clang. ``__device__`` code is parsed and must be + semantically correct, even though we're not generating code for the device + at this time. + + ``F`` is passed to this compilation, and clang includes it in a special ELF + section, where it can be found by tools like ``cuobjdump``. + +(You may ask at this point, why does clang need to parse the input file +multiple times? Why not parse it just once, and then use the AST to generate +code for the host and each device architecture? + +Unfortunately this can't work because we have to define different macros during +host compilation and during device compilation for each GPU architecture.) + +clang's approach allows it to be highly robust to C++ edge cases, as it doesn't +need to decide at an early stage which declarations to keep and which to throw +away. But it has some consequences you should be aware of. + +Overloading Based on ``__host__`` and ``__device__`` Attributes +--------------------------------------------------------------- + +Let "H", "D", and "HD" stand for "``__host__`` functions", "``__device__`` +functions", and "``__host__ __device__`` functions", respectively. Functions +with no attributes behave the same as H. + +nvcc does not allow you to create H and D functions with the same signature: + +.. code-block:: c++ + + // nvcc: error - function "foo" has already been defined + __host__ void foo() {} + __device__ void foo() {} + +However, nvcc allows you to "overload" H and D functions with different +signatures: + +.. code-block:: c++ + + // nvcc: no error + __host__ void foo(int) {} + __device__ void foo() {} + +In clang, the ``__host__`` and ``__device__`` attributes are part of a +function's signature, and so it's legal to have H and D functions with +(otherwise) the same signature: + +.. code-block:: c++ + + // clang: no error + __host__ void foo() {} + __device__ void foo() {} + +HD functions cannot be overloaded by H or D functions with the same signature: + +.. code-block:: c++ + + // nvcc: error - function "foo" has already been defined + // clang: error - redefinition of 'foo' + __host__ __device__ void foo() {} + __device__ void foo() {} + + // nvcc: no error + // clang: no error + __host__ __device__ void bar(int) {} + __device__ void bar() {} + +When resolving an overloaded function, clang considers the host/device +attributes of the caller and callee. These are used as a tiebreaker during +overload resolution. See `IdentifyCUDAPreference +<http://clang.llvm.org/doxygen/SemaCUDA_8cpp.html>`_ for the full set of rules, +but at a high level they are: + + * D functions prefer to call other Ds. HDs are given lower priority. + + * Similarly, H functions prefer to call other Hs, or ``__global__`` functions + (with equal priority). HDs are given lower priority. + + * HD functions prefer to call other HDs. + + When compiling for device, HDs will call Ds with lower priority than HD, and + will call Hs with still lower priority. If it's forced to call an H, the + program is malformed if we emit code for this HD function. We call this the + "wrong-side rule", see example below. + + The rules are symmetrical when compiling for host. + +Some examples: + +.. code-block:: c++ + + __host__ void foo(); + __device__ void foo(); + + __host__ void bar(); + __host__ __device__ void bar(); + + __host__ void test_host() { + foo(); // calls H overload + bar(); // calls H overload + } + + __device__ void test_device() { + foo(); // calls D overload + bar(); // calls HD overload + } + + __host__ __device__ void test_hd() { + foo(); // calls H overload when compiling for host, otherwise D overload + bar(); // always calls HD overload + } + +Wrong-side rule example: + +.. code-block:: c++ + + __host__ void host_only(); + + // We don't codegen inline functions unless they're referenced by a + // non-inline function. inline_hd1() is called only from the host side, so + // does not generate an error. inline_hd2() is called from the device side, + // so it generates an error. + inline __host__ __device__ void inline_hd1() { host_only(); } // no error + inline __host__ __device__ void inline_hd2() { host_only(); } // error + + __host__ void host_fn() { inline_hd1(); } + __device__ void device_fn() { inline_hd2(); } + + // This function is not inline, so it's always codegen'ed on both the host + // and the device. Therefore, it generates an error. + __host__ __device__ void not_inline_hd() { host_only(); } + +For the purposes of the wrong-side rule, templated functions also behave like +``inline`` functions: They aren't codegen'ed unless they're instantiated +(usually as part of the process of invoking them). + +clang's behavior with respect to the wrong-side rule matches nvcc's, except +nvcc only emits a warning for ``not_inline_hd``; device code is allowed to call +``not_inline_hd``. In its generated code, nvcc may omit ``not_inline_hd``'s +call to ``host_only`` entirely, or it may try to generate code for +``host_only`` on the device. What you get seems to depend on whether or not +the compiler chooses to inline ``host_only``. + +Member functions, including constructors, may be overloaded using H and D +attributes. However, destructors cannot be overloaded. + +Using a Different Class on Host/Device +-------------------------------------- + +Occasionally you may want to have a class with different host/device versions. + +If all of the class's members are the same on the host and device, you can just +provide overloads for the class's member functions. + +However, if you want your class to have different members on host/device, you +won't be able to provide working H and D overloads in both classes. In this +case, clang is likely to be unhappy with you. + +.. code-block:: c++ + + #ifdef __CUDA_ARCH__ + struct S { + __device__ void foo() { /* use device_only */ } + int device_only; + }; + #else + struct S { + __host__ void foo() { /* use host_only */ } + double host_only; + }; + + __device__ void test() { + S s; + // clang generates an error here, because during host compilation, we + // have ifdef'ed away the __device__ overload of S::foo(). The __device__ + // overload must be present *even during host compilation*. + S.foo(); + } + #endif + +We posit that you don't really want to have classes with different members on H +and D. For example, if you were to pass one of these as a parameter to a +kernel, it would have a different layout on H and D, so would not work +properly. + +To make code like this compatible with clang, we recommend you separate it out +into two classes. If you need to write code that works on both host and +device, consider writing an overloaded wrapper function that returns different +types on host and device. + +.. code-block:: c++ + + struct HostS { ... }; + struct DeviceS { ... }; + + __host__ HostS MakeStruct() { return HostS(); } + __device__ DeviceS MakeStruct() { return DeviceS(); } + + // Now host and device code can call MakeStruct(). + +Unfortunately, this idiom isn't compatible with nvcc, because it doesn't allow +you to overload based on the H/D attributes. Here's an idiom that works with +both clang and nvcc: + +.. code-block:: c++ + + struct HostS { ... }; + struct DeviceS { ... }; + + #ifdef __NVCC__ + #ifndef __CUDA_ARCH__ + __host__ HostS MakeStruct() { return HostS(); } + #else + __device__ DeviceS MakeStruct() { return DeviceS(); } + #endif + #else + __host__ HostS MakeStruct() { return HostS(); } + __device__ DeviceS MakeStruct() { return DeviceS(); } + #endif + + // Now host and device code can call MakeStruct(). + +Hopefully you don't have to do this sort of thing often. + Optimizations ============= -CPU and GPU have different design philosophies and architectures. For example, a -typical CPU has branch prediction, out-of-order execution, and is superscalar, -whereas a typical GPU has none of these. Due to such differences, an -optimization pipeline well-tuned for CPUs may be not suitable for GPUs. +Modern CPUs and GPUs are architecturally quite different, so code that's fast +on a CPU isn't necessarily fast on a GPU. We've made a number of changes to +LLVM to make it generate good GPU code. Among these changes are: -LLVM performs several general and CUDA-specific optimizations for GPUs. The -list below shows some of the more important optimizations for GPUs. Most of -them have been upstreamed to ``lib/Transforms/Scalar`` and -``lib/Target/NVPTX``. A few of them have not been upstreamed due to lack of a -customizable target-independent optimization pipeline. +* `Straight-line scalar optimizations <https://goo.gl/4Rb9As>`_ -- These + reduce redundancy within straight-line code. -* **Straight-line scalar optimizations**. These optimizations reduce redundancy - in straight-line code. Details can be found in the `design document for - straight-line scalar optimizations <https://goo.gl/4Rb9As>`_. +* `Aggressive speculative execution + <http://llvm.org/docs/doxygen/html/SpeculativeExecution_8cpp_source.html>`_ + -- This is mainly for promoting straight-line scalar optimizations, which are + most effective on code along dominator paths. -* **Inferring memory spaces**. `This optimization - <https://github.com/llvm-mirror/llvm/blob/master/lib/Target/NVPTX/NVPTXInferAddressSpaces.cpp>`_ - infers the memory space of an address so that the backend can emit faster - special loads and stores from it. +* `Memory space inference + <http://llvm.org/doxygen/NVPTXInferAddressSpaces_8cpp_source.html>`_ -- + In PTX, we can operate on pointers that are in a paricular "address space" + (global, shared, constant, or local), or we can operate on pointers in the + "generic" address space, which can point to anything. Operations in a + non-generic address space are faster, but pointers in CUDA are not explicitly + annotated with their address space, so it's up to LLVM to infer it where + possible. -* **Aggressive loop unrooling and function inlining**. Loop unrolling and - function inlining need to be more aggressive for GPUs than for CPUs because - control flow transfer in GPU is more expensive. They also promote other - optimizations such as constant propagation and SROA which sometimes speed up - code by over 10x. An empirical inline threshold for GPUs is 1100. This - configuration has yet to be upstreamed with a target-specific optimization - pipeline. LLVM also provides `loop unrolling pragmas - <http://clang.llvm.org/docs/AttributeReference.html#pragma-unroll-pragma-nounroll>`_ - and ``__attribute__((always_inline))`` for programmers to force unrolling and - inling. +* `Bypassing 64-bit divides + <http://llvm.org/docs/doxygen/html/BypassSlowDivision_8cpp_source.html>`_ -- + This was an existing optimization that we enabled for the PTX backend. -* **Aggressive speculative execution**. `This transformation - <http://llvm.org/docs/doxygen/html/SpeculativeExecution_8cpp_source.html>`_ is - mainly for promoting straight-line scalar optimizations which are most - effective on code along dominator paths. + 64-bit integer divides are much slower than 32-bit ones on NVIDIA GPUs. + Many of the 64-bit divides in our benchmarks have a divisor and dividend + which fit in 32-bits at runtime. This optimization provides a fast path for + this common case. -* **Memory-space alias analysis**. `This alias analysis - <http://reviews.llvm.org/D12414>`_ infers that two pointers in different - special memory spaces do not alias. It has yet to be integrated to the new - alias analysis infrastructure; the new infrastructure does not run - target-specific alias analysis. +* Aggressive loop unrooling and function inlining -- Loop unrolling and + function inlining need to be more aggressive for GPUs than for CPUs because + control flow transfer in GPU is more expensive. More aggressive unrolling and + inlining also promote other optimizations, such as constant propagation and + SROA, which sometimes speed up code by over 10x. -* **Bypassing 64-bit divides**. `An existing optimization - <http://llvm.org/docs/doxygen/html/BypassSlowDivision_8cpp_source.html>`_ - enabled in the NVPTX backend. 64-bit integer divides are much slower than - 32-bit ones on NVIDIA GPUs due to lack of a divide unit. Many of the 64-bit - divides in our benchmarks have a divisor and dividend which fit in 32-bits at - runtime. This optimization provides a fast path for this common case. + (Programmers can force unrolling and inline using clang's `loop unrolling pragmas + <http://clang.llvm.org/docs/AttributeReference.html#pragma-unroll-pragma-nounroll>`_ + and ``__attribute__((always_inline))``.) Publication =========== +The team at Google published a paper in CGO 2016 detailing the optimizations +they'd made to clang/LLVM. Note that "gpucc" is no longer a meaningful name: +The relevant tools are now just vanilla clang/LLVM. + | `gpucc: An Open-Source GPGPU Compiler <http://dl.acm.org/citation.cfm?id=2854041>`_ | Jingyue Wu, Artem Belevich, Eli Bendersky, Mark Heffernan, Chris Leary, Jacques Pienaar, Bjarke Roune, Rob Springer, Xuetian Weng, Robert Hundt | *Proceedings of the 2016 International Symposium on Code Generation and Optimization (CGO 2016)* -| `Slides for the CGO talk <http://wujingyue.com/docs/gpucc-talk.pdf>`_ - -Tutorial -======== - -`CGO 2016 gpucc tutorial <http://wujingyue.com/docs/gpucc-tutorial.pdf>`_ +| +| `Slides from the CGO talk <http://wujingyue.com/docs/gpucc-talk.pdf>`_ +| +| `Tutorial given at CGO <http://wujingyue.com/docs/gpucc-tutorial.pdf>`_ Obtaining Help ============== diff --git a/docs/CompilerWriterInfo.rst b/docs/CompilerWriterInfo.rst index 5ae47ea89fe2c..8ce999033b7f6 100644 --- a/docs/CompilerWriterInfo.rst +++ b/docs/CompilerWriterInfo.rst @@ -18,9 +18,9 @@ AArch64 & ARM * `ARMv8-A Architecture Reference Manual <http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0487a.h/index.html>`_ (authentication required, free sign-up). This document covers both AArch64 and ARM instructions -* `ARMv7-M Architecture Reference Manual` <http://infocenter.arm.com/help/topic/com.arm.doc.ddi0403e.b/index.html>`_ (authentication required, free sign-up). This covers the Thumb2-only microcontrollers +* `ARMv7-M Architecture Reference Manual <http://infocenter.arm.com/help/topic/com.arm.doc.ddi0403e.b/index.html>`_ (authentication required, free sign-up). This covers the Thumb2-only microcontrollers -* `ARMv6-M Architecture Reference Manual` <http://infocenter.arm.com/help/topic/com.arm.doc.ddi0419c/index.html>_ (authentication required, free sign-up). This covers the Thumb1-only microcontrollers +* `ARMv6-M Architecture Reference Manual <http://infocenter.arm.com/help/topic/com.arm.doc.ddi0419c/index.html>`_ (authentication required, free sign-up). This covers the Thumb1-only microcontrollers * `ARM C Language Extensions <http://infocenter.arm.com/help/topic/com.arm.doc.ihi0053c/IHI0053C_acle_2_0.pdf>`_ @@ -31,10 +31,16 @@ Itanium (ia64) * `Itanium documentation <http://developer.intel.com/design/itanium2/documentation.htm>`_ +Lanai +----- + +* `Lanai Instruction Set Architecture <http://g.co/lanai/isa>`_ + + MIPS ---- -* `MIPS Processor Architecture <http://imgtec.com/mips/mips-architectures.asp>`_ +* `MIPS Processor Architecture <https://imgtec.com/mips/architectures/>`_ * `MIPS 64-bit ELF Object File Specification <http://techpubs.sgi.com/library/manuals/4000/007-4658-001/pdf/007-4658-001.pdf>`_ @@ -72,8 +78,14 @@ AMDGPU * `AMD Cayman/Trinity shader ISA <http://developer.amd.com/wordpress/media/2012/10/AMD_HD_6900_Series_Instruction_Set_Architecture.pdf>`_ * `AMD Southern Islands Series ISA <http://developer.amd.com/wordpress/media/2012/12/AMD_Southern_Islands_Instruction_Set_Architecture.pdf>`_ * `AMD Sea Islands Series ISA <http://developer.amd.com/wordpress/media/2013/07/AMD_Sea_Islands_Instruction_Set_Architecture.pdf>`_ +* `AMD GCN3 Instruction Set Architecture <http://amd-dev.wpengine.netdna-cdn.com/wordpress/media/2013/12/AMD_GCN3_Instruction_Set_Architecture_rev1.1.pdf>`__ * `AMD GPU Programming Guide <http://developer.amd.com/download/AMD_Accelerated_Parallel_Processing_OpenCL_Programming_Guide.pdf>`_ * `AMD Compute Resources <http://developer.amd.com/tools/heterogeneous-computing/amd-accelerated-parallel-processing-app-sdk/documentation/>`_ +* `AMDGPU Compute Application Binary Interface <https://github.com/RadeonOpenCompute/ROCm-ComputeABI-Doc/blob/master/AMDGPU-ABI.md>`__ + +RISC-V +------ +* `RISC-V User-Level ISA Specification <https://riscv.org/specifications/>`_ SPARC ----- @@ -90,7 +102,7 @@ SystemZ X86 --- -* `AMD processor manuals <http://www.amd.com/us-en/Processors/TechnicalResources/0,,30_182_739,00.html>`_ +* `AMD processor manuals <http://developer.amd.com/resources/developer-guides-manuals/>`_ * `Intel 64 and IA-32 manuals <http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html>`_ * `Intel Itanium documentation <http://www.intel.com/design/itanium/documentation.htm?iid=ipp_srvr_proc_itanium2+techdocs>`_ * `X86 and X86-64 SysV psABI <https://github.com/hjl-tools/x86-psABI/wiki/X86-psABI>`_ @@ -102,6 +114,11 @@ XCore * `The XMOS XS1 Architecture (ISA) <https://www.xmos.com/en/download/public/The-XMOS-XS1-Architecture%28X7879A%29.pdf>`_ * `Tools Development Guide (includes ABI) <https://www.xmos.com/download/public/Tools-Development-Guide%28X9114A%29.pdf>`_ +Hexagon +------- + +* `Hexagon Programmer's Reference Manuals and Hexagon ABI Specification (registration required, free sign-up) <https://developer.qualcomm.com/software/hexagon-dsp-sdk/tools>`_ + Other relevant lists -------------------- diff --git a/docs/Coroutines.rst b/docs/Coroutines.rst new file mode 100644 index 0000000000000..0e7cde7aa38ba --- /dev/null +++ b/docs/Coroutines.rst @@ -0,0 +1,1244 @@ +===================================== +Coroutines in LLVM +===================================== + +.. contents:: + :local: + :depth: 3 + +.. warning:: + This is a work in progress. Compatibility across LLVM releases is not + guaranteed. + +Introduction +============ + +.. _coroutine handle: + +LLVM coroutines are functions that have one or more `suspend points`_. +When a suspend point is reached, the execution of a coroutine is suspended and +control is returned back to its caller. A suspended coroutine can be resumed +to continue execution from the last suspend point or it can be destroyed. + +In the following example, we call function `f` (which may or may not be a +coroutine itself) that returns a handle to a suspended coroutine +(**coroutine handle**) that is used by `main` to resume the coroutine twice and +then destroy it: + +.. code-block:: llvm + + define i32 @main() { + entry: + %hdl = call i8* @f(i32 4) + call void @llvm.coro.resume(i8* %hdl) + call void @llvm.coro.resume(i8* %hdl) + call void @llvm.coro.destroy(i8* %hdl) + ret i32 0 + } + +.. _coroutine frame: + +In addition to the function stack frame which exists when a coroutine is +executing, there is an additional region of storage that contains objects that +keep the coroutine state when a coroutine is suspended. This region of storage +is called **coroutine frame**. It is created when a coroutine is called and +destroyed when a coroutine runs to completion or destroyed by a call to +the `coro.destroy`_ intrinsic. + +An LLVM coroutine is represented as an LLVM function that has calls to +`coroutine intrinsics`_ defining the structure of the coroutine. +After lowering, a coroutine is split into several +functions that represent three different ways of how control can enter the +coroutine: + +1. a ramp function, which represents an initial invocation of the coroutine that + creates the coroutine frame and executes the coroutine code until it + encounters a suspend point or reaches the end of the function; + +2. a coroutine resume function that is invoked when the coroutine is resumed; + +3. a coroutine destroy function that is invoked when the coroutine is destroyed. + +.. note:: Splitting out resume and destroy functions are just one of the + possible ways of lowering the coroutine. We chose it for initial + implementation as it matches closely the mental model and results in + reasonably nice code. + +Coroutines by Example +===================== + +Coroutine Representation +------------------------ + +Let's look at an example of an LLVM coroutine with the behavior sketched +by the following pseudo-code. + +.. code-block:: c++ + + void *f(int n) { + for(;;) { + print(n++); + <suspend> // returns a coroutine handle on first suspend + } + } + +This coroutine calls some function `print` with value `n` as an argument and +suspends execution. Every time this coroutine resumes, it calls `print` again with an argument one bigger than the last time. This coroutine never completes by itself and must be destroyed explicitly. If we use this coroutine with +a `main` shown in the previous section. It will call `print` with values 4, 5 +and 6 after which the coroutine will be destroyed. + +The LLVM IR for this coroutine looks like this: + +.. code-block:: none + + define i8* @f(i32 %n) { + entry: + %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null) + %size = call i32 @llvm.coro.size.i32() + %alloc = call i8* @malloc(i32 %size) + %hdl = call noalias i8* @llvm.coro.begin(token %id, i8* %alloc) + br label %loop + loop: + %n.val = phi i32 [ %n, %entry ], [ %inc, %loop ] + %inc = add nsw i32 %n.val, 1 + call void @print(i32 %n.val) + %0 = call i8 @llvm.coro.suspend(token none, i1 false) + switch i8 %0, label %suspend [i8 0, label %loop + i8 1, label %cleanup] + cleanup: + %mem = call i8* @llvm.coro.free(token %id, i8* %hdl) + call void @free(i8* %mem) + br label %suspend + suspend: + call void @llvm.coro.end(i8* %hdl, i1 false) + ret i8* %hdl + } + +The `entry` block establishes the coroutine frame. The `coro.size`_ intrinsic is +lowered to a constant representing the size required for the coroutine frame. +The `coro.begin`_ intrinsic initializes the coroutine frame and returns the +coroutine handle. The second parameter of `coro.begin` is given a block of memory +to be used if the coroutine frame needs to be allocated dynamically. +The `coro.id`_ intrinsic serves as coroutine identity useful in cases when the +`coro.begin`_ intrinsic get duplicated by optimization passes such as +jump-threading. + +The `cleanup` block destroys the coroutine frame. The `coro.free`_ intrinsic, +given the coroutine handle, returns a pointer of the memory block to be freed or +`null` if the coroutine frame was not allocated dynamically. The `cleanup` +block is entered when coroutine runs to completion by itself or destroyed via +call to the `coro.destroy`_ intrinsic. + +The `suspend` block contains code to be executed when coroutine runs to +completion or suspended. The `coro.end`_ intrinsic marks the point where +a coroutine needs to return control back to the caller if it is not an initial +invocation of the coroutine. + +The `loop` blocks represents the body of the coroutine. The `coro.suspend`_ +intrinsic in combination with the following switch indicates what happens to +control flow when a coroutine is suspended (default case), resumed (case 0) or +destroyed (case 1). + +Coroutine Transformation +------------------------ + +One of the steps of coroutine lowering is building the coroutine frame. The +def-use chains are analyzed to determine which objects need be kept alive across +suspend points. In the coroutine shown in the previous section, use of virtual register +`%n.val` is separated from the definition by a suspend point, therefore, it +cannot reside on the stack frame since the latter goes away once the coroutine +is suspended and control is returned back to the caller. An i32 slot is +allocated in the coroutine frame and `%n.val` is spilled and reloaded from that +slot as needed. + +We also store addresses of the resume and destroy functions so that the +`coro.resume` and `coro.destroy` intrinsics can resume and destroy the coroutine +when its identity cannot be determined statically at compile time. For our +example, the coroutine frame will be: + +.. code-block:: text + + %f.frame = type { void (%f.frame*)*, void (%f.frame*)*, i32 } + +After resume and destroy parts are outlined, function `f` will contain only the +code responsible for creation and initialization of the coroutine frame and +execution of the coroutine until a suspend point is reached: + +.. code-block:: none + + define i8* @f(i32 %n) { + entry: + %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null) + %alloc = call noalias i8* @malloc(i32 24) + %0 = call noalias i8* @llvm.coro.begin(token %id, i8* %alloc) + %frame = bitcast i8* %0 to %f.frame* + %1 = getelementptr %f.frame, %f.frame* %frame, i32 0, i32 0 + store void (%f.frame*)* @f.resume, void (%f.frame*)** %1 + %2 = getelementptr %f.frame, %f.frame* %frame, i32 0, i32 1 + store void (%f.frame*)* @f.destroy, void (%f.frame*)** %2 + + %inc = add nsw i32 %n, 1 + %inc.spill.addr = getelementptr inbounds %f.Frame, %f.Frame* %FramePtr, i32 0, i32 2 + store i32 %inc, i32* %inc.spill.addr + call void @print(i32 %n) + + ret i8* %frame + } + +Outlined resume part of the coroutine will reside in function `f.resume`: + +.. code-block:: llvm + + define internal fastcc void @f.resume(%f.frame* %frame.ptr.resume) { + entry: + %inc.spill.addr = getelementptr %f.frame, %f.frame* %frame.ptr.resume, i64 0, i32 2 + %inc.spill = load i32, i32* %inc.spill.addr, align 4 + %inc = add i32 %n.val, 1 + store i32 %inc, i32* %inc.spill.addr, align 4 + tail call void @print(i32 %inc) + ret void + } + +Whereas function `f.destroy` will contain the cleanup code for the coroutine: + +.. code-block:: llvm + + define internal fastcc void @f.destroy(%f.frame* %frame.ptr.destroy) { + entry: + %0 = bitcast %f.frame* %frame.ptr.destroy to i8* + tail call void @free(i8* %0) + ret void + } + +Avoiding Heap Allocations +------------------------- + +A particular coroutine usage pattern, which is illustrated by the `main` +function in the overview section, where a coroutine is created, manipulated and +destroyed by the same calling function, is common for coroutines implementing +RAII idiom and is suitable for allocation elision optimization which avoid +dynamic allocation by storing the coroutine frame as a static `alloca` in its +caller. + +In the entry block, we will call `coro.alloc`_ intrinsic that will return `true` +when dynamic allocation is required, and `false` if dynamic allocation is +elided. + +.. code-block:: none + + entry: + %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null) + %need.dyn.alloc = call i1 @llvm.coro.alloc(token %id) + br i1 %need.dyn.alloc, label %dyn.alloc, label %coro.begin + dyn.alloc: + %size = call i32 @llvm.coro.size.i32() + %alloc = call i8* @CustomAlloc(i32 %size) + br label %coro.begin + coro.begin: + %phi = phi i8* [ null, %entry ], [ %alloc, %dyn.alloc ] + %hdl = call noalias i8* @llvm.coro.begin(token %id, i8* %phi) + +In the cleanup block, we will make freeing the coroutine frame conditional on +`coro.free`_ intrinsic. If allocation is elided, `coro.free`_ returns `null` +thus skipping the deallocation code: + +.. code-block:: text + + cleanup: + %mem = call i8* @llvm.coro.free(token %id, i8* %hdl) + %need.dyn.free = icmp ne i8* %mem, null + br i1 %need.dyn.free, label %dyn.free, label %if.end + dyn.free: + call void @CustomFree(i8* %mem) + br label %if.end + if.end: + ... + +With allocations and deallocations represented as described as above, after +coroutine heap allocation elision optimization, the resulting main will be: + +.. code-block:: llvm + + define i32 @main() { + entry: + call void @print(i32 4) + call void @print(i32 5) + call void @print(i32 6) + ret i32 0 + } + +Multiple Suspend Points +----------------------- + +Let's consider the coroutine that has more than one suspend point: + +.. code-block:: c++ + + void *f(int n) { + for(;;) { + print(n++); + <suspend> + print(-n); + <suspend> + } + } + +Matching LLVM code would look like (with the rest of the code remaining the same +as the code in the previous section): + +.. code-block:: text + + loop: + %n.addr = phi i32 [ %n, %entry ], [ %inc, %loop.resume ] + call void @print(i32 %n.addr) #4 + %2 = call i8 @llvm.coro.suspend(token none, i1 false) + switch i8 %2, label %suspend [i8 0, label %loop.resume + i8 1, label %cleanup] + loop.resume: + %inc = add nsw i32 %n.addr, 1 + %sub = xor i32 %n.addr, -1 + call void @print(i32 %sub) + %3 = call i8 @llvm.coro.suspend(token none, i1 false) + switch i8 %3, label %suspend [i8 0, label %loop + i8 1, label %cleanup] + +In this case, the coroutine frame would include a suspend index that will +indicate at which suspend point the coroutine needs to resume. The resume +function will use an index to jump to an appropriate basic block and will look +as follows: + +.. code-block:: llvm + + define internal fastcc void @f.Resume(%f.Frame* %FramePtr) { + entry.Resume: + %index.addr = getelementptr inbounds %f.Frame, %f.Frame* %FramePtr, i64 0, i32 2 + %index = load i8, i8* %index.addr, align 1 + %switch = icmp eq i8 %index, 0 + %n.addr = getelementptr inbounds %f.Frame, %f.Frame* %FramePtr, i64 0, i32 3 + %n = load i32, i32* %n.addr, align 4 + br i1 %switch, label %loop.resume, label %loop + + loop.resume: + %sub = xor i32 %n, -1 + call void @print(i32 %sub) + br label %suspend + loop: + %inc = add nsw i32 %n, 1 + store i32 %inc, i32* %n.addr, align 4 + tail call void @print(i32 %inc) + br label %suspend + + suspend: + %storemerge = phi i8 [ 0, %loop ], [ 1, %loop.resume ] + store i8 %storemerge, i8* %index.addr, align 1 + ret void + } + +If different cleanup code needs to get executed for different suspend points, +a similar switch will be in the `f.destroy` function. + +.. note :: + + Using suspend index in a coroutine state and having a switch in `f.resume` and + `f.destroy` is one of the possible implementation strategies. We explored + another option where a distinct `f.resume1`, `f.resume2`, etc. are created for + every suspend point, and instead of storing an index, the resume and destroy + function pointers are updated at every suspend. Early testing showed that the + current approach is easier on the optimizer than the latter so it is a + lowering strategy implemented at the moment. + +Distinct Save and Suspend +------------------------- + +In the previous example, setting a resume index (or some other state change that +needs to happen to prepare a coroutine for resumption) happens at the same time as +a suspension of a coroutine. However, in certain cases, it is necessary to control +when coroutine is prepared for resumption and when it is suspended. + +In the following example, a coroutine represents some activity that is driven +by completions of asynchronous operations `async_op1` and `async_op2` which get +a coroutine handle as a parameter and resume the coroutine once async +operation is finished. + +.. code-block:: text + + void g() { + for (;;) + if (cond()) { + async_op1(<coroutine-handle>); // will resume once async_op1 completes + <suspend> + do_one(); + } + else { + async_op2(<coroutine-handle>); // will resume once async_op2 completes + <suspend> + do_two(); + } + } + } + +In this case, coroutine should be ready for resumption prior to a call to +`async_op1` and `async_op2`. The `coro.save`_ intrinsic is used to indicate a +point when coroutine should be ready for resumption (namely, when a resume index +should be stored in the coroutine frame, so that it can be resumed at the +correct resume point): + +.. code-block:: text + + if.true: + %save1 = call token @llvm.coro.save(i8* %hdl) + call void async_op1(i8* %hdl) + %suspend1 = call i1 @llvm.coro.suspend(token %save1, i1 false) + switch i8 %suspend1, label %suspend [i8 0, label %resume1 + i8 1, label %cleanup] + if.false: + %save2 = call token @llvm.coro.save(i8* %hdl) + call void async_op2(i8* %hdl) + %suspend2 = call i1 @llvm.coro.suspend(token %save2, i1 false) + switch i8 %suspend1, label %suspend [i8 0, label %resume2 + i8 1, label %cleanup] + +.. _coroutine promise: + +Coroutine Promise +----------------- + +A coroutine author or a frontend may designate a distinguished `alloca` that can +be used to communicate with the coroutine. This distinguished alloca is called +**coroutine promise** and is provided as the second parameter to the +`coro.id`_ intrinsic. + +The following coroutine designates a 32 bit integer `promise` and uses it to +store the current value produced by a coroutine. + +.. code-block:: text + + define i8* @f(i32 %n) { + entry: + %promise = alloca i32 + %pv = bitcast i32* %promise to i8* + %id = call token @llvm.coro.id(i32 0, i8* %pv, i8* null, i8* null) + %need.dyn.alloc = call i1 @llvm.coro.alloc(token %id) + br i1 %need.dyn.alloc, label %dyn.alloc, label %coro.begin + dyn.alloc: + %size = call i32 @llvm.coro.size.i32() + %alloc = call i8* @malloc(i32 %size) + br label %coro.begin + coro.begin: + %phi = phi i8* [ null, %entry ], [ %alloc, %dyn.alloc ] + %hdl = call noalias i8* @llvm.coro.begin(token %id, i8* %phi) + br label %loop + loop: + %n.val = phi i32 [ %n, %coro.begin ], [ %inc, %loop ] + %inc = add nsw i32 %n.val, 1 + store i32 %n.val, i32* %promise + %0 = call i8 @llvm.coro.suspend(token none, i1 false) + switch i8 %0, label %suspend [i8 0, label %loop + i8 1, label %cleanup] + cleanup: + %mem = call i8* @llvm.coro.free(token %id, i8* %hdl) + call void @free(i8* %mem) + br label %suspend + suspend: + call void @llvm.coro.end(i8* %hdl, i1 false) + ret i8* %hdl + } + +A coroutine consumer can rely on the `coro.promise`_ intrinsic to access the +coroutine promise. + +.. code-block:: llvm + + define i32 @main() { + entry: + %hdl = call i8* @f(i32 4) + %promise.addr.raw = call i8* @llvm.coro.promise(i8* %hdl, i32 4, i1 false) + %promise.addr = bitcast i8* %promise.addr.raw to i32* + %val0 = load i32, i32* %promise.addr + call void @print(i32 %val0) + call void @llvm.coro.resume(i8* %hdl) + %val1 = load i32, i32* %promise.addr + call void @print(i32 %val1) + call void @llvm.coro.resume(i8* %hdl) + %val2 = load i32, i32* %promise.addr + call void @print(i32 %val2) + call void @llvm.coro.destroy(i8* %hdl) + ret i32 0 + } + +After example in this section is compiled, result of the compilation will be: + +.. code-block:: llvm + + define i32 @main() { + entry: + tail call void @print(i32 4) + tail call void @print(i32 5) + tail call void @print(i32 6) + ret i32 0 + } + +.. _final: +.. _final suspend: + +Final Suspend +------------- + +A coroutine author or a frontend may designate a particular suspend to be final, +by setting the second argument of the `coro.suspend`_ intrinsic to `true`. +Such a suspend point has two properties: + +* it is possible to check whether a suspended coroutine is at the final suspend + point via `coro.done`_ intrinsic; + +* a resumption of a coroutine stopped at the final suspend point leads to + undefined behavior. The only possible action for a coroutine at a final + suspend point is destroying it via `coro.destroy`_ intrinsic. + +From the user perspective, the final suspend point represents an idea of a +coroutine reaching the end. From the compiler perspective, it is an optimization +opportunity for reducing number of resume points (and therefore switch cases) in +the resume function. + +The following is an example of a function that keeps resuming the coroutine +until the final suspend point is reached after which point the coroutine is +destroyed: + +.. code-block:: llvm + + define i32 @main() { + entry: + %hdl = call i8* @f(i32 4) + br label %while + while: + call void @llvm.coro.resume(i8* %hdl) + %done = call i1 @llvm.coro.done(i8* %hdl) + br i1 %done, label %end, label %while + end: + call void @llvm.coro.destroy(i8* %hdl) + ret i32 0 + } + +Usually, final suspend point is a frontend injected suspend point that does not +correspond to any explicitly authored suspend point of the high level language. +For example, for a Python generator that has only one suspend point: + +.. code-block:: python + + def coroutine(n): + for i in range(n): + yield i + +Python frontend would inject two more suspend points, so that the actual code +looks like this: + +.. code-block:: c + + void* coroutine(int n) { + int current_value; + <designate current_value to be coroutine promise> + <SUSPEND> // injected suspend point, so that the coroutine starts suspended + for (int i = 0; i < n; ++i) { + current_value = i; <SUSPEND>; // corresponds to "yield i" + } + <SUSPEND final=true> // injected final suspend point + } + +and python iterator `__next__` would look like: + +.. code-block:: c++ + + int __next__(void* hdl) { + coro.resume(hdl); + if (coro.done(hdl)) throw StopIteration(); + return *(int*)coro.promise(hdl, 4, false); + } + +Intrinsics +========== + +Coroutine Manipulation Intrinsics +--------------------------------- + +Intrinsics described in this section are used to manipulate an existing +coroutine. They can be used in any function which happen to have a pointer +to a `coroutine frame`_ or a pointer to a `coroutine promise`_. + +.. _coro.destroy: + +'llvm.coro.destroy' Intrinsic +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: +""""""" + +:: + + declare void @llvm.coro.destroy(i8* <handle>) + +Overview: +""""""""" + +The '``llvm.coro.destroy``' intrinsic destroys a suspended +coroutine. + +Arguments: +"""""""""" + +The argument is a coroutine handle to a suspended coroutine. + +Semantics: +"""""""""" + +When possible, the `coro.destroy` intrinsic is replaced with a direct call to +the coroutine destroy function. Otherwise it is replaced with an indirect call +based on the function pointer for the destroy function stored in the coroutine +frame. Destroying a coroutine that is not suspended leads to undefined behavior. + +.. _coro.resume: + +'llvm.coro.resume' Intrinsic +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +:: + + declare void @llvm.coro.resume(i8* <handle>) + +Overview: +""""""""" + +The '``llvm.coro.resume``' intrinsic resumes a suspended coroutine. + +Arguments: +"""""""""" + +The argument is a handle to a suspended coroutine. + +Semantics: +"""""""""" + +When possible, the `coro.resume` intrinsic is replaced with a direct call to the +coroutine resume function. Otherwise it is replaced with an indirect call based +on the function pointer for the resume function stored in the coroutine frame. +Resuming a coroutine that is not suspended leads to undefined behavior. + +.. _coro.done: + +'llvm.coro.done' Intrinsic +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +:: + + declare i1 @llvm.coro.done(i8* <handle>) + +Overview: +""""""""" + +The '``llvm.coro.done``' intrinsic checks whether a suspended coroutine is at +the final suspend point or not. + +Arguments: +"""""""""" + +The argument is a handle to a suspended coroutine. + +Semantics: +"""""""""" + +Using this intrinsic on a coroutine that does not have a `final suspend`_ point +or on a coroutine that is not suspended leads to undefined behavior. + +.. _coro.promise: + +'llvm.coro.promise' Intrinsic +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +:: + + declare i8* @llvm.coro.promise(i8* <ptr>, i32 <alignment>, i1 <from>) + +Overview: +""""""""" + +The '``llvm.coro.promise``' intrinsic obtains a pointer to a +`coroutine promise`_ given a coroutine handle and vice versa. + +Arguments: +"""""""""" + +The first argument is a handle to a coroutine if `from` is false. Otherwise, +it is a pointer to a coroutine promise. + +The second argument is an alignment requirements of the promise. +If a frontend designated `%promise = alloca i32` as a promise, the alignment +argument to `coro.promise` should be the alignment of `i32` on the target +platform. If a frontend designated `%promise = alloca i32, align 16` as a +promise, the alignment argument should be 16. +This argument only accepts constants. + +The third argument is a boolean indicating a direction of the transformation. +If `from` is true, the intrinsic returns a coroutine handle given a pointer +to a promise. If `from` is false, the intrinsics return a pointer to a promise +from a coroutine handle. This argument only accepts constants. + +Semantics: +"""""""""" + +Using this intrinsic on a coroutine that does not have a coroutine promise +leads to undefined behavior. It is possible to read and modify coroutine +promise of the coroutine which is currently executing. The coroutine author and +a coroutine user are responsible to makes sure there is no data races. + +Example: +"""""""" + +.. code-block:: text + + define i8* @f(i32 %n) { + entry: + %promise = alloca i32 + %pv = bitcast i32* %promise to i8* + ; the second argument to coro.id points to the coroutine promise. + %id = call token @llvm.coro.id(i32 0, i8* %pv, i8* null, i8* null) + ... + %hdl = call noalias i8* @llvm.coro.begin(token %id, i8* %alloc) + ... + store i32 42, i32* %promise ; store something into the promise + ... + ret i8* %hdl + } + + define i32 @main() { + entry: + %hdl = call i8* @f(i32 4) ; starts the coroutine and returns its handle + %promise.addr.raw = call i8* @llvm.coro.promise(i8* %hdl, i32 4, i1 false) + %promise.addr = bitcast i8* %promise.addr.raw to i32* + %val = load i32, i32* %promise.addr ; load a value from the promise + call void @print(i32 %val) + call void @llvm.coro.destroy(i8* %hdl) + ret i32 0 + } + +.. _coroutine intrinsics: + +Coroutine Structure Intrinsics +------------------------------ +Intrinsics described in this section are used within a coroutine to describe +the coroutine structure. They should not be used outside of a coroutine. + +.. _coro.size: + +'llvm.coro.size' Intrinsic +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +:: + + declare i32 @llvm.coro.size.i32() + declare i64 @llvm.coro.size.i64() + +Overview: +""""""""" + +The '``llvm.coro.size``' intrinsic returns the number of bytes +required to store a `coroutine frame`_. + +Arguments: +"""""""""" + +None + +Semantics: +"""""""""" + +The `coro.size` intrinsic is lowered to a constant representing the size of +the coroutine frame. + +.. _coro.begin: + +'llvm.coro.begin' Intrinsic +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +:: + + declare i8* @llvm.coro.begin(token <id>, i8* <mem>) + +Overview: +""""""""" + +The '``llvm.coro.begin``' intrinsic returns an address of the coroutine frame. + +Arguments: +"""""""""" + +The first argument is a token returned by a call to '``llvm.coro.id``' +identifying the coroutine. + +The second argument is a pointer to a block of memory where coroutine frame +will be stored if it is allocated dynamically. + +Semantics: +"""""""""" + +Depending on the alignment requirements of the objects in the coroutine frame +and/or on the codegen compactness reasons the pointer returned from `coro.begin` +may be at offset to the `%mem` argument. (This could be beneficial if +instructions that express relative access to data can be more compactly encoded +with small positive and negative offsets). + +A frontend should emit exactly one `coro.begin` intrinsic per coroutine. + +.. _coro.free: + +'llvm.coro.free' Intrinsic +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +:: + + declare i8* @llvm.coro.free(token %id, i8* <frame>) + +Overview: +""""""""" + +The '``llvm.coro.free``' intrinsic returns a pointer to a block of memory where +coroutine frame is stored or `null` if this instance of a coroutine did not use +dynamically allocated memory for its coroutine frame. + +Arguments: +"""""""""" + +The first argument is a token returned by a call to '``llvm.coro.id``' +identifying the coroutine. + +The second argument is a pointer to the coroutine frame. This should be the same +pointer that was returned by prior `coro.begin` call. + +Example (custom deallocation function): +""""""""""""""""""""""""""""""""""""""" + +.. code-block:: text + + cleanup: + %mem = call i8* @llvm.coro.free(token %id, i8* %frame) + %mem_not_null = icmp ne i8* %mem, null + br i1 %mem_not_null, label %if.then, label %if.end + if.then: + call void @CustomFree(i8* %mem) + br label %if.end + if.end: + ret void + +Example (standard deallocation functions): +"""""""""""""""""""""""""""""""""""""""""" + +.. code-block:: text + + cleanup: + %mem = call i8* @llvm.coro.free(token %id, i8* %frame) + call void @free(i8* %mem) + ret void + +.. _coro.alloc: + +'llvm.coro.alloc' Intrinsic +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +:: + + declare i1 @llvm.coro.alloc(token <id>) + +Overview: +""""""""" + +The '``llvm.coro.alloc``' intrinsic returns `true` if dynamic allocation is +required to obtain a memory for the corutine frame and `false` otherwise. + +Arguments: +"""""""""" + +The first argument is a token returned by a call to '``llvm.coro.id``' +identifying the coroutine. + +Semantics: +"""""""""" + +A frontend should emit at most one `coro.alloc` intrinsic per coroutine. +The intrinsic is used to suppress dynamic allocation of the coroutine frame +when possible. + +Example: +"""""""" + +.. code-block:: text + + entry: + %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null) + %dyn.alloc.required = call i1 @llvm.coro.alloc(token %id) + br i1 %dyn.alloc.required, label %coro.alloc, label %coro.begin + + coro.alloc: + %frame.size = call i32 @llvm.coro.size() + %alloc = call i8* @MyAlloc(i32 %frame.size) + br label %coro.begin + + coro.begin: + %phi = phi i8* [ null, %entry ], [ %alloc, %coro.alloc ] + %frame = call i8* @llvm.coro.begin(token %id, i8* %phi) + +.. _coro.frame: + +'llvm.coro.frame' Intrinsic +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +:: + + declare i8* @llvm.coro.frame() + +Overview: +""""""""" + +The '``llvm.coro.frame``' intrinsic returns an address of the coroutine frame of +the enclosing coroutine. + +Arguments: +"""""""""" + +None + +Semantics: +"""""""""" + +This intrinsic is lowered to refer to the `coro.begin`_ instruction. This is +a frontend convenience intrinsic that makes it easier to refer to the +coroutine frame. + +.. _coro.id: + +'llvm.coro.id' Intrinsic +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +:: + + declare token @llvm.coro.id(i32 <align>, i8* <promise>, i8* <coroaddr>, + i8* <fnaddrs>) + +Overview: +""""""""" + +The '``llvm.coro.id``' intrinsic returns a token identifying a coroutine. + +Arguments: +"""""""""" + +The first argument provides information on the alignment of the memory returned +by the allocation function and given to `coro.begin` by the first argument. If +this argument is 0, the memory is assumed to be aligned to 2 * sizeof(i8*). +This argument only accepts constants. + +The second argument, if not `null`, designates a particular alloca instruction +to be a `coroutine promise`_. + +The third argument is `null` coming out of the frontend. The CoroEarly pass sets +this argument to point to the function this coro.id belongs to. + +The fourth argument is `null` before coroutine is split, and later is replaced +to point to a private global constant array containing function pointers to +outlined resume and destroy parts of the coroutine. + + +Semantics: +"""""""""" + +The purpose of this intrinsic is to tie together `coro.id`, `coro.alloc` and +`coro.begin` belonging to the same coroutine to prevent optimization passes from +duplicating any of these instructions unless entire body of the coroutine is +duplicated. + +A frontend should emit exactly one `coro.id` intrinsic per coroutine. + +.. _coro.end: + +'llvm.coro.end' Intrinsic +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +:: + + declare void @llvm.coro.end(i8* <handle>, i1 <unwind>) + +Overview: +""""""""" + +The '``llvm.coro.end``' marks the point where execution of the resume part of +the coroutine should end and control returns back to the caller. + + +Arguments: +"""""""""" + +The first argument should refer to the coroutine handle of the enclosing coroutine. + +The second argument should be `true` if this coro.end is in the block that is +part of the unwind sequence leaving the coroutine body due to exception prior to +the first reaching any suspend points, and `false` otherwise. + +Semantics: +"""""""""" +The `coro.end`_ intrinsic is a no-op during an initial invocation of the +coroutine. When the coroutine resumes, the intrinsic marks the point when +coroutine need to return control back to the caller. + +This intrinsic is removed by the CoroSplit pass when a coroutine is split into +the start, resume and destroy parts. In start part, the intrinsic is removed, +in resume and destroy parts, it is replaced with `ret void` instructions and +the rest of the block containing `coro.end` instruction is discarded. + +In landing pads it is replaced with an appropriate instruction to unwind to +caller. + +A frontend is allowed to supply null as the first parameter, in this case +`coro-early` pass will replace the null with an appropriate coroutine handle +value. + +.. _coro.suspend: +.. _suspend points: + +'llvm.coro.suspend' Intrinsic +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +:: + + declare i8 @llvm.coro.suspend(token <save>, i1 <final>) + +Overview: +""""""""" + +The '``llvm.coro.suspend``' marks the point where execution of the coroutine +need to get suspended and control returned back to the caller. +Conditional branches consuming the result of this intrinsic lead to basic blocks +where coroutine should proceed when suspended (-1), resumed (0) or destroyed +(1). + +Arguments: +"""""""""" + +The first argument refers to a token of `coro.save` intrinsic that marks the +point when coroutine state is prepared for suspension. If `none` token is passed, +the intrinsic behaves as if there were a `coro.save` immediately preceding +the `coro.suspend` intrinsic. + +The second argument indicates whether this suspension point is `final`_. +The second argument only accepts constants. If more than one suspend point is +designated as final, the resume and destroy branches should lead to the same +basic blocks. + +Example (normal suspend point): +""""""""""""""""""""""""""""""" + +.. code-block:: text + + %0 = call i8 @llvm.coro.suspend(token none, i1 false) + switch i8 %0, label %suspend [i8 0, label %resume + i8 1, label %cleanup] + +Example (final suspend point): +"""""""""""""""""""""""""""""" + +.. code-block:: text + + while.end: + %s.final = call i8 @llvm.coro.suspend(token none, i1 true) + switch i8 %s.final, label %suspend [i8 0, label %trap + i8 1, label %cleanup] + trap: + call void @llvm.trap() + unreachable + +Semantics: +"""""""""" + +If a coroutine that was suspended at the suspend point marked by this intrinsic +is resumed via `coro.resume`_ the control will transfer to the basic block +of the 0-case. If it is resumed via `coro.destroy`_, it will proceed to the +basic block indicated by the 1-case. To suspend, coroutine proceed to the +default label. + +If suspend intrinsic is marked as final, it can consider the `true` branch +unreachable and can perform optimizations that can take advantage of that fact. + +.. _coro.save: + +'llvm.coro.save' Intrinsic +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +:: + + declare token @llvm.coro.save(i8* <handle>) + +Overview: +""""""""" + +The '``llvm.coro.save``' marks the point where a coroutine need to update its +state to prepare for resumption to be considered suspended (and thus eligible +for resumption). + +Arguments: +"""""""""" + +The first argument points to a coroutine handle of the enclosing coroutine. + +Semantics: +"""""""""" + +Whatever coroutine state changes are required to enable resumption of +the coroutine from the corresponding suspend point should be done at the point +of `coro.save` intrinsic. + +Example: +"""""""" + +Separate save and suspend points are necessary when a coroutine is used to +represent an asynchronous control flow driven by callbacks representing +completions of asynchronous operations. + +In such a case, a coroutine should be ready for resumption prior to a call to +`async_op` function that may trigger resumption of a coroutine from the same or +a different thread possibly prior to `async_op` call returning control back +to the coroutine: + +.. code-block:: text + + %save1 = call token @llvm.coro.save(i8* %hdl) + call void async_op1(i8* %hdl) + %suspend1 = call i1 @llvm.coro.suspend(token %save1, i1 false) + switch i8 %suspend1, label %suspend [i8 0, label %resume1 + i8 1, label %cleanup] + +.. _coro.param: + +'llvm.coro.param' Intrinsic +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +:: + + declare i1 @llvm.coro.param(i8* <original>, i8* <copy>) + +Overview: +""""""""" + +The '``llvm.coro.param``' is used by a frontend to mark up the code used to +construct and destruct copies of the parameters. If the optimizer discovers that +a particular parameter copy is not used after any suspends, it can remove the +construction and destruction of the copy by replacing corresponding coro.param +with `i1 false` and replacing any use of the `copy` with the `original`. + +Arguments: +"""""""""" + +The first argument points to an `alloca` storing the value of a parameter to a +coroutine. + +The second argument points to an `alloca` storing the value of the copy of that +parameter. + +Semantics: +"""""""""" + +The optimizer is free to always replace this intrinsic with `i1 true`. + +The optimizer is also allowed to replace it with `i1 false` provided that the +parameter copy is only used prior to control flow reaching any of the suspend +points. The code that would be DCE'd if the `coro.param` is replaced with +`i1 false` is not considered to be a use of the parameter copy. + +The frontend can emit this intrinsic if its language rules allow for this +optimization. + +Example: +"""""""" +Consider the following example. A coroutine takes two parameters `a` and `b` +that has a destructor and a move constructor. + +.. code-block:: c++ + + struct A { ~A(); A(A&&); bool foo(); void bar(); }; + + task<int> f(A a, A b) { + if (a.foo()) + return 42; + + a.bar(); + co_await read_async(); // introduces suspend point + b.bar(); + } + +Note that, uses of `b` is used after a suspend point and thus must be copied +into a coroutine frame, whereas `a` does not have to, since it never used +after suspend. + +A frontend can create parameter copies for `a` and `b` as follows: + +.. code-block:: text + + task<int> f(A a', A b') { + a = alloca A; + b = alloca A; + // move parameters to its copies + if (coro.param(a', a)) A::A(a, A&& a'); + if (coro.param(b', b)) A::A(b, A&& b'); + ... + // destroy parameters copies + if (coro.param(a', a)) A::~A(a); + if (coro.param(b', b)) A::~A(b); + } + +The optimizer can replace coro.param(a',a) with `i1 false` and replace all uses +of `a` with `a'`, since it is not used after suspend. + +The optimizer must replace coro.param(b', b) with `i1 true`, since `b` is used +after suspend and therefore, it has to reside in the coroutine frame. + +Coroutine Transformation Passes +=============================== +CoroEarly +--------- +The pass CoroEarly lowers coroutine intrinsics that hide the details of the +structure of the coroutine frame, but, otherwise not needed to be preserved to +help later coroutine passes. This pass lowers `coro.frame`_, `coro.done`_, +and `coro.promise`_ intrinsics. + +.. _CoroSplit: + +CoroSplit +--------- +The pass CoroSplit buides coroutine frame and outlines resume and destroy parts +into separate functions. + +CoroElide +--------- +The pass CoroElide examines if the inlined coroutine is eligible for heap +allocation elision optimization. If so, it replaces +`coro.begin` intrinsic with an address of a coroutine frame placed on its caller +and replaces `coro.alloc` and `coro.free` intrinsics with `false` and `null` +respectively to remove the deallocation code. +This pass also replaces `coro.resume` and `coro.destroy` intrinsics with direct +calls to resume and destroy functions for a particular coroutine where possible. + +CoroCleanup +----------- +This pass runs late to lower all coroutine related intrinsics not replaced by +earlier passes. + +Areas Requiring Attention +========================= +#. A coroutine frame is bigger than it could be. Adding stack packing and stack + coloring like optimization on the coroutine frame will result in tighter + coroutine frames. + +#. Take advantage of the lifetime intrinsics for the data that goes into the + coroutine frame. Leave lifetime intrinsics as is for the data that stays in + allocas. + +#. The CoroElide optimization pass relies on coroutine ramp function to be + inlined. It would be beneficial to split the ramp function further to + increase the chance that it will get inlined into its caller. + +#. Design a convention that would make it possible to apply coroutine heap + elision optimization across ABI boundaries. + +#. Cannot handle coroutines with `inalloca` parameters (used in x86 on Windows). + +#. Alignment is ignored by coro.begin and coro.free intrinsics. + +#. Make required changes to make sure that coroutine optimizations work with + LTO. + +#. More tests, more tests, more tests diff --git a/docs/CoverageMappingFormat.rst b/docs/CoverageMappingFormat.rst index 158255ab86397..f4dcfda5bdacd 100644 --- a/docs/CoverageMappingFormat.rst +++ b/docs/CoverageMappingFormat.rst @@ -434,7 +434,7 @@ LEB128 is an unsigned integer value that is encoded using DWARF's LEB128 encoding, optimizing for the case where values are small (1 byte for values less than 128). -.. _Strings: +.. _CoverageStrings: Strings ^^^^^^^ diff --git a/docs/DeveloperPolicy.rst b/docs/DeveloperPolicy.rst index 23bdb2fcf17be..9ec6fb84636f4 100644 --- a/docs/DeveloperPolicy.rst +++ b/docs/DeveloperPolicy.rst @@ -169,6 +169,8 @@ on a patch, but only people with Subversion write access can approve it. There is a web based code review tool that can optionally be used for code reviews. See :doc:`Phabricator`. +.. _code owners: + Code Owners ----------- @@ -497,6 +499,8 @@ list, development list, or LLVM bug tracker component. If someone sends you a patch privately, encourage them to submit it to the appropriate list first. +.. _IR backwards compatibility: + IR Backwards Compatibility -------------------------- @@ -510,8 +514,7 @@ for llvm users and not imposing a big burden on llvm developers: * Additions and changes to the IR should be reflected in ``test/Bitcode/compatibility.ll``. -* The bitcode format produced by a X.Y release will be readable by all - following X.Z releases and the (X+1).0 release. +* The current LLVM version supports loading any bitcode since version 3.0. * After each X.Y release, ``compatibility.ll`` must be copied to ``compatibility-X.Y.ll``. The corresponding bitcode file should be assembled @@ -554,6 +557,85 @@ C API Changes release notes so that it's clear to external users who do not follow the project how the C API is changing and evolving. +New Targets +----------- + +LLVM is very receptive to new targets, even experimental ones, but a number of +problems can appear when adding new large portions of code, and back-ends are +normally added in bulk. We have found that landing large pieces of new code +and then trying to fix emergent problems in-tree is problematic for a variety +of reasons. + +For these reasons, new targets are *always* added as *experimental* until +they can be proven stable, and later moved to non-experimental. The difference +between both classes is that experimental targets are not built by default +(need to be added to -DLLVM_TARGETS_TO_BUILD at CMake time). + +The basic rules for a back-end to be upstreamed in **experimental** mode are: + +* Every target must have a :ref:`code owner<code owners>`. The `CODE_OWNERS.TXT` + file has to be updated as part of the first merge. The code owner makes sure + that changes to the target get reviewed and steers the overall effort. + +* There must be an active community behind the target. This community + will help maintain the target by providing buildbots, fixing + bugs, answering the LLVM community's questions and making sure the new + target doesn't break any of the other targets, or generic code. This + behavior is expected to continue throughout the lifetime of the + target's code. + +* The code must be free of contentious issues, for example, large + changes in how the IR behaves or should be formed by the front-ends, + unless agreed by the majority of the community via refactoring of the + (:doc:`IR standard<LangRef>`) **before** the merge of the new target changes, + following the :ref:`IR backwards compatibility`. + +* The code conforms to all of the policies laid out in this developer policy + document, including license, patent, and coding standards. + +* The target should have either reasonable documentation on how it + works (ISA, ABI, etc.) or a publicly available simulator/hardware + (either free or cheap enough) - preferably both. This allows + developers to validate assumptions, understand constraints and review code + that can affect the target. + +In addition, the rules for a back-end to be promoted to **official** are: + +* The target must have addressed every other minimum requirement and + have been stable in tree for at least 3 months. This cool down + period is to make sure that the back-end and the target community can + endure continuous upstream development for the foreseeable future. + +* The target's code must have been completely adapted to this policy + as well as the :doc:`coding standards<CodingStandards>`. Any exceptions that + were made to move into experimental mode must have been fixed **before** + becoming official. + +* The test coverage needs to be broad and well written (small tests, + well documented). The build target ``check-all`` must pass with the + new target built, and where applicable, the ``test-suite`` must also + pass without errors, in at least one configuration (publicly + demonstrated, for example, via buildbots). + +* Public buildbots need to be created and actively maintained, unless + the target requires no additional buildbots (ex. ``check-all`` covers + all tests). The more relevant and public the new target's CI infrastructure + is, the more the LLVM community will embrace it. + +To **continue** as a supported and official target: + +* The maintainer(s) must continue following these rules throughout the lifetime + of the target. Continuous violations of aforementioned rules and policies + could lead to complete removal of the target from the code base. + +* Degradation in support, documentation or test coverage will make the target as + nuisance to other targets and be considered a candidate for deprecation and + ultimately removed. + +In essences, these rules are necessary for targets to gain and retain their +status, but also markers to define bit-rot, and will be used to clean up the +tree from unmaintained targets. + .. _copyright-license-patents: Copyright, License, and Patents diff --git a/docs/Extensions.rst b/docs/Extensions.rst index f7029215c199b..850c42750911f 100644 --- a/docs/Extensions.rst +++ b/docs/Extensions.rst @@ -67,7 +67,7 @@ the target. It corresponds to the COFF relocation types .long 4 .long 242 .long 40 - .secrel32 _function_name + .secrel32 _function_name + 0 .secidx _function_name ... @@ -165,6 +165,22 @@ and ``.bar`` is associated to ``.foo``. .section .foo,"bw",discard, "sym" .section .bar,"rd",associative, "sym" +MC supports these flags in the COFF ``.section`` directive: + + - ``b``: BSS section (``IMAGE_SCN_CNT_INITIALIZED_DATA``) + - ``d``: Data section (``IMAGE_SCN_CNT_UNINITIALIZED_DATA``) + - ``n``: Section is not loaded (``IMAGE_SCN_LNK_REMOVE``) + - ``r``: Read-only + - ``s``: Shared section + - ``w``: Writable + - ``x``: Executable section + - ``y``: Not readable + - ``D``: Discardable (``IMAGE_SCN_MEM_DISCARDABLE``) + +These flags are all compatible with gas, with the exception of the ``D`` flag, +which gnu as does not support. For gas compatibility, sections with a name +starting with ".debug" are implicitly discardable. + ELF-Dependent ------------- diff --git a/docs/FAQ.rst b/docs/FAQ.rst index 0ab99f3452a7a..ef8b0c886bfaf 100644 --- a/docs/FAQ.rst +++ b/docs/FAQ.rst @@ -19,7 +19,7 @@ Initiative (OSI). Can I modify LLVM source code and redistribute the modified source? ------------------------------------------------------------------- Yes. The modified source distribution must retain the copyright notice and -follow the three bulletted conditions listed in the `LLVM license +follow the three bulleted conditions listed in the `LLVM license <http://llvm.org/svn/llvm-project/llvm/trunk/LICENSE.TXT>`_. diff --git a/docs/GarbageCollection.rst b/docs/GarbageCollection.rst index 81605bc20958b..4ef174410b788 100644 --- a/docs/GarbageCollection.rst +++ b/docs/GarbageCollection.rst @@ -1007,7 +1007,7 @@ a realistic example: void MyGCPrinter::finishAssembly(AsmPrinter &AP) { MCStreamer &OS = AP.OutStreamer; - unsigned IntPtrSize = AP.TM.getSubtargetImpl()->getDataLayout()->getPointerSize(); + unsigned IntPtrSize = AP.getPointerSize(); // Put this in the data section. OS.SwitchSection(AP.getObjFileLowering().getDataSection()); diff --git a/docs/GettingStarted.rst b/docs/GettingStarted.rst index 54240b92b6af8..543f12a859b06 100644 --- a/docs/GettingStarted.rst +++ b/docs/GettingStarted.rst @@ -202,7 +202,7 @@ uses the package and provides other details. Package Version Notes =========================================================== ============ ========================================== `GNU Make <http://savannah.gnu.org/projects/make>`_ 3.79, 3.79.1 Makefile/build processor -`GCC <http://gcc.gnu.org/>`_ >=4.7.0 C/C++ compiler\ :sup:`1` +`GCC <http://gcc.gnu.org/>`_ >=4.8.0 C/C++ compiler\ :sup:`1` `python <http://www.python.org/>`_ >=2.7 Automated test suite\ :sup:`2` `zlib <http://zlib.net>`_ >=1.2.3.4 Compression library\ :sup:`3` =========================================================== ============ ========================================== @@ -261,8 +261,8 @@ For the most popular host toolchains we check for specific minimum versions in our build systems: * Clang 3.1 -* GCC 4.7 -* Visual Studio 2013 +* GCC 4.8 +* Visual Studio 2015 (Update 3) Anything older than these toolchains *may* work, but will require forcing the build system with a special option and is not really a supported host platform. @@ -275,9 +275,6 @@ recent version may be required to support all of the C++ features used in LLVM. We track certain versions of software that are *known* to fail when used as part of the host toolchain. These even include linkers at times. -**GCC 4.6.3 on ARM**: Miscompiles ``llvm-readobj`` at ``-O3``. A test failure -in ``test/Object/readobj-shared-object.test`` is one symptom of the problem. - **GNU ld 2.16.X**. Some 2.16.X versions of the ld linker will produce very long warning messages complaining that some "``.gnu.linkonce.t.*``" symbol was defined in a discarded section. You can safely ignore these messages as they are @@ -294,26 +291,13 @@ intermittent failures when building LLVM with position independent code. The symptom is an error about cyclic dependencies. We recommend upgrading to a newer version of Gold. -**Clang 3.0 with libstdc++ 4.7.x**: a few Linux distributions (Ubuntu 12.10, -Fedora 17) have both Clang 3.0 and libstdc++ 4.7 in their repositories. Clang -3.0 does not implement a few builtins that are used in this library. We -recommend using the system GCC to compile LLVM and Clang in this case. - -**Clang 3.0 on Mageia 2**. There's a packaging issue: Clang can not find at -least some (``cxxabi.h``) libstdc++ headers. - -**Clang in C++11 mode and libstdc++ 4.7.2**. This version of libstdc++ -contained `a bug <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53841>`__ which -causes Clang to refuse to compile condition_variable header file. At the time -of writing, this breaks LLD build. - Getting a Modern Host C++ Toolchain ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This section mostly applies to Linux and older BSDs. On Mac OS X, you should have a sufficiently modern Xcode, or you will likely need to upgrade until you -do. On Windows, just use Visual Studio 2013 as the host compiler, it is -explicitly supported and widely available. FreeBSD 10.0 and newer have a modern +do. Windows does not have a "system compiler", so you must install either Visual +Studio 2015 or a recent version of mingw64. FreeBSD 10.0 and newer have a modern Clang as the system compiler. However, some Linux distributions and some other or older BSDs sometimes have @@ -696,6 +680,73 @@ about files with uncommitted changes. The fix is to rebuild the metadata: Please, refer to the Git-SVN manual (``man git-svn``) for more information. +For developers to work with a git monorepo +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. note:: + + This set-up is using unofficial mirror hosted on GitHub, use with caution. + +To set up a clone of all the llvm projects using a unified repository: + +.. code-block:: console + + % export TOP_LEVEL_DIR=`pwd` + % git clone https://github.com/llvm-project/llvm-project/ + % cd llvm-project + % git config branch.master.rebase true + +You can configure various build directory from this clone, starting with a build +of LLVM alone: + +.. code-block:: console + + % cd $TOP_LEVEL_DIR + % mkdir llvm-build && cd llvm-build + % cmake -GNinja ../llvm-project/llvm + +Or lldb: + +.. code-block:: console + + % cd $TOP_LEVEL_DIR + % mkdir lldb-build && cd lldb-build + % cmake -GNinja ../llvm-project/llvm -DLLVM_ENABLE_PROJECTS=lldb + +Or a combination of multiple projects: + +.. code-block:: console + + % cd $TOP_LEVEL_DIR + % mkdir clang-build && cd clang-build + % cmake -GNinja ../llvm-project/llvm -DLLVM_ENABLE_PROJECTS="clang;libcxx;compiler-rt" + +A helper script is provided in `llvm/utils/git-svn/git-llvm`. After you add it +to your path, you can push committed changes upstream with `git llvm push`. + +.. code-block:: console + + % export PATH=$PATH:$TOP_LEVEL_DIR/llvm-project/llvm/utils/git-svn/ + % git llvm push + +While this is using SVN under the hood, it does not require any interaction from +you with git-svn. +After a few minutes, `git pull` should get back the changes as they were +commited. Note that a current limitation is that `git` does not directly record +file rename, and thus it is propagated to SVN as a combination of delete-add +instead of a file rename. + +If you are using `arc` to interact with Phabricator, you need to manually put it +at the root of the checkout: + +.. code-block:: console + + % cd $TOP_LEVEL_DIR + % cp llvm/.arcconfig ./ + % mkdir -p .git/info/ + % echo .arcconfig >> .git/info/exclude + + Local LLVM Configuration ------------------------ diff --git a/docs/GettingStartedVS.rst b/docs/GettingStartedVS.rst index 57ed875ca4f8d..1e46767679393 100644 --- a/docs/GettingStartedVS.rst +++ b/docs/GettingStartedVS.rst @@ -39,18 +39,16 @@ and software you will need. Hardware -------- -Any system that can adequately run Visual Studio 2013 is fine. The LLVM +Any system that can adequately run Visual Studio 2015 is fine. The LLVM source tree and object files, libraries and executables will consume approximately 3GB. Software -------- -You will need Visual Studio 2013 or higher, with the latest Update installed. +You will need Visual Studio 2015 or higher, with the latest Update installed. You will also need the `CMake <http://www.cmake.org/>`_ build system since it -generates the project files you will use to build with. CMake 2.8.12.2 is the -minimum required version for building with Visual Studio, though the latest -version of CMake is recommended. +generates the project files you will use to build with. If you would like to run the LLVM tests you will need `Python <http://www.python.org/>`_. Version 2.7 and newer are known to work. You will diff --git a/docs/GlobalISel.rst b/docs/GlobalISel.rst new file mode 100644 index 0000000000000..fd247a534f683 --- /dev/null +++ b/docs/GlobalISel.rst @@ -0,0 +1,672 @@ +============================ +Global Instruction Selection +============================ + +.. contents:: + :local: + :depth: 1 + +.. warning:: + This document is a work in progress. It reflects the current state of the + implementation, as well as open design and implementation issues. + +Introduction +============ + +GlobalISel is a framework that provides a set of reusable passes and utilities +for instruction selection --- translation from LLVM IR to target-specific +Machine IR (MIR). + +GlobalISel is intended to be a replacement for SelectionDAG and FastISel, to +solve three major problems: + +* **Performance** --- SelectionDAG introduces a dedicated intermediate + representation, which has a compile-time cost. + + GlobalISel directly operates on the post-isel representation used by the + rest of the code generator, MIR. + It does require extensions to that representation to support arbitrary + incoming IR: :ref:`gmir`. + +* **Granularity** --- SelectionDAG and FastISel operate on individual basic + blocks, losing some global optimization opportunities. + + GlobalISel operates on the whole function. + +* **Modularity** --- SelectionDAG and FastISel are radically different and share + very little code. + + GlobalISel is built in a way that enables code reuse. For instance, both the + optimized and fast selectors share the :ref:`pipeline`, and targets can + configure that pipeline to better suit their needs. + + +.. _gmir: + +Generic Machine IR +================== + +Machine IR operates on physical registers, register classes, and (mostly) +target-specific instructions. + +To bridge the gap with LLVM IR, GlobalISel introduces "generic" extensions to +Machine IR: + +.. contents:: + :local: + +``NOTE``: +The generic MIR (GMIR) representation still contains references to IR +constructs (such as ``GlobalValue``). Removing those should let us write more +accurate tests, or delete IR after building the initial MIR. However, it is +not part of the GlobalISel effort. + +.. _gmir-instructions: + +Generic Instructions +-------------------- + +The main addition is support for pre-isel generic machine instructions (e.g., +``G_ADD``). Like other target-independent instructions (e.g., ``COPY`` or +``PHI``), these are available on all targets. + +``TODO``: +While we're progressively adding instructions, one kind in particular exposes +interesting problems: compares and how to represent condition codes. +Some targets (x86, ARM) have generic comparisons setting multiple flags, +which are then used by predicated variants. +Others (IR) specify the predicate in the comparison and users just get a single +bit. SelectionDAG uses SETCC/CONDBR vs BR_CC (and similar for select) to +represent this. + +The ``MachineIRBuilder`` class wraps the ``MachineInstrBuilder`` and provides +a convenient way to create these generic instructions. + +.. _gmir-gvregs: + +Generic Virtual Registers +------------------------- + +Generic instructions operate on a new kind of register: "generic" virtual +registers. As opposed to non-generic vregs, they are not assigned a Register +Class. Instead, generic vregs have a :ref:`gmir-llt`, and can be assigned +a :ref:`gmir-regbank`. + +``MachineRegisterInfo`` tracks the same information that it does for +non-generic vregs (e.g., use-def chains). Additionally, it also tracks the +:ref:`gmir-llt` of the register, and, instead of the ``TargetRegisterClass``, +its :ref:`gmir-regbank`, if any. + +For simplicity, most generic instructions only accept generic vregs: + +* instead of immediates, they use a gvreg defined by an instruction + materializing the immediate value (see :ref:`irtranslator-constants`). +* instead of physical register, they use a gvreg defined by a ``COPY``. + +``NOTE``: +We started with an alternative representation, where MRI tracks a size for +each gvreg, and instructions have lists of types. +That had two flaws: the type and size are redundant, and there was no generic +way of getting a given operand's type (as there was no 1:1 mapping between +instruction types and operands). +We considered putting the type in some variant of MCInstrDesc instead: +See `PR26576 <http://llvm.org/PR26576>`_: [GlobalISel] Generic MachineInstrs +need a type but this increases the memory footprint of the related objects + +.. _gmir-regbank: + +Register Bank +------------- + +A Register Bank is a set of register classes defined by the target. +A bank has a size, which is the maximum store size of all covered classes. + +In general, cross-class copies inside a bank are expected to be cheaper than +copies across banks. They are also coalesceable by the register coalescer, +whereas cross-bank copies are not. + +Also, equivalent operations can be performed on different banks using different +instructions. + +For example, X86 can be seen as having 3 main banks: general-purpose, x87, and +vector (which could be further split into a bank per domain for single vs +double precision instructions). + +Register banks are described by a target-provided API, +:ref:`RegisterBankInfo <api-registerbankinfo>`. + +.. _gmir-llt: + +Low Level Type +-------------- + +Additionally, every generic virtual register has a type, represented by an +instance of the ``LLT`` class. + +Like ``EVT``/``MVT``/``Type``, it has no distinction between unsigned and signed +integer types. Furthermore, it also has no distinction between integer and +floating-point types: it mainly conveys absolutely necessary information, such +as size and number of vector lanes: + +* ``sN`` for scalars +* ``pN`` for pointers +* ``<N x sM>`` for vectors +* ``unsized`` for labels, etc.. + +``LLT`` is intended to replace the usage of ``EVT`` in SelectionDAG. + +Here are some LLT examples and their ``EVT`` and ``Type`` equivalents: + + ============= ========= ====================================== + LLT EVT IR Type + ============= ========= ====================================== + ``s1`` ``i1`` ``i1`` + ``s8`` ``i8`` ``i8`` + ``s32`` ``i32`` ``i32`` + ``s32`` ``f32`` ``float`` + ``s17`` ``i17`` ``i17`` + ``s16`` N/A ``{i8, i8}`` + ``s32`` N/A ``[4 x i8]`` + ``p0`` ``iPTR`` ``i8*``, ``i32*``, ``%opaque*`` + ``p2`` ``iPTR`` ``i8 addrspace(2)*`` + ``<4 x s32>`` ``v4f32`` ``<4 x float>`` + ``s64`` ``v1f64`` ``<1 x double>`` + ``<3 x s32>`` ``v3i32`` ``<3 x i32>`` + ``unsized`` ``Other`` ``label`` + ============= ========= ====================================== + + +Rationale: instructions already encode a specific interpretation of types +(e.g., ``add`` vs. ``fadd``, or ``sdiv`` vs. ``udiv``). Also encoding that +information in the type system requires introducing bitcast with no real +advantage for the selector. + +Pointer types are distinguished by address space. This matches IR, as opposed +to SelectionDAG where address space is an attribute on operations. +This representation better supports pointers having different sizes depending +on their addressspace. + +``NOTE``: +Currently, LLT requires at least 2 elements in vectors, but some targets have +the concept of a '1-element vector'. Representing them as their underlying +scalar type is a nice simplification. + +``TODO``: +Currently, non-generic virtual registers, defined by non-pre-isel-generic +instructions, cannot have a type, and thus cannot be used by a pre-isel generic +instruction. Instead, they are given a type using a COPY. We could relax that +and allow types on all vregs: this would reduce the number of MI required when +emitting target-specific MIR early in the pipeline. This should purely be +a compile-time optimization. + +.. _pipeline: + +Core Pipeline +============= + +There are four required passes, regardless of the optimization mode: + +.. contents:: + :local: + +Additional passes can then be inserted at higher optimization levels or for +specific targets. For example, to match the current SelectionDAG set of +transformations: MachineCSE and a better MachineCombiner between every pass. + +``NOTE``: +In theory, not all passes are always necessary. +As an additional compile-time optimization, we could skip some of the passes by +setting the relevant MachineFunction properties. For instance, if the +IRTranslator did not encounter any illegal instruction, it would set the +``legalized`` property to avoid running the :ref:`milegalizer`. +Similarly, we considered specializing the IRTranslator per-target to directly +emit target-specific MI. +However, we instead decided to keep the core pipeline simple, and focus on +minimizing the overhead of the passes in the no-op cases. + + +.. _irtranslator: + +IRTranslator +------------ + +This pass translates the input LLVM IR ``Function`` to a GMIR +``MachineFunction``. + +``TODO``: +This currently doesn't support the more complex instructions, in particular +those involving control flow (``switch``, ``invoke``, ...). +For ``switch`` in particular, we can initially use the ``LowerSwitch`` pass. + +.. _api-calllowering: + +API: CallLowering +^^^^^^^^^^^^^^^^^ + +The ``IRTranslator`` (using the ``CallLowering`` target-provided utility) also +implements the ABI's calling convention by lowering calls, returns, and +arguments to the appropriate physical register usage and instruction sequences. + +.. _irtranslator-aggregates: + +Aggregates +^^^^^^^^^^ + +Aggregates are lowered to a single scalar vreg. +This differs from SelectionDAG's multiple vregs via ``GetValueVTs``. + +``TODO``: +As some of the bits are undef (padding), we should consider augmenting the +representation with additional metadata (in effect, caching computeKnownBits +information on vregs). +See `PR26161 <http://llvm.org/PR26161>`_: [GlobalISel] Value to vreg during +IR to MachineInstr translation for aggregate type + +.. _irtranslator-constants: + +Constant Lowering +^^^^^^^^^^^^^^^^^ + +The ``IRTranslator`` lowers ``Constant`` operands into uses of gvregs defined +by ``G_CONSTANT`` or ``G_FCONSTANT`` instructions. +Currently, these instructions are always emitted in the entry basic block. +In a ``MachineFunction``, each ``Constant`` is materialized by a single gvreg. + +This is beneficial as it allows us to fold constants into immediate operands +during :ref:`instructionselect`, while still avoiding redundant materializations +for expensive non-foldable constants. +However, this can lead to unnecessary spills and reloads in an -O0 pipeline, as +these vregs can have long live ranges. + +``TODO``: +We're investigating better placement of these instructions, in fast and +optimized modes. + + +.. _milegalizer: + +Legalizer +--------- + +This pass transforms the generic machine instructions such that they are legal. + +A legal instruction is defined as: + +* **selectable** --- the target will later be able to select it to a + target-specific (non-generic) instruction. + +* operating on **vregs that can be loaded and stored** -- if necessary, the + target can select a ``G_LOAD``/``G_STORE`` of each gvreg operand. + +As opposed to SelectionDAG, there are no legalization phases. In particular, +'type' and 'operation' legalization are not separate. + +Legalization is iterative, and all state is contained in GMIR. To maintain the +validity of the intermediate code, instructions are introduced: + +* ``G_SEQUENCE`` --- concatenate multiple registers into a single wider + register. + +* ``G_EXTRACT`` --- extract multiple registers (as contiguous sequences of bits) + from a single wider register. + +As they are expected to be temporary byproducts of the legalization process, +they are combined at the end of the :ref:`milegalizer` pass. +If any remain, they are expected to always be selectable, using loads and stores +if necessary. + +.. _api-legalizerinfo: + +API: LegalizerInfo +^^^^^^^^^^^^^^^^^^ + +Currently the API is broadly similar to SelectionDAG/TargetLowering, but +extended in two ways: + +* The set of available actions is wider, avoiding the currently very + overloaded ``Expand`` (which can cover everything from libcalls to + scalarization depending on the node's opcode). + +* Since there's no separate type legalization, independently varying + types on an instruction can have independent actions. For example a + ``G_ICMP`` has 2 independent types: the result and the inputs; we need + to be able to say that comparing 2 s32s is OK, but the s1 result + must be dealt with in another way. + +As such, the primary key when deciding what to do is the ``InstrAspect``, +essentially a tuple consisting of ``(Opcode, TypeIdx, Type)`` and mapping to a +suggested course of action. + +An example use might be: + + .. code-block:: c++ + + // The CPU can't deal with an s1 result, do something about it. + setAction({G_ICMP, 0, s1}, WidenScalar); + // An s32 input (the second type) is fine though. + setAction({G_ICMP, 1, s32}, Legal); + + +``TODO``: +An alternative worth investigating is to generalize the API to represent +actions using ``std::function`` that implements the action, instead of explicit +enum tokens (``Legal``, ``WidenScalar``, ...). + +``TODO``: +Moreover, we could use TableGen to initially infer legality of operation from +existing patterns (as any pattern we can select is by definition legal). +Expanding that to describe legalization actions is a much larger but +potentially useful project. + +.. _milegalizer-scalar-narrow: + +Scalar narrow types +^^^^^^^^^^^^^^^^^^^ + +In the AArch64 port, we currently mark as legal operations on narrow integer +types that have a legal equivalent in a wider type. + +For example, this: + + %2(GPR,s8) = G_ADD %0, %1 + +is selected to a 32-bit instruction: + + %2(GPR32) = ADDWrr %0, %1 + +This avoids unnecessarily legalizing operations that can be seen as legal: +8-bit additions are supported, but happen to have a 32-bit result with the high +24 bits undefined. + +``TODO``: +This has implications regarding vreg classes (as narrow values can now be +represented by wider vregs) and should be investigated further. + +``TODO``: +In particular, s1 comparison results can be represented as wider values in +different ways. +SelectionDAG has the notion of BooleanContents, which allows targets to choose +what true and false are when in a larger register: + +* ``ZeroOrOne`` --- if only 0 and 1 are valid bools, even in a larger register. +* ``ZeroOrMinusOne`` --- if -1 is true (common for vector instructions, + where compares produce -1). +* ``Undefined`` --- if only the low bit is relevant in determining truth. + +.. _milegalizer-non-power-of-2: + +Non-power of 2 types +^^^^^^^^^^^^^^^^^^^^ + +``TODO``: +Types which have a size that isn't a power of 2 aren't currently supported. +The setAction API will probably require changes to support them. +Even notionally explicitly specified operations only make suggestions +like "Widen" or "Narrow". The eventual type is still unspecified and a +search is performed by repeated doubling/halving of the type's +size. +This is incorrect for types that aren't a power of 2. It's reasonable to +expect we could construct an efficient set of side-tables for more general +lookups though, encoding a map from the integers (i.e. the size of the current +type) to types (the legal size). + +.. _milegalizer-vector: + +Vector types +^^^^^^^^^^^^ + +Vectors first get their element type legalized: ``<A x sB>`` becomes +``<A x sC>`` such that at least one operation is legal with ``sC``. + +This is currently specified by the function ``setScalarInVectorAction``, called +for example as: + + setScalarInVectorAction(G_ICMP, s1, WidenScalar); + +Next the number of elements is chosen so that the entire operation is +legal. This aspect is not controllable at the moment, but probably +should be (you could imagine disagreements on whether a ``<2 x s8>`` +operation should be scalarized or extended to ``<8 x s8>``). + + +.. _regbankselect: + +RegBankSelect +------------- + +This pass constrains the :ref:`gmir-gvregs` operands of generic +instructions to some :ref:`gmir-regbank`. + +It iteratively maps instructions to a set of per-operand bank assignment. +The possible mappings are determined by the target-provided +:ref:`RegisterBankInfo <api-registerbankinfo>`. +The mapping is then applied, possibly introducing ``COPY`` instructions if +necessary. + +It traverses the ``MachineFunction`` top down so that all operands are already +mapped when analyzing an instruction. + +This pass could also remap target-specific instructions when beneficial. +In the future, this could replace the ExeDepsFix pass, as we can directly +select the best variant for an instruction that's available on multiple banks. + +.. _api-registerbankinfo: + +API: RegisterBankInfo +^^^^^^^^^^^^^^^^^^^^^ + +The ``RegisterBankInfo`` class describes multiple aspects of register banks. + +* **Banks**: ``addRegBankCoverage`` --- which register bank covers each + register class. + +* **Cross-Bank Copies**: ``copyCost`` --- the cost of a ``COPY`` from one bank + to another. + +* **Default Mapping**: ``getInstrMapping`` --- the default bank assignments for + a given instruction. + +* **Alternative Mapping**: ``getInstrAlternativeMapping`` --- the other + possible bank assignments for a given instruction. + +``TODO``: +All this information should eventually be static and generated by TableGen, +mostly using existing information augmented by bank descriptions. + +``TODO``: +``getInstrMapping`` is currently separate from ``getInstrAlternativeMapping`` +because the latter is more expensive: as we move to static mapping info, +both methods should be free, and we should merge them. + +.. _regbankselect-modes: + +RegBankSelect Modes +^^^^^^^^^^^^^^^^^^^ + +``RegBankSelect`` currently has two modes: + +* **Fast** --- For each instruction, pick a target-provided "default" bank + assignment. This is the default at -O0. + +* **Greedy** --- For each instruction, pick the cheapest of several + target-provided bank assignment alternatives. + +We intend to eventually introduce an additional optimizing mode: + +* **Global** --- Across multiple instructions, pick the cheapest combination of + bank assignments. + +``NOTE``: +On AArch64, we are considering using the Greedy mode even at -O0 (or perhaps at +backend -O1): because :ref:`gmir-llt` doesn't distinguish floating point from +integer scalars, the default assignment for loads and stores is the integer +bank, introducing cross-bank copies on most floating point operations. + + +.. _instructionselect: + +InstructionSelect +----------------- + +This pass transforms generic machine instructions into equivalent +target-specific instructions. It traverses the ``MachineFunction`` bottom-up, +selecting uses before definitions, enabling trivial dead code elimination. + +.. _api-instructionselector: + +API: InstructionSelector +^^^^^^^^^^^^^^^^^^^^^^^^ + +The target implements the ``InstructionSelector`` class, containing the +target-specific selection logic proper. + +The instance is provided by the subtarget, so that it can specialize the +selector by subtarget feature (with, e.g., a vector selector overriding parts +of a general-purpose common selector). +We might also want to parameterize it by MachineFunction, to enable selector +variants based on function attributes like optsize. + +The simple API consists of: + + .. code-block:: c++ + + virtual bool select(MachineInstr &MI) + +This target-provided method is responsible for mutating (or replacing) a +possibly-generic MI into a fully target-specific equivalent. +It is also responsible for doing the necessary constraining of gvregs into the +appropriate register classes. + +The ``InstructionSelector`` can fold other instructions into the selected MI, +by walking the use-def chain of the vreg operands. +As GlobalISel is Global, this folding can occur across basic blocks. + +``TODO``: +Currently, the Select pass is implemented with hand-written c++, similar to +FastISel, rather than backed by tblgen'erated pattern-matching. +We intend to eventually reuse SelectionDAG patterns. + + +.. _maintainability: + +Maintainability +=============== + +.. _maintainability-iterative: + +Iterative Transformations +------------------------- + +Passes are split into small, iterative transformations, with all state +represented in the MIR. + +This differs from SelectionDAG (in particular, the legalizer) using various +in-memory side-tables. + + +.. _maintainability-mir: + +MIR Serialization +----------------- + +.. FIXME: Update the MIRLangRef to include GMI additions. + +:ref:`gmir` is serializable (see :doc:`MIRLangRef`). +Combined with :ref:`maintainability-iterative`, this enables much finer-grained +testing, rather than requiring large and fragile IR-to-assembly tests. + +The current "stage" in the :ref:`pipeline` is represented by a set of +``MachineFunctionProperties``: + +* ``legalized`` +* ``regBankSelected`` +* ``selected`` + + +.. _maintainability-verifier: + +MachineVerifier +--------------- + +The pass approach lets us use the ``MachineVerifier`` to enforce invariants. +For instance, a ``regBankSelected`` function may not have gvregs without +a bank. + +``TODO``: +The ``MachineVerifier`` being monolithic, some of the checks we want to do +can't be integrated to it: GlobalISel is a separate library, so we can't +directly reference it from CodeGen. For instance, legality checks are +currently done in RegBankSelect/InstructionSelect proper. We could #ifdef out +the checks, or we could add some sort of verifier API. + + +.. _progress: + +Progress and Future Work +======================== + +The initial goal is to replace FastISel on AArch64. The next step will be to +replace SelectionDAG as the optimized ISel. + +``NOTE``: +While we iterate on GlobalISel, we strive to avoid affecting the performance of +SelectionDAG, FastISel, or the other MIR passes. For instance, the types of +:ref:`gmir-gvregs` are stored in a separate table in ``MachineRegisterInfo``, +that is destroyed after :ref:`instructionselect`. + +.. _progress-fastisel: + +FastISel Replacement +-------------------- + +For the initial FastISel replacement, we intend to fallback to SelectionDAG on +selection failures. + +Currently, compile-time of the fast pipeline is within 1.5x of FastISel. +We're optimistic we can get to within 1.1/1.2x, but beating FastISel will be +challenging given the multi-pass approach. +Still, supporting all IR (via a complete legalizer) and avoiding the fallback +to SelectionDAG in the worst case should enable better amortized performance +than SelectionDAG+FastISel. + +``NOTE``: +We considered never having a fallback to SelectionDAG, instead deciding early +whether a given function is supported by GlobalISel or not. The decision would +be based on :ref:`milegalizer` queries. +We abandoned that for two reasons: +a) on IR inputs, we'd need to basically simulate the :ref:`irtranslator`; +b) to be robust against unforeseen failures and to enable iterative +improvements. + +.. _progress-targets: + +Support For Other Targets +------------------------- + +In parallel, we're investigating adding support for other - ideally quite +different - targets. For instance, there is some initial AMDGPU support. + + +.. _porting: + +Porting GlobalISel to A New Target +================================== + +There are four major classes to implement by the target: + +* :ref:`CallLowering <api-calllowering>` --- lower calls, returns, and arguments + according to the ABI. +* :ref:`RegisterBankInfo <api-registerbankinfo>` --- describe + :ref:`gmir-regbank` coverage, cross-bank copy cost, and the mapping of + operands onto banks for each instruction. +* :ref:`LegalizerInfo <api-legalizerinfo>` --- describe what is legal, and how + to legalize what isn't. +* :ref:`InstructionSelector <api-instructionselector>` --- select generic MIR + to target-specific MIR. + +Additionally: + +* ``TargetPassConfig`` --- create the passes constituting the pipeline, + including additional passes not included in the :ref:`pipeline`. +* ``GISelAccessor`` --- setup the various subtarget-provided classes, with a + graceful fallback to no-op when GlobalISel isn't enabled. diff --git a/docs/HowToAddABuilder.rst b/docs/HowToAddABuilder.rst index 893f12d19d55d..9e06a3276470b 100644 --- a/docs/HowToAddABuilder.rst +++ b/docs/HowToAddABuilder.rst @@ -30,7 +30,7 @@ Here are the steps you can follow to do so: #. Install buildslave (currently we are using buildbot version 0.8.5). Depending on the platform, buildslave could be available to download and - install with your packet manager, or you can download it directly from + install with your package manager, or you can download it directly from `<http://trac.buildbot.net>`_ and install it manually. #. Create a designated user account, your buildslave will be running under, @@ -43,7 +43,7 @@ Here are the steps you can follow to do so: #. Create a buildslave in context of that buildslave account. Point it to the **lab.llvm.org** port **9990** (see `Buildbot documentation, Creating a slave - <http://buildbot.net/buildbot/docs/current/full.html#creating-a-slave>`_ + <http://docs.buildbot.net/current/tutorial/firstrun.html#creating-a-slave>`_ for more details) by running the following command: .. code-block:: bash diff --git a/docs/HowToReleaseLLVM.rst b/docs/HowToReleaseLLVM.rst index d44ea04a9fafc..5ea6d49cf4801 100644 --- a/docs/HowToReleaseLLVM.rst +++ b/docs/HowToReleaseLLVM.rst @@ -2,17 +2,13 @@ How To Release LLVM To The Public ================================= -.. contents:: - :local: - :depth: 1 - Introduction ============ This document contains information about successfully releasing LLVM --- -including subprojects: e.g., ``clang`` and ``dragonegg`` --- to the public. It -is the Release Manager's responsibility to ensure that a high quality build of -LLVM is released. +including sub-projects: e.g., ``clang`` and ``compiler-rt`` --- to the public. +It is the Release Manager's responsibility to ensure that a high quality build +of LLVM is released. If you're looking for the document on how to test the release candidates and create the binary packages, please refer to the :doc:`ReleaseProcess` instead. @@ -46,7 +42,7 @@ The release process is roughly as follows: the end of the first round of testing will be removed or disabled for the release. -* Generate and send out the second release candidate sources. Only *critial* +* Generate and send out the second release candidate sources. Only *critical* bugs found during this testing phase will be fixed. Any bugs introduced by merged patches will be fixed. If so a third round of testing is needed. @@ -89,24 +85,10 @@ Branch the Subversion trunk using the following procedure: #. Verify that the current Subversion trunk is in decent shape by examining nightly tester and buildbot results. -#. Create the release branch for ``llvm``, ``clang``, the ``test-suite``, and - ``dragonegg`` from the last known good revision. The branch's name is +#. Create the release branch for ``llvm``, ``clang``, and other sub-projects, + from the last known good revision. The branch's name is ``release_XY``, where ``X`` is the major and ``Y`` the minor release - numbers. The branches should be created using the following commands: - - :: - - $ svn copy https://llvm.org/svn/llvm-project/llvm/trunk \ - https://llvm.org/svn/llvm-project/llvm/branches/release_XY - - $ svn copy https://llvm.org/svn/llvm-project/cfe/trunk \ - https://llvm.org/svn/llvm-project/cfe/branches/release_XY - - $ svn copy https://llvm.org/svn/llvm-project/dragonegg/trunk \ - https://llvm.org/svn/llvm-project/dragonegg/branches/release_XY - - $ svn copy https://llvm.org/svn/llvm-project/test-suite/trunk \ - https://llvm.org/svn/llvm-project/test-suite/branches/release_XY + numbers. Use ``utils/release/tag.sh`` to tag the release. #. Advise developers that they may now check their patches into the Subversion tree again. @@ -121,8 +103,6 @@ Branch the Subversion trunk using the following procedure: $ svn co https://llvm.org/svn/llvm-project/cfe/branches/release_XY clang-X.Y - $ svn co https://llvm.org/svn/llvm-project/dragonegg/branches/release_XY dragonegg-X.Y - $ svn co https://llvm.org/svn/llvm-project/test-suite/branches/release_XY test-suite-X.Y Update LLVM Version @@ -155,71 +135,19 @@ be done with the export.sh script in utils/release. This will generate source tarballs for each LLVM project being validated, which can be uploaded to the website for further testing. -Building the Release --------------------- - -The builds of ``llvm``, ``clang``, and ``dragonegg`` *must* be free of -errors and warnings in Debug, Release+Asserts, and Release builds. If all -builds are clean, then the release passes Build Qualification. - -The ``make`` options for building the different modes: - -+-----------------+---------------------------------------------+ -| Mode | Options | -+=================+=============================================+ -| Debug | ``ENABLE_OPTIMIZED=0`` | -+-----------------+---------------------------------------------+ -| Release+Asserts | ``ENABLE_OPTIMIZED=1`` | -+-----------------+---------------------------------------------+ -| Release | ``ENABLE_OPTIMIZED=1 DISABLE_ASSERTIONS=1`` | -+-----------------+---------------------------------------------+ - -Build LLVM -^^^^^^^^^^ - -Build ``Debug``, ``Release+Asserts``, and ``Release`` versions -of ``llvm`` on all supported platforms. Directions to build ``llvm`` -are :doc:`here <GettingStarted>`. - Build Clang Binary Distribution ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Creating the ``clang`` binary distribution (Debug/Release+Asserts/Release) -requires performing the following steps for each supported platform: - -#. Build clang according to the directions `here - <http://clang.llvm.org/get_started.html>`__. +Creating the ``clang`` binary distribution requires following the instructions +:doc:`here <ReleaseProcess>`. -#. Build both a Debug and Release version of clang. The binary will be the - Release build. +That process will perform both Release+Asserts and Release builds but only +pack the Release build for upload. You should use the Release+Asserts sysroot, +normally under ``final/Phase3/Release+Asserts/llvmCore-3.8.1-RCn.install/``, +for test-suite and run-time benchmarks, to make sure nothing serious has +passed through the net. For compile-time benchmarks, use the Release version. -#. Package ``clang`` (details to follow). - -Target Specific Build Details -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The table below specifies which compilers are used for each Arch/OS combination -when qualifying the build of ``llvm``, ``clang``, and ``dragonegg``. - -+--------------+---------------+----------------------+ -| Architecture | OS | compiler | -+==============+===============+======================+ -| x86-32 | Mac OS 10.5 | gcc 4.0.1 | -+--------------+---------------+----------------------+ -| x86-32 | Linux | gcc 4.2.X, gcc 4.3.X | -+--------------+---------------+----------------------+ -| x86-32 | FreeBSD | gcc 4.2.X | -+--------------+---------------+----------------------+ -| x86-32 | mingw | gcc 3.4.5 | -+--------------+---------------+----------------------+ -| x86-64 | Mac OS 10.5 | gcc 4.0.1 | -+--------------+---------------+----------------------+ -| x86-64 | Linux | gcc 4.2.X, gcc 4.3.X | -+--------------+---------------+----------------------+ -| x86-64 | FreeBSD | gcc 4.2.X | -+--------------+---------------+----------------------+ -| ARMv7 | Linux | gcc 4.6.X, gcc 4.7.X | -+--------------+---------------+----------------------+ +The minimum required version of the tools you'll need are :doc:`here <GettingStarted>` Release Qualification Criteria ------------------------------ @@ -229,68 +157,53 @@ baseline). Regressions are related to correctness first and performance second. (We may tolerate some minor performance regressions if they are deemed necessary for the general quality of the compiler.) -**Regressions are new failures in the set of tests that are used to qualify +More specifically, Clang/LLVM is qualified when it has a clean test with all +supported sub-projects included (``make check-all``), per target, and it has no +regressions with the ``test-suite`` in relation to the previous release. + +Regressions are new failures in the set of tests that are used to qualify each product and only include things on the list. Every release will have some bugs in it. It is the reality of developing a complex piece of software. We need a very concrete and definitive release criteria that ensures we have monotonically improving quality on some metric. The metric we use is described below. This doesn't mean that we don't care about other criteria, but these are the criteria which we found to be most important and -which must be satisfied before a release can go out.** +which must be satisfied before a release can go out. -Qualify LLVM -^^^^^^^^^^^^ +Official Testing +---------------- -LLVM is qualified when it has a clean test run without a front-end. And it has -no regressions when using either ``clang`` or ``dragonegg`` with the -``test-suite`` from the previous release. +A few developers in the community have dedicated time to validate the release +candidates and volunteered to be the official release testers for each +architecture. -Qualify Clang -^^^^^^^^^^^^^ +These will be the ones testing, generating and uploading the official binaries +to the server, and will be the minimum tests *necessary* for the release to +proceed. -``Clang`` is qualified when front-end specific tests in the ``llvm`` regression -test suite all pass, clang's own test suite passes cleanly, and there are no -regressions in the ``test-suite``. +This will obviously not cover all OSs and distributions, so additional community +validation is important. However, if community input is not reached before the +release is out, all bugs reported will have to go on the next stable release. -Specific Target Qualification Details -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The official release managers are: -+--------------+-------------+----------------+-----------------------------+ -| Architecture | OS | clang baseline | tests | -+==============+=============+================+=============================+ -| x86-32 | Linux | last release | llvm regression tests, | -| | | | clang regression tests, | -| | | | test-suite (including spec) | -+--------------+-------------+----------------+-----------------------------+ -| x86-32 | FreeBSD | last release | llvm regression tests, | -| | | | clang regression tests, | -| | | | test-suite | -+--------------+-------------+----------------+-----------------------------+ -| x86-32 | mingw | none | QT | -+--------------+-------------+----------------+-----------------------------+ -| x86-64 | Mac OS 10.X | last release | llvm regression tests, | -| | | | clang regression tests, | -| | | | test-suite (including spec) | -+--------------+-------------+----------------+-----------------------------+ -| x86-64 | Linux | last release | llvm regression tests, | -| | | | clang regression tests, | -| | | | test-suite (including spec) | -+--------------+-------------+----------------+-----------------------------+ -| x86-64 | FreeBSD | last release | llvm regression tests, | -| | | | clang regression tests, | -| | | | test-suite | -+--------------+-------------+----------------+-----------------------------+ -| ARMv7A | Linux | last release | llvm regression tests, | -| | | | clang regression tests, | -| | | | test-suite | -+--------------+-------------+----------------+-----------------------------+ +* Major releases (X.0): Hans Wennborg +* Stable releases (X.n): Tom Stellard + +The official release testers are volunteered from the community and have +consistently validated and released binaries for their targets/OSs. To contact +them, you should email the ``release-testers@lists.llvm.org`` mailing list. + +The official testers list is in the file ``RELEASE_TESTERS.TXT``, in the ``LLVM`` +repository. Community Testing ----------------- Once all testing has been completed and appropriate bugs filed, the release candidate tarballs are put on the website and the LLVM community is notified. -Ask that all LLVM developers test the release in 2 ways: + +We ask that all LLVM developers test the release in any the following ways: #. Download ``llvm-X.Y``, ``llvm-test-X.Y``, and the appropriate ``clang`` binary. Build LLVM. Run ``make check`` and the full LLVM test suite (``make @@ -300,28 +213,57 @@ Ask that all LLVM developers test the release in 2 ways: everything. Run ``make check`` and the full LLVM test suite (``make TEST=nightly report``). -Ask LLVM developers to submit the test suite report and ``make check`` results -to the list. Verify that there are no regressions from the previous release. -The results are not used to qualify a release, but to spot other potential -problems. For unsupported targets, verify that ``make check`` is at least -clean. +#. Download ``llvm-X.Y``, ``llvm-test-X.Y``, and the appropriate ``clang`` + binary. Build whole programs with it (ex. Chromium, Firefox, Apache) for + your platform. + +#. Download ``llvm-X.Y``, ``llvm-test-X.Y``, and the appropriate ``clang`` + binary. Build *your* programs with it and check for conformance and + performance regressions. + +#. Run the :doc:`release process <ReleaseProcess>`, if your platform is + *different* than that which is officially supported, and report back errors + only if they were not reported by the official release tester for that + architecture. + +We also ask that the OS distribution release managers test their packages with +the first candidate of every release, and report any *new* errors in Bugzilla. +If the bug can be reproduced with an unpatched upstream version of the release +candidate (as opposed to the distribution's own build), the priority should be +release blocker. During the first round of testing, all regressions must be fixed before the second release candidate is tagged. -If this is the second round of testing, the testing is only to ensure that bug +In the subsequent stages, the testing is only to ensure that bug fixes previously merged in have not created new major problems. *This is not the time to solve additional and unrelated bugs!* If no patches are merged in, the release is determined to be ready and the release manager may move onto the next stage. +Reporting Regressions +--------------------- + +Every regression that is found during the tests (as per the criteria above), +should be filled in a bug in Bugzilla with the priority *release blocker* and +blocking a specific release. + +To help manage all the bugs reported and which ones are blockers or not, a new +"[meta]" bug should be created and all regressions *blocking* that Meta. Once +all blockers are done, the Meta can be closed. + +If a bug can't be reproduced, or stops being a blocker, it should be removed +from the Meta and its priority decreased to *normal*. Debugging can continue, +but on trunk. + Release Patch Rules ------------------- Below are the rules regarding patching the release branch: #. Patches applied to the release branch may only be applied by the release - manager. + manager, the official release testers or the code owners with approval from + the release manager. #. During the first round of testing, patches that fix regressions or that are small and relatively risk free (verified by the appropriate code owner) are @@ -333,7 +275,7 @@ Below are the rules regarding patching the release branch: regressions may be applied. #. For dot releases all patches must maintain both API and ABI compatibility with - the previous major release. Only bugfixes will be accepted. + the previous major release. Only bug-fixes will be accepted. Merging Patches ^^^^^^^^^^^^^^^ @@ -394,10 +336,10 @@ is what to do: #. Check out the ``www`` module from Subversion. -#. Create a new subdirectory ``X.Y`` in the releases directory. +#. Create a new sub-directory ``X.Y`` in the releases directory. -#. Commit the ``llvm``, ``test-suite``, ``clang`` source, ``clang binaries``, - ``dragonegg`` source, and ``dragonegg`` binaries in this new directory. +#. Commit the ``llvm``, ``test-suite``, ``clang`` source and binaries in this + new directory. #. Copy and commit the ``llvm/docs`` and ``LICENSE.txt`` files into this new directory. The docs should be built with ``BUILD_FOR_WEBSITE=1``. @@ -417,5 +359,6 @@ is what to do: Announce the Release ^^^^^^^^^^^^^^^^^^^^ -Have Chris send out the release announcement when everything is finished. +Send an email to the list announcing the release, pointing people to all the +relevant documentation, download pages and bugs fixed. diff --git a/docs/LLVMBuild.rst b/docs/LLVMBuild.rst index 0200f78bfb7f4..a93dcf644084d 100644 --- a/docs/LLVMBuild.rst +++ b/docs/LLVMBuild.rst @@ -321,4 +321,3 @@ the properties which are associated with that component. ``BuildTool`` components currently use the exact same properties as ``Tool`` components, the type distinction is only used to differentiate what the tool is built for. - diff --git a/docs/LangRef.rst b/docs/LangRef.rst index ce15c47111cd1..ecf37bab55d04 100644 --- a/docs/LangRef.rst +++ b/docs/LangRef.rst @@ -546,6 +546,25 @@ An example of an identified structure specification is: Prior to the LLVM 3.0 release, identified types were structurally uniqued. Only literal types are uniqued in recent versions of LLVM. +.. _nointptrtype: + +Non-Integral Pointer Type +------------------------- + +Note: non-integral pointer types are a work in progress, and they should be +considered experimental at this time. + +LLVM IR optionally allows the frontend to denote pointers in certain address +spaces as "non-integral" via the :ref:`datalayout string<langref_datalayout>`. +Non-integral pointer types represent pointers that have an *unspecified* bitwise +representation; that is, the integral representation may be target dependent or +unstable (not backed by a fixed integer). + +``inttoptr`` instructions converting integers to non-integral pointer types are +ill-typed, and so are ``ptrtoint`` instructions converting values of +non-integral pointer types to integers. Vector versions of said instructions +are ill-typed as well. + .. _globalvars: Global Variables @@ -1010,10 +1029,9 @@ Currently, only the following parameter attributes are defined: This indicates that the pointer parameter specifies the address of a structure that is the return value of the function in the source program. This pointer must be guaranteed by the caller to be valid: - loads and stores to the structure may be assumed by the callee - not to trap and to be properly aligned. This may only be applied to - the first parameter. This is not a valid attribute for return - values. + loads and stores to the structure may be assumed by the callee not + to trap and to be properly aligned. This is not a valid attribute + for return values. ``align <n>`` This indicates that the pointer value may be assumed by the optimizer to @@ -1108,10 +1126,11 @@ Currently, only the following parameter attributes are defined: This attribute is motivated to model and optimize Swift error handling. It can be applied to a parameter with pointer to pointer type or a pointer-sized alloca. At the call site, the actual argument that corresponds - to a ``swifterror`` parameter has to come from a ``swifterror`` alloca. A - ``swifterror`` value (either the parameter or the alloca) can only be loaded - and stored from, or used as a ``swifterror`` argument. This is not a valid - attribute for return values and can only be applied to one parameter. + to a ``swifterror`` parameter has to come from a ``swifterror`` alloca or + the ``swifterror`` parameter of the caller. A ``swifterror`` value (either + the parameter or the alloca) can only be loaded and stored from, or used as + a ``swifterror`` argument. This is not a valid attribute for return values + and can only be applied to one parameter. These constraints allow the calling convention to optimize access to ``swifterror`` variables by associating them with a specific register at @@ -1597,9 +1616,6 @@ example: Operand Bundles --------------- -Note: operand bundles are a work in progress, and they should be -considered experimental at this time. - Operand bundles are tagged sets of SSA values that can be associated with certain LLVM instructions (currently only ``call`` s and ``invoke`` s). In a way they are like metadata, but dropping them is @@ -1831,6 +1847,10 @@ as follows: ``n32:64`` for PowerPC 64, or ``n8:16:32:64`` for X86-64. Elements of this set are considered to support most general arithmetic operations efficiently. +``ni:<address space0>:<address space1>:<address space2>...`` + This specifies pointer types with the specified address spaces + as :ref:`Non-Integral Pointer Type <nointptrtype>` s. The ``0`` + address space cannot be specified as non-integral. On every specification that takes a ``<abi>:<pref>``, specifying the ``<pref>`` alignment is optional. If omitted, the preceding ``:`` @@ -2811,6 +2831,9 @@ bits. Any output bit can have a zero or one depending on the input bits. Safe: %A = -1 %B = 0 + Safe: + %A = %X ;; By choosing undef as 0 + %B = %X ;; By choosing undef as -1 Unsafe: %A = undef %B = undef @@ -3362,6 +3385,9 @@ constraints, e.g. "``~{eax}``". The one exception is that a clobber string of memory locations -- not only the memory pointed to by a declared indirect output. +Note that clobbering named registers that are also present in output +constraints is not legal. + Constraint Codes """""""""""""""" @@ -3972,10 +3998,13 @@ DIFile .. code-block:: llvm - !0 = !DIFile(filename: "path/to/file", directory: "/path/to/dir") + !0 = !DIFile(filename: "path/to/file", directory: "/path/to/dir", + checksumkind: CSK_MD5, + checksum: "000102030405060708090a0b0c0d0e0f") Files are sometimes used in ``scope:`` fields, and are the only valid target for ``file:`` fields. +Valid values for ``checksumkind:`` field are: {CSK_None, CSK_MD5, CSK_SHA1} .. _DIBasicType: @@ -4049,6 +4078,7 @@ The following ``tag:`` values are valid: DW_TAG_friend = 42 DW_TAG_volatile_type = 53 DW_TAG_restrict_type = 55 + DW_TAG_atomic_type = 71 .. _DIDerivedTypeMember: @@ -4065,8 +4095,8 @@ friends. ``DW_TAG_typedef`` is used to provide a name for the ``baseType:``. ``DW_TAG_pointer_type``, ``DW_TAG_reference_type``, ``DW_TAG_const_type``, -``DW_TAG_volatile_type`` and ``DW_TAG_restrict_type`` are used to qualify the -``baseType:``. +``DW_TAG_volatile_type``, ``DW_TAG_restrict_type`` and ``DW_TAG_atomic_type`` +are used to qualify the ``baseType:``. Note that the ``void *`` type is expressed as a type derived from NULL. @@ -4562,6 +4592,25 @@ Examples: !2 = !{ i8 0, i8 2, i8 3, i8 6 } !3 = !{ i8 -2, i8 0, i8 3, i8 6 } +'``absolute_symbol``' Metadata +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``absolute_symbol`` metadata may be attached to a global variable +declaration. It marks the declaration as a reference to an absolute symbol, +which causes the backend to use absolute relocations for the symbol even +in position independent code, and expresses the possible ranges that the +global variable's *address* (not its value) is in, in the same format as +``range`` metadata. + +Example: + +.. code-block:: llvm + + @a = external global i8, !absolute_symbol !0 ; Absolute symbol in range [0,256) + + ... + !0 = !{ i64 0, i64 256 } + '``unpredictable``' Metadata ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -4855,7 +4904,8 @@ The existence of the ``invariant.group`` metadata on the instruction tells the optimizer that every ``load`` and ``store`` to the same pointer operand within the same invariant group can be assumed to load or store the same value (but see the ``llvm.invariant.group.barrier`` intrinsic which affects -when two pointers are considered the same). +when two pointers are considered the same). Pointers returned by bitcast or +getelementptr with only zero indices are considered the same. Examples: @@ -4889,6 +4939,10 @@ Examples: !0 = !{!"magic ptr"} !1 = !{!"other ptr"} +'``type``' Metadata +^^^^^^^^^^^^^^^^^^^ + +See :doc:`TypeMetadata`. Module Flags Metadata @@ -6399,9 +6453,7 @@ If the ``nuw`` keyword is present, then the shift produces a :ref:`poison value <poisonvalues>` if it shifts out any non-zero bits. If the ``nsw`` keyword is present, then the shift produces a :ref:`poison value <poisonvalues>` if it shifts out any bits that disagree with the -resultant sign bit. As such, NUW/NSW have the same semantics as they -would if the shift were expressed as a mul instruction with the same -nsw/nuw bits in (mul %op1, (shl 1, %op2)). +resultant sign bit. Example: """""""" @@ -7042,12 +7094,10 @@ as the ``MOVNT`` instruction on x86. The optional ``!invariant.load`` metadata must reference a single metadata name ``<index>`` corresponding to a metadata node with no -entries. The existence of the ``!invariant.load`` metadata on the -instruction tells the optimizer and code generator that the address -operand to this load points to memory which can be assumed unchanged. -Being invariant does not imply that a location is dereferenceable, -but it does imply that once the location is known dereferenceable -its value is henceforth unchanging. +entries. If a load instruction tagged with the ``!invariant.load`` +metadata is executed, the optimizer may assume the memory location +referenced by the load contains the same value at all points in the +program where the memory location is known to be dereferenceable. The optional ``!invariant.group`` metadata must reference a single metadata name ``<index>`` corresponding to a metadata node. See ``invariant.group`` metadata. @@ -7421,9 +7471,9 @@ Syntax: :: - <result> = getelementptr <ty>, <ty>* <ptrval>{, <ty> <idx>}* - <result> = getelementptr inbounds <ty>, <ty>* <ptrval>{, <ty> <idx>}* - <result> = getelementptr <ty>, <ptr vector> <ptrval>, <vector index type> <idx> + <result> = getelementptr <ty>, <ty>* <ptrval>{, [inrange] <ty> <idx>}* + <result> = getelementptr inbounds <ty>, <ty>* <ptrval>{, [inrange] <ty> <idx>}* + <result> = getelementptr <ty>, <ptr vector> <ptrval>, [inrange] <vector index type> <idx> Overview: """"""""" @@ -7540,6 +7590,18 @@ though, even if it happens to point into allocated storage. See the :ref:`Pointer Aliasing Rules <pointeraliasing>` section for more information. +If the ``inrange`` keyword is present before any index, loading from or +storing to any pointer derived from the ``getelementptr`` has undefined +behavior if the load or store would access memory outside of the bounds of +the element selected by the index marked as ``inrange``. The result of a +pointer comparison or ``ptrtoint`` (including ``ptrtoint``-like operations +involving memory) involving a pointer derived from a ``getelementptr`` with +the ``inrange`` keyword is undefined, with the exception of comparisons +in the case where both operands are in the range of the element selected +by the ``inrange`` keyword, inclusive of the address one past the end of +that element. Note that the ``inrange`` keyword is currently only allowed +in constant ``getelementptr`` expressions. + The getelementptr instruction is often confusing. For some more insight into how it works, see :doc:`the getelementptr FAQ <GetElementPtr>`. @@ -9263,6 +9325,32 @@ Note that calling this intrinsic does not prevent function inlining or other aggressive transformations, so the value returned may not be that of the obvious source-language caller. +'``llvm.addressofreturnaddress``' Intrinsic +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: +""""""" + +:: + + declare i8 *@llvm.addressofreturnaddress() + +Overview: +""""""""" + +The '``llvm.addressofreturnaddress``' intrinsic returns a target-specific +pointer to the place in the stack frame where the return address of the +current function is stored. + +Semantics: +"""""""""" + +Note that calling this intrinsic does not prevent function inlining or +other aggressive transformations, so the value returned may not be that +of the obvious source-language caller. + +This intrinsic is only implemented for x86. + '``llvm.frameaddress``' Intrinsic ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -9466,8 +9554,8 @@ Syntax: declare i32 @llvm.get.dynamic.area.offset.i32() declare i64 @llvm.get.dynamic.area.offset.i64() - Overview: - """"""""" +Overview: +""""""""" The '``llvm.get.dynamic.area.offset.*``' intrinsic family is used to get the offset from native stack pointer to the address of the most @@ -9485,7 +9573,7 @@ Semantics: on the caller's stack. In particular, for targets where stack grows downwards, adding this offset to the native stack pointer would get the address of the most recent dynamic alloca. For targets where stack grows upwards, the situation is a bit more - complicated, because substracting this value from stack pointer would get the address + complicated, because subtracting this value from stack pointer would get the address one past the end of the most recent dynamic alloca. Although for most targets `llvm.get.dynamic.area.offset <int_get_dynamic_area_offset>` @@ -9673,6 +9761,37 @@ structures and the code to increment the appropriate value, in a format that can be written out by a compiler runtime and consumed via the ``llvm-profdata`` tool. +'``llvm.instrprof_increment_step``' Intrinsic +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: +""""""" + +:: + + declare void @llvm.instrprof_increment_step(i8* <name>, i64 <hash>, + i32 <num-counters>, + i32 <index>, i64 <step>) + +Overview: +""""""""" + +The '``llvm.instrprof_increment_step``' intrinsic is an extension to +the '``llvm.instrprof_increment``' intrinsic with an additional fifth +argument to specify the step of the increment. + +Arguments: +"""""""""" +The first four arguments are the same as '``llvm.instrprof_increment``' +instrinsic. + +The last argument specifies the value of the increment of the counter variable. + +Semantics: +"""""""""" +See description of '``llvm.instrprof_increment``' instrinsic. + + '``llvm.instrprof_value_profile``' Intrinsic ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -10717,7 +10836,7 @@ bitpattern of an integer value; for example ``0b10110110`` becomes Semantics: """""""""" -The ``llvm.bitreverse.iN`` intrinsic returns an i16 value that has bit +The ``llvm.bitreverse.iN`` intrinsic returns an iN value that has bit ``M`` in the input moved to bit ``N-M`` in the output. '``llvm.bswap.*``' Intrinsics @@ -11842,10 +11961,11 @@ object following this intrinsic may be removed as dead. Syntax: """"""" +This is an overloaded intrinsic. The memory object can belong to any address space. :: - declare {}* @llvm.invariant.start(i64 <size>, i8* nocapture <ptr>) + declare {}* @llvm.invariant.start.p0i8(i64 <size>, i8* nocapture <ptr>) Overview: """"""""" @@ -11872,10 +11992,11 @@ unchanging. Syntax: """"""" +This is an overloaded intrinsic. The memory object can belong to any address space. :: - declare void @llvm.invariant.end({}* <start>, i64 <size>, i8* nocapture <ptr>) + declare void @llvm.invariant.end.p0i8({}* <start>, i64 <size>, i8* nocapture <ptr>) Overview: """"""""" @@ -12541,3 +12662,79 @@ Stack Map Intrinsics LLVM provides experimental intrinsics to support runtime patching mechanisms commonly desired in dynamic language JITs. These intrinsics are described in :doc:`StackMaps`. + +Element Wise Atomic Memory Intrinsics +------------------------------------- + +These intrinsics are similar to the standard library memory intrinsics except +that they perform memory transfer as a sequence of atomic memory accesses. + +.. _int_memcpy_element_atomic: + +'``llvm.memcpy.element.atomic``' Intrinsic +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: +""""""" + +This is an overloaded intrinsic. You can use ``llvm.memcpy.element.atomic`` on +any integer bit width and for different address spaces. Not all targets +support all bit widths however. + +:: + + declare void @llvm.memcpy.element.atomic.p0i8.p0i8(i8* <dest>, i8* <src>, + i64 <num_elements>, i32 <element_size>) + +Overview: +""""""""" + +The '``llvm.memcpy.element.atomic.*``' intrinsic performs copy of a block of +memory from the source location to the destination location as a sequence of +unordered atomic memory accesses where each access is a multiple of +``element_size`` bytes wide and aligned at an element size boundary. For example +each element is accessed atomically in source and destination buffers. + +Arguments: +"""""""""" + +The first argument is a pointer to the destination, the second is a +pointer to the source. The third argument is an integer argument +specifying the number of elements to copy, the fourth argument is size of +the single element in bytes. + +``element_size`` should be a power of two, greater than zero and less than +a target-specific atomic access size limit. + +For each of the input pointers ``align`` parameter attribute must be specified. +It must be a power of two and greater than or equal to the ``element_size``. +Caller guarantees that both the source and destination pointers are aligned to +that boundary. + +Semantics: +"""""""""" + +The '``llvm.memcpy.element.atomic.*``' intrinsic copies +'``num_elements`` * ``element_size``' bytes of memory from the source location to +the destination location. These locations are not allowed to overlap. Memory copy +is performed as a sequence of unordered atomic memory accesses where each access +is guaranteed to be a multiple of ``element_size`` bytes wide and aligned at an +element size boundary. + +The order of the copy is unspecified. The same value may be read from the source +buffer many times, but only one write is issued to the destination buffer per +element. It is well defined to have concurrent reads and writes to both source +and destination provided those reads and writes are at least unordered atomic. + +This intrinsic does not provide any additional ordering guarantees over those +provided by a set of unordered loads from the source location and stores to the +destination. + +Lowering: +""""""""" + +In the most general case call to the '``llvm.memcpy.element.atomic.*``' is lowered +to a call to the symbol ``__llvm_memcpy_element_atomic_*``. Where '*' is replaced +with an actual element size. + +Optimizer is allowed to inline memory copy when it's profitable to do so. diff --git a/docs/Lexicon.rst b/docs/Lexicon.rst index 912dee2cf0790..de929bec1b0e9 100644 --- a/docs/Lexicon.rst +++ b/docs/Lexicon.rst @@ -180,6 +180,10 @@ O P - +**PR** + Problem report. A bug filed on `the LLVM Bug Tracking System + <http://llvm.org/bugs/enter_bug.cgi>`_. + **PRE** Partial Redundancy Elimination diff --git a/docs/LibFuzzer.rst b/docs/LibFuzzer.rst index 92937c2d0b529..c4abe123a0ea4 100644 --- a/docs/LibFuzzer.rst +++ b/docs/LibFuzzer.rst @@ -8,18 +8,13 @@ libFuzzer – a library for coverage-guided fuzz testing. Introduction ============ -LibFuzzer is a library for in-process, coverage-guided, evolutionary fuzzing -of other libraries. +LibFuzzer is in-process, coverage-guided, evolutionary fuzzing engine. -LibFuzzer is similar in concept to American Fuzzy Lop (AFL_), but it performs -all of its fuzzing inside a single process. This in-process fuzzing can be more -restrictive and fragile, but is potentially much faster as there is no overhead -for process start-up. - -The fuzzer is linked with the library under test, and feeds fuzzed inputs to the +LibFuzzer is linked with the library under test, and feeds fuzzed inputs to the library via a specific fuzzing entrypoint (aka "target function"); the fuzzer then tracks which areas of the code are reached, and generates mutations on the -corpus of input data in order to maximize the code coverage. The code coverage +corpus of input data in order to maximize the code coverage. +The code coverage information for libFuzzer is provided by LLVM's SanitizerCoverage_ instrumentation. @@ -28,8 +23,8 @@ Contact: libfuzzer(#)googlegroups.com Versions ======== -LibFuzzer is under active development so a current (or at least very recent) -version of Clang is the only supported variant. +LibFuzzer is under active development so you will need the current +(or at least a very recent) version of the Clang compiler. (If `building Clang from trunk`_ is too time-consuming or difficult, then the Clang binaries that the Chromium developers build are likely to be @@ -53,7 +48,6 @@ infrastructure and can be used for other projects without requiring the rest of LLVM. - Getting Started =============== @@ -61,11 +55,13 @@ Getting Started :local: :depth: 1 -Building --------- +Fuzz Target +----------- -The first step for using libFuzzer on a library is to implement a fuzzing -target function that accepts a sequence of bytes, like this: +The first step in using libFuzzer on a library is to implement a +*fuzz target* -- a function that accepts an array of bytes and +does something interesting with these bytes using the API under test. +Like this: .. code-block:: c++ @@ -75,21 +71,37 @@ target function that accepts a sequence of bytes, like this: return 0; // Non-zero return values are reserved for future use. } +Note that this fuzz target does not depend on libFuzzer in any way +and so it is possible and even desirable to use it with other fuzzing engines +e.g. AFL_ and/or Radamsa_. + +Some important things to remember about fuzz targets: + +* The fuzzing engine will execute the fuzz target many times with different inputs in the same process. +* It must tolerate any kind of input (empty, huge, malformed, etc). +* It must not `exit()` on any input. +* It may use threads but ideally all threads should be joined at the end of the function. +* It must be as deterministic as possible. Non-determinism (e.g. random decisions not based on the input bytes) will make fuzzing inefficient. +* It must be fast. Try avoiding cubic or greater complexity, logging, or excessive memory consumption. +* Ideally, it should not modify any global state (although that's not strict). +* Usually, the narrower the target the better. E.g. if your target can parse several data formats, split it into several targets, one per format. + + +Building +-------- + Next, build the libFuzzer library as a static archive, without any sanitizer options. Note that the libFuzzer library contains the ``main()`` function: .. code-block:: console - svn co http://llvm.org/svn/llvm-project/llvm/trunk/lib/Fuzzer - # Alternative: get libFuzzer from a dedicated git mirror: - # git clone https://chromium.googlesource.com/chromium/llvm-project/llvm/lib/Fuzzer - clang++ -c -g -O2 -std=c++11 Fuzzer/*.cpp -IFuzzer - ar ruv libFuzzer.a Fuzzer*.o + svn co http://llvm.org/svn/llvm-project/llvm/trunk/lib/Fuzzer # or git clone https://chromium.googlesource.com/chromium/llvm-project/llvm/lib/Fuzzer + ./Fuzzer/build.sh # Produces libFuzzer.a Then build the fuzzing target function and the library under test using the SanitizerCoverage_ option, which instruments the code so that the fuzzer can retrieve code coverage information (to guide the fuzzing). Linking with -the libFuzzer code then gives an fuzzer executable. +the libFuzzer code then gives a fuzzer executable. You should also enable one or more of the *sanitizers*, which help to expose latent bugs by making incorrect behavior generate errors at runtime: @@ -105,7 +117,7 @@ latent bugs by making incorrect behavior generate errors at runtime: Finally, link with ``libFuzzer.a``:: - clang -fsanitize-coverage=edge -fsanitize=address your_lib.cc fuzz_target.cc libFuzzer.a -o my_fuzzer + clang -fsanitize-coverage=trace-pc-guard -fsanitize=address your_lib.cc fuzz_target.cc libFuzzer.a -o my_fuzzer Corpus ------ @@ -229,8 +241,9 @@ The most important command line options are: The limit is checked in a separate thread every second. If running w/o ASAN/MSAN, you may use 'ulimit -v' instead. ``-timeout_exitcode`` - Exit code (default 77) to emit when terminating due to timeout, when - ``-abort_on_timeout`` is not set. + Exit code (default 77) used if libFuzzer reports a timeout. +``-error_exitcode`` + Exit code (default 77) used if libFuzzer itself (not a sanitizer) reports a bug (leak, OOM, etc). ``-max_total_time`` If positive, indicates the maximum total time in seconds to run the fuzzer. If 0 (the default), run indefinitely. @@ -238,6 +251,9 @@ The most important command line options are: If set to 1, any corpus inputs from the 2nd, 3rd etc. corpus directories that trigger new code coverage will be merged into the first corpus directory. Defaults to 0. This flag can be used to minimize a corpus. +``-minimize_crash`` + If 1, minimizes the provided crash input. + Use with -runs=N or -max_total_time=N to limit the number of attempts. ``-reload`` If set to 1 (the default), the corpus directory is re-read periodically to check for new inputs; this allows detection of new inputs that were discovered @@ -256,8 +272,8 @@ The most important command line options are: ``-use_counters`` Use `coverage counters`_ to generate approximate counts of how often code blocks are hit; defaults to 1. -``-use_traces`` - Use instruction traces (experimental, defaults to 0); see `Data-flow-guided fuzzing`_. +``-use_value_profile`` + Use `value profile`_ to guide corpus expansion; defaults to 0. ``-only_ascii`` If 1, generate only ASCII (``isprint``+``isspace``) inputs. Defaults to 0. ``-artifact_prefix`` @@ -268,9 +284,11 @@ The most important command line options are: failure (crash, timeout) as ``$(exact_artifact_path)``. This overrides ``-artifact_prefix`` and will not use checksum in the file name. Do not use the same path for several parallel processes. +``-print_pcs`` + If 1, print out newly covered PCs. Defaults to 0. ``-print_final_stats`` If 1, print statistics at exit. Defaults to 0. -``-detect-leaks`` +``-detect_leaks`` If 1 (default) and if LeakSanitizer is enabled try to detect memory leaks during fuzzing (i.e. not only at shut down). ``-close_fd_mask`` @@ -289,14 +307,16 @@ Output During operation the fuzzer prints information to ``stderr``, for example:: - INFO: Seed: 3338750330 - Loaded 1024/1211 files from corpus/ + INFO: Seed: 1523017872 + INFO: Loaded 1 modules (16 guards): [0x744e60, 0x744ea0), INFO: -max_len is not provided, using 64 - #0 READ units: 1211 exec/s: 0 - #1211 INITED cov: 2575 bits: 8855 indir: 5 units: 830 exec/s: 1211 - #1422 NEW cov: 2580 bits: 8860 indir: 5 units: 831 exec/s: 1422 L: 21 MS: 1 ShuffleBytes- - #1688 NEW cov: 2581 bits: 8865 indir: 5 units: 832 exec/s: 1688 L: 19 MS: 2 EraseByte-CrossOver- - #1734 NEW cov: 2583 bits: 8879 indir: 5 units: 833 exec/s: 1734 L: 27 MS: 3 ChangeBit-EraseByte-ShuffleBytes- + INFO: A corpus is not provided, starting from an empty corpus + #0 READ units: 1 + #1 INITED cov: 3 ft: 2 corp: 1/1b exec/s: 0 rss: 24Mb + #3811 NEW cov: 4 ft: 3 corp: 2/2b exec/s: 0 rss: 25Mb L: 1 MS: 5 ChangeBit-ChangeByte-ChangeBit-ShuffleBytes-ChangeByte- + #3827 NEW cov: 5 ft: 4 corp: 3/4b exec/s: 0 rss: 25Mb L: 2 MS: 1 CopyPart- + #3963 NEW cov: 6 ft: 5 corp: 4/6b exec/s: 0 rss: 25Mb L: 2 MS: 2 ShuffleBytes-ChangeBit- + #4167 NEW cov: 7 ft: 6 corp: 5/9b exec/s: 0 rss: 25Mb L: 3 MS: 1 InsertByte- ... The early parts of the output include information about the fuzzer options and @@ -321,9 +341,6 @@ possible event codes are: ``DONE`` The fuzzer has completed operation because it has reached the specified iteration limit (``-runs``) or time limit (``-max_total_time``). -``MIN<n>`` - The fuzzer is minimizing the combination of input corpus directories into - a single unified corpus (due to the ``-merge`` command line option). ``RELOAD`` The fuzzer is performing a periodic reload of inputs from the corpus directory; this allows it to discover any inputs discovered by other @@ -334,17 +351,16 @@ Each output line also reports the following statistics (when non-zero): ``cov:`` Total number of code blocks or edges covered by the executing the current corpus. -``bits:`` - Rough measure of the number of code blocks or edges covered, and how often; - only valid if the fuzzer is run with ``-use_counters=1``. -``indir:`` - Number of distinct function `caller-callee pairs`_ executed with the - current corpus; only valid if the code under test was built with - ``-fsanitize-coverage=indirect-calls``. -``units:`` - Number of entries in the current input corpus. +``ft:`` + libFuzzer uses different signals to evaluate the code coverage: + edge coverage, edge counters, value profiles, indirect caller/callee pairs, etc. + These signals combined are called *features* (`ft:`). +``corp:`` + Number of entries in the current in-memory test corpus and its size in bytes. ``exec/s:`` Number of fuzzer iterations per second. +``rss:`` + Current memory consumption. For ``NEW`` events, the output line also includes information about the mutation operation that produced the new input: @@ -379,189 +395,34 @@ A simple function that does something interesting if it receives the input } EOF # Build test_fuzzer.cc with asan and link against libFuzzer.a - clang++ -fsanitize=address -fsanitize-coverage=edge test_fuzzer.cc libFuzzer.a + clang++ -fsanitize=address -fsanitize-coverage=trace-pc-guard test_fuzzer.cc libFuzzer.a # Run the fuzzer with no corpus. ./a.out You should get an error pretty quickly:: - #0 READ units: 1 exec/s: 0 - #1 INITED cov: 3 units: 1 exec/s: 0 - #2 NEW cov: 5 units: 2 exec/s: 0 L: 64 MS: 0 - #19237 NEW cov: 9 units: 3 exec/s: 0 L: 64 MS: 0 - #20595 NEW cov: 10 units: 4 exec/s: 0 L: 1 MS: 4 ChangeASCIIInt-ShuffleBytes-ChangeByte-CrossOver- - #34574 NEW cov: 13 units: 5 exec/s: 0 L: 2 MS: 3 ShuffleBytes-CrossOver-ChangeBit- - #34807 NEW cov: 15 units: 6 exec/s: 0 L: 3 MS: 1 CrossOver- - ==31511== ERROR: libFuzzer: deadly signal - ... - artifact_prefix='./'; Test unit written to ./crash-b13e8756b13a00cf168300179061fb4b91fefbed - - -PCRE2 ------ - -Here we show how to use libFuzzer on something real, yet simple: pcre2_:: - - COV_FLAGS=" -fsanitize-coverage=edge,indirect-calls,8bit-counters" - # Get PCRE2 - wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre2-10.20.tar.gz - tar xf pcre2-10.20.tar.gz - # Build PCRE2 with AddressSanitizer and coverage; requires autotools. - (cd pcre2-10.20; ./autogen.sh; CC="clang -fsanitize=address $COV_FLAGS" ./configure --prefix=`pwd`/../inst && make -j && make install) - # Build the fuzzing target function that does something interesting with PCRE2. - cat << EOF > pcre_fuzzer.cc - #include <string.h> - #include <stdint.h> - #include "pcre2posix.h" - extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { - if (size < 1) return 0; - char *str = new char[size+1]; - memcpy(str, data, size); - str[size] = 0; - regex_t preg; - if (0 == regcomp(&preg, str, 0)) { - regexec(&preg, str, 0, 0, 0); - regfree(&preg); - } - delete [] str; - return 0; - } - EOF - clang++ -g -fsanitize=address $COV_FLAGS -c -std=c++11 -I inst/include/ pcre_fuzzer.cc - # Link. - clang++ -g -fsanitize=address -Wl,--whole-archive inst/lib/*.a -Wl,-no-whole-archive libFuzzer.a pcre_fuzzer.o -o pcre_fuzzer - -This will give you a binary of the fuzzer, called ``pcre_fuzzer``. -Now, create a directory that will hold the test corpus: - -.. code-block:: console - - mkdir -p CORPUS - -For simple input languages like regular expressions this is all you need. -For more complicated/structured inputs, the fuzzer works much more efficiently -if you can populate the corpus directory with a variety of valid and invalid -inputs for the code under test. -Now run the fuzzer with the corpus directory as the only parameter: - -.. code-block:: console - - ./pcre_fuzzer ./CORPUS - -Initially, you will see Output_ like this:: - - INFO: Seed: 2938818941 + INFO: Seed: 1523017872 + INFO: Loaded 1 modules (16 guards): [0x744e60, 0x744ea0), INFO: -max_len is not provided, using 64 INFO: A corpus is not provided, starting from an empty corpus - #0 READ units: 1 exec/s: 0 - #1 INITED cov: 3 bits: 3 units: 1 exec/s: 0 - #2 NEW cov: 176 bits: 176 indir: 3 units: 2 exec/s: 0 L: 64 MS: 0 - #8 NEW cov: 176 bits: 179 indir: 3 units: 3 exec/s: 0 L: 63 MS: 2 ChangeByte-EraseByte- - ... - #14004 NEW cov: 1500 bits: 4536 indir: 5 units: 406 exec/s: 0 L: 54 MS: 3 ChangeBit-ChangeBit-CrossOver- - -Now, interrupt the fuzzer and run it again the same way. You will see:: - - INFO: Seed: 3398349082 - INFO: -max_len is not provided, using 64 - #0 READ units: 405 exec/s: 0 - #405 INITED cov: 1499 bits: 4535 indir: 5 units: 286 exec/s: 0 - #587 NEW cov: 1499 bits: 4540 indir: 5 units: 287 exec/s: 0 L: 52 MS: 2 InsertByte-EraseByte- - #667 NEW cov: 1501 bits: 4542 indir: 5 units: 288 exec/s: 0 L: 39 MS: 2 ChangeBit-InsertByte- - #672 NEW cov: 1501 bits: 4543 indir: 5 units: 289 exec/s: 0 L: 15 MS: 2 ChangeASCIIInt-ChangeBit- - #739 NEW cov: 1501 bits: 4544 indir: 5 units: 290 exec/s: 0 L: 64 MS: 4 ShuffleBytes-ChangeASCIIInt-InsertByte-ChangeBit- + #0 READ units: 1 + #1 INITED cov: 3 ft: 2 corp: 1/1b exec/s: 0 rss: 24Mb + #3811 NEW cov: 4 ft: 3 corp: 2/2b exec/s: 0 rss: 25Mb L: 1 MS: 5 ChangeBit-ChangeByte-ChangeBit-ShuffleBytes-ChangeByte- + #3827 NEW cov: 5 ft: 4 corp: 3/4b exec/s: 0 rss: 25Mb L: 2 MS: 1 CopyPart- + #3963 NEW cov: 6 ft: 5 corp: 4/6b exec/s: 0 rss: 25Mb L: 2 MS: 2 ShuffleBytes-ChangeBit- + #4167 NEW cov: 7 ft: 6 corp: 5/9b exec/s: 0 rss: 25Mb L: 3 MS: 1 InsertByte- + ==31511== ERROR: libFuzzer: deadly signal ... + artifact_prefix='./'; Test unit written to ./crash-b13e8756b13a00cf168300179061fb4b91fefbed -On the second execution the fuzzer has a non-empty input corpus (405 items). As -the first step, the fuzzer minimized this corpus (the ``INITED`` line) to -produce 286 interesting items, omitting inputs that do not hit any additional -code. - -(Aside: although the fuzzer only saves new inputs that hit additional code, this -does not mean that the corpus as a whole is kept minimized. For example, if -an input hitting A-B-C then an input that hits A-B-C-D are generated, -they will both be saved, even though the latter subsumes the former.) - - -You may run ``N`` independent fuzzer jobs in parallel on ``M`` CPUs: - -.. code-block:: console - - N=100; M=4; ./pcre_fuzzer ./CORPUS -jobs=$N -workers=$M - -By default (``-reload=1``) the fuzzer processes will periodically scan the corpus directory -and reload any new tests. This way the test inputs found by one process will be picked up -by all others. - -If ``-workers=$M`` is not supplied, ``min($N,NumberOfCpuCore/2)`` will be used. - -Heartbleed ----------- -Remember Heartbleed_? -As it was recently `shown <https://blog.hboeck.de/archives/868-How-Heartbleed-couldve-been-found.html>`_, -fuzzing with AddressSanitizer_ can find Heartbleed. Indeed, here are the step-by-step instructions -to find Heartbleed with libFuzzer:: - - wget https://www.openssl.org/source/openssl-1.0.1f.tar.gz - tar xf openssl-1.0.1f.tar.gz - COV_FLAGS="-fsanitize-coverage=edge,indirect-calls" # -fsanitize-coverage=8bit-counters - (cd openssl-1.0.1f/ && ./config && - make -j 32 CC="clang -g -fsanitize=address $COV_FLAGS") - # Get and build libFuzzer - svn co http://llvm.org/svn/llvm-project/llvm/trunk/lib/Fuzzer - clang -c -g -O2 -std=c++11 Fuzzer/*.cpp -IFuzzer - # Get examples of key/pem files. - git clone https://github.com/hannob/selftls - cp selftls/server* . -v - cat << EOF > handshake-fuzz.cc - #include <openssl/ssl.h> - #include <openssl/err.h> - #include <assert.h> - #include <stdint.h> - #include <stddef.h> - - SSL_CTX *sctx; - int Init() { - SSL_library_init(); - SSL_load_error_strings(); - ERR_load_BIO_strings(); - OpenSSL_add_all_algorithms(); - assert (sctx = SSL_CTX_new(TLSv1_method())); - assert (SSL_CTX_use_certificate_file(sctx, "server.pem", SSL_FILETYPE_PEM)); - assert (SSL_CTX_use_PrivateKey_file(sctx, "server.key", SSL_FILETYPE_PEM)); - return 0; - } - extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { - static int unused = Init(); - SSL *server = SSL_new(sctx); - BIO *sinbio = BIO_new(BIO_s_mem()); - BIO *soutbio = BIO_new(BIO_s_mem()); - SSL_set_bio(server, sinbio, soutbio); - SSL_set_accept_state(server); - BIO_write(sinbio, Data, Size); - SSL_do_handshake(server); - SSL_free(server); - return 0; - } - EOF - # Build the fuzzer. - clang++ -g handshake-fuzz.cc -fsanitize=address \ - openssl-1.0.1f/libssl.a openssl-1.0.1f/libcrypto.a Fuzzer*.o - # Run 20 independent fuzzer jobs. - ./a.out -jobs=20 -workers=20 -Voila:: +More examples +------------- - #1048576 pulse cov 3424 bits 0 units 9 exec/s 24385 - ================================================================= - ==17488==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x629000004748 at pc 0x00000048c979 bp 0x7fffe3e864f0 sp 0x7fffe3e85ca8 - READ of size 60731 at 0x629000004748 thread T0 - #0 0x48c978 in __asan_memcpy - #1 0x4db504 in tls1_process_heartbeat openssl-1.0.1f/ssl/t1_lib.c:2586:3 - #2 0x580be3 in ssl3_read_bytes openssl-1.0.1f/ssl/s3_pkt.c:1092:4 +Examples of real-life fuzz targets and the bugs they find can be found +at http://tutorial.libfuzzer.info. Among other things you can learn how +to detect Heartbleed_ in one second. -Note: a `similar fuzzer <https://boringssl.googlesource.com/boringssl/+/HEAD/FUZZING.md>`_ -is now a part of the BoringSSL_ source tree. Advanced features ================= @@ -588,17 +449,37 @@ The dictionary syntax is similar to that used by AFL_ for its ``-x`` option:: # the name of the keyword followed by '=' may be omitted: "foo\x0Abar" -Data-flow-guided fuzzing + + +Tracing CMP instructions ------------------------ +With an additional compiler flag ``-fsanitize-coverage=trace-cmp`` +(see SanitizerCoverageTraceDataFlow_) +libFuzzer will intercept CMP instructions and guide mutations based +on the arguments of intercepted CMP instructions. This may slow down +the fuzzing but is very likely to improve the results. + +Value Profile +------------- + *EXPERIMENTAL*. -With an additional compiler flag ``-fsanitize-coverage=trace-cmp`` (see SanitizerCoverageTraceDataFlow_) -and extra run-time flag ``-use_traces=1`` the fuzzer will try to apply *data-flow-guided fuzzing*. -That is, the fuzzer will record the inputs to comparison instructions, switch statements, -and several libc functions (``memcmp``, ``strcmp``, ``strncmp``, etc). -It will later use those recorded inputs during mutations. +With ``-fsanitize-coverage=trace-cmp`` +and extra run-time flag ``-use_value_profile=1`` the fuzzer will +collect value profiles for the parameters of compare instructions +and treat some new values as new coverage. + +The current imlpementation does roughly the following: -This mode can be combined with DataFlowSanitizer_ to achieve better sensitivity. +* The compiler instruments all CMP instructions with a callback that receives both CMP arguments. +* The callback computes `(caller_pc&4095) | (popcnt(Arg1 ^ Arg2) << 12)` and uses this value to set a bit in a bitset. +* Every new observed bit in the bitset is treated as new coverage. + + +This feature has a potential to discover many interesting inputs, +but there are two downsides. +First, the extra instrumentation may bring up to 2x additional slowdown. +Second, the corpus may grow by several times. Fuzzer-friendly build mode --------------------------- @@ -656,11 +537,12 @@ You can get the coverage for your corpus like this: .. code-block:: console - ASAN_OPTIONS=coverage=1:html_cov_report=1 ./fuzzer CORPUS_DIR -runs=0 + ASAN_OPTIONS=coverage=1 ./fuzzer CORPUS_DIR -runs=0 This will run all tests in the CORPUS_DIR but will not perform any fuzzing. -At the end of the process it will dump a single html file with coverage information. -See SanitizerCoverage_ for details. +At the end of the process it will dump a single ``.sancov`` file with coverage +information. See SanitizerCoverage_ for details on querying the file using the +``sancov`` tool. You may also use other ways to visualize coverage, e.g. using `Clang coverage <http://clang.llvm.org/docs/SourceBasedCodeCoverage.html>`_, @@ -816,7 +698,7 @@ Q. What about Windows then? The fuzzer contains code that does not build on Wind Volunteers are welcome. -Q. When this Fuzzer is not a good solution for a problem? +Q. When libFuzzer is not a good solution for a problem? --------------------------------------------------------- * If the test inputs are validated by the target library and the validator @@ -884,13 +766,17 @@ Trophies * WOFF2: `[1] <https://github.com/google/woff2/commit/a15a8ab>`__ -* LLVM: `Clang <https://llvm.org/bugs/show_bug.cgi?id=23057>`_, `Clang-format <https://llvm.org/bugs/show_bug.cgi?id=23052>`_, `libc++ <https://llvm.org/bugs/show_bug.cgi?id=24411>`_, `llvm-as <https://llvm.org/bugs/show_bug.cgi?id=24639>`_, Disassembler: http://reviews.llvm.org/rL247405, http://reviews.llvm.org/rL247414, http://reviews.llvm.org/rL247416, http://reviews.llvm.org/rL247417, http://reviews.llvm.org/rL247420, http://reviews.llvm.org/rL247422. +* LLVM: `Clang <https://llvm.org/bugs/show_bug.cgi?id=23057>`_, `Clang-format <https://llvm.org/bugs/show_bug.cgi?id=23052>`_, `libc++ <https://llvm.org/bugs/show_bug.cgi?id=24411>`_, `llvm-as <https://llvm.org/bugs/show_bug.cgi?id=24639>`_, `Demangler <https://bugs.chromium.org/p/chromium/issues/detail?id=606626>`_, Disassembler: http://reviews.llvm.org/rL247405, http://reviews.llvm.org/rL247414, http://reviews.llvm.org/rL247416, http://reviews.llvm.org/rL247417, http://reviews.llvm.org/rL247420, http://reviews.llvm.org/rL247422. + +* Tensorflow: `[1] <https://github.com/tensorflow/tensorflow/commit/7231d01fcb2cd9ef9ffbfea03b724892c8a4026e>`__ + +* Ffmpeg: `[1] <https://github.com/FFmpeg/FFmpeg/commit/c92f55847a3d9cd12db60bfcd0831ff7f089c37c>`__ `[2] <https://github.com/FFmpeg/FFmpeg/commit/25ab1a65f3acb5ec67b53fb7a2463a7368f1ad16>`__ `[3] <https://github.com/FFmpeg/FFmpeg/commit/85d23e5cbc9ad6835eef870a5b4247de78febe56>`__ `[4] <https://github.com/FFmpeg/FFmpeg/commit/04bd1b38ee6b8df410d0ab8d4949546b6c4af26a>`__ .. _pcre2: http://www.pcre.org/ .. _AFL: http://lcamtuf.coredump.cx/afl/ +.. _Radamsa: https://github.com/aoh/radamsa .. _SanitizerCoverage: http://clang.llvm.org/docs/SanitizerCoverage.html .. _SanitizerCoverageTraceDataFlow: http://clang.llvm.org/docs/SanitizerCoverage.html#tracing-data-flow -.. _DataFlowSanitizer: http://clang.llvm.org/docs/DataFlowSanitizer.html .. _AddressSanitizer: http://clang.llvm.org/docs/AddressSanitizer.html .. _LeakSanitizer: http://clang.llvm.org/docs/LeakSanitizer.html .. _Heartbleed: http://en.wikipedia.org/wiki/Heartbleed @@ -900,6 +786,7 @@ Trophies .. _MemorySanitizer: http://clang.llvm.org/docs/MemorySanitizer.html .. _UndefinedBehaviorSanitizer: http://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html .. _`coverage counters`: http://clang.llvm.org/docs/SanitizerCoverage.html#coverage-counters +.. _`value profile`: #value-profile .. _`caller-callee pairs`: http://clang.llvm.org/docs/SanitizerCoverage.html#caller-callee-coverage .. _BoringSSL: https://boringssl.googlesource.com/boringssl/ .. _`fuzz various parts of LLVM itself`: `Fuzzing components of LLVM`_ diff --git a/docs/LinkTimeOptimization.rst b/docs/LinkTimeOptimization.rst index 9c1e5607596bb..010a7881623c3 100644 --- a/docs/LinkTimeOptimization.rst +++ b/docs/LinkTimeOptimization.rst @@ -9,7 +9,7 @@ Description =========== LLVM features powerful intermodular optimizations which can be used at link -time. Link Time Optimization (LTO) is another name for intermodular +time. Link Time Optimization (LTO) is another name for intermodular optimization when performed during the link stage. This document describes the interface and design between the LTO optimizer and the linker. @@ -21,7 +21,7 @@ intermodular optimization, in the compiler tool chain. Its main goal is to let the developer take advantage of intermodular optimizations without making any significant changes to the developer's makefiles or build system. This is achieved through tight integration with the linker. In this model, the linker -treates LLVM bitcode files like native object files and allows mixing and +treats LLVM bitcode files like native object files and allows mixing and matching among them. The linker uses `libLTO`_, a shared object, to handle LLVM bitcode files. This tight integration between the linker and LLVM optimizer helps to do optimizations that are not possible in other models. The linker @@ -34,7 +34,7 @@ Example of link time optimization The following example illustrates the advantages of LTO's integrated approach and clean interface. This example requires a system linker which supports LTO -through the interface described in this document. Here, clang transparently +through the interface described in this document. Here, clang transparently invokes system linker. * Input source file ``a.c`` is compiled into LLVM bitcode form. @@ -64,7 +64,7 @@ invokes system linker. int foo1(void) { int data = 0; - if (i < 0) + if (i < 0) data = foo3(); data = data + 42; @@ -121,12 +121,12 @@ Alternative Approaches In this model, a new, separate, tool or library replicates the linker's capability to collect information for link time optimization. Not only is this code duplication difficult to justify, but it also has several other - disadvantages. For example, the linking semantics and the features provided + disadvantages. For example, the linking semantics and the features provided by the linker on various platform are not unique. This means, this new tool needs to support all such features and platforms in one super tool or a separate tool per platform is required. This increases maintenance cost for link time optimizer significantly, which is not necessary. This approach - also requires staying synchronized with linker developements on various + also requires staying synchronized with linker developments on various platforms, which is not the main focus of the link time optimizer. Finally, this approach increases end user's build time due to the duplication of work done by this separate tool and the linker itself. @@ -136,12 +136,12 @@ Multi-phase communication between ``libLTO`` and linker The linker collects information about symbol definitions and uses in various link objects which is more accurate than any information collected by other -tools during typical build cycles. The linker collects this information by +tools during typical build cycles. The linker collects this information by looking at the definitions and uses of symbols in native .o files and using symbol visibility information. The linker also uses user-supplied information, such as a list of exported symbols. LLVM optimizer collects control flow information, data flow information and knows much more about program structure -from the optimizer's point of view. Our goal is to take advantage of tight +from the optimizer's point of view. Our goal is to take advantage of tight integration between the linker and the optimizer by sharing this information during various linking phases. @@ -152,33 +152,33 @@ The linker first reads all object files in natural order and collects symbol information. This includes native object files as well as LLVM bitcode files. To minimize the cost to the linker in the case that all .o files are native object files, the linker only calls ``lto_module_create()`` when a supplied -object file is found to not be a native object file. If ``lto_module_create()`` +object file is found to not be a native object file. If ``lto_module_create()`` returns that the file is an LLVM bitcode file, the linker then iterates over the module using ``lto_module_get_symbol_name()`` and ``lto_module_get_symbol_attribute()`` to get all symbols defined and referenced. This information is added to the linker's global symbol table. -The lto* functions are all implemented in a shared object libLTO. This allows -the LLVM LTO code to be updated independently of the linker tool. On platforms +The lto* functions are all implemented in a shared object libLTO. This allows +the LLVM LTO code to be updated independently of the linker tool. On platforms that support it, the shared object is lazily loaded. Phase 2 : Symbol Resolution --------------------------- -In this stage, the linker resolves symbols using global symbol table. It may +In this stage, the linker resolves symbols using global symbol table. It may report undefined symbol errors, read archive members, replace weak symbols, etc. The linker is able to do this seamlessly even though it does not know the exact -content of input LLVM bitcode files. If dead code stripping is enabled then the +content of input LLVM bitcode files. If dead code stripping is enabled then the linker collects the list of live symbols. Phase 3 : Optimize Bitcode Files -------------------------------- After symbol resolution, the linker tells the LTO shared object which symbols -are needed by native object files. In the example above, the linker reports +are needed by native object files. In the example above, the linker reports that only ``foo1()`` is used by native object files using -``lto_codegen_add_must_preserve_symbol()``. Next the linker invokes the LLVM +``lto_codegen_add_must_preserve_symbol()``. Next the linker invokes the LLVM optimizer and code generators using ``lto_codegen_compile()`` which returns a native object file creating by merging the LLVM bitcode files and applying various optimization passes. @@ -212,7 +212,7 @@ their object files and the standard linker tool. ``lto_module_t`` ---------------- -A non-native object file is handled via an ``lto_module_t``. The following +A non-native object file is handled via an ``lto_module_t``. The following functions allow the linker to check if a file (on disk or in a memory buffer) is a file which libLTO can process: @@ -254,7 +254,7 @@ The attributes of a symbol include the alignment, visibility, and kind. Once the linker has loaded each non-native object files into an ``lto_module_t``, it can request ``libLTO`` to process them all and generate a -native object file. This is done in a couple of steps. First, a code generator +native object file. This is done in a couple of steps. First, a code generator is created with: .. code-block:: c @@ -267,19 +267,19 @@ Then, each non-native object file is added to the code generator with: lto_codegen_add_module(lto_code_gen_t, lto_module_t) -The linker then has the option of setting some codegen options. Whether or not +The linker then has the option of setting some codegen options. Whether or not to generate DWARF debug info is set with: - + .. code-block:: c lto_codegen_set_debug_model(lto_code_gen_t) -Which kind of position independence is set with: +which kind of position independence is set with: .. code-block:: c lto_codegen_set_pic_model(lto_code_gen_t) - + And each symbol that is referenced by a native object file or otherwise must not be optimized away is set with: diff --git a/docs/MemorySSA.rst b/docs/MemorySSA.rst new file mode 100644 index 0000000000000..0249e702c037e --- /dev/null +++ b/docs/MemorySSA.rst @@ -0,0 +1,364 @@ +========= +MemorySSA +========= + +.. contents:: + :local: + +Introduction +============ + +``MemorySSA`` is an analysis that allows us to cheaply reason about the +interactions between various memory operations. Its goal is to replace +``MemoryDependenceAnalysis`` for most (if not all) use-cases. This is because, +unless you're very careful, use of ``MemoryDependenceAnalysis`` can easily +result in quadratic-time algorithms in LLVM. Additionally, ``MemorySSA`` doesn't +have as many arbitrary limits as ``MemoryDependenceAnalysis``, so you should get +better results, too. + +At a high level, one of the goals of ``MemorySSA`` is to provide an SSA based +form for memory, complete with def-use and use-def chains, which +enables users to quickly find may-def and may-uses of memory operations. +It can also be thought of as a way to cheaply give versions to the complete +state of heap memory, and associate memory operations with those versions. + +This document goes over how ``MemorySSA`` is structured, and some basic +intuition on how ``MemorySSA`` works. + +A paper on MemorySSA (with notes about how it's implemented in GCC) `can be +found here <http://www.airs.com/dnovillo/Papers/mem-ssa.pdf>`_. Though, it's +relatively out-of-date; the paper references multiple heap partitions, but GCC +eventually swapped to just using one, like we now have in LLVM. Like +GCC's, LLVM's MemorySSA is intraprocedural. + + +MemorySSA Structure +=================== + +MemorySSA is a virtual IR. After it's built, ``MemorySSA`` will contain a +structure that maps ``Instruction``\ s to ``MemoryAccess``\ es, which are +``MemorySSA``'s parallel to LLVM ``Instruction``\ s. + +Each ``MemoryAccess`` can be one of three types: + +- ``MemoryPhi`` +- ``MemoryUse`` +- ``MemoryDef`` + +``MemoryPhi``\ s are ``PhiNode``\ s, but for memory operations. If at any +point we have two (or more) ``MemoryDef``\ s that could flow into a +``BasicBlock``, the block's top ``MemoryAccess`` will be a +``MemoryPhi``. As in LLVM IR, ``MemoryPhi``\ s don't correspond to any +concrete operation. As such, ``BasicBlock``\ s are mapped to ``MemoryPhi``\ s +inside ``MemorySSA``, whereas ``Instruction``\ s are mapped to ``MemoryUse``\ s +and ``MemoryDef``\ s. + +Note also that in SSA, Phi nodes merge must-reach definitions (that is, +definitions that *must* be new versions of variables). In MemorySSA, PHI nodes +merge may-reach definitions (that is, until disambiguated, the versions that +reach a phi node may or may not clobber a given variable). + +``MemoryUse``\ s are operations which use but don't modify memory. An example of +a ``MemoryUse`` is a ``load``, or a ``readonly`` function call. + +``MemoryDef``\ s are operations which may either modify memory, or which +introduce some kind of ordering constraints. Examples of ``MemoryDef``\ s +include ``store``\ s, function calls, ``load``\ s with ``acquire`` (or higher) +ordering, volatile operations, memory fences, etc. + +Every function that exists has a special ``MemoryDef`` called ``liveOnEntry``. +It dominates every ``MemoryAccess`` in the function that ``MemorySSA`` is being +run on, and implies that we've hit the top of the function. It's the only +``MemoryDef`` that maps to no ``Instruction`` in LLVM IR. Use of +``liveOnEntry`` implies that the memory being used is either undefined or +defined before the function begins. + +An example of all of this overlaid on LLVM IR (obtained by running ``opt +-passes='print<memoryssa>' -disable-output`` on an ``.ll`` file) is below. When +viewing this example, it may be helpful to view it in terms of clobbers. The +operands of a given ``MemoryAccess`` are all (potential) clobbers of said +MemoryAccess, and the value produced by a ``MemoryAccess`` can act as a clobber +for other ``MemoryAccess``\ es. Another useful way of looking at it is in +terms of heap versions. In that view, operands of of a given +``MemoryAccess`` are the version of the heap before the operation, and +if the access produces a value, the value is the new version of the heap +after the operation. + +.. code-block:: llvm + + define void @foo() { + entry: + %p1 = alloca i8 + %p2 = alloca i8 + %p3 = alloca i8 + ; 1 = MemoryDef(liveOnEntry) + store i8 0, i8* %p3 + br label %while.cond + + while.cond: + ; 6 = MemoryPhi({%0,1},{if.end,4}) + br i1 undef, label %if.then, label %if.else + + if.then: + ; 2 = MemoryDef(6) + store i8 0, i8* %p1 + br label %if.end + + if.else: + ; 3 = MemoryDef(6) + store i8 1, i8* %p2 + br label %if.end + + if.end: + ; 5 = MemoryPhi({if.then,2},{if.else,3}) + ; MemoryUse(5) + %1 = load i8, i8* %p1 + ; 4 = MemoryDef(5) + store i8 2, i8* %p2 + ; MemoryUse(1) + %2 = load i8, i8* %p3 + br label %while.cond + } + +The ``MemorySSA`` IR is shown in comments that precede the instructions they map +to (if such an instruction exists). For example, ``1 = MemoryDef(liveOnEntry)`` +is a ``MemoryAccess`` (specifically, a ``MemoryDef``), and it describes the LLVM +instruction ``store i8 0, i8* %p3``. Other places in ``MemorySSA`` refer to this +particular ``MemoryDef`` as ``1`` (much like how one can refer to ``load i8, i8* +%p1`` in LLVM with ``%1``). Again, ``MemoryPhi``\ s don't correspond to any LLVM +Instruction, so the line directly below a ``MemoryPhi`` isn't special. + +Going from the top down: + +- ``6 = MemoryPhi({entry,1},{if.end,4})`` notes that, when entering + ``while.cond``, the reaching definition for it is either ``1`` or ``4``. This + ``MemoryPhi`` is referred to in the textual IR by the number ``6``. +- ``2 = MemoryDef(6)`` notes that ``store i8 0, i8* %p1`` is a definition, + and its reaching definition before it is ``6``, or the ``MemoryPhi`` after + ``while.cond``. (See the `Build-time use optimization`_ and `Precision`_ + sections below for why this ``MemoryDef`` isn't linked to a separate, + disambiguated ``MemoryPhi``.) +- ``3 = MemoryDef(6)`` notes that ``store i8 0, i8* %p2`` is a definition; its + reaching definition is also ``6``. +- ``5 = MemoryPhi({if.then,2},{if.else,3})`` notes that the clobber before + this block could either be ``2`` or ``3``. +- ``MemoryUse(5)`` notes that ``load i8, i8* %p1`` is a use of memory, and that + it's clobbered by ``5``. +- ``4 = MemoryDef(5)`` notes that ``store i8 2, i8* %p2`` is a definition; it's + reaching definition is ``5``. +- ``MemoryUse(1)`` notes that ``load i8, i8* %p3`` is just a user of memory, + and the last thing that could clobber this use is above ``while.cond`` (e.g. + the store to ``%p3``). In heap versioning parlance, it really only depends on + the heap version 1, and is unaffected by the new heap versions generated since + then. + +As an aside, ``MemoryAccess`` is a ``Value`` mostly for convenience; it's not +meant to interact with LLVM IR. + +Design of MemorySSA +=================== + +``MemorySSA`` is an analysis that can be built for any arbitrary function. When +it's built, it does a pass over the function's IR in order to build up its +mapping of ``MemoryAccess``\ es. You can then query ``MemorySSA`` for things +like the dominance relation between ``MemoryAccess``\ es, and get the +``MemoryAccess`` for any given ``Instruction`` . + +When ``MemorySSA`` is done building, it also hands you a ``MemorySSAWalker`` +that you can use (see below). + + +The walker +---------- + +A structure that helps ``MemorySSA`` do its job is the ``MemorySSAWalker``, or +the walker, for short. The goal of the walker is to provide answers to clobber +queries beyond what's represented directly by ``MemoryAccess``\ es. For example, +given: + +.. code-block:: llvm + + define void @foo() { + %a = alloca i8 + %b = alloca i8 + + ; 1 = MemoryDef(liveOnEntry) + store i8 0, i8* %a + ; 2 = MemoryDef(1) + store i8 0, i8* %b + } + +The store to ``%a`` is clearly not a clobber for the store to ``%b``. It would +be the walker's goal to figure this out, and return ``liveOnEntry`` when queried +for the clobber of ``MemoryAccess`` ``2``. + +By default, ``MemorySSA`` provides a walker that can optimize ``MemoryDef``\ s +and ``MemoryUse``\ s by consulting whatever alias analysis stack you happen to +be using. Walkers were built to be flexible, though, so it's entirely reasonable +(and expected) to create more specialized walkers (e.g. one that specifically +queries ``GlobalsAA``, one that always stops at ``MemoryPhi`` nodes, etc). + + +Locating clobbers yourself +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +If you choose to make your own walker, you can find the clobber for a +``MemoryAccess`` by walking every ``MemoryDef`` that dominates said +``MemoryAccess``. The structure of ``MemoryDef``\ s makes this relatively simple; +they ultimately form a linked list of every clobber that dominates the +``MemoryAccess`` that you're trying to optimize. In other words, the +``definingAccess`` of a ``MemoryDef`` is always the nearest dominating +``MemoryDef`` or ``MemoryPhi`` of said ``MemoryDef``. + + +Build-time use optimization +--------------------------- + +``MemorySSA`` will optimize some ``MemoryAccess``\ es at build-time. +Specifically, we optimize the operand of every ``MemoryUse`` to point to the +actual clobber of said ``MemoryUse``. This can be seen in the above example; the +second ``MemoryUse`` in ``if.end`` has an operand of ``1``, which is a +``MemoryDef`` from the entry block. This is done to make walking, +value numbering, etc, faster and easier. + +It is not possible to optimize ``MemoryDef`` in the same way, as we +restrict ``MemorySSA`` to one heap variable and, thus, one Phi node +per block. + + +Invalidation and updating +------------------------- + +Because ``MemorySSA`` keeps track of LLVM IR, it needs to be updated whenever +the IR is updated. "Update", in this case, includes the addition, deletion, and +motion of ``Instructions``. The update API is being made on an as-needed basis. +If you'd like examples, ``GVNHoist`` is a user of ``MemorySSA``\ s update API. + + +Phi placement +^^^^^^^^^^^^^ + +``MemorySSA`` only places ``MemoryPhi``\ s where they're actually +needed. That is, it is a pruned SSA form, like LLVM's SSA form. For +example, consider: + +.. code-block:: llvm + + define void @foo() { + entry: + %p1 = alloca i8 + %p2 = alloca i8 + %p3 = alloca i8 + ; 1 = MemoryDef(liveOnEntry) + store i8 0, i8* %p3 + br label %while.cond + + while.cond: + ; 3 = MemoryPhi({%0,1},{if.end,2}) + br i1 undef, label %if.then, label %if.else + + if.then: + br label %if.end + + if.else: + br label %if.end + + if.end: + ; MemoryUse(1) + %1 = load i8, i8* %p1 + ; 2 = MemoryDef(3) + store i8 2, i8* %p2 + ; MemoryUse(1) + %2 = load i8, i8* %p3 + br label %while.cond + } + +Because we removed the stores from ``if.then`` and ``if.else``, a ``MemoryPhi`` +for ``if.end`` would be pointless, so we don't place one. So, if you need to +place a ``MemoryDef`` in ``if.then`` or ``if.else``, you'll need to also create +a ``MemoryPhi`` for ``if.end``. + +If it turns out that this is a large burden, we can just place ``MemoryPhi``\ s +everywhere. Because we have Walkers that are capable of optimizing above said +phis, doing so shouldn't prohibit optimizations. + + +Non-Goals +--------- + +``MemorySSA`` is meant to reason about the relation between memory +operations, and enable quicker querying. +It isn't meant to be the single source of truth for all potential memory-related +optimizations. Specifically, care must be taken when trying to use ``MemorySSA`` +to reason about atomic or volatile operations, as in: + +.. code-block:: llvm + + define i8 @foo(i8* %a) { + entry: + br i1 undef, label %if.then, label %if.end + + if.then: + ; 1 = MemoryDef(liveOnEntry) + %0 = load volatile i8, i8* %a + br label %if.end + + if.end: + %av = phi i8 [0, %entry], [%0, %if.then] + ret i8 %av + } + +Going solely by ``MemorySSA``'s analysis, hoisting the ``load`` to ``entry`` may +seem legal. Because it's a volatile load, though, it's not. + + +Design tradeoffs +---------------- + +Precision +^^^^^^^^^ + +``MemorySSA`` in LLVM deliberately trades off precision for speed. +Let us think about memory variables as if they were disjoint partitions of the +heap (that is, if you have one variable, as above, it represents the entire +heap, and if you have multiple variables, each one represents some +disjoint portion of the heap) + +First, because alias analysis results conflict with each other, and +each result may be what an analysis wants (IE +TBAA may say no-alias, and something else may say must-alias), it is +not possible to partition the heap the way every optimization wants. +Second, some alias analysis results are not transitive (IE A noalias B, +and B noalias C, does not mean A noalias C), so it is not possible to +come up with a precise partitioning in all cases without variables to +represent every pair of possible aliases. Thus, partitioning +precisely may require introducing at least N^2 new virtual variables, +phi nodes, etc. + +Each of these variables may be clobbered at multiple def sites. + +To give an example, if you were to split up struct fields into +individual variables, all aliasing operations that may-def multiple struct +fields, will may-def more than one of them. This is pretty common (calls, +copies, field stores, etc). + +Experience with SSA forms for memory in other compilers has shown that +it is simply not possible to do this precisely, and in fact, doing it +precisely is not worth it, because now all the optimizations have to +walk tons and tons of virtual variables and phi nodes. + +So we partition. At the point at which you partition, again, +experience has shown us there is no point in partitioning to more than +one variable. It simply generates more IR, and optimizations still +have to query something to disambiguate further anyway. + +As a result, LLVM partitions to one variable. + +Use Optimization +^^^^^^^^^^^^^^^^ + +Unlike other partitioned forms, LLVM's ``MemorySSA`` does make one +useful guarantee - all loads are optimized to point at the thing that +actually clobbers them. This gives some nice properties. For example, +for a given store, you can find all loads actually clobbered by that +store by walking the immediate uses of the store. diff --git a/docs/OptBisect.rst b/docs/OptBisect.rst new file mode 100644 index 0000000000000..e9f1c2541c9c0 --- /dev/null +++ b/docs/OptBisect.rst @@ -0,0 +1,197 @@ +==================================================== +Using -opt-bisect-limit to debug optimization errors +==================================================== +.. contents:: + :local: + :depth: 1 + +Introduction +============ + +The -opt-bisect-limit option provides a way to disable all optimization passes +above a specified limit without modifying the way in which the Pass Managers +are populated. The intention of this option is to assist in tracking down +problems where incorrect transformations during optimization result in incorrect +run-time behavior. + +This feature is implemented on an opt-in basis. Passes which can be safely +skipped while still allowing correct code generation call a function to +check the opt-bisect limit before performing optimizations. Passes which +either must be run or do not modify the IR do not perform this check and are +therefore never skipped. Generally, this means analysis passes, passes +that are run at CodeGenOpt::None and passes which are required for register +allocation. + +The -opt-bisect-limit option can be used with any tool, including front ends +such as clang, that uses the core LLVM library for optimization and code +generation. The exact syntax for invoking the option is discussed below. + +This feature is not intended to replace other debugging tools such as bugpoint. +Rather it provides an alternate course of action when reproducing the problem +requires a complex build infrastructure that would make using bugpoint +impractical or when reproducing the failure requires a sequence of +transformations that is difficult to replicate with tools like opt and llc. + + +Getting Started +=============== + +The -opt-bisect-limit command line option can be passed directly to tools such +as opt, llc and lli. The syntax is as follows: + +:: + + <tool name> [other options] -opt-bisect-limit=<limit> + +If a value of -1 is used the tool will perform all optimizations but a message +will be printed to stderr for each optimization that could be skipped +indicating the index value that is associated with that optimization. To skip +optimizations, pass the value of the last optimization to be performed as the +opt-bisect-limit. All optimizations with a higher index value will be skipped. + +In order to use the -opt-bisect-limit option with a driver that provides a +wrapper around the LLVM core library, an additional prefix option may be +required, as defined by the driver. For example, to use this option with +clang, the "-mllvm" prefix must be used. A typical clang invocation would look +like this: + +:: + + clang -O2 -mllvm -opt-bisect-limit=256 my_file.c + +The -opt-bisect-limit option may also be applied to link-time optimizations by +using a prefix to indicate that this is a plug-in option for the linker. The +following syntax will set a bisect limit for LTO transformations: + +:: + + clang -flto -Wl,-plugin-opt,-opt-bisect-limit=256 my_file.o my_other_file.o + +LTO passes are run by a library instance invoked by the linker. Therefore any +passes run in the primary driver compilation phase are not affected by options +passed via '-Wl,-plugin-opt' and LTO passes are not affected by options +passed to the driver-invoked LLVM invocation via '-mllvm'. + + +Bisection Index Values +====================== + +The granularity of the optimizations associated with a single index value is +variable. Depending on how the optimization pass has been instrumented the +value may be associated with as much as all transformations that would have +been performed by an optimization pass on an IR unit for which it is invoked +(for instance, during a single call of runOnFunction for a FunctionPass) or as +little as a single transformation. The index values may also be nested so that +if an invocation of the pass is not skipped individual transformations within +that invocation may still be skipped. + +The order of the values assigned is guaranteed to remain stable and consistent +from one run to the next up to and including the value specified as the limit. +Above the limit value skipping of optimizations can cause a change in the +numbering, but because all optimizations above the limit are skipped this +is not a problem. + +When an opt-bisect index value refers to an entire invocation of the run +function for a pass, the pass will query whether or not it should be skipped +each time it is invoked and each invocation will be assigned a unique value. +For example, if a FunctionPass is used with a module containing three functions +a different index value will be assigned to the pass for each of the functions +as the pass is run. The pass may be run on two functions but skipped for the +third. + +If the pass internally performs operations on a smaller IR unit the pass must be +specifically instrumented to enable bisection at this finer level of granularity +(see below for details). + + +Example Usage +============= + +.. code-block:: console + + $ opt -O2 -o test-opt.bc -opt-bisect-limit=16 test.ll + + BISECT: running pass (1) Simplify the CFG on function (g) + BISECT: running pass (2) SROA on function (g) + BISECT: running pass (3) Early CSE on function (g) + BISECT: running pass (4) Infer set function attributes on module (test.ll) + BISECT: running pass (5) Interprocedural Sparse Conditional Constant Propagation on module (test.ll) + BISECT: running pass (6) Global Variable Optimizer on module (test.ll) + BISECT: running pass (7) Promote Memory to Register on function (g) + BISECT: running pass (8) Dead Argument Elimination on module (test.ll) + BISECT: running pass (9) Combine redundant instructions on function (g) + BISECT: running pass (10) Simplify the CFG on function (g) + BISECT: running pass (11) Remove unused exception handling info on SCC (<<null function>>) + BISECT: running pass (12) Function Integration/Inlining on SCC (<<null function>>) + BISECT: running pass (13) Deduce function attributes on SCC (<<null function>>) + BISECT: running pass (14) Remove unused exception handling info on SCC (f) + BISECT: running pass (15) Function Integration/Inlining on SCC (f) + BISECT: running pass (16) Deduce function attributes on SCC (f) + BISECT: NOT running pass (17) Remove unused exception handling info on SCC (g) + BISECT: NOT running pass (18) Function Integration/Inlining on SCC (g) + BISECT: NOT running pass (19) Deduce function attributes on SCC (g) + BISECT: NOT running pass (20) SROA on function (g) + BISECT: NOT running pass (21) Early CSE on function (g) + BISECT: NOT running pass (22) Speculatively execute instructions if target has divergent branches on function (g) + ... etc. ... + + +Pass Skipping Implementation +============================ + +The -opt-bisect-limit implementation depends on individual passes opting in to +the opt-bisect process. The OptBisect object that manages the process is +entirely passive and has no knowledge of how any pass is implemented. When a +pass is run if the pass may be skipped, it should call the OptBisect object to +see if it should be skipped. + +The OptBisect object is intended to be accessed through LLVMContext and each +Pass base class contains a helper function that abstracts the details in order +to make this check uniform across all passes. These helper functions are: + +.. code-block:: c++ + + bool ModulePass::skipModule(Module &M); + bool CallGraphSCCPass::skipSCC(CallGraphSCC &SCC); + bool FunctionPass::skipFunction(const Function &F); + bool BasicBlockPass::skipBasicBlock(const BasicBlock &BB); + bool LoopPass::skipLoop(const Loop *L); + +A MachineFunctionPass should use FunctionPass::skipFunction() as such: + +.. code-block:: c++ + + bool MyMachineFunctionPass::runOnMachineFunction(Function &MF) { + if (skipFunction(*MF.getFunction()) + return false; + // Otherwise, run the pass normally. + } + +In addition to checking with the OptBisect class to see if the pass should be +skipped, the skipFunction(), skipLoop() and skipBasicBlock() helper functions +also look for the presence of the "optnone" function attribute. The calling +pass will be unable to determine whether it is being skipped because the +"optnone" attribute is present or because the opt-bisect-limit has been +reached. This is desirable because the behavior should be the same in either +case. + +The majority of LLVM passes which can be skipped have already been instrumented +in the manner described above. If you are adding a new pass or believe you +have found a pass which is not being included in the opt-bisect process but +should be, you can add it as described above. + + +Adding Finer Granularity +======================== + +Once the pass in which an incorrect transformation is performed has been +determined, it may be useful to perform further analysis in order to determine +which specific transformation is causing the problem. Ideally all passes +would be instrumented to allow skipping of individual transformations. This +functionality is available through the OptBisect object but it is impractical +to proactively instrument every existing pass. It is hoped that as developers +find that they need a pass to be instrumented they will add the instrumentation +and contribute it back to the LLVM source base. + +Helper functions will be added to simplify this level of instrumentation, but +this work is not yet completed. For more information, contact Andy Kaylor. diff --git a/docs/PDB/CodeViewSymbols.rst b/docs/PDB/CodeViewSymbols.rst new file mode 100644 index 0000000000000..8b2133cf308d7 --- /dev/null +++ b/docs/PDB/CodeViewSymbols.rst @@ -0,0 +1,4 @@ +=====================================
+CodeView Symbol Records
+=====================================
+
diff --git a/docs/PDB/CodeViewTypes.rst b/docs/PDB/CodeViewTypes.rst new file mode 100644 index 0000000000000..ad806a70df1f4 --- /dev/null +++ b/docs/PDB/CodeViewTypes.rst @@ -0,0 +1,4 @@ +=====================================
+CodeView Type Records
+=====================================
+
diff --git a/docs/PDB/DbiStream.rst b/docs/PDB/DbiStream.rst new file mode 100644 index 0000000000000..fec0e29ae533c --- /dev/null +++ b/docs/PDB/DbiStream.rst @@ -0,0 +1,445 @@ +===================================== +The PDB DBI (Debug Info) Stream +===================================== + +.. contents:: + :local: + +.. _dbi_intro: + +Introduction +============ + +The PDB DBI Stream (Index 3) is one of the largest and most important streams +in a PDB file. It contains information about how the program was compiled, +(e.g. compilation flags, etc), the compilands (e.g. object files) that +were used to link together the program, the source files which were used +to build the program, as well as references to other streams that contain more +detailed information about each compiland, such as the CodeView symbol records +contained within each compiland and the source and line information for +functions and other symbols within each compiland. + + +.. _dbi_header: + +Stream Header +============= +At offset 0 of the DBI Stream is a header with the following layout: + + +.. code-block:: c++ + + struct DbiStreamHeader { + int32_t VersionSignature; + uint32_t VersionHeader; + uint32_t Age; + uint16_t GlobalStreamIndex; + uint16_t BuildNumber; + uint16_t PublicStreamIndex; + uint16_t PdbDllVersion; + uint16_t SymRecordStream; + uint16_t PdbDllRbld; + int32_t ModInfoSize; + int32_t SectionContributionSize; + int32_t SectionMapSize; + int32_t SourceInfoSize; + int32_t TypeServerSize; + uint32_t MFCTypeServerIndex; + int32_t OptionalDbgHeaderSize; + int32_t ECSubstreamSize; + uint16_t Flags; + uint16_t Machine; + uint32_t Padding; + }; + +- **VersionSignature** - Unknown meaning. Appears to always be ``-1``. + +- **VersionHeader** - A value from the following enum. + +.. code-block:: c++ + + enum class DbiStreamVersion : uint32_t { + VC41 = 930803, + V50 = 19960307, + V60 = 19970606, + V70 = 19990903, + V110 = 20091201 + }; + +Similar to the :doc:`PDB Stream <PdbStream>`, this value always appears to be +``V70``, and it is not clear what the other values are for. + +- **Age** - The number of times the PDB has been written. Equal to the same + field from the :ref:`PDB Stream header <pdb_stream_header>`. + +- **GlobalStreamIndex** - The index of the :doc:`Global Symbol Stream <GlobalStream>`, + which contains CodeView symbol records for all global symbols. Actual records + are stored in the symbol record stream, and are referenced from this stream. + +- **BuildNumber** - A bitfield containing values representing the major and minor + version number of the toolchain (e.g. 12.0 for MSVC 2013) used to build the + program, with the following layout: + +.. code-block:: c++ + + uint16_t MinorVersion : 8; + uint16_t MajorVersion : 7; + uint16_t NewVersionFormat : 1; + +For the purposes of LLVM, we assume ``NewVersionFormat`` to be always ``true``. +If it is ``false``, the layout above does not apply and the reader should consult +the `Microsoft Source Code <https://github.com/Microsoft/microsoft-pdb>`__ for +further guidance. + +- **PublicStreamIndex** - The index of the :doc:`Public Symbol Stream <PublicStream>`, + which contains CodeView symbol records for all public symbols. Actual records + are stored in the symbol record stream, and are referenced from this stream. + +- **PdbDllVersion** - The version number of ``mspdbXXXX.dll`` used to produce this + PDB. Note this obviously does not apply for LLVM as LLVM does not use ``mspdb.dll``. + +- **SymRecordStream** - The stream containing all CodeView symbol records used + by the program. This is used for deduplication, so that many different + compilands can refer to the same symbols without having to include the full record + content inside of each module stream. + +- **PdbDllRbld** - Unknown + +- **MFCTypeServerIndex** - The length of the :ref:dbi_mfc_type_server_substream + +- **Flags** - A bitfield with the following layout, containing various + information about how the program was built: + +.. code-block:: c++ + + uint16_t WasIncrementallyLinked : 1; + uint16_t ArePrivateSymbolsStripped : 1; + uint16_t HasConflictingTypes : 1; + uint16_t Reserved : 13; + +The only one of these that is not self-explanatory is ``HasConflictingTypes``. +Although undocumented, ``link.exe`` contains a hidden flag ``/DEBUG:CTYPES``. +If it is passed to ``link.exe``, this field will be set. Otherwise it will +not be set. It is unclear what this flag does, although it seems to have +subtle implications on the algorithm used to look up type records. + +- **Machine** - A value from the `CV_CPU_TYPE_e <https://msdn.microsoft.com/en-us/library/b2fc64ek.aspx>`__ + enumeration. Common values are ``0x8664`` (x86-64) and ``0x14C`` (x86). + +Immediately after the fixed-size DBI Stream header are ``7`` variable-length +`substreams`. The following ``7`` fields of the DBI Stream header specify the +number of bytes of the corresponding substream. Each substream's contents will +be described in detail :ref:`below <dbi_substreams>`. The length of the entire +DBI Stream should equal ``64`` (the length of the header above) plus the value +of each of the following ``7`` fields. + +- **ModInfoSize** - The length of the :ref:`dbi_mod_info_substream`. + +- **SectionContributionSize** - The length of the :ref:`dbi_sec_contr_substream`. + +- **SectionMapSize** - The length of the :ref:`dbi_section_map_substream`. + +- **SourceInfoSize** - The length of the :ref:`dbi_file_info_substream`. + +- **TypeServerSize** - The length of the :ref:`dbi_type_server_substream`. + +- **OptionalDbgHeaderSize** - The length of the :ref:`dbi_optional_dbg_stream`. + +- **ECSubstreamSize** - The length of the :ref:`dbi_ec_substream`. + +.. _dbi_substreams: + +Substreams +========== + +.. _dbi_mod_info_substream: + +Module Info Substream +^^^^^^^^^^^^^^^^^^^^^ + +Begins at offset ``0`` immediately after the :ref:`header <dbi_header>`. The +module info substream is an array of variable-length records, each one +describing a single module (e.g. object file) linked into the program. Each +record in the array has the format: + +.. code-block:: c++ + + struct SectionContribEntry { + uint16_t Section; + char Padding1[2]; + int32_t Offset; + int32_t Size; + uint32_t Characteristics; + uint16_t ModuleIndex; + char Padding2[2]; + uint32_t DataCrc; + uint32_t RelocCrc; + }; + +While most of these are self-explanatory, the ``Characteristics`` field +warrants some elaboration. It corresponds to the ``Characteristics`` +field of the `IMAGE_SECTION_HEADER <https://msdn.microsoft.com/en-us/library/windows/desktop/ms680341(v=vs.85).aspx>`__ +structure. + +.. code-block:: c++ + + struct ModInfo { + uint32_t Unused1; + SectionContribEntry SectionContr; + uint16_t Flags; + uint16_t ModuleSymStream; + uint32_t SymByteSize; + uint32_t C11ByteSize; + uint32_t C13ByteSize; + uint16_t SourceFileCount; + char Padding[2]; + uint32_t Unused2; + uint32_t SourceFileNameIndex; + uint32_t PdbFilePathNameIndex; + char ModuleName[]; + char ObjFileName[]; + }; + +- **SectionContr** - Describes the properties of the section in the final binary + which contain the code and data from this module. + +- **Flags** - A bitfield with the following format: + +.. code-block:: c++ + + uint16_t Dirty : 1; // ``true`` if this ModInfo has been written since reading the PDB. + uint16_t EC : 1; // ``true`` if EC information is present for this module. It is unknown what EC actually is. + uint16_t Unused : 6; + uint16_t TSM : 8; // Type Server Index for this module. It is unknown what this is used for, but it is not used by LLVM. + + +- **ModuleSymStream** - The index of the stream that contains symbol information + for this module. This includes CodeView symbol information as well as source + and line information. + +- **SymByteSize** - The number of bytes of data from the stream identified by + ``ModuleSymStream`` that represent CodeView symbol records. + +- **C11ByteSize** - The number of bytes of data from the stream identified by + ``ModuleSymStream`` that represent C11-style CodeView line information. + +- **C13ByteSize** - The number of bytes of data from the stream identified by + ``ModuleSymStream`` that represent C13-style CodeView line information. At + most one of ``C11ByteSize`` and ``C13ByteSize`` will be non-zero. + +- **SourceFileCount** - The number of source files that contributed to this + module during compilation. + +- **SourceFileNameIndex** - The offset in the names buffer of the primary + translation unit used to build this module. All PDB files observed to date + always have this value equal to 0. + +- **PdbFilePathNameIndex** - The offset in the names buffer of the PDB file + containing this module's symbol information. This has only been observed + to be non-zero for the special ``* Linker *`` module. + +- **ModuleName** - The module name. This is usually either a full path to an + object file (either directly passed to ``link.exe`` or from an archive) or + a string of the form ``Import:<dll name>``. + +- **ObjFileName** - The object file name. In the case of an module that is + linked directly passed to ``link.exe``, this is the same as **ModuleName**. + In the case of a module that comes from an archive, this is usually the full + path to the archive. + +.. _dbi_sec_contr_substream: + +Section Contribution Substream +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Begins at offset ``0`` immediately after the :ref:`dbi_mod_info_substream` ends, +and consumes ``Header->SectionContributionSize`` bytes. This substream begins +with a single ``uint32_t`` which will be one of the following values: + +.. code-block:: c++ + + enum class SectionContrSubstreamVersion : uint32_t { + Ver60 = 0xeffe0000 + 19970605, + V2 = 0xeffe0000 + 20140516 + }; + +``Ver60`` is the only value which has been observed in a PDB so far. Following +this ``4`` byte field is an array of fixed-length structures. If the version +is ``Ver60``, it is an array of ``SectionContribEntry`` structures. If the +version is ``V2``, it is an array of ``SectionContribEntry2`` structures, +defined as follows: + +.. code-block:: c++ + + struct SectionContribEntry2 { + SectionContribEntry SC; + uint32_t ISectCoff; + }; + +The purpose of the second field is not well understood. + + +.. _dbi_section_map_substream: + +Section Map Substream +^^^^^^^^^^^^^^^^^^^^^ +Begins at offset ``0`` immediately after the :ref:`dbi_sec_contr_substream` ends, +and consumes ``Header->SectionMapSize`` bytes. This substream begins with an ``8`` +byte header followed by an array of fixed-length records. The header and records +have the following layout: + +.. code-block:: c++ + + struct SectionMapHeader { + uint16_t Count; // Number of segment descriptors + uint16_t LogCount; // Number of logical segment descriptors + }; + + struct SectionMapEntry { + uint16_t Flags; // See the SectionMapEntryFlags enum below. + uint16_t Ovl; // Logical overlay number + uint16_t Group; // Group index into descriptor array. + uint16_t Frame; + uint16_t SectionName; // Byte index of segment / group name in string table, or 0xFFFF. + uint16_t ClassName; // Byte index of class in string table, or 0xFFFF. + uint32_t Offset; // Byte offset of the logical segment within physical segment. If group is set in flags, this is the offset of the group. + uint32_t SectionLength; // Byte count of the segment or group. + }; + + enum class SectionMapEntryFlags : uint16_t { + Read = 1 << 0, // Segment is readable. + Write = 1 << 1, // Segment is writable. + Execute = 1 << 2, // Segment is executable. + AddressIs32Bit = 1 << 3, // Descriptor describes a 32-bit linear address. + IsSelector = 1 << 8, // Frame represents a selector. + IsAbsoluteAddress = 1 << 9, // Frame represents an absolute address. + IsGroup = 1 << 10 // If set, descriptor represents a group. + }; + +Many of these fields are not well understood, so will not be discussed further. + +.. _dbi_file_info_substream: + +File Info Substream +^^^^^^^^^^^^^^^^^^^ +Begins at offset ``0`` immediately after the :ref:`dbi_section_map_substream` ends, +and consumes ``Header->SourceInfoSize`` bytes. This substream defines the mapping +from module to the source files that contribute to that module. Since multiple +modules can use the same source file (for example, a header file), this substream +uses a string table to store each unique file name only once, and then have each +module use offsets into the string table rather than embedding the string's value +directly. The format of this substream is as follows: + +.. code-block:: c++ + + struct FileInfoSubstream { + uint16_t NumModules; + uint16_t NumSourceFiles; + + uint16_t ModIndices[NumModules]; + uint16_t ModFileCounts[NumModules]; + uint32_t FileNameOffsets[NumSourceFiles]; + char NamesBuffer[][NumSourceFiles]; + }; + +**NumModules** - The number of modules for which source file information is +contained within this substream. Should match the corresponding value from the +ref:`dbi_header`. + +**NumSourceFiles**: In theory this is supposed to contain the number of source +files for which this substream contains information. But that would present a +problem in that the width of this field being ``16``-bits would prevent one from +having more than 64K source files in a program. In early versions of the file +format, this seems to have been the case. In order to support more than this, this +field of the is simply ignored, and computed dynamically by summing up the values of +the ``ModFileCounts`` array (discussed below). In short, this value should be +ignored. + +**ModIndices** - This array is present, but does not appear to be useful. + +**ModFileCountArray** - An array of ``NumModules`` integers, each one containing +the number of source files which contribute to the module at the specified index. +While each individual module is limited to 64K contributing source files, the +union of all modules' source files may be greater than 64K. The real number of +source files is thus computed by summing this array. Note that summing this array +does not give the number of `unique` source files, only the total number of source +file contributions to modules. + +**FileNameOffsets** - An array of **NumSourceFiles** integers (where **NumSourceFiles** +here refers to the 32-bit value obtained from summing **ModFileCountArray**), where +each integer is an offset into **NamesBuffer** pointing to a null terminated string. + +**NamesBuffer** - An array of null terminated strings containing the actual source +file names. + +.. _dbi_type_server_substream: + +Type Server Substream +^^^^^^^^^^^^^^^^^^^^^ +Begins at offset ``0`` immediately after the :ref:`dbi_file_info_substream` ends, +and consumes ``Header->TypeServerSize`` bytes. Neither the purpose nor the layout +of this substream is understood, although it is assumed to related somehow to the +usage of ``/Zi`` and ``mspdbsrv.exe``. This substream will not be discussed further. + +.. _dbi_ec_substream: + +EC Substream +^^^^^^^^^^^^ +Begins at offset ``0`` immediately after the :ref:`dbi_type_server_substream` ends, +and consumes ``Header->ECSubstreamSize`` bytes. Neither the purpose nor the layout +of this substream is understood, and it will not be discussed further. + +.. _dbi_optional_dbg_stream: + +Optional Debug Header Stream +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Begins at offset ``0`` immediately after the :ref:`dbi_ec_substream` ends, and +consumes ``Header->OptionalDbgHeaderSize`` bytes. This field is an array of +stream indices (e.g. ``uint16_t``'s), each of which identifies a stream +index in the larger MSF file which contains some additional debug information. +Each position of this array has a special meaning, allowing one to determine +what kind of debug information is at the referenced stream. ``11`` indices +are currently understood, although it's possible there may be more. The +layout of each stream generally corresponds exactly to a particular type +of debug data directory from the PE/COFF file. The format of these fields +can be found in the `Microsoft PE/COFF Specification <https://www.microsoft.com/en-us/download/details.aspx?id=19509>`__. + +**FPO Data** - ``DbgStreamArray[0]``. The data in the referenced stream is a +debug data directory of type ``IMAGE_DEBUG_TYPE_FPO`` + +**Exception Data** - ``DbgStreamArray[1]``. The data in the referenced stream +is a debug data directory of type ``IMAGE_DEBUG_TYPE_EXCEPTION``. + +**Fixup Data** - ``DbgStreamArray[2]``. The data in the referenced stream is a +debug data directory of type ``IMAGE_DEBUG_TYPE_FIXUP``. + +**Omap To Src Data** - ``DbgStreamArray[3]``. The data in the referenced stream +is a debug data directory of type ``IMAGE_DEBUG_TYPE_OMAP_TO_SRC``. This +is used for mapping addresses between instrumented and uninstrumented code. + +**Omap From Src Data** - ``DbgStreamArray[4]``. The data in the referenced stream +is a debug data directory of type ``IMAGE_DEBUG_TYPE_OMAP_FROM_SRC``. This +is used for mapping addresses between instrumented and uninstrumented code. + +**Section Header Data** - ``DbgStreamArray[5]``. A dump of all section headers from +the original executable. + +**Token / RID Map** - ``DbgStreamArray[6]``. The layout of this stream is not +understood, but it is assumed to be a mapping from ``CLR Token`` to +``CLR Record ID``. Refer to `ECMA 335 <http://www.ecma-international.org/publications/standards/Ecma-335.htm>`__ +for more information. + +**Xdata** - ``DbgStreamArray[7]``. A copy of the ``.xdata`` section from the +executable. + +**Pdata** - ``DbgStreamArray[8]``. This is assumed to be a copy of the ``.pdata`` +section from the executable, but that would make it identical to +``DbgStreamArray[1]``. The difference between these two indices is not well +understood. + +**New FPO Data** - ``DbgStreamArray[9]``. The data in the referenced stream is a +debug data directory of type ``IMAGE_DEBUG_TYPE_FPO``. It is not clear how this +differs from ``DbgStreamArray[0]``, but in practice all observed PDB files have +used the "new" format rather than the "old" format. + +**Original Section Header Data** - ``DbgStreamArray[10]``. Assumed to be similar +to ``DbgStreamArray[5]``, but has not been observed in practice. diff --git a/docs/PDB/GlobalStream.rst b/docs/PDB/GlobalStream.rst new file mode 100644 index 0000000000000..314b9f01ffa8b --- /dev/null +++ b/docs/PDB/GlobalStream.rst @@ -0,0 +1,3 @@ +=====================================
+The PDB Global Symbol Stream
+=====================================
diff --git a/docs/PDB/HashStream.rst b/docs/PDB/HashStream.rst new file mode 100644 index 0000000000000..a758db4d03d6e --- /dev/null +++ b/docs/PDB/HashStream.rst @@ -0,0 +1,3 @@ +=====================================
+The TPI & IPI Hash Streams
+=====================================
diff --git a/docs/PDB/ModiStream.rst b/docs/PDB/ModiStream.rst new file mode 100644 index 0000000000000..7e500bd921c6f --- /dev/null +++ b/docs/PDB/ModiStream.rst @@ -0,0 +1,80 @@ +=====================================
+The Module Information Stream
+=====================================
+
+.. contents::
+ :local:
+
+.. _modi_stream_intro:
+
+Introduction
+============
+
+The Module Info Stream (henceforth referred to as the Modi stream) contains
+information about a single module (object file, import library, etc that
+contributes to the binary this PDB contains debug information about. There
+is one modi stream for each module, and the mapping between modi stream index
+and module is contained in the :doc:`DBI Stream <DbiStream>`. The modi stream
+for a single module contains line information for the compiland, as well as
+all CodeView information for the symbols defined in the compiland. Finally,
+there is a "global refs" substream which is not well understood.
+
+.. _modi_stream_layout:
+
+Stream Layout
+=============
+
+A modi stream is laid out as follows:
+
+
+.. code-block:: c++
+
+ struct ModiStream {
+ uint32_t Signature;
+ uint8_t Symbols[SymbolSize-4];
+ uint8_t C11LineInfo[C11Size];
+ uint8_t C13LineInfo[C13Size];
+
+ uint32_t GlobalRefsSize;
+ uint8_t GlobalRefs[GlobalRefsSize];
+ };
+
+- **Signature** - Unknown. In practice only the value of ``4`` has been
+ observed. It is hypothesized that this value corresponds to the set of
+ ``CV_SIGNATURE_xx`` defines in ``cvinfo.h``, with the value of ``4``
+ meaning that this module has C13 line information (as opposed to C11 line
+ information). A corollary of this is that we expect to only ever see
+ C13 line info, and that we do not understand the format of C11 line info.
+
+- **Symbols** - The :ref:`CodeView Symbol Substream <modi_symbol_substream>`.
+ ``SymbolSize`` is equal to the value of ``SymByteSize`` for the
+ corresponding module's entry in the :ref:`Module Info Substream <dbi_mod_info_substream>`
+ of the :doc:`DBI Stream <DbiStream>`.
+
+- **C11LineInfo** - A block containing CodeView line information in C11
+ format. ``C11Size`` is equal to the value of ``C11ByteSize`` from the
+ :ref:`Module Info Substream <dbi_mod_info_substream>` of the
+ :doc:`DBI Stream <DbiStream>`. If this value is ``0``, then C11 line
+ information is not present. As mentioned previously, the format of
+ C11 line info is not understood and we assume all line in modern PDBs
+ to be in C13 format.
+
+- **C13LineInfo** - A block containing CodeView line information in C13
+ format. ``C13Size`` is equal to the value of ``C13ByteSize`` from the
+ :ref:`Module Info Substream <dbi_mod_info_substream>` of the
+ :doc:`DBI Stream <DbiStream>`. If this value is ``0``, then C13 line
+ information is not present.
+
+- **GlobalRefs** - The meaning of this substream is not understood.
+
+.. _modi_symbol_substream:
+
+The CodeView Symbol Substream
+=============================
+
+The CodeView Symbol Substream. This is an array of variable length
+records describing the functions, variables, inlining information,
+and other symbols defined in the compiland. The entire array consumes
+``SymbolSize-4`` bytes. The format of a CodeView Symbol Record (and
+thusly, an array of CodeView Symbol Records) is described in
+:doc:`CodeViewSymbols`.
diff --git a/docs/PDB/MsfFile.rst b/docs/PDB/MsfFile.rst new file mode 100644 index 0000000000000..bdceca3aeb39b --- /dev/null +++ b/docs/PDB/MsfFile.rst @@ -0,0 +1,121 @@ +=====================================
+The MSF File Format
+=====================================
+
+.. contents::
+ :local:
+
+.. _msf_superblock:
+
+The Superblock
+==============
+At file offset 0 in an MSF file is the MSF *SuperBlock*, which is laid out as
+follows:
+
+.. code-block:: c++
+
+ struct SuperBlock {
+ char FileMagic[sizeof(Magic)];
+ ulittle32_t BlockSize;
+ ulittle32_t FreeBlockMapBlock;
+ ulittle32_t NumBlocks;
+ ulittle32_t NumDirectoryBytes;
+ ulittle32_t Unknown;
+ ulittle32_t BlockMapAddr;
+ };
+
+- **FileMagic** - Must be equal to ``"Microsoft C / C++ MSF 7.00\\r\\n"``
+ followed by the bytes ``1A 44 53 00 00 00``.
+- **BlockSize** - The block size of the internal file system. Valid values are
+ 512, 1024, 2048, and 4096 bytes. Certain aspects of the MSF file layout vary
+ depending on the block sizes. For the purposes of LLVM, we handle only block
+ sizes of 4KiB, and all further discussion assumes a block size of 4KiB.
+- **FreeBlockMapBlock** - The index of a block within the file, at which begins
+ a bitfield representing the set of all blocks within the file which are "free"
+ (i.e. the data within that block is not used). This bitfield is spread across
+ the MSF file at ``BlockSize`` intervals.
+ **Important**: ``FreeBlockMapBlock`` can only be ``1`` or ``2``! This field
+ is designed to support incremental and atomic updates of the underlying MSF
+ file. While writing to an MSF file, if the value of this field is `1`, you
+ can write your new modified bitfield to page 2, and vice versa. Only when
+ you commit the file to disk do you need to swap the value in the SuperBlock
+ to point to the new ``FreeBlockMapBlock``.
+- **NumBlocks** - The total number of blocks in the file. ``NumBlocks * BlockSize``
+ should equal the size of the file on disk.
+- **NumDirectoryBytes** - The size of the stream directory, in bytes. The stream
+ directory contains information about each stream's size and the set of blocks
+ that it occupies. It will be described in more detail later.
+- **BlockMapAddr** - The index of a block within the MSF file. At this block is
+ an array of ``ulittle32_t``'s listing the blocks that the stream directory
+ resides on. For large MSF files, the stream directory (which describes the
+ block layout of each stream) may not fit entirely on a single block. As a
+ result, this extra layer of indirection is introduced, whereby this block
+ contains the list of blocks that the stream directory occupies, and the stream
+ directory itself can be stitched together accordingly. The number of
+ ``ulittle32_t``'s in this array is given by ``ceil(NumDirectoryBytes / BlockSize)``.
+
+The Stream Directory
+====================
+The Stream Directory is the root of all access to the other streams in an MSF
+file. Beginning at byte 0 of the stream directory is the following structure:
+
+.. code-block:: c++
+
+ struct StreamDirectory {
+ ulittle32_t NumStreams;
+ ulittle32_t StreamSizes[NumStreams];
+ ulittle32_t StreamBlocks[NumStreams][];
+ };
+
+And this structure occupies exactly ``SuperBlock->NumDirectoryBytes`` bytes.
+Note that each of the last two arrays is of variable length, and in particular
+that the second array is jagged.
+
+**Example:** Suppose a hypothetical PDB file with a 4KiB block size, and 4
+streams of lengths {1000 bytes, 8000 bytes, 16000 bytes, 9000 bytes}.
+
+Stream 0: ceil(1000 / 4096) = 1 block
+
+Stream 1: ceil(8000 / 4096) = 2 blocks
+
+Stream 2: ceil(16000 / 4096) = 4 blocks
+
+Stream 3: ceil(9000 / 4096) = 3 blocks
+
+In total, 10 blocks are used. Let's see what the stream directory might look
+like:
+
+.. code-block:: c++
+
+ struct StreamDirectory {
+ ulittle32_t NumStreams = 4;
+ ulittle32_t StreamSizes[] = {1000, 8000, 16000, 9000};
+ ulittle32_t StreamBlocks[][] = {
+ {4},
+ {5, 6},
+ {11, 9, 7, 8},
+ {10, 15, 12}
+ };
+ };
+
+In total, this occupies ``15 * 4 = 60`` bytes, so ``SuperBlock->NumDirectoryBytes``
+would equal ``60``, and ``SuperBlock->BlockMapAddr`` would be an array of one
+``ulittle32_t``, since ``60 <= SuperBlock->BlockSize``.
+
+Note also that the streams are discontiguous, and that part of stream 3 is in the
+middle of part of stream 2. You cannot assume anything about the layout of the
+blocks!
+
+Alignment and Block Boundaries
+==============================
+As may be clear by now, it is possible for a single field (whether it be a high
+level record, a long string field, or even a single ``uint16``) to begin and
+end in separate blocks. For example, if the block size is 4096 bytes, and a
+``uint16`` field begins at the last byte of the current block, then it would
+need to end on the first byte of the next block. Since blocks are not
+necessarily contiguously laid out in the file, this means that both the consumer
+and the producer of an MSF file must be prepared to split data apart
+accordingly. In the aforementioned example, the high byte of the ``uint16``
+would be written to the last byte of block N, and the low byte would be written
+to the first byte of block N+1, which could be tens of thousands of bytes later
+(or even earlier!) in the file, depending on what the stream directory says.
diff --git a/docs/PDB/PdbStream.rst b/docs/PDB/PdbStream.rst new file mode 100644 index 0000000000000..0f9e0715edd85 --- /dev/null +++ b/docs/PDB/PdbStream.rst @@ -0,0 +1,80 @@ +======================================== +The PDB Info Stream (aka the PDB Stream) +======================================== + +.. contents:: + :local: + +.. _pdb_stream_header: + +Stream Header +============= +At offset 0 of the PDB Stream is a header with the following layout: + + +.. code-block:: c++ + + struct PdbStreamHeader { + ulittle32_t Version; + ulittle32_t Signature; + ulittle32_t Age; + Guid UniqueId; + }; + +- **Version** - A Value from the following enum: + +.. code-block:: c++ + + enum class PdbStreamVersion : uint32_t { + VC2 = 19941610, + VC4 = 19950623, + VC41 = 19950814, + VC50 = 19960307, + VC98 = 19970604, + VC70Dep = 19990604, + VC70 = 20000404, + VC80 = 20030901, + VC110 = 20091201, + VC140 = 20140508, + }; + +While the meaning of this field appears to be obvious, in practice we have +never observed a value other than ``VC70``, even with modern versions of +the toolchain, and it is unclear why the other values exist. It is assumed +that certain aspects of the PDB stream's layout, and perhaps even that of +the other streams, will change if the value is something other than ``VC70``. + +- **Signature** - A 32-bit time-stamp generated with a call to ``time()`` at + the time the PDB file is written. Note that due to the inherent uniqueness + problems of using a timestamp with 1-second granularity, this field does not + really serve its intended purpose, and as such is typically ignored in favor + of the ``Guid`` field, described below. + +- **Age** - The number of times the PDB file has been written. This can be used + along with ``Guid`` to match the PDB to its corresponding executable. + +- **Guid** - A 128-bit identifier guaranteed to be unique across space and time. + In general, this can be thought of as the result of calling the Win32 API + `UuidCreate <https://msdn.microsoft.com/en-us/library/windows/desktop/aa379205(v=vs.85).aspx>`__, + although LLVM cannot rely on that, as it must work on non-Windows platforms. + +Matching a PDB to its executable +================================ +The linker is responsible for writing both the PDB and the final executable, and +as a result is the only entity capable of writing the information necessary to +match the PDB to the executable. + +In order to accomplish this, the linker generates a guid for the PDB (or +re-uses the existing guid if it is linking incrementally) and increments the Age +field. + +The executable is a PE/COFF file, and part of a PE/COFF file is the presence of +number of "directories". For our purposes here, we are interested in the "debug +directory". The exact format of a debug directory is described by the +`IMAGE_DEBUG_DIRECTORY structure <https://msdn.microsoft.com/en-us/library/windows/desktop/ms680307(v=vs.85).aspx>`__. +For this particular case, the linker emits a debug directory of type +``IMAGE_DEBUG_TYPE_CODEVIEW``. The format of this record is defined in +``llvm/DebugInfo/CodeView/CVDebugRecord.h``, but it suffices to say here only +that it includes the same ``Guid`` and ``Age`` fields. At runtime, a +debugger or tool can scan the COFF executable image for the presence of +a debug directory of the correct type and verify that the Guid and Age match. diff --git a/docs/PDB/PublicStream.rst b/docs/PDB/PublicStream.rst new file mode 100644 index 0000000000000..5b413cfb88659 --- /dev/null +++ b/docs/PDB/PublicStream.rst @@ -0,0 +1,3 @@ +=====================================
+The PDB Public Symbol Stream
+=====================================
diff --git a/docs/PDB/TpiStream.rst b/docs/PDB/TpiStream.rst new file mode 100644 index 0000000000000..1e3297ebdc74d --- /dev/null +++ b/docs/PDB/TpiStream.rst @@ -0,0 +1,3 @@ +=====================================
+The PDB TPI Stream
+=====================================
diff --git a/docs/PDB/index.rst b/docs/PDB/index.rst new file mode 100644 index 0000000000000..5300588b1d8ae --- /dev/null +++ b/docs/PDB/index.rst @@ -0,0 +1,167 @@ +=====================================
+The PDB File Format
+=====================================
+
+.. contents::
+ :local:
+
+.. _pdb_intro:
+
+Introduction
+============
+
+PDB (Program Database) is a file format invented by Microsoft and which contains
+debug information that can be consumed by debuggers and other tools. Since
+officially supported APIs exist on Windows for querying debug information from
+PDBs even without the user understanding the internals of the file format, a
+large ecosystem of tools has been built for Windows to consume this format. In
+order for Clang to be able to generate programs that can interoperate with these
+tools, it is necessary for us to generate PDB files ourselves.
+
+At the same time, LLVM has a long history of being able to cross-compile from
+any platform to any platform, and we wish for the same to be true here. So it
+is necessary for us to understand the PDB file format at the byte-level so that
+we can generate PDB files entirely on our own.
+
+This manual describes what we know about the PDB file format today. The layout
+of the file, the various streams contained within, the format of individual
+records within, and more.
+
+We would like to extend our heartfelt gratitude to Microsoft, without whom we
+would not be where we are today. Much of the knowledge contained within this
+manual was learned through reading code published by Microsoft on their `GitHub
+repo <https://github.com/Microsoft/microsoft-pdb>`__.
+
+.. _pdb_layout:
+
+File Layout
+===========
+
+.. important::
+ Unless otherwise specified, all numeric values are encoded in little endian.
+ If you see a type such as ``uint16_t`` or ``uint64_t`` going forward, always
+ assume it is little endian!
+
+.. toctree::
+ :hidden:
+
+ MsfFile
+ PdbStream
+ TpiStream
+ DbiStream
+ ModiStream
+ PublicStream
+ GlobalStream
+ HashStream
+ CodeViewSymbols
+ CodeViewTypes
+
+.. _msf:
+
+The MSF Container
+-----------------
+A PDB file is really just a special case of an MSF (Multi-Stream Format) file.
+An MSF file is actually a miniature "file system within a file". It contains
+multiple streams (aka files) which can represent arbitrary data, and these
+streams are divided into blocks which may not necessarily be contiguously
+laid out within the file (aka fragmented). Additionally, the MSF contains a
+stream directory (aka MFT) which describes how the streams (files) are laid
+out within the MSF.
+
+For more information about the MSF container format, stream directory, and
+block layout, see :doc:`MsfFile`.
+
+.. _streams:
+
+Streams
+-------
+The PDB format contains a number of streams which describe various information
+such as the types, symbols, source files, and compilands (e.g. object files)
+of a program, as well as some additional streams containing hash tables that are
+used by debuggers and other tools to provide fast lookup of records and types
+by name, and various other information about how the program was compiled such
+as the specific toolchain used, and more. A summary of streams contained in a
+PDB file is as follows:
+
++--------------------+------------------------------+-------------------------------------------+
+| Name | Stream Index | Contents |
++====================+==============================+===========================================+
+| Old Directory | - Fixed Stream Index 0 | - Previous MSF Stream Directory |
++--------------------+------------------------------+-------------------------------------------+
+| PDB Stream | - Fixed Stream Index 1 | - Basic File Information |
+| | | - Fields to match EXE to this PDB |
+| | | - Map of named streams to stream indices |
++--------------------+------------------------------+-------------------------------------------+
+| TPI Stream | - Fixed Stream Index 2 | - CodeView Type Records |
+| | | - Index of TPI Hash Stream |
++--------------------+------------------------------+-------------------------------------------+
+| DBI Stream | - Fixed Stream Index 3 | - Module/Compiland Information |
+| | | - Indices of individual module streams |
+| | | - Indices of public / global streams |
+| | | - Section Contribution Information |
+| | | - Source File Information |
+| | | - FPO / PGO Data |
++--------------------+------------------------------+-------------------------------------------+
+| IPI Stream | - Fixed Stream Index 4 | - CodeView Type Records |
+| | | - Index of IPI Hash Stream |
++--------------------+------------------------------+-------------------------------------------+
+| /LinkInfo | - Contained in PDB Stream | - Unknown |
+| | Named Stream map | |
++--------------------+------------------------------+-------------------------------------------+
+| /src/headerblock | - Contained in PDB Stream | - Unknown |
+| | Named Stream map | |
++--------------------+------------------------------+-------------------------------------------+
+| /names | - Contained in PDB Stream | - PDB-wide global string table used for |
+| | Named Stream map | string de-duplication |
++--------------------+------------------------------+-------------------------------------------+
+| Module Info Stream | - Contained in DBI Stream | - CodeView Symbol Records for this module |
+| | - One for each compiland | - Line Number Information |
++--------------------+------------------------------+-------------------------------------------+
+| Public Stream | - Contained in DBI Stream | - Public (Exported) Symbol Records |
+| | | - Index of Public Hash Stream |
++--------------------+------------------------------+-------------------------------------------+
+| Global Stream | - Contained in DBI Stream | - Global Symbol Records |
+| | | - Index of Global Hash Stream |
++--------------------+------------------------------+-------------------------------------------+
+| TPI Hash Stream | - Contained in TPI Stream | - Hash table for looking up TPI records |
+| | | by name |
++--------------------+------------------------------+-------------------------------------------+
+| IPI Hash Stream | - Contained in IPI Stream | - Hash table for looking up IPI records |
+| | | by name |
++--------------------+------------------------------+-------------------------------------------+
+
+More information about the structure of each of these can be found on the
+following pages:
+
+:doc:`PdbStream`
+ Information about the PDB Info Stream and how it is used to match PDBs to EXEs.
+
+:doc:`TpiStream`
+ Information about the TPI stream and the CodeView records contained within.
+
+:doc:`DbiStream`
+ Information about the DBI stream and relevant substreams including the Module Substreams,
+ source file information, and CodeView symbol records contained within.
+
+:doc:`ModiStream`
+ Information about the Module Information Stream, of which there is one for each compilation
+ unit and the format of symbols contained within.
+
+:doc:`PublicStream`
+ Information about the Public Symbol Stream.
+
+:doc:`GlobalStream`
+ Information about the Global Symbol Stream.
+
+:doc:`HashStream`
+ Information about the Hash Table stream, and how it can be used to quickly look up records
+ by name.
+
+CodeView
+========
+CodeView is another format which comes into the picture. While MSF defines
+the structure of the overall file, and PDB defines the set of streams that
+appear within the MSF file and the format of those streams, CodeView defines
+the format of **symbol and type records** that appear within specific streams.
+Refer to the pages on :doc:`CodeViewSymbols` and :doc:`CodeViewTypes` for
+more information about the CodeView format.
diff --git a/docs/Phabricator.rst b/docs/Phabricator.rst index 04319a9a378f6..06a9c6af9b4d7 100644 --- a/docs/Phabricator.rst +++ b/docs/Phabricator.rst @@ -128,8 +128,12 @@ Committing a change ------------------- Once a patch has been reviewed and approved on Phabricator it can then be -committed to trunk. There are multiple workflows to achieve this. Whichever -method you follow it is recommend that your commit message ends with the line: +committed to trunk. If you do not have commit access, someone has to +commit the change for you (with attribution). It is sufficient to add +a comment to the approved review indicating you cannot commit the patch +yourself. If you have commit access, there are multiple workflows to commit the +change. Whichever method you follow it is recommend that your commit message +ends with the line: :: diff --git a/docs/ProgrammersManual.rst b/docs/ProgrammersManual.rst index 030637048bfb2..ffc022eef168d 100644 --- a/docs/ProgrammersManual.rst +++ b/docs/ProgrammersManual.rst @@ -149,7 +149,7 @@ rarely have to include this file directly). .. code-block:: c++ - if (AllocationInst *AI = dyn_cast<AllocationInst>(Val)) { + if (auto *AI = dyn_cast<AllocationInst>(Val)) { // ... } @@ -263,6 +263,134 @@ almost never be stored or mentioned directly. They are intended solely for use when defining a function which should be able to efficiently accept concatenated strings. +.. _formatting_strings: + +Formatting strings (the ``formatv`` function) +--------------------------------------------- +While LLVM doesn't necessarily do a lot of string manipulation and parsing, it +does do a lot of string formatting. From diagnostic messages, to llvm tool +outputs such as ``llvm-readobj`` to printing verbose disassembly listings and +LLDB runtime logging, the need for string formatting is pervasive. + +The ``formatv`` is similar in spirit to ``printf``, but uses a different syntax +which borrows heavily from Python and C#. Unlike ``printf`` it deduces the type +to be formatted at compile time, so it does not need a format specifier such as +``%d``. This reduces the mental overhead of trying to construct portable format +strings, especially for platform-specific types like ``size_t`` or pointer types. +Unlike both ``printf`` and Python, it additionally fails to compile if LLVM does +not know how to format the type. These two properties ensure that the function +is both safer and simpler to use than traditional formatting methods such as +the ``printf`` family of functions. + +Simple formatting +^^^^^^^^^^^^^^^^^ + +A call to ``formatv`` involves a single **format string** consisting of 0 or more +**replacement sequences**, followed by a variable length list of **replacement values**. +A replacement sequence is a string of the form ``{N[[,align]:style]}``. + +``N`` refers to the 0-based index of the argument from the list of replacement +values. Note that this means it is possible to reference the same parameter +multiple times, possibly with different style and/or alignment options, in any order. + +``align`` is an optional string specifying the width of the field to format +the value into, and the alignment of the value within the field. It is specified as +an optional **alignment style** followed by a positive integral **field width**. The +alignment style can be one of the characters ``-`` (left align), ``=`` (center align), +or ``+`` (right align). The default is right aligned. + +``style`` is an optional string consisting of a type specific that controls the +formatting of the value. For example, to format a floating point value as a percentage, +you can use the style option ``P``. + +Custom formatting +^^^^^^^^^^^^^^^^^ + +There are two ways to customize the formatting behavior for a type. + +1. Provide a template specialization of ``llvm::format_provider<T>`` for your + type ``T`` with the appropriate static format method. + + .. code-block:: c++ + + namespace llvm { + template<> + struct format_provider<MyFooBar> { + static void format(const MyFooBar &V, raw_ostream &Stream, StringRef Style) { + // Do whatever is necessary to format `V` into `Stream` + } + }; + void foo() { + MyFooBar X; + std::string S = formatv("{0}", X); + } + } + + This is a useful extensibility mechanism for adding support for formatting your own + custom types with your own custom Style options. But it does not help when you want + to extend the mechanism for formatting a type that the library already knows how to + format. For that, we need something else. + +2. Provide a **format adapter** inheriting from ``llvm::FormatAdapter<T>``. + + .. code-block:: c++ + + namespace anything { + struct format_int_custom : public llvm::FormatAdapter<int> { + explicit format_int_custom(int N) : llvm::FormatAdapter<int>(N) {} + void format(llvm::raw_ostream &Stream, StringRef Style) override { + // Do whatever is necessary to format ``this->Item`` into ``Stream`` + } + }; + } + namespace llvm { + void foo() { + std::string S = formatv("{0}", anything::format_int_custom(42)); + } + } + + If the type is detected to be derived from ``FormatAdapter<T>``, ``formatv`` + will call the + ``format`` method on the argument passing in the specified style. This allows + one to provide custom formatting of any type, including one which already has + a builtin format provider. + +``formatv`` Examples +^^^^^^^^^^^^^^^^^^^^ +Below is intended to provide an incomplete set of examples demonstrating +the usage of ``formatv``. More information can be found by reading the +doxygen documentation or by looking at the unit test suite. + + +.. code-block:: c++ + + std::string S; + // Simple formatting of basic types and implicit string conversion. + S = formatv("{0} ({1:P})", 7, 0.35); // S == "7 (35.00%)" + + // Out-of-order referencing and multi-referencing + outs() << formatv("{0} {2} {1} {0}", 1, "test", 3); // prints "1 3 test 1" + + // Left, right, and center alignment + S = formatv("{0,7}", 'a'); // S == " a"; + S = formatv("{0,-7}", 'a'); // S == "a "; + S = formatv("{0,=7}", 'a'); // S == " a "; + S = formatv("{0,+7}", 'a'); // S == " a"; + + // Custom styles + S = formatv("{0:N} - {0:x} - {1:E}", 12345, 123908342); // S == "12,345 - 0x3039 - 1.24E8" + + // Adapters + S = formatv("{0}", fmt_align(42, AlignStyle::Center, 7)); // S == " 42 " + S = formatv("{0}", fmt_repeat("hi", 3)); // S == "hihihi" + S = formatv("{0}", fmt_pad("hi", 2, 6)); // S == " hi " + + // Ranges + std::vector<int> V = {8, 9, 10}; + S = formatv("{0}", make_range(V.begin(), V.end())); // S == "8, 9, 10" + S = formatv("{0:$[+]}", make_range(V.begin(), V.end())); // S == "8+9+10" + S = formatv("{0:$[ + ]@[x]}", make_range(V.begin(), V.end())); // S == "0x8 + 0x9 + 0xA" + .. _error_apis: Error handling @@ -320,7 +448,7 @@ actually a lightweight wrapper for user-defined error types, allowing arbitrary information to be attached to describe the error. This is similar to the way C++ exceptions allow throwing of user-defined types. -Success values are created by calling ``Error::success()``: +Success values are created by calling ``Error::success()``, E.g.: .. code-block:: c++ @@ -334,28 +462,32 @@ Success values are very cheap to construct and return - they have minimal impact on program performance. Failure values are constructed using ``make_error<T>``, where ``T`` is any class -that inherits from the ErrorInfo utility: +that inherits from the ErrorInfo utility, E.g.: .. code-block:: c++ - class MyError : public ErrorInfo<MyError> { + class BadFileFormat : public ErrorInfo<BadFileFormat> { public: - MyError(std::string Msg) : Msg(Msg) {} - void log(OStream &OS) const override { OS << "MyError - " << Msg; } static char ID; - private: - std::string Msg; - }; + std::string Path; - char MyError::ID = 0; // In MyError.cpp + BadFileFormat(StringRef Path) : Path(Path.str()) {} - Error bar() { - if (checkErrorCondition) - return make_error<MyError>("Error condition detected"); + void log(raw_ostream &OS) const override { + OS << Path << " is malformed"; + } - // No error - proceed with bar. + std::error_code convertToErrorCode() const override { + return make_error_code(object_error::parse_failed); + } + }; - // Return success value. + char FileExists::ID; // This should be declared in the C++ file. + + Error printFormattedFile(StringRef Path) { + if (<check for valid format>) + return make_error<InvalidObjectFile>(Path); + // print file contents. return Error::success(); } @@ -374,35 +506,58 @@ success, enabling the following idiom: For functions that can fail but need to return a value the ``Expected<T>`` utility can be used. Values of this type can be constructed with either a -``T``, or a ``Error``. Expected<T> values are also implicitly convertible to -boolean, but with the opposite convention to Error: true for success, false for -error. If success, the ``T`` value can be accessed via the dereference operator. -If failure, the ``Error`` value can be extracted using the ``takeError()`` -method. Idiomatic usage looks like: +``T``, or an ``Error``. Expected<T> values are also implicitly convertible to +boolean, but with the opposite convention to ``Error``: true for success, false +for error. If success, the ``T`` value can be accessed via the dereference +operator. If failure, the ``Error`` value can be extracted using the +``takeError()`` method. Idiomatic usage looks like: .. code-block:: c++ - Expected<float> parseAndSquareRoot(IStream &IS) { - float f; - OS >> f; - if (f < 0) - return make_error<FloatingPointError>(...); - return sqrt(f); + Expected<FormattedFile> openFormattedFile(StringRef Path) { + // If badly formatted, return an error. + if (auto Err = checkFormat(Path)) + return std::move(Err); + // Otherwise return a FormattedFile instance. + return FormattedFile(Path); } - Error foo(IStream &IS) { - if (auto SqrtOrErr = parseAndSquartRoot(IS)) { - float Sqrt = *SqrtOrErr; - // ... + Error processFormattedFile(StringRef Path) { + // Try to open a formatted file + if (auto FileOrErr = openFormattedFile(Path)) { + // On success, grab a reference to the file and continue. + auto &File = *FileOrErr; + ... } else - return SqrtOrErr.takeError(); + // On error, extract the Error value and return it. + return FileOrErr.takeError(); } -All Error instances, whether success or failure, must be either checked or -moved from (via std::move or a return) before they are destructed. Accidentally -discarding an unchecked error will cause a program abort at the point where the -unchecked value's destructor is run, making it easy to identify and fix -violations of this rule. +If an ``Expected<T>`` value is in success mode then the ``takeError()`` method +will return a success value. Using this fact, the above function can be +rewritten as: + +.. code-block:: c++ + + Error processFormattedFile(StringRef Path) { + // Try to open a formatted file + auto FileOrErr = openFormattedFile(Path); + if (auto Err = FileOrErr.takeError()) + // On error, extract the Error value and return it. + return Err; + // On success, grab a reference to the file and continue. + auto &File = *FileOrErr; + ... + } + +This second form is often more readable for functions that involve multiple +``Expected<T>`` values as it limits the indentation required. + +All ``Error`` instances, whether success or failure, must be either checked or +moved from (via ``std::move`` or a return) before they are destructed. +Accidentally discarding an unchecked error will cause a program abort at the +point where the unchecked value's destructor is run, making it easy to identify +and fix violations of this rule. Success values are considered checked once they have been tested (by invoking the boolean conversion operator): @@ -414,8 +569,8 @@ the boolean conversion operator): // Safe to continue: Err was checked. -In contrast, the following code will always cause an abort, regardless of the -return value of ``foo``: +In contrast, the following code will always cause an abort, even if ``canFail`` +returns a success value: .. code-block:: c++ @@ -428,22 +583,318 @@ been activated: .. code-block:: c++ - auto Err = canFail(...); - if (auto Err2 = - handleErrors(std::move(Err), - [](std::unique_ptr<MyError> M) { - // Try to handle 'M'. If successful, return a success value from - // the handler. - if (tryToHandle(M)) - return Error::success(); + handleErrors( + processFormattedFile(...), + [](const BadFileFormat &BFF) { + report("Unable to process " + BFF.Path + ": bad format"); + }, + [](const FileNotFound &FNF) { + report("File not found " + FNF.Path); + }); + +The ``handleErrors`` function takes an error as its first argument, followed by +a variadic list of "handlers", each of which must be a callable type (a +function, lambda, or class with a call operator) with one argument. The +``handleErrors`` function will visit each handler in the sequence and check its +argument type against the dynamic type of the error, running the first handler +that matches. This is the same decision process that is used decide which catch +clause to run for a C++ exception. + +Since the list of handlers passed to ``handleErrors`` may not cover every error +type that can occur, the ``handleErrors`` function also returns an Error value +that must be checked or propagated. If the error value that is passed to +``handleErrors`` does not match any of the handlers it will be returned from +handleErrors. Idiomatic use of ``handleErrors`` thus looks like: + +.. code-block:: c++ + + if (auto Err = + handleErrors( + processFormattedFile(...), + [](const BadFileFormat &BFF) { + report("Unable to process " + BFF.Path + ": bad format"); + }, + [](const FileNotFound &FNF) { + report("File not found " + FNF.Path); + })) + return Err; + +In cases where you truly know that the handler list is exhaustive the +``handleAllErrors`` function can be used instead. This is identical to +``handleErrors`` except that it will terminate the program if an unhandled +error is passed in, and can therefore return void. The ``handleAllErrors`` +function should generally be avoided: the introduction of a new error type +elsewhere in the program can easily turn a formerly exhaustive list of errors +into a non-exhaustive list, risking unexpected program termination. Where +possible, use handleErrors and propagate unknown errors up the stack instead. + +For tool code, where errors can be handled by printing an error message then +exiting with an error code, the :ref:`ExitOnError <err_exitonerr>` utility +may be a better choice than handleErrors, as it simplifies control flow when +calling fallible functions. + +StringError +""""""""""" + +Many kinds of errors have no recovery strategy, the only action that can be +taken is to report them to the user so that the user can attempt to fix the +environment. In this case representing the error as a string makes perfect +sense. LLVM provides the ``StringError`` class for this purpose. It takes two +arguments: A string error message, and an equivalent ``std::error_code`` for +interoperability: + +.. code-block:: c++ + + make_error<StringError>("Bad executable", + make_error_code(errc::executable_format_error")); + +If you're certain that the error you're building will never need to be converted +to a ``std::error_code`` you can use the ``inconvertibleErrorCode()`` function: + +.. code-block:: c++ + + make_error<StringError>("Bad executable", inconvertibleErrorCode()); + +This should be done only after careful consideration. If any attempt is made to +convert this error to a ``std::error_code`` it will trigger immediate program +termination. Unless you are certain that your errors will not need +interoperability you should look for an existing ``std::error_code`` that you +can convert to, and even (as painful as it is) consider introducing a new one as +a stopgap measure. + +Interoperability with std::error_code and ErrorOr +""""""""""""""""""""""""""""""""""""""""""""""""" + +Many existing LLVM APIs use ``std::error_code`` and its partner ``ErrorOr<T>`` +(which plays the same role as ``Expected<T>``, but wraps a ``std::error_code`` +rather than an ``Error``). The infectious nature of error types means that an +attempt to change one of these functions to return ``Error`` or ``Expected<T>`` +instead often results in an avalanche of changes to callers, callers of callers, +and so on. (The first such attempt, returning an ``Error`` from +MachOObjectFile's constructor, was abandoned after the diff reached 3000 lines, +impacted half a dozen libraries, and was still growing). + +To solve this problem, the ``Error``/``std::error_code`` interoperability requirement was +introduced. Two pairs of functions allow any ``Error`` value to be converted to a +``std::error_code``, any ``Expected<T>`` to be converted to an ``ErrorOr<T>``, and vice +versa: + +.. code-block:: c++ + + std::error_code errorToErrorCode(Error Err); + Error errorCodeToError(std::error_code EC); + + template <typename T> ErrorOr<T> expectedToErrorOr(Expected<T> TOrErr); + template <typename T> Expected<T> errorOrToExpected(ErrorOr<T> TOrEC); + + +Using these APIs it is easy to make surgical patches that update individual +functions from ``std::error_code`` to ``Error``, and from ``ErrorOr<T>`` to +``Expected<T>``. + +Returning Errors from error handlers +"""""""""""""""""""""""""""""""""""" + +Error recovery attempts may themselves fail. For that reason, ``handleErrors`` +actually recognises three different forms of handler signature: + +.. code-block:: c++ + + // Error must be handled, no new errors produced: + void(UserDefinedError &E); + + // Error must be handled, new errors can be produced: + Error(UserDefinedError &E); + + // Original error can be inspected, then re-wrapped and returned (or a new + // error can be produced): + Error(std::unique_ptr<UserDefinedError> E); + +Any error returned from a handler will be returned from the ``handleErrors`` +function so that it can be handled itself, or propagated up the stack. + +.. _err_exitonerr: + +Using ExitOnError to simplify tool code +""""""""""""""""""""""""""""""""""""""" + +Library code should never call ``exit`` for a recoverable error, however in tool +code (especially command line tools) this can be a reasonable approach. Calling +``exit`` upon encountering an error dramatically simplifies control flow as the +error no longer needs to be propagated up the stack. This allows code to be +written in straight-line style, as long as each fallible call is wrapped in a +check and call to exit. The ``ExitOnError`` class supports this pattern by +providing call operators that inspect ``Error`` values, stripping the error away +in the success case and logging to ``stderr`` then exiting in the failure case. - // We failed to handle 'M' - return it from the handler. - // This value will be passed back from catchErrors and - // wind up in Err2, where it will be returned from this function. - return Error(std::move(M)); - }))) - return Err2; +To use this class, declare a global ``ExitOnError`` variable in your program: +.. code-block:: c++ + + ExitOnError ExitOnErr; + +Calls to fallible functions can then be wrapped with a call to ``ExitOnErr``, +turning them into non-failing calls: + +.. code-block:: c++ + + Error mayFail(); + Expected<int> mayFail2(); + + void foo() { + ExitOnErr(mayFail()); + int X = ExitOnErr(mayFail2()); + } + +On failure, the error's log message will be written to ``stderr``, optionally +preceded by a string "banner" that can be set by calling the setBanner method. A +mapping can also be supplied from ``Error`` values to exit codes using the +``setExitCodeMapper`` method: + +.. code-block:: c++ + + int main(int argc, char *argv[]) { + ExitOnErr.setBanner(std::string(argv[0]) + " error:"); + ExitOnErr.setExitCodeMapper( + [](const Error &Err) { + if (Err.isA<BadFileFormat>()) + return 2; + return 1; + }); + +Use ``ExitOnError`` in your tool code where possible as it can greatly improve +readability. + +Fallible constructors +""""""""""""""""""""" + +Some classes require resource acquisition or other complex initialization that +can fail during construction. Unfortunately constructors can't return errors, +and having clients test objects after they're constructed to ensure that they're +valid is error prone as it's all too easy to forget the test. To work around +this, use the named constructor idiom and return an ``Expected<T>``: + +.. code-block:: c++ + + class Foo { + public: + + static Expected<Foo> Create(Resource R1, Resource R2) { + Error Err; + Foo F(R1, R2, Err); + if (Err) + return std::move(Err); + return std::move(F); + } + + private: + + Foo(Resource R1, Resource R2, Error &Err) { + ErrorAsOutParameter EAO(&Err); + if (auto Err2 = R1.acquire()) { + Err = std::move(Err2); + return; + } + Err = R2.acquire(); + } + }; + + +Here, the named constructor passes an ``Error`` by reference into the actual +constructor, which the constructor can then use to return errors. The +``ErrorAsOutParameter`` utility sets the ``Error`` value's checked flag on entry +to the constructor so that the error can be assigned to, then resets it on exit +to force the client (the named constructor) to check the error. + +By using this idiom, clients attempting to construct a Foo receive either a +well-formed Foo or an Error, never an object in an invalid state. + +Propagating and consuming errors based on types +""""""""""""""""""""""""""""""""""""""""""""""" + +In some contexts, certain types of error are known to be benign. For example, +when walking an archive, some clients may be happy to skip over badly formatted +object files rather than terminating the walk immediately. Skipping badly +formatted objects could be achieved using an elaborate handler method, but the +Error.h header provides two utilities that make this idiom much cleaner: the +type inspection method, ``isA``, and the ``consumeError`` function: + +.. code-block:: c++ + + Error walkArchive(Archive A) { + for (unsigned I = 0; I != A.numMembers(); ++I) { + auto ChildOrErr = A.getMember(I); + if (auto Err = ChildOrErr.takeError()) { + if (Err.isA<BadFileFormat>()) + consumeError(std::move(Err)) + else + return Err; + } + auto &Child = *ChildOrErr; + // Use Child + ... + } + return Error::success(); + } + +Concatenating Errors with joinErrors +"""""""""""""""""""""""""""""""""""" + +In the archive walking example above ``BadFileFormat`` errors are simply +consumed and ignored. If the client had wanted report these errors after +completing the walk over the archive they could use the ``joinErrors`` utility: + +.. code-block:: c++ + + Error walkArchive(Archive A) { + Error DeferredErrs = Error::success(); + for (unsigned I = 0; I != A.numMembers(); ++I) { + auto ChildOrErr = A.getMember(I); + if (auto Err = ChildOrErr.takeError()) + if (Err.isA<BadFileFormat>()) + DeferredErrs = joinErrors(std::move(DeferredErrs), std::move(Err)); + else + return Err; + auto &Child = *ChildOrErr; + // Use Child + ... + } + return DeferredErrs; + } + +The ``joinErrors`` routine builds a special error type called ``ErrorList``, +which holds a list of user defined errors. The ``handleErrors`` routine +recognizes this type and will attempt to handle each of the contained erorrs in +order. If all contained errors can be handled, ``handleErrors`` will return +``Error::success()``, otherwise ``handleErrors`` will concatenate the remaining +errors and return the resulting ``ErrorList``. + +Building fallible iterators and iterator ranges +""""""""""""""""""""""""""""""""""""""""""""""" + +The archive walking examples above retrieve archive members by index, however +this requires considerable boiler-plate for iteration and error checking. We can +clean this up by using ``Error`` with the "fallible iterator" pattern. The usual +C++ iterator patterns do not allow for failure on increment, but we can +incorporate support for it by having iterators hold an Error reference through +which they can report failure. In this pattern, if an increment operation fails +the failure is recorded via the Error reference and the iterator value is set to +the end of the range in order to terminate the loop. This ensures that the +dereference operation is safe anywhere that an ordinary iterator dereference +would be safe (i.e. when the iterator is not equal to end). Where this pattern +is followed (as in the ``llvm::object::Archive`` class) the result is much +cleaner iteration idiom: + +.. code-block:: c++ + + Error Err; + for (auto &Child : Ar->children(Err)) { + // Use Child - we only enter the loop when it's valid + ... + } + // Check Err after the loop to ensure it didn't break due to an error. + if (Err) + return Err; .. _function_apis: @@ -1743,6 +2194,22 @@ reverse) is O(1) worst case. Testing and setting bits within 128 bits (depends on size) of the current bit is also O(1). As a general statement, testing/setting bits in a SparseBitVector is O(distance away from last set bit). +.. _debugging: + +Debugging +========= + +A handful of `GDB pretty printers +<https://sourceware.org/gdb/onlinedocs/gdb/Pretty-Printing.html>`__ are +provided for some of the core LLVM libraries. To use them, execute the +following (or add it to your ``~/.gdbinit``):: + + source /path/to/llvm/src/utils/gdb-scripts/prettyprinters.py + +It also might be handy to enable the `print pretty +<http://ftp.gnu.org/old-gnu/Manuals/gdb/html_node/gdb_57.html>`__ option to +avoid data structures being printed as a big block of text. + .. _common: Helpful Hints for Common Operations @@ -2054,7 +2521,7 @@ iterate over all predecessors of BB: .. code-block:: c++ - #include "llvm/Support/CFG.h" + #include "llvm/IR/CFG.h" BasicBlock *BB = ...; for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) { @@ -2825,20 +3292,20 @@ Important Derived Types * ``unsigned getBitWidth() const``: Get the bit width of an integer type. ``SequentialType`` - This is subclassed by ArrayType, PointerType and VectorType. + This is subclassed by ArrayType and VectorType. * ``const Type * getElementType() const``: Returns the type of each of the elements in the sequential type. + * ``uint64_t getNumElements() const``: Returns the number of elements + in the sequential type. + ``ArrayType`` This is a subclass of SequentialType and defines the interface for array types. - * ``unsigned getNumElements() const``: Returns the number of elements - in the array. - ``PointerType`` - Subclass of SequentialType for pointer types. + Subclass of Type for pointer types. ``VectorType`` Subclass of SequentialType for vector types. A vector type is similar to an diff --git a/docs/Proposals/GitHubMove.rst b/docs/Proposals/GitHubMove.rst new file mode 100644 index 0000000000000..c1bdfb3592892 --- /dev/null +++ b/docs/Proposals/GitHubMove.rst @@ -0,0 +1,868 @@ +============================== +Moving LLVM Projects to GitHub +============================== + +.. contents:: Table of Contents + :depth: 4 + :local: + +Introduction +============ + +This is a proposal to move our current revision control system from our own +hosted Subversion to GitHub. Below are the financial and technical arguments as +to why we are proposing such a move and how people (and validation +infrastructure) will continue to work with a Git-based LLVM. + +There will be a survey pointing at this document which we'll use to gauge the +community's reaction and, if we collectively decide to move, the time-frame. Be +sure to make your view count. + +Additionally, we will discuss this during a BoF at the next US LLVM Developer +meeting (http://llvm.org/devmtg/2016-11/). + +What This Proposal is *Not* About +================================= + +Changing the development policy. + +This proposal relates only to moving the hosting of our source-code repository +from SVN hosted on our own servers to Git hosted on GitHub. We are not proposing +using GitHub's issue tracker, pull-requests, or code-review. + +Contributers will continue to earn commit access on demand under the Developer +Policy, except that that a GitHub account will be required instead of SVN +username/password-hash. + +Why Git, and Why GitHub? +======================== + +Why Move At All? +---------------- + +This discussion began because we currently host our own Subversion server +and Git mirror on a voluntary basis. The LLVM Foundation sponsors the server and +provides limited support, but there is only so much it can do. + +Volunteers are not sysadmins themselves, but compiler engineers that happen +to know a thing or two about hosting servers. We also don't have 24/7 support, +and we sometimes wake up to see that continuous integration is broken because +the SVN server is either down or unresponsive. + +We should take advantage of one of the services out there (GitHub, GitLab, +and BitBucket, among others) that offer better service (24/7 stability, disk +space, Git server, code browsing, forking facilities, etc) for free. + +Why Git? +-------- + +Many new coders nowadays start with Git, and a lot of people have never used +SVN, CVS, or anything else. Websites like GitHub have changed the landscape +of open source contributions, reducing the cost of first contribution and +fostering collaboration. + +Git is also the version control many LLVM developers use. Despite the +sources being stored in a SVN server, these developers are already using Git +through the Git-SVN integration. + +Git allows you to: + +* Commit, squash, merge, and fork locally without touching the remote server. +* Maintain local branches, enabling multiple threads of development. +* Collaborate on these branches (e.g. through your own fork of llvm on GitHub). +* Inspect the repository history (blame, log, bisect) without Internet access. +* Maintain remote forks and branches on Git hosting services and + integrate back to the main repository. + +In addition, because Git seems to be replacing many OSS projects' version +control systems, there are many tools that are built over Git. +Future tooling may support Git first (if not only). + +Why GitHub? +----------- + +GitHub, like GitLab and BitBucket, provides free code hosting for open source +projects. Any of these could replace the code-hosting infrastructure that we +have today. + +These services also have a dedicated team to monitor, migrate, improve and +distribute the contents of the repositories depending on region and load. + +GitHub has one important advantage over GitLab and +BitBucket: it offers read-write **SVN** access to the repository +(https://github.com/blog/626-announcing-svn-support). +This would enable people to continue working post-migration as though our code +were still canonically in an SVN repository. + +In addition, there are already multiple LLVM mirrors on GitHub, indicating that +part of our community has already settled there. + +On Managing Revision Numbers with Git +------------------------------------- + +The current SVN repository hosts all the LLVM sub-projects alongside each other. +A single revision number (e.g. r123456) thus identifies a consistent version of +all LLVM sub-projects. + +Git does not use sequential integer revision number but instead uses a hash to +identify each commit. (Linus mentioned that the lack of such revision number +is "the only real design mistake" in Git [TorvaldRevNum]_.) + +The loss of a sequential integer revision number has been a sticking point in +past discussions about Git: + +- "The 'branch' I most care about is mainline, and losing the ability to say + 'fixed in r1234' (with some sort of monotonically increasing number) would + be a tragic loss." [LattnerRevNum]_ +- "I like those results sorted by time and the chronology should be obvious, but + timestamps are incredibly cumbersome and make it difficult to verify that a + given checkout matches a given set of results." [TrickRevNum]_ +- "There is still the major regression with unreadable version numbers. + Given the amount of Bugzilla traffic with 'Fixed in...', that's a + non-trivial issue." [JSonnRevNum]_ +- "Sequential IDs are important for LNT and llvmlab bisection tool." [MatthewsRevNum]_. + +However, Git can emulate this increasing revision number: +``git rev-list --count <commit-hash>``. This identifier is unique only +within a single branch, but this means the tuple `(num, branch-name)` uniquely +identifies a commit. + +We can thus use this revision number to ensure that e.g. `clang -v` reports a +user-friendly revision number (e.g. `master-12345` or `4.0-5321`), addressing +the objections raised above with respect to this aspect of Git. + +What About Branches and Merges? +------------------------------- + +In contrast to SVN, Git makes branching easy. Git's commit history is +represented as a DAG, a departure from SVN's linear history. However, we propose +to mandate making merge commits illegal in our canonical Git repository. + +Unfortunately, GitHub does not support server side hooks to enforce such a +policy. We must rely on the community to avoid pushing merge commits. + +GitHub offers a feature called `Status Checks`: a branch protected by +`status checks` requires commits to be whitelisted before the push can happen. +We could supply a pre-push hook on the client side that would run and check the +history, before whitelisting the commit being pushed [statuschecks]_. +However this solution would be somewhat fragile (how do you update a script +installed on every developer machine?) and prevents SVN access to the +repository. + +What About Commit Emails? +------------------------- + +We will need a new bot to send emails for each commit. This proposal leaves the +email format unchanged besides the commit URL. + +Straw Man Migration Plan +======================== + +Step #1 : Before The Move +------------------------- + +1. Update docs to mention the move, so people are aware of what is going on. +2. Set up a read-only version of the GitHub project, mirroring our current SVN + repository. +3. Add the required bots to implement the commit emails, as well as the + umbrella repository update (if the multirepo is selected) or the read-only + Git views for the sub-projects (if the monorepo is selected). + +Step #2 : Git Move +------------------ + +4. Update the buildbots to pick up updates and commits from the GitHub + repository. Not all bots have to migrate at this point, but it'll help + provide infrastructure testing. +5. Update Phabricator to pick up commits from the GitHub repository. +6. LNT and llvmlab have to be updated: they rely on unique monotonically + increasing integer across branch [MatthewsRevNum]_. +7. Instruct downstream integrators to pick up commits from the GitHub + repository. +8. Review and prepare an update for the LLVM documentation. + +Until this point nothing has changed for developers, it will just +boil down to a lot of work for buildbot and other infrastructure +owners. + +The migration will pause here until all dependencies have cleared, and all +problems have been solved. + +Step #3: Write Access Move +-------------------------- + +9. Collect developers' GitHub account information, and add them to the project. +10. Switch the SVN repository to read-only and allow pushes to the GitHub repository. +11. Update the documentation. +12. Mirror Git to SVN. + +Step #4 : Post Move +------------------- + +13. Archive the SVN repository. +14. Update links on the LLVM website pointing to viewvc/klaus/phab etc. to + point to GitHub instead. + +One or Multiple Repositories? +============================= + +There are two major variants for how to structure our Git repository: The +"multirepo" and the "monorepo". + +Multirepo Variant +----------------- + +This variant recommends moving each LLVM sub-project to a separate Git +repository. This mimics the existing official read-only Git repositories +(e.g., http://llvm.org/git/compiler-rt.git), and creates new canonical +repositories for each sub-project. + +This will allow the individual sub-projects to remain distinct: a +developer interested only in compiler-rt can checkout only this repository, +build it, and work in isolation of the other sub-projects. + +A key need is to be able to check out multiple projects (i.e. lldb+clang+llvm or +clang+llvm+libcxx for example) at a specific revision. + +A tuple of revisions (one entry per repository) accurately describes the state +across the sub-projects. +For example, a given version of clang would be +*<LLVM-12345, clang-5432, libcxx-123, etc.>*. + +Umbrella Repository +^^^^^^^^^^^^^^^^^^^ + +To make this more convenient, a separate *umbrella* repository will be +provided. This repository will be used for the sole purpose of understanding +the sequence in which commits were pushed to the different repositories and to +provide a single revision number. + +This umbrella repository will be read-only and continuously updated +to record the above tuple. The proposed form to record this is to use Git +[submodules]_, possibly along with a set of scripts to help check out a +specific revision of the LLVM distribution. + +A regular LLVM developer does not need to interact with the umbrella repository +-- the individual repositories can be checked out independently -- but you would +need to use the umbrella repository to bisect multiple sub-projects at the same +time, or to check-out old revisions of LLVM with another sub-project at a +consistent state. + +This umbrella repository will be updated automatically by a bot (running on +notice from a webhook on every push, and periodically) on a per commit basis: a +single commit in the umbrella repository would match a single commit in a +sub-project. + +Living Downstream +^^^^^^^^^^^^^^^^^ + +Downstream SVN users can use the read/write SVN bridges with the following +caveats: + + * Be prepared for a one-time change to the upstream revision numbers. + * The upstream sub-project revision numbers will no longer be in sync. + +Downstream Git users can continue without any major changes, with the minor +change of upstreaming using `git push` instead of `git svn dcommit`. + +Git users also have the option of adopting an umbrella repository downstream. +The tooling for the upstream umbrella can easily be reused for downstream needs, +incorporating extra sub-projects and branching in parallel with sub-project +branches. + +Multirepo Preview +^^^^^^^^^^^^^^^^^ + +As a preview (disclaimer: this rough prototype, not polished and not +representative of the final solution), you can look at the following: + + * Repository: https://github.com/llvm-beanz/llvm-submodules + * Update bot: http://beanz-bot.com:8180/jenkins/job/submodule-update/ + +Concerns +^^^^^^^^ + + * Because GitHub does not allow server-side hooks, and because there is no + "push timestamp" in Git, the umbrella repository sequence isn't totally + exact: commits from different repositories pushed around the same time can + appear in different orders. However, we don't expect it to be the common case + or to cause serious issues in practice. + * You can't have a single cross-projects commit that would update both LLVM and + other sub-projects (something that can be achieved now). It would be possible + to establish a protocol whereby users add a special token to their commit + messages that causes the umbrella repo's updater bot to group all of them + into a single revision. + * Another option is to group commits that were pushed closely enough together + in the umbrella repository. This has the advantage of allowing cross-project + commits, and is less sensitive to mis-ordering commits. However, this has the + potential to group unrelated commits together, especially if the bot goes + down and needs to catch up. + * This variant relies on heavier tooling. But the current prototype shows that + it is not out-of-reach. + * Submodules don't have a good reputation / are complicating the command line. + However, in the proposed setup, a regular developer will seldom interact with + submodules directly, and certainly never update them. + * Refactoring across projects is not friendly: taking some functions from clang + to make it part of a utility in libSupport wouldn't carry the history of the + code in the llvm repo, preventing recursively applying `git blame` for + instance. However, this is not very different than how most people are + Interacting with the repository today, by splitting such change in multiple + commits. + +Workflows +^^^^^^^^^ + + * :ref:`Checkout/Clone a Single Project, without Commit Access <workflow-checkout-commit>`. + * :ref:`Checkout/Clone a Single Project, with Commit Access <workflow-multicheckout-nocommit>`. + * :ref:`Checkout/Clone Multiple Projects, with Commit Access <workflow-multicheckout-multicommit>`. + * :ref:`Commit an API Change in LLVM and Update the Sub-projects <workflow-cross-repo-commit>`. + * :ref:`Branching/Stashing/Updating for Local Development or Experiments <workflow-multi-branching>`. + * :ref:`Bisecting <workflow-multi-bisecting>`. + +Monorepo Variant +---------------- + +This variant recommends moving all LLVM sub-projects to a single Git repository, +similar to https://github.com/llvm-project/llvm-project. +This would mimic an export of the current SVN repository, with each sub-project +having its own top-level directory. +Not all sub-projects are used for building toolchains. In practice, www/ +and test-suite/ will probably stay out of the monorepo. + +Putting all sub-projects in a single checkout makes cross-project refactoring +naturally simple: + + * New sub-projects can be trivially split out for better reuse and/or layering + (e.g., to allow libSupport and/or LIT to be used by runtimes without adding a + dependency on LLVM). + * Changing an API in LLVM and upgrading the sub-projects will always be done in + a single commit, designing away a common source of temporary build breakage. + * Moving code across sub-project (during refactoring for instance) in a single + commit enables accurate `git blame` when tracking code change history. + * Tooling based on `git grep` works natively across sub-projects, allowing to + easier find refactoring opportunities across projects (for example reusing a + datastructure initially in LLDB by moving it into libSupport). + * Having all the sources present encourages maintaining the other sub-projects + when changing API. + +Finally, the monorepo maintains the property of the existing SVN repository that +the sub-projects move synchronously, and a single revision number (or commit +hash) identifies the state of the development across all projects. + +.. _build_single_project: + +Building a single sub-project +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Nobody will be forced to build unnecessary projects. The exact structure +is TBD, but making it trivial to configure builds for a single sub-project +(or a subset of sub-projects) is a hard requirement. + +As an example, it could look like the following:: + + mkdir build && cd build + # Configure only LLVM (default) + cmake path/to/monorepo + # Configure LLVM and lld + cmake path/to/monorepo -DLLVM_ENABLE_PROJECTS=lld + # Configure LLVM and clang + cmake path/to/monorepo -DLLVM_ENABLE_PROJECTS=clang + +.. _git-svn-mirror: + +Read/write sub-project mirrors +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +With the Monorepo, the existing single-subproject mirrors (e.g. +http://llvm.org/git/compiler-rt.git) with git-svn read-write access would +continue to be maintained: developers would continue to be able to use the +existing single-subproject git repositories as they do today, with *no changes +to workflow*. Everything (git fetch, git svn dcommit, etc.) could continue to +work identically to how it works today. The monorepo can be set-up such that the +SVN revision number matches the SVN revision in the GitHub SVN-bridge. + +Living Downstream +^^^^^^^^^^^^^^^^^ + +Downstream SVN users can use the read/write SVN bridge. The SVN revision +number can be preserved in the monorepo, minimizing the impact. + +Downstream Git users can continue without any major changes, by using the +git-svn mirrors on top of the SVN bridge. + +Git users can also work upstream with monorepo even if their downstream +fork has split repositories. They can apply patches in the appropriate +subdirectories of the monorepo using, e.g., `git am --directory=...`, or +plain `diff` and `patch`. + +Alternatively, Git users can migrate their own fork to the monorepo. As a +demonstration, we've migrated the "CHERI" fork to the monorepo in two ways: + + * Using a script that rewrites history (including merges) so that it looks + like the fork always lived in the monorepo [LebarCHERI]_. The upside of + this is when you check out an old revision, you get a copy of all llvm + sub-projects at a consistent revision. (For instance, if it's a clang + fork, when you check out an old revision you'll get a consistent version + of llvm proper.) The downside is that this changes the fork's commit + hashes. + + * Merging the fork into the monorepo [AminiCHERI]_. This preserves the + fork's commit hashes, but when you check out an old commit you only get + the one sub-project. + +Monorepo Preview +^^^^^^^^^^^^^^^^^ + +As a preview (disclaimer: this rough prototype, not polished and not +representative of the final solution), you can look at the following: + + * Full Repository: https://github.com/joker-eph/llvm-project + * Single sub-project view with *SVN write access* to the full repo: + https://github.com/joker-eph/compiler-rt + +Concerns +^^^^^^^^ + + * Using the monolithic repository may add overhead for those contributing to a + standalone sub-project, particularly on runtimes like libcxx and compiler-rt + that don't rely on LLVM; currently, a fresh clone of libcxx is only 15MB (vs. + 1GB for the monorepo), and the commit rate of LLVM may cause more frequent + `git push` collisions when upstreaming. Affected contributors can continue to + use the SVN bridge or the single-subproject Git mirrors with git-svn for + read-write. + * Using the monolithic repository may add overhead for those *integrating* a + standalone sub-project, even if they aren't contributing to it, due to the + same disk space concern as the point above. The availability of the + sub-project Git mirror addesses this, even without SVN access. + * Preservation of the existing read/write SVN-based workflows relies on the + GitHub SVN bridge, which is an extra dependency. Maintaining this locks us + into GitHub and could restrict future workflow changes. + +Workflows +^^^^^^^^^ + + * :ref:`Checkout/Clone a Single Project, without Commit Access <workflow-checkout-commit>`. + * :ref:`Checkout/Clone a Single Project, with Commit Access <workflow-monocheckout-nocommit>`. + * :ref:`Checkout/Clone Multiple Projects, with Commit Access <workflow-monocheckout-multicommit>`. + * :ref:`Commit an API Change in LLVM and Update the Sub-projects <workflow-cross-repo-commit>`. + * :ref:`Branching/Stashing/Updating for Local Development or Experiments <workflow-mono-branching>`. + * :ref:`Bisecting <workflow-mono-bisecting>`. + +Multi/Mono Hybrid Variant +------------------------- + +This variant recommends moving only the LLVM sub-projects that are *rev-locked* +to LLVM into a monorepo (clang, lld, lldb, ...), following the multirepo +proposal for the rest. While neither variant recommends combining sub-projects +like www/ and test-suite/ (which are completely standalone), this goes further +and keeps sub-projects like libcxx and compiler-rt in their own distinct +repositories. + +Concerns +^^^^^^^^ + + * This has most disadvantages of multirepo and monorepo, without bringing many + of the advantages. + * Downstream have to upgrade to the monorepo structure, but only partially. So + they will keep the infrastructure to integrate the other separate + sub-projects. + * All projects that use LIT for testing are effectively rev-locked to LLVM. + Furthermore, some runtimes (like compiler-rt) are rev-locked with Clang. + It's not clear where to draw the lines. + + +Workflow Before/After +===================== + +This section goes through a few examples of workflows, intended to illustrate +how end-users or developers would interact with the repository for +various use-cases. + +.. _workflow-checkout-commit: + +Checkout/Clone a Single Project, without Commit Access +------------------------------------------------------ + +Except the URL, nothing changes. The possibilities today are:: + + svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm + # or with Git + git clone http://llvm.org/git/llvm.git + +After the move to GitHub, you would do either:: + + git clone https://github.com/llvm-project/llvm.git + # or using the GitHub svn native bridge + svn co https://github.com/llvm-project/llvm/trunk + +The above works for both the monorepo and the multirepo, as we'll maintain the +existing read-only views of the individual sub-projects. + +Checkout/Clone a Single Project, with Commit Access +--------------------------------------------------- + +Currently +^^^^^^^^^ + +:: + + # direct SVN checkout + svn co https://user@llvm.org/svn/llvm-project/llvm/trunk llvm + # or using the read-only Git view, with git-svn + git clone http://llvm.org/git/llvm.git + cd llvm + git svn init https://llvm.org/svn/llvm-project/llvm/trunk --username=<username> + git config svn-remote.svn.fetch :refs/remotes/origin/master + git svn rebase -l # -l avoids fetching ahead of the git mirror. + +Commits are performed using `svn commit` or with the sequence `git commit` and +`git svn dcommit`. + +.. _workflow-multicheckout-nocommit: + +Multirepo Variant +^^^^^^^^^^^^^^^^^ + +With the multirepo variant, nothing changes but the URL, and commits can be +performed using `svn commit` or `git commit` and `git push`:: + + git clone https://github.com/llvm/llvm.git llvm + # or using the GitHub svn native bridge + svn co https://github.com/llvm/llvm/trunk/ llvm + +.. _workflow-monocheckout-nocommit: + +Monorepo Variant +^^^^^^^^^^^^^^^^ + +With the monorepo variant, there are a few options, depending on your +constraints. First, you could just clone the full repository:: + + git clone https://github.com/llvm/llvm-projects.git llvm + # or using the GitHub svn native bridge + svn co https://github.com/llvm/llvm-projects/trunk/ llvm + +At this point you have every sub-project (llvm, clang, lld, lldb, ...), which +:ref:`doesn't imply you have to build all of them <build_single_project>`. You +can still build only compiler-rt for instance. In this way it's not different +from someone who would check out all the projects with SVN today. + +You can commit as normal using `git commit` and `git push` or `svn commit`, and +read the history for a single project (`git log libcxx` for example). + +Secondly, there are a few options to avoid checking out all the sources. + +**Using the GitHub SVN bridge** + +The GitHub SVN native bridge allows to checkout a subdirectory directly: + + svn co https://github.com/llvm/llvm-projects/trunk/compiler-rt compiler-rt —username=... + +This checks out only compiler-rt and provides commit access using "svn commit", +in the same way as it would do today. + +**Using a Subproject Git Nirror** + +You can use *git-svn* and one of the sub-project mirrors:: + + # Clone from the single read-only Git repo + git clone http://llvm.org/git/llvm.git + cd llvm + # Configure the SVN remote and initialize the svn metadata + $ git svn init https://github.com/joker-eph/llvm-project/trunk/llvm —username=... + git config svn-remote.svn.fetch :refs/remotes/origin/master + git svn rebase -l + +In this case the repository contains only a single sub-project, and commits can +be made using `git svn dcommit`, again exactly as we do today. + +**Using a Sparse Checkouts** + +You can hide the other directories using a Git sparse checkout:: + + git config core.sparseCheckout true + echo /compiler-rt > .git/info/sparse-checkout + git read-tree -mu HEAD + +The data for all sub-projects is still in your `.git` directory, but in your +checkout, you only see `compiler-rt`. +Before you push, you'll need to fetch and rebase (`git pull --rebase`) as +usual. + +Note that when you fetch you'll likely pull in changes to sub-projects you don't +care about. If you are using spasre checkout, the files from other projects +won't appear on your disk. The only effect is that your commit hash changes. + +You can check whether the changes in the last fetch are relevant to your commit +by running:: + + git log origin/master@{1}..origin/master -- libcxx + +This command can be hidden in a script so that `git llvmpush` would perform all +these steps, fail only if such a dependent change exists, and show immediately +the change that prevented the push. An immediate repeat of the command would +(almost) certainly result in a successful push. +Note that today with SVN or git-svn, this step is not possible since the +"rebase" implicitly happens while committing (unless a conflict occurs). + +Checkout/Clone Multiple Projects, with Commit Access +---------------------------------------------------- + +Let's look how to assemble llvm+clang+libcxx at a given revision. + +Currently +^^^^^^^^^ + +:: + + svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm -r $REVISION + cd llvm/tools + svn co http://llvm.org/svn/llvm-project/clang/trunk clang -r $REVISION + cd ../projects + svn co http://llvm.org/svn/llvm-project/libcxx/trunk libcxx -r $REVISION + +Or using git-svn:: + + git clone http://llvm.org/git/llvm.git + cd llvm/ + git svn init https://llvm.org/svn/llvm-project/llvm/trunk --username=<username> + git config svn-remote.svn.fetch :refs/remotes/origin/master + git svn rebase -l + git checkout `git svn find-rev -B r258109` + cd tools + git clone http://llvm.org/git/clang.git + cd clang/ + git svn init https://llvm.org/svn/llvm-project/clang/trunk --username=<username> + git config svn-remote.svn.fetch :refs/remotes/origin/master + git svn rebase -l + git checkout `git svn find-rev -B r258109` + cd ../../projects/ + git clone http://llvm.org/git/libcxx.git + cd libcxx + git svn init https://llvm.org/svn/llvm-project/libcxx/trunk --username=<username> + git config svn-remote.svn.fetch :refs/remotes/origin/master + git svn rebase -l + git checkout `git svn find-rev -B r258109` + +Note that the list would be longer with more sub-projects. + +.. _workflow-multicheckout-multicommit: + +Multirepo Variant +^^^^^^^^^^^^^^^^^ + +With the multirepo variant, the umbrella repository will be used. This is +where the mapping from a single revision number to the individual repositories +revisions is stored.:: + + git clone https://github.com/llvm-beanz/llvm-submodules + cd llvm-submodules + git checkout $REVISION + git submodule init + git submodule update clang llvm libcxx + # the list of sub-project is optional, `git submodule update` would get them all. + +At this point the clang, llvm, and libcxx individual repositories are cloned +and stored alongside each other. There are CMake flags to describe the directory +structure; alternatively, you can just symlink `clang` to `llvm/tools/clang`, +etc. + +Another option is to checkout repositories based on the commit timestamp:: + + git checkout `git rev-list -n 1 --before="2009-07-27 13:37" master` + +.. _workflow-monocheckout-multicommit: + +Monorepo Variant +^^^^^^^^^^^^^^^^ + +The repository contains natively the source for every sub-projects at the right +revision, which makes this straightforward:: + + git clone https://github.com/llvm/llvm-projects.git llvm-projects + cd llvm-projects + git checkout $REVISION + +As before, at this point clang, llvm, and libcxx are stored in directories +alongside each other. + +.. _workflow-cross-repo-commit: + +Commit an API Change in LLVM and Update the Sub-projects +-------------------------------------------------------- + +Today this is possible, even though not common (at least not documented) for +subversion users and for git-svn users. For example, few Git users try to update +LLD or Clang in the same commit as they change an LLVM API. + +The multirepo variant does not address this: one would have to commit and push +separately in every individual repository. It would be possible to establish a +protocol whereby users add a special token to their commit messages that causes +the umbrella repo's updater bot to group all of them into a single revision. + +The monorepo variant handles this natively. + +Branching/Stashing/Updating for Local Development or Experiments +---------------------------------------------------------------- + +Currently +^^^^^^^^^ + +SVN does not allow this use case, but developers that are currently using +git-svn can do it. Let's look in practice what it means when dealing with +multiple sub-projects. + +To update the repository to tip of trunk:: + + git pull + cd tools/clang + git pull + cd ../../projects/libcxx + git pull + +To create a new branch:: + + git checkout -b MyBranch + cd tools/clang + git checkout -b MyBranch + cd ../../projects/libcxx + git checkout -b MyBranch + +To switch branches:: + + git checkout AnotherBranch + cd tools/clang + git checkout AnotherBranch + cd ../../projects/libcxx + git checkout AnotherBranch + +.. _workflow-multi-branching: + +Multirepo Variant +^^^^^^^^^^^^^^^^^ + +The multirepo works the same as the current Git workflow: every command needs +to be applied to each of the individual repositories. +However, the umbrella repository makes this easy using `git submodule foreach` +to replicate a command on all the individual repositories (or submodules +in this case): + +To create a new branch:: + + git submodule foreach git checkout -b MyBranch + +To switch branches:: + + git submodule foreach git checkout AnotherBranch + +.. _workflow-mono-branching: + +Monorepo Variant +^^^^^^^^^^^^^^^^ + +Regular Git commands are sufficient, because everything is in a single +repository: + +To update the repository to tip of trunk:: + + git pull + +To create a new branch:: + + git checkout -b MyBranch + +To switch branches:: + + git checkout AnotherBranch + +Bisecting +--------- + +Assuming a developer is looking for a bug in clang (or lld, or lldb, ...). + +Currently +^^^^^^^^^ + +SVN does not have builtin bisection support, but the single revision across +sub-projects makes it possible to script around. + +Using the existing Git read-only view of the repositories, it is possible to use +the native Git bisection script over the llvm repository, and use some scripting +to synchronize the clang repository to match the llvm revision. + +.. _workflow-multi-bisecting: + +Multirepo Variant +^^^^^^^^^^^^^^^^^ + +With the multi-repositories variant, the cross-repository synchronization is +achieved using the umbrella repository. This repository contains only +submodules for the other sub-projects. The native Git bisection can be used on +the umbrella repository directly. A subtlety is that the bisect script itself +needs to make sure the submodules are updated accordingly. + +For example, to find which commit introduces a regression where clang-3.9 +crashes but not clang-3.8 passes, one should be able to simply do:: + + git bisect start release_39 release_38 + git bisect run ./bisect_script.sh + +With the `bisect_script.sh` script being:: + + #!/bin/sh + cd $UMBRELLA_DIRECTORY + git submodule update llvm clang libcxx #.... + cd $BUILD_DIR + + ninja clang || exit 125 # an exit code of 125 asks "git bisect" + # to "skip" the current commit + + ./bin/clang some_crash_test.cpp + +When the `git bisect run` command returns, the umbrella repository is set to +the state where the regression is introduced. The commit diff in the umbrella +indicate which submodule was updated, and the last commit in this sub-projects +is the one that the bisect found. + +.. _workflow-mono-bisecting: + +Monorepo Variant +^^^^^^^^^^^^^^^^ + +Bisecting on the monorepo is straightforward, and very similar to the above, +except that the bisection script does not need to include the +`git submodule update` step. + +The same example, finding which commit introduces a regression where clang-3.9 +crashes but not clang-3.8 passes, will look like:: + + git bisect start release_39 release_38 + git bisect run ./bisect_script.sh + +With the `bisect_script.sh` script being:: + + #!/bin/sh + cd $BUILD_DIR + + ninja clang || exit 125 # an exit code of 125 asks "git bisect" + # to "skip" the current commit + + ./bin/clang some_crash_test.cpp + +Also, since the monorepo handles commits update across multiple projects, you're +less like to encounter a build failure where a commit change an API in LLVM and +another later one "fixes" the build in clang. + + +References +========== + +.. [LattnerRevNum] Chris Lattner, http://lists.llvm.org/pipermail/llvm-dev/2011-July/041739.html +.. [TrickRevNum] Andrew Trick, http://lists.llvm.org/pipermail/llvm-dev/2011-July/041721.html +.. [JSonnRevNum] Joerg Sonnenberg, http://lists.llvm.org/pipermail/llvm-dev/2011-July/041688.html +.. [TorvaldRevNum] Linus Torvald, http://git.661346.n2.nabble.com/Git-commit-generation-numbers-td6584414.html +.. [MatthewsRevNum] Chris Matthews, http://lists.llvm.org/pipermail/cfe-dev/2016-July/049886.html +.. [submodules] Git submodules, https://git-scm.com/book/en/v2/Git-Tools-Submodules) +.. [statuschecks] GitHub status-checks, https://help.github.com/articles/about-required-status-checks/ +.. [LebarCHERI] Port *CHERI* to a single repository rewriting history, http://lists.llvm.org/pipermail/llvm-dev/2016-July/102787.html +.. [AminiCHERI] Port *CHERI* to a single repository preserving history, http://lists.llvm.org/pipermail/llvm-dev/2016-July/102804.html diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst index 757434a02ce49..81db882891532 100644 --- a/docs/ReleaseNotes.rst +++ b/docs/ReleaseNotes.rst @@ -1,15 +1,21 @@ -====================== -LLVM 3.9 Release Notes -====================== +======================== +LLVM 4.0.0 Release Notes +======================== .. contents:: :local: +.. warning:: + These are in-progress notes for the upcoming LLVM 4.0.0 release. You may + prefer the `LLVM 3.9 Release Notes <http://llvm.org/releases/3.9.0/docs + /ReleaseNotes.html>`_. + + Introduction ============ This document contains the release notes for the LLVM Compiler Infrastructure, -release 3.9. Here we describe the status of LLVM, including major improvements +release 4.0.0. Here we describe the status of LLVM, including major improvements from the previous release, improvements in various subprojects of LLVM, and some of the current users of the code. All LLVM releases may be downloaded from the `LLVM releases web site <http://llvm.org/releases/>`_. @@ -20,249 +26,97 @@ have questions or comments, the `LLVM Developer's Mailing List <http://lists.llvm.org/mailman/listinfo/llvm-dev>`_ is a good place to send them. +Note that if you are reading this file from a Subversion checkout or the main +LLVM web page, this document applies to the *next* release, not the current +one. To see the release notes for a specific release, please see the `releases +page <http://llvm.org/releases/>`_. + Non-comprehensive list of changes in this release ================================================= -* The LLVMContext gains a new runtime check (see - LLVMContext::discardValueNames()) that can be set to discard Value names - (other than GlobalValue). This is intended to be used in release builds by - clients that are interested in saving CPU/memory as much as possible. - -* There is no longer a "global context" available in LLVM, except for the C API. - -* The autoconf build system has been removed in favor of CMake. LLVM 3.9 - requires CMake 3.4.3 or later to build. For information about using CMake - please see the documentation on :doc:`CMake`. For information about the CMake - language there is also a :doc:`CMakePrimer` document available. - -* C API functions LLVMParseBitcode, - LLVMParseBitcodeInContext, LLVMGetBitcodeModuleInContext and - LLVMGetBitcodeModule having been removed. LLVMGetTargetMachineData has been - removed (use LLVMGetDataLayout instead). +* The C API functions LLVMAddFunctionAttr, LLVMGetFunctionAttr, + LLVMRemoveFunctionAttr, LLVMAddAttribute, LLVMRemoveAttribute, + LLVMGetAttribute, LLVMAddInstrAttribute and + LLVMRemoveInstrAttribute have been removed. -* The C API function LLVMLinkModules has been removed. +* The C API enum LLVMAttribute has been deleted. -* The C API function LLVMAddTargetData has been removed. +.. NOTE + For small 1-3 sentence descriptions, just add an entry at the end of + this list. If your description won't fit comfortably in one bullet + point (e.g. maybe you would like to give an example of the + functionality, or simply have a lot to talk about), see the `NOTE` below + for adding a new subsection. -* The C API function LLVMGetDataLayout is deprecated - in favor of LLVMGetDataLayoutStr. +* The definition and uses of LLVM_ATRIBUTE_UNUSED_RESULT in the LLVM source + were replaced with LLVM_NODISCARD, which matches the C++17 [[nodiscard]] + semantics rather than gcc's __attribute__((warn_unused_result)). -* The C API enum LLVMAttribute and associated API is deprecated in favor of - the new LLVMAttributeRef API. The deprecated functions are - LLVMAddFunctionAttr, LLVMAddTargetDependentFunctionAttr, - LLVMRemoveFunctionAttr, LLVMGetFunctionAttr, LLVMAddAttribute, - LLVMRemoveAttribute, LLVMGetAttribute, LLVMAddInstrAttribute, - LLVMRemoveInstrAttribute and LLVMSetInstrParamAlignment. +* Minimum compiler version to build has been raised to GCC 4.8 and VS 2015. -* ``TargetFrameLowering::eliminateCallFramePseudoInstr`` now returns an - iterator to the next instruction instead of ``void``. Targets that previously - did ``MBB.erase(I); return;`` now probably want ``return MBB.erase(I);``. +* The Timer related APIs now expect a Name and Description. When upgrading code + the previously used names should become descriptions and a short name in the + style of a programming language identifier should be added. -* ``SelectionDAGISel::Select`` now returns ``void``. Out-of-tree targets will - need to be updated to replace the argument node and remove any dead nodes in - cases where they currently return an ``SDNode *`` from this interface. +* ... next change ... -* Added the MemorySSA analysis, which hopes to replace MemoryDependenceAnalysis. - It should provide higher-quality results than MemDep, and be algorithmically - faster than MemDep. Currently, GVNHoist (which is off by default) makes use of - MemorySSA. +.. NOTE + If you would like to document a larger change, then you can add a + subsection about it right here. You can copy the following boilerplate + and un-indent it (the indentation causes it to be inside this comment). -* The minimum density for lowering switches with jump tables has been reduced - from 40% to 10% for functions which are not marked ``optsize`` (that is, - compiled with ``-Os``). + Special New Feature + ------------------- -GCC ABI Tag ------------ - -Recently, many of the Linux distributions (e.g. `Fedora <http://developerblog.redhat.com/2015/02/10/gcc-5-in-fedora/>`_, -`Debian <https://wiki.debian.org/GCC5>`_, `Ubuntu <https://wiki.ubuntu.com/GCC5>`_) -have moved on to use the new `GCC ABI <https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html>`_ -to work around `C++11 incompatibilities in libstdc++ <https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html>`_. -This caused `incompatibility problems <https://gcc.gnu.org/ml/gcc-patches/2015-04/msg00153.html>`_ -with other compilers (e.g. Clang), which needed to be fixed, but due to the -experimental nature of GCC's own implementation, it took a long time for it to -land in LLVM (`D18035 <https://reviews.llvm.org/D18035>`_ and -`D17567 <https://reviews.llvm.org/D17567>`_), not in time for the 3.8 release. - -Those patches are now present in the 3.9.0 release and should be working in the -majority of cases, as they have been tested thoroughly. However, some bugs were -`filed in GCC <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71712>`_ and have not -yet been fixed, so there may be corner cases not covered by either GCC or Clang. -Bug fixes to those problems should be reported in Bugzilla (either LLVM or GCC), -and patches to LLVM's trunk are very likely to be back-ported to future 3.9.x -releases (depends on how destructive it is). - -Unfortunately, these patches won't be back-ported to 3.8.x or earlier, so we -strongly recommend people to use 3.9.x when GCC ABI cases are at stake. - -For a more in-depth view of the issue, check our `Bugzilla entry <https://llvm.org/bugs/show_bug.cgi?id=23529>`_. + Makes programs 10x faster by doing Special New Thing. Changes to the LLVM IR ---------------------- -* New intrinsics ``llvm.masked.load``, ``llvm.masked.store``, - ``llvm.masked.gather`` and ``llvm.masked.scatter`` were introduced to the - LLVM IR to allow selective memory access for vector data types. - -* The new ``notail`` attribute prevents optimization passes from adding ``tail`` - or ``musttail`` markers to a call. It is used to prevent tail call - optimization from being performed on the call. - -Changes to LLVM's IPO model ---------------------------- - -LLVM no longer does inter-procedural analysis and optimization (except -inlining) on functions with comdat linkage. Doing IPO over such -functions is unsound because the implementation the linker chooses at -link-time may be differently optimized than the one what was visible -during optimization, and may have arbitrarily different observable -behavior. See `PR26774 <http://llvm.org/PR26774>`_ for more details. - -Support for ThinLTO -------------------- - -LLVM now supports ThinLTO compilation, which can be invoked by compiling -and linking with ``-flto=thin``. The gold linker plugin, as well as linkers -that use the new ThinLTO API in libLTO (like ld64), will transparently -execute the ThinLTO backends in parallel threads. -For more information on ThinLTO and the LLVM implementation, see the -`ThinLTO blog post <http://blog.llvm.org/2016/06/thinlto-scalable-and-incremental-lto.html>`_. - -Changes to the ARM Targets +Changes to the ARM Backend -------------------------- -**During this release the AArch64 backend has:** - -* Gained support for Qualcomm's Kryo and Broadcom's Vulcan CPUs, including - scheduling models. -* Landed a scheduling model for Samsung's Exynos M1. -* Seen a lot of work on GlobalISel. -* Learned a few more useful combines (fadd and fmul into fmadd, adjustments to the - stack pointer for callee-save stack memory and local stack memory etc). -* Gained support for the Swift calling convention. -* Switched to using SubtargetFeatures rather than testing for specific CPUs and - to using TableGen for handling system instruction operands. -* Like ARM, AArch64 is now using the TargetParser, so no more StringSwitches - matching CPU, FPU or feature names will be accepted in normal code. -* Clang can now self-host itself using LLD on AArch64. -* Gained a big batch of tests from Halide. - - Furthermore, LLDB now supports AArch64 compact unwind tables, as used on iOS, - tvos and watchos. - -**During this release the ARM target has:** - -* ARMv8.2-A can now be targeted directly via Clang flags. -* Adding preliminary support for Cortex-R8. -* LLDB can now parse EABI attributes for an ELF input. -* Initial ARM/Thumb support was added to LLD. -* The ExecutionEngine now supports COFF/ARM. -* Swift calling convention was ported to ARM. -* A large number of codegen fixes around ARMv8, DSP, correct sub-target support, - relocations, EABI, EHABI, Windows on ARM, atomics.. -* Improved assembler support for Linux/Android/Chromium sub-projects. -* Initial support for MUSL (libc) on ARM. -* Support for Thumb1 targets in libunwind. -* Gained a big batch of tests from Halide. + During this release ... Changes to the MIPS Target -------------------------- -**During this release the MIPS target has:** - -* Enabled the Integrated Assembler by default for all ``mips-*`` and - ``mipsel-*`` triples. -* Significantly improved the Integrated Assembler support for the n64 ABI. -* Added the Clang frontend ``-mcompact-branches={never,optimal,always}`` option - that controls how LLVM generates compact branches for MIPS targets. -* Improved performance and code size for stack pointer adjustments in functions - with large frames. -* Implemented many instructions from the microMIPS32R6 ISA and added CodeGen - support for most of them. -* Added support for the triple used by Debian Stretch for little endian - MIPS64, ie. ``mips64el-linux-gnuabi64``. -* Removed EABI which was neither tested nor properly supported. -* Gained the ability to self-host on MIPS32R6. -* Gained the ability to self-host on MIPS64R2 and MIPS64R6 when using the n64 - ABI. -* Added support for the ``LA`` macro in PIC mode for o32. -* Added support for safestack in compiler-rt. -* Added support for the MIPS n64 ABI in LLD. -* Added LLD support for TLS relocations for both o32 and n64 MIPS ABIs. - -**The MIPS target has also fixed various bugs including the following notable -fixes:** - -* Delay slots are no longer filled multiple times when either ``-save-temps`` - or ``-via-file-asm`` are used. -* Updated n32 and n64 to follow the standard ELF conventions for label prefixes - (``.L``), whereas o32 still uses its own (``$``). -* Properly sign-extend values to GPR width for instructions that expect 32-bit - values on 64-bit ISAs. -* Several fixes for the delay-slot filler pass, including correct - forbidden-slot hazard handling. -* Fixed several errors caught by the machine verifier when turned on for MIPS. -* Fixed broken predicate for ``SELECT`` patterns in MIPS64. -* Fixed wrong truncation of memory address for ``LL``/``SC`` seqeuences in - MIPS64. -* Fixed the o32, n32 and n64 handling of ``.cprestore`` directives when inside - a ``.set noat`` region by the Integrated Assembler. -* Fixed the ordering of ``HI``/``LO`` pairs in the relocation table. -* Fixed the generated ELF ``EFlags`` when Octeon is the target. + During this release ... Changes to the PowerPC Target ----------------------------- -* Moved some optimizations from O3 to O2 (D18562) - -* Enable sibling call optimization on ppc64 ELFv1/ELFv2 abi + During this release ... Changes to the X86 Target ------------------------- -* LLVM now supports the Intel CPU codenamed Skylake Server with AVX-512 - extensions using ``-march=skylake-avx512``. The switch enables the - ISA extensions AVX-512{F, CD, VL, BW, DQ}. - -* LLVM now supports the Intel CPU codenamed Knights Landing with AVX-512 - extensions using ``-march=knl``. The switch enables the ISA extensions - AVX-512{F, CD, ER, PF}. - -* LLVM will now prefer ``PUSH`` instructions rather than ``%esp``-relative - ``MOV`` instructions for function calls at all optimization levels greater - than ``-O0``. Previously this transformation only occurred at ``-Os``. + During this release ... Changes to the AMDGPU Target ----------------------------- - * Added backend support for OpenGL shader image, buffer storage, atomic - counter, and compute shader extensions (supported since Mesa 12) + During this release ... - * Mesa 11.0.x is no longer supported +Changes to the AVR Target +----------------------------- +* The entire backend has been merged in-tree with all tests passing. All of + the instruction selection code and the machine code backend has landed + recently and is fully usable. -External Open Source Projects Using LLVM 3.9 -============================================ +Changes to the OCaml bindings +----------------------------- -An exciting aspect of LLVM is that it is used as an enabling technology for -a lot of other language and tools projects. This section lists some of the -projects that have already been updated to work with LLVM 3.9. +* The attribute API was completely overhauled, following the changes + to the C API. -LDC - the LLVM-based D compiler -------------------------------- -`D <http://dlang.org>`_ is a language with C-like syntax and static typing. It -pragmatically combines efficiency, control, and modeling power, with safety and -programmer productivity. D supports powerful concepts like Compile-Time Function -Execution (CTFE) and Template Meta-Programming, provides an innovative approach -to concurrency and offers many classical paradigms. +External Open Source Projects Using LLVM 4.0.0 +============================================== -`LDC <http://wiki.dlang.org/LDC>`_ uses the frontend from the reference compiler -combined with LLVM as backend to produce efficient native code. LDC targets -x86/x86_64 systems like Linux, OS X, FreeBSD and Windows and also Linux on ARM -and PowerPC (32/64 bit). Ports to other architectures like AArch64 and MIPS64 -are underway. +* A project... Additional Information @@ -277,4 +131,3 @@ going into the ``llvm/docs/`` directory in the LLVM tree. If you have any questions or comments about LLVM, please feel free to contact us via the `mailing lists <http://llvm.org/docs/#maillist>`_. - diff --git a/docs/ScudoHardenedAllocator.rst b/docs/ScudoHardenedAllocator.rst index 5bc390eadd5c4..a22051cca0630 100644 --- a/docs/ScudoHardenedAllocator.rst +++ b/docs/ScudoHardenedAllocator.rst @@ -8,6 +8,7 @@ Scudo Hardened Allocator Introduction ============ + The Scudo Hardened Allocator is a user-mode allocator based on LLVM Sanitizer's CombinedAllocator, which aims at providing additional mitigations against heap based vulnerabilities, while maintaining good performance. @@ -17,6 +18,7 @@ meaning Shield in Spanish and Portuguese). Design ====== + Chunk Header ------------ Every chunk of heap memory will be preceded by a chunk header. This has two @@ -77,41 +79,89 @@ Usage Library ------- The allocator static library can be built from the LLVM build tree thanks to -the "scudo" CMake rule. The associated tests can be exercised thanks to the -"check-scudo" CMake rule. +the ``scudo`` CMake rule. The associated tests can be exercised thanks to the +``check-scudo`` CMake rule. Linking the static library to your project can require the use of the -"whole-archive" linker flag (or equivalent), depending on your linker. +``whole-archive`` linker flag (or equivalent), depending on your linker. Additional flags might also be necessary. Your linked binary should now make use of the Scudo allocation and deallocation functions. +You may also build Scudo like this: + +.. code:: + + cd $LLVM/projects/compiler-rt/lib + clang++ -fPIC -std=c++11 -msse4.2 -mcx16 -O2 -I. scudo/*.cpp \ + $(\ls sanitizer_common/*.{cc,S} | grep -v "sanitizer_termination\|sanitizer_common_nolibc") \ + -shared -o scudo-allocator.so -lpthread + +and then use it with existing binaries as follows: + +.. code:: + + LD_PRELOAD=`pwd`/scudo-allocator.so ./a.out + Options ------- -Several aspects of the allocator can be configured through environment options, -following the usual ASan options syntax, through the variable SCUDO_OPTIONS. +Several aspects of the allocator can be configured through the following ways: -For example: SCUDO_OPTIONS="DeleteSizeMismatch=1:QuarantineSizeMb=16". +- by defining a ``__scudo_default_options`` function in one's program that + returns the options string to be parsed. Said function must have the following + prototype: ``extern "C" const char* __scudo_default_options()``. -The following options are available: +- through the environment variable SCUDO_OPTIONS, containing the options string + to be parsed. Options defined this way will override any definition made + through ``__scudo_default_options``; + +The options string follows a syntax similar to ASan, where distinct options +can be assigned in the same string, separated by colons. + +For example, using the environment variable: + +.. code:: -- QuarantineSizeMb (integer, defaults to 64): the size (in Mb) of quarantine - used to delay the actual deallocation of chunks. Lower value may reduce - memory usage but decrease the effectiveness of the mitigation; a negative - value will fallback to a default of 64Mb; + SCUDO_OPTIONS="DeleteSizeMismatch=1:QuarantineSizeMb=16" ./a.out -- ThreadLocalQuarantineSizeKb (integer, default to 1024): the size (in Kb) of - per-thread cache used to offload the global quarantine. Lower value may - reduce memory usage but might increase the contention on the global - quarantine. +Or using the function: -- DeallocationTypeMismatch (boolean, defaults to true): whether or not we report - errors on malloc/delete, new/free, new/delete[], etc; +.. code:: + + extern "C" const char *__scudo_default_options() { + return "DeleteSizeMismatch=1:QuarantineSizeMb=16"; + } + + +The following options are available: -- DeleteSizeMismatch (boolean, defaults to true): whether or not we report - errors on mismatch between size of new and delete; ++-----------------------------+---------+------------------------------------------------+ +| Option | Default | Description | ++-----------------------------+---------+------------------------------------------------+ +| QuarantineSizeMb | 64 | The size (in Mb) of quarantine used to delay | +| | | the actual deallocation of chunks. Lower value | +| | | may reduce memory usage but decrease the | +| | | effectiveness of the mitigation; a negative | +| | | value will fallback to a default of 64Mb. | ++-----------------------------+---------+------------------------------------------------+ +| ThreadLocalQuarantineSizeKb | 1024 | The size (in Kb) of per-thread cache use to | +| | | offload the global quarantine. Lower value may | +| | | reduce memory usage but might increase | +| | | contention on the global quarantine. | ++-----------------------------+---------+------------------------------------------------+ +| DeallocationTypeMismatch | true | Whether or not we report errors on | +| | | malloc/delete, new/free, new/delete[], etc. | ++-----------------------------+---------+------------------------------------------------+ +| DeleteSizeMismatch | true | Whether or not we report errors on mismatch | +| | | between sizes of new and delete. | ++-----------------------------+---------+------------------------------------------------+ +| ZeroContents | false | Whether or not we zero chunk contents on | +| | | allocation and deallocation. | ++-----------------------------+---------+------------------------------------------------+ -- ZeroContents (boolean, defaults to false): whether or not we zero chunk - contents on allocation and deallocation. +Allocator related common Sanitizer options can also be passed through Scudo +options, such as ``allocator_may_return_null``. A detailed list including those +can be found here: +https://github.com/google/sanitizers/wiki/SanitizerCommonFlags. diff --git a/docs/SourceLevelDebugging.rst b/docs/SourceLevelDebugging.rst index 8c3142ed21917..41f8dbfab3dce 100644 --- a/docs/SourceLevelDebugging.rst +++ b/docs/SourceLevelDebugging.rst @@ -64,7 +64,7 @@ user a relationship between generated code and the original program source code. Currently, there are two backend consumers of debug info: DwarfDebug and -CodeViewDebug. DwarfDebug produces DWARF sutable for use with GDB, LLDB, and +CodeViewDebug. DwarfDebug produces DWARF suitable for use with GDB, LLDB, and other DWARF-based debuggers. :ref:`CodeViewDebug <codeview>` produces CodeView, the Microsoft debug info format, which is usable with Microsoft debuggers such as Visual Studio and WinDBG. LLVM's debug information format is mostly derived @@ -92,11 +92,10 @@ information provides the following guarantees: as setting program variables, or calling functions that have been deleted. -* As desired, LLVM optimizations can be upgraded to be aware of the LLVM - debugging information, allowing them to update the debugging information - as they perform aggressive optimizations. This means that, with effort, - the LLVM optimizers could optimize debug code just as well as non-debug - code. +* As desired, LLVM optimizations can be upgraded to be aware of debugging + information, allowing them to update the debugging information as they + perform aggressive optimizations. This means that, with effort, the LLVM + optimizers could optimize debug code just as well as non-debug code. * LLVM debug information does not prevent optimizations from happening (for example inlining, basic block reordering/merging/cleanup, @@ -113,10 +112,10 @@ the program as it executes from a debugger. Compiling a program with "``-O3 -g``" gives you full debug information that is always available and accurate for reading (e.g., you get accurate stack traces despite tail call elimination and inlining), but you might lose the ability to modify the program -and call functions where were optimized out of the program, or inlined away +and call functions which were optimized out of the program, or inlined away completely. -:ref:`LLVM test suite <test-suite-quickstart>` provides a framework to test +The :ref:`LLVM test suite <test-suite-quickstart>` provides a framework to test optimizer's handling of debugging information. It can be run like this: .. code-block:: bash @@ -386,7 +385,7 @@ Given an integer global variable declared as follows: .. code-block:: c - int MyGlobal = 100; + _Alignas(8) int MyGlobal = 100; a C/C++ front-end would generate the following descriptors: @@ -395,54 +394,59 @@ a C/C++ front-end would generate the following descriptors: ;; ;; Define the global itself. ;; - @MyGlobal = global i32 100, align 4 + @MyGlobal = global i32 100, align 8, !dbg !0 ;; ;; List of debug info of globals ;; - !llvm.dbg.cu = !{!0} + !llvm.dbg.cu = !{!1} ;; Some unrelated metadata. !llvm.module.flags = !{!6, !7} + !llvm.ident = !{!8} + + ;; Define the global variable itself + !0 = distinct !DIGlobalVariable(name: "MyGlobal", scope: !1, file: !2, line: 1, type: !5, isLocal: false, isDefinition: true, align: 64) ;; Define the compile unit. - !0 = !DICompileUnit(language: DW_LANG_C99, file: !1, - producer: - "clang version 3.7.0 (trunk 231150) (llvm/trunk 231154)", - isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, - enums: !2, retainedTypes: !2, subprograms: !2, globals: - !3, imports: !2) + !1 = distinct !DICompileUnit(language: DW_LANG_C99, file: !2, + producer: "clang version 4.0.0 (http://llvm.org/git/clang.git ae4deadbea242e8ea517eef662c30443f75bd086) (http://llvm.org/git/llvm.git 818b4c1539df3e51dc7e62c89ead4abfd348827d)", + isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, + enums: !3, globals: !4) ;; ;; Define the file ;; - !1 = !DIFile(filename: "/dev/stdin", + !2 = !DIFile(filename: "/dev/stdin", directory: "/Users/dexonsmith/data/llvm/debug-info") ;; An empty array. - !2 = !{} + !3 = !{} ;; The Array of Global Variables - !3 = !{!4} - - ;; - ;; Define the global variable itself. - ;; - !4 = !DIGlobalVariable(name: "MyGlobal", scope: !0, file: !1, line: 1, - type: !5, isLocal: false, isDefinition: true, - variable: i32* @MyGlobal) + !4 = !{!0} ;; ;; Define the type ;; - !5 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed) + !5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) ;; Dwarf version to output. - !6 = !{i32 2, !"Dwarf Version", i32 2} + !6 = !{i32 2, !"Dwarf Version", i32 4} ;; Debug info schema version. !7 = !{i32 2, !"Debug Info Version", i32 3} + ;; Compiler identification + !8 = !{!"clang version 4.0.0 (http://llvm.org/git/clang.git ae4deadbea242e8ea517eef662c30443f75bd086) (http://llvm.org/git/llvm.git 818b4c1539df3e51dc7e62c89ead4abfd348827d)"} + + +The align value in DIGlobalVariable description specifies variable alignment in +case it was forced by C11 _Alignas(), C++11 alignas() keywords or compiler +attribute __attribute__((aligned ())). In other case (when this field is missing) +alignment is considered default. This is used when producing DWARF output +for DW_AT_alignment value. + C/C++ function information -------------------------- @@ -824,13 +828,13 @@ for the current string value. The problem with this layout for debuggers is that we need to optimize for the negative lookup case where the symbol we're searching for is not present. So -if we were to lookup "``printf``" in the table above, we would make a 32 hash -for "``printf``", it might match ``bucket[3]``. We would need to go to the -offset 0x000034f0 and start looking to see if our 32 bit hash matches. To do -so, we need to read the next pointer, then read the hash, compare it, and skip -to the next bucket. Each time we are skipping many bytes in memory and -touching new cache pages just to do the compare on the full 32 bit hash. All -of these accesses then tell us that we didn't have a match. +if we were to lookup "``printf``" in the table above, we would make a 32-bit +hash for "``printf``", it might match ``bucket[3]``. We would need to go to +the offset 0x000034f0 and start looking to see if our 32 bit hash matches. To +do so, we need to read the next pointer, then read the hash, compare it, and +skip to the next bucket. Each time we are skipping many bytes in memory and +touching new pages just to do the compare on the full 32 bit hash. All of +these accesses then tell us that we didn't have a match. Name Hash Tables """""""""""""""" @@ -1259,6 +1263,7 @@ tag is one of: * DW_TAG_packed_type * DW_TAG_volatile_type * DW_TAG_restrict_type +* DW_TAG_atomic_type * DW_TAG_interface_type * DW_TAG_unspecified_type * DW_TAG_shared_type diff --git a/docs/StackMaps.rst b/docs/StackMaps.rst index 5bdae38b699df..a78fde16c2be9 100644 --- a/docs/StackMaps.rst +++ b/docs/StackMaps.rst @@ -319,7 +319,7 @@ format of this section follows: .. code-block:: none Header { - uint8 : Stack Map Version (current version is 1) + uint8 : Stack Map Version (current version is 2) uint8 : Reserved (expected to be 0) uint16 : Reserved (expected to be 0) } @@ -329,6 +329,7 @@ format of this section follows: StkSizeRecord[NumFunctions] { uint64 : Function Address uint64 : Stack Size + uint64 : Record Count } Constants[NumConstants] { uint64 : LargeConstant @@ -434,7 +435,7 @@ precisely determine the location of values at a specific position in the code. LLVM does not maintain any mapping between those values and any higher-level entity. The runtime must be able to interpret the stack map record given only the ID, offset, and the order of the -locations, which LLVM preserves. +locations, records, and functions, which LLVM preserves. Note that this is quite different from the goal of debug information, which is a best-effort attempt to track the location of named @@ -508,4 +509,3 @@ Support for StackMap generation and the related intrinsics requires some code for each backend. Today, only a subset of LLVM's backends are supported. The currently supported architectures are X86_64, PowerPC, and Aarch64. - diff --git a/docs/TableGen/BackEnds.rst b/docs/TableGen/BackEnds.rst index e8544b65216dc..fdab266fa31ce 100644 --- a/docs/TableGen/BackEnds.rst +++ b/docs/TableGen/BackEnds.rst @@ -66,7 +66,7 @@ The macros will be undef'd automatically as they're used, in the include file. On all LLVM back-ends, the ``llvm-tblgen`` binary will be executed on the root TableGen file ``<Target>.td``, which should include all others. This guarantees that all information needed is accessible, and that no duplication is needed -in the TbleGen files. +in the TableGen files. CodeEmitter ----------- @@ -100,11 +100,12 @@ InstrInfo **Purpose**: This tablegen backend is responsible for emitting a description of the target instruction set for the code generator. (what are the differences from CodeEmitter?) -**Output**: C++ code with enums and structures representing the register mappings, +**Output**: C++ code with enums and structures representing the instruction mappings, properties, masks, etc. **Usage**: Both on ``<Target>BaseInstrInfo`` and ``<Target>MCTargetDesc`` (headers and source files) with macros defining in which they are for declaration vs. +initialization issues. AsmWriter --------- @@ -146,7 +147,7 @@ PseudoLowering **Purpose**: Generate pseudo instruction lowering. -**Output**: Implements ``ARMAsmPrinter::emitPseudoExpansionLowering()``. +**Output**: Implements ``<Target>AsmPrinter::emitPseudoExpansionLowering()``. **Usage**: Included directly into ``<Target>AsmPrinter.cpp``. @@ -160,7 +161,7 @@ conventions supported by this target. chained by matching styles, returning false on no match. **Usage**: Used in ISelLowering and FastIsel as function pointers to -implementation returned by a CC sellection function. +implementation returned by a CC selection function. DAGISel ------- diff --git a/docs/TableGen/LangIntro.rst b/docs/TableGen/LangIntro.rst index c1391e73646ed..d8bd17d750b8e 100644 --- a/docs/TableGen/LangIntro.rst +++ b/docs/TableGen/LangIntro.rst @@ -98,9 +98,6 @@ supported include: Note that this is sized by the number of bits given and will not be silently extended/truncated. -``07654321`` - octal integer value (indicated by a leading 0) - ``7`` decimal integer value diff --git a/docs/TableGen/LangRef.rst b/docs/TableGen/LangRef.rst index 58da6285c077e..285572fa481c9 100644 --- a/docs/TableGen/LangRef.rst +++ b/docs/TableGen/LangRef.rst @@ -97,7 +97,9 @@ wide variety of meanings: BangOperator: one of :!eq !if !head !tail !con :!add !shl !sra !srl !and - :!cast !empty !subst !foreach !listconcat !strconcat + :!or !empty !subst !foreach !strconcat + :!cast !listconcat + Syntax ====== diff --git a/docs/WritingAnLLVMBackend.rst b/docs/WritingAnLLVMBackend.rst index f0f3ab5504db4..f06a95da21522 100644 --- a/docs/WritingAnLLVMBackend.rst +++ b/docs/WritingAnLLVMBackend.rst @@ -288,11 +288,11 @@ looks like this: .. code-block:: c++ - Target llvm::TheSparcTarget; + Target llvm::getTheSparcTarget(); extern "C" void LLVMInitializeSparcTargetInfo() { RegisterTarget<Triple::sparc, /*HasJIT=*/false> - X(TheSparcTarget, "sparc", "Sparc"); + X(getTheSparcTarget(), "sparc", "Sparc"); } This allows the ``TargetRegistry`` to look up the target by name or by target @@ -305,7 +305,7 @@ example. Here is an example of registering the Sparc assembly printer: .. code-block:: c++ extern "C" void LLVMInitializeSparcAsmPrinter() { - RegisterAsmPrinter<SparcAsmPrinter> X(TheSparcTarget); + RegisterAsmPrinter<SparcAsmPrinter> X(getTheSparcTarget()); } For more information, see "`llvm/Target/TargetRegistry.h diff --git a/docs/WritingAnLLVMPass.rst b/docs/WritingAnLLVMPass.rst index 537bbbc19d25a..54b3630e655ff 100644 --- a/docs/WritingAnLLVMPass.rst +++ b/docs/WritingAnLLVMPass.rst @@ -50,34 +50,34 @@ Setting up the build environment First, configure and build LLVM. Next, you need to create a new directory somewhere in the LLVM source base. For this example, we'll assume that you made ``lib/Transforms/Hello``. Finally, you must set up a build script -(``Makefile``) that will compile the source code for the new pass. To do this, -copy the following into ``Makefile``: +that will compile the source code for the new pass. To do this, +copy the following into ``CMakeLists.txt``: -.. code-block:: make +.. code-block:: cmake - # Makefile for hello pass + add_llvm_loadable_module( LLVMHello + Hello.cpp + + PLUGIN_TOOL + opt + ) - # Path to top level of LLVM hierarchy - LEVEL = ../../.. +and the following line into ``lib/Transforms/CMakeLists.txt``: - # Name of the library to build - LIBRARYNAME = Hello +.. code-block:: cmake - # Make the shared library become a loadable module so the tools can - # dlopen/dlsym on the resulting library. - LOADABLE_MODULE = 1 + add_subdirectory(Hello) - # Include the makefile implementation stuff - include $(LEVEL)/Makefile.common +(Note that there is already a directory named ``Hello`` with a sample "Hello" +pass; you may play with it -- in which case you don't need to modify any +``CMakeLists.txt`` files -- or, if you want to create everything from scratch, +use another name.) -This makefile specifies that all of the ``.cpp`` files in the current directory -are to be compiled and linked together into a shared object -``$(LEVEL)/Debug+Asserts/lib/Hello.so`` that can be dynamically loaded by the -:program:`opt` or :program:`bugpoint` tools via their :option:`-load` options. -If your operating system uses a suffix other than ``.so`` (such as Windows or Mac -OS X), the appropriate extension will be used. - -If you are used CMake to build LLVM, see :ref:`cmake-out-of-source-pass`. +This build script specifies that ``Hello.cpp`` file in the current directory +is to be compiled and linked into a shared object ``$(LEVEL)/lib/LLVMHello.so`` that +can be dynamically loaded by the :program:`opt` tool via its :option:`-load` +option. If your operating system uses a suffix other than ``.so`` (such as +Windows or Mac OS X), the appropriate extension will be used. Now that we have the build scripts set up, we just need to write the code for the pass itself. @@ -143,12 +143,12 @@ to avoid using expensive C++ runtime information. .. code-block:: c++ - bool runOnFunction(Function &F) override { - errs() << "Hello: "; - errs().write_escaped(F.getName()) << "\n"; - return false; - } - }; // end of struct Hello + bool runOnFunction(Function &F) override { + errs() << "Hello: "; + errs().write_escaped(F.getName()) << '\n'; + return false; + } + }; // end of struct Hello } // end of anonymous namespace We declare a :ref:`runOnFunction <writing-an-llvm-pass-runOnFunction>` method, @@ -180,31 +180,33 @@ As a whole, the ``.cpp`` file looks like: .. code-block:: c++ - #include "llvm/Pass.h" - #include "llvm/IR/Function.h" - #include "llvm/Support/raw_ostream.h" - - using namespace llvm; - - namespace { - struct Hello : public FunctionPass { - static char ID; - Hello() : FunctionPass(ID) {} - - bool runOnFunction(Function &F) override { - errs() << "Hello: "; - errs().write_escaped(F.getName()) << '\n'; - return false; - } - }; + #include "llvm/Pass.h" + #include "llvm/IR/Function.h" + #include "llvm/Support/raw_ostream.h" + + using namespace llvm; + + namespace { + struct Hello : public FunctionPass { + static char ID; + Hello() : FunctionPass(ID) {} + + bool runOnFunction(Function &F) override { + errs() << "Hello: "; + errs().write_escaped(F.getName()) << '\n'; + return false; } - - char Hello::ID = 0; - static RegisterPass<Hello> X("hello", "Hello World Pass", false, false); + }; // end of struct Hello + } // end of anonymous namespace + + char Hello::ID = 0; + static RegisterPass<Hello> X("hello", "Hello World Pass", + false /* Only looks at CFG */, + false /* Analysis Pass */); Now that it's all together, compile the file with a simple "``gmake``" command from the top level of your build directory and you should get a new file -"``Debug+Asserts/lib/Hello.so``". Note that everything in this file is +"``lib/LLVMHello.so``". Note that everything in this file is contained in an anonymous namespace --- this reflects the fact that passes are self contained units that do not need external interfaces (although they can have them) to be useful. @@ -224,7 +226,7 @@ will work): .. code-block:: console - $ opt -load ../../Debug+Asserts/lib/Hello.so -hello < hello.bc > /dev/null + $ opt -load lib/LLVMHello.so -hello < hello.bc > /dev/null Hello: __main Hello: puts Hello: main @@ -241,20 +243,20 @@ To see what happened to the other string you registered, try running .. code-block:: console - $ opt -load ../../Debug+Asserts/lib/Hello.so -help - OVERVIEW: llvm .bc -> .bc modular optimizer + $ opt -load lib/LLVMHello.so -help + OVERVIEW: llvm .bc -> .bc modular optimizer and analysis printer - USAGE: opt [options] <input bitcode> + USAGE: opt [subcommand] [options] <input bitcode file> OPTIONS: Optimizations available: ... - -globalopt - Global Variable Optimizer - -globalsmodref-aa - Simple mod/ref analysis for globals + -guard-widening - Widen guards -gvn - Global Value Numbering + -gvn-hoist - Early GVN Hoisting of Expressions -hello - Hello World Pass -indvars - Induction Variable Simplification - -inline - Function Integration/Inlining + -inferattrs - Infer set function attributes ... The pass name gets added as the information string for your pass, giving some @@ -268,21 +270,20 @@ you queue up. For example: .. code-block:: console - $ opt -load ../../Debug+Asserts/lib/Hello.so -hello -time-passes < hello.bc > /dev/null + $ opt -load lib/LLVMHello.so -hello -time-passes < hello.bc > /dev/null Hello: __main Hello: puts Hello: main - =============================================================================== + ===-------------------------------------------------------------------------=== ... Pass execution timing report ... - =============================================================================== - Total Execution Time: 0.02 seconds (0.0479059 wall clock) - - ---User Time--- --System Time-- --User+System-- ---Wall Time--- --- Pass Name --- - 0.0100 (100.0%) 0.0000 ( 0.0%) 0.0100 ( 50.0%) 0.0402 ( 84.0%) Bitcode Writer - 0.0000 ( 0.0%) 0.0100 (100.0%) 0.0100 ( 50.0%) 0.0031 ( 6.4%) Dominator Set Construction - 0.0000 ( 0.0%) 0.0000 ( 0.0%) 0.0000 ( 0.0%) 0.0013 ( 2.7%) Module Verifier - 0.0000 ( 0.0%) 0.0000 ( 0.0%) 0.0000 ( 0.0%) 0.0033 ( 6.9%) Hello World Pass - 0.0100 (100.0%) 0.0100 (100.0%) 0.0200 (100.0%) 0.0479 (100.0%) TOTAL + ===-------------------------------------------------------------------------=== + Total Execution Time: 0.0007 seconds (0.0005 wall clock) + + ---User Time--- --User+System-- ---Wall Time--- --- Name --- + 0.0004 ( 55.3%) 0.0004 ( 55.3%) 0.0004 ( 75.7%) Bitcode Writer + 0.0003 ( 44.7%) 0.0003 ( 44.7%) 0.0001 ( 13.6%) Hello World Pass + 0.0000 ( 0.0%) 0.0000 ( 0.0%) 0.0001 ( 10.7%) Module Verifier + 0.0007 (100.0%) 0.0007 (100.0%) 0.0005 (100.0%) Total As you can see, our implementation above is pretty fast. The additional passes listed are automatically inserted by the :program:`opt` tool to verify @@ -964,14 +965,14 @@ just does a few simple checks that don't require significant analysis to compute (such as: two different globals can never alias each other, etc). Passes that use the `AliasAnalysis <http://llvm.org/doxygen/classllvm_1_1AliasAnalysis.html>`_ interface (for -example the `gcse <http://llvm.org/doxygen/structGCSE.html>`_ pass), do not +example the `gvn <http://llvm.org/doxygen/classllvm_1_1GVN.html>`_ pass), do not care which implementation of alias analysis is actually provided, they just use the designated interface. From the user's perspective, commands work just like normal. Issuing the -command ``opt -gcse ...`` will cause the ``basicaa`` class to be instantiated -and added to the pass sequence. Issuing the command ``opt -somefancyaa -gcse -...`` will cause the ``gcse`` pass to use the ``somefancyaa`` alias analysis +command ``opt -gvn ...`` will cause the ``basicaa`` class to be instantiated +and added to the pass sequence. Issuing the command ``opt -somefancyaa -gvn +...`` will cause the ``gvn`` pass to use the ``somefancyaa`` alias analysis (which doesn't actually exist, it's just a hypothetical example) instead. .. _writing-an-llvm-pass-RegisterAnalysisGroup: @@ -1092,74 +1093,69 @@ information about all of the variants of the ``--debug-pass`` option, just type By using the --debug-pass=Structure option, for example, we can see how our :ref:`Hello World <writing-an-llvm-pass-basiccode>` pass interacts with other -passes. Lets try it out with the gcse and licm passes: +passes. Lets try it out with the gvn and licm passes: .. code-block:: console - $ opt -load ../../Debug+Asserts/lib/Hello.so -gcse -licm --debug-pass=Structure < hello.bc > /dev/null - Module Pass Manager - Function Pass Manager - Dominator Set Construction - Immediate Dominators Construction - Global Common Subexpression Elimination - -- Immediate Dominators Construction - -- Global Common Subexpression Elimination - Natural Loop Construction - Loop Invariant Code Motion - -- Natural Loop Construction - -- Loop Invariant Code Motion + $ opt -load lib/LLVMHello.so -gvn -licm --debug-pass=Structure < hello.bc > /dev/null + ModulePass Manager + FunctionPass Manager + Dominator Tree Construction + Basic Alias Analysis (stateless AA impl) + Function Alias Analysis Results + Memory Dependence Analysis + Global Value Numbering + Natural Loop Information + Canonicalize natural loops + Loop-Closed SSA Form Pass + Basic Alias Analysis (stateless AA impl) + Function Alias Analysis Results + Scalar Evolution Analysis + Loop Pass Manager + Loop Invariant Code Motion Module Verifier - -- Dominator Set Construction - -- Module Verifier Bitcode Writer - --Bitcode Writer -This output shows us when passes are constructed and when the analysis results -are known to be dead (prefixed with "``--``"). Here we see that GCSE uses -dominator and immediate dominator information to do its job. The LICM pass -uses natural loop information, which uses dominator sets, but not immediate -dominators. Because immediate dominators are no longer useful after the GCSE -pass, it is immediately destroyed. The dominator sets are then reused to -compute natural loop information, which is then used by the LICM pass. +This output shows us when passes are constructed. +Here we see that GVN uses dominator tree information to do its job. The LICM pass +uses natural loop information, which uses dominator tree as well. After the LICM pass, the module verifier runs (which is automatically added by -the :program:`opt` tool), which uses the dominator set to check that the -resultant LLVM code is well formed. After it finishes, the dominator set -information is destroyed, after being computed once, and shared by three -passes. +the :program:`opt` tool), which uses the dominator tree to check that the +resultant LLVM code is well formed. Note that the dominator tree is computed +once, and shared by three passes. Lets see how this changes when we run the :ref:`Hello World <writing-an-llvm-pass-basiccode>` pass in between the two passes: .. code-block:: console - $ opt -load ../../Debug+Asserts/lib/Hello.so -gcse -hello -licm --debug-pass=Structure < hello.bc > /dev/null - Module Pass Manager - Function Pass Manager - Dominator Set Construction - Immediate Dominators Construction - Global Common Subexpression Elimination - -- Dominator Set Construction - -- Immediate Dominators Construction - -- Global Common Subexpression Elimination + $ opt -load lib/LLVMHello.so -gvn -hello -licm --debug-pass=Structure < hello.bc > /dev/null + ModulePass Manager + FunctionPass Manager + Dominator Tree Construction + Basic Alias Analysis (stateless AA impl) + Function Alias Analysis Results + Memory Dependence Analysis + Global Value Numbering Hello World Pass - -- Hello World Pass - Dominator Set Construction - Natural Loop Construction - Loop Invariant Code Motion - -- Natural Loop Construction - -- Loop Invariant Code Motion + Dominator Tree Construction + Natural Loop Information + Canonicalize natural loops + Loop-Closed SSA Form Pass + Basic Alias Analysis (stateless AA impl) + Function Alias Analysis Results + Scalar Evolution Analysis + Loop Pass Manager + Loop Invariant Code Motion Module Verifier - -- Dominator Set Construction - -- Module Verifier Bitcode Writer - --Bitcode Writer Hello: __main Hello: puts Hello: main Here we see that the :ref:`Hello World <writing-an-llvm-pass-basiccode>` pass -has killed the Dominator Set pass, even though it doesn't modify the code at +has killed the Dominator Tree pass, even though it doesn't modify the code at all! To fix this, we need to add the following :ref:`getAnalysisUsage <writing-an-llvm-pass-getAnalysisUsage>` method to our pass: @@ -1174,26 +1170,26 @@ Now when we run our pass, we get this output: .. code-block:: console - $ opt -load ../../Debug+Asserts/lib/Hello.so -gcse -hello -licm --debug-pass=Structure < hello.bc > /dev/null - Pass Arguments: -gcse -hello -licm - Module Pass Manager - Function Pass Manager - Dominator Set Construction - Immediate Dominators Construction - Global Common Subexpression Elimination - -- Immediate Dominators Construction - -- Global Common Subexpression Elimination + $ opt -load lib/LLVMHello.so -gvn -hello -licm --debug-pass=Structure < hello.bc > /dev/null + Pass Arguments: -gvn -hello -licm + ModulePass Manager + FunctionPass Manager + Dominator Tree Construction + Basic Alias Analysis (stateless AA impl) + Function Alias Analysis Results + Memory Dependence Analysis + Global Value Numbering Hello World Pass - -- Hello World Pass - Natural Loop Construction - Loop Invariant Code Motion - -- Loop Invariant Code Motion - -- Natural Loop Construction + Natural Loop Information + Canonicalize natural loops + Loop-Closed SSA Form Pass + Basic Alias Analysis (stateless AA impl) + Function Alias Analysis Results + Scalar Evolution Analysis + Loop Pass Manager + Loop Invariant Code Motion Module Verifier - -- Dominator Set Construction - -- Module Verifier Bitcode Writer - --Bitcode Writer Hello: __main Hello: puts Hello: main diff --git a/docs/XRay.rst b/docs/XRay.rst new file mode 100644 index 0000000000000..222cc8f2e049c --- /dev/null +++ b/docs/XRay.rst @@ -0,0 +1,232 @@ +==================== +XRay Instrumentation +==================== + +:Version: 1 as of 2016-11-08 + +.. contents:: + :local: + + +Introduction +============ + +XRay is a function call tracing system which combines compiler-inserted +instrumentation points and a runtime library that can dynamically enable and +disable the instrumentation. + +More high level information about XRay can be found in the `XRay whitepaper`_. + +This document describes how to use XRay as implemented in LLVM. + +XRay in LLVM +============ + +XRay consists of three main parts: + +- Compiler-inserted instrumentation points. +- A runtime library for enabling/disabling tracing at runtime. +- A suite of tools for analysing the traces. + + **NOTE:** As of the time of this writing, XRay is only available for x86_64 + and arm7 32-bit (no-thumb) Linux. + +The compiler-inserted instrumentation points come in the form of nop-sleds in +the final generated binary, and an ELF section named ``xray_instr_map`` which +contains entries pointing to these instrumentation points. The runtime library +relies on being able to access the entries of the ``xray_instr_map``, and +overwrite the instrumentation points at runtime. + +Using XRay +========== + +You can use XRay in a couple of ways: + +- Instrumenting your C/C++/Objective-C/Objective-C++ application. +- Generating LLVM IR with the correct function attributes. + +The rest of this section covers these main ways and later on how to customise +what XRay does in an XRay-instrumented binary. + +Instrumenting your C/C++/Objective-C Application +------------------------------------------------ + +The easiest way of getting XRay instrumentation for your application is by +enabling the ``-fxray-instrument`` flag in your clang invocation. + +For example: + +:: + + clang -fxray-instrument .. + +By default, functions that have at least 200 instructions will get XRay +instrumentation points. You can tweak that number through the +``-fxray-instruction-threshold=`` flag: + +:: + + clang -fxray-instrument -fxray-instruction-threshold=1 .. + +You can also specifically instrument functions in your binary to either always +or never be instrumented using source-level attributes. You can do it using the +GCC-style attributes or C++11-style attributes. + +.. code-block:: c++ + + [[clang::xray_always_intrument]] void always_instrumented(); + + [[clang::xray_never_instrument]] void never_instrumented(); + + void alt_always_instrumented() __attribute__((xray_always_intrument)); + + void alt_never_instrumented() __attribute__((xray_never_instrument)); + +When linking a binary, you can either manually link in the `XRay Runtime +Library`_ or use ``clang`` to link it in automatically with the +``-fxray-instrument`` flag. + +LLVM Function Attribute +----------------------- + +If you're using LLVM IR directly, you can add the ``function-instrument`` +string attribute to your functions, to get the similar effect that the +C/C++/Objective-C source-level attributes would get: + +.. code-block:: llvm + + define i32 @always_instrument() uwtable "function-instrument"="xray-always" { + ; ... + } + + define i32 @never_instrument() uwtable "function-instrument"="xray-never" { + ; ... + } + +You can also set the ``xray-instruction-threshold`` attribute and provide a +numeric string value for how many instructions should be in the function before +it gets instrumented. + +.. code-block:: llvm + + define i32 @maybe_instrument() uwtable "xray-instruction-threshold"="2" { + ; ... + } + +XRay Runtime Library +-------------------- + +The XRay Runtime Library is part of the compiler-rt project, which implements +the runtime components that perform the patching and unpatching of inserted +instrumentation points. When you use ``clang`` to link your binaries and the +``-fxray-instrument`` flag, it will automatically link in the XRay runtime. + +The default implementation of the XRay runtime will enable XRay instrumentation +before ``main`` starts, which works for applications that have a short +lifetime. This implementation also records all function entry and exit events +which may result in a lot of records in the resulting trace. + +Also by default the filename of the XRay trace is ``xray-log.XXXXXX`` where the +``XXXXXX`` part is randomly generated. + +These options can be controlled through the ``XRAY_OPTIONS`` environment +variable, where we list down the options and their defaults below. + ++-------------------+-----------------+---------------+------------------------+ +| Option | Type | Default | Description | ++===================+=================+===============+========================+ +| patch_premain | ``bool`` | ``true`` | Whether to patch | +| | | | instrumentation points | +| | | | before main. | ++-------------------+-----------------+---------------+------------------------+ +| xray_naive_log | ``bool`` | ``true`` | Whether to install | +| | | | the naive log | +| | | | implementation. | ++-------------------+-----------------+---------------+------------------------+ +| xray_logfile_base | ``const char*`` | ``xray-log.`` | Filename base for the | +| | | | XRay logfile. | ++-------------------+-----------------+---------------+------------------------+ + +If you choose to not use the default logging implementation that comes with the +XRay runtime and/or control when/how the XRay instrumentation runs, you may use +the XRay APIs directly for doing so. To do this, you'll need to include the +``xray_interface.h`` from the compiler-rt ``xray`` directory. The important API +functions we list below: + +- ``__xray_set_handler(void (*entry)(int32_t, XRayEntryType))``: Install your + own logging handler for when an event is encountered. See + ``xray/xray_interface.h`` for more details. +- ``__xray_remove_handler()``: Removes whatever the installed handler is. +- ``__xray_patch()``: Patch all the instrumentation points defined in the + binary. +- ``__xray_unpatch()``: Unpatch the instrumentation points defined in the + binary. + +There are some requirements on the logging handler to be installed for the +thread-safety of operations to be performed by the XRay runtime library: + +- The function should be thread-safe, as multiple threads may be invoking the + function at the same time. If the logging function needs to do + synchronisation, it must do so internally as XRay does not provide any + synchronisation guarantees outside from the atomicity of updates to the + pointer. +- The pointer provided to ``__xray_set_handler(...)`` must be live even after + calls to ``__xray_remove_handler()`` and ``__xray_unpatch()`` have succeeded. + XRay cannot guarantee that all threads that have ever gotten a copy of the + pointer will not invoke the function. + + +Trace Analysis Tools +-------------------- + +We currently have the beginnings of a trace analysis tool in LLVM, which can be +found in the ``tools/llvm-xray`` directory. The ``llvm-xray`` tool currently +supports the following subcommands: + +- ``extract``: Extract the instrumentation map from a binary, and return it as + YAML. + + +Future Work +=========== + +There are a number of ongoing efforts for expanding the toolset building around +the XRay instrumentation system. + +Flight Data Recorder Mode +------------------------- + +The `XRay whitepaper`_ mentions a mode for when events are kept in memory, and +have the traces be dumped on demand through a triggering API. This work is +currently ongoing. + +Trace Analysis +-------------- + +There are a few more subcommands making its way to the ``llvm-xray`` tool, that +are currently under review: + +- ``convert``: Turns an XRay trace from one format to another. Currently + supporting conversion from the binary XRay log to YAML. +- ``account``: Do function call accounting based on data in the XRay log. + +We have more subcommands and modes that we're thinking of developing, in the +following forms: + +- ``stack``: Reconstruct the function call stacks in a timeline. +- ``convert``: Converting from one version of the XRay log to another (higher) + version, and converting to other trace formats (i.e. Chrome Trace Viewer, + pprof, etc.). +- ``graph``: Generate a function call graph with relative timings and distributions. + +More Platforms +-------------- + +Since XRay is only currently available in x86_64 and arm7 32-bit (no-thumb) +running Linux, we're looking to supporting more platforms (architectures and +operating systems). + +.. References... + +.. _`XRay whitepaper`: http://research.google.com/pubs/pub45287.html + diff --git a/docs/_static/llvm.css b/docs/_static/llvm.css index d7b5dae5a93c0..53eeed95c6c0a 100644 --- a/docs/_static/llvm.css +++ b/docs/_static/llvm.css @@ -82,7 +82,7 @@ h2+div, h2+p {text-align: left; padding-left: 20pt; padding-right: 10pt;} h3+div, h3+p {text-align: left; padding-left: 20pt; padding-right: 10pt;} h4+div, h4+p {text-align: left; padding-left: 20pt; padding-right: 10pt;} -/* It is preferrable to use <pre class="doc_code"> everywhere instead of the +/* It is preferable to use <pre class="doc_code"> everywhere instead of the * <div class="doc_code"><pre>...</ptr></div> construct. * * Once all docs use <pre> for code regions, this style can be merged with the diff --git a/docs/conf.py b/docs/conf.py index 224cca142884d..428a513774e49 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -48,9 +48,9 @@ copyright = u'2003-%d, LLVM Project' % date.today().year # built documents. # # The short X.Y version. -version = '3.9' +version = '4.0' # The full version, including alpha/beta/rc tags. -release = '3.9' +release = '4.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -249,5 +249,5 @@ for name in os.listdir(command_guide_path): # If true, show URL addresses after external links. #man_show_urls = False -# FIXME: Define intersphinx configration. +# FIXME: Define intersphinx configuration. intersphinx_mapping = {} diff --git a/docs/doxygen.cfg.in b/docs/doxygen.cfg.in index 7699711adce90..7095dbd9aebfe 100644 --- a/docs/doxygen.cfg.in +++ b/docs/doxygen.cfg.in @@ -1937,7 +1937,7 @@ PREDEFINED = EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will -# remove all refrences to function-like macros that are alone on a line, have an +# remove all references to function-like macros that are alone on a line, have an # all uppercase name, and do not end with a semicolon. Such function macros are # typically used for boiler-plate code, and will confuse the parser if not # removed. diff --git a/docs/index.rst b/docs/index.rst index a68dd1b8c73e4..341a9c16325b9 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,6 +1,11 @@ Overview ======== +.. warning:: + + If you are using a released version of LLVM, see `the download page + <http://llvm.org/releases/>`_ to find your documentation. + The LLVM compiler infrastructure supports a wide range of projects, from industrial strength compilers to specialized JIT applications to small research projects. @@ -174,6 +179,7 @@ For developers of applications which use LLVM as a library. Extensions LibFuzzer ScudoHardenedAllocator + OptBisect :doc:`LLVM Language Reference Manual <LangRef>` Defines the LLVM intermediate representation and the assembly form of the @@ -221,6 +227,9 @@ For developers of applications which use LLVM as a library. :doc:`ScudoHardenedAllocator` A library that implements a security-hardened `malloc()`. +:doc:`OptBisect` + A command line option for debugging optimization-induced failures. + Subsystem Documentation ======================= @@ -230,6 +239,7 @@ For API clients and LLVM developers. :hidden: AliasAnalysis + MemorySSA BitCodeFormat BlockFrequencyTerminology BranchWeightMetadata @@ -261,6 +271,10 @@ For API clients and LLVM developers. TypeMetadata FaultMaps MIRLangRef + Coroutines + GlobalISel + XRay + PDB/index :doc:`WritingAnLLVMPass` Information on how to write LLVM transformations and analyses. @@ -285,6 +299,9 @@ For API clients and LLVM developers. Information on how to write a new alias analysis implementation or how to use existing analyses. +:doc:`MemorySSA` + Information about the MemorySSA utility in LLVM, as well as how to use it. + :doc:`GarbageCollection` The interfaces source-language compilers should use for compiling GC'd programs. @@ -373,6 +390,18 @@ For API clients and LLVM developers. :doc:`CompileCudaWithLLVM` LLVM support for CUDA. +:doc:`Coroutines` + LLVM support for coroutines. + +:doc:`GlobalISel` + This describes the prototype instruction selection replacement, GlobalISel. + +:doc:`XRay` + High-level documentation of how to use XRay in LLVM. + +:doc:`The Microsoft PDB File Format <PDB/index>` + A detailed description of the Microsoft PDB (Program Database) file format. + Development Process Documentation ================================= @@ -483,6 +512,25 @@ This channel has several bots. * clang-bot - A `geordi <http://www.eelis.net/geordi/>`_ instance running near-trunk clang instead of gcc. +Community wide proposals +------------------------ + +Proposals for massive changes in how the community behaves and how the work flow +can be better. + +.. toctree:: + :hidden: + + CodeOfConduct + Proposals/GitHubMove + +:doc:`CodeOfConduct` + Proposal to adopt a code of conduct on the LLVM social spaces (lists, events, + IRC, etc). + +:doc:`Proposals/GitHubMove` + Proposal to move from SVN/Git to GitHub. + Indices and tables ================== diff --git a/docs/tutorial/BuildingAJIT1.rst b/docs/tutorial/BuildingAJIT1.rst index f30b979579dcf..80957ee620f0f 100644 --- a/docs/tutorial/BuildingAJIT1.rst +++ b/docs/tutorial/BuildingAJIT1.rst @@ -190,14 +190,14 @@ available for execution. auto Resolver = createLambdaResolver( [&](const std::string &Name) { if (auto Sym = CompileLayer.findSymbol(Name, false)) - return Sym.toRuntimeDyldSymbol(); - return RuntimeDyld::SymbolInfo(nullptr); + return Sym; + return JITSymbol(nullptr); }, [](const std::string &S) { if (auto SymAddr = RTDyldMemoryManager::getSymbolAddressInProcess(Name)) - return RuntimeDyld::SymbolInfo(SymAddr, JITSymbolFlags::Exported); - return RuntimeDyld::SymbolInfo(nullptr); + return JITSymbol(SymAddr, JITSymbolFlags::Exported); + return JITSymbol(nullptr); }); // Build a singlton module set to hold our module. @@ -242,28 +242,27 @@ implementation? By using a single symbol resolution scheme we are free to choose whatever makes the most sense for any given use case. Building a symbol resolver is made especially easy by the *createLambdaResolver* -function. This function takes two lambdas [3]_ and returns a -RuntimeDyld::SymbolResolver instance. The first lambda is used as the -implementation of the resolver's findSymbolInLogicalDylib method, which searches -for symbol definitions that should be thought of as being part of the same -"logical" dynamic library as this Module. If you are familiar with static -linking: this means that findSymbolInLogicalDylib should expose symbols with -common linkage and hidden visibility. If all this sounds foreign you can ignore -the details and just remember that this is the first method that the linker will -use to try to find a symbol definition. If the findSymbolInLogicalDylib method -returns a null result then the linker will call the second symbol resolver -method, called findSymbol, which searches for symbols that should be thought of -as external to (but visibile from) the module and its logical dylib. In this -tutorial we will adopt the following simple scheme: All modules added to the JIT -will behave as if they were linked into a single, ever-growing logical dylib. To -implement this our first lambda (the one defining findSymbolInLogicalDylib) will -just search for JIT'd code by calling the CompileLayer's findSymbol method. If -we don't find a symbol in the JIT itself we'll fall back to our second lambda, -which implements findSymbol. This will use the -RTDyldMemoyrManager::getSymbolAddressInProcess method to search for the symbol -within the program itself. If we can't find a symbol definition via either of -these paths the JIT will refuse to accept our module, returning a "symbol not -found" error. +function. This function takes two lambdas [3]_ and returns a JITSymbolResolver +instance. The first lambda is used as the implementation of the resolver's +findSymbolInLogicalDylib method, which searches for symbol definitions that +should be thought of as being part of the same "logical" dynamic library as this +Module. If you are familiar with static linking: this means that +findSymbolInLogicalDylib should expose symbols with common linkage and hidden +visibility. If all this sounds foreign you can ignore the details and just +remember that this is the first method that the linker will use to try to find a +symbol definition. If the findSymbolInLogicalDylib method returns a null result +then the linker will call the second symbol resolver method, called findSymbol, +which searches for symbols that should be thought of as external to (but +visibile from) the module and its logical dylib. In this tutorial we will adopt +the following simple scheme: All modules added to the JIT will behave as if they +were linked into a single, ever-growing logical dylib. To implement this our +first lambda (the one defining findSymbolInLogicalDylib) will just search for +JIT'd code by calling the CompileLayer's findSymbol method. If we don't find a +symbol in the JIT itself we'll fall back to our second lambda, which implements +findSymbol. This will use the RTDyldMemoyrManager::getSymbolAddressInProcess +method to search for the symbol within the program itself. If we can't find a +symbol definition via either of these paths the JIT will refuse to accept our +module, returning a "symbol not found" error. Now that we've built our symbol resolver we're ready to add our module to the JIT. We do this by calling the CompileLayer's addModuleSet method [4]_. Since diff --git a/docs/tutorial/BuildingAJIT2.rst b/docs/tutorial/BuildingAJIT2.rst index 8fa92317f54fe..839875266a241 100644 --- a/docs/tutorial/BuildingAJIT2.rst +++ b/docs/tutorial/BuildingAJIT2.rst @@ -93,8 +93,8 @@ define below. auto Resolver = createLambdaResolver( [&](const std::string &Name) { if (auto Sym = OptimizeLayer.findSymbol(Name, false)) - return Sym.toRuntimeDyldSymbol(); - return RuntimeDyld::SymbolInfo(nullptr); + return Sym; + return JITSymbol(nullptr); }, // ... diff --git a/docs/tutorial/BuildingAJIT3.rst b/docs/tutorial/BuildingAJIT3.rst index ba0dab91c4ef5..071e92c74541d 100644 --- a/docs/tutorial/BuildingAJIT3.rst +++ b/docs/tutorial/BuildingAJIT3.rst @@ -19,29 +19,46 @@ CompileOnDemand layer the JIT from `Chapter 2 <BuildingAJIT2.html>`_. Lazy Compilation ================ -When we add a module to the KaleidoscopeJIT class described in Chapter 2 it is +When we add a module to the KaleidoscopeJIT class from Chapter 2 it is immediately optimized, compiled and linked for us by the IRTransformLayer, IRCompileLayer and ObjectLinkingLayer respectively. This scheme, where all the -work to make a Module executable is done up front, is relatively simple to -understand its performance characteristics are easy to reason about. However, -it will lead to very high startup times if the amount of code to be compiled is -large, and may also do a lot of unnecessary compilation if only a few compiled -functions are ever called at runtime. A truly "just-in-time" compiler should -allow us to defer the compilation of any given function until the moment that -function is first called, improving launch times and eliminating redundant work. -In fact, the ORC APIs provide us with a layer to lazily compile LLVM IR: +work to make a Module executable is done up front, is simple to understand and +its performance characteristics are easy to reason about. However, it will lead +to very high startup times if the amount of code to be compiled is large, and +may also do a lot of unnecessary compilation if only a few compiled functions +are ever called at runtime. A truly "just-in-time" compiler should allow us to +defer the compilation of any given function until the moment that function is +first called, improving launch times and eliminating redundant work. In fact, +the ORC APIs provide us with a layer to lazily compile LLVM IR: *CompileOnDemandLayer*. -The CompileOnDemandLayer conforms to the layer interface described in Chapter 2, -but the addModuleSet method behaves quite differently from the layers we have -seen so far: rather than doing any work up front, it just constructs a *stub* -for each function in the module and arranges for the stub to trigger compilation -of the actual function the first time it is called. Because stub functions are -very cheap to produce CompileOnDemand's addModuleSet method runs very quickly, -reducing the time required to launch the first function to be executed, and -saving us from doing any redundant compilation. By conforming to the layer -interface, CompileOnDemand can be easily added on top of our existing JIT class. -We just need a few changes: +The CompileOnDemandLayer class conforms to the layer interface described in +Chapter 2, but its addModuleSet method behaves quite differently from the layers +we have seen so far: rather than doing any work up front, it just scans the +Modules being added and arranges for each function in them to be compiled the +first time it is called. To do this, the CompileOnDemandLayer creates two small +utilities for each function that it scans: a *stub* and a *compile +callback*. The stub is a pair of a function pointer (which will be pointed at +the function's implementation once the function has been compiled) and an +indirect jump through the pointer. By fixing the address of the indirect jump +for the lifetime of the program we can give the function a permanent "effective +address", one that can be safely used for indirection and function pointer +comparison even if the function's implementation is never compiled, or if it is +compiled more than once (due to, for example, recompiling the function at a +higher optimization level) and changes address. The second utility, the compile +callback, represents a re-entry point from the program into the compiler that +will trigger compilation and then execution of a function. By initializing the +function's stub to point at the function's compile callback, we enable lazy +compilation: The first attempted call to the function will follow the function +pointer and trigger the compile callback instead. The compile callback will +compile the function, update the function pointer for the stub, then execute +the function. On all subsequent calls to the function, the function pointer +will point at the already-compiled function, so there is no further overhead +from the compiler. We will look at this process in more detail in the next +chapter of this tutorial, but for now we'll trust the CompileOnDemandLayer to +set all the stubs and callbacks up for us. All we need to do is to add the +CompileOnDemandLayer to the top of our stack and we'll get the benefits of +lazy compilation. We just need a few changes to the source: .. code-block:: c++ @@ -71,12 +88,8 @@ We just need a few changes: First we need to include the CompileOnDemandLayer.h header, then add two new members: a std::unique_ptr<CompileCallbackManager> and a CompileOnDemandLayer, -to our class. The CompileCallbackManager is a utility that enables us to -create re-entry points into the compiler for functions that we want to lazily -compile. In the next chapter we'll be looking at this class in detail, but for -now we'll be treating it as an opaque utility: We just need to pass a reference -to it into our new CompileOnDemandLayer, and the layer will do all the work of -setting up the callbacks using the callback manager we gave it. +to our class. The CompileCallbackManager member is used by the CompileOnDemandLayer +to create the compile callback needed for each function. .. code-block:: c++ @@ -100,10 +113,11 @@ setting up the callbacks using the callback manager we gave it. Next we have to update our constructor to initialize the new members. To create an appropriate compile callback manager we use the createLocalCompileCallbackManager function, which takes a TargetMachine and a -TargetAddress to call if it receives a request to compile an unknown function. -In our simple JIT this situation is unlikely to come up, so we'll cheat and -just pass '0' here. In a production quality JIT you could give the address of a -function that throws an exception in order to unwind the JIT'd code stack. +JITTargetAddress to call if it receives a request to compile an unknown +function. In our simple JIT this situation is unlikely to come up, so we'll +cheat and just pass '0' here. In a production quality JIT you could give the +address of a function that throws an exception in order to unwind the JIT'd +code's stack. Now we can construct our CompileOnDemandLayer. Following the pattern from previous layers we start by passing a reference to the next layer down in our @@ -116,13 +130,13 @@ functions that are unconditionally called (or highly likely to be called) from the function being called. For KaleidoscopeJIT we'll keep it simple and just request compilation of the function that was called. Next we pass a reference to our CompileCallbackManager. Finally, we need to supply an "indirect stubs -manager builder". This is a function that constructs IndirectStubManagers, which -are in turn used to build the stubs for each module. The CompileOnDemandLayer -will call the indirect stub manager builder once for each call to addModuleSet, -and use the resulting indirect stubs manager to create stubs for all functions -in all modules added. If/when the module set is removed from the JIT the -indirect stubs manager will be deleted, freeing any memory allocated to the -stubs. We supply this function by using the +manager builder": a utility function that constructs IndirectStubManagers, which +are in turn used to build the stubs for the functions in each module. The +CompileOnDemandLayer will call the indirect stub manager builder once for each +call to addModuleSet, and use the resulting indirect stubs manager to create +stubs for all functions in all modules in the set. If/when the module set is +removed from the JIT the indirect stubs manager will be deleted, freeing any +memory allocated to the stubs. We supply this function by using the createLocalIndirectStubsManagerBuilder utility. .. code-block:: c++ @@ -148,7 +162,7 @@ findSymbol, and removeModule methods. With that, we're up and running. **To be done:** -** Discuss CompileCallbackManagers and IndirectStubManagers in more detail.** +** Chapter conclusion.** Full Code Listing ================= diff --git a/docs/tutorial/LangImpl02.rst b/docs/tutorial/LangImpl02.rst index 701cbc9611363..ac8d2d7987432 100644 --- a/docs/tutorial/LangImpl02.rst +++ b/docs/tutorial/LangImpl02.rst @@ -708,7 +708,7 @@ For example, here is a sample interaction: There is a lot of room for extension here. You can define new AST nodes, extend the language in many ways, etc. In the `next -installment <LangImpl3.html>`_, we will describe how to generate LLVM +installment <LangImpl03.html>`_, we will describe how to generate LLVM Intermediate Representation (IR) from the AST. Full Code Listing diff --git a/docs/tutorial/LangImpl06.rst b/docs/tutorial/LangImpl06.rst index 7c9a2123e8f38..f6d2bd943ef7d 100644 --- a/docs/tutorial/LangImpl06.rst +++ b/docs/tutorial/LangImpl06.rst @@ -32,7 +32,7 @@ User-defined Operators: the Idea The "operator overloading" that we will add to Kaleidoscope is more general than languages like C++. In C++, you are only allowed to -redefine existing operators: you can't programatically change the +redefine existing operators: you can't programmatically change the grammar, introduce new operators, change precedence levels, etc. In this chapter, we will add this capability to Kaleidoscope, which will let the user round out the set of operators that are supported. diff --git a/docs/tutorial/OCamlLangImpl6.rst b/docs/tutorial/OCamlLangImpl6.rst index 2fa25f5c22fb5..4b3e1575adf6e 100644 --- a/docs/tutorial/OCamlLangImpl6.rst +++ b/docs/tutorial/OCamlLangImpl6.rst @@ -32,7 +32,7 @@ User-defined Operators: the Idea The "operator overloading" that we will add to Kaleidoscope is more general than languages like C++. In C++, you are only allowed to -redefine existing operators: you can't programatically change the +redefine existing operators: you can't programmatically change the grammar, introduce new operators, change precedence levels, etc. In this chapter, we will add this capability to Kaleidoscope, which will let the user round out the set of operators that are supported. |
