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