//===-- LICM.cpp - Loop Invariant Code Motion Pass ------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This pass performs loop invariant code motion, attempting to remove as much
// code from the body of a loop as possible.  It does this by either hoisting
// code into the preheader block, or by sinking code to the exit blocks if it is
// safe.  This pass also promotes must-aliased memory locations in the loop to
// live in registers, thus hoisting and sinking "invariant" loads and stores.
//
// This pass uses alias analysis for two purposes:
//
//  1. Moving loop invariant loads and calls out of loops.  If we can determine
//     that a load or call inside of a loop never aliases anything stored to,
//     we can hoist it or sink it like any other instruction.
//  2. Scalar Promotion of Memory - If there is a store instruction inside of
//     the loop, we try to move the store to happen AFTER the loop instead of
//     inside of the loop.  This can only happen if a few conditions are true:
//       A. The pointer stored through is loop invariant
//       B. There are no stores or loads in the loop which _may_ alias the
//          pointer.  There are no calls in the loop which mod/ref the pointer.
//     If these conditions are true, we can promote the loads and stores in the
//     loop of the pointer to use a temporary alloca'd variable.  We then use
//     the mem2reg functionality to construct the appropriate SSA form for the
//     variable.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "licm"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Instructions.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/AliasSetTracker.h"
#include "llvm/Analysis/Dominators.h"
#include "llvm/Transforms/Utils/PromoteMemToReg.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/ADT/Statistic.h"
#include <algorithm>
using namespace llvm;

STATISTIC(NumSunk      , "Number of instructions sunk out of loop");
STATISTIC(NumHoisted   , "Number of instructions hoisted out of loop");
STATISTIC(NumMovedLoads, "Number of load insts hoisted or sunk");
STATISTIC(NumMovedCalls, "Number of call insts hoisted or sunk");
STATISTIC(NumPromoted  , "Number of memory locations promoted to registers");

namespace {
  cl::opt<bool>
  DisablePromotion("disable-licm-promotion", cl::Hidden,
                   cl::desc("Disable memory promotion in LICM pass"));

  struct VISIBILITY_HIDDEN LICM : public LoopPass {
    static char ID; // Pass identifcation, replacement for typeid
    LICM() : LoopPass((intptr_t)&ID) {}

    virtual bool runOnLoop(Loop *L, LPPassManager &LPM);

    /// This transformation requires natural loop information & requires that
    /// loop preheaders be inserted into the CFG...
    ///
    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
      AU.setPreservesCFG();
      AU.addRequiredID(LoopSimplifyID);
      AU.addRequired<LoopInfo>();
      AU.addRequired<DominatorTree>();
      AU.addRequired<ETForest>();
      AU.addRequired<DominanceFrontier>();  // For scalar promotion (mem2reg)
      AU.addRequired<AliasAnalysis>();
    }

    bool doFinalization() {
      LoopToAliasMap.clear();
      return false;
    }

  private:
    // Various analyses that we use...
    AliasAnalysis *AA;       // Current AliasAnalysis information
    LoopInfo      *LI;       // Current LoopInfo
    ETForest      *ET;       // ETForest for the current loop..
    DominatorTree *DT;       // Dominator Tree for the current Loop...
    DominanceFrontier *DF;   // Current Dominance Frontier

    // State that is updated as we process loops
    bool Changed;            // Set to true when we change anything.
    BasicBlock *Preheader;   // The preheader block of the current loop...
    Loop *CurLoop;           // The current loop we are working on...
    AliasSetTracker *CurAST; // AliasSet information for the current loop...
    std::map<Loop *, AliasSetTracker *> LoopToAliasMap;

    /// SinkRegion - Walk the specified region of the CFG (defined by all blocks
    /// dominated by the specified block, and that are in the current loop) in
    /// reverse depth first order w.r.t the DominatorTree.  This allows us to
    /// visit uses before definitions, allowing us to sink a loop body in one
    /// pass without iteration.
    ///
    void SinkRegion(DominatorTree::Node *N);

    /// HoistRegion - Walk the specified region of the CFG (defined by all
    /// blocks dominated by the specified block, and that are in the current
    /// loop) in depth first order w.r.t the DominatorTree.  This allows us to
    /// visit definitions before uses, allowing us to hoist a loop body in one
    /// pass without iteration.
    ///
    void HoistRegion(DominatorTree::Node *N);

    /// inSubLoop - Little predicate that returns true if the specified basic
    /// block is in a subloop of the current one, not the current one itself.
    ///
    bool inSubLoop(BasicBlock *BB) {
      assert(CurLoop->contains(BB) && "Only valid if BB is IN the loop");
      for (Loop::iterator I = CurLoop->begin(), E = CurLoop->end(); I != E; ++I)
        if ((*I)->contains(BB))
          return true;  // A subloop actually contains this block!
      return false;
    }

    /// isExitBlockDominatedByBlockInLoop - This method checks to see if the
    /// specified exit block of the loop is dominated by the specified block
    /// that is in the body of the loop.  We use these constraints to
    /// dramatically limit the amount of the dominator tree that needs to be
    /// searched.
    bool isExitBlockDominatedByBlockInLoop(BasicBlock *ExitBlock,
                                           BasicBlock *BlockInLoop) const {
      // If the block in the loop is the loop header, it must be dominated!
      BasicBlock *LoopHeader = CurLoop->getHeader();
      if (BlockInLoop == LoopHeader)
        return true;

      DominatorTree::Node *BlockInLoopNode = DT->getNode(BlockInLoop);
      DominatorTree::Node *IDom            = DT->getNode(ExitBlock);

      // Because the exit block is not in the loop, we know we have to get _at
      // least_ its immediate dominator.
      do {
        // Get next Immediate Dominator.
        IDom = IDom->getIDom();

        // If we have got to the header of the loop, then the instructions block
        // did not dominate the exit node, so we can't hoist it.
        if (IDom->getBlock() == LoopHeader)
          return false;

      } while (IDom != BlockInLoopNode);

      return true;
    }

    /// sink - When an instruction is found to only be used outside of the loop,
    /// this function moves it to the exit blocks and patches up SSA form as
    /// needed.
    ///
    void sink(Instruction &I);

    /// hoist - When an instruction is found to only use loop invariant operands
    /// that is safe to hoist, this instruction is called to do the dirty work.
    ///
    void hoist(Instruction &I);

    /// isSafeToExecuteUnconditionally - Only sink or hoist an instruction if it
    /// is not a trapping instruction or if it is a trapping instruction and is
    /// guaranteed to execute.
    ///
    bool isSafeToExecuteUnconditionally(Instruction &I);

    /// pointerInvalidatedByLoop - Return true if the body of this loop may
    /// store into the memory location pointed to by V.
    ///
    bool pointerInvalidatedByLoop(Value *V, unsigned Size) {
      // Check to see if any of the basic blocks in CurLoop invalidate *V.
      return CurAST->getAliasSetForPointer(V, Size).isMod();
    }

    bool canSinkOrHoistInst(Instruction &I);
    bool isLoopInvariantInst(Instruction &I);
    bool isNotUsedInLoop(Instruction &I);

    /// PromoteValuesInLoop - Look at the stores in the loop and promote as many
    /// to scalars as we can.
    ///
    void PromoteValuesInLoop();

    /// FindPromotableValuesInLoop - Check the current loop for stores to
    /// definite pointers, which are not loaded and stored through may aliases.
    /// If these are found, create an alloca for the value, add it to the
    /// PromotedValues list, and keep track of the mapping from value to
    /// alloca...
    ///
    void FindPromotableValuesInLoop(
                   std::vector<std::pair<AllocaInst*, Value*> > &PromotedValues,
                                    std::map<Value*, AllocaInst*> &Val2AlMap);
  };

  char LICM::ID = 0;
  RegisterPass<LICM> X("licm", "Loop Invariant Code Motion");
}

LoopPass *llvm::createLICMPass() { return new LICM(); }

/// Hoist expressions out of the specified loop...
///
bool LICM::runOnLoop(Loop *L, LPPassManager &LPM) {
  Changed = false;

  // Get our Loop and Alias Analysis information...
  LI = &getAnalysis<LoopInfo>();
  AA = &getAnalysis<AliasAnalysis>();
  DF = &getAnalysis<DominanceFrontier>();
  DT = &getAnalysis<DominatorTree>();
  ET = &getAnalysis<ETForest>();

  CurAST = new AliasSetTracker(*AA);
  // Collect Alias info frmo subloops
  for (Loop::iterator LoopItr = L->begin(), LoopItrE = L->end();
       LoopItr != LoopItrE; ++LoopItr) {
    Loop *InnerL = *LoopItr;
    AliasSetTracker *InnerAST = LoopToAliasMap[InnerL];
    assert (InnerAST && "Where is my AST?");

    // What if InnerLoop was modified by other passes ?
    CurAST->add(*InnerAST);
  }
  
  CurLoop = L;

  // Get the preheader block to move instructions into...
  Preheader = L->getLoopPreheader();
  assert(Preheader&&"Preheader insertion pass guarantees we have a preheader!");

  // Loop over the body of this loop, looking for calls, invokes, and stores.
  // Because subloops have already been incorporated into AST, we skip blocks in
  // subloops.
  //
  for (std::vector<BasicBlock*>::const_iterator I = L->getBlocks().begin(),
         E = L->getBlocks().end(); I != E; ++I)
    if (LI->getLoopFor(*I) == L)        // Ignore blocks in subloops...
      CurAST->add(**I);                 // Incorporate the specified basic block

  // We want to visit all of the instructions in this loop... that are not parts
  // of our subloops (they have already had their invariants hoisted out of
  // their loop, into this loop, so there is no need to process the BODIES of
  // the subloops).
  //
  // Traverse the body of the loop in depth first order on the dominator tree so
  // that we are guaranteed to see definitions before we see uses.  This allows
  // us to sink instructions in one pass, without iteration.  AFter sinking
  // instructions, we perform another pass to hoist them out of the loop.
  //
  SinkRegion(DT->getNode(L->getHeader()));
  HoistRegion(DT->getNode(L->getHeader()));

  // Now that all loop invariants have been removed from the loop, promote any
  // memory references to scalars that we can...
  if (!DisablePromotion)
    PromoteValuesInLoop();

  // Clear out loops state information for the next iteration
  CurLoop = 0;
  Preheader = 0;

  LoopToAliasMap[L] = CurAST;
  return Changed;
}

/// SinkRegion - Walk the specified region of the CFG (defined by all blocks
/// dominated by the specified block, and that are in the current loop) in
/// reverse depth first order w.r.t the DominatorTree.  This allows us to visit
/// uses before definitions, allowing us to sink a loop body in one pass without
/// iteration.
///
void LICM::SinkRegion(DominatorTree::Node *N) {
  assert(N != 0 && "Null dominator tree node?");
  BasicBlock *BB = N->getBlock();

  // If this subregion is not in the top level loop at all, exit.
  if (!CurLoop->contains(BB)) return;

  // We are processing blocks in reverse dfo, so process children first...
  const std::vector<DominatorTree::Node*> &Children = N->getChildren();
  for (unsigned i = 0, e = Children.size(); i != e; ++i)
    SinkRegion(Children[i]);

  // Only need to process the contents of this block if it is not part of a
  // subloop (which would already have been processed).
  if (inSubLoop(BB)) return;

  for (BasicBlock::iterator II = BB->end(); II != BB->begin(); ) {
    Instruction &I = *--II;

    // Check to see if we can sink this instruction to the exit blocks
    // of the loop.  We can do this if the all users of the instruction are
    // outside of the loop.  In this case, it doesn't even matter if the
    // operands of the instruction are loop invariant.
    //
    if (isNotUsedInLoop(I) && canSinkOrHoistInst(I)) {
      ++II;
      sink(I);
    }
  }
}


/// HoistRegion - Walk the specified region of the CFG (defined by all blocks
/// dominated by the specified block, and that are in the current loop) in depth
/// first order w.r.t the DominatorTree.  This allows us to visit definitions
/// before uses, allowing us to hoist a loop body in one pass without iteration.
///
void LICM::HoistRegion(DominatorTree::Node *N) {
  assert(N != 0 && "Null dominator tree node?");
  BasicBlock *BB = N->getBlock();

  // If this subregion is not in the top level loop at all, exit.
  if (!CurLoop->contains(BB)) return;

  // Only need to process the contents of this block if it is not part of a
  // subloop (which would already have been processed).
  if (!inSubLoop(BB))
    for (BasicBlock::iterator II = BB->begin(), E = BB->end(); II != E; ) {
      Instruction &I = *II++;

      // Try hoisting the instruction out to the preheader.  We can only do this
      // if all of the operands of the instruction are loop invariant and if it
      // is safe to hoist the instruction.
      //
      if (isLoopInvariantInst(I) && canSinkOrHoistInst(I) &&
          isSafeToExecuteUnconditionally(I))
        hoist(I);
      }

  const std::vector<DominatorTree::Node*> &Children = N->getChildren();
  for (unsigned i = 0, e = Children.size(); i != e; ++i)
    HoistRegion(Children[i]);
}

/// canSinkOrHoistInst - Return true if the hoister and sinker can handle this
/// instruction.
///
bool LICM::canSinkOrHoistInst(Instruction &I) {
  // Loads have extra constraints we have to verify before we can hoist them.
  if (LoadInst *LI = dyn_cast<LoadInst>(&I)) {
    if (LI->isVolatile())
      return false;        // Don't hoist volatile loads!

    // Don't hoist loads which have may-aliased stores in loop.
    unsigned Size = 0;
    if (LI->getType()->isSized())
      Size = AA->getTargetData().getTypeSize(LI->getType());
    return !pointerInvalidatedByLoop(LI->getOperand(0), Size);
  } else if (CallInst *CI = dyn_cast<CallInst>(&I)) {
    // Handle obvious cases efficiently.
    if (Function *Callee = CI->getCalledFunction()) {
      AliasAnalysis::ModRefBehavior Behavior =AA->getModRefBehavior(Callee, CI);
      if (Behavior == AliasAnalysis::DoesNotAccessMemory)
        return true;
      else if (Behavior == AliasAnalysis::OnlyReadsMemory) {
        // If this call only reads from memory and there are no writes to memory
        // in the loop, we can hoist or sink the call as appropriate.
        bool FoundMod = false;
        for (AliasSetTracker::iterator I = CurAST->begin(), E = CurAST->end();
             I != E; ++I) {
          AliasSet &AS = *I;
          if (!AS.isForwardingAliasSet() && AS.isMod()) {
            FoundMod = true;
            break;
          }
        }
        if (!FoundMod) return true;
      }
    }

    // FIXME: This should use mod/ref information to see if we can hoist or sink
    // the call.

    return false;
  }

  // Otherwise these instructions are hoistable/sinkable
  return isa<BinaryOperator>(I) || isa<CastInst>(I) ||
         isa<SelectInst>(I) || isa<GetElementPtrInst>(I) || isa<CmpInst>(I);
}

/// isNotUsedInLoop - Return true if the only users of this instruction are
/// outside of the loop.  If this is true, we can sink the instruction to the
/// exit blocks of the loop.
///
bool LICM::isNotUsedInLoop(Instruction &I) {
  for (Value::use_iterator UI = I.use_begin(), E = I.use_end(); UI != E; ++UI) {
    Instruction *User = cast<Instruction>(*UI);
    if (PHINode *PN = dyn_cast<PHINode>(User)) {
      // PHI node uses occur in predecessor blocks!
      for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
        if (PN->getIncomingValue(i) == &I)
          if (CurLoop->contains(PN->getIncomingBlock(i)))
            return false;
    } else if (CurLoop->contains(User->getParent())) {
      return false;
    }
  }
  return true;
}


/// isLoopInvariantInst - Return true if all operands of this instruction are
/// loop invariant.  We also filter out non-hoistable instructions here just for
/// efficiency.
///
bool LICM::isLoopInvariantInst(Instruction &I) {
  // The instruction is loop invariant if all of its operands are loop-invariant
  for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i)
    if (!CurLoop->isLoopInvariant(I.getOperand(i)))
      return false;

  // If we got this far, the instruction is loop invariant!
  return true;
}

/// sink - When an instruction is found to only be used outside of the loop,
/// this function moves it to the exit blocks and patches up SSA form as needed.
/// This method is guaranteed to remove the original instruction from its
/// position, and may either delete it or move it to outside of the loop.
///
void LICM::sink(Instruction &I) {
  DOUT << "LICM sinking instruction: " << I;

  std::vector<BasicBlock*> ExitBlocks;
  CurLoop->getExitBlocks(ExitBlocks);

  if (isa<LoadInst>(I)) ++NumMovedLoads;
  else if (isa<CallInst>(I)) ++NumMovedCalls;
  ++NumSunk;
  Changed = true;

  // The case where there is only a single exit node of this loop is common
  // enough that we handle it as a special (more efficient) case.  It is more
  // efficient to handle because there are no PHI nodes that need to be placed.
  if (ExitBlocks.size() == 1) {
    if (!isExitBlockDominatedByBlockInLoop(ExitBlocks[0], I.getParent())) {
      // Instruction is not used, just delete it.
      CurAST->deleteValue(&I);
      if (!I.use_empty())  // If I has users in unreachable blocks, eliminate.
        I.replaceAllUsesWith(UndefValue::get(I.getType()));
      I.eraseFromParent();
    } else {
      // Move the instruction to the start of the exit block, after any PHI
      // nodes in it.
      I.removeFromParent();

      BasicBlock::iterator InsertPt = ExitBlocks[0]->begin();
      while (isa<PHINode>(InsertPt)) ++InsertPt;
      ExitBlocks[0]->getInstList().insert(InsertPt, &I);
    }
  } else if (ExitBlocks.size() == 0) {
    // The instruction is actually dead if there ARE NO exit blocks.
    CurAST->deleteValue(&I);
    if (!I.use_empty())  // If I has users in unreachable blocks, eliminate.
      I.replaceAllUsesWith(UndefValue::get(I.getType()));
    I.eraseFromParent();
  } else {
    // Otherwise, if we have multiple exits, use the PromoteMem2Reg function to
    // do all of the hard work of inserting PHI nodes as necessary.  We convert
    // the value into a stack object to get it to do this.

    // Firstly, we create a stack object to hold the value...
    AllocaInst *AI = 0;

    if (I.getType() != Type::VoidTy)
      AI = new AllocaInst(I.getType(), 0, I.getName(),
                          I.getParent()->getParent()->getEntryBlock().begin());

    // Secondly, insert load instructions for each use of the instruction
    // outside of the loop.
    while (!I.use_empty()) {
      Instruction *U = cast<Instruction>(I.use_back());

      // If the user is a PHI Node, we actually have to insert load instructions
      // in all predecessor blocks, not in the PHI block itself!
      if (PHINode *UPN = dyn_cast<PHINode>(U)) {
        // Only insert into each predecessor once, so that we don't have
        // different incoming values from the same block!
        std::map<BasicBlock*, Value*> InsertedBlocks;
        for (unsigned i = 0, e = UPN->getNumIncomingValues(); i != e; ++i)
          if (UPN->getIncomingValue(i) == &I) {
            BasicBlock *Pred = UPN->getIncomingBlock(i);
            Value *&PredVal = InsertedBlocks[Pred];
            if (!PredVal) {
              // Insert a new load instruction right before the terminator in
              // the predecessor block.
              PredVal = new LoadInst(AI, "", Pred->getTerminator());
            }

            UPN->setIncomingValue(i, PredVal);
          }

      } else {
        LoadInst *L = new LoadInst(AI, "", U);
        U->replaceUsesOfWith(&I, L);
      }
    }

    // Thirdly, insert a copy of the instruction in each exit block of the loop
    // that is dominated by the instruction, storing the result into the memory
    // location.  Be careful not to insert the instruction into any particular
    // basic block more than once.
    std::set<BasicBlock*> InsertedBlocks;
    BasicBlock *InstOrigBB = I.getParent();

    for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i) {
      BasicBlock *ExitBlock = ExitBlocks[i];

      if (isExitBlockDominatedByBlockInLoop(ExitBlock, InstOrigBB)) {
        // If we haven't already processed this exit block, do so now.
        if (InsertedBlocks.insert(ExitBlock).second) {
          // Insert the code after the last PHI node...
          BasicBlock::iterator InsertPt = ExitBlock->begin();
          while (isa<PHINode>(InsertPt)) ++InsertPt;

          // If this is the first exit block processed, just move the original
          // instruction, otherwise clone the original instruction and insert
          // the copy.
          Instruction *New;
          if (InsertedBlocks.size() == 1) {
            I.removeFromParent();
            ExitBlock->getInstList().insert(InsertPt, &I);
            New = &I;
          } else {
            New = I.clone();
            CurAST->copyValue(&I, New);
            if (!I.getName().empty())
              New->setName(I.getName()+".le");
            ExitBlock->getInstList().insert(InsertPt, New);
          }

          // Now that we have inserted the instruction, store it into the alloca
          if (AI) new StoreInst(New, AI, InsertPt);
        }
      }
    }

    // If the instruction doesn't dominate any exit blocks, it must be dead.
    if (InsertedBlocks.empty()) {
      CurAST->deleteValue(&I);
      I.eraseFromParent();
    }

    // Finally, promote the fine value to SSA form.
    if (AI) {
      std::vector<AllocaInst*> Allocas;
      Allocas.push_back(AI);
      PromoteMemToReg(Allocas, *ET, *DF, CurAST);
    }
  }
}

/// hoist - When an instruction is found to only use loop invariant operands
/// that is safe to hoist, this instruction is called to do the dirty work.
///
void LICM::hoist(Instruction &I) {
  DOUT << "LICM hoisting to " << Preheader->getName() << ": " << I;

  // Remove the instruction from its current basic block... but don't delete the
  // instruction.
  I.removeFromParent();

  // Insert the new node in Preheader, before the terminator.
  Preheader->getInstList().insert(Preheader->getTerminator(), &I);

  if (isa<LoadInst>(I)) ++NumMovedLoads;
  else if (isa<CallInst>(I)) ++NumMovedCalls;
  ++NumHoisted;
  Changed = true;
}

/// isSafeToExecuteUnconditionally - Only sink or hoist an instruction if it is
/// not a trapping instruction or if it is a trapping instruction and is
/// guaranteed to execute.
///
bool LICM::isSafeToExecuteUnconditionally(Instruction &Inst) {
  // If it is not a trapping instruction, it is always safe to hoist.
  if (!Inst.isTrapping()) return true;

  // Otherwise we have to check to make sure that the instruction dominates all
  // of the exit blocks.  If it doesn't, then there is a path out of the loop
  // which does not execute this instruction, so we can't hoist it.

  // If the instruction is in the header block for the loop (which is very
  // common), it is always guaranteed to dominate the exit blocks.  Since this
  // is a common case, and can save some work, check it now.
  if (Inst.getParent() == CurLoop->getHeader())
    return true;

  // It's always safe to load from a global or alloca.
  if (isa<LoadInst>(Inst))
    if (isa<AllocationInst>(Inst.getOperand(0)) ||
        isa<GlobalVariable>(Inst.getOperand(0)))
      return true;

  // Get the exit blocks for the current loop.
  std::vector<BasicBlock*> ExitBlocks;
  CurLoop->getExitBlocks(ExitBlocks);

  // For each exit block, get the DT node and walk up the DT until the
  // instruction's basic block is found or we exit the loop.
  for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i)
    if (!isExitBlockDominatedByBlockInLoop(ExitBlocks[i], Inst.getParent()))
      return false;

  return true;
}


/// PromoteValuesInLoop - Try to promote memory values to scalars by sinking
/// stores out of the loop and moving loads to before the loop.  We do this by
/// looping over the stores in the loop, looking for stores to Must pointers
/// which are loop invariant.  We promote these memory locations to use allocas
/// instead.  These allocas can easily be raised to register values by the
/// PromoteMem2Reg functionality.
///
void LICM::PromoteValuesInLoop() {
  // PromotedValues - List of values that are promoted out of the loop.  Each
  // value has an alloca instruction for it, and a canonical version of the
  // pointer.
  std::vector<std::pair<AllocaInst*, Value*> > PromotedValues;
  std::map<Value*, AllocaInst*> ValueToAllocaMap; // Map of ptr to alloca

  FindPromotableValuesInLoop(PromotedValues, ValueToAllocaMap);
  if (ValueToAllocaMap.empty()) return;   // If there are values to promote.

  Changed = true;
  NumPromoted += PromotedValues.size();

  std::vector<Value*> PointerValueNumbers;

  // Emit a copy from the value into the alloca'd value in the loop preheader
  TerminatorInst *LoopPredInst = Preheader->getTerminator();
  for (unsigned i = 0, e = PromotedValues.size(); i != e; ++i) {
    Value *Ptr = PromotedValues[i].second;

    // If we are promoting a pointer value, update alias information for the
    // inserted load.
    Value *LoadValue = 0;
    if (isa<PointerType>(cast<PointerType>(Ptr->getType())->getElementType())) {
      // Locate a load or store through the pointer, and assign the same value
      // to LI as we are loading or storing.  Since we know that the value is
      // stored in this loop, this will always succeed.
      for (Value::use_iterator UI = Ptr->use_begin(), E = Ptr->use_end();
           UI != E; ++UI)
        if (LoadInst *LI = dyn_cast<LoadInst>(*UI)) {
          LoadValue = LI;
          break;
        } else if (StoreInst *SI = dyn_cast<StoreInst>(*UI)) {
          if (SI->getOperand(1) == Ptr) {
            LoadValue = SI->getOperand(0);
            break;
          }
        }
      assert(LoadValue && "No store through the pointer found!");
      PointerValueNumbers.push_back(LoadValue);  // Remember this for later.
    }

    // Load from the memory we are promoting.
    LoadInst *LI = new LoadInst(Ptr, Ptr->getName()+".promoted", LoopPredInst);

    if (LoadValue) CurAST->copyValue(LoadValue, LI);

    // Store into the temporary alloca.
    new StoreInst(LI, PromotedValues[i].first, LoopPredInst);
  }

  // Scan the basic blocks in the loop, replacing uses of our pointers with
  // uses of the allocas in question.
  //
  const std::vector<BasicBlock*> &LoopBBs = CurLoop->getBlocks();
  for (std::vector<BasicBlock*>::const_iterator I = LoopBBs.begin(),
         E = LoopBBs.end(); I != E; ++I) {
    // Rewrite all loads and stores in the block of the pointer...
    for (BasicBlock::iterator II = (*I)->begin(), E = (*I)->end();
         II != E; ++II) {
      if (LoadInst *L = dyn_cast<LoadInst>(II)) {
        std::map<Value*, AllocaInst*>::iterator
          I = ValueToAllocaMap.find(L->getOperand(0));
        if (I != ValueToAllocaMap.end())
          L->setOperand(0, I->second);    // Rewrite load instruction...
      } else if (StoreInst *S = dyn_cast<StoreInst>(II)) {
        std::map<Value*, AllocaInst*>::iterator
          I = ValueToAllocaMap.find(S->getOperand(1));
        if (I != ValueToAllocaMap.end())
          S->setOperand(1, I->second);    // Rewrite store instruction...
      }
    }
  }

  // Now that the body of the loop uses the allocas instead of the original
  // memory locations, insert code to copy the alloca value back into the
  // original memory location on all exits from the loop.  Note that we only
  // want to insert one copy of the code in each exit block, though the loop may
  // exit to the same block more than once.
  //
  std::set<BasicBlock*> ProcessedBlocks;

  std::vector<BasicBlock*> ExitBlocks;
  CurLoop->getExitBlocks(ExitBlocks);
  for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i)
    if (ProcessedBlocks.insert(ExitBlocks[i]).second) {
      // Copy all of the allocas into their memory locations.
      BasicBlock::iterator BI = ExitBlocks[i]->begin();
      while (isa<PHINode>(*BI))
        ++BI;             // Skip over all of the phi nodes in the block.
      Instruction *InsertPos = BI;
      unsigned PVN = 0;
      for (unsigned i = 0, e = PromotedValues.size(); i != e; ++i) {
        // Load from the alloca.
        LoadInst *LI = new LoadInst(PromotedValues[i].first, "", InsertPos);

        // If this is a pointer type, update alias info appropriately.
        if (isa<PointerType>(LI->getType()))
          CurAST->copyValue(PointerValueNumbers[PVN++], LI);

        // Store into the memory we promoted.
        new StoreInst(LI, PromotedValues[i].second, InsertPos);
      }
    }

  // Now that we have done the deed, use the mem2reg functionality to promote
  // all of the new allocas we just created into real SSA registers.
  //
  std::vector<AllocaInst*> PromotedAllocas;
  PromotedAllocas.reserve(PromotedValues.size());
  for (unsigned i = 0, e = PromotedValues.size(); i != e; ++i)
    PromotedAllocas.push_back(PromotedValues[i].first);
  PromoteMemToReg(PromotedAllocas, *ET, *DF, CurAST);
}

/// FindPromotableValuesInLoop - Check the current loop for stores to definite
/// pointers, which are not loaded and stored through may aliases.  If these are
/// found, create an alloca for the value, add it to the PromotedValues list,
/// and keep track of the mapping from value to alloca.
///
void LICM::FindPromotableValuesInLoop(
                   std::vector<std::pair<AllocaInst*, Value*> > &PromotedValues,
                             std::map<Value*, AllocaInst*> &ValueToAllocaMap) {
  Instruction *FnStart = CurLoop->getHeader()->getParent()->begin()->begin();

  // Loop over all of the alias sets in the tracker object.
  for (AliasSetTracker::iterator I = CurAST->begin(), E = CurAST->end();
       I != E; ++I) {
    AliasSet &AS = *I;
    // We can promote this alias set if it has a store, if it is a "Must" alias
    // set, if the pointer is loop invariant, and if we are not eliminating any
    // volatile loads or stores.
    if (!AS.isForwardingAliasSet() && AS.isMod() && AS.isMustAlias() &&
        !AS.isVolatile() && CurLoop->isLoopInvariant(AS.begin()->first)) {
      assert(AS.begin() != AS.end() &&
             "Must alias set should have at least one pointer element in it!");
      Value *V = AS.begin()->first;

      // Check that all of the pointers in the alias set have the same type.  We
      // cannot (yet) promote a memory location that is loaded and stored in
      // different sizes.
      bool PointerOk = true;
      for (AliasSet::iterator I = AS.begin(), E = AS.end(); I != E; ++I)
        if (V->getType() != I->first->getType()) {
          PointerOk = false;
          break;
        }

      if (PointerOk) {
        const Type *Ty = cast<PointerType>(V->getType())->getElementType();
        AllocaInst *AI = new AllocaInst(Ty, 0, V->getName()+".tmp", FnStart);
        PromotedValues.push_back(std::make_pair(AI, V));

        // Update the AST and alias analysis.
        CurAST->copyValue(V, AI);

        for (AliasSet::iterator I = AS.begin(), E = AS.end(); I != E; ++I)
          ValueToAllocaMap.insert(std::make_pair(I->first, AI));

        DOUT << "LICM: Promoting value: " << *V << "\n";
      }
    }
  }
}
