//===-- PhiElimination.cpp - Eliminate PHI nodes by inserting copies ------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This pass eliminates machine instruction PHI nodes by inserting copy
// instructions.  This destroys SSA information, but is the desired input for
// some register allocators.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "phielim"
#include "llvm/CodeGen/LiveVariables.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/Compiler.h"
#include <set>
#include <algorithm>
using namespace llvm;

STATISTIC(NumAtomic, "Number of atomic phis lowered");
//STATISTIC(NumSimple, "Number of simple phis lowered");

namespace {
  struct VISIBILITY_HIDDEN PNE : public MachineFunctionPass {
    static char ID; // Pass identification, replacement for typeid
    PNE() : MachineFunctionPass((intptr_t)&ID) {}

    bool runOnMachineFunction(MachineFunction &Fn) {
      analyzePHINodes(Fn);

      bool Changed = false;

      // Eliminate PHI instructions by inserting copies into predecessor blocks.
      for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I)
        Changed |= EliminatePHINodes(Fn, *I);

      VRegPHIUseCount.clear();
      return Changed;
    }

    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
      AU.addPreserved<LiveVariables>();
      AU.addPreservedID(MachineLoopInfoID);
      AU.addPreservedID(MachineDominatorsID);
      MachineFunctionPass::getAnalysisUsage(AU);
    }

  private:
    /// EliminatePHINodes - Eliminate phi nodes by inserting copy instructions
    /// in predecessor basic blocks.
    ///
    bool EliminatePHINodes(MachineFunction &MF, MachineBasicBlock &MBB);
    void LowerAtomicPHINode(MachineBasicBlock &MBB,
                            MachineBasicBlock::iterator AfterPHIsIt);

    /// analyzePHINodes - Gather information about the PHI nodes in
    /// here. In particular, we want to map the number of uses of a virtual
    /// register which is used in a PHI node. We map that to the BB the
    /// vreg is coming from. This is used later to determine when the vreg
    /// is killed in the BB.
    ///
    void analyzePHINodes(const MachineFunction& Fn);

    typedef std::pair<const MachineBasicBlock*, unsigned> BBVRegPair;
    typedef std::map<BBVRegPair, unsigned> VRegPHIUse;

    VRegPHIUse VRegPHIUseCount;
  };

  char PNE::ID = 0;
  RegisterPass<PNE> X("phi-node-elimination",
                      "Eliminate PHI nodes for register allocation");
}

const PassInfo *llvm::PHIEliminationID = X.getPassInfo();

/// EliminatePHINodes - Eliminate phi nodes by inserting copy instructions in
/// predecessor basic blocks.
///
bool PNE::EliminatePHINodes(MachineFunction &MF, MachineBasicBlock &MBB) {
  if (MBB.empty() || MBB.front().getOpcode() != TargetInstrInfo::PHI)
    return false;   // Quick exit for basic blocks without PHIs.

  // Get an iterator to the first instruction after the last PHI node (this may
  // also be the end of the basic block).
  MachineBasicBlock::iterator AfterPHIsIt = MBB.begin();
  while (AfterPHIsIt != MBB.end() &&
         AfterPHIsIt->getOpcode() == TargetInstrInfo::PHI)
    ++AfterPHIsIt;    // Skip over all of the PHI nodes...

  while (MBB.front().getOpcode() == TargetInstrInfo::PHI)
    LowerAtomicPHINode(MBB, AfterPHIsIt);

  return true;
}

/// InstructionUsesRegister - Return true if the specified machine instr has a
/// use of the specified register.
static bool InstructionUsesRegister(MachineInstr *MI, unsigned SrcReg) {
  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i)
    if (MI->getOperand(i).isRegister() &&
        MI->getOperand(i).getReg() == SrcReg &&
        MI->getOperand(i).isUse())
      return true;
  return false;
}

/// LowerAtomicPHINode - Lower the PHI node at the top of the specified block,
/// under the assuption that it needs to be lowered in a way that supports
/// atomic execution of PHIs.  This lowering method is always correct all of the
/// time.
void PNE::LowerAtomicPHINode(MachineBasicBlock &MBB,
                             MachineBasicBlock::iterator AfterPHIsIt) {
  // Unlink the PHI node from the basic block, but don't delete the PHI yet.
  MachineInstr *MPhi = MBB.remove(MBB.begin());

  unsigned DestReg = MPhi->getOperand(0).getReg();

  // Create a new register for the incoming PHI arguments.
  MachineFunction &MF = *MBB.getParent();
  const TargetRegisterClass *RC = MF.getRegInfo().getRegClass(DestReg);
  unsigned IncomingReg = MF.getRegInfo().createVirtualRegister(RC);

  // Insert a register to register copy in the top of the current block (but
  // after any remaining phi nodes) which copies the new incoming register
  // into the phi node destination.
  //
  const TargetInstrInfo *TII = MF.getTarget().getInstrInfo();
  TII->copyRegToReg(MBB, AfterPHIsIt, DestReg, IncomingReg, RC, RC);

  // Update live variable information if there is any...
  LiveVariables *LV = getAnalysisToUpdate<LiveVariables>();
  if (LV) {
    MachineInstr *PHICopy = prior(AfterPHIsIt);

    // Increment use count of the newly created virtual register.
    LV->getVarInfo(IncomingReg).NumUses++;

    // Add information to LiveVariables to know that the incoming value is
    // killed.  Note that because the value is defined in several places (once
    // each for each incoming block), the "def" block and instruction fields
    // for the VarInfo is not filled in.
    //
    LV->addVirtualRegisterKilled(IncomingReg, PHICopy);

    // Since we are going to be deleting the PHI node, if it is the last use
    // of any registers, or if the value itself is dead, we need to move this
    // information over to the new copy we just inserted.
    //
    LV->removeVirtualRegistersKilled(MPhi);

    // If the result is dead, update LV.
    if (LV->RegisterDefIsDead(MPhi, DestReg)) {
      LV->addVirtualRegisterDead(DestReg, PHICopy);
      LV->removeVirtualRegistersDead(MPhi);
    }

    LV->getVarInfo(IncomingReg).UsedBlocks[MBB.getNumber()] = true;
  }

  // Adjust the VRegPHIUseCount map to account for the removal of this PHI
  // node.
  for (unsigned i = 1; i != MPhi->getNumOperands(); i += 2)
    --VRegPHIUseCount[BBVRegPair(MPhi->getOperand(i + 1).getMBB(),
                                 MPhi->getOperand(i).getReg())];

  // Now loop over all of the incoming arguments, changing them to copy into
  // the IncomingReg register in the corresponding predecessor basic block.
  //
  std::set<MachineBasicBlock*> MBBsInsertedInto;
  for (int i = MPhi->getNumOperands() - 1; i >= 2; i-=2) {
    unsigned SrcReg = MPhi->getOperand(i-1).getReg();
    assert(MRegisterInfo::isVirtualRegister(SrcReg) &&
           "Machine PHI Operands must all be virtual registers!");

    // Get the MachineBasicBlock equivalent of the BasicBlock that is the
    // source path the PHI.
    MachineBasicBlock &opBlock = *MPhi->getOperand(i).getMBB();

    // Check to make sure we haven't already emitted the copy for this block.
    // This can happen because PHI nodes may have multiple entries for the
    // same basic block.
    if (!MBBsInsertedInto.insert(&opBlock).second)
      continue;  // If the copy has already been emitted, we're done.
 
    // Get an iterator pointing to the first terminator in the block (or end()).
    // This is the point where we can insert a copy if we'd like to.
    MachineBasicBlock::iterator I = opBlock.getFirstTerminator();
    
    // Insert the copy.
    TII->copyRegToReg(opBlock, I, IncomingReg, SrcReg, RC, RC);

    // Now update live variable information if we have it.  Otherwise we're done
    if (!LV) continue;
    
    // We want to be able to insert a kill of the register if this PHI
    // (aka, the copy we just inserted) is the last use of the source
    // value.  Live variable analysis conservatively handles this by
    // saying that the value is live until the end of the block the PHI
    // entry lives in.  If the value really is dead at the PHI copy, there
    // will be no successor blocks which have the value live-in.
    //
    // Check to see if the copy is the last use, and if so, update the
    // live variables information so that it knows the copy source
    // instruction kills the incoming value.
    //
    LiveVariables::VarInfo &InRegVI = LV->getVarInfo(SrcReg);
    InRegVI.UsedBlocks[opBlock.getNumber()] = true;

    // Loop over all of the successors of the basic block, checking to see
    // if the value is either live in the block, or if it is killed in the
    // block.  Also check to see if this register is in use by another PHI
    // node which has not yet been eliminated.  If so, it will be killed
    // at an appropriate point later.
    //

    // Is it used by any PHI instructions in this block?
    bool ValueIsLive = VRegPHIUseCount[BBVRegPair(&opBlock, SrcReg)] != 0;

    std::vector<MachineBasicBlock*> OpSuccBlocks;
    
    // Otherwise, scan successors, including the BB the PHI node lives in.
    for (MachineBasicBlock::succ_iterator SI = opBlock.succ_begin(),
           E = opBlock.succ_end(); SI != E && !ValueIsLive; ++SI) {
      MachineBasicBlock *SuccMBB = *SI;

      // Is it alive in this successor?
      unsigned SuccIdx = SuccMBB->getNumber();
      if (SuccIdx < InRegVI.AliveBlocks.size() &&
          InRegVI.AliveBlocks[SuccIdx]) {
        ValueIsLive = true;
        break;
      }

      OpSuccBlocks.push_back(SuccMBB);
    }

    // Check to see if this value is live because there is a use in a successor
    // that kills it.
    if (!ValueIsLive) {
      switch (OpSuccBlocks.size()) {
      case 1: {
        MachineBasicBlock *MBB = OpSuccBlocks[0];
        for (unsigned i = 0, e = InRegVI.Kills.size(); i != e; ++i)
          if (InRegVI.Kills[i]->getParent() == MBB) {
            ValueIsLive = true;
            break;
          }
        break;
      }
      case 2: {
        MachineBasicBlock *MBB1 = OpSuccBlocks[0], *MBB2 = OpSuccBlocks[1];
        for (unsigned i = 0, e = InRegVI.Kills.size(); i != e; ++i)
          if (InRegVI.Kills[i]->getParent() == MBB1 || 
              InRegVI.Kills[i]->getParent() == MBB2) {
            ValueIsLive = true;
            break;
          }
        break;        
      }
      default:
        std::sort(OpSuccBlocks.begin(), OpSuccBlocks.end());
        for (unsigned i = 0, e = InRegVI.Kills.size(); i != e; ++i)
          if (std::binary_search(OpSuccBlocks.begin(), OpSuccBlocks.end(),
                                 InRegVI.Kills[i]->getParent())) {
            ValueIsLive = true;
            break;
          }
      }
    }        

    // Okay, if we now know that the value is not live out of the block,
    // we can add a kill marker in this block saying that it kills the incoming
    // value!
    if (!ValueIsLive) {
      // In our final twist, we have to decide which instruction kills the
      // register.  In most cases this is the copy, however, the first 
      // terminator instruction at the end of the block may also use the value.
      // In this case, we should mark *it* as being the killing block, not the
      // copy.
      bool FirstTerminatorUsesValue = false;
      if (I != opBlock.end()) {
        FirstTerminatorUsesValue = InstructionUsesRegister(I, SrcReg);
      
        // Check that no other terminators use values.
#ifndef NDEBUG
        for (MachineBasicBlock::iterator TI = next(I); TI != opBlock.end();
             ++TI) {
          assert(!InstructionUsesRegister(TI, SrcReg) &&
                 "Terminator instructions cannot use virtual registers unless"
                 "they are the first terminator in a block!");
        }
#endif
      }
      
      MachineBasicBlock::iterator KillInst;
      if (!FirstTerminatorUsesValue) 
        KillInst = prior(I);
      else
        KillInst = I;
      
      // Finally, mark it killed.
      LV->addVirtualRegisterKilled(SrcReg, KillInst);

      // This vreg no longer lives all of the way through opBlock.
      unsigned opBlockNum = opBlock.getNumber();
      if (opBlockNum < InRegVI.AliveBlocks.size())
        InRegVI.AliveBlocks[opBlockNum] = false;
    }
  }
    
  // Really delete the PHI instruction now!
  delete MPhi;
  ++NumAtomic;
}

/// analyzePHINodes - Gather information about the PHI nodes in here. In
/// particular, we want to map the number of uses of a virtual register which is
/// used in a PHI node. We map that to the BB the vreg is coming from. This is
/// used later to determine when the vreg is killed in the BB.
///
void PNE::analyzePHINodes(const MachineFunction& Fn) {
  for (MachineFunction::const_iterator I = Fn.begin(), E = Fn.end();
       I != E; ++I)
    for (MachineBasicBlock::const_iterator BBI = I->begin(), BBE = I->end();
         BBI != BBE && BBI->getOpcode() == TargetInstrInfo::PHI; ++BBI)
      for (unsigned i = 1, e = BBI->getNumOperands(); i != e; i += 2)
        ++VRegPHIUseCount[BBVRegPair(BBI->getOperand(i + 1).getMBB(),
                                     BBI->getOperand(i).getReg())];
}
