1 //===- bolt/Passes/DataflowAnalysis.cpp -----------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file implements functions and classes used for data-flow analysis. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "bolt/Passes/DataflowAnalysis.h" 14 #include "llvm/MC/MCRegisterInfo.h" 15 16 #define DEBUG_TYPE "dataflow" 17 18 namespace llvm { 19 20 raw_ostream &operator<<(raw_ostream &OS, const BitVector &State) { 21 LLVM_DEBUG({ 22 OS << "BitVector("; 23 const char *Sep = ""; 24 if (State.count() > (State.size() >> 1)) { 25 OS << "all, except: "; 26 BitVector BV = State; 27 BV.flip(); 28 for (int I = BV.find_first(); I != -1; I = BV.find_next(I)) { 29 OS << Sep << I; 30 Sep = " "; 31 } 32 OS << ")"; 33 return OS; 34 } 35 for (int I = State.find_first(); I != -1; I = State.find_next(I)) { 36 OS << Sep << I; 37 Sep = " "; 38 } 39 OS << ")"; 40 return OS; 41 }); 42 OS << "BitVector"; 43 return OS; 44 } 45 46 namespace bolt { 47 48 void doForAllPreds(const BinaryBasicBlock &BB, 49 std::function<void(ProgramPoint)> Task) { 50 MCPlusBuilder *MIB = BB.getFunction()->getBinaryContext().MIB.get(); 51 for (BinaryBasicBlock *Pred : BB.predecessors()) { 52 if (Pred->isValid()) 53 Task(ProgramPoint::getLastPointAt(*Pred)); 54 } 55 if (!BB.isLandingPad()) 56 return; 57 for (BinaryBasicBlock *Thrower : BB.throwers()) { 58 for (MCInst &Inst : *Thrower) { 59 if (!MIB->isInvoke(Inst)) 60 continue; 61 const Optional<MCPlus::MCLandingPad> EHInfo = MIB->getEHInfo(Inst); 62 if (!EHInfo || EHInfo->first != BB.getLabel()) 63 continue; 64 Task(ProgramPoint(&Inst)); 65 } 66 } 67 } 68 69 /// Operates on all successors of a basic block. 70 void doForAllSuccs(const BinaryBasicBlock &BB, 71 std::function<void(ProgramPoint)> Task) { 72 for (BinaryBasicBlock *Succ : BB.successors()) 73 if (Succ->isValid()) 74 Task(ProgramPoint::getFirstPointAt(*Succ)); 75 } 76 77 void RegStatePrinter::print(raw_ostream &OS, const BitVector &State) const { 78 if (State.all()) { 79 OS << "(all)"; 80 return; 81 } 82 if (State.count() > (State.size() >> 1)) { 83 OS << "all, except: "; 84 BitVector BV = State; 85 BV.flip(); 86 for (int I = BV.find_first(); I != -1; I = BV.find_next(I)) 87 OS << BC.MRI->getName(I) << " "; 88 return; 89 } 90 for (int I = State.find_first(); I != -1; I = State.find_next(I)) 91 OS << BC.MRI->getName(I) << " "; 92 } 93 94 } // namespace bolt 95 } // namespace llvm 96