blob: 59d156d7235262b416fb03a49b08005831c8a936 [file] [log] [blame]
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +00001//===- MergedLoadStoreMotion.cpp - merge and hoist/sink load/stores -------===//
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//! \file
11//! \brief This pass performs merges of loads and stores on both sides of a
12// diamond (hammock). It hoists the loads and sinks the stores.
13//
14// The algorithm iteratively hoists two loads to the same address out of a
15// diamond (hammock) and merges them into a single load in the header. Similar
16// it sinks and merges two stores to the tail block (footer). The algorithm
17// iterates over the instructions of one side of the diamond and attempts to
18// find a matching load/store on the other side. It hoists / sinks when it
19// thinks it safe to do so. This optimization helps with eg. hiding load
20// latencies, triggering if-conversion, and reducing static code size.
21//
22//===----------------------------------------------------------------------===//
23//
24//
25// Example:
26// Diamond shaped code before merge:
27//
28// header:
29// br %cond, label %if.then, label %if.else
Gerolf Hoflehnerea96a3d2014-08-07 23:19:55 +000030// + +
31// + +
32// + +
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +000033// if.then: if.else:
34// %lt = load %addr_l %le = load %addr_l
35// <use %lt> <use %le>
36// <...> <...>
37// store %st, %addr_s store %se, %addr_s
38// br label %if.end br label %if.end
Gerolf Hoflehnerea96a3d2014-08-07 23:19:55 +000039// + +
40// + +
41// + +
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +000042// if.end ("footer"):
43// <...>
44//
45// Diamond shaped code after merge:
46//
47// header:
48// %l = load %addr_l
49// br %cond, label %if.then, label %if.else
Gerolf Hoflehnerea96a3d2014-08-07 23:19:55 +000050// + +
51// + +
52// + +
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +000053// if.then: if.else:
54// <use %l> <use %l>
55// <...> <...>
56// br label %if.end br label %if.end
Gerolf Hoflehnerea96a3d2014-08-07 23:19:55 +000057// + +
58// + +
59// + +
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +000060// if.end ("footer"):
61// %s.sink = phi [%st, if.then], [%se, if.else]
62// <...>
63// store %s.sink, %addr_s
64// <...>
65//
66//
67//===----------------------- TODO -----------------------------------------===//
68//
69// 1) Generalize to regions other than diamonds
70// 2) Be more aggressive merging memory operations
71// Note that both changes require register pressure control
72//
73//===----------------------------------------------------------------------===//
74
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +000075#include "llvm/ADT/Statistic.h"
76#include "llvm/Analysis/AliasAnalysis.h"
77#include "llvm/Analysis/CFG.h"
Chandler Carruth7b560d42015-09-09 17:55:00 +000078#include "llvm/Analysis/GlobalsModRef.h"
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +000079#include "llvm/Analysis/Loads.h"
80#include "llvm/Analysis/MemoryBuiltins.h"
81#include "llvm/Analysis/MemoryDependenceAnalysis.h"
Benjamin Kramerb85d3752015-03-23 18:45:56 +000082#include "llvm/Analysis/TargetLibraryInfo.h"
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +000083#include "llvm/IR/Metadata.h"
84#include "llvm/IR/PatternMatch.h"
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +000085#include "llvm/Support/Debug.h"
Benjamin Kramerb85d3752015-03-23 18:45:56 +000086#include "llvm/Support/raw_ostream.h"
Mehdi Aminib550cb12016-04-18 09:17:29 +000087#include "llvm/Transforms/Scalar.h"
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +000088#include "llvm/Transforms/Utils/BasicBlockUtils.h"
89#include "llvm/Transforms/Utils/SSAUpdater.h"
Hans Wennborg083ca9b2015-10-06 23:24:35 +000090
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +000091using namespace llvm;
92
93#define DEBUG_TYPE "mldst-motion"
94
95//===----------------------------------------------------------------------===//
96// MergedLoadStoreMotion Pass
97//===----------------------------------------------------------------------===//
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +000098
99namespace {
100class MergedLoadStoreMotion : public FunctionPass {
101 AliasAnalysis *AA;
Chandler Carruth61440d22016-03-10 00:55:30 +0000102 MemoryDependenceResults *MD;
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000103
104public:
105 static char ID; // Pass identification, replacement for typeid
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000106 MergedLoadStoreMotion()
NAKAMURA Takumiab184fb2014-07-19 03:29:25 +0000107 : FunctionPass(ID), MD(nullptr), MagicCompileTimeControl(250) {
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000108 initializeMergedLoadStoreMotionPass(*PassRegistry::getPassRegistry());
109 }
110
111 bool runOnFunction(Function &F) override;
112
113private:
114 // This transformation requires dominator postdominator info
115 void getAnalysisUsage(AnalysisUsage &AU) const override {
Jakub Staszakf12821a2015-10-18 19:34:10 +0000116 AU.setPreservesCFG();
Chandler Carruthb98f63d2015-01-15 10:41:28 +0000117 AU.addRequired<TargetLibraryInfoWrapperPass>();
Chandler Carruth7b560d42015-09-09 17:55:00 +0000118 AU.addRequired<AAResultsWrapperPass>();
119 AU.addPreserved<GlobalsAAWrapperPass>();
Chandler Carruth61440d22016-03-10 00:55:30 +0000120 AU.addPreserved<MemoryDependenceWrapperPass>();
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000121 }
122
123 // Helper routines
124
125 ///
126 /// \brief Remove instruction from parent and update memory dependence
127 /// analysis.
128 ///
129 void removeInstruction(Instruction *Inst);
130 BasicBlock *getDiamondTail(BasicBlock *BB);
131 bool isDiamondHead(BasicBlock *BB);
132 // Routines for hoisting loads
Elena Demikhovsky27152ae2014-11-02 08:03:05 +0000133 bool isLoadHoistBarrierInRange(const Instruction& Start,
134 const Instruction& End,
135 LoadInst* LI);
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000136 LoadInst *canHoistFromBlock(BasicBlock *BB, LoadInst *LI);
137 void hoistInstruction(BasicBlock *BB, Instruction *HoistCand,
138 Instruction *ElseInst);
139 bool isSafeToHoist(Instruction *I) const;
140 bool hoistLoad(BasicBlock *BB, LoadInst *HoistCand, LoadInst *ElseInst);
141 bool mergeLoads(BasicBlock *BB);
142 // Routines for sinking stores
143 StoreInst *canSinkFromBlock(BasicBlock *BB, StoreInst *SI);
144 PHINode *getPHIOperand(BasicBlock *BB, StoreInst *S0, StoreInst *S1);
Chandler Carruthac80dc72015-06-17 07:18:54 +0000145 bool isStoreSinkBarrierInRange(const Instruction &Start,
146 const Instruction &End, MemoryLocation Loc);
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000147 bool sinkStore(BasicBlock *BB, StoreInst *SinkCand, StoreInst *ElseInst);
148 bool mergeStores(BasicBlock *BB);
149 // The mergeLoad/Store algorithms could have Size0 * Size1 complexity,
150 // where Size0 and Size1 are the #instructions on the two sides of
151 // the diamond. The constant chosen here is arbitrary. Compiler Time
152 // Control is enforced by the check Size0 * Size1 < MagicCompileTimeControl.
NAKAMURA Takumiab184fb2014-07-19 03:29:25 +0000153 const int MagicCompileTimeControl;
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000154};
155
156char MergedLoadStoreMotion::ID = 0;
Eugene Zelenkoffec81c2015-11-04 22:32:32 +0000157} // anonymous namespace
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000158
159///
160/// \brief createMergedLoadStoreMotionPass - The public interface to this file.
161///
162FunctionPass *llvm::createMergedLoadStoreMotionPass() {
163 return new MergedLoadStoreMotion();
164}
165
166INITIALIZE_PASS_BEGIN(MergedLoadStoreMotion, "mldst-motion",
167 "MergedLoadStoreMotion", false, false)
Chandler Carruth61440d22016-03-10 00:55:30 +0000168INITIALIZE_PASS_DEPENDENCY(MemoryDependenceWrapperPass)
Chandler Carruthb98f63d2015-01-15 10:41:28 +0000169INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
Chandler Carruth7b560d42015-09-09 17:55:00 +0000170INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
171INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass)
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000172INITIALIZE_PASS_END(MergedLoadStoreMotion, "mldst-motion",
173 "MergedLoadStoreMotion", false, false)
174
175///
176/// \brief Remove instruction from parent and update memory dependence analysis.
177///
178void MergedLoadStoreMotion::removeInstruction(Instruction *Inst) {
179 // Notify the memory dependence analysis.
180 if (MD) {
181 MD->removeInstruction(Inst);
David Majnemer8cce3332016-05-26 05:43:12 +0000182 if (auto *LI = dyn_cast<LoadInst>(Inst))
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000183 MD->invalidateCachedPointerInfo(LI->getPointerOperand());
David Majnemer8cce3332016-05-26 05:43:12 +0000184 if (Inst->getType()->isPtrOrPtrVectorTy()) {
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000185 MD->invalidateCachedPointerInfo(Inst);
186 }
187 }
188 Inst->eraseFromParent();
189}
190
191///
192/// \brief Return tail block of a diamond.
193///
194BasicBlock *MergedLoadStoreMotion::getDiamondTail(BasicBlock *BB) {
195 assert(isDiamondHead(BB) && "Basic block is not head of a diamond");
David Majnemer8cce3332016-05-26 05:43:12 +0000196 return BB->getTerminator()->getSuccessor(0)->getSingleSuccessor();
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000197}
198
199///
200/// \brief True when BB is the head of a diamond (hammock)
201///
202bool MergedLoadStoreMotion::isDiamondHead(BasicBlock *BB) {
203 if (!BB)
204 return false;
David Majnemer8cce3332016-05-26 05:43:12 +0000205 auto *BI = dyn_cast<BranchInst>(BB->getTerminator());
206 if (!BI || !BI->isConditional())
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000207 return false;
208
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000209 BasicBlock *Succ0 = BI->getSuccessor(0);
210 BasicBlock *Succ1 = BI->getSuccessor(1);
211
David Majnemer8cce3332016-05-26 05:43:12 +0000212 if (!Succ0->getSinglePredecessor())
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000213 return false;
David Majnemer8cce3332016-05-26 05:43:12 +0000214 if (!Succ1->getSinglePredecessor())
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000215 return false;
216
David Majnemer8cce3332016-05-26 05:43:12 +0000217 BasicBlock *Succ0Succ = Succ0->getSingleSuccessor();
218 BasicBlock *Succ1Succ = Succ1->getSingleSuccessor();
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000219 // Ignore triangles.
David Majnemer8cce3332016-05-26 05:43:12 +0000220 if (!Succ0Succ || !Succ1Succ || Succ0Succ != Succ1Succ)
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000221 return false;
222 return true;
223}
224
225///
226/// \brief True when instruction is a hoist barrier for a load
227///
228/// Whenever an instruction could possibly modify the value
229/// being loaded or protect against the load from happening
230/// it is considered a hoist barrier.
231///
Elena Demikhovsky27152ae2014-11-02 08:03:05 +0000232bool MergedLoadStoreMotion::isLoadHoistBarrierInRange(const Instruction& Start,
233 const Instruction& End,
234 LoadInst* LI) {
Chandler Carruthac80dc72015-06-17 07:18:54 +0000235 MemoryLocation Loc = MemoryLocation::get(LI);
Chandler Carruth194f59c2015-07-22 23:15:57 +0000236 return AA->canInstructionRangeModRef(Start, End, Loc, MRI_Mod);
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000237}
238
239///
240/// \brief Decide if a load can be hoisted
241///
242/// When there is a load in \p BB to the same address as \p LI
243/// and it can be hoisted from \p BB, return that load.
244/// Otherwise return Null.
245///
Elena Demikhovsky27152ae2014-11-02 08:03:05 +0000246LoadInst *MergedLoadStoreMotion::canHoistFromBlock(BasicBlock *BB1,
247 LoadInst *Load0) {
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000248
Elena Demikhovsky27152ae2014-11-02 08:03:05 +0000249 for (BasicBlock::iterator BBI = BB1->begin(), BBE = BB1->end(); BBI != BBE;
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000250 ++BBI) {
Duncan P. N. Exon Smithbe4d8cb2015-10-13 19:26:58 +0000251 Instruction *Inst = &*BBI;
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000252
253 // Only merge and hoist loads when their result in used only in BB
Elena Demikhovsky27152ae2014-11-02 08:03:05 +0000254 if (!isa<LoadInst>(Inst) || Inst->isUsedOutsideOfBlock(BB1))
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000255 continue;
256
David Majnemer8cce3332016-05-26 05:43:12 +0000257 auto *Load1 = cast<LoadInst>(Inst);
Elena Demikhovsky27152ae2014-11-02 08:03:05 +0000258 BasicBlock *BB0 = Load0->getParent();
259
Chandler Carruthac80dc72015-06-17 07:18:54 +0000260 MemoryLocation Loc0 = MemoryLocation::get(Load0);
261 MemoryLocation Loc1 = MemoryLocation::get(Load1);
Elena Demikhovsky27152ae2014-11-02 08:03:05 +0000262 if (AA->isMustAlias(Loc0, Loc1) && Load0->isSameOperationAs(Load1) &&
263 !isLoadHoistBarrierInRange(BB1->front(), *Load1, Load1) &&
264 !isLoadHoistBarrierInRange(BB0->front(), *Load0, Load0)) {
265 return Load1;
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000266 }
267 }
Elena Demikhovsky27152ae2014-11-02 08:03:05 +0000268 return nullptr;
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000269}
270
271///
272/// \brief Merge two equivalent instructions \p HoistCand and \p ElseInst into
273/// \p BB
274///
275/// BB is the head of a diamond
276///
277void MergedLoadStoreMotion::hoistInstruction(BasicBlock *BB,
278 Instruction *HoistCand,
279 Instruction *ElseInst) {
280 DEBUG(dbgs() << " Hoist Instruction into BB \n"; BB->dump();
281 dbgs() << "Instruction Left\n"; HoistCand->dump(); dbgs() << "\n";
282 dbgs() << "Instruction Right\n"; ElseInst->dump(); dbgs() << "\n");
283 // Hoist the instruction.
284 assert(HoistCand->getParent() != BB);
285
286 // Intersect optional metadata.
287 HoistCand->intersectOptionalDataWith(ElseInst);
Adrian Prantlcbdfdb72015-08-20 22:00:30 +0000288 HoistCand->dropUnknownNonDebugMetadata();
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000289
290 // Prepend point for instruction insert
291 Instruction *HoistPt = BB->getTerminator();
292
293 // Merged instruction
294 Instruction *HoistedInst = HoistCand->clone();
295
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000296 // Hoist instruction.
297 HoistedInst->insertBefore(HoistPt);
298
299 HoistCand->replaceAllUsesWith(HoistedInst);
300 removeInstruction(HoistCand);
301 // Replace the else block instruction.
302 ElseInst->replaceAllUsesWith(HoistedInst);
303 removeInstruction(ElseInst);
304}
305
306///
307/// \brief Return true if no operand of \p I is defined in I's parent block
308///
309bool MergedLoadStoreMotion::isSafeToHoist(Instruction *I) const {
310 BasicBlock *Parent = I->getParent();
David Majnemer8cce3332016-05-26 05:43:12 +0000311 for (Use &U : I->operands())
312 if (auto *Instr = dyn_cast<Instruction>(&U))
313 if (Instr->getParent() == Parent)
314 return false;
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000315 return true;
316}
317
318///
319/// \brief Merge two equivalent loads and GEPs and hoist into diamond head
320///
321bool MergedLoadStoreMotion::hoistLoad(BasicBlock *BB, LoadInst *L0,
322 LoadInst *L1) {
323 // Only one definition?
David Majnemer8cce3332016-05-26 05:43:12 +0000324 auto *A0 = dyn_cast<Instruction>(L0->getPointerOperand());
325 auto *A1 = dyn_cast<Instruction>(L1->getPointerOperand());
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000326 if (A0 && A1 && A0->isIdenticalTo(A1) && isSafeToHoist(A0) &&
327 A0->hasOneUse() && (A0->getParent() == L0->getParent()) &&
328 A1->hasOneUse() && (A1->getParent() == L1->getParent()) &&
329 isa<GetElementPtrInst>(A0)) {
330 DEBUG(dbgs() << "Hoist Instruction into BB \n"; BB->dump();
331 dbgs() << "Instruction Left\n"; L0->dump(); dbgs() << "\n";
332 dbgs() << "Instruction Right\n"; L1->dump(); dbgs() << "\n");
333 hoistInstruction(BB, A0, A1);
334 hoistInstruction(BB, L0, L1);
335 return true;
David Majnemer8cce3332016-05-26 05:43:12 +0000336 }
337 return false;
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000338}
339
340///
341/// \brief Try to hoist two loads to same address into diamond header
342///
343/// Starting from a diamond head block, iterate over the instructions in one
344/// successor block and try to match a load in the second successor.
345///
346bool MergedLoadStoreMotion::mergeLoads(BasicBlock *BB) {
347 bool MergedLoads = false;
348 assert(isDiamondHead(BB));
David Majnemer8cce3332016-05-26 05:43:12 +0000349 BranchInst *BI = cast<BranchInst>(BB->getTerminator());
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000350 BasicBlock *Succ0 = BI->getSuccessor(0);
351 BasicBlock *Succ1 = BI->getSuccessor(1);
352 // #Instructions in Succ1 for Compile Time Control
353 int Size1 = Succ1->size();
354 int NLoads = 0;
355 for (BasicBlock::iterator BBI = Succ0->begin(), BBE = Succ0->end();
356 BBI != BBE;) {
Duncan P. N. Exon Smithbe4d8cb2015-10-13 19:26:58 +0000357 Instruction *I = &*BBI;
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000358 ++BBI;
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000359
David Majnemer8cce3332016-05-26 05:43:12 +0000360 // Don't move non-simple (atomic, volatile) loads.
361 auto *L0 = dyn_cast<LoadInst>(I);
Elena Demikhovsky27152ae2014-11-02 08:03:05 +0000362 if (!L0 || !L0->isSimple() || L0->isUsedOutsideOfBlock(Succ0))
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000363 continue;
364
365 ++NLoads;
366 if (NLoads * Size1 >= MagicCompileTimeControl)
367 break;
368 if (LoadInst *L1 = canHoistFromBlock(Succ1, L0)) {
369 bool Res = hoistLoad(BB, L0, L1);
370 MergedLoads |= Res;
371 // Don't attempt to hoist above loads that had not been hoisted.
372 if (!Res)
373 break;
374 }
375 }
376 return MergedLoads;
377}
378
379///
Elena Demikhovskya5599bf2014-12-15 14:09:53 +0000380/// \brief True when instruction is a sink barrier for a store
381/// located in Loc
382///
383/// Whenever an instruction could possibly read or modify the
384/// value being stored or protect against the store from
385/// happening it is considered a sink barrier.
386///
Chandler Carruthac80dc72015-06-17 07:18:54 +0000387bool MergedLoadStoreMotion::isStoreSinkBarrierInRange(const Instruction &Start,
388 const Instruction &End,
389 MemoryLocation Loc) {
Chandler Carruth194f59c2015-07-22 23:15:57 +0000390 return AA->canInstructionRangeModRef(Start, End, Loc, MRI_ModRef);
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000391}
392
393///
394/// \brief Check if \p BB contains a store to the same address as \p SI
395///
396/// \return The store in \p when it is safe to sink. Otherwise return Null.
397///
Elena Demikhovskya5599bf2014-12-15 14:09:53 +0000398StoreInst *MergedLoadStoreMotion::canSinkFromBlock(BasicBlock *BB1,
399 StoreInst *Store0) {
400 DEBUG(dbgs() << "can Sink? : "; Store0->dump(); dbgs() << "\n");
Elena Demikhovskyef035bb2015-02-17 13:10:05 +0000401 BasicBlock *BB0 = Store0->getParent();
Elena Demikhovskya5599bf2014-12-15 14:09:53 +0000402 for (BasicBlock::reverse_iterator RBI = BB1->rbegin(), RBE = BB1->rend();
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000403 RBI != RBE; ++RBI) {
404 Instruction *Inst = &*RBI;
405
Elena Demikhovskya5599bf2014-12-15 14:09:53 +0000406 if (!isa<StoreInst>(Inst))
407 continue;
408
409 StoreInst *Store1 = cast<StoreInst>(Inst);
Elena Demikhovskya5599bf2014-12-15 14:09:53 +0000410
Chandler Carruthac80dc72015-06-17 07:18:54 +0000411 MemoryLocation Loc0 = MemoryLocation::get(Store0);
412 MemoryLocation Loc1 = MemoryLocation::get(Store1);
Elena Demikhovskya5599bf2014-12-15 14:09:53 +0000413 if (AA->isMustAlias(Loc0, Loc1) && Store0->isSameOperationAs(Store1) &&
David Majnemer8cce3332016-05-26 05:43:12 +0000414 !isStoreSinkBarrierInRange(*(std::next(BasicBlock::iterator(Store1))),
415 BB1->back(), Loc1) &&
416 !isStoreSinkBarrierInRange(*(std::next(BasicBlock::iterator(Store0))),
417 BB0->back(), Loc0)) {
Elena Demikhovskya5599bf2014-12-15 14:09:53 +0000418 return Store1;
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000419 }
420 }
Elena Demikhovskya5599bf2014-12-15 14:09:53 +0000421 return nullptr;
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000422}
423
424///
425/// \brief Create a PHI node in BB for the operands of S0 and S1
426///
427PHINode *MergedLoadStoreMotion::getPHIOperand(BasicBlock *BB, StoreInst *S0,
428 StoreInst *S1) {
429 // Create a phi if the values mismatch.
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000430 Value *Opd1 = S0->getValueOperand();
431 Value *Opd2 = S1->getValueOperand();
David Majnemer8cce3332016-05-26 05:43:12 +0000432 if (Opd1 == Opd2)
433 return nullptr;
434
435 auto *NewPN = PHINode::Create(Opd1->getType(), 2, Opd2->getName() + ".sink",
436 &BB->front());
437 NewPN->addIncoming(Opd1, S0->getParent());
438 NewPN->addIncoming(Opd2, S1->getParent());
439 if (MD && NewPN->getType()->getScalarType()->isPointerTy())
440 MD->invalidateCachedPointerInfo(NewPN);
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000441 return NewPN;
442}
443
444///
445/// \brief Merge two stores to same address and sink into \p BB
446///
447/// Also sinks GEP instruction computing the store address
448///
449bool MergedLoadStoreMotion::sinkStore(BasicBlock *BB, StoreInst *S0,
450 StoreInst *S1) {
451 // Only one definition?
David Majnemer8cce3332016-05-26 05:43:12 +0000452 auto *A0 = dyn_cast<Instruction>(S0->getPointerOperand());
453 auto *A1 = dyn_cast<Instruction>(S1->getPointerOperand());
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000454 if (A0 && A1 && A0->isIdenticalTo(A1) && A0->hasOneUse() &&
455 (A0->getParent() == S0->getParent()) && A1->hasOneUse() &&
456 (A1->getParent() == S1->getParent()) && isa<GetElementPtrInst>(A0)) {
457 DEBUG(dbgs() << "Sink Instruction into BB \n"; BB->dump();
458 dbgs() << "Instruction Left\n"; S0->dump(); dbgs() << "\n";
459 dbgs() << "Instruction Right\n"; S1->dump(); dbgs() << "\n");
460 // Hoist the instruction.
461 BasicBlock::iterator InsertPt = BB->getFirstInsertionPt();
462 // Intersect optional metadata.
463 S0->intersectOptionalDataWith(S1);
Adrian Prantlcbdfdb72015-08-20 22:00:30 +0000464 S0->dropUnknownNonDebugMetadata();
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000465
466 // Create the new store to be inserted at the join point.
David Majnemer8cce3332016-05-26 05:43:12 +0000467 StoreInst *SNew = cast<StoreInst>(S0->clone());
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000468 Instruction *ANew = A0->clone();
Duncan P. N. Exon Smithbe4d8cb2015-10-13 19:26:58 +0000469 SNew->insertBefore(&*InsertPt);
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000470 ANew->insertBefore(SNew);
471
472 assert(S0->getParent() == A0->getParent());
473 assert(S1->getParent() == A1->getParent());
474
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000475 // New PHI operand? Use it.
David Majnemer8cce3332016-05-26 05:43:12 +0000476 if (PHINode *NewPN = getPHIOperand(BB, S0, S1))
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000477 SNew->setOperand(0, NewPN);
478 removeInstruction(S0);
479 removeInstruction(S1);
480 A0->replaceAllUsesWith(ANew);
481 removeInstruction(A0);
482 A1->replaceAllUsesWith(ANew);
483 removeInstruction(A1);
484 return true;
485 }
486 return false;
487}
488
489///
490/// \brief True when two stores are equivalent and can sink into the footer
491///
492/// Starting from a diamond tail block, iterate over the instructions in one
493/// predecessor block and try to match a store in the second predecessor.
494///
495bool MergedLoadStoreMotion::mergeStores(BasicBlock *T) {
496
497 bool MergedStores = false;
498 assert(T && "Footer of a diamond cannot be empty");
499
500 pred_iterator PI = pred_begin(T), E = pred_end(T);
501 assert(PI != E);
502 BasicBlock *Pred0 = *PI;
503 ++PI;
504 BasicBlock *Pred1 = *PI;
505 ++PI;
506 // tail block of a diamond/hammock?
507 if (Pred0 == Pred1)
508 return false; // No.
509 if (PI != E)
510 return false; // No. More than 2 predecessors.
511
512 // #Instructions in Succ1 for Compile Time Control
513 int Size1 = Pred1->size();
514 int NStores = 0;
515
516 for (BasicBlock::reverse_iterator RBI = Pred0->rbegin(), RBE = Pred0->rend();
517 RBI != RBE;) {
518
519 Instruction *I = &*RBI;
520 ++RBI;
Elena Demikhovskya5599bf2014-12-15 14:09:53 +0000521
David Majnemer8cce3332016-05-26 05:43:12 +0000522 // Don't sink non-simple (atomic, volatile) stores.
523 auto *S0 = dyn_cast<StoreInst>(I);
524 if (!S0 || !S0->isSimple())
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000525 continue;
526
527 ++NStores;
528 if (NStores * Size1 >= MagicCompileTimeControl)
529 break;
530 if (StoreInst *S1 = canSinkFromBlock(Pred1, S0)) {
531 bool Res = sinkStore(T, S0, S1);
532 MergedStores |= Res;
533 // Don't attempt to sink below stores that had to stick around
534 // But after removal of a store and some of its feeding
535 // instruction search again from the beginning since the iterator
536 // is likely stale at this point.
537 if (!Res)
538 break;
David Majnemer8cce3332016-05-26 05:43:12 +0000539 RBI = Pred0->rbegin();
540 RBE = Pred0->rend();
541 DEBUG(dbgs() << "Search again\n"; Instruction *I = &*RBI; I->dump());
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000542 }
543 }
544 return MergedStores;
545}
Hans Wennborg083ca9b2015-10-06 23:24:35 +0000546
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000547///
548/// \brief Run the transformation for each function
549///
550bool MergedLoadStoreMotion::runOnFunction(Function &F) {
Andrew Kayloraa641a52016-04-22 22:06:11 +0000551 if (skipFunction(F))
552 return false;
553
Chandler Carruth61440d22016-03-10 00:55:30 +0000554 auto *MDWP = getAnalysisIfAvailable<MemoryDependenceWrapperPass>();
555 MD = MDWP ? &MDWP->getMemDep() : nullptr;
Chandler Carruth7b560d42015-09-09 17:55:00 +0000556 AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000557
558 bool Changed = false;
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000559 DEBUG(dbgs() << "Instruction Merger\n");
560
561 // Merge unconditional branches, allowing PRE to catch more
562 // optimization opportunities.
563 for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE;) {
Duncan P. N. Exon Smithbe4d8cb2015-10-13 19:26:58 +0000564 BasicBlock *BB = &*FI++;
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000565
566 // Hoist equivalent loads and sink stores
567 // outside diamonds when possible
Gerolf Hoflehnerf27ae6c2014-07-18 19:13:09 +0000568 if (isDiamondHead(BB)) {
569 Changed |= mergeLoads(BB);
570 Changed |= mergeStores(getDiamondTail(BB));
571 }
572 }
573 return Changed;
574}