//===- SparsePropagation.cpp - Sparse Conditional Property Propagation ----===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements an abstract sparse conditional propagation algorithm,
// modeled after SCCP, but with a customizable lattice function.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "sparseprop"
#include "llvm/Analysis/SparsePropagation.h"
#include "llvm/Constants.h"
#include "llvm/Function.h"
#include "llvm/Instructions.h"
#include "llvm/Support/Debug.h"
using namespace llvm;

//===----------------------------------------------------------------------===//
//                  AbstractLatticeFunction Implementation
//===----------------------------------------------------------------------===//

AbstractLatticeFunction::~AbstractLatticeFunction() {}

/// PrintValue - Render the specified lattice value to the specified stream.
void AbstractLatticeFunction::PrintValue(LatticeVal V, std::ostream &OS) {
  if (V == UndefVal)
    OS << "undefined";
  else if (V == OverdefinedVal)
    OS << "overdefined";
  else if (V == UntrackedVal)
    OS << "untracked";
  else
    OS << "unknown lattice value";
}

//===----------------------------------------------------------------------===//
//                          SparseSolver Implementation
//===----------------------------------------------------------------------===//

/// getOrInitValueState - Return the LatticeVal object that corresponds to the
/// value, initializing the value's state if it hasn't been entered into the
/// map yet.   This function is necessary because not all values should start
/// out in the underdefined state... Arguments should be overdefined, and
/// constants should be marked as constants.
///
SparseSolver::LatticeVal SparseSolver::getOrInitValueState(Value *V) {
  DenseMap<Value*, LatticeVal>::iterator I = ValueState.find(V);
  if (I != ValueState.end()) return I->second;  // Common case, in the map
  
  LatticeVal LV;
  if (LatticeFunc->IsUntrackedValue(V))
    return LatticeFunc->getUntrackedVal();
  else if (Constant *C = dyn_cast<Constant>(V))
    LV = LatticeFunc->ComputeConstant(C);
  else if (Argument *A = dyn_cast<Argument>(V))
    LV = LatticeFunc->ComputeArgument(A);
  else if (!isa<Instruction>(V))
    // All other non-instructions are overdefined.
    LV = LatticeFunc->getOverdefinedVal();
  else
    // All instructions are underdefined by default.
    LV = LatticeFunc->getUndefVal();
  
  // If this value is untracked, don't add it to the map.
  if (LV == LatticeFunc->getUntrackedVal())
    return LV;
  return ValueState[V] = LV;
}

/// UpdateState - When the state for some instruction is potentially updated,
/// this function notices and adds I to the worklist if needed.
void SparseSolver::UpdateState(Instruction &Inst, LatticeVal V) {
  DenseMap<Value*, LatticeVal>::iterator I = ValueState.find(&Inst);
  if (I != ValueState.end() && I->second == V)
    return;  // No change.
  
  // An update.  Visit uses of I.
  ValueState[&Inst] = V;
  InstWorkList.push_back(&Inst);
}

/// MarkBlockExecutable - This method can be used by clients to mark all of
/// the blocks that are known to be intrinsically live in the processed unit.
void SparseSolver::MarkBlockExecutable(BasicBlock *BB) {
  DOUT << "Marking Block Executable: " << BB->getNameStart() << "\n";
  BBExecutable.insert(BB);   // Basic block is executable!
  BBWorkList.push_back(BB);  // Add the block to the work list!
}

/// markEdgeExecutable - Mark a basic block as executable, adding it to the BB
/// work list if it is not already executable...
void SparseSolver::markEdgeExecutable(BasicBlock *Source, BasicBlock *Dest) {
  if (!KnownFeasibleEdges.insert(Edge(Source, Dest)).second)
    return;  // This edge is already known to be executable!
  
  DOUT << "Marking Edge Executable: " << Source->getNameStart()
       << " -> " << Dest->getNameStart() << "\n";

  if (BBExecutable.count(Dest)) {
    // The destination is already executable, but we just made an edge
    // feasible that wasn't before.  Revisit the PHI nodes in the block
    // because they have potentially new operands.
    for (BasicBlock::iterator I = Dest->begin(); isa<PHINode>(I); ++I)
      visitPHINode(*cast<PHINode>(I));
    
  } else {
    MarkBlockExecutable(Dest);
  }
}


/// getFeasibleSuccessors - Return a vector of booleans to indicate which
/// successors are reachable from a given terminator instruction.
void SparseSolver::getFeasibleSuccessors(TerminatorInst &TI,
                                         SmallVectorImpl<bool> &Succs,
                                         bool AggressiveUndef) {
  Succs.resize(TI.getNumSuccessors());
  if (TI.getNumSuccessors() == 0) return;
  
  if (BranchInst *BI = dyn_cast<BranchInst>(&TI)) {
    if (BI->isUnconditional()) {
      Succs[0] = true;
      return;
    }
    
    LatticeVal BCValue;
    if (AggressiveUndef)
      BCValue = getOrInitValueState(BI->getCondition());
    else
      BCValue = getLatticeState(BI->getCondition());
    
    if (BCValue == LatticeFunc->getOverdefinedVal() ||
        BCValue == LatticeFunc->getUntrackedVal()) {
      // Overdefined condition variables can branch either way.
      Succs[0] = Succs[1] = true;
      return;
    }

    // If undefined, neither is feasible yet.
    if (BCValue == LatticeFunc->getUndefVal())
      return;

    Constant *C = LatticeFunc->GetConstant(BCValue, BI->getCondition(), *this);
    if (C == 0 || !isa<ConstantInt>(C)) {
      // Non-constant values can go either way.
      Succs[0] = Succs[1] = true;
      return;
    }

    // Constant condition variables mean the branch can only go a single way
    Succs[C == ConstantInt::getFalse()] = true;
    return;
  }
  
  if (isa<InvokeInst>(TI)) {
    // Invoke instructions successors are always executable.
    // TODO: Could ask the lattice function if the value can throw.
    Succs[0] = Succs[1] = true;
    return;
  }
  
  SwitchInst &SI = cast<SwitchInst>(TI);
  LatticeVal SCValue;
  if (AggressiveUndef)
    SCValue = getOrInitValueState(SI.getCondition());
  else
    SCValue = getLatticeState(SI.getCondition());
  
  if (SCValue == LatticeFunc->getOverdefinedVal() ||
      SCValue == LatticeFunc->getUntrackedVal()) {
    // All destinations are executable!
    Succs.assign(TI.getNumSuccessors(), true);
    return;
  }
  
  // If undefined, neither is feasible yet.
  if (SCValue == LatticeFunc->getUndefVal())
    return;
  
  Constant *C = LatticeFunc->GetConstant(SCValue, SI.getCondition(), *this);
  if (C == 0 || !isa<ConstantInt>(C)) {
    // All destinations are executable!
    Succs.assign(TI.getNumSuccessors(), true);
    return;
  }
  
  Succs[SI.findCaseValue(cast<ConstantInt>(C))] = true;
}


/// isEdgeFeasible - Return true if the control flow edge from the 'From'
/// basic block to the 'To' basic block is currently feasible...
bool SparseSolver::isEdgeFeasible(BasicBlock *From, BasicBlock *To,
                                  bool AggressiveUndef) {
  SmallVector<bool, 16> SuccFeasible;
  TerminatorInst *TI = From->getTerminator();
  getFeasibleSuccessors(*TI, SuccFeasible, AggressiveUndef);
  
  for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i)
    if (TI->getSuccessor(i) == To && SuccFeasible[i])
      return true;
  
  return false;
}

void SparseSolver::visitTerminatorInst(TerminatorInst &TI) {
  SmallVector<bool, 16> SuccFeasible;
  getFeasibleSuccessors(TI, SuccFeasible, true);
  
  BasicBlock *BB = TI.getParent();
  
  // Mark all feasible successors executable...
  for (unsigned i = 0, e = SuccFeasible.size(); i != e; ++i)
    if (SuccFeasible[i])
      markEdgeExecutable(BB, TI.getSuccessor(i));
}

void SparseSolver::visitPHINode(PHINode &PN) {
  LatticeVal PNIV = getOrInitValueState(&PN);
  LatticeVal Overdefined = LatticeFunc->getOverdefinedVal();
  
  // If this value is already overdefined (common) just return.
  if (PNIV == Overdefined || PNIV == LatticeFunc->getUntrackedVal())
    return;  // Quick exit
  
  // Super-extra-high-degree PHI nodes are unlikely to ever be interesting,
  // and slow us down a lot.  Just mark them overdefined.
  if (PN.getNumIncomingValues() > 64) {
    UpdateState(PN, Overdefined);
    return;
  }
  
  // Look at all of the executable operands of the PHI node.  If any of them
  // are overdefined, the PHI becomes overdefined as well.  Otherwise, ask the
  // transfer function to give us the merge of the incoming values.
  for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) {
    // If the edge is not yet known to be feasible, it doesn't impact the PHI.
    if (!isEdgeFeasible(PN.getIncomingBlock(i), PN.getParent(), true))
      continue;
    
    // Merge in this value.
    LatticeVal OpVal = getOrInitValueState(PN.getIncomingValue(i));
    if (OpVal != PNIV)
      PNIV = LatticeFunc->MergeValues(PNIV, OpVal);
    
    if (PNIV == Overdefined)
      break;  // Rest of input values don't matter.
  }

  // Update the PHI with the compute value, which is the merge of the inputs.
  UpdateState(PN, PNIV);
}


void SparseSolver::visitInst(Instruction &I) {
  // PHIs are handled by the propagation logic, they are never passed into the
  // transfer functions.
  if (PHINode *PN = dyn_cast<PHINode>(&I))
    return visitPHINode(*PN);
  
  // Otherwise, ask the transfer function what the result is.  If this is
  // something that we care about, remember it.
  LatticeVal IV = LatticeFunc->ComputeInstructionState(I, *this);
  if (IV != LatticeFunc->getUntrackedVal())
    UpdateState(I, IV);
  
  if (TerminatorInst *TI = dyn_cast<TerminatorInst>(&I))
    visitTerminatorInst(*TI);
}

void SparseSolver::Solve(Function &F) {
  MarkBlockExecutable(&F.getEntryBlock());
  
  // Process the work lists until they are empty!
  while (!BBWorkList.empty() || !InstWorkList.empty()) {
    // Process the instruction work list.
    while (!InstWorkList.empty()) {
      Instruction *I = InstWorkList.back();
      InstWorkList.pop_back();

      DOUT << "\nPopped off I-WL: " << *I;

      // "I" got into the work list because it made a transition.  See if any
      // users are both live and in need of updating.
      for (Value::use_iterator UI = I->use_begin(), E = I->use_end();
           UI != E; ++UI) {
        Instruction *U = cast<Instruction>(*UI);
        if (BBExecutable.count(U->getParent()))   // Inst is executable?
          visitInst(*U);
      }
    }

    // Process the basic block work list.
    while (!BBWorkList.empty()) {
      BasicBlock *BB = BBWorkList.back();
      BBWorkList.pop_back();

      DOUT << "\nPopped off BBWL: " << *BB;

      // Notify all instructions in this basic block that they are newly
      // executable.
      for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I)
        visitInst(*I);
    }
  }
}

void SparseSolver::Print(Function &F, std::ostream &OS) {
  OS << "\nFUNCTION: " << F.getNameStr() << "\n";
  for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
    if (!BBExecutable.count(BB))
      OS << "INFEASIBLE: ";
    OS << "\t";
    if (BB->hasName())
      OS << BB->getNameStr() << ":\n";
    else
      OS << "; anon bb\n";
    for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) {
      LatticeFunc->PrintValue(getLatticeState(I), OS);
      OS << *I;
    }
    
    OS << "\n";
  }
}

