| Dan Gohman | 5d5b8b1 | 2010-05-07 15:40:13 +0000 | [diff] [blame] | 1 | //===-- Sink.cpp - Code Sinking -------------------------------------------===// | 
|  | 2 | // | 
|  | 3 | //                     The LLVM Compiler Infrastructure | 
|  | 4 | // | 
|  | 5 | // This file is distributed under the University of Illinois Open Source | 
|  | 6 | // License. See LICENSE.TXT for details. | 
|  | 7 | // | 
|  | 8 | //===----------------------------------------------------------------------===// | 
|  | 9 | // | 
|  | 10 | // This pass moves instructions into successor blocks, when possible, so that | 
|  | 11 | // they aren't executed on paths where their results aren't needed. | 
|  | 12 | // | 
|  | 13 | //===----------------------------------------------------------------------===// | 
|  | 14 |  | 
| Justin Bogner | b939490 | 2016-04-22 19:54:10 +0000 | [diff] [blame] | 15 | #include "llvm/Transforms/Scalar/Sink.h" | 
| Chandler Carruth | ed0881b | 2012-12-03 16:50:05 +0000 | [diff] [blame] | 16 | #include "llvm/ADT/Statistic.h" | 
|  | 17 | #include "llvm/Analysis/AliasAnalysis.h" | 
| Dan Gohman | 5d5b8b1 | 2010-05-07 15:40:13 +0000 | [diff] [blame] | 18 | #include "llvm/Analysis/LoopInfo.h" | 
| Dan Gohman | 75d7d5e | 2011-12-14 23:49:11 +0000 | [diff] [blame] | 19 | #include "llvm/Analysis/ValueTracking.h" | 
| Chandler Carruth | 1305dc3 | 2014-03-04 11:45:46 +0000 | [diff] [blame] | 20 | #include "llvm/IR/CFG.h" | 
| Hal Finkel | 511fea7 | 2014-07-10 16:07:11 +0000 | [diff] [blame] | 21 | #include "llvm/IR/DataLayout.h" | 
| Chandler Carruth | 5ad5f15 | 2014-01-13 09:26:24 +0000 | [diff] [blame] | 22 | #include "llvm/IR/Dominators.h" | 
| Chandler Carruth | 9fb823b | 2013-01-02 11:36:10 +0000 | [diff] [blame] | 23 | #include "llvm/IR/IntrinsicInst.h" | 
| Mehdi Amini | 46a4355 | 2015-03-04 18:43:29 +0000 | [diff] [blame] | 24 | #include "llvm/IR/Module.h" | 
| Dan Gohman | 5d5b8b1 | 2010-05-07 15:40:13 +0000 | [diff] [blame] | 25 | #include "llvm/Support/Debug.h" | 
|  | 26 | #include "llvm/Support/raw_ostream.h" | 
| Justin Bogner | b939490 | 2016-04-22 19:54:10 +0000 | [diff] [blame] | 27 | #include "llvm/Transforms/Scalar.h" | 
| Dan Gohman | 5d5b8b1 | 2010-05-07 15:40:13 +0000 | [diff] [blame] | 28 | using namespace llvm; | 
|  | 29 |  | 
| Chandler Carruth | 964daaa | 2014-04-22 02:55:47 +0000 | [diff] [blame] | 30 | #define DEBUG_TYPE "sink" | 
|  | 31 |  | 
| Dan Gohman | 5d5b8b1 | 2010-05-07 15:40:13 +0000 | [diff] [blame] | 32 | STATISTIC(NumSunk, "Number of instructions sunk"); | 
| Duncan Sands | 339bb61 | 2012-05-31 08:09:49 +0000 | [diff] [blame] | 33 | STATISTIC(NumSinkIter, "Number of sinking iterations"); | 
| Dan Gohman | 5d5b8b1 | 2010-05-07 15:40:13 +0000 | [diff] [blame] | 34 |  | 
| Dan Gohman | 5d5b8b1 | 2010-05-07 15:40:13 +0000 | [diff] [blame] | 35 | /// AllUsesDominatedByBlock - Return true if all uses of the specified value | 
|  | 36 | /// occur in blocks dominated by the specified block. | 
| Justin Bogner | b939490 | 2016-04-22 19:54:10 +0000 | [diff] [blame] | 37 | static bool AllUsesDominatedByBlock(Instruction *Inst, BasicBlock *BB, | 
|  | 38 | DominatorTree &DT) { | 
| Dan Gohman | 5d5b8b1 | 2010-05-07 15:40:13 +0000 | [diff] [blame] | 39 | // Ignoring debug uses is necessary so debug info doesn't affect the code. | 
|  | 40 | // This may leave a referencing dbg_value in the original block, before | 
|  | 41 | // the definition of the vreg.  Dwarf generator handles this although the | 
|  | 42 | // user might not get the right info at runtime. | 
| Chandler Carruth | cdf4788 | 2014-03-09 03:16:01 +0000 | [diff] [blame] | 43 | for (Use &U : Inst->uses()) { | 
| Dan Gohman | 5d5b8b1 | 2010-05-07 15:40:13 +0000 | [diff] [blame] | 44 | // Determine the block of the use. | 
| Chandler Carruth | cdf4788 | 2014-03-09 03:16:01 +0000 | [diff] [blame] | 45 | Instruction *UseInst = cast<Instruction>(U.getUser()); | 
| Dan Gohman | 5d5b8b1 | 2010-05-07 15:40:13 +0000 | [diff] [blame] | 46 | BasicBlock *UseBlock = UseInst->getParent(); | 
|  | 47 | if (PHINode *PN = dyn_cast<PHINode>(UseInst)) { | 
|  | 48 | // PHI nodes use the operand in the predecessor block, not the block with | 
|  | 49 | // the PHI. | 
| Chandler Carruth | cdf4788 | 2014-03-09 03:16:01 +0000 | [diff] [blame] | 50 | unsigned Num = PHINode::getIncomingValueNumForOperand(U.getOperandNo()); | 
| Dan Gohman | 5d5b8b1 | 2010-05-07 15:40:13 +0000 | [diff] [blame] | 51 | UseBlock = PN->getIncomingBlock(Num); | 
|  | 52 | } | 
|  | 53 | // Check that it dominates. | 
| Justin Bogner | b939490 | 2016-04-22 19:54:10 +0000 | [diff] [blame] | 54 | if (!DT.dominates(BB, UseBlock)) | 
| Dan Gohman | 5d5b8b1 | 2010-05-07 15:40:13 +0000 | [diff] [blame] | 55 | return false; | 
|  | 56 | } | 
|  | 57 | return true; | 
|  | 58 | } | 
|  | 59 |  | 
| Justin Bogner | b939490 | 2016-04-22 19:54:10 +0000 | [diff] [blame] | 60 | static bool isSafeToMove(Instruction *Inst, AliasAnalysis &AA, | 
| Craig Topper | 71b7b68 | 2014-08-21 05:55:13 +0000 | [diff] [blame] | 61 | SmallPtrSetImpl<Instruction *> &Stores) { | 
| Dan Gohman | 5d5b8b1 | 2010-05-07 15:40:13 +0000 | [diff] [blame] | 62 |  | 
| Eli Friedman | 71f5c2f | 2011-09-01 21:21:24 +0000 | [diff] [blame] | 63 | if (Inst->mayWriteToMemory()) { | 
|  | 64 | Stores.insert(Inst); | 
|  | 65 | return false; | 
|  | 66 | } | 
|  | 67 |  | 
|  | 68 | if (LoadInst *L = dyn_cast<LoadInst>(Inst)) { | 
| Chandler Carruth | ac80dc7 | 2015-06-17 07:18:54 +0000 | [diff] [blame] | 69 | MemoryLocation Loc = MemoryLocation::get(L); | 
| Craig Topper | 4627679 | 2014-08-24 23:23:06 +0000 | [diff] [blame] | 70 | for (Instruction *S : Stores) | 
| Alina Sbirlea | 63d2250 | 2017-12-05 20:12:23 +0000 | [diff] [blame] | 71 | if (isModSet(AA.getModRefInfo(S, Loc))) | 
| Dan Gohman | 5d5b8b1 | 2010-05-07 15:40:13 +0000 | [diff] [blame] | 72 | return false; | 
|  | 73 | } | 
|  | 74 |  | 
| Chandler Carruth | 9ae926b | 2018-08-26 09:51:22 +0000 | [diff] [blame] | 75 | if (Inst->isTerminator() || isa<PHINode>(Inst) || Inst->isEHPad() || | 
| David Majnemer | 8a1c45d | 2015-12-12 05:38:55 +0000 | [diff] [blame] | 76 | Inst->mayThrow()) | 
| Dan Gohman | c3b4ea7 | 2010-11-11 16:20:28 +0000 | [diff] [blame] | 77 | return false; | 
|  | 78 |  | 
| Owen Anderson | 15d1805 | 2015-06-01 17:20:31 +0000 | [diff] [blame] | 79 | if (auto CS = CallSite(Inst)) { | 
| Nicolai Haehnle | 889a20c | 2016-07-11 14:11:51 +0000 | [diff] [blame] | 80 | // Convergent operations cannot be made control-dependent on additional | 
|  | 81 | // values. | 
| Owen Anderson | 15d1805 | 2015-06-01 17:20:31 +0000 | [diff] [blame] | 82 | if (CS.hasFnAttr(Attribute::Convergent)) | 
|  | 83 | return false; | 
| Nicolai Haehnle | 889a20c | 2016-07-11 14:11:51 +0000 | [diff] [blame] | 84 |  | 
|  | 85 | for (Instruction *S : Stores) | 
| Alina Sbirlea | 63d2250 | 2017-12-05 20:12:23 +0000 | [diff] [blame] | 86 | if (isModSet(AA.getModRefInfo(S, CS))) | 
| Nicolai Haehnle | 889a20c | 2016-07-11 14:11:51 +0000 | [diff] [blame] | 87 | return false; | 
| Owen Anderson | 15d1805 | 2015-06-01 17:20:31 +0000 | [diff] [blame] | 88 | } | 
|  | 89 |  | 
| Dan Gohman | c3b4ea7 | 2010-11-11 16:20:28 +0000 | [diff] [blame] | 90 | return true; | 
| Dan Gohman | 5d5b8b1 | 2010-05-07 15:40:13 +0000 | [diff] [blame] | 91 | } | 
|  | 92 |  | 
| Duncan Sands | 339bb61 | 2012-05-31 08:09:49 +0000 | [diff] [blame] | 93 | /// IsAcceptableTarget - Return true if it is possible to sink the instruction | 
|  | 94 | /// in the specified basic block. | 
| Justin Bogner | b939490 | 2016-04-22 19:54:10 +0000 | [diff] [blame] | 95 | static bool IsAcceptableTarget(Instruction *Inst, BasicBlock *SuccToSinkTo, | 
|  | 96 | DominatorTree &DT, LoopInfo &LI) { | 
| Duncan Sands | 339bb61 | 2012-05-31 08:09:49 +0000 | [diff] [blame] | 97 | assert(Inst && "Instruction to be sunk is null"); | 
|  | 98 | assert(SuccToSinkTo && "Candidate sink target is null"); | 
| Nadav Rotem | 465834c | 2012-07-24 10:51:42 +0000 | [diff] [blame] | 99 |  | 
| Duncan Sands | 339bb61 | 2012-05-31 08:09:49 +0000 | [diff] [blame] | 100 | // It is not possible to sink an instruction into its own block.  This can | 
|  | 101 | // happen with loops. | 
|  | 102 | if (Inst->getParent() == SuccToSinkTo) | 
|  | 103 | return false; | 
| Nadav Rotem | 465834c | 2012-07-24 10:51:42 +0000 | [diff] [blame] | 104 |  | 
| David Majnemer | 8a1c45d | 2015-12-12 05:38:55 +0000 | [diff] [blame] | 105 | // It's never legal to sink an instruction into a block which terminates in an | 
|  | 106 | // EH-pad. | 
| Chandler Carruth | 698fbe7 | 2018-08-26 08:56:42 +0000 | [diff] [blame] | 107 | if (SuccToSinkTo->getTerminator()->isExceptionalTerminator()) | 
| David Majnemer | 8a1c45d | 2015-12-12 05:38:55 +0000 | [diff] [blame] | 108 | return false; | 
|  | 109 |  | 
| Nadav Rotem | 465834c | 2012-07-24 10:51:42 +0000 | [diff] [blame] | 110 | // If the block has multiple predecessors, this would introduce computation | 
| Duncan Sands | 339bb61 | 2012-05-31 08:09:49 +0000 | [diff] [blame] | 111 | // on different code paths.  We could split the critical edge, but for now we | 
|  | 112 | // just punt. | 
|  | 113 | // FIXME: Split critical edges if not backedges. | 
|  | 114 | if (SuccToSinkTo->getUniquePredecessor() != Inst->getParent()) { | 
|  | 115 | // We cannot sink a load across a critical edge - there may be stores in | 
|  | 116 | // other code paths. | 
| Fiona Glaser | efe6a84 | 2018-01-11 21:28:57 +0000 | [diff] [blame] | 117 | if (Inst->mayReadFromMemory()) | 
| Duncan Sands | 339bb61 | 2012-05-31 08:09:49 +0000 | [diff] [blame] | 118 | return false; | 
| Nadav Rotem | 465834c | 2012-07-24 10:51:42 +0000 | [diff] [blame] | 119 |  | 
| Duncan Sands | 339bb61 | 2012-05-31 08:09:49 +0000 | [diff] [blame] | 120 | // We don't want to sink across a critical edge if we don't dominate the | 
|  | 121 | // successor. We could be introducing calculations to new code paths. | 
| Justin Bogner | b939490 | 2016-04-22 19:54:10 +0000 | [diff] [blame] | 122 | if (!DT.dominates(Inst->getParent(), SuccToSinkTo)) | 
| Duncan Sands | 339bb61 | 2012-05-31 08:09:49 +0000 | [diff] [blame] | 123 | return false; | 
| Nadav Rotem | 465834c | 2012-07-24 10:51:42 +0000 | [diff] [blame] | 124 |  | 
| Duncan Sands | 339bb61 | 2012-05-31 08:09:49 +0000 | [diff] [blame] | 125 | // Don't sink instructions into a loop. | 
| Justin Bogner | b939490 | 2016-04-22 19:54:10 +0000 | [diff] [blame] | 126 | Loop *succ = LI.getLoopFor(SuccToSinkTo); | 
|  | 127 | Loop *cur = LI.getLoopFor(Inst->getParent()); | 
| Craig Topper | f40110f | 2014-04-25 05:29:35 +0000 | [diff] [blame] | 128 | if (succ != nullptr && succ != cur) | 
| Duncan Sands | 339bb61 | 2012-05-31 08:09:49 +0000 | [diff] [blame] | 129 | return false; | 
|  | 130 | } | 
| Nadav Rotem | 465834c | 2012-07-24 10:51:42 +0000 | [diff] [blame] | 131 |  | 
| Duncan Sands | 339bb61 | 2012-05-31 08:09:49 +0000 | [diff] [blame] | 132 | // Finally, check that all the uses of the instruction are actually | 
|  | 133 | // dominated by the candidate | 
| Justin Bogner | b939490 | 2016-04-22 19:54:10 +0000 | [diff] [blame] | 134 | return AllUsesDominatedByBlock(Inst, SuccToSinkTo, DT); | 
| Duncan Sands | 339bb61 | 2012-05-31 08:09:49 +0000 | [diff] [blame] | 135 | } | 
|  | 136 |  | 
| Dan Gohman | 5d5b8b1 | 2010-05-07 15:40:13 +0000 | [diff] [blame] | 137 | /// SinkInstruction - Determine whether it is safe to sink the specified machine | 
|  | 138 | /// instruction out of its current block into a successor. | 
| Justin Bogner | b939490 | 2016-04-22 19:54:10 +0000 | [diff] [blame] | 139 | static bool SinkInstruction(Instruction *Inst, | 
|  | 140 | SmallPtrSetImpl<Instruction *> &Stores, | 
|  | 141 | DominatorTree &DT, LoopInfo &LI, AAResults &AA) { | 
| Tom Stellard | edfd81d | 2014-03-21 15:51:51 +0000 | [diff] [blame] | 142 |  | 
|  | 143 | // Don't sink static alloca instructions.  CodeGen assumes allocas outside the | 
|  | 144 | // entry block are dynamically sized stack objects. | 
|  | 145 | if (AllocaInst *AI = dyn_cast<AllocaInst>(Inst)) | 
|  | 146 | if (AI->isStaticAlloca()) | 
|  | 147 | return false; | 
|  | 148 |  | 
| Dan Gohman | 5d5b8b1 | 2010-05-07 15:40:13 +0000 | [diff] [blame] | 149 | // Check if it's safe to move the instruction. | 
|  | 150 | if (!isSafeToMove(Inst, AA, Stores)) | 
|  | 151 | return false; | 
| Nadav Rotem | 465834c | 2012-07-24 10:51:42 +0000 | [diff] [blame] | 152 |  | 
| Dan Gohman | 5d5b8b1 | 2010-05-07 15:40:13 +0000 | [diff] [blame] | 153 | // FIXME: This should include support for sinking instructions within the | 
|  | 154 | // block they are currently in to shorten the live ranges.  We often get | 
|  | 155 | // instructions sunk into the top of a large block, but it would be better to | 
|  | 156 | // also sink them down before their first use in the block.  This xform has to | 
|  | 157 | // be careful not to *increase* register pressure though, e.g. sinking | 
|  | 158 | // "x = y + z" down if it kills y and z would increase the live ranges of y | 
|  | 159 | // and z and only shrink the live range of x. | 
| Nadav Rotem | 465834c | 2012-07-24 10:51:42 +0000 | [diff] [blame] | 160 |  | 
| Dan Gohman | 5d5b8b1 | 2010-05-07 15:40:13 +0000 | [diff] [blame] | 161 | // SuccToSinkTo - This is the successor to sink this instruction to, once we | 
|  | 162 | // decide. | 
| Craig Topper | f40110f | 2014-04-25 05:29:35 +0000 | [diff] [blame] | 163 | BasicBlock *SuccToSinkTo = nullptr; | 
| Nadav Rotem | 465834c | 2012-07-24 10:51:42 +0000 | [diff] [blame] | 164 |  | 
| Dan Gohman | 5d5b8b1 | 2010-05-07 15:40:13 +0000 | [diff] [blame] | 165 | // Instructions can only be sunk if all their uses are in blocks | 
|  | 166 | // dominated by one of the successors. | 
| Xin Tong | cbf04d9 | 2017-03-20 00:30:19 +0000 | [diff] [blame] | 167 | // Look at all the dominated blocks and see if we can sink it in one. | 
| Justin Bogner | b939490 | 2016-04-22 19:54:10 +0000 | [diff] [blame] | 168 | DomTreeNode *DTN = DT.getNode(Inst->getParent()); | 
| Nadav Rotem | 465834c | 2012-07-24 10:51:42 +0000 | [diff] [blame] | 169 | for (DomTreeNode::iterator I = DTN->begin(), E = DTN->end(); | 
| Craig Topper | f40110f | 2014-04-25 05:29:35 +0000 | [diff] [blame] | 170 | I != E && SuccToSinkTo == nullptr; ++I) { | 
| Duncan Sands | 339bb61 | 2012-05-31 08:09:49 +0000 | [diff] [blame] | 171 | BasicBlock *Candidate = (*I)->getBlock(); | 
| Xin Tong | cbf04d9 | 2017-03-20 00:30:19 +0000 | [diff] [blame] | 172 | // A node always immediate-dominates its children on the dominator | 
|  | 173 | // tree. | 
|  | 174 | if (IsAcceptableTarget(Inst, Candidate, DT, LI)) | 
| Duncan Sands | 339bb61 | 2012-05-31 08:09:49 +0000 | [diff] [blame] | 175 | SuccToSinkTo = Candidate; | 
|  | 176 | } | 
|  | 177 |  | 
| Nadav Rotem | 465834c | 2012-07-24 10:51:42 +0000 | [diff] [blame] | 178 | // If no suitable postdominator was found, look at all the successors and | 
| Duncan Sands | 339bb61 | 2012-05-31 08:09:49 +0000 | [diff] [blame] | 179 | // decide which one we should sink to, if any. | 
| Duncan P. N. Exon Smith | 6c99015 | 2014-07-21 17:06:51 +0000 | [diff] [blame] | 180 | for (succ_iterator I = succ_begin(Inst->getParent()), | 
|  | 181 | E = succ_end(Inst->getParent()); I != E && !SuccToSinkTo; ++I) { | 
| Justin Bogner | b939490 | 2016-04-22 19:54:10 +0000 | [diff] [blame] | 182 | if (IsAcceptableTarget(Inst, *I, DT, LI)) | 
| Duncan P. N. Exon Smith | 6c99015 | 2014-07-21 17:06:51 +0000 | [diff] [blame] | 183 | SuccToSinkTo = *I; | 
| Dan Gohman | 5d5b8b1 | 2010-05-07 15:40:13 +0000 | [diff] [blame] | 184 | } | 
| Nadav Rotem | 465834c | 2012-07-24 10:51:42 +0000 | [diff] [blame] | 185 |  | 
| Dan Gohman | 5d5b8b1 | 2010-05-07 15:40:13 +0000 | [diff] [blame] | 186 | // If we couldn't find a block to sink to, ignore this instruction. | 
| Craig Topper | f40110f | 2014-04-25 05:29:35 +0000 | [diff] [blame] | 187 | if (!SuccToSinkTo) | 
| Dan Gohman | 5d5b8b1 | 2010-05-07 15:40:13 +0000 | [diff] [blame] | 188 | return false; | 
| Nadav Rotem | 465834c | 2012-07-24 10:51:42 +0000 | [diff] [blame] | 189 |  | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 190 | LLVM_DEBUG(dbgs() << "Sink" << *Inst << " ("; | 
|  | 191 | Inst->getParent()->printAsOperand(dbgs(), false); dbgs() << " -> "; | 
|  | 192 | SuccToSinkTo->printAsOperand(dbgs(), false); dbgs() << ")\n"); | 
| Nadav Rotem | 465834c | 2012-07-24 10:51:42 +0000 | [diff] [blame] | 193 |  | 
| Dan Gohman | 5d5b8b1 | 2010-05-07 15:40:13 +0000 | [diff] [blame] | 194 | // Move the instruction. | 
| Duncan P. N. Exon Smith | be4d8cb | 2015-10-13 19:26:58 +0000 | [diff] [blame] | 195 | Inst->moveBefore(&*SuccToSinkTo->getFirstInsertionPt()); | 
| Dan Gohman | 5d5b8b1 | 2010-05-07 15:40:13 +0000 | [diff] [blame] | 196 | return true; | 
|  | 197 | } | 
| Justin Bogner | 82077c4 | 2016-04-22 19:54:04 +0000 | [diff] [blame] | 198 |  | 
| Justin Bogner | b939490 | 2016-04-22 19:54:10 +0000 | [diff] [blame] | 199 | static bool ProcessBlock(BasicBlock &BB, DominatorTree &DT, LoopInfo &LI, | 
|  | 200 | AAResults &AA) { | 
| Justin Bogner | 82077c4 | 2016-04-22 19:54:04 +0000 | [diff] [blame] | 201 | // Can't sink anything out of a block that has less than two successors. | 
|  | 202 | if (BB.getTerminator()->getNumSuccessors() <= 1) return false; | 
|  | 203 |  | 
|  | 204 | // Don't bother sinking code out of unreachable blocks. In addition to being | 
|  | 205 | // unprofitable, it can also lead to infinite looping, because in an | 
|  | 206 | // unreachable loop there may be nowhere to stop. | 
| Justin Bogner | b939490 | 2016-04-22 19:54:10 +0000 | [diff] [blame] | 207 | if (!DT.isReachableFromEntry(&BB)) return false; | 
| Justin Bogner | 82077c4 | 2016-04-22 19:54:04 +0000 | [diff] [blame] | 208 |  | 
|  | 209 | bool MadeChange = false; | 
|  | 210 |  | 
|  | 211 | // Walk the basic block bottom-up.  Remember if we saw a store. | 
|  | 212 | BasicBlock::iterator I = BB.end(); | 
|  | 213 | --I; | 
|  | 214 | bool ProcessedBegin = false; | 
|  | 215 | SmallPtrSet<Instruction *, 8> Stores; | 
|  | 216 | do { | 
|  | 217 | Instruction *Inst = &*I; // The instruction to sink. | 
|  | 218 |  | 
|  | 219 | // Predecrement I (if it's not begin) so that it isn't invalidated by | 
|  | 220 | // sinking. | 
|  | 221 | ProcessedBegin = I == BB.begin(); | 
|  | 222 | if (!ProcessedBegin) | 
|  | 223 | --I; | 
|  | 224 |  | 
|  | 225 | if (isa<DbgInfoIntrinsic>(Inst)) | 
|  | 226 | continue; | 
|  | 227 |  | 
| Justin Bogner | b939490 | 2016-04-22 19:54:10 +0000 | [diff] [blame] | 228 | if (SinkInstruction(Inst, Stores, DT, LI, AA)) { | 
| Justin Bogner | 82077c4 | 2016-04-22 19:54:04 +0000 | [diff] [blame] | 229 | ++NumSunk; | 
|  | 230 | MadeChange = true; | 
|  | 231 | } | 
|  | 232 |  | 
|  | 233 | // If we just processed the first instruction in the block, we're done. | 
|  | 234 | } while (!ProcessedBegin); | 
|  | 235 |  | 
|  | 236 | return MadeChange; | 
|  | 237 | } | 
|  | 238 |  | 
| Justin Bogner | b939490 | 2016-04-22 19:54:10 +0000 | [diff] [blame] | 239 | static bool iterativelySinkInstructions(Function &F, DominatorTree &DT, | 
|  | 240 | LoopInfo &LI, AAResults &AA) { | 
| Justin Bogner | 82077c4 | 2016-04-22 19:54:04 +0000 | [diff] [blame] | 241 | bool MadeChange, EverMadeChange = false; | 
|  | 242 |  | 
|  | 243 | do { | 
|  | 244 | MadeChange = false; | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 245 | LLVM_DEBUG(dbgs() << "Sinking iteration " << NumSinkIter << "\n"); | 
| Justin Bogner | 82077c4 | 2016-04-22 19:54:04 +0000 | [diff] [blame] | 246 | // Process all basic blocks. | 
| Benjamin Kramer | 135f735 | 2016-06-26 12:28:59 +0000 | [diff] [blame] | 247 | for (BasicBlock &I : F) | 
|  | 248 | MadeChange |= ProcessBlock(I, DT, LI, AA); | 
| Justin Bogner | 82077c4 | 2016-04-22 19:54:04 +0000 | [diff] [blame] | 249 | EverMadeChange |= MadeChange; | 
|  | 250 | NumSinkIter++; | 
|  | 251 | } while (MadeChange); | 
|  | 252 |  | 
|  | 253 | return EverMadeChange; | 
|  | 254 | } | 
| Justin Bogner | b939490 | 2016-04-22 19:54:10 +0000 | [diff] [blame] | 255 |  | 
| Sean Silva | 36e0d01 | 2016-08-09 00:28:15 +0000 | [diff] [blame] | 256 | PreservedAnalyses SinkingPass::run(Function &F, FunctionAnalysisManager &AM) { | 
| Justin Bogner | b939490 | 2016-04-22 19:54:10 +0000 | [diff] [blame] | 257 | auto &DT = AM.getResult<DominatorTreeAnalysis>(F); | 
|  | 258 | auto &LI = AM.getResult<LoopAnalysis>(F); | 
|  | 259 | auto &AA = AM.getResult<AAManager>(F); | 
|  | 260 |  | 
|  | 261 | if (!iterativelySinkInstructions(F, DT, LI, AA)) | 
|  | 262 | return PreservedAnalyses::all(); | 
|  | 263 |  | 
| Chandler Carruth | ca68a3e | 2017-01-15 06:32:49 +0000 | [diff] [blame] | 264 | PreservedAnalyses PA; | 
|  | 265 | PA.preserveSet<CFGAnalyses>(); | 
| Justin Bogner | b939490 | 2016-04-22 19:54:10 +0000 | [diff] [blame] | 266 | return PA; | 
|  | 267 | } | 
|  | 268 |  | 
|  | 269 | namespace { | 
|  | 270 | class SinkingLegacyPass : public FunctionPass { | 
|  | 271 | public: | 
|  | 272 | static char ID; // Pass identification | 
|  | 273 | SinkingLegacyPass() : FunctionPass(ID) { | 
|  | 274 | initializeSinkingLegacyPassPass(*PassRegistry::getPassRegistry()); | 
|  | 275 | } | 
|  | 276 |  | 
|  | 277 | bool runOnFunction(Function &F) override { | 
|  | 278 | auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree(); | 
|  | 279 | auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo(); | 
|  | 280 | auto &AA = getAnalysis<AAResultsWrapperPass>().getAAResults(); | 
|  | 281 |  | 
|  | 282 | return iterativelySinkInstructions(F, DT, LI, AA); | 
|  | 283 | } | 
|  | 284 |  | 
|  | 285 | void getAnalysisUsage(AnalysisUsage &AU) const override { | 
|  | 286 | AU.setPreservesCFG(); | 
|  | 287 | FunctionPass::getAnalysisUsage(AU); | 
|  | 288 | AU.addRequired<AAResultsWrapperPass>(); | 
|  | 289 | AU.addRequired<DominatorTreeWrapperPass>(); | 
|  | 290 | AU.addRequired<LoopInfoWrapperPass>(); | 
|  | 291 | AU.addPreserved<DominatorTreeWrapperPass>(); | 
|  | 292 | AU.addPreserved<LoopInfoWrapperPass>(); | 
|  | 293 | } | 
|  | 294 | }; | 
|  | 295 | } // end anonymous namespace | 
|  | 296 |  | 
|  | 297 | char SinkingLegacyPass::ID = 0; | 
|  | 298 | INITIALIZE_PASS_BEGIN(SinkingLegacyPass, "sink", "Code sinking", false, false) | 
|  | 299 | INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass) | 
|  | 300 | INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) | 
|  | 301 | INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) | 
|  | 302 | INITIALIZE_PASS_END(SinkingLegacyPass, "sink", "Code sinking", false, false) | 
|  | 303 |  | 
|  | 304 | FunctionPass *llvm::createSinkingPass() { return new SinkingLegacyPass(); } |