xref: /openbsd-src/gnu/llvm/llvm/docs/TransformMetadata.rst (revision 73471bf04ceb096474c7f0fa83b1b65c70a787a1)
109467b48Spatrick.. _transformation-metadata:
209467b48Spatrick
309467b48Spatrick============================
409467b48SpatrickCode Transformation Metadata
509467b48Spatrick============================
609467b48Spatrick
709467b48Spatrick.. contents::
809467b48Spatrick   :local:
909467b48Spatrick
1009467b48SpatrickOverview
1109467b48Spatrick========
1209467b48Spatrick
1309467b48SpatrickLLVM transformation passes can be controlled by attaching metadata to
1409467b48Spatrickthe code to transform. By default, transformation passes use heuristics
1509467b48Spatrickto determine whether or not to perform transformations, and when doing
1609467b48Spatrickso, other details of how the transformations are applied (e.g., which
1709467b48Spatrickvectorization factor to select).
1809467b48SpatrickUnless the optimizer is otherwise directed, transformations are applied
1909467b48Spatrickconservatively. This conservatism generally allows the optimizer to
2009467b48Spatrickavoid unprofitable transformations, but in practice, this results in the
2109467b48Spatrickoptimizer not applying transformations that would be highly profitable.
2209467b48Spatrick
2309467b48SpatrickFrontends can give additional hints to LLVM passes on which
2409467b48Spatricktransformations they should apply. This can be additional knowledge that
2509467b48Spatrickcannot be derived from the emitted IR, or directives passed from the
2609467b48Spatrickuser/programmer. OpenMP pragmas are an example of the latter.
2709467b48Spatrick
2809467b48SpatrickIf any such metadata is dropped from the program, the code's semantics
2909467b48Spatrickmust not change.
3009467b48Spatrick
3109467b48SpatrickMetadata on Loops
3209467b48Spatrick=================
3309467b48Spatrick
3409467b48SpatrickAttributes can be attached to loops as described in :ref:`llvm.loop`.
3509467b48SpatrickAttributes can describe properties of the loop, disable transformations,
3609467b48Spatrickforce specific transformations and set transformation options.
3709467b48Spatrick
3809467b48SpatrickBecause metadata nodes are immutable (with the exception of
3909467b48Spatrick``MDNode::replaceOperandWith`` which is dangerous to use on uniqued
4009467b48Spatrickmetadata), in order to add or remove a loop attributes, a new ``MDNode``
4109467b48Spatrickmust be created and assigned as the new ``llvm.loop`` metadata. Any
4209467b48Spatrickconnection between the old ``MDNode`` and the loop is lost. The
4309467b48Spatrick``llvm.loop`` node is also used as LoopID (``Loop::getLoopID()``), i.e.
4409467b48Spatrickthe loop effectively gets a new identifier. For instance,
4509467b48Spatrick``llvm.mem.parallel_loop_access`` references the LoopID. Therefore, if
4609467b48Spatrickthe parallel access property is to be preserved after adding/removing
4709467b48Spatrickloop attributes, any ``llvm.mem.parallel_loop_access`` reference must be
4809467b48Spatrickupdated to the new LoopID.
4909467b48Spatrick
5009467b48SpatrickTransformation Metadata Structure
5109467b48Spatrick=================================
5209467b48Spatrick
5309467b48SpatrickSome attributes describe code transformations (unrolling, vectorizing,
5409467b48Spatrickloop distribution, etc.). They can either be a hint to the optimizer
5509467b48Spatrickthat a transformation might be beneficial, instruction to use a specific
5609467b48Spatrickoption, , or convey a specific request from the user (such as
5709467b48Spatrick``#pragma clang loop`` or ``#pragma omp simd``).
5809467b48Spatrick
5909467b48SpatrickIf a transformation is forced but cannot be carried-out for any reason,
6009467b48Spatrickan optimization-missed warning must be emitted. Semantic information
6109467b48Spatricksuch as a transformation being safe (e.g.
6209467b48Spatrick``llvm.mem.parallel_loop_access``) can be unused by the optimizer
6309467b48Spatrickwithout generating a warning.
6409467b48Spatrick
6509467b48SpatrickUnless explicitly disabled, any optimization pass may heuristically
6609467b48Spatrickdetermine whether a transformation is beneficial and apply it. If
6709467b48Spatrickmetadata for another transformation was specified, applying a different
6809467b48Spatricktransformation before it might be inadvertent due to being applied on a
6909467b48Spatrickdifferent loop or the loop not existing anymore. To avoid having to
7009467b48Spatrickexplicitly disable an unknown number of passes, the attribute
7109467b48Spatrick``llvm.loop.disable_nonforced`` disables all optional, high-level,
7209467b48Spatrickrestructuring transformations.
7309467b48Spatrick
7409467b48SpatrickThe following example avoids the loop being altered before being
7509467b48Spatrickvectorized, for instance being unrolled.
7609467b48Spatrick
7709467b48Spatrick.. code-block:: llvm
7809467b48Spatrick
7909467b48Spatrick      br i1 %exitcond, label %for.exit, label %for.header, !llvm.loop !0
8009467b48Spatrick    ...
8109467b48Spatrick    !0 = distinct !{!0, !1, !2}
8209467b48Spatrick    !1 = !{!"llvm.loop.vectorize.enable", i1 true}
8309467b48Spatrick    !2 = !{!"llvm.loop.disable_nonforced"}
8409467b48Spatrick
8509467b48SpatrickAfter a transformation is applied, follow-up attributes are set on the
8609467b48Spatricktransformed and/or new loop(s). This allows additional attributes
8709467b48Spatrickincluding followup-transformations to be specified. Specifying multiple
8809467b48Spatricktransformations in the same metadata node is possible for compatibility
8909467b48Spatrickreasons, but their execution order is undefined. For instance, when
9009467b48Spatrick``llvm.loop.vectorize.enable`` and ``llvm.loop.unroll.enable`` are
9109467b48Spatrickspecified at the same time, unrolling may occur either before or after
9209467b48Spatrickvectorization.
9309467b48Spatrick
9409467b48SpatrickAs an example, the following instructs a loop to be vectorized and only
9509467b48Spatrickthen unrolled.
9609467b48Spatrick
9709467b48Spatrick.. code-block:: llvm
9809467b48Spatrick
9909467b48Spatrick    !0 = distinct !{!0, !1, !2, !3}
10009467b48Spatrick    !1 = !{!"llvm.loop.vectorize.enable", i1 true}
10109467b48Spatrick    !2 = !{!"llvm.loop.disable_nonforced"}
10209467b48Spatrick    !3 = !{!"llvm.loop.vectorize.followup_vectorized", !{"llvm.loop.unroll.enable"}}
10309467b48Spatrick
10409467b48SpatrickIf, and only if, no followup is specified, the pass may add attributes itself.
10509467b48SpatrickFor instance, the vectorizer adds a ``llvm.loop.isvectorized`` attribute and
10609467b48Spatrickall attributes from the original loop excluding its loop vectorizer
10709467b48Spatrickattributes. To avoid this, an empty followup attribute can be used, e.g.
10809467b48Spatrick
10909467b48Spatrick.. code-block:: llvm
11009467b48Spatrick
11109467b48Spatrick    !3 = !{!"llvm.loop.vectorize.followup_vectorized"}
11209467b48Spatrick
11309467b48SpatrickThe followup attributes of a transformation that cannot be applied will
11409467b48Spatricknever be added to a loop and are therefore effectively ignored. This means
11509467b48Spatrickthat any followup-transformation in such attributes requires that its
11609467b48Spatrickprior transformations are applied before the followup-transformation.
11709467b48SpatrickThe user should receive a warning about the first transformation in the
11809467b48Spatricktransformation chain that could not be applied if it a forced
11909467b48Spatricktransformation. All following transformations are skipped.
12009467b48Spatrick
12109467b48SpatrickPass-Specific Transformation Metadata
12209467b48Spatrick=====================================
12309467b48Spatrick
12409467b48SpatrickTransformation options are specific to each transformation. In the
12509467b48Spatrickfollowing, we present the model for each LLVM loop optimization pass and
12609467b48Spatrickthe metadata to influence them.
12709467b48Spatrick
12809467b48SpatrickLoop Vectorization and Interleaving
12909467b48Spatrick-----------------------------------
13009467b48Spatrick
13109467b48SpatrickLoop vectorization and interleaving is interpreted as a single
13209467b48Spatricktransformation. It is interpreted as forced if
13309467b48Spatrick``!{"llvm.loop.vectorize.enable", i1 true}`` is set.
13409467b48Spatrick
13509467b48SpatrickAssuming the pre-vectorization loop is
13609467b48Spatrick
13709467b48Spatrick.. code-block:: c
13809467b48Spatrick
13909467b48Spatrick    for (int i = 0; i < n; i+=1) // original loop
14009467b48Spatrick      Stmt(i);
14109467b48Spatrick
14209467b48Spatrickthen the code after vectorization will be approximately (assuming an
14309467b48SpatrickSIMD width of 4):
14409467b48Spatrick
14509467b48Spatrick.. code-block:: c
14609467b48Spatrick
14709467b48Spatrick    int i = 0;
14809467b48Spatrick    if (rtc) {
14909467b48Spatrick      for (; i + 3 < n; i+=4) // vectorized/interleaved loop
15009467b48Spatrick        Stmt(i:i+3);
15109467b48Spatrick    }
15209467b48Spatrick    for (; i < n; i+=1) // epilogue loop
15309467b48Spatrick      Stmt(i);
15409467b48Spatrick
15509467b48Spatrickwhere ``rtc`` is a generated runtime check.
15609467b48Spatrick
15709467b48Spatrick``llvm.loop.vectorize.followup_vectorized`` will set the attributes for
15809467b48Spatrickthe vectorized loop. If not specified, ``llvm.loop.isvectorized`` is
15909467b48Spatrickcombined with the original loop's attributes to avoid it being
16009467b48Spatrickvectorized multiple times.
16109467b48Spatrick
16209467b48Spatrick``llvm.loop.vectorize.followup_epilogue`` will set the attributes for
16309467b48Spatrickthe remainder loop. If not specified, it will have the original loop's
16409467b48Spatrickattributes combined with ``llvm.loop.isvectorized`` and
16509467b48Spatrick``llvm.loop.unroll.runtime.disable`` (unless the original loop already
16609467b48Spatrickhas unroll metadata).
16709467b48Spatrick
16809467b48SpatrickThe attributes specified by ``llvm.loop.vectorize.followup_all`` are
16909467b48Spatrickadded to both loops.
17009467b48Spatrick
17109467b48SpatrickWhen using a follow-up attribute, it replaces any automatically deduced
17209467b48Spatrickattributes for the generated loop in question. Therefore it is
17309467b48Spatrickrecommended to add ``llvm.loop.isvectorized`` to
17409467b48Spatrick``llvm.loop.vectorize.followup_all`` which avoids that the loop
17509467b48Spatrickvectorizer tries to optimize the loops again.
17609467b48Spatrick
17709467b48SpatrickLoop Unrolling
17809467b48Spatrick--------------
17909467b48Spatrick
18009467b48SpatrickUnrolling is interpreted as forced any ``!{!"llvm.loop.unroll.enable"}``
18109467b48Spatrickmetadata or option (``llvm.loop.unroll.count``, ``llvm.loop.unroll.full``)
18209467b48Spatrickis present. Unrolling can be full unrolling, partial unrolling of a loop
18309467b48Spatrickwith constant trip count or runtime unrolling of a loop with a trip
18409467b48Spatrickcount unknown at compile-time.
18509467b48Spatrick
18609467b48SpatrickIf the loop has been unrolled fully, there is no followup-loop. For
18709467b48Spatrickpartial/runtime unrolling, the original loop of
18809467b48Spatrick
18909467b48Spatrick.. code-block:: c
19009467b48Spatrick
19109467b48Spatrick    for (int i = 0; i < n; i+=1) // original loop
19209467b48Spatrick      Stmt(i);
19309467b48Spatrick
19409467b48Spatrickis transformed into (using an unroll factor of 4):
19509467b48Spatrick
19609467b48Spatrick.. code-block:: c
19709467b48Spatrick
19809467b48Spatrick    int i = 0;
199*73471bf0Spatrick    for (; i + 3 < n; i+=4) { // unrolled loop
20009467b48Spatrick      Stmt(i);
20109467b48Spatrick      Stmt(i+1);
20209467b48Spatrick      Stmt(i+2);
20309467b48Spatrick      Stmt(i+3);
20409467b48Spatrick    }
20509467b48Spatrick    for (; i < n; i+=1) // remainder loop
20609467b48Spatrick      Stmt(i);
20709467b48Spatrick
20809467b48Spatrick``llvm.loop.unroll.followup_unrolled`` will set the loop attributes of
20909467b48Spatrickthe unrolled loop. If not specified, the attributes of the original loop
21009467b48Spatrickwithout the ``llvm.loop.unroll.*`` attributes are copied and
21109467b48Spatrick``llvm.loop.unroll.disable`` added to it.
21209467b48Spatrick
21309467b48Spatrick``llvm.loop.unroll.followup_remainder`` defines the attributes of the
21409467b48Spatrickremainder loop. If not specified the remainder loop will have no
21509467b48Spatrickattributes. The remainder loop might not be present due to being fully
21609467b48Spatrickunrolled in which case this attribute has no effect.
21709467b48Spatrick
21809467b48SpatrickAttributes defined in ``llvm.loop.unroll.followup_all`` are added to the
21909467b48Spatrickunrolled and remainder loops.
22009467b48Spatrick
22109467b48SpatrickTo avoid that the partially unrolled loop is unrolled again, it is
22209467b48Spatrickrecommended to add ``llvm.loop.unroll.disable`` to
22309467b48Spatrick``llvm.loop.unroll.followup_all``. If no follow-up attribute specified
22409467b48Spatrickfor a generated loop, it is added automatically.
22509467b48Spatrick
22609467b48SpatrickUnroll-And-Jam
22709467b48Spatrick--------------
22809467b48Spatrick
22909467b48SpatrickUnroll-and-jam uses the following transformation model (here with an
23009467b48Spatrickunroll factor if 2). Currently, it does not support a fallback version
23109467b48Spatrickwhen the transformation is unsafe.
23209467b48Spatrick
23309467b48Spatrick.. code-block:: c
23409467b48Spatrick
23509467b48Spatrick    for (int i = 0; i < n; i+=1) { // original outer loop
23609467b48Spatrick      Fore(i);
23709467b48Spatrick      for (int j = 0; j < m; j+=1) // original inner loop
23809467b48Spatrick        SubLoop(i, j);
23909467b48Spatrick      Aft(i);
24009467b48Spatrick    }
24109467b48Spatrick
24209467b48Spatrick.. code-block:: c
24309467b48Spatrick
24409467b48Spatrick    int i = 0;
24509467b48Spatrick    for (; i + 1 < n; i+=2) { // unrolled outer loop
24609467b48Spatrick      Fore(i);
24709467b48Spatrick      Fore(i+1);
24809467b48Spatrick      for (int j = 0; j < m; j+=1) { // unrolled inner loop
24909467b48Spatrick        SubLoop(i, j);
25009467b48Spatrick        SubLoop(i+1, j);
25109467b48Spatrick      }
25209467b48Spatrick      Aft(i);
25309467b48Spatrick      Aft(i+1);
25409467b48Spatrick    }
25509467b48Spatrick    for (; i < n; i+=1) { // remainder outer loop
25609467b48Spatrick      Fore(i);
25709467b48Spatrick      for (int j = 0; j < m; j+=1) // remainder inner loop
25809467b48Spatrick        SubLoop(i, j);
25909467b48Spatrick      Aft(i);
26009467b48Spatrick    }
26109467b48Spatrick
26209467b48Spatrick``llvm.loop.unroll_and_jam.followup_outer`` will set the loop attributes
26309467b48Spatrickof the unrolled outer loop. If not specified, the attributes of the
26409467b48Spatrickoriginal outer loop without the ``llvm.loop.unroll.*`` attributes are
26509467b48Spatrickcopied and ``llvm.loop.unroll.disable`` added to it.
26609467b48Spatrick
26709467b48Spatrick``llvm.loop.unroll_and_jam.followup_inner`` will set the loop attributes
26809467b48Spatrickof the unrolled inner loop. If not specified, the attributes of the
26909467b48Spatrickoriginal inner loop are used unchanged.
27009467b48Spatrick
27109467b48Spatrick``llvm.loop.unroll_and_jam.followup_remainder_outer`` sets the loop
27209467b48Spatrickattributes of the outer remainder loop. If not specified it will not
27309467b48Spatrickhave any attributes. The remainder loop might not be present due to
27409467b48Spatrickbeing fully unrolled.
27509467b48Spatrick
27609467b48Spatrick``llvm.loop.unroll_and_jam.followup_remainder_inner`` sets the loop
27709467b48Spatrickattributes of the inner remainder loop. If not specified it will have
27809467b48Spatrickthe attributes of the original inner loop. It the outer remainder loop
27909467b48Spatrickis unrolled, the inner remainder loop might be present multiple times.
28009467b48Spatrick
28109467b48SpatrickAttributes defined in ``llvm.loop.unroll_and_jam.followup_all`` are
28209467b48Spatrickadded to all of the aforementioned output loops.
28309467b48Spatrick
28409467b48SpatrickTo avoid that the unrolled loop is unrolled again, it is
28509467b48Spatrickrecommended to add ``llvm.loop.unroll.disable`` to
28609467b48Spatrick``llvm.loop.unroll_and_jam.followup_all``. It suppresses unroll-and-jam
28709467b48Spatrickas well as an additional inner loop unrolling. If no follow-up
28809467b48Spatrickattribute specified for a generated loop, it is added automatically.
28909467b48Spatrick
29009467b48SpatrickLoop Distribution
29109467b48Spatrick-----------------
29209467b48Spatrick
29309467b48SpatrickThe LoopDistribution pass tries to separate vectorizable parts of a loop
29409467b48Spatrickfrom the non-vectorizable part (which otherwise would make the entire
29509467b48Spatrickloop non-vectorizable). Conceptually, it transforms a loop such as
29609467b48Spatrick
29709467b48Spatrick.. code-block:: c
29809467b48Spatrick
29909467b48Spatrick    for (int i = 1; i < n; i+=1) { // original loop
30009467b48Spatrick      A[i] = i;
30109467b48Spatrick      B[i] = 2 + B[i];
30209467b48Spatrick      C[i] = 3 + C[i - 1];
30309467b48Spatrick    }
30409467b48Spatrick
30509467b48Spatrickinto the following code:
30609467b48Spatrick
30709467b48Spatrick.. code-block:: c
30809467b48Spatrick
30909467b48Spatrick    if (rtc) {
31009467b48Spatrick      for (int i = 1; i < n; i+=1) // coincident loop
31109467b48Spatrick        A[i] = i;
31209467b48Spatrick      for (int i = 1; i < n; i+=1) // coincident loop
31309467b48Spatrick        B[i] = 2 + B[i];
31409467b48Spatrick      for (int i = 1; i < n; i+=1) // sequential loop
31509467b48Spatrick        C[i] = 3 + C[i - 1];
31609467b48Spatrick    } else {
31709467b48Spatrick      for (int i = 1; i < n; i+=1) { // fallback loop
31809467b48Spatrick        A[i] = i;
31909467b48Spatrick        B[i] = 2 + B[i];
32009467b48Spatrick        C[i] = 3 + C[i - 1];
32109467b48Spatrick      }
32209467b48Spatrick    }
32309467b48Spatrick
32409467b48Spatrickwhere ``rtc`` is a generated runtime check.
32509467b48Spatrick
32609467b48Spatrick``llvm.loop.distribute.followup_coincident`` sets the loop attributes of
32709467b48Spatrickall loops without loop-carried dependencies (i.e. vectorizable loops).
32809467b48SpatrickThere might be more than one such loops. If not defined, the loops will
32909467b48Spatrickinherit the original loop's attributes.
33009467b48Spatrick
33109467b48Spatrick``llvm.loop.distribute.followup_sequential`` sets the loop attributes of the
33209467b48Spatrickloop with potentially unsafe dependencies. There should be at most one
33309467b48Spatricksuch loop. If not defined, the loop will inherit the original loop's
33409467b48Spatrickattributes.
33509467b48Spatrick
33609467b48Spatrick``llvm.loop.distribute.followup_fallback`` defines the loop attributes
33709467b48Spatrickfor the fallback loop, which is a copy of the original loop for when
33809467b48Spatrickloop versioning is required. If undefined, the fallback loop inherits
33909467b48Spatrickall attributes from the original loop.
34009467b48Spatrick
34109467b48SpatrickAttributes defined in ``llvm.loop.distribute.followup_all`` are added to
34209467b48Spatrickall of the aforementioned output loops.
34309467b48Spatrick
34409467b48SpatrickIt is recommended to add ``llvm.loop.disable_nonforced`` to
34509467b48Spatrick``llvm.loop.distribute.followup_fallback``. This avoids that the
346097a140dSpatrickfallback version (which is likely never executed) is further optimized
34709467b48Spatrickwhich would increase the code size.
34809467b48Spatrick
34909467b48SpatrickVersioning LICM
35009467b48Spatrick---------------
35109467b48Spatrick
35209467b48SpatrickThe pass hoists code out of loops that are only loop-invariant when
35309467b48Spatrickdynamic conditions apply. For instance, it transforms the loop
35409467b48Spatrick
35509467b48Spatrick.. code-block:: c
35609467b48Spatrick
35709467b48Spatrick    for (int i = 0; i < n; i+=1) // original loop
35809467b48Spatrick      A[i] = B[0];
35909467b48Spatrick
36009467b48Spatrickinto:
36109467b48Spatrick
36209467b48Spatrick.. code-block:: c
36309467b48Spatrick
36409467b48Spatrick    if (rtc) {
36509467b48Spatrick      auto b = B[0];
36609467b48Spatrick      for (int i = 0; i < n; i+=1) // versioned loop
36709467b48Spatrick        A[i] = b;
36809467b48Spatrick    } else {
36909467b48Spatrick      for (int i = 0; i < n; i+=1) // unversioned loop
37009467b48Spatrick        A[i] = B[0];
37109467b48Spatrick    }
37209467b48Spatrick
37309467b48SpatrickThe runtime condition (``rtc``) checks that the array ``A`` and the
37409467b48Spatrickelement `B[0]` do not alias.
37509467b48Spatrick
37609467b48SpatrickCurrently, this transformation does not support followup-attributes.
37709467b48Spatrick
37809467b48SpatrickLoop Interchange
37909467b48Spatrick----------------
38009467b48Spatrick
38109467b48SpatrickCurrently, the ``LoopInterchange`` pass does not use any metadata.
38209467b48Spatrick
38309467b48SpatrickAmbiguous Transformation Order
38409467b48Spatrick==============================
38509467b48Spatrick
38609467b48SpatrickIf there multiple transformations defined, the order in which they are
38709467b48Spatrickexecuted depends on the order in LLVM's pass pipeline, which is subject
38809467b48Spatrickto change. The default optimization pipeline (anything higher than
38909467b48Spatrick``-O0``) has the following order.
39009467b48Spatrick
39109467b48SpatrickWhen using the legacy pass manager:
39209467b48Spatrick
39309467b48Spatrick - LoopInterchange (if enabled)
39409467b48Spatrick - SimpleLoopUnroll/LoopFullUnroll (only performs full unrolling)
39509467b48Spatrick - VersioningLICM (if enabled)
39609467b48Spatrick - LoopDistribute
39709467b48Spatrick - LoopVectorizer
39809467b48Spatrick - LoopUnrollAndJam (if enabled)
39909467b48Spatrick - LoopUnroll (partial and runtime unrolling)
40009467b48Spatrick
40109467b48SpatrickWhen using the legacy pass manager with LTO:
40209467b48Spatrick
40309467b48Spatrick - LoopInterchange (if enabled)
40409467b48Spatrick - SimpleLoopUnroll/LoopFullUnroll (only performs full unrolling)
40509467b48Spatrick - LoopVectorizer
40609467b48Spatrick - LoopUnroll (partial and runtime unrolling)
40709467b48Spatrick
40809467b48SpatrickWhen using the new pass manager:
40909467b48Spatrick
41009467b48Spatrick - SimpleLoopUnroll/LoopFullUnroll (only performs full unrolling)
41109467b48Spatrick - LoopDistribute
41209467b48Spatrick - LoopVectorizer
41309467b48Spatrick - LoopUnrollAndJam (if enabled)
41409467b48Spatrick - LoopUnroll (partial and runtime unrolling)
41509467b48Spatrick
41609467b48SpatrickLeftover Transformations
41709467b48Spatrick========================
41809467b48Spatrick
41909467b48SpatrickForced transformations that have not been applied after the last
42009467b48Spatricktransformation pass should be reported to the user. The transformation
42109467b48Spatrickpasses themselves cannot be responsible for this reporting because they
42209467b48Spatrickmight not be in the pipeline, there might be multiple passes able to
42309467b48Spatrickapply a transformation (e.g. ``LoopInterchange`` and Polly) or a
42409467b48Spatricktransformation attribute may be 'hidden' inside another passes' followup
42509467b48Spatrickattribute.
42609467b48Spatrick
42709467b48SpatrickThe pass ``-transform-warning`` (``WarnMissedTransformationsPass``)
42809467b48Spatrickemits such warnings. It should be placed after the last transformation
42909467b48Spatrickpass.
43009467b48Spatrick
43109467b48SpatrickThe current pass pipeline has a fixed order in which transformations
43209467b48Spatrickpasses are executed. A transformation can be in the followup of a pass
43309467b48Spatrickthat is executed later and thus leftover. For instance, a loop nest
43409467b48Spatrickcannot be distributed and then interchanged with the current pass
43509467b48Spatrickpipeline. The loop distribution will execute, but there is no loop
43609467b48Spatrickinterchange pass following such that any loop interchange metadata will
43709467b48Spatrickbe ignored. The ``-transform-warning`` should emit a warning in this
43809467b48Spatrickcase.
43909467b48Spatrick
44009467b48SpatrickFuture versions of LLVM may fix this by executing transformations using
44109467b48Spatricka dynamic ordering.
442