diff --git a/llvm/docs/Frontend/PerformanceTips.rst b/llvm/docs/Frontend/PerformanceTips.rst index dfa3ccdd1ddd1..289106cd1e28e 100644 --- a/llvm/docs/Frontend/PerformanceTips.rst +++ b/llvm/docs/Frontend/PerformanceTips.rst @@ -64,16 +64,36 @@ SSA is the canonical form expected by much of the optimizer; if allocas can not be eliminated by Mem2Reg or SROA, the optimizer is likely to be less effective than it could be. -Avoid loads and stores of large aggregate type -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Avoid creating values of aggregate type +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Avoid creating values of :ref:`aggregate types ` (i.e. structs and +arrays). In particular, avoid loading and storing them, or manipulating them +with insertvalue and extractvalue instructions. Instead, only load and store +individual fields of the aggregate. + +There are some exceptions to this rule: + +* It is fine to use values of aggregate type in global variable initializers. +* It is fine to return structs, if this is done to represent the return of + multiple values in registers. +* It is fine to work with structs returned by LLVM intrinsics, such as the + ``with.overflow`` family of intrinsics. +* It is fine to use aggregate *types* without creating values. For example, + they are commonly used in ``getelementptr`` instructions or attributes like + ``sret``. + +Avoid loads and stores of non-byte-sized types +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Avoid loading or storing non-byte-sized types like ``i1``. Instead, +appropriately extend them to the next byte-sized type. -LLVM currently does not optimize well loads and stores of large :ref:`aggregate -types ` (i.e. structs and arrays). As an alternative, consider -loading individual fields from memory. +For example, when working with boolean values, store them by zero-extending +``i1`` to ``i8`` and load them by loading ``i8`` and truncating to ``i1``. -Aggregates that are smaller than the largest (performant) load or store -instruction supported by the targeted hardware are well supported. These can -be an effective way to represent collections of small packed fields. +If you do use loads/stores on non-byte-sized types, make sure that you *always* +use those types. For example, do not first store ``i8`` and then load ``i1``. Prefer zext over sext when legal ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^