| Chris Lattner | 4ee3632 | 2004-01-09 18:15:24 +0000 | [diff] [blame] | 1 | //===-- BBLiveVar.cpp - Live Variable Analysis for a BasicBlock -----------===// | 
|  | 2 | // | 
|  | 3 | //                     The LLVM Compiler Infrastructure | 
|  | 4 | // | 
|  | 5 | // This file was developed by the LLVM research group and is distributed under | 
|  | 6 | // the University of Illinois Open Source License. See LICENSE.TXT for details. | 
|  | 7 | // | 
|  | 8 | //===----------------------------------------------------------------------===// | 
|  | 9 | // | 
|  | 10 | // This is a wrapper class for BasicBlock which is used by live var analysis. | 
|  | 11 | // | 
|  | 12 | //===----------------------------------------------------------------------===// | 
|  | 13 |  | 
|  | 14 | #include "BBLiveVar.h" | 
|  | 15 | #include "llvm/CodeGen/FunctionLiveVarInfo.h" | 
|  | 16 | #include "llvm/CodeGen/MachineInstr.h" | 
|  | 17 | #include "llvm/CodeGen/MachineBasicBlock.h" | 
|  | 18 | #include "llvm/Support/CFG.h" | 
|  | 19 | #include "Support/SetOperations.h" | 
|  | 20 | #include "../SparcInternals.h" | 
|  | 21 |  | 
|  | 22 | namespace llvm { | 
|  | 23 |  | 
| Alkis Evlogimenos | 8f41426 | 2004-02-11 17:55:09 +0000 | [diff] [blame] | 24 | BBLiveVar::BBLiveVar(const BasicBlock &bb, | 
|  | 25 | const MachineBasicBlock &mbb, | 
|  | 26 | unsigned id) | 
| Chris Lattner | 4ee3632 | 2004-01-09 18:15:24 +0000 | [diff] [blame] | 27 | : BB(bb), MBB(mbb), POID(id) { | 
|  | 28 | InSetChanged = OutSetChanged = false; | 
|  | 29 |  | 
|  | 30 | calcDefUseSets(); | 
|  | 31 | } | 
|  | 32 |  | 
|  | 33 | //----------------------------------------------------------------------------- | 
|  | 34 | // calculates def and use sets for each BB | 
|  | 35 | // There are two passes over operands of a machine instruction. This is | 
|  | 36 | // because, we can have instructions like V = V + 1, since we no longer | 
|  | 37 | // assume single definition. | 
|  | 38 | //----------------------------------------------------------------------------- | 
|  | 39 |  | 
|  | 40 | void BBLiveVar::calcDefUseSets() { | 
|  | 41 | // iterate over all the machine instructions in BB | 
|  | 42 | for (MachineBasicBlock::const_reverse_iterator MII = MBB.rbegin(), | 
|  | 43 | MIE = MBB.rend(); MII != MIE; ++MII) { | 
| Alkis Evlogimenos | 80da865 | 2004-02-12 02:27:10 +0000 | [diff] [blame] | 44 | const MachineInstr *MI = &*MII; | 
| Chris Lattner | 4ee3632 | 2004-01-09 18:15:24 +0000 | [diff] [blame] | 45 |  | 
|  | 46 | if (DEBUG_LV >= LV_DEBUG_Verbose) { | 
|  | 47 | std::cerr << " *Iterating over machine instr "; | 
|  | 48 | MI->dump(); | 
|  | 49 | std::cerr << "\n"; | 
|  | 50 | } | 
|  | 51 |  | 
|  | 52 | // iterate over  MI operands to find defs | 
|  | 53 | for (MachineInstr::const_val_op_iterator OpI = MI->begin(), OpE = MI->end(); | 
|  | 54 | OpI != OpE; ++OpI) | 
|  | 55 | if (OpI.isDef()) // add to Defs if this operand is a def | 
|  | 56 | addDef(*OpI); | 
|  | 57 |  | 
|  | 58 | // do for implicit operands as well | 
|  | 59 | for (unsigned i = 0; i < MI->getNumImplicitRefs(); ++i) | 
|  | 60 | if (MI->getImplicitOp(i).isDef()) | 
|  | 61 | addDef(MI->getImplicitRef(i)); | 
|  | 62 |  | 
|  | 63 | // iterate over MI operands to find uses | 
|  | 64 | for (MachineInstr::const_val_op_iterator OpI = MI->begin(), OpE = MI->end(); | 
|  | 65 | OpI != OpE; ++OpI) { | 
|  | 66 | const Value *Op = *OpI; | 
|  | 67 |  | 
|  | 68 | if (isa<BasicBlock>(Op)) | 
|  | 69 | continue;             // don't process labels | 
|  | 70 |  | 
|  | 71 | if (OpI.isUse()) { // add to Uses only if this operand is a use | 
|  | 72 | // | 
|  | 73 | // *** WARNING: The following code for handling dummy PHI machine | 
|  | 74 | //     instructions is untested.  The previous code was broken and I | 
|  | 75 | //     fixed it, but it turned out to be unused as long as Phi | 
|  | 76 | //     elimination is performed during instruction selection. | 
|  | 77 | // | 
|  | 78 | // Put Phi operands in UseSet for the incoming edge, not node. | 
|  | 79 | // They must not "hide" later defs, and must be handled specially | 
|  | 80 | // during set propagation over the CFG. | 
| Brian Gaeke | b22186a | 2004-02-11 20:47:34 +0000 | [diff] [blame] | 81 | if (MI->getOpcode() == V9::PHI) {         // for a phi node | 
| Chris Lattner | 4ee3632 | 2004-01-09 18:15:24 +0000 | [diff] [blame] | 82 | const Value *ArgVal = Op; | 
|  | 83 | const BasicBlock *PredBB = cast<BasicBlock>(*++OpI); // next ptr is BB | 
|  | 84 |  | 
|  | 85 | PredToEdgeInSetMap[PredBB].insert(ArgVal); | 
|  | 86 |  | 
|  | 87 | if (DEBUG_LV >= LV_DEBUG_Verbose) | 
|  | 88 | std::cerr << "   - phi operand " << RAV(ArgVal) << " came from BB " | 
|  | 89 | << RAV(PredBB) << "\n"; | 
|  | 90 | } // if( IsPhi ) | 
|  | 91 | else { | 
|  | 92 | // It is not a Phi use: add to regular use set and remove later defs. | 
|  | 93 | addUse(Op); | 
|  | 94 | } | 
|  | 95 | } // if a use | 
|  | 96 | } // for all operands | 
|  | 97 |  | 
|  | 98 | // do for implicit operands as well | 
|  | 99 | for (unsigned i = 0; i < MI->getNumImplicitRefs(); ++i) { | 
| Brian Gaeke | b22186a | 2004-02-11 20:47:34 +0000 | [diff] [blame] | 100 | assert(MI->getOpcode() != V9::PHI && "Phi cannot have implicit operands"); | 
| Chris Lattner | 4ee3632 | 2004-01-09 18:15:24 +0000 | [diff] [blame] | 101 | const Value *Op = MI->getImplicitRef(i); | 
|  | 102 |  | 
|  | 103 | if (Op->getType() == Type::LabelTy)             // don't process labels | 
|  | 104 | continue; | 
|  | 105 |  | 
|  | 106 | if (MI->getImplicitOp(i).isUse()) | 
|  | 107 | addUse(Op); | 
|  | 108 | } | 
|  | 109 | } // for all machine instructions | 
|  | 110 | } | 
|  | 111 |  | 
|  | 112 |  | 
|  | 113 |  | 
|  | 114 | //----------------------------------------------------------------------------- | 
|  | 115 | // To add an operand which is a def | 
|  | 116 | //----------------------------------------------------------------------------- | 
|  | 117 | void BBLiveVar::addDef(const Value *Op) { | 
|  | 118 | DefSet.insert(Op);     // operand is a def - so add to def set | 
|  | 119 | InSet.erase(Op);       // this definition kills any later uses | 
|  | 120 | InSetChanged = true; | 
|  | 121 |  | 
|  | 122 | if (DEBUG_LV >= LV_DEBUG_Verbose) std::cerr << "  +Def: " << RAV(Op) << "\n"; | 
|  | 123 | } | 
|  | 124 |  | 
|  | 125 |  | 
|  | 126 | //----------------------------------------------------------------------------- | 
|  | 127 | // To add an operand which is a use | 
|  | 128 | //----------------------------------------------------------------------------- | 
|  | 129 | void  BBLiveVar::addUse(const Value *Op) { | 
|  | 130 | InSet.insert(Op);   // An operand is a use - so add to use set | 
|  | 131 | DefSet.erase(Op);   // remove if there is a def below this use | 
|  | 132 | InSetChanged = true; | 
|  | 133 |  | 
|  | 134 | if (DEBUG_LV >= LV_DEBUG_Verbose) std::cerr << "   Use: " << RAV(Op) << "\n"; | 
|  | 135 | } | 
|  | 136 |  | 
|  | 137 |  | 
|  | 138 | //----------------------------------------------------------------------------- | 
|  | 139 | // Applies the transfer function to a basic block to produce the InSet using | 
|  | 140 | // the OutSet. | 
|  | 141 | //----------------------------------------------------------------------------- | 
|  | 142 |  | 
|  | 143 | bool BBLiveVar::applyTransferFunc() { | 
|  | 144 | // IMPORTANT: caller should check whether the OutSet changed | 
|  | 145 | //           (else no point in calling) | 
|  | 146 |  | 
|  | 147 | ValueSet OutMinusDef = set_difference(OutSet, DefSet); | 
|  | 148 | InSetChanged = set_union(InSet, OutMinusDef); | 
|  | 149 |  | 
|  | 150 | OutSetChanged = false;      // no change to OutSet since transf func applied | 
|  | 151 | return InSetChanged; | 
|  | 152 | } | 
|  | 153 |  | 
|  | 154 |  | 
|  | 155 | //----------------------------------------------------------------------------- | 
|  | 156 | // calculates Out set using In sets of the successors | 
|  | 157 | //----------------------------------------------------------------------------- | 
|  | 158 |  | 
|  | 159 | bool BBLiveVar::setPropagate(ValueSet *OutSet, const ValueSet *InSet, | 
|  | 160 | const BasicBlock *PredBB) { | 
|  | 161 | bool Changed = false; | 
|  | 162 |  | 
|  | 163 | // merge all members of InSet into OutSet of the predecessor | 
|  | 164 | for (ValueSet::const_iterator InIt = InSet->begin(), InE = InSet->end(); | 
|  | 165 | InIt != InE; ++InIt) | 
|  | 166 | if ((OutSet->insert(*InIt)).second) | 
|  | 167 | Changed = true; | 
|  | 168 |  | 
|  | 169 | // | 
|  | 170 | //**** WARNING: The following code for handling dummy PHI machine | 
|  | 171 | //     instructions is untested.  See explanation above. | 
|  | 172 | // | 
|  | 173 | // then merge all members of the EdgeInSet for the predecessor into the OutSet | 
|  | 174 | const ValueSet& EdgeInSet = PredToEdgeInSetMap[PredBB]; | 
|  | 175 | for (ValueSet::const_iterator InIt = EdgeInSet.begin(), InE = EdgeInSet.end(); | 
|  | 176 | InIt != InE; ++InIt) | 
|  | 177 | if ((OutSet->insert(*InIt)).second) | 
|  | 178 | Changed = true; | 
|  | 179 | // | 
|  | 180 | //**** | 
|  | 181 |  | 
|  | 182 | return Changed; | 
|  | 183 | } | 
|  | 184 |  | 
|  | 185 |  | 
|  | 186 | //----------------------------------------------------------------------------- | 
|  | 187 | // propagates in set to OutSets of PREDECESSORs | 
|  | 188 | //----------------------------------------------------------------------------- | 
|  | 189 |  | 
|  | 190 | bool BBLiveVar::applyFlowFunc(hash_map<const BasicBlock*, | 
|  | 191 | BBLiveVar*> &BBLiveVarInfo) { | 
|  | 192 | // IMPORTANT: caller should check whether inset changed | 
|  | 193 | //            (else no point in calling) | 
|  | 194 |  | 
|  | 195 | // If this BB changed any OutSets of preds whose POID is lower, than we need | 
|  | 196 | // another iteration... | 
|  | 197 | // | 
|  | 198 | bool needAnotherIt = false; | 
|  | 199 |  | 
|  | 200 | for (pred_const_iterator PI = pred_begin(&BB), PE = pred_end(&BB); | 
|  | 201 | PI != PE ; ++PI) { | 
|  | 202 | BBLiveVar *PredLVBB = BBLiveVarInfo[*PI]; | 
|  | 203 |  | 
|  | 204 | // do set union | 
|  | 205 | if (setPropagate(&PredLVBB->OutSet, &InSet, *PI)) { | 
|  | 206 | PredLVBB->OutSetChanged = true; | 
|  | 207 |  | 
|  | 208 | // if the predec POID is lower than mine | 
|  | 209 | if (PredLVBB->getPOId() <= POID) | 
|  | 210 | needAnotherIt = true; | 
|  | 211 | } | 
|  | 212 | }  // for | 
|  | 213 |  | 
|  | 214 | return needAnotherIt; | 
|  | 215 | } | 
|  | 216 |  | 
|  | 217 |  | 
|  | 218 |  | 
|  | 219 | // ----------------- Methods For Debugging (Printing) ----------------- | 
|  | 220 |  | 
|  | 221 | void BBLiveVar::printAllSets() const { | 
|  | 222 | std::cerr << "  Defs: "; printSet(DefSet);  std::cerr << "\n"; | 
|  | 223 | std::cerr << "  In: ";  printSet(InSet);  std::cerr << "\n"; | 
|  | 224 | std::cerr << "  Out: "; printSet(OutSet);  std::cerr << "\n"; | 
|  | 225 | } | 
|  | 226 |  | 
|  | 227 | void BBLiveVar::printInOutSets() const { | 
|  | 228 | std::cerr << "  In: ";   printSet(InSet);  std::cerr << "\n"; | 
|  | 229 | std::cerr << "  Out: ";  printSet(OutSet);  std::cerr << "\n"; | 
|  | 230 | } | 
|  | 231 |  | 
|  | 232 | } // End llvm namespace |