106f32e7eSjoerg //===- StackColoring.cpp --------------------------------------------------===//
206f32e7eSjoerg //
306f32e7eSjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
406f32e7eSjoerg // See https://llvm.org/LICENSE.txt for license information.
506f32e7eSjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
606f32e7eSjoerg //
706f32e7eSjoerg //===----------------------------------------------------------------------===//
806f32e7eSjoerg //
906f32e7eSjoerg // This pass implements the stack-coloring optimization that looks for
1006f32e7eSjoerg // lifetime markers machine instructions (LIFESTART_BEGIN and LIFESTART_END),
1106f32e7eSjoerg // which represent the possible lifetime of stack slots. It attempts to
1206f32e7eSjoerg // merge disjoint stack slots and reduce the used stack space.
1306f32e7eSjoerg // NOTE: This pass is not StackSlotColoring, which optimizes spill slots.
1406f32e7eSjoerg //
1506f32e7eSjoerg // TODO: In the future we plan to improve stack coloring in the following ways:
1606f32e7eSjoerg // 1. Allow merging multiple small slots into a single larger slot at different
1706f32e7eSjoerg //    offsets.
1806f32e7eSjoerg // 2. Merge this pass with StackSlotColoring and allow merging of allocas with
1906f32e7eSjoerg //    spill slots.
2006f32e7eSjoerg //
2106f32e7eSjoerg //===----------------------------------------------------------------------===//
2206f32e7eSjoerg 
2306f32e7eSjoerg #include "llvm/ADT/BitVector.h"
2406f32e7eSjoerg #include "llvm/ADT/DenseMap.h"
2506f32e7eSjoerg #include "llvm/ADT/DepthFirstIterator.h"
2606f32e7eSjoerg #include "llvm/ADT/SmallPtrSet.h"
2706f32e7eSjoerg #include "llvm/ADT/SmallVector.h"
2806f32e7eSjoerg #include "llvm/ADT/Statistic.h"
2906f32e7eSjoerg #include "llvm/Analysis/ValueTracking.h"
3006f32e7eSjoerg #include "llvm/CodeGen/LiveInterval.h"
3106f32e7eSjoerg #include "llvm/CodeGen/MachineBasicBlock.h"
3206f32e7eSjoerg #include "llvm/CodeGen/MachineFrameInfo.h"
3306f32e7eSjoerg #include "llvm/CodeGen/MachineFunction.h"
3406f32e7eSjoerg #include "llvm/CodeGen/MachineFunctionPass.h"
3506f32e7eSjoerg #include "llvm/CodeGen/MachineInstr.h"
3606f32e7eSjoerg #include "llvm/CodeGen/MachineMemOperand.h"
3706f32e7eSjoerg #include "llvm/CodeGen/MachineOperand.h"
3806f32e7eSjoerg #include "llvm/CodeGen/Passes.h"
3906f32e7eSjoerg #include "llvm/CodeGen/SelectionDAGNodes.h"
4006f32e7eSjoerg #include "llvm/CodeGen/SlotIndexes.h"
4106f32e7eSjoerg #include "llvm/CodeGen/TargetOpcodes.h"
4206f32e7eSjoerg #include "llvm/CodeGen/WinEHFuncInfo.h"
4306f32e7eSjoerg #include "llvm/Config/llvm-config.h"
4406f32e7eSjoerg #include "llvm/IR/Constants.h"
4506f32e7eSjoerg #include "llvm/IR/DebugInfoMetadata.h"
4606f32e7eSjoerg #include "llvm/IR/Function.h"
4706f32e7eSjoerg #include "llvm/IR/Instructions.h"
4806f32e7eSjoerg #include "llvm/IR/Metadata.h"
4906f32e7eSjoerg #include "llvm/IR/Use.h"
5006f32e7eSjoerg #include "llvm/IR/Value.h"
51*da58b97aSjoerg #include "llvm/InitializePasses.h"
5206f32e7eSjoerg #include "llvm/Pass.h"
5306f32e7eSjoerg #include "llvm/Support/Casting.h"
5406f32e7eSjoerg #include "llvm/Support/CommandLine.h"
5506f32e7eSjoerg #include "llvm/Support/Compiler.h"
5606f32e7eSjoerg #include "llvm/Support/Debug.h"
5706f32e7eSjoerg #include "llvm/Support/raw_ostream.h"
5806f32e7eSjoerg #include <algorithm>
5906f32e7eSjoerg #include <cassert>
6006f32e7eSjoerg #include <limits>
6106f32e7eSjoerg #include <memory>
6206f32e7eSjoerg #include <utility>
6306f32e7eSjoerg 
6406f32e7eSjoerg using namespace llvm;
6506f32e7eSjoerg 
6606f32e7eSjoerg #define DEBUG_TYPE "stack-coloring"
6706f32e7eSjoerg 
6806f32e7eSjoerg static cl::opt<bool>
6906f32e7eSjoerg DisableColoring("no-stack-coloring",
7006f32e7eSjoerg         cl::init(false), cl::Hidden,
7106f32e7eSjoerg         cl::desc("Disable stack coloring"));
7206f32e7eSjoerg 
7306f32e7eSjoerg /// The user may write code that uses allocas outside of the declared lifetime
7406f32e7eSjoerg /// zone. This can happen when the user returns a reference to a local
7506f32e7eSjoerg /// data-structure. We can detect these cases and decide not to optimize the
7606f32e7eSjoerg /// code. If this flag is enabled, we try to save the user. This option
7706f32e7eSjoerg /// is treated as overriding LifetimeStartOnFirstUse below.
7806f32e7eSjoerg static cl::opt<bool>
7906f32e7eSjoerg ProtectFromEscapedAllocas("protect-from-escaped-allocas",
8006f32e7eSjoerg                           cl::init(false), cl::Hidden,
8106f32e7eSjoerg                           cl::desc("Do not optimize lifetime zones that "
8206f32e7eSjoerg                                    "are broken"));
8306f32e7eSjoerg 
8406f32e7eSjoerg /// Enable enhanced dataflow scheme for lifetime analysis (treat first
8506f32e7eSjoerg /// use of stack slot as start of slot lifetime, as opposed to looking
8606f32e7eSjoerg /// for LIFETIME_START marker). See "Implementation notes" below for
8706f32e7eSjoerg /// more info.
8806f32e7eSjoerg static cl::opt<bool>
8906f32e7eSjoerg LifetimeStartOnFirstUse("stackcoloring-lifetime-start-on-first-use",
9006f32e7eSjoerg         cl::init(true), cl::Hidden,
9106f32e7eSjoerg         cl::desc("Treat stack lifetimes as starting on first use, not on START marker."));
9206f32e7eSjoerg 
9306f32e7eSjoerg 
9406f32e7eSjoerg STATISTIC(NumMarkerSeen,  "Number of lifetime markers found.");
9506f32e7eSjoerg STATISTIC(StackSpaceSaved, "Number of bytes saved due to merging slots.");
9606f32e7eSjoerg STATISTIC(StackSlotMerged, "Number of stack slot merged.");
9706f32e7eSjoerg STATISTIC(EscapedAllocas, "Number of allocas that escaped the lifetime region");
9806f32e7eSjoerg 
9906f32e7eSjoerg //===----------------------------------------------------------------------===//
10006f32e7eSjoerg //                           StackColoring Pass
10106f32e7eSjoerg //===----------------------------------------------------------------------===//
10206f32e7eSjoerg //
10306f32e7eSjoerg // Stack Coloring reduces stack usage by merging stack slots when they
10406f32e7eSjoerg // can't be used together. For example, consider the following C program:
10506f32e7eSjoerg //
10606f32e7eSjoerg //     void bar(char *, int);
10706f32e7eSjoerg //     void foo(bool var) {
10806f32e7eSjoerg //         A: {
10906f32e7eSjoerg //             char z[4096];
11006f32e7eSjoerg //             bar(z, 0);
11106f32e7eSjoerg //         }
11206f32e7eSjoerg //
11306f32e7eSjoerg //         char *p;
11406f32e7eSjoerg //         char x[4096];
11506f32e7eSjoerg //         char y[4096];
11606f32e7eSjoerg //         if (var) {
11706f32e7eSjoerg //             p = x;
11806f32e7eSjoerg //         } else {
11906f32e7eSjoerg //             bar(y, 1);
12006f32e7eSjoerg //             p = y + 1024;
12106f32e7eSjoerg //         }
12206f32e7eSjoerg //     B:
12306f32e7eSjoerg //         bar(p, 2);
12406f32e7eSjoerg //     }
12506f32e7eSjoerg //
12606f32e7eSjoerg // Naively-compiled, this program would use 12k of stack space. However, the
12706f32e7eSjoerg // stack slot corresponding to `z` is always destroyed before either of the
12806f32e7eSjoerg // stack slots for `x` or `y` are used, and then `x` is only used if `var`
12906f32e7eSjoerg // is true, while `y` is only used if `var` is false. So in no time are 2
13006f32e7eSjoerg // of the stack slots used together, and therefore we can merge them,
13106f32e7eSjoerg // compiling the function using only a single 4k alloca:
13206f32e7eSjoerg //
13306f32e7eSjoerg //     void foo(bool var) { // equivalent
13406f32e7eSjoerg //         char x[4096];
13506f32e7eSjoerg //         char *p;
13606f32e7eSjoerg //         bar(x, 0);
13706f32e7eSjoerg //         if (var) {
13806f32e7eSjoerg //             p = x;
13906f32e7eSjoerg //         } else {
14006f32e7eSjoerg //             bar(x, 1);
14106f32e7eSjoerg //             p = x + 1024;
14206f32e7eSjoerg //         }
14306f32e7eSjoerg //         bar(p, 2);
14406f32e7eSjoerg //     }
14506f32e7eSjoerg //
14606f32e7eSjoerg // This is an important optimization if we want stack space to be under
14706f32e7eSjoerg // control in large functions, both open-coded ones and ones created by
14806f32e7eSjoerg // inlining.
14906f32e7eSjoerg //
15006f32e7eSjoerg // Implementation Notes:
15106f32e7eSjoerg // ---------------------
15206f32e7eSjoerg //
15306f32e7eSjoerg // An important part of the above reasoning is that `z` can't be accessed
15406f32e7eSjoerg // while the latter 2 calls to `bar` are running. This is justified because
15506f32e7eSjoerg // `z`'s lifetime is over after we exit from block `A:`, so any further
15606f32e7eSjoerg // accesses to it would be UB. The way we represent this information
15706f32e7eSjoerg // in LLVM is by having frontends delimit blocks with `lifetime.start`
15806f32e7eSjoerg // and `lifetime.end` intrinsics.
15906f32e7eSjoerg //
16006f32e7eSjoerg // The effect of these intrinsics seems to be as follows (maybe I should
16106f32e7eSjoerg // specify this in the reference?):
16206f32e7eSjoerg //
16306f32e7eSjoerg //   L1) at start, each stack-slot is marked as *out-of-scope*, unless no
16406f32e7eSjoerg //   lifetime intrinsic refers to that stack slot, in which case
16506f32e7eSjoerg //   it is marked as *in-scope*.
16606f32e7eSjoerg //   L2) on a `lifetime.start`, a stack slot is marked as *in-scope* and
16706f32e7eSjoerg //   the stack slot is overwritten with `undef`.
16806f32e7eSjoerg //   L3) on a `lifetime.end`, a stack slot is marked as *out-of-scope*.
16906f32e7eSjoerg //   L4) on function exit, all stack slots are marked as *out-of-scope*.
17006f32e7eSjoerg //   L5) `lifetime.end` is a no-op when called on a slot that is already
17106f32e7eSjoerg //   *out-of-scope*.
17206f32e7eSjoerg //   L6) memory accesses to *out-of-scope* stack slots are UB.
17306f32e7eSjoerg //   L7) when a stack-slot is marked as *out-of-scope*, all pointers to it
17406f32e7eSjoerg //   are invalidated, unless the slot is "degenerate". This is used to
17506f32e7eSjoerg //   justify not marking slots as in-use until the pointer to them is
17606f32e7eSjoerg //   used, but feels a bit hacky in the presence of things like LICM. See
17706f32e7eSjoerg //   the "Degenerate Slots" section for more details.
17806f32e7eSjoerg //
17906f32e7eSjoerg // Now, let's ground stack coloring on these rules. We'll define a slot
18006f32e7eSjoerg // as *in-use* at a (dynamic) point in execution if it either can be
18106f32e7eSjoerg // written to at that point, or if it has a live and non-undef content
18206f32e7eSjoerg // at that point.
18306f32e7eSjoerg //
18406f32e7eSjoerg // Obviously, slots that are never *in-use* together can be merged, and
18506f32e7eSjoerg // in our example `foo`, the slots for `x`, `y` and `z` are never
18606f32e7eSjoerg // in-use together (of course, sometimes slots that *are* in-use together
18706f32e7eSjoerg // might still be mergable, but we don't care about that here).
18806f32e7eSjoerg //
18906f32e7eSjoerg // In this implementation, we successively merge pairs of slots that are
19006f32e7eSjoerg // not *in-use* together. We could be smarter - for example, we could merge
19106f32e7eSjoerg // a single large slot with 2 small slots, or we could construct the
19206f32e7eSjoerg // interference graph and run a "smart" graph coloring algorithm, but with
19306f32e7eSjoerg // that aside, how do we find out whether a pair of slots might be *in-use*
19406f32e7eSjoerg // together?
19506f32e7eSjoerg //
19606f32e7eSjoerg // From our rules, we see that *out-of-scope* slots are never *in-use*,
19706f32e7eSjoerg // and from (L7) we see that "non-degenerate" slots remain non-*in-use*
19806f32e7eSjoerg // until their address is taken. Therefore, we can approximate slot activity
19906f32e7eSjoerg // using dataflow.
20006f32e7eSjoerg //
20106f32e7eSjoerg // A subtle point: naively, we might try to figure out which pairs of
20206f32e7eSjoerg // stack-slots interfere by propagating `S in-use` through the CFG for every
20306f32e7eSjoerg // stack-slot `S`, and having `S` and `T` interfere if there is a CFG point in
20406f32e7eSjoerg // which they are both *in-use*.
20506f32e7eSjoerg //
20606f32e7eSjoerg // That is sound, but overly conservative in some cases: in our (artificial)
20706f32e7eSjoerg // example `foo`, either `x` or `y` might be in use at the label `B:`, but
20806f32e7eSjoerg // as `x` is only in use if we came in from the `var` edge and `y` only
20906f32e7eSjoerg // if we came from the `!var` edge, they still can't be in use together.
21006f32e7eSjoerg // See PR32488 for an important real-life case.
21106f32e7eSjoerg //
21206f32e7eSjoerg // If we wanted to find all points of interference precisely, we could
21306f32e7eSjoerg // propagate `S in-use` and `S&T in-use` predicates through the CFG. That
21406f32e7eSjoerg // would be precise, but requires propagating `O(n^2)` dataflow facts.
21506f32e7eSjoerg //
21606f32e7eSjoerg // However, we aren't interested in the *set* of points of interference
21706f32e7eSjoerg // between 2 stack slots, only *whether* there *is* such a point. So we
21806f32e7eSjoerg // can rely on a little trick: for `S` and `T` to be in-use together,
21906f32e7eSjoerg // one of them needs to become in-use while the other is in-use (or
22006f32e7eSjoerg // they might both become in use simultaneously). We can check this
22106f32e7eSjoerg // by also keeping track of the points at which a stack slot might *start*
22206f32e7eSjoerg // being in-use.
22306f32e7eSjoerg //
22406f32e7eSjoerg // Exact first use:
22506f32e7eSjoerg // ----------------
22606f32e7eSjoerg //
22706f32e7eSjoerg // Consider the following motivating example:
22806f32e7eSjoerg //
22906f32e7eSjoerg //     int foo() {
23006f32e7eSjoerg //       char b1[1024], b2[1024];
23106f32e7eSjoerg //       if (...) {
23206f32e7eSjoerg //         char b3[1024];
23306f32e7eSjoerg //         <uses of b1, b3>;
23406f32e7eSjoerg //         return x;
23506f32e7eSjoerg //       } else {
23606f32e7eSjoerg //         char b4[1024], b5[1024];
23706f32e7eSjoerg //         <uses of b2, b4, b5>;
23806f32e7eSjoerg //         return y;
23906f32e7eSjoerg //       }
24006f32e7eSjoerg //     }
24106f32e7eSjoerg //
24206f32e7eSjoerg // In the code above, "b3" and "b4" are declared in distinct lexical
24306f32e7eSjoerg // scopes, meaning that it is easy to prove that they can share the
24406f32e7eSjoerg // same stack slot. Variables "b1" and "b2" are declared in the same
24506f32e7eSjoerg // scope, meaning that from a lexical point of view, their lifetimes
24606f32e7eSjoerg // overlap. From a control flow pointer of view, however, the two
24706f32e7eSjoerg // variables are accessed in disjoint regions of the CFG, thus it
24806f32e7eSjoerg // should be possible for them to share the same stack slot. An ideal
24906f32e7eSjoerg // stack allocation for the function above would look like:
25006f32e7eSjoerg //
25106f32e7eSjoerg //     slot 0: b1, b2
25206f32e7eSjoerg //     slot 1: b3, b4
25306f32e7eSjoerg //     slot 2: b5
25406f32e7eSjoerg //
25506f32e7eSjoerg // Achieving this allocation is tricky, however, due to the way
25606f32e7eSjoerg // lifetime markers are inserted. Here is a simplified view of the
25706f32e7eSjoerg // control flow graph for the code above:
25806f32e7eSjoerg //
25906f32e7eSjoerg //                +------  block 0 -------+
26006f32e7eSjoerg //               0| LIFETIME_START b1, b2 |
26106f32e7eSjoerg //               1| <test 'if' condition> |
26206f32e7eSjoerg //                +-----------------------+
26306f32e7eSjoerg //                   ./              \.
26406f32e7eSjoerg //   +------  block 1 -------+   +------  block 2 -------+
26506f32e7eSjoerg //  2| LIFETIME_START b3     |  5| LIFETIME_START b4, b5 |
26606f32e7eSjoerg //  3| <uses of b1, b3>      |  6| <uses of b2, b4, b5>  |
26706f32e7eSjoerg //  4| LIFETIME_END b3       |  7| LIFETIME_END b4, b5   |
26806f32e7eSjoerg //   +-----------------------+   +-----------------------+
26906f32e7eSjoerg //                   \.              /.
27006f32e7eSjoerg //                +------  block 3 -------+
27106f32e7eSjoerg //               8| <cleanupcode>         |
27206f32e7eSjoerg //               9| LIFETIME_END b1, b2   |
27306f32e7eSjoerg //              10| return                |
27406f32e7eSjoerg //                +-----------------------+
27506f32e7eSjoerg //
27606f32e7eSjoerg // If we create live intervals for the variables above strictly based
27706f32e7eSjoerg // on the lifetime markers, we'll get the set of intervals on the
27806f32e7eSjoerg // left. If we ignore the lifetime start markers and instead treat a
27906f32e7eSjoerg // variable's lifetime as beginning with the first reference to the
28006f32e7eSjoerg // var, then we get the intervals on the right.
28106f32e7eSjoerg //
28206f32e7eSjoerg //            LIFETIME_START      First Use
28306f32e7eSjoerg //     b1:    [0,9]               [3,4] [8,9]
28406f32e7eSjoerg //     b2:    [0,9]               [6,9]
28506f32e7eSjoerg //     b3:    [2,4]               [3,4]
28606f32e7eSjoerg //     b4:    [5,7]               [6,7]
28706f32e7eSjoerg //     b5:    [5,7]               [6,7]
28806f32e7eSjoerg //
28906f32e7eSjoerg // For the intervals on the left, the best we can do is overlap two
29006f32e7eSjoerg // variables (b3 and b4, for example); this gives us a stack size of
29106f32e7eSjoerg // 4*1024 bytes, not ideal. When treating first-use as the start of a
29206f32e7eSjoerg // lifetime, we can additionally overlap b1 and b5, giving us a 3*1024
29306f32e7eSjoerg // byte stack (better).
29406f32e7eSjoerg //
29506f32e7eSjoerg // Degenerate Slots:
29606f32e7eSjoerg // -----------------
29706f32e7eSjoerg //
29806f32e7eSjoerg // Relying entirely on first-use of stack slots is problematic,
29906f32e7eSjoerg // however, due to the fact that optimizations can sometimes migrate
30006f32e7eSjoerg // uses of a variable outside of its lifetime start/end region. Here
30106f32e7eSjoerg // is an example:
30206f32e7eSjoerg //
30306f32e7eSjoerg //     int bar() {
30406f32e7eSjoerg //       char b1[1024], b2[1024];
30506f32e7eSjoerg //       if (...) {
30606f32e7eSjoerg //         <uses of b2>
30706f32e7eSjoerg //         return y;
30806f32e7eSjoerg //       } else {
30906f32e7eSjoerg //         <uses of b1>
31006f32e7eSjoerg //         while (...) {
31106f32e7eSjoerg //           char b3[1024];
31206f32e7eSjoerg //           <uses of b3>
31306f32e7eSjoerg //         }
31406f32e7eSjoerg //       }
31506f32e7eSjoerg //     }
31606f32e7eSjoerg //
31706f32e7eSjoerg // Before optimization, the control flow graph for the code above
31806f32e7eSjoerg // might look like the following:
31906f32e7eSjoerg //
32006f32e7eSjoerg //                +------  block 0 -------+
32106f32e7eSjoerg //               0| LIFETIME_START b1, b2 |
32206f32e7eSjoerg //               1| <test 'if' condition> |
32306f32e7eSjoerg //                +-----------------------+
32406f32e7eSjoerg //                   ./              \.
32506f32e7eSjoerg //   +------  block 1 -------+    +------- block 2 -------+
32606f32e7eSjoerg //  2| <uses of b2>          |   3| <uses of b1>          |
32706f32e7eSjoerg //   +-----------------------+    +-----------------------+
32806f32e7eSjoerg //              |                            |
32906f32e7eSjoerg //              |                 +------- block 3 -------+ <-\.
33006f32e7eSjoerg //              |                4| <while condition>     |    |
33106f32e7eSjoerg //              |                 +-----------------------+    |
33206f32e7eSjoerg //              |               /          |                   |
33306f32e7eSjoerg //              |              /  +------- block 4 -------+
33406f32e7eSjoerg //              \             /  5| LIFETIME_START b3     |    |
33506f32e7eSjoerg //               \           /   6| <uses of b3>          |    |
33606f32e7eSjoerg //                \         /    7| LIFETIME_END b3       |    |
33706f32e7eSjoerg //                 \        |    +------------------------+    |
33806f32e7eSjoerg //                  \       |                 \                /
33906f32e7eSjoerg //                +------  block 5 -----+      \---------------
34006f32e7eSjoerg //               8| <cleanupcode>       |
34106f32e7eSjoerg //               9| LIFETIME_END b1, b2 |
34206f32e7eSjoerg //              10| return              |
34306f32e7eSjoerg //                +---------------------+
34406f32e7eSjoerg //
34506f32e7eSjoerg // During optimization, however, it can happen that an instruction
34606f32e7eSjoerg // computing an address in "b3" (for example, a loop-invariant GEP) is
34706f32e7eSjoerg // hoisted up out of the loop from block 4 to block 2.  [Note that
34806f32e7eSjoerg // this is not an actual load from the stack, only an instruction that
34906f32e7eSjoerg // computes the address to be loaded]. If this happens, there is now a
35006f32e7eSjoerg // path leading from the first use of b3 to the return instruction
35106f32e7eSjoerg // that does not encounter the b3 LIFETIME_END, hence b3's lifetime is
35206f32e7eSjoerg // now larger than if we were computing live intervals strictly based
35306f32e7eSjoerg // on lifetime markers. In the example above, this lengthened lifetime
35406f32e7eSjoerg // would mean that it would appear illegal to overlap b3 with b2.
35506f32e7eSjoerg //
35606f32e7eSjoerg // To deal with this such cases, the code in ::collectMarkers() below
35706f32e7eSjoerg // tries to identify "degenerate" slots -- those slots where on a single
35806f32e7eSjoerg // forward pass through the CFG we encounter a first reference to slot
35906f32e7eSjoerg // K before we hit the slot K lifetime start marker. For such slots,
36006f32e7eSjoerg // we fall back on using the lifetime start marker as the beginning of
36106f32e7eSjoerg // the variable's lifetime.  NB: with this implementation, slots can
36206f32e7eSjoerg // appear degenerate in cases where there is unstructured control flow:
36306f32e7eSjoerg //
36406f32e7eSjoerg //    if (q) goto mid;
36506f32e7eSjoerg //    if (x > 9) {
36606f32e7eSjoerg //         int b[100];
36706f32e7eSjoerg //         memcpy(&b[0], ...);
36806f32e7eSjoerg //    mid: b[k] = ...;
36906f32e7eSjoerg //         abc(&b);
37006f32e7eSjoerg //    }
37106f32e7eSjoerg //
37206f32e7eSjoerg // If in RPO ordering chosen to walk the CFG  we happen to visit the b[k]
37306f32e7eSjoerg // before visiting the memcpy block (which will contain the lifetime start
37406f32e7eSjoerg // for "b" then it will appear that 'b' has a degenerate lifetime.
37506f32e7eSjoerg //
376*da58b97aSjoerg // Handle Windows Exception with LifetimeStartOnFirstUse:
377*da58b97aSjoerg // -----------------
378*da58b97aSjoerg //
379*da58b97aSjoerg // There was a bug for using LifetimeStartOnFirstUse in win32.
380*da58b97aSjoerg // class Type1 {
381*da58b97aSjoerg // ...
382*da58b97aSjoerg // ~Type1(){ write memory;}
383*da58b97aSjoerg // }
384*da58b97aSjoerg // ...
385*da58b97aSjoerg // try{
386*da58b97aSjoerg // Type1 V
387*da58b97aSjoerg // ...
388*da58b97aSjoerg // } catch (Type2 X){
389*da58b97aSjoerg // ...
390*da58b97aSjoerg // }
391*da58b97aSjoerg // For variable X in catch(X), we put point pX=&(&X) into ConservativeSlots
392*da58b97aSjoerg // to prevent using LifetimeStartOnFirstUse. Because pX may merged with
393*da58b97aSjoerg // object V which may call destructor after implicitly writing pX. All these
394*da58b97aSjoerg // are done in C++ EH runtime libs (through CxxThrowException), and can't
395*da58b97aSjoerg // obviously check it in IR level.
396*da58b97aSjoerg //
397*da58b97aSjoerg // The loader of pX, without obvious writing IR, is usually the first LOAD MI
398*da58b97aSjoerg // in EHPad, Some like:
399*da58b97aSjoerg // bb.x.catch.i (landing-pad, ehfunclet-entry):
400*da58b97aSjoerg // ; predecessors: %bb...
401*da58b97aSjoerg //   successors: %bb...
402*da58b97aSjoerg //  %n:gr32 = MOV32rm %stack.pX ...
403*da58b97aSjoerg //  ...
404*da58b97aSjoerg // The Type2** %stack.pX will only be written in EH runtime libs, so we
405*da58b97aSjoerg // check the StoreSlots to screen it out.
40606f32e7eSjoerg 
40706f32e7eSjoerg namespace {
40806f32e7eSjoerg 
40906f32e7eSjoerg /// StackColoring - A machine pass for merging disjoint stack allocations,
41006f32e7eSjoerg /// marked by the LIFETIME_START and LIFETIME_END pseudo instructions.
41106f32e7eSjoerg class StackColoring : public MachineFunctionPass {
41206f32e7eSjoerg   MachineFrameInfo *MFI;
41306f32e7eSjoerg   MachineFunction *MF;
41406f32e7eSjoerg 
41506f32e7eSjoerg   /// A class representing liveness information for a single basic block.
41606f32e7eSjoerg   /// Each bit in the BitVector represents the liveness property
41706f32e7eSjoerg   /// for a different stack slot.
41806f32e7eSjoerg   struct BlockLifetimeInfo {
41906f32e7eSjoerg     /// Which slots BEGINs in each basic block.
42006f32e7eSjoerg     BitVector Begin;
42106f32e7eSjoerg 
42206f32e7eSjoerg     /// Which slots ENDs in each basic block.
42306f32e7eSjoerg     BitVector End;
42406f32e7eSjoerg 
42506f32e7eSjoerg     /// Which slots are marked as LIVE_IN, coming into each basic block.
42606f32e7eSjoerg     BitVector LiveIn;
42706f32e7eSjoerg 
42806f32e7eSjoerg     /// Which slots are marked as LIVE_OUT, coming out of each basic block.
42906f32e7eSjoerg     BitVector LiveOut;
43006f32e7eSjoerg   };
43106f32e7eSjoerg 
43206f32e7eSjoerg   /// Maps active slots (per bit) for each basic block.
43306f32e7eSjoerg   using LivenessMap = DenseMap<const MachineBasicBlock *, BlockLifetimeInfo>;
43406f32e7eSjoerg   LivenessMap BlockLiveness;
43506f32e7eSjoerg 
43606f32e7eSjoerg   /// Maps serial numbers to basic blocks.
43706f32e7eSjoerg   DenseMap<const MachineBasicBlock *, int> BasicBlocks;
43806f32e7eSjoerg 
43906f32e7eSjoerg   /// Maps basic blocks to a serial number.
44006f32e7eSjoerg   SmallVector<const MachineBasicBlock *, 8> BasicBlockNumbering;
44106f32e7eSjoerg 
44206f32e7eSjoerg   /// Maps slots to their use interval. Outside of this interval, slots
44306f32e7eSjoerg   /// values are either dead or `undef` and they will not be written to.
44406f32e7eSjoerg   SmallVector<std::unique_ptr<LiveInterval>, 16> Intervals;
44506f32e7eSjoerg 
44606f32e7eSjoerg   /// Maps slots to the points where they can become in-use.
44706f32e7eSjoerg   SmallVector<SmallVector<SlotIndex, 4>, 16> LiveStarts;
44806f32e7eSjoerg 
44906f32e7eSjoerg   /// VNInfo is used for the construction of LiveIntervals.
45006f32e7eSjoerg   VNInfo::Allocator VNInfoAllocator;
45106f32e7eSjoerg 
45206f32e7eSjoerg   /// SlotIndex analysis object.
45306f32e7eSjoerg   SlotIndexes *Indexes;
45406f32e7eSjoerg 
45506f32e7eSjoerg   /// The list of lifetime markers found. These markers are to be removed
45606f32e7eSjoerg   /// once the coloring is done.
45706f32e7eSjoerg   SmallVector<MachineInstr*, 8> Markers;
45806f32e7eSjoerg 
45906f32e7eSjoerg   /// Record the FI slots for which we have seen some sort of
46006f32e7eSjoerg   /// lifetime marker (either start or end).
46106f32e7eSjoerg   BitVector InterestingSlots;
46206f32e7eSjoerg 
46306f32e7eSjoerg   /// FI slots that need to be handled conservatively (for these
46406f32e7eSjoerg   /// slots lifetime-start-on-first-use is disabled).
46506f32e7eSjoerg   BitVector ConservativeSlots;
46606f32e7eSjoerg 
467*da58b97aSjoerg   /// Record the FI slots referenced by a 'may write to memory'.
468*da58b97aSjoerg   BitVector StoreSlots;
469*da58b97aSjoerg 
47006f32e7eSjoerg   /// Number of iterations taken during data flow analysis.
47106f32e7eSjoerg   unsigned NumIterations;
47206f32e7eSjoerg 
47306f32e7eSjoerg public:
47406f32e7eSjoerg   static char ID;
47506f32e7eSjoerg 
StackColoring()47606f32e7eSjoerg   StackColoring() : MachineFunctionPass(ID) {
47706f32e7eSjoerg     initializeStackColoringPass(*PassRegistry::getPassRegistry());
47806f32e7eSjoerg   }
47906f32e7eSjoerg 
48006f32e7eSjoerg   void getAnalysisUsage(AnalysisUsage &AU) const override;
48106f32e7eSjoerg   bool runOnMachineFunction(MachineFunction &Func) override;
48206f32e7eSjoerg 
48306f32e7eSjoerg private:
48406f32e7eSjoerg   /// Used in collectMarkers
48506f32e7eSjoerg   using BlockBitVecMap = DenseMap<const MachineBasicBlock *, BitVector>;
48606f32e7eSjoerg 
48706f32e7eSjoerg   /// Debug.
48806f32e7eSjoerg   void dump() const;
48906f32e7eSjoerg   void dumpIntervals() const;
49006f32e7eSjoerg   void dumpBB(MachineBasicBlock *MBB) const;
49106f32e7eSjoerg   void dumpBV(const char *tag, const BitVector &BV) const;
49206f32e7eSjoerg 
49306f32e7eSjoerg   /// Removes all of the lifetime marker instructions from the function.
49406f32e7eSjoerg   /// \returns true if any markers were removed.
49506f32e7eSjoerg   bool removeAllMarkers();
49606f32e7eSjoerg 
49706f32e7eSjoerg   /// Scan the machine function and find all of the lifetime markers.
49806f32e7eSjoerg   /// Record the findings in the BEGIN and END vectors.
49906f32e7eSjoerg   /// \returns the number of markers found.
50006f32e7eSjoerg   unsigned collectMarkers(unsigned NumSlot);
50106f32e7eSjoerg 
50206f32e7eSjoerg   /// Perform the dataflow calculation and calculate the lifetime for each of
50306f32e7eSjoerg   /// the slots, based on the BEGIN/END vectors. Set the LifetimeLIVE_IN and
50406f32e7eSjoerg   /// LifetimeLIVE_OUT maps that represent which stack slots are live coming
50506f32e7eSjoerg   /// in and out blocks.
50606f32e7eSjoerg   void calculateLocalLiveness();
50706f32e7eSjoerg 
50806f32e7eSjoerg   /// Returns TRUE if we're using the first-use-begins-lifetime method for
50906f32e7eSjoerg   /// this slot (if FALSE, then the start marker is treated as start of lifetime).
applyFirstUse(int Slot)51006f32e7eSjoerg   bool applyFirstUse(int Slot) {
51106f32e7eSjoerg     if (!LifetimeStartOnFirstUse || ProtectFromEscapedAllocas)
51206f32e7eSjoerg       return false;
51306f32e7eSjoerg     if (ConservativeSlots.test(Slot))
51406f32e7eSjoerg       return false;
51506f32e7eSjoerg     return true;
51606f32e7eSjoerg   }
51706f32e7eSjoerg 
51806f32e7eSjoerg   /// Examines the specified instruction and returns TRUE if the instruction
51906f32e7eSjoerg   /// represents the start or end of an interesting lifetime. The slot or slots
52006f32e7eSjoerg   /// starting or ending are added to the vector "slots" and "isStart" is set
52106f32e7eSjoerg   /// accordingly.
52206f32e7eSjoerg   /// \returns True if inst contains a lifetime start or end
52306f32e7eSjoerg   bool isLifetimeStartOrEnd(const MachineInstr &MI,
52406f32e7eSjoerg                             SmallVector<int, 4> &slots,
52506f32e7eSjoerg                             bool &isStart);
52606f32e7eSjoerg 
52706f32e7eSjoerg   /// Construct the LiveIntervals for the slots.
52806f32e7eSjoerg   void calculateLiveIntervals(unsigned NumSlots);
52906f32e7eSjoerg 
53006f32e7eSjoerg   /// Go over the machine function and change instructions which use stack
53106f32e7eSjoerg   /// slots to use the joint slots.
53206f32e7eSjoerg   void remapInstructions(DenseMap<int, int> &SlotRemap);
53306f32e7eSjoerg 
53406f32e7eSjoerg   /// The input program may contain instructions which are not inside lifetime
53506f32e7eSjoerg   /// markers. This can happen due to a bug in the compiler or due to a bug in
53606f32e7eSjoerg   /// user code (for example, returning a reference to a local variable).
53706f32e7eSjoerg   /// This procedure checks all of the instructions in the function and
53806f32e7eSjoerg   /// invalidates lifetime ranges which do not contain all of the instructions
53906f32e7eSjoerg   /// which access that frame slot.
54006f32e7eSjoerg   void removeInvalidSlotRanges();
54106f32e7eSjoerg 
54206f32e7eSjoerg   /// Map entries which point to other entries to their destination.
54306f32e7eSjoerg   ///   A->B->C becomes A->C.
54406f32e7eSjoerg   void expungeSlotMap(DenseMap<int, int> &SlotRemap, unsigned NumSlots);
54506f32e7eSjoerg };
54606f32e7eSjoerg 
54706f32e7eSjoerg } // end anonymous namespace
54806f32e7eSjoerg 
54906f32e7eSjoerg char StackColoring::ID = 0;
55006f32e7eSjoerg 
55106f32e7eSjoerg char &llvm::StackColoringID = StackColoring::ID;
55206f32e7eSjoerg 
55306f32e7eSjoerg INITIALIZE_PASS_BEGIN(StackColoring, DEBUG_TYPE,
55406f32e7eSjoerg                       "Merge disjoint stack slots", false, false)
INITIALIZE_PASS_DEPENDENCY(SlotIndexes)55506f32e7eSjoerg INITIALIZE_PASS_DEPENDENCY(SlotIndexes)
55606f32e7eSjoerg INITIALIZE_PASS_END(StackColoring, DEBUG_TYPE,
55706f32e7eSjoerg                     "Merge disjoint stack slots", false, false)
55806f32e7eSjoerg 
55906f32e7eSjoerg void StackColoring::getAnalysisUsage(AnalysisUsage &AU) const {
56006f32e7eSjoerg   AU.addRequired<SlotIndexes>();
56106f32e7eSjoerg   MachineFunctionPass::getAnalysisUsage(AU);
56206f32e7eSjoerg }
56306f32e7eSjoerg 
56406f32e7eSjoerg #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dumpBV(const char * tag,const BitVector & BV) const56506f32e7eSjoerg LLVM_DUMP_METHOD void StackColoring::dumpBV(const char *tag,
56606f32e7eSjoerg                                             const BitVector &BV) const {
56706f32e7eSjoerg   dbgs() << tag << " : { ";
56806f32e7eSjoerg   for (unsigned I = 0, E = BV.size(); I != E; ++I)
56906f32e7eSjoerg     dbgs() << BV.test(I) << " ";
57006f32e7eSjoerg   dbgs() << "}\n";
57106f32e7eSjoerg }
57206f32e7eSjoerg 
dumpBB(MachineBasicBlock * MBB) const57306f32e7eSjoerg LLVM_DUMP_METHOD void StackColoring::dumpBB(MachineBasicBlock *MBB) const {
57406f32e7eSjoerg   LivenessMap::const_iterator BI = BlockLiveness.find(MBB);
57506f32e7eSjoerg   assert(BI != BlockLiveness.end() && "Block not found");
57606f32e7eSjoerg   const BlockLifetimeInfo &BlockInfo = BI->second;
57706f32e7eSjoerg 
57806f32e7eSjoerg   dumpBV("BEGIN", BlockInfo.Begin);
57906f32e7eSjoerg   dumpBV("END", BlockInfo.End);
58006f32e7eSjoerg   dumpBV("LIVE_IN", BlockInfo.LiveIn);
58106f32e7eSjoerg   dumpBV("LIVE_OUT", BlockInfo.LiveOut);
58206f32e7eSjoerg }
58306f32e7eSjoerg 
dump() const58406f32e7eSjoerg LLVM_DUMP_METHOD void StackColoring::dump() const {
58506f32e7eSjoerg   for (MachineBasicBlock *MBB : depth_first(MF)) {
58606f32e7eSjoerg     dbgs() << "Inspecting block #" << MBB->getNumber() << " ["
58706f32e7eSjoerg            << MBB->getName() << "]\n";
58806f32e7eSjoerg     dumpBB(MBB);
58906f32e7eSjoerg   }
59006f32e7eSjoerg }
59106f32e7eSjoerg 
dumpIntervals() const59206f32e7eSjoerg LLVM_DUMP_METHOD void StackColoring::dumpIntervals() const {
59306f32e7eSjoerg   for (unsigned I = 0, E = Intervals.size(); I != E; ++I) {
59406f32e7eSjoerg     dbgs() << "Interval[" << I << "]:\n";
59506f32e7eSjoerg     Intervals[I]->dump();
59606f32e7eSjoerg   }
59706f32e7eSjoerg }
59806f32e7eSjoerg #endif
59906f32e7eSjoerg 
getStartOrEndSlot(const MachineInstr & MI)60006f32e7eSjoerg static inline int getStartOrEndSlot(const MachineInstr &MI)
60106f32e7eSjoerg {
60206f32e7eSjoerg   assert((MI.getOpcode() == TargetOpcode::LIFETIME_START ||
60306f32e7eSjoerg           MI.getOpcode() == TargetOpcode::LIFETIME_END) &&
60406f32e7eSjoerg          "Expected LIFETIME_START or LIFETIME_END op");
60506f32e7eSjoerg   const MachineOperand &MO = MI.getOperand(0);
60606f32e7eSjoerg   int Slot = MO.getIndex();
60706f32e7eSjoerg   if (Slot >= 0)
60806f32e7eSjoerg     return Slot;
60906f32e7eSjoerg   return -1;
61006f32e7eSjoerg }
61106f32e7eSjoerg 
61206f32e7eSjoerg // At the moment the only way to end a variable lifetime is with
61306f32e7eSjoerg // a VARIABLE_LIFETIME op (which can't contain a start). If things
61406f32e7eSjoerg // change and the IR allows for a single inst that both begins
61506f32e7eSjoerg // and ends lifetime(s), this interface will need to be reworked.
isLifetimeStartOrEnd(const MachineInstr & MI,SmallVector<int,4> & slots,bool & isStart)61606f32e7eSjoerg bool StackColoring::isLifetimeStartOrEnd(const MachineInstr &MI,
61706f32e7eSjoerg                                          SmallVector<int, 4> &slots,
61806f32e7eSjoerg                                          bool &isStart) {
61906f32e7eSjoerg   if (MI.getOpcode() == TargetOpcode::LIFETIME_START ||
62006f32e7eSjoerg       MI.getOpcode() == TargetOpcode::LIFETIME_END) {
62106f32e7eSjoerg     int Slot = getStartOrEndSlot(MI);
62206f32e7eSjoerg     if (Slot < 0)
62306f32e7eSjoerg       return false;
62406f32e7eSjoerg     if (!InterestingSlots.test(Slot))
62506f32e7eSjoerg       return false;
62606f32e7eSjoerg     slots.push_back(Slot);
62706f32e7eSjoerg     if (MI.getOpcode() == TargetOpcode::LIFETIME_END) {
62806f32e7eSjoerg       isStart = false;
62906f32e7eSjoerg       return true;
63006f32e7eSjoerg     }
63106f32e7eSjoerg     if (!applyFirstUse(Slot)) {
63206f32e7eSjoerg       isStart = true;
63306f32e7eSjoerg       return true;
63406f32e7eSjoerg     }
63506f32e7eSjoerg   } else if (LifetimeStartOnFirstUse && !ProtectFromEscapedAllocas) {
63606f32e7eSjoerg     if (!MI.isDebugInstr()) {
63706f32e7eSjoerg       bool found = false;
63806f32e7eSjoerg       for (const MachineOperand &MO : MI.operands()) {
63906f32e7eSjoerg         if (!MO.isFI())
64006f32e7eSjoerg           continue;
64106f32e7eSjoerg         int Slot = MO.getIndex();
64206f32e7eSjoerg         if (Slot<0)
64306f32e7eSjoerg           continue;
64406f32e7eSjoerg         if (InterestingSlots.test(Slot) && applyFirstUse(Slot)) {
64506f32e7eSjoerg           slots.push_back(Slot);
64606f32e7eSjoerg           found = true;
64706f32e7eSjoerg         }
64806f32e7eSjoerg       }
64906f32e7eSjoerg       if (found) {
65006f32e7eSjoerg         isStart = true;
65106f32e7eSjoerg         return true;
65206f32e7eSjoerg       }
65306f32e7eSjoerg     }
65406f32e7eSjoerg   }
65506f32e7eSjoerg   return false;
65606f32e7eSjoerg }
65706f32e7eSjoerg 
collectMarkers(unsigned NumSlot)65806f32e7eSjoerg unsigned StackColoring::collectMarkers(unsigned NumSlot) {
65906f32e7eSjoerg   unsigned MarkersFound = 0;
66006f32e7eSjoerg   BlockBitVecMap SeenStartMap;
66106f32e7eSjoerg   InterestingSlots.clear();
66206f32e7eSjoerg   InterestingSlots.resize(NumSlot);
66306f32e7eSjoerg   ConservativeSlots.clear();
66406f32e7eSjoerg   ConservativeSlots.resize(NumSlot);
665*da58b97aSjoerg   StoreSlots.clear();
666*da58b97aSjoerg   StoreSlots.resize(NumSlot);
66706f32e7eSjoerg 
66806f32e7eSjoerg   // number of start and end lifetime ops for each slot
66906f32e7eSjoerg   SmallVector<int, 8> NumStartLifetimes(NumSlot, 0);
67006f32e7eSjoerg   SmallVector<int, 8> NumEndLifetimes(NumSlot, 0);
671*da58b97aSjoerg   SmallVector<int, 8> NumLoadInCatchPad(NumSlot, 0);
67206f32e7eSjoerg 
67306f32e7eSjoerg   // Step 1: collect markers and populate the "InterestingSlots"
67406f32e7eSjoerg   // and "ConservativeSlots" sets.
67506f32e7eSjoerg   for (MachineBasicBlock *MBB : depth_first(MF)) {
67606f32e7eSjoerg     // Compute the set of slots for which we've seen a START marker but have
67706f32e7eSjoerg     // not yet seen an END marker at this point in the walk (e.g. on entry
67806f32e7eSjoerg     // to this bb).
67906f32e7eSjoerg     BitVector BetweenStartEnd;
68006f32e7eSjoerg     BetweenStartEnd.resize(NumSlot);
681*da58b97aSjoerg     for (const MachineBasicBlock *Pred : MBB->predecessors()) {
682*da58b97aSjoerg       BlockBitVecMap::const_iterator I = SeenStartMap.find(Pred);
68306f32e7eSjoerg       if (I != SeenStartMap.end()) {
68406f32e7eSjoerg         BetweenStartEnd |= I->second;
68506f32e7eSjoerg       }
68606f32e7eSjoerg     }
68706f32e7eSjoerg 
68806f32e7eSjoerg     // Walk the instructions in the block to look for start/end ops.
68906f32e7eSjoerg     for (MachineInstr &MI : *MBB) {
69006f32e7eSjoerg       if (MI.getOpcode() == TargetOpcode::LIFETIME_START ||
69106f32e7eSjoerg           MI.getOpcode() == TargetOpcode::LIFETIME_END) {
69206f32e7eSjoerg         int Slot = getStartOrEndSlot(MI);
69306f32e7eSjoerg         if (Slot < 0)
69406f32e7eSjoerg           continue;
69506f32e7eSjoerg         InterestingSlots.set(Slot);
69606f32e7eSjoerg         if (MI.getOpcode() == TargetOpcode::LIFETIME_START) {
69706f32e7eSjoerg           BetweenStartEnd.set(Slot);
69806f32e7eSjoerg           NumStartLifetimes[Slot] += 1;
69906f32e7eSjoerg         } else {
70006f32e7eSjoerg           BetweenStartEnd.reset(Slot);
70106f32e7eSjoerg           NumEndLifetimes[Slot] += 1;
70206f32e7eSjoerg         }
70306f32e7eSjoerg         const AllocaInst *Allocation = MFI->getObjectAllocation(Slot);
70406f32e7eSjoerg         if (Allocation) {
70506f32e7eSjoerg           LLVM_DEBUG(dbgs() << "Found a lifetime ");
70606f32e7eSjoerg           LLVM_DEBUG(dbgs() << (MI.getOpcode() == TargetOpcode::LIFETIME_START
70706f32e7eSjoerg                                     ? "start"
70806f32e7eSjoerg                                     : "end"));
70906f32e7eSjoerg           LLVM_DEBUG(dbgs() << " marker for slot #" << Slot);
71006f32e7eSjoerg           LLVM_DEBUG(dbgs()
71106f32e7eSjoerg                      << " with allocation: " << Allocation->getName() << "\n");
71206f32e7eSjoerg         }
71306f32e7eSjoerg         Markers.push_back(&MI);
71406f32e7eSjoerg         MarkersFound += 1;
71506f32e7eSjoerg       } else {
71606f32e7eSjoerg         for (const MachineOperand &MO : MI.operands()) {
71706f32e7eSjoerg           if (!MO.isFI())
71806f32e7eSjoerg             continue;
71906f32e7eSjoerg           int Slot = MO.getIndex();
72006f32e7eSjoerg           if (Slot < 0)
72106f32e7eSjoerg             continue;
72206f32e7eSjoerg           if (! BetweenStartEnd.test(Slot)) {
72306f32e7eSjoerg             ConservativeSlots.set(Slot);
72406f32e7eSjoerg           }
725*da58b97aSjoerg           // Here we check the StoreSlots to screen catch point out. For more
726*da58b97aSjoerg           // information, please refer "Handle Windows Exception with
727*da58b97aSjoerg           // LifetimeStartOnFirstUse" at the head of this file.
728*da58b97aSjoerg           if (MI.mayStore())
729*da58b97aSjoerg             StoreSlots.set(Slot);
730*da58b97aSjoerg           if (MF->getWinEHFuncInfo() && MBB->isEHPad() && MI.mayLoad())
731*da58b97aSjoerg             NumLoadInCatchPad[Slot] += 1;
73206f32e7eSjoerg         }
73306f32e7eSjoerg       }
73406f32e7eSjoerg     }
73506f32e7eSjoerg     BitVector &SeenStart = SeenStartMap[MBB];
73606f32e7eSjoerg     SeenStart |= BetweenStartEnd;
73706f32e7eSjoerg   }
73806f32e7eSjoerg   if (!MarkersFound) {
73906f32e7eSjoerg     return 0;
74006f32e7eSjoerg   }
74106f32e7eSjoerg 
742*da58b97aSjoerg   // 1) PR27903: slots with multiple start or end lifetime ops are not
74306f32e7eSjoerg   // safe to enable for "lifetime-start-on-first-use".
744*da58b97aSjoerg   // 2) And also not safe for variable X in catch(X) in windows.
745*da58b97aSjoerg   for (unsigned slot = 0; slot < NumSlot; ++slot) {
746*da58b97aSjoerg     if (NumStartLifetimes[slot] > 1 || NumEndLifetimes[slot] > 1 ||
747*da58b97aSjoerg         (NumLoadInCatchPad[slot] > 1 && !StoreSlots.test(slot)))
74806f32e7eSjoerg       ConservativeSlots.set(slot);
749*da58b97aSjoerg   }
75006f32e7eSjoerg   LLVM_DEBUG(dumpBV("Conservative slots", ConservativeSlots));
75106f32e7eSjoerg 
75206f32e7eSjoerg   // Step 2: compute begin/end sets for each block
75306f32e7eSjoerg 
75406f32e7eSjoerg   // NOTE: We use a depth-first iteration to ensure that we obtain a
75506f32e7eSjoerg   // deterministic numbering.
75606f32e7eSjoerg   for (MachineBasicBlock *MBB : depth_first(MF)) {
75706f32e7eSjoerg     // Assign a serial number to this basic block.
75806f32e7eSjoerg     BasicBlocks[MBB] = BasicBlockNumbering.size();
75906f32e7eSjoerg     BasicBlockNumbering.push_back(MBB);
76006f32e7eSjoerg 
76106f32e7eSjoerg     // Keep a reference to avoid repeated lookups.
76206f32e7eSjoerg     BlockLifetimeInfo &BlockInfo = BlockLiveness[MBB];
76306f32e7eSjoerg 
76406f32e7eSjoerg     BlockInfo.Begin.resize(NumSlot);
76506f32e7eSjoerg     BlockInfo.End.resize(NumSlot);
76606f32e7eSjoerg 
76706f32e7eSjoerg     SmallVector<int, 4> slots;
76806f32e7eSjoerg     for (MachineInstr &MI : *MBB) {
76906f32e7eSjoerg       bool isStart = false;
77006f32e7eSjoerg       slots.clear();
77106f32e7eSjoerg       if (isLifetimeStartOrEnd(MI, slots, isStart)) {
77206f32e7eSjoerg         if (!isStart) {
77306f32e7eSjoerg           assert(slots.size() == 1 && "unexpected: MI ends multiple slots");
77406f32e7eSjoerg           int Slot = slots[0];
77506f32e7eSjoerg           if (BlockInfo.Begin.test(Slot)) {
77606f32e7eSjoerg             BlockInfo.Begin.reset(Slot);
77706f32e7eSjoerg           }
77806f32e7eSjoerg           BlockInfo.End.set(Slot);
77906f32e7eSjoerg         } else {
78006f32e7eSjoerg           for (auto Slot : slots) {
78106f32e7eSjoerg             LLVM_DEBUG(dbgs() << "Found a use of slot #" << Slot);
78206f32e7eSjoerg             LLVM_DEBUG(dbgs()
78306f32e7eSjoerg                        << " at " << printMBBReference(*MBB) << " index ");
78406f32e7eSjoerg             LLVM_DEBUG(Indexes->getInstructionIndex(MI).print(dbgs()));
78506f32e7eSjoerg             const AllocaInst *Allocation = MFI->getObjectAllocation(Slot);
78606f32e7eSjoerg             if (Allocation) {
78706f32e7eSjoerg               LLVM_DEBUG(dbgs()
78806f32e7eSjoerg                          << " with allocation: " << Allocation->getName());
78906f32e7eSjoerg             }
79006f32e7eSjoerg             LLVM_DEBUG(dbgs() << "\n");
79106f32e7eSjoerg             if (BlockInfo.End.test(Slot)) {
79206f32e7eSjoerg               BlockInfo.End.reset(Slot);
79306f32e7eSjoerg             }
79406f32e7eSjoerg             BlockInfo.Begin.set(Slot);
79506f32e7eSjoerg           }
79606f32e7eSjoerg         }
79706f32e7eSjoerg       }
79806f32e7eSjoerg     }
79906f32e7eSjoerg   }
80006f32e7eSjoerg 
80106f32e7eSjoerg   // Update statistics.
80206f32e7eSjoerg   NumMarkerSeen += MarkersFound;
80306f32e7eSjoerg   return MarkersFound;
80406f32e7eSjoerg }
80506f32e7eSjoerg 
calculateLocalLiveness()80606f32e7eSjoerg void StackColoring::calculateLocalLiveness() {
80706f32e7eSjoerg   unsigned NumIters = 0;
80806f32e7eSjoerg   bool changed = true;
80906f32e7eSjoerg   while (changed) {
81006f32e7eSjoerg     changed = false;
81106f32e7eSjoerg     ++NumIters;
81206f32e7eSjoerg 
81306f32e7eSjoerg     for (const MachineBasicBlock *BB : BasicBlockNumbering) {
81406f32e7eSjoerg       // Use an iterator to avoid repeated lookups.
81506f32e7eSjoerg       LivenessMap::iterator BI = BlockLiveness.find(BB);
81606f32e7eSjoerg       assert(BI != BlockLiveness.end() && "Block not found");
81706f32e7eSjoerg       BlockLifetimeInfo &BlockInfo = BI->second;
81806f32e7eSjoerg 
81906f32e7eSjoerg       // Compute LiveIn by unioning together the LiveOut sets of all preds.
82006f32e7eSjoerg       BitVector LocalLiveIn;
821*da58b97aSjoerg       for (MachineBasicBlock *Pred : BB->predecessors()) {
822*da58b97aSjoerg         LivenessMap::const_iterator I = BlockLiveness.find(Pred);
82306f32e7eSjoerg         // PR37130: transformations prior to stack coloring can
82406f32e7eSjoerg         // sometimes leave behind statically unreachable blocks; these
82506f32e7eSjoerg         // can be safely skipped here.
82606f32e7eSjoerg         if (I != BlockLiveness.end())
82706f32e7eSjoerg           LocalLiveIn |= I->second.LiveOut;
82806f32e7eSjoerg       }
82906f32e7eSjoerg 
83006f32e7eSjoerg       // Compute LiveOut by subtracting out lifetimes that end in this
83106f32e7eSjoerg       // block, then adding in lifetimes that begin in this block.  If
83206f32e7eSjoerg       // we have both BEGIN and END markers in the same basic block
83306f32e7eSjoerg       // then we know that the BEGIN marker comes after the END,
83406f32e7eSjoerg       // because we already handle the case where the BEGIN comes
83506f32e7eSjoerg       // before the END when collecting the markers (and building the
83606f32e7eSjoerg       // BEGIN/END vectors).
83706f32e7eSjoerg       BitVector LocalLiveOut = LocalLiveIn;
83806f32e7eSjoerg       LocalLiveOut.reset(BlockInfo.End);
83906f32e7eSjoerg       LocalLiveOut |= BlockInfo.Begin;
84006f32e7eSjoerg 
84106f32e7eSjoerg       // Update block LiveIn set, noting whether it has changed.
84206f32e7eSjoerg       if (LocalLiveIn.test(BlockInfo.LiveIn)) {
84306f32e7eSjoerg         changed = true;
84406f32e7eSjoerg         BlockInfo.LiveIn |= LocalLiveIn;
84506f32e7eSjoerg       }
84606f32e7eSjoerg 
84706f32e7eSjoerg       // Update block LiveOut set, noting whether it has changed.
84806f32e7eSjoerg       if (LocalLiveOut.test(BlockInfo.LiveOut)) {
84906f32e7eSjoerg         changed = true;
85006f32e7eSjoerg         BlockInfo.LiveOut |= LocalLiveOut;
85106f32e7eSjoerg       }
85206f32e7eSjoerg     }
85306f32e7eSjoerg   } // while changed.
85406f32e7eSjoerg 
85506f32e7eSjoerg   NumIterations = NumIters;
85606f32e7eSjoerg }
85706f32e7eSjoerg 
calculateLiveIntervals(unsigned NumSlots)85806f32e7eSjoerg void StackColoring::calculateLiveIntervals(unsigned NumSlots) {
85906f32e7eSjoerg   SmallVector<SlotIndex, 16> Starts;
86006f32e7eSjoerg   SmallVector<bool, 16> DefinitelyInUse;
86106f32e7eSjoerg 
86206f32e7eSjoerg   // For each block, find which slots are active within this block
86306f32e7eSjoerg   // and update the live intervals.
86406f32e7eSjoerg   for (const MachineBasicBlock &MBB : *MF) {
86506f32e7eSjoerg     Starts.clear();
86606f32e7eSjoerg     Starts.resize(NumSlots);
86706f32e7eSjoerg     DefinitelyInUse.clear();
86806f32e7eSjoerg     DefinitelyInUse.resize(NumSlots);
86906f32e7eSjoerg 
87006f32e7eSjoerg     // Start the interval of the slots that we previously found to be 'in-use'.
87106f32e7eSjoerg     BlockLifetimeInfo &MBBLiveness = BlockLiveness[&MBB];
87206f32e7eSjoerg     for (int pos = MBBLiveness.LiveIn.find_first(); pos != -1;
87306f32e7eSjoerg          pos = MBBLiveness.LiveIn.find_next(pos)) {
87406f32e7eSjoerg       Starts[pos] = Indexes->getMBBStartIdx(&MBB);
87506f32e7eSjoerg     }
87606f32e7eSjoerg 
87706f32e7eSjoerg     // Create the interval for the basic blocks containing lifetime begin/end.
87806f32e7eSjoerg     for (const MachineInstr &MI : MBB) {
87906f32e7eSjoerg       SmallVector<int, 4> slots;
88006f32e7eSjoerg       bool IsStart = false;
88106f32e7eSjoerg       if (!isLifetimeStartOrEnd(MI, slots, IsStart))
88206f32e7eSjoerg         continue;
88306f32e7eSjoerg       SlotIndex ThisIndex = Indexes->getInstructionIndex(MI);
88406f32e7eSjoerg       for (auto Slot : slots) {
88506f32e7eSjoerg         if (IsStart) {
88606f32e7eSjoerg           // If a slot is already definitely in use, we don't have to emit
88706f32e7eSjoerg           // a new start marker because there is already a pre-existing
88806f32e7eSjoerg           // one.
88906f32e7eSjoerg           if (!DefinitelyInUse[Slot]) {
89006f32e7eSjoerg             LiveStarts[Slot].push_back(ThisIndex);
89106f32e7eSjoerg             DefinitelyInUse[Slot] = true;
89206f32e7eSjoerg           }
89306f32e7eSjoerg           if (!Starts[Slot].isValid())
89406f32e7eSjoerg             Starts[Slot] = ThisIndex;
89506f32e7eSjoerg         } else {
89606f32e7eSjoerg           if (Starts[Slot].isValid()) {
89706f32e7eSjoerg             VNInfo *VNI = Intervals[Slot]->getValNumInfo(0);
89806f32e7eSjoerg             Intervals[Slot]->addSegment(
89906f32e7eSjoerg                 LiveInterval::Segment(Starts[Slot], ThisIndex, VNI));
90006f32e7eSjoerg             Starts[Slot] = SlotIndex(); // Invalidate the start index
90106f32e7eSjoerg             DefinitelyInUse[Slot] = false;
90206f32e7eSjoerg           }
90306f32e7eSjoerg         }
90406f32e7eSjoerg       }
90506f32e7eSjoerg     }
90606f32e7eSjoerg 
90706f32e7eSjoerg     // Finish up started segments
90806f32e7eSjoerg     for (unsigned i = 0; i < NumSlots; ++i) {
90906f32e7eSjoerg       if (!Starts[i].isValid())
91006f32e7eSjoerg         continue;
91106f32e7eSjoerg 
91206f32e7eSjoerg       SlotIndex EndIdx = Indexes->getMBBEndIdx(&MBB);
91306f32e7eSjoerg       VNInfo *VNI = Intervals[i]->getValNumInfo(0);
91406f32e7eSjoerg       Intervals[i]->addSegment(LiveInterval::Segment(Starts[i], EndIdx, VNI));
91506f32e7eSjoerg     }
91606f32e7eSjoerg   }
91706f32e7eSjoerg }
91806f32e7eSjoerg 
removeAllMarkers()91906f32e7eSjoerg bool StackColoring::removeAllMarkers() {
92006f32e7eSjoerg   unsigned Count = 0;
92106f32e7eSjoerg   for (MachineInstr *MI : Markers) {
92206f32e7eSjoerg     MI->eraseFromParent();
92306f32e7eSjoerg     Count++;
92406f32e7eSjoerg   }
92506f32e7eSjoerg   Markers.clear();
92606f32e7eSjoerg 
92706f32e7eSjoerg   LLVM_DEBUG(dbgs() << "Removed " << Count << " markers.\n");
92806f32e7eSjoerg   return Count;
92906f32e7eSjoerg }
93006f32e7eSjoerg 
remapInstructions(DenseMap<int,int> & SlotRemap)93106f32e7eSjoerg void StackColoring::remapInstructions(DenseMap<int, int> &SlotRemap) {
93206f32e7eSjoerg   unsigned FixedInstr = 0;
93306f32e7eSjoerg   unsigned FixedMemOp = 0;
93406f32e7eSjoerg   unsigned FixedDbg = 0;
93506f32e7eSjoerg 
93606f32e7eSjoerg   // Remap debug information that refers to stack slots.
93706f32e7eSjoerg   for (auto &VI : MF->getVariableDbgInfo()) {
93806f32e7eSjoerg     if (!VI.Var)
93906f32e7eSjoerg       continue;
94006f32e7eSjoerg     if (SlotRemap.count(VI.Slot)) {
94106f32e7eSjoerg       LLVM_DEBUG(dbgs() << "Remapping debug info for ["
94206f32e7eSjoerg                         << cast<DILocalVariable>(VI.Var)->getName() << "].\n");
94306f32e7eSjoerg       VI.Slot = SlotRemap[VI.Slot];
94406f32e7eSjoerg       FixedDbg++;
94506f32e7eSjoerg     }
94606f32e7eSjoerg   }
94706f32e7eSjoerg 
94806f32e7eSjoerg   // Keep a list of *allocas* which need to be remapped.
94906f32e7eSjoerg   DenseMap<const AllocaInst*, const AllocaInst*> Allocas;
95006f32e7eSjoerg 
95106f32e7eSjoerg   // Keep a list of allocas which has been affected by the remap.
95206f32e7eSjoerg   SmallPtrSet<const AllocaInst*, 32> MergedAllocas;
95306f32e7eSjoerg 
95406f32e7eSjoerg   for (const std::pair<int, int> &SI : SlotRemap) {
95506f32e7eSjoerg     const AllocaInst *From = MFI->getObjectAllocation(SI.first);
95606f32e7eSjoerg     const AllocaInst *To = MFI->getObjectAllocation(SI.second);
95706f32e7eSjoerg     assert(To && From && "Invalid allocation object");
95806f32e7eSjoerg     Allocas[From] = To;
95906f32e7eSjoerg 
960*da58b97aSjoerg     // If From is before wo, its possible that there is a use of From between
961*da58b97aSjoerg     // them.
962*da58b97aSjoerg     if (From->comesBefore(To))
963*da58b97aSjoerg       const_cast<AllocaInst*>(To)->moveBefore(const_cast<AllocaInst*>(From));
964*da58b97aSjoerg 
96506f32e7eSjoerg     // AA might be used later for instruction scheduling, and we need it to be
96606f32e7eSjoerg     // able to deduce the correct aliasing releationships between pointers
96706f32e7eSjoerg     // derived from the alloca being remapped and the target of that remapping.
96806f32e7eSjoerg     // The only safe way, without directly informing AA about the remapping
96906f32e7eSjoerg     // somehow, is to directly update the IR to reflect the change being made
97006f32e7eSjoerg     // here.
97106f32e7eSjoerg     Instruction *Inst = const_cast<AllocaInst *>(To);
97206f32e7eSjoerg     if (From->getType() != To->getType()) {
97306f32e7eSjoerg       BitCastInst *Cast = new BitCastInst(Inst, From->getType());
97406f32e7eSjoerg       Cast->insertAfter(Inst);
97506f32e7eSjoerg       Inst = Cast;
97606f32e7eSjoerg     }
97706f32e7eSjoerg 
97806f32e7eSjoerg     // We keep both slots to maintain AliasAnalysis metadata later.
97906f32e7eSjoerg     MergedAllocas.insert(From);
98006f32e7eSjoerg     MergedAllocas.insert(To);
98106f32e7eSjoerg 
98206f32e7eSjoerg     // Transfer the stack protector layout tag, but make sure that SSPLK_AddrOf
98306f32e7eSjoerg     // does not overwrite SSPLK_SmallArray or SSPLK_LargeArray, and make sure
98406f32e7eSjoerg     // that SSPLK_SmallArray does not overwrite SSPLK_LargeArray.
98506f32e7eSjoerg     MachineFrameInfo::SSPLayoutKind FromKind
98606f32e7eSjoerg         = MFI->getObjectSSPLayout(SI.first);
98706f32e7eSjoerg     MachineFrameInfo::SSPLayoutKind ToKind = MFI->getObjectSSPLayout(SI.second);
98806f32e7eSjoerg     if (FromKind != MachineFrameInfo::SSPLK_None &&
98906f32e7eSjoerg         (ToKind == MachineFrameInfo::SSPLK_None ||
99006f32e7eSjoerg          (ToKind != MachineFrameInfo::SSPLK_LargeArray &&
99106f32e7eSjoerg           FromKind != MachineFrameInfo::SSPLK_AddrOf)))
99206f32e7eSjoerg       MFI->setObjectSSPLayout(SI.second, FromKind);
99306f32e7eSjoerg 
99406f32e7eSjoerg     // The new alloca might not be valid in a llvm.dbg.declare for this
99506f32e7eSjoerg     // variable, so undef out the use to make the verifier happy.
99606f32e7eSjoerg     AllocaInst *FromAI = const_cast<AllocaInst *>(From);
99706f32e7eSjoerg     if (FromAI->isUsedByMetadata())
99806f32e7eSjoerg       ValueAsMetadata::handleRAUW(FromAI, UndefValue::get(FromAI->getType()));
99906f32e7eSjoerg     for (auto &Use : FromAI->uses()) {
100006f32e7eSjoerg       if (BitCastInst *BCI = dyn_cast<BitCastInst>(Use.get()))
100106f32e7eSjoerg         if (BCI->isUsedByMetadata())
100206f32e7eSjoerg           ValueAsMetadata::handleRAUW(BCI, UndefValue::get(BCI->getType()));
100306f32e7eSjoerg     }
100406f32e7eSjoerg 
100506f32e7eSjoerg     // Note that this will not replace uses in MMOs (which we'll update below),
100606f32e7eSjoerg     // or anywhere else (which is why we won't delete the original
100706f32e7eSjoerg     // instruction).
100806f32e7eSjoerg     FromAI->replaceAllUsesWith(Inst);
100906f32e7eSjoerg   }
101006f32e7eSjoerg 
101106f32e7eSjoerg   // Remap all instructions to the new stack slots.
1012*da58b97aSjoerg   std::vector<std::vector<MachineMemOperand *>> SSRefs(
1013*da58b97aSjoerg       MFI->getObjectIndexEnd());
101406f32e7eSjoerg   for (MachineBasicBlock &BB : *MF)
101506f32e7eSjoerg     for (MachineInstr &I : BB) {
101606f32e7eSjoerg       // Skip lifetime markers. We'll remove them soon.
101706f32e7eSjoerg       if (I.getOpcode() == TargetOpcode::LIFETIME_START ||
101806f32e7eSjoerg           I.getOpcode() == TargetOpcode::LIFETIME_END)
101906f32e7eSjoerg         continue;
102006f32e7eSjoerg 
102106f32e7eSjoerg       // Update the MachineMemOperand to use the new alloca.
102206f32e7eSjoerg       for (MachineMemOperand *MMO : I.memoperands()) {
102306f32e7eSjoerg         // We've replaced IR-level uses of the remapped allocas, so we only
102406f32e7eSjoerg         // need to replace direct uses here.
102506f32e7eSjoerg         const AllocaInst *AI = dyn_cast_or_null<AllocaInst>(MMO->getValue());
102606f32e7eSjoerg         if (!AI)
102706f32e7eSjoerg           continue;
102806f32e7eSjoerg 
102906f32e7eSjoerg         if (!Allocas.count(AI))
103006f32e7eSjoerg           continue;
103106f32e7eSjoerg 
103206f32e7eSjoerg         MMO->setValue(Allocas[AI]);
103306f32e7eSjoerg         FixedMemOp++;
103406f32e7eSjoerg       }
103506f32e7eSjoerg 
103606f32e7eSjoerg       // Update all of the machine instruction operands.
103706f32e7eSjoerg       for (MachineOperand &MO : I.operands()) {
103806f32e7eSjoerg         if (!MO.isFI())
103906f32e7eSjoerg           continue;
104006f32e7eSjoerg         int FromSlot = MO.getIndex();
104106f32e7eSjoerg 
104206f32e7eSjoerg         // Don't touch arguments.
104306f32e7eSjoerg         if (FromSlot<0)
104406f32e7eSjoerg           continue;
104506f32e7eSjoerg 
104606f32e7eSjoerg         // Only look at mapped slots.
104706f32e7eSjoerg         if (!SlotRemap.count(FromSlot))
104806f32e7eSjoerg           continue;
104906f32e7eSjoerg 
105006f32e7eSjoerg         // In a debug build, check that the instruction that we are modifying is
105106f32e7eSjoerg         // inside the expected live range. If the instruction is not inside
105206f32e7eSjoerg         // the calculated range then it means that the alloca usage moved
105306f32e7eSjoerg         // outside of the lifetime markers, or that the user has a bug.
105406f32e7eSjoerg         // NOTE: Alloca address calculations which happen outside the lifetime
105506f32e7eSjoerg         // zone are okay, despite the fact that we don't have a good way
105606f32e7eSjoerg         // for validating all of the usages of the calculation.
105706f32e7eSjoerg #ifndef NDEBUG
1058*da58b97aSjoerg         bool TouchesMemory = I.mayLoadOrStore();
105906f32e7eSjoerg         // If we *don't* protect the user from escaped allocas, don't bother
106006f32e7eSjoerg         // validating the instructions.
106106f32e7eSjoerg         if (!I.isDebugInstr() && TouchesMemory && ProtectFromEscapedAllocas) {
106206f32e7eSjoerg           SlotIndex Index = Indexes->getInstructionIndex(I);
106306f32e7eSjoerg           const LiveInterval *Interval = &*Intervals[FromSlot];
106406f32e7eSjoerg           assert(Interval->find(Index) != Interval->end() &&
106506f32e7eSjoerg                  "Found instruction usage outside of live range.");
106606f32e7eSjoerg         }
106706f32e7eSjoerg #endif
106806f32e7eSjoerg 
106906f32e7eSjoerg         // Fix the machine instructions.
107006f32e7eSjoerg         int ToSlot = SlotRemap[FromSlot];
107106f32e7eSjoerg         MO.setIndex(ToSlot);
107206f32e7eSjoerg         FixedInstr++;
107306f32e7eSjoerg       }
107406f32e7eSjoerg 
107506f32e7eSjoerg       // We adjust AliasAnalysis information for merged stack slots.
107606f32e7eSjoerg       SmallVector<MachineMemOperand *, 2> NewMMOs;
107706f32e7eSjoerg       bool ReplaceMemOps = false;
107806f32e7eSjoerg       for (MachineMemOperand *MMO : I.memoperands()) {
1079*da58b97aSjoerg         // Collect MachineMemOperands which reference
1080*da58b97aSjoerg         // FixedStackPseudoSourceValues with old frame indices.
1081*da58b97aSjoerg         if (const auto *FSV = dyn_cast_or_null<FixedStackPseudoSourceValue>(
1082*da58b97aSjoerg                 MMO->getPseudoValue())) {
1083*da58b97aSjoerg           int FI = FSV->getFrameIndex();
1084*da58b97aSjoerg           auto To = SlotRemap.find(FI);
1085*da58b97aSjoerg           if (To != SlotRemap.end())
1086*da58b97aSjoerg             SSRefs[FI].push_back(MMO);
1087*da58b97aSjoerg         }
1088*da58b97aSjoerg 
108906f32e7eSjoerg         // If this memory location can be a slot remapped here,
109006f32e7eSjoerg         // we remove AA information.
109106f32e7eSjoerg         bool MayHaveConflictingAAMD = false;
109206f32e7eSjoerg         if (MMO->getAAInfo()) {
109306f32e7eSjoerg           if (const Value *MMOV = MMO->getValue()) {
109406f32e7eSjoerg             SmallVector<Value *, 4> Objs;
1095*da58b97aSjoerg             getUnderlyingObjectsForCodeGen(MMOV, Objs);
109606f32e7eSjoerg 
109706f32e7eSjoerg             if (Objs.empty())
109806f32e7eSjoerg               MayHaveConflictingAAMD = true;
109906f32e7eSjoerg             else
110006f32e7eSjoerg               for (Value *V : Objs) {
110106f32e7eSjoerg                 // If this memory location comes from a known stack slot
110206f32e7eSjoerg                 // that is not remapped, we continue checking.
110306f32e7eSjoerg                 // Otherwise, we need to invalidate AA infomation.
110406f32e7eSjoerg                 const AllocaInst *AI = dyn_cast_or_null<AllocaInst>(V);
110506f32e7eSjoerg                 if (AI && MergedAllocas.count(AI)) {
110606f32e7eSjoerg                   MayHaveConflictingAAMD = true;
110706f32e7eSjoerg                   break;
110806f32e7eSjoerg                 }
110906f32e7eSjoerg               }
111006f32e7eSjoerg           }
111106f32e7eSjoerg         }
111206f32e7eSjoerg         if (MayHaveConflictingAAMD) {
111306f32e7eSjoerg           NewMMOs.push_back(MF->getMachineMemOperand(MMO, AAMDNodes()));
111406f32e7eSjoerg           ReplaceMemOps = true;
111506f32e7eSjoerg         } else {
111606f32e7eSjoerg           NewMMOs.push_back(MMO);
111706f32e7eSjoerg         }
111806f32e7eSjoerg       }
111906f32e7eSjoerg 
112006f32e7eSjoerg       // If any memory operand is updated, set memory references of
112106f32e7eSjoerg       // this instruction.
112206f32e7eSjoerg       if (ReplaceMemOps)
112306f32e7eSjoerg         I.setMemRefs(*MF, NewMMOs);
112406f32e7eSjoerg     }
112506f32e7eSjoerg 
1126*da58b97aSjoerg   // Rewrite MachineMemOperands that reference old frame indices.
1127*da58b97aSjoerg   for (auto E : enumerate(SSRefs))
1128*da58b97aSjoerg     if (!E.value().empty()) {
1129*da58b97aSjoerg       const PseudoSourceValue *NewSV =
1130*da58b97aSjoerg           MF->getPSVManager().getFixedStack(SlotRemap.find(E.index())->second);
1131*da58b97aSjoerg       for (MachineMemOperand *Ref : E.value())
1132*da58b97aSjoerg         Ref->setValue(NewSV);
1133*da58b97aSjoerg     }
1134*da58b97aSjoerg 
113506f32e7eSjoerg   // Update the location of C++ catch objects for the MSVC personality routine.
113606f32e7eSjoerg   if (WinEHFuncInfo *EHInfo = MF->getWinEHFuncInfo())
113706f32e7eSjoerg     for (WinEHTryBlockMapEntry &TBME : EHInfo->TryBlockMap)
113806f32e7eSjoerg       for (WinEHHandlerType &H : TBME.HandlerArray)
113906f32e7eSjoerg         if (H.CatchObj.FrameIndex != std::numeric_limits<int>::max() &&
114006f32e7eSjoerg             SlotRemap.count(H.CatchObj.FrameIndex))
114106f32e7eSjoerg           H.CatchObj.FrameIndex = SlotRemap[H.CatchObj.FrameIndex];
114206f32e7eSjoerg 
114306f32e7eSjoerg   LLVM_DEBUG(dbgs() << "Fixed " << FixedMemOp << " machine memory operands.\n");
114406f32e7eSjoerg   LLVM_DEBUG(dbgs() << "Fixed " << FixedDbg << " debug locations.\n");
114506f32e7eSjoerg   LLVM_DEBUG(dbgs() << "Fixed " << FixedInstr << " machine instructions.\n");
114606f32e7eSjoerg }
114706f32e7eSjoerg 
removeInvalidSlotRanges()114806f32e7eSjoerg void StackColoring::removeInvalidSlotRanges() {
114906f32e7eSjoerg   for (MachineBasicBlock &BB : *MF)
115006f32e7eSjoerg     for (MachineInstr &I : BB) {
115106f32e7eSjoerg       if (I.getOpcode() == TargetOpcode::LIFETIME_START ||
115206f32e7eSjoerg           I.getOpcode() == TargetOpcode::LIFETIME_END || I.isDebugInstr())
115306f32e7eSjoerg         continue;
115406f32e7eSjoerg 
115506f32e7eSjoerg       // Some intervals are suspicious! In some cases we find address
115606f32e7eSjoerg       // calculations outside of the lifetime zone, but not actual memory
115706f32e7eSjoerg       // read or write. Memory accesses outside of the lifetime zone are a clear
115806f32e7eSjoerg       // violation, but address calculations are okay. This can happen when
115906f32e7eSjoerg       // GEPs are hoisted outside of the lifetime zone.
116006f32e7eSjoerg       // So, in here we only check instructions which can read or write memory.
116106f32e7eSjoerg       if (!I.mayLoad() && !I.mayStore())
116206f32e7eSjoerg         continue;
116306f32e7eSjoerg 
116406f32e7eSjoerg       // Check all of the machine operands.
116506f32e7eSjoerg       for (const MachineOperand &MO : I.operands()) {
116606f32e7eSjoerg         if (!MO.isFI())
116706f32e7eSjoerg           continue;
116806f32e7eSjoerg 
116906f32e7eSjoerg         int Slot = MO.getIndex();
117006f32e7eSjoerg 
117106f32e7eSjoerg         if (Slot<0)
117206f32e7eSjoerg           continue;
117306f32e7eSjoerg 
117406f32e7eSjoerg         if (Intervals[Slot]->empty())
117506f32e7eSjoerg           continue;
117606f32e7eSjoerg 
117706f32e7eSjoerg         // Check that the used slot is inside the calculated lifetime range.
117806f32e7eSjoerg         // If it is not, warn about it and invalidate the range.
117906f32e7eSjoerg         LiveInterval *Interval = &*Intervals[Slot];
118006f32e7eSjoerg         SlotIndex Index = Indexes->getInstructionIndex(I);
118106f32e7eSjoerg         if (Interval->find(Index) == Interval->end()) {
118206f32e7eSjoerg           Interval->clear();
118306f32e7eSjoerg           LLVM_DEBUG(dbgs() << "Invalidating range #" << Slot << "\n");
118406f32e7eSjoerg           EscapedAllocas++;
118506f32e7eSjoerg         }
118606f32e7eSjoerg       }
118706f32e7eSjoerg     }
118806f32e7eSjoerg }
118906f32e7eSjoerg 
expungeSlotMap(DenseMap<int,int> & SlotRemap,unsigned NumSlots)119006f32e7eSjoerg void StackColoring::expungeSlotMap(DenseMap<int, int> &SlotRemap,
119106f32e7eSjoerg                                    unsigned NumSlots) {
119206f32e7eSjoerg   // Expunge slot remap map.
119306f32e7eSjoerg   for (unsigned i=0; i < NumSlots; ++i) {
119406f32e7eSjoerg     // If we are remapping i
119506f32e7eSjoerg     if (SlotRemap.count(i)) {
119606f32e7eSjoerg       int Target = SlotRemap[i];
119706f32e7eSjoerg       // As long as our target is mapped to something else, follow it.
119806f32e7eSjoerg       while (SlotRemap.count(Target)) {
119906f32e7eSjoerg         Target = SlotRemap[Target];
120006f32e7eSjoerg         SlotRemap[i] = Target;
120106f32e7eSjoerg       }
120206f32e7eSjoerg     }
120306f32e7eSjoerg   }
120406f32e7eSjoerg }
120506f32e7eSjoerg 
runOnMachineFunction(MachineFunction & Func)120606f32e7eSjoerg bool StackColoring::runOnMachineFunction(MachineFunction &Func) {
120706f32e7eSjoerg   LLVM_DEBUG(dbgs() << "********** Stack Coloring **********\n"
120806f32e7eSjoerg                     << "********** Function: " << Func.getName() << '\n');
120906f32e7eSjoerg   MF = &Func;
121006f32e7eSjoerg   MFI = &MF->getFrameInfo();
121106f32e7eSjoerg   Indexes = &getAnalysis<SlotIndexes>();
121206f32e7eSjoerg   BlockLiveness.clear();
121306f32e7eSjoerg   BasicBlocks.clear();
121406f32e7eSjoerg   BasicBlockNumbering.clear();
121506f32e7eSjoerg   Markers.clear();
121606f32e7eSjoerg   Intervals.clear();
121706f32e7eSjoerg   LiveStarts.clear();
121806f32e7eSjoerg   VNInfoAllocator.Reset();
121906f32e7eSjoerg 
122006f32e7eSjoerg   unsigned NumSlots = MFI->getObjectIndexEnd();
122106f32e7eSjoerg 
122206f32e7eSjoerg   // If there are no stack slots then there are no markers to remove.
122306f32e7eSjoerg   if (!NumSlots)
122406f32e7eSjoerg     return false;
122506f32e7eSjoerg 
122606f32e7eSjoerg   SmallVector<int, 8> SortedSlots;
122706f32e7eSjoerg   SortedSlots.reserve(NumSlots);
122806f32e7eSjoerg   Intervals.reserve(NumSlots);
122906f32e7eSjoerg   LiveStarts.resize(NumSlots);
123006f32e7eSjoerg 
123106f32e7eSjoerg   unsigned NumMarkers = collectMarkers(NumSlots);
123206f32e7eSjoerg 
123306f32e7eSjoerg   unsigned TotalSize = 0;
123406f32e7eSjoerg   LLVM_DEBUG(dbgs() << "Found " << NumMarkers << " markers and " << NumSlots
123506f32e7eSjoerg                     << " slots\n");
123606f32e7eSjoerg   LLVM_DEBUG(dbgs() << "Slot structure:\n");
123706f32e7eSjoerg 
123806f32e7eSjoerg   for (int i=0; i < MFI->getObjectIndexEnd(); ++i) {
123906f32e7eSjoerg     LLVM_DEBUG(dbgs() << "Slot #" << i << " - " << MFI->getObjectSize(i)
124006f32e7eSjoerg                       << " bytes.\n");
124106f32e7eSjoerg     TotalSize += MFI->getObjectSize(i);
124206f32e7eSjoerg   }
124306f32e7eSjoerg 
124406f32e7eSjoerg   LLVM_DEBUG(dbgs() << "Total Stack size: " << TotalSize << " bytes\n\n");
124506f32e7eSjoerg 
124606f32e7eSjoerg   // Don't continue because there are not enough lifetime markers, or the
124706f32e7eSjoerg   // stack is too small, or we are told not to optimize the slots.
124806f32e7eSjoerg   if (NumMarkers < 2 || TotalSize < 16 || DisableColoring ||
124906f32e7eSjoerg       skipFunction(Func.getFunction())) {
125006f32e7eSjoerg     LLVM_DEBUG(dbgs() << "Will not try to merge slots.\n");
125106f32e7eSjoerg     return removeAllMarkers();
125206f32e7eSjoerg   }
125306f32e7eSjoerg 
125406f32e7eSjoerg   for (unsigned i=0; i < NumSlots; ++i) {
125506f32e7eSjoerg     std::unique_ptr<LiveInterval> LI(new LiveInterval(i, 0));
125606f32e7eSjoerg     LI->getNextValue(Indexes->getZeroIndex(), VNInfoAllocator);
125706f32e7eSjoerg     Intervals.push_back(std::move(LI));
125806f32e7eSjoerg     SortedSlots.push_back(i);
125906f32e7eSjoerg   }
126006f32e7eSjoerg 
126106f32e7eSjoerg   // Calculate the liveness of each block.
126206f32e7eSjoerg   calculateLocalLiveness();
126306f32e7eSjoerg   LLVM_DEBUG(dbgs() << "Dataflow iterations: " << NumIterations << "\n");
126406f32e7eSjoerg   LLVM_DEBUG(dump());
126506f32e7eSjoerg 
126606f32e7eSjoerg   // Propagate the liveness information.
126706f32e7eSjoerg   calculateLiveIntervals(NumSlots);
126806f32e7eSjoerg   LLVM_DEBUG(dumpIntervals());
126906f32e7eSjoerg 
127006f32e7eSjoerg   // Search for allocas which are used outside of the declared lifetime
127106f32e7eSjoerg   // markers.
127206f32e7eSjoerg   if (ProtectFromEscapedAllocas)
127306f32e7eSjoerg     removeInvalidSlotRanges();
127406f32e7eSjoerg 
127506f32e7eSjoerg   // Maps old slots to new slots.
127606f32e7eSjoerg   DenseMap<int, int> SlotRemap;
127706f32e7eSjoerg   unsigned RemovedSlots = 0;
127806f32e7eSjoerg   unsigned ReducedSize = 0;
127906f32e7eSjoerg 
128006f32e7eSjoerg   // Do not bother looking at empty intervals.
128106f32e7eSjoerg   for (unsigned I = 0; I < NumSlots; ++I) {
128206f32e7eSjoerg     if (Intervals[SortedSlots[I]]->empty())
128306f32e7eSjoerg       SortedSlots[I] = -1;
128406f32e7eSjoerg   }
128506f32e7eSjoerg 
128606f32e7eSjoerg   // This is a simple greedy algorithm for merging allocas. First, sort the
128706f32e7eSjoerg   // slots, placing the largest slots first. Next, perform an n^2 scan and look
1288*da58b97aSjoerg   // for disjoint slots. When you find disjoint slots, merge the smaller one
128906f32e7eSjoerg   // into the bigger one and update the live interval. Remove the small alloca
129006f32e7eSjoerg   // and continue.
129106f32e7eSjoerg 
129206f32e7eSjoerg   // Sort the slots according to their size. Place unused slots at the end.
129306f32e7eSjoerg   // Use stable sort to guarantee deterministic code generation.
129406f32e7eSjoerg   llvm::stable_sort(SortedSlots, [this](int LHS, int RHS) {
129506f32e7eSjoerg     // We use -1 to denote a uninteresting slot. Place these slots at the end.
129606f32e7eSjoerg     if (LHS == -1)
129706f32e7eSjoerg       return false;
129806f32e7eSjoerg     if (RHS == -1)
129906f32e7eSjoerg       return true;
130006f32e7eSjoerg     // Sort according to size.
130106f32e7eSjoerg     return MFI->getObjectSize(LHS) > MFI->getObjectSize(RHS);
130206f32e7eSjoerg   });
130306f32e7eSjoerg 
130406f32e7eSjoerg   for (auto &s : LiveStarts)
130506f32e7eSjoerg     llvm::sort(s);
130606f32e7eSjoerg 
130706f32e7eSjoerg   bool Changed = true;
130806f32e7eSjoerg   while (Changed) {
130906f32e7eSjoerg     Changed = false;
131006f32e7eSjoerg     for (unsigned I = 0; I < NumSlots; ++I) {
131106f32e7eSjoerg       if (SortedSlots[I] == -1)
131206f32e7eSjoerg         continue;
131306f32e7eSjoerg 
131406f32e7eSjoerg       for (unsigned J=I+1; J < NumSlots; ++J) {
131506f32e7eSjoerg         if (SortedSlots[J] == -1)
131606f32e7eSjoerg           continue;
131706f32e7eSjoerg 
131806f32e7eSjoerg         int FirstSlot = SortedSlots[I];
131906f32e7eSjoerg         int SecondSlot = SortedSlots[J];
132006f32e7eSjoerg         LiveInterval *First = &*Intervals[FirstSlot];
132106f32e7eSjoerg         LiveInterval *Second = &*Intervals[SecondSlot];
132206f32e7eSjoerg         auto &FirstS = LiveStarts[FirstSlot];
132306f32e7eSjoerg         auto &SecondS = LiveStarts[SecondSlot];
132406f32e7eSjoerg         assert(!First->empty() && !Second->empty() && "Found an empty range");
132506f32e7eSjoerg 
132606f32e7eSjoerg         // Merge disjoint slots. This is a little bit tricky - see the
132706f32e7eSjoerg         // Implementation Notes section for an explanation.
132806f32e7eSjoerg         if (!First->isLiveAtIndexes(SecondS) &&
132906f32e7eSjoerg             !Second->isLiveAtIndexes(FirstS)) {
133006f32e7eSjoerg           Changed = true;
133106f32e7eSjoerg           First->MergeSegmentsInAsValue(*Second, First->getValNumInfo(0));
133206f32e7eSjoerg 
133306f32e7eSjoerg           int OldSize = FirstS.size();
133406f32e7eSjoerg           FirstS.append(SecondS.begin(), SecondS.end());
133506f32e7eSjoerg           auto Mid = FirstS.begin() + OldSize;
133606f32e7eSjoerg           std::inplace_merge(FirstS.begin(), Mid, FirstS.end());
133706f32e7eSjoerg 
133806f32e7eSjoerg           SlotRemap[SecondSlot] = FirstSlot;
133906f32e7eSjoerg           SortedSlots[J] = -1;
134006f32e7eSjoerg           LLVM_DEBUG(dbgs() << "Merging #" << FirstSlot << " and slots #"
134106f32e7eSjoerg                             << SecondSlot << " together.\n");
1342*da58b97aSjoerg           Align MaxAlignment = std::max(MFI->getObjectAlign(FirstSlot),
1343*da58b97aSjoerg                                         MFI->getObjectAlign(SecondSlot));
134406f32e7eSjoerg 
134506f32e7eSjoerg           assert(MFI->getObjectSize(FirstSlot) >=
134606f32e7eSjoerg                  MFI->getObjectSize(SecondSlot) &&
134706f32e7eSjoerg                  "Merging a small object into a larger one");
134806f32e7eSjoerg 
134906f32e7eSjoerg           RemovedSlots+=1;
135006f32e7eSjoerg           ReducedSize += MFI->getObjectSize(SecondSlot);
135106f32e7eSjoerg           MFI->setObjectAlignment(FirstSlot, MaxAlignment);
135206f32e7eSjoerg           MFI->RemoveStackObject(SecondSlot);
135306f32e7eSjoerg         }
135406f32e7eSjoerg       }
135506f32e7eSjoerg     }
135606f32e7eSjoerg   }// While changed.
135706f32e7eSjoerg 
135806f32e7eSjoerg   // Record statistics.
135906f32e7eSjoerg   StackSpaceSaved += ReducedSize;
136006f32e7eSjoerg   StackSlotMerged += RemovedSlots;
136106f32e7eSjoerg   LLVM_DEBUG(dbgs() << "Merge " << RemovedSlots << " slots. Saved "
136206f32e7eSjoerg                     << ReducedSize << " bytes\n");
136306f32e7eSjoerg 
136406f32e7eSjoerg   // Scan the entire function and update all machine operands that use frame
136506f32e7eSjoerg   // indices to use the remapped frame index.
136606f32e7eSjoerg   expungeSlotMap(SlotRemap, NumSlots);
136706f32e7eSjoerg   remapInstructions(SlotRemap);
136806f32e7eSjoerg 
136906f32e7eSjoerg   return removeAllMarkers();
137006f32e7eSjoerg }
1371