MergedLoadStoreMotion.cpp revision 277320
1//===- 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
30//                        +                    +
31//                       +                      +
32//                      +                        +
33//            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
39//                     +                         +
40//                      +                       +
41//                       +                     +
42//            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
50//                        +                    +
51//                       +                      +
52//                      +                        +
53//            if.then:                         if.else:
54//               <use %l>                         <use %l>
55//               <...>                            <...>
56//               br label %if.end                 br label %if.end
57//                      +                        +
58//                       +                      +
59//                        +                    +
60//            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
75#include "llvm/Transforms/Scalar.h"
76#include "llvm/ADT/SetVector.h"
77#include "llvm/ADT/SmallPtrSet.h"
78#include "llvm/ADT/Statistic.h"
79#include "llvm/Analysis/AliasAnalysis.h"
80#include "llvm/Analysis/CFG.h"
81#include "llvm/Analysis/Loads.h"
82#include "llvm/Analysis/MemoryBuiltins.h"
83#include "llvm/Analysis/MemoryDependenceAnalysis.h"
84#include "llvm/IR/Metadata.h"
85#include "llvm/IR/PatternMatch.h"
86#include "llvm/Support/Allocator.h"
87#include "llvm/Support/CommandLine.h"
88#include "llvm/Support/Debug.h"
89#include "llvm/Target/TargetLibraryInfo.h"
90#include "llvm/Transforms/Utils/BasicBlockUtils.h"
91#include "llvm/Transforms/Utils/SSAUpdater.h"
92#include <vector>
93using namespace llvm;
94
95#define DEBUG_TYPE "mldst-motion"
96
97//===----------------------------------------------------------------------===//
98//                         MergedLoadStoreMotion Pass
99//===----------------------------------------------------------------------===//
100static cl::opt<bool>
101EnableMLSM("mlsm", cl::desc("Enable motion of merged load and store"),
102           cl::init(true));
103
104namespace {
105class MergedLoadStoreMotion : public FunctionPass {
106  AliasAnalysis *AA;
107  MemoryDependenceAnalysis *MD;
108
109public:
110  static char ID; // Pass identification, replacement for typeid
111  explicit MergedLoadStoreMotion(void)
112      : FunctionPass(ID), MD(nullptr), MagicCompileTimeControl(250) {
113    initializeMergedLoadStoreMotionPass(*PassRegistry::getPassRegistry());
114  }
115
116  bool runOnFunction(Function &F) override;
117
118private:
119  // This transformation requires dominator postdominator info
120  void getAnalysisUsage(AnalysisUsage &AU) const override {
121    AU.addRequired<TargetLibraryInfo>();
122    AU.addRequired<MemoryDependenceAnalysis>();
123    AU.addRequired<AliasAnalysis>();
124    AU.addPreserved<AliasAnalysis>();
125  }
126
127  // Helper routines
128
129  ///
130  /// \brief Remove instruction from parent and update memory dependence
131  /// analysis.
132  ///
133  void removeInstruction(Instruction *Inst);
134  BasicBlock *getDiamondTail(BasicBlock *BB);
135  bool isDiamondHead(BasicBlock *BB);
136  // Routines for hoisting loads
137  bool isLoadHoistBarrier(Instruction *Inst);
138  LoadInst *canHoistFromBlock(BasicBlock *BB, LoadInst *LI);
139  void hoistInstruction(BasicBlock *BB, Instruction *HoistCand,
140                        Instruction *ElseInst);
141  bool isSafeToHoist(Instruction *I) const;
142  bool hoistLoad(BasicBlock *BB, LoadInst *HoistCand, LoadInst *ElseInst);
143  bool mergeLoads(BasicBlock *BB);
144  // Routines for sinking stores
145  StoreInst *canSinkFromBlock(BasicBlock *BB, StoreInst *SI);
146  PHINode *getPHIOperand(BasicBlock *BB, StoreInst *S0, StoreInst *S1);
147  bool isStoreSinkBarrier(Instruction *Inst);
148  bool sinkStore(BasicBlock *BB, StoreInst *SinkCand, StoreInst *ElseInst);
149  bool mergeStores(BasicBlock *BB);
150  // The mergeLoad/Store algorithms could have Size0 * Size1 complexity,
151  // where Size0 and Size1 are the #instructions on the two sides of
152  // the diamond. The constant chosen here is arbitrary. Compiler Time
153  // Control is enforced by the check Size0 * Size1 < MagicCompileTimeControl.
154  const int MagicCompileTimeControl;
155};
156
157char MergedLoadStoreMotion::ID = 0;
158}
159
160///
161/// \brief createMergedLoadStoreMotionPass - The public interface to this file.
162///
163FunctionPass *llvm::createMergedLoadStoreMotionPass() {
164  return new MergedLoadStoreMotion();
165}
166
167INITIALIZE_PASS_BEGIN(MergedLoadStoreMotion, "mldst-motion",
168                      "MergedLoadStoreMotion", false, false)
169INITIALIZE_PASS_DEPENDENCY(MemoryDependenceAnalysis)
170INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfo)
171INITIALIZE_AG_DEPENDENCY(AliasAnalysis)
172INITIALIZE_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);
182    if (LoadInst *LI = dyn_cast<LoadInst>(Inst))
183      MD->invalidateCachedPointerInfo(LI->getPointerOperand());
184    if (Inst->getType()->getScalarType()->isPointerTy()) {
185      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");
196  BranchInst *BI = (BranchInst *)(BB->getTerminator());
197  BasicBlock *Succ0 = BI->getSuccessor(0);
198  BasicBlock *Tail = Succ0->getTerminator()->getSuccessor(0);
199  return Tail;
200}
201
202///
203/// \brief True when BB is the head of a diamond (hammock)
204///
205bool MergedLoadStoreMotion::isDiamondHead(BasicBlock *BB) {
206  if (!BB)
207    return false;
208  if (!isa<BranchInst>(BB->getTerminator()))
209    return false;
210  if (BB->getTerminator()->getNumSuccessors() != 2)
211    return false;
212
213  BranchInst *BI = (BranchInst *)(BB->getTerminator());
214  BasicBlock *Succ0 = BI->getSuccessor(0);
215  BasicBlock *Succ1 = BI->getSuccessor(1);
216
217  if (!Succ0->getSinglePredecessor() ||
218      Succ0->getTerminator()->getNumSuccessors() != 1)
219    return false;
220  if (!Succ1->getSinglePredecessor() ||
221      Succ1->getTerminator()->getNumSuccessors() != 1)
222    return false;
223
224  BasicBlock *Tail = Succ0->getTerminator()->getSuccessor(0);
225  // Ignore triangles.
226  if (Succ1->getTerminator()->getSuccessor(0) != Tail)
227    return false;
228  return true;
229}
230
231///
232/// \brief True when instruction is a hoist barrier for a load
233///
234/// Whenever an instruction could possibly modify the value
235/// being loaded or protect against the load from happening
236/// it is considered a hoist barrier.
237///
238bool MergedLoadStoreMotion::isLoadHoistBarrier(Instruction *Inst) {
239  // FIXME: A call with no side effects should not be a barrier.
240  // Aren't all such calls covered by mayHaveSideEffects() below?
241  // Then this check can be removed.
242  if (isa<CallInst>(Inst))
243    return true;
244  if (isa<TerminatorInst>(Inst))
245    return true;
246  // FIXME: Conservatively let a store instruction block the load.
247  // Use alias analysis instead.
248  if (isa<StoreInst>(Inst))
249    return true;
250  // Note: mayHaveSideEffects covers all instructions that could
251  // trigger a change to state. Eg. in-flight stores have to be executed
252  // before ordered loads or fences, calls could invoke functions that store
253  // data to memory etc.
254  if (Inst->mayHaveSideEffects()) {
255    return true;
256  }
257  DEBUG(dbgs() << "No Hoist Barrier\n");
258  return false;
259}
260
261///
262/// \brief Decide if a load can be hoisted
263///
264/// When there is a load in \p BB to the same address as \p LI
265/// and it can be hoisted from \p BB, return that load.
266/// Otherwise return Null.
267///
268LoadInst *MergedLoadStoreMotion::canHoistFromBlock(BasicBlock *BB,
269                                                   LoadInst *LI) {
270  LoadInst *I = nullptr;
271  assert(isa<LoadInst>(LI));
272  if (LI->isUsedOutsideOfBlock(LI->getParent()))
273    return nullptr;
274
275  for (BasicBlock::iterator BBI = BB->begin(), BBE = BB->end(); BBI != BBE;
276       ++BBI) {
277    Instruction *Inst = BBI;
278
279    // Only merge and hoist loads when their result in used only in BB
280    if (isLoadHoistBarrier(Inst))
281      break;
282    if (!isa<LoadInst>(Inst))
283      continue;
284    if (Inst->isUsedOutsideOfBlock(Inst->getParent()))
285      continue;
286
287    AliasAnalysis::Location LocLI = AA->getLocation(LI);
288    AliasAnalysis::Location LocInst = AA->getLocation((LoadInst *)Inst);
289    if (AA->isMustAlias(LocLI, LocInst) && LI->getType() == Inst->getType()) {
290      I = (LoadInst *)Inst;
291      break;
292    }
293  }
294  return I;
295}
296
297///
298/// \brief Merge two equivalent instructions \p HoistCand and \p ElseInst into
299/// \p BB
300///
301/// BB is the head of a diamond
302///
303void MergedLoadStoreMotion::hoistInstruction(BasicBlock *BB,
304                                             Instruction *HoistCand,
305                                             Instruction *ElseInst) {
306  DEBUG(dbgs() << " Hoist Instruction into BB \n"; BB->dump();
307        dbgs() << "Instruction Left\n"; HoistCand->dump(); dbgs() << "\n";
308        dbgs() << "Instruction Right\n"; ElseInst->dump(); dbgs() << "\n");
309  // Hoist the instruction.
310  assert(HoistCand->getParent() != BB);
311
312  // Intersect optional metadata.
313  HoistCand->intersectOptionalDataWith(ElseInst);
314  HoistCand->dropUnknownMetadata();
315
316  // Prepend point for instruction insert
317  Instruction *HoistPt = BB->getTerminator();
318
319  // Merged instruction
320  Instruction *HoistedInst = HoistCand->clone();
321
322  // Notify AA of the new value.
323  if (isa<LoadInst>(HoistCand))
324    AA->copyValue(HoistCand, HoistedInst);
325
326  // Hoist instruction.
327  HoistedInst->insertBefore(HoistPt);
328
329  HoistCand->replaceAllUsesWith(HoistedInst);
330  removeInstruction(HoistCand);
331  // Replace the else block instruction.
332  ElseInst->replaceAllUsesWith(HoistedInst);
333  removeInstruction(ElseInst);
334}
335
336///
337/// \brief Return true if no operand of \p I is defined in I's parent block
338///
339bool MergedLoadStoreMotion::isSafeToHoist(Instruction *I) const {
340  BasicBlock *Parent = I->getParent();
341  for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
342    Instruction *Instr = dyn_cast<Instruction>(I->getOperand(i));
343    if (Instr && Instr->getParent() == Parent)
344      return false;
345  }
346  return true;
347}
348
349///
350/// \brief Merge two equivalent loads and GEPs and hoist into diamond head
351///
352bool MergedLoadStoreMotion::hoistLoad(BasicBlock *BB, LoadInst *L0,
353                                      LoadInst *L1) {
354  // Only one definition?
355  Instruction *A0 = dyn_cast<Instruction>(L0->getPointerOperand());
356  Instruction *A1 = dyn_cast<Instruction>(L1->getPointerOperand());
357  if (A0 && A1 && A0->isIdenticalTo(A1) && isSafeToHoist(A0) &&
358      A0->hasOneUse() && (A0->getParent() == L0->getParent()) &&
359      A1->hasOneUse() && (A1->getParent() == L1->getParent()) &&
360      isa<GetElementPtrInst>(A0)) {
361    DEBUG(dbgs() << "Hoist Instruction into BB \n"; BB->dump();
362          dbgs() << "Instruction Left\n"; L0->dump(); dbgs() << "\n";
363          dbgs() << "Instruction Right\n"; L1->dump(); dbgs() << "\n");
364    hoistInstruction(BB, A0, A1);
365    hoistInstruction(BB, L0, L1);
366    return true;
367  } else
368    return false;
369}
370
371///
372/// \brief Try to hoist two loads to same address into diamond header
373///
374/// Starting from a diamond head block, iterate over the instructions in one
375/// successor block and try to match a load in the second successor.
376///
377bool MergedLoadStoreMotion::mergeLoads(BasicBlock *BB) {
378  bool MergedLoads = false;
379  assert(isDiamondHead(BB));
380  BranchInst *BI = dyn_cast<BranchInst>(BB->getTerminator());
381  BasicBlock *Succ0 = BI->getSuccessor(0);
382  BasicBlock *Succ1 = BI->getSuccessor(1);
383  // #Instructions in Succ1 for Compile Time Control
384  int Size1 = Succ1->size();
385  int NLoads = 0;
386  for (BasicBlock::iterator BBI = Succ0->begin(), BBE = Succ0->end();
387       BBI != BBE;) {
388
389    Instruction *I = BBI;
390    ++BBI;
391    if (isLoadHoistBarrier(I))
392      break;
393
394    // Only move non-simple (atomic, volatile) loads.
395    if (!isa<LoadInst>(I))
396      continue;
397
398    LoadInst *L0 = (LoadInst *)I;
399    if (!L0->isSimple())
400      continue;
401
402    ++NLoads;
403    if (NLoads * Size1 >= MagicCompileTimeControl)
404      break;
405    if (LoadInst *L1 = canHoistFromBlock(Succ1, L0)) {
406      bool Res = hoistLoad(BB, L0, L1);
407      MergedLoads |= Res;
408      // Don't attempt to hoist above loads that had not been hoisted.
409      if (!Res)
410        break;
411    }
412  }
413  return MergedLoads;
414}
415
416///
417/// \brief True when instruction is sink barrier for a store
418///
419bool MergedLoadStoreMotion::isStoreSinkBarrier(Instruction *Inst) {
420  // FIXME: Conservatively let a load instruction block the store.
421  // Use alias analysis instead.
422  if (isa<LoadInst>(Inst))
423    return true;
424  if (isa<CallInst>(Inst))
425    return true;
426  if (isa<TerminatorInst>(Inst) && !isa<BranchInst>(Inst))
427    return true;
428  // Note: mayHaveSideEffects covers all instructions that could
429  // trigger a change to state. Eg. in-flight stores have to be executed
430  // before ordered loads or fences, calls could invoke functions that store
431  // data to memory etc.
432  if (!isa<StoreInst>(Inst) && Inst->mayHaveSideEffects()) {
433    return true;
434  }
435  DEBUG(dbgs() << "No Sink Barrier\n");
436  return false;
437}
438
439///
440/// \brief Check if \p BB contains a store to the same address as \p SI
441///
442/// \return The store in \p  when it is safe to sink. Otherwise return Null.
443///
444StoreInst *MergedLoadStoreMotion::canSinkFromBlock(BasicBlock *BB,
445                                                   StoreInst *SI) {
446  StoreInst *I = 0;
447  DEBUG(dbgs() << "can Sink? : "; SI->dump(); dbgs() << "\n");
448  for (BasicBlock::reverse_iterator RBI = BB->rbegin(), RBE = BB->rend();
449       RBI != RBE; ++RBI) {
450    Instruction *Inst = &*RBI;
451
452    // Only move loads if they are used in the block.
453    if (isStoreSinkBarrier(Inst))
454      break;
455    if (isa<StoreInst>(Inst)) {
456      AliasAnalysis::Location LocSI = AA->getLocation(SI);
457      AliasAnalysis::Location LocInst = AA->getLocation((StoreInst *)Inst);
458      if (AA->isMustAlias(LocSI, LocInst)) {
459        I = (StoreInst *)Inst;
460        break;
461      }
462    }
463  }
464  return I;
465}
466
467///
468/// \brief Create a PHI node in BB for the operands of S0 and S1
469///
470PHINode *MergedLoadStoreMotion::getPHIOperand(BasicBlock *BB, StoreInst *S0,
471                                              StoreInst *S1) {
472  // Create a phi if the values mismatch.
473  PHINode *NewPN = 0;
474  Value *Opd1 = S0->getValueOperand();
475  Value *Opd2 = S1->getValueOperand();
476  if (Opd1 != Opd2) {
477    NewPN = PHINode::Create(Opd1->getType(), 2, Opd2->getName() + ".sink",
478                            BB->begin());
479    NewPN->addIncoming(Opd1, S0->getParent());
480    NewPN->addIncoming(Opd2, S1->getParent());
481    if (NewPN->getType()->getScalarType()->isPointerTy()) {
482      // Notify AA of the new value.
483      AA->copyValue(Opd1, NewPN);
484      AA->copyValue(Opd2, NewPN);
485      // AA needs to be informed when a PHI-use of the pointer value is added
486      for (unsigned I = 0, E = NewPN->getNumIncomingValues(); I != E; ++I) {
487        unsigned J = PHINode::getOperandNumForIncomingValue(I);
488        AA->addEscapingUse(NewPN->getOperandUse(J));
489      }
490      if (MD)
491        MD->invalidateCachedPointerInfo(NewPN);
492    }
493  }
494  return NewPN;
495}
496
497///
498/// \brief Merge two stores to same address and sink into \p BB
499///
500/// Also sinks GEP instruction computing the store address
501///
502bool MergedLoadStoreMotion::sinkStore(BasicBlock *BB, StoreInst *S0,
503                                      StoreInst *S1) {
504  // Only one definition?
505  Instruction *A0 = dyn_cast<Instruction>(S0->getPointerOperand());
506  Instruction *A1 = dyn_cast<Instruction>(S1->getPointerOperand());
507  if (A0 && A1 && A0->isIdenticalTo(A1) && A0->hasOneUse() &&
508      (A0->getParent() == S0->getParent()) && A1->hasOneUse() &&
509      (A1->getParent() == S1->getParent()) && isa<GetElementPtrInst>(A0)) {
510    DEBUG(dbgs() << "Sink Instruction into BB \n"; BB->dump();
511          dbgs() << "Instruction Left\n"; S0->dump(); dbgs() << "\n";
512          dbgs() << "Instruction Right\n"; S1->dump(); dbgs() << "\n");
513    // Hoist the instruction.
514    BasicBlock::iterator InsertPt = BB->getFirstInsertionPt();
515    // Intersect optional metadata.
516    S0->intersectOptionalDataWith(S1);
517    S0->dropUnknownMetadata();
518
519    // Create the new store to be inserted at the join point.
520    StoreInst *SNew = (StoreInst *)(S0->clone());
521    Instruction *ANew = A0->clone();
522    AA->copyValue(S0, SNew);
523    SNew->insertBefore(InsertPt);
524    ANew->insertBefore(SNew);
525
526    assert(S0->getParent() == A0->getParent());
527    assert(S1->getParent() == A1->getParent());
528
529    PHINode *NewPN = getPHIOperand(BB, S0, S1);
530    // New PHI operand? Use it.
531    if (NewPN)
532      SNew->setOperand(0, NewPN);
533    removeInstruction(S0);
534    removeInstruction(S1);
535    A0->replaceAllUsesWith(ANew);
536    removeInstruction(A0);
537    A1->replaceAllUsesWith(ANew);
538    removeInstruction(A1);
539    return true;
540  }
541  return false;
542}
543
544///
545/// \brief True when two stores are equivalent and can sink into the footer
546///
547/// Starting from a diamond tail block, iterate over the instructions in one
548/// predecessor block and try to match a store in the second predecessor.
549///
550bool MergedLoadStoreMotion::mergeStores(BasicBlock *T) {
551
552  bool MergedStores = false;
553  assert(T && "Footer of a diamond cannot be empty");
554
555  pred_iterator PI = pred_begin(T), E = pred_end(T);
556  assert(PI != E);
557  BasicBlock *Pred0 = *PI;
558  ++PI;
559  BasicBlock *Pred1 = *PI;
560  ++PI;
561  // tail block  of a diamond/hammock?
562  if (Pred0 == Pred1)
563    return false; // No.
564  if (PI != E)
565    return false; // No. More than 2 predecessors.
566
567  // #Instructions in Succ1 for Compile Time Control
568  int Size1 = Pred1->size();
569  int NStores = 0;
570
571  for (BasicBlock::reverse_iterator RBI = Pred0->rbegin(), RBE = Pred0->rend();
572       RBI != RBE;) {
573
574    Instruction *I = &*RBI;
575    ++RBI;
576    if (isStoreSinkBarrier(I))
577      break;
578    // Sink move non-simple (atomic, volatile) stores
579    if (!isa<StoreInst>(I))
580      continue;
581    StoreInst *S0 = (StoreInst *)I;
582    if (!S0->isSimple())
583      continue;
584
585    ++NStores;
586    if (NStores * Size1 >= MagicCompileTimeControl)
587      break;
588    if (StoreInst *S1 = canSinkFromBlock(Pred1, S0)) {
589      bool Res = sinkStore(T, S0, S1);
590      MergedStores |= Res;
591      // Don't attempt to sink below stores that had to stick around
592      // But after removal of a store and some of its feeding
593      // instruction search again from the beginning since the iterator
594      // is likely stale at this point.
595      if (!Res)
596        break;
597      else {
598        RBI = Pred0->rbegin();
599        RBE = Pred0->rend();
600        DEBUG(dbgs() << "Search again\n"; Instruction *I = &*RBI; I->dump());
601      }
602    }
603  }
604  return MergedStores;
605}
606///
607/// \brief Run the transformation for each function
608///
609bool MergedLoadStoreMotion::runOnFunction(Function &F) {
610  MD = &getAnalysis<MemoryDependenceAnalysis>();
611  AA = &getAnalysis<AliasAnalysis>();
612
613  bool Changed = false;
614  if (!EnableMLSM)
615    return false;
616  DEBUG(dbgs() << "Instruction Merger\n");
617
618  // Merge unconditional branches, allowing PRE to catch more
619  // optimization opportunities.
620  for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE;) {
621    BasicBlock *BB = FI++;
622
623    // Hoist equivalent loads and sink stores
624    // outside diamonds when possible
625    // Run outside core GVN
626    if (isDiamondHead(BB)) {
627      Changed |= mergeLoads(BB);
628      Changed |= mergeStores(getDiamondTail(BB));
629    }
630  }
631  return Changed;
632}
633