LCOV - code coverage report
Current view: top level - lib/Analysis - SparsePropagation.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 0 152 0.0 %
Date: 2017-09-14 15:23:50 Functions: 0 12 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- SparsePropagation.cpp - Sparse Conditional Property Propagation ----===//
       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             : // This file implements an abstract sparse conditional propagation algorithm,
      11             : // modeled after SCCP, but with a customizable lattice function.
      12             : //
      13             : //===----------------------------------------------------------------------===//
      14             : 
      15             : #include "llvm/Analysis/SparsePropagation.h"
      16             : #include "llvm/ADT/DenseMap.h"
      17             : #include "llvm/ADT/SmallVector.h"
      18             : #include "llvm/IR/Argument.h"
      19             : #include "llvm/IR/BasicBlock.h"
      20             : #include "llvm/IR/Constant.h"
      21             : #include "llvm/IR/Constants.h"
      22             : #include "llvm/IR/Function.h"
      23             : #include "llvm/IR/InstrTypes.h"
      24             : #include "llvm/IR/Instruction.h"
      25             : #include "llvm/IR/Instructions.h"
      26             : #include "llvm/IR/User.h"
      27             : #include "llvm/Support/Casting.h"
      28             : #include "llvm/Support/Debug.h"
      29             : #include "llvm/Support/raw_ostream.h"
      30             : 
      31             : using namespace llvm;
      32             : 
      33             : #define DEBUG_TYPE "sparseprop"
      34             : 
      35             : //===----------------------------------------------------------------------===//
      36             : //                  AbstractLatticeFunction Implementation
      37             : //===----------------------------------------------------------------------===//
      38             : 
      39             : AbstractLatticeFunction::~AbstractLatticeFunction() = default;
      40             : 
      41             : /// PrintValue - Render the specified lattice value to the specified stream.
      42           0 : void AbstractLatticeFunction::PrintValue(LatticeVal V, raw_ostream &OS) {
      43           0 :   if (V == UndefVal)
      44           0 :     OS << "undefined";
      45           0 :   else if (V == OverdefinedVal)
      46           0 :     OS << "overdefined";
      47           0 :   else if (V == UntrackedVal)
      48           0 :     OS << "untracked";
      49             :   else
      50           0 :     OS << "unknown lattice value";
      51           0 : }
      52             : 
      53             : //===----------------------------------------------------------------------===//
      54             : //                          SparseSolver Implementation
      55             : //===----------------------------------------------------------------------===//
      56             : 
      57             : /// getOrInitValueState - Return the LatticeVal object that corresponds to the
      58             : /// value, initializing the value's state if it hasn't been entered into the
      59             : /// map yet.   This function is necessary because not all values should start
      60             : /// out in the underdefined state... Arguments should be overdefined, and
      61             : /// constants should be marked as constants.
      62           0 : SparseSolver::LatticeVal SparseSolver::getOrInitValueState(Value *V) {
      63           0 :   DenseMap<Value*, LatticeVal>::iterator I = ValueState.find(V);
      64           0 :   if (I != ValueState.end()) return I->second;  // Common case, in the map
      65             :   
      66             :   LatticeVal LV;
      67           0 :   if (LatticeFunc->IsUntrackedValue(V))
      68           0 :     return LatticeFunc->getUntrackedVal();
      69           0 :   else if (Constant *C = dyn_cast<Constant>(V))
      70           0 :     LV = LatticeFunc->ComputeConstant(C);
      71           0 :   else if (Argument *A = dyn_cast<Argument>(V))
      72           0 :     LV = LatticeFunc->ComputeArgument(A);
      73           0 :   else if (!isa<Instruction>(V))
      74             :     // All other non-instructions are overdefined.
      75           0 :     LV = LatticeFunc->getOverdefinedVal();
      76             :   else
      77             :     // All instructions are underdefined by default.
      78           0 :     LV = LatticeFunc->getUndefVal();
      79             :   
      80             :   // If this value is untracked, don't add it to the map.
      81           0 :   if (LV == LatticeFunc->getUntrackedVal())
      82             :     return LV;
      83           0 :   return ValueState[V] = LV;
      84             : }
      85             : 
      86             : /// UpdateState - When the state for some instruction is potentially updated,
      87             : /// this function notices and adds I to the worklist if needed.
      88           0 : void SparseSolver::UpdateState(Instruction &Inst, LatticeVal V) {
      89           0 :   DenseMap<Value*, LatticeVal>::iterator I = ValueState.find(&Inst);
      90           0 :   if (I != ValueState.end() && I->second == V)
      91           0 :     return;  // No change.
      92             :   
      93             :   // An update.  Visit uses of I.
      94           0 :   ValueState[&Inst] = V;
      95           0 :   InstWorkList.push_back(&Inst);
      96             : }
      97             : 
      98             : /// MarkBlockExecutable - This method can be used by clients to mark all of
      99             : /// the blocks that are known to be intrinsically live in the processed unit.
     100           0 : void SparseSolver::MarkBlockExecutable(BasicBlock *BB) {
     101             :   DEBUG(dbgs() << "Marking Block Executable: " << BB->getName() << "\n");
     102           0 :   BBExecutable.insert(BB);   // Basic block is executable!
     103           0 :   BBWorkList.push_back(BB);  // Add the block to the work list!
     104           0 : }
     105             : 
     106             : /// markEdgeExecutable - Mark a basic block as executable, adding it to the BB
     107             : /// work list if it is not already executable...
     108           0 : void SparseSolver::markEdgeExecutable(BasicBlock *Source, BasicBlock *Dest) {
     109           0 :   if (!KnownFeasibleEdges.insert(Edge(Source, Dest)).second)
     110             :     return;  // This edge is already known to be executable!
     111             :   
     112             :   DEBUG(dbgs() << "Marking Edge Executable: " << Source->getName()
     113             :         << " -> " << Dest->getName() << "\n");
     114             : 
     115           0 :   if (BBExecutable.count(Dest)) {
     116             :     // The destination is already executable, but we just made an edge
     117             :     // feasible that wasn't before.  Revisit the PHI nodes in the block
     118             :     // because they have potentially new operands.
     119           0 :     for (BasicBlock::iterator I = Dest->begin(); isa<PHINode>(I); ++I)
     120           0 :       visitPHINode(*cast<PHINode>(I));
     121             :   } else {
     122           0 :     MarkBlockExecutable(Dest);
     123             :   }
     124             : }
     125             : 
     126             : /// getFeasibleSuccessors - Return a vector of booleans to indicate which
     127             : /// successors are reachable from a given terminator instruction.
     128           0 : void SparseSolver::getFeasibleSuccessors(TerminatorInst &TI,
     129             :                                          SmallVectorImpl<bool> &Succs,
     130             :                                          bool AggressiveUndef) {
     131           0 :   Succs.resize(TI.getNumSuccessors());
     132           0 :   if (TI.getNumSuccessors() == 0) return;
     133             :   
     134           0 :   if (BranchInst *BI = dyn_cast<BranchInst>(&TI)) {
     135           0 :     if (BI->isUnconditional()) {
     136           0 :       Succs[0] = true;
     137           0 :       return;
     138             :     }
     139             :     
     140             :     LatticeVal BCValue;
     141           0 :     if (AggressiveUndef)
     142           0 :       BCValue = getOrInitValueState(BI->getCondition());
     143             :     else
     144           0 :       BCValue = getLatticeState(BI->getCondition());
     145             :     
     146           0 :     if (BCValue == LatticeFunc->getOverdefinedVal() ||
     147           0 :         BCValue == LatticeFunc->getUntrackedVal()) {
     148             :       // Overdefined condition variables can branch either way.
     149           0 :       Succs[0] = Succs[1] = true;
     150           0 :       return;
     151             :     }
     152             : 
     153             :     // If undefined, neither is feasible yet.
     154           0 :     if (BCValue == LatticeFunc->getUndefVal())
     155             :       return;
     156             : 
     157           0 :     Constant *C = LatticeFunc->GetConstant(BCValue, BI->getCondition(), *this);
     158           0 :     if (!C || !isa<ConstantInt>(C)) {
     159             :       // Non-constant values can go either way.
     160           0 :       Succs[0] = Succs[1] = true;
     161           0 :       return;
     162             :     }
     163             : 
     164             :     // Constant condition variables mean the branch can only go a single way
     165           0 :     Succs[C->isNullValue()] = true;
     166           0 :     return;
     167             :   }
     168             :   
     169           0 :   if (isa<InvokeInst>(TI)) {
     170             :     // Invoke instructions successors are always executable.
     171             :     // TODO: Could ask the lattice function if the value can throw.
     172           0 :     Succs[0] = Succs[1] = true;
     173           0 :     return;
     174             :   }
     175             :   
     176           0 :   if (isa<IndirectBrInst>(TI)) {
     177           0 :     Succs.assign(Succs.size(), true);
     178           0 :     return;
     179             :   }
     180             :   
     181           0 :   SwitchInst &SI = cast<SwitchInst>(TI);
     182             :   LatticeVal SCValue;
     183           0 :   if (AggressiveUndef)
     184           0 :     SCValue = getOrInitValueState(SI.getCondition());
     185             :   else
     186           0 :     SCValue = getLatticeState(SI.getCondition());
     187             :   
     188           0 :   if (SCValue == LatticeFunc->getOverdefinedVal() ||
     189           0 :       SCValue == LatticeFunc->getUntrackedVal()) {
     190             :     // All destinations are executable!
     191           0 :     Succs.assign(TI.getNumSuccessors(), true);
     192           0 :     return;
     193             :   }
     194             :   
     195             :   // If undefined, neither is feasible yet.
     196           0 :   if (SCValue == LatticeFunc->getUndefVal())
     197             :     return;
     198             :   
     199           0 :   Constant *C = LatticeFunc->GetConstant(SCValue, SI.getCondition(), *this);
     200           0 :   if (!C || !isa<ConstantInt>(C)) {
     201             :     // All destinations are executable!
     202           0 :     Succs.assign(TI.getNumSuccessors(), true);
     203           0 :     return;
     204             :   }
     205           0 :   SwitchInst::CaseHandle Case = *SI.findCaseValue(cast<ConstantInt>(C));
     206           0 :   Succs[Case.getSuccessorIndex()] = true;
     207             : }
     208             : 
     209             : /// isEdgeFeasible - Return true if the control flow edge from the 'From'
     210             : /// basic block to the 'To' basic block is currently feasible...
     211           0 : bool SparseSolver::isEdgeFeasible(BasicBlock *From, BasicBlock *To,
     212             :                                   bool AggressiveUndef) {
     213           0 :   SmallVector<bool, 16> SuccFeasible;
     214           0 :   TerminatorInst *TI = From->getTerminator();
     215           0 :   getFeasibleSuccessors(*TI, SuccFeasible, AggressiveUndef);
     216             :   
     217           0 :   for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i)
     218           0 :     if (TI->getSuccessor(i) == To && SuccFeasible[i])
     219             :       return true;
     220             :   
     221             :   return false;
     222             : }
     223             : 
     224           0 : void SparseSolver::visitTerminatorInst(TerminatorInst &TI) {
     225           0 :   SmallVector<bool, 16> SuccFeasible;
     226           0 :   getFeasibleSuccessors(TI, SuccFeasible, true);
     227             :   
     228           0 :   BasicBlock *BB = TI.getParent();
     229             :   
     230             :   // Mark all feasible successors executable...
     231           0 :   for (unsigned i = 0, e = SuccFeasible.size(); i != e; ++i)
     232           0 :     if (SuccFeasible[i])
     233           0 :       markEdgeExecutable(BB, TI.getSuccessor(i));
     234           0 : }
     235             : 
     236           0 : void SparseSolver::visitPHINode(PHINode &PN) {
     237             :   // The lattice function may store more information on a PHINode than could be
     238             :   // computed from its incoming values.  For example, SSI form stores its sigma
     239             :   // functions as PHINodes with a single incoming value.
     240           0 :   if (LatticeFunc->IsSpecialCasedPHI(&PN)) {
     241           0 :     LatticeVal IV = LatticeFunc->ComputeInstructionState(PN, *this);
     242           0 :     if (IV != LatticeFunc->getUntrackedVal())
     243           0 :       UpdateState(PN, IV);
     244             :     return;
     245             :   }
     246             : 
     247           0 :   LatticeVal PNIV = getOrInitValueState(&PN);
     248           0 :   LatticeVal Overdefined = LatticeFunc->getOverdefinedVal();
     249             :   
     250             :   // If this value is already overdefined (common) just return.
     251           0 :   if (PNIV == Overdefined || PNIV == LatticeFunc->getUntrackedVal())
     252             :     return;  // Quick exit
     253             :   
     254             :   // Super-extra-high-degree PHI nodes are unlikely to ever be interesting,
     255             :   // and slow us down a lot.  Just mark them overdefined.
     256           0 :   if (PN.getNumIncomingValues() > 64) {
     257           0 :     UpdateState(PN, Overdefined);
     258           0 :     return;
     259             :   }
     260             :   
     261             :   // Look at all of the executable operands of the PHI node.  If any of them
     262             :   // are overdefined, the PHI becomes overdefined as well.  Otherwise, ask the
     263             :   // transfer function to give us the merge of the incoming values.
     264           0 :   for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) {
     265             :     // If the edge is not yet known to be feasible, it doesn't impact the PHI.
     266           0 :     if (!isEdgeFeasible(PN.getIncomingBlock(i), PN.getParent(), true))
     267           0 :       continue;
     268             :     
     269             :     // Merge in this value.
     270           0 :     LatticeVal OpVal = getOrInitValueState(PN.getIncomingValue(i));
     271           0 :     if (OpVal != PNIV)
     272           0 :       PNIV = LatticeFunc->MergeValues(PNIV, OpVal);
     273             :     
     274           0 :     if (PNIV == Overdefined)
     275             :       break;  // Rest of input values don't matter.
     276             :   }
     277             : 
     278             :   // Update the PHI with the compute value, which is the merge of the inputs.
     279           0 :   UpdateState(PN, PNIV);
     280             : }
     281             : 
     282           0 : void SparseSolver::visitInst(Instruction &I) {
     283             :   // PHIs are handled by the propagation logic, they are never passed into the
     284             :   // transfer functions.
     285           0 :   if (PHINode *PN = dyn_cast<PHINode>(&I))
     286           0 :     return visitPHINode(*PN);
     287             :   
     288             :   // Otherwise, ask the transfer function what the result is.  If this is
     289             :   // something that we care about, remember it.
     290           0 :   LatticeVal IV = LatticeFunc->ComputeInstructionState(I, *this);
     291           0 :   if (IV != LatticeFunc->getUntrackedVal())
     292           0 :     UpdateState(I, IV);
     293             :   
     294           0 :   if (TerminatorInst *TI = dyn_cast<TerminatorInst>(&I))
     295           0 :     visitTerminatorInst(*TI);
     296             : }
     297             : 
     298           0 : void SparseSolver::Solve(Function &F) {
     299           0 :   MarkBlockExecutable(&F.getEntryBlock());
     300             :   
     301             :   // Process the work lists until they are empty!
     302           0 :   while (!BBWorkList.empty() || !InstWorkList.empty()) {
     303             :     // Process the instruction work list.
     304           0 :     while (!InstWorkList.empty()) {
     305           0 :       Instruction *I = InstWorkList.back();
     306           0 :       InstWorkList.pop_back();
     307             : 
     308             :       DEBUG(dbgs() << "\nPopped off I-WL: " << *I << "\n");
     309             : 
     310             :       // "I" got into the work list because it made a transition.  See if any
     311             :       // users are both live and in need of updating.
     312           0 :       for (User *U : I->users()) {
     313           0 :         Instruction *UI = cast<Instruction>(U);
     314           0 :         if (BBExecutable.count(UI->getParent()))   // Inst is executable?
     315           0 :           visitInst(*UI);
     316             :       }
     317             :     }
     318             : 
     319             :     // Process the basic block work list.
     320           0 :     while (!BBWorkList.empty()) {
     321           0 :       BasicBlock *BB = BBWorkList.back();
     322           0 :       BBWorkList.pop_back();
     323             : 
     324             :       DEBUG(dbgs() << "\nPopped off BBWL: " << *BB);
     325             : 
     326             :       // Notify all instructions in this basic block that they are newly
     327             :       // executable.
     328           0 :       for (Instruction &I : *BB)
     329           0 :         visitInst(I);
     330             :     }
     331             :   }
     332           0 : }
     333             : 
     334           0 : void SparseSolver::Print(Function &F, raw_ostream &OS) const {
     335           0 :   OS << "\nFUNCTION: " << F.getName() << "\n";
     336           0 :   for (auto &BB : F) {
     337           0 :     if (!BBExecutable.count(&BB))
     338           0 :       OS << "INFEASIBLE: ";
     339           0 :     OS << "\t";
     340           0 :     if (BB.hasName())
     341           0 :       OS << BB.getName() << ":\n";
     342             :     else
     343           0 :       OS << "; anon bb\n";
     344           0 :     for (auto &I : BB) {
     345           0 :       LatticeFunc->PrintValue(getLatticeState(&I), OS);
     346           0 :       OS << I << "\n";
     347             :     }
     348             :     
     349           0 :     OS << "\n";
     350             :   }
     351           0 : }

Generated by: LCOV version 1.13