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"
1457f7c7d9Sserge-sans-paille #include "llvm/MC/MCRegisterInfo.h"
15a34c753fSRafael Auler
16a34c753fSRafael Auler #define DEBUG_TYPE "dataflow"
17a34c753fSRafael Auler
18a34c753fSRafael Auler namespace llvm {
19a34c753fSRafael Auler
operator <<(raw_ostream & OS,const BitVector & State)20a34c753fSRafael Auler raw_ostream &operator<<(raw_ostream &OS, const BitVector &State) {
21a34c753fSRafael Auler LLVM_DEBUG({
22a34c753fSRafael Auler OS << "BitVector(";
23a34c753fSRafael Auler const char *Sep = "";
24a34c753fSRafael Auler if (State.count() > (State.size() >> 1)) {
25a34c753fSRafael Auler OS << "all, except: ";
26a34c753fSRafael Auler BitVector BV = State;
27a34c753fSRafael Auler BV.flip();
28d63c5a38SAmir Ayupov for (int I : BV.set_bits()) {
29a34c753fSRafael Auler OS << Sep << I;
30a34c753fSRafael Auler Sep = " ";
31a34c753fSRafael Auler }
32a34c753fSRafael Auler OS << ")";
33a34c753fSRafael Auler return OS;
34a34c753fSRafael Auler }
35d63c5a38SAmir Ayupov for (int I : State.set_bits()) {
36a34c753fSRafael Auler OS << Sep << I;
37a34c753fSRafael Auler Sep = " ";
38a34c753fSRafael Auler }
39a34c753fSRafael Auler OS << ")";
40a34c753fSRafael Auler return OS;
41a34c753fSRafael Auler });
42a34c753fSRafael Auler OS << "BitVector";
43a34c753fSRafael Auler return OS;
44a34c753fSRafael Auler }
45a34c753fSRafael Auler
46a34c753fSRafael Auler namespace bolt {
47a34c753fSRafael Auler
doForAllPreds(const BinaryBasicBlock & BB,std::function<void (ProgramPoint)> Task)4860b09997SMaksim Panchenko void doForAllPreds(const BinaryBasicBlock &BB,
49a34c753fSRafael Auler std::function<void(ProgramPoint)> Task) {
5060b09997SMaksim Panchenko MCPlusBuilder *MIB = BB.getFunction()->getBinaryContext().MIB.get();
51a34c753fSRafael Auler for (BinaryBasicBlock *Pred : BB.predecessors()) {
52a34c753fSRafael Auler if (Pred->isValid())
53a34c753fSRafael Auler Task(ProgramPoint::getLastPointAt(*Pred));
54a34c753fSRafael Auler }
55a34c753fSRafael Auler if (!BB.isLandingPad())
56a34c753fSRafael Auler return;
57a34c753fSRafael Auler for (BinaryBasicBlock *Thrower : BB.throwers()) {
58a34c753fSRafael Auler for (MCInst &Inst : *Thrower) {
5960b09997SMaksim Panchenko if (!MIB->isInvoke(Inst))
60a34c753fSRafael Auler continue;
61*2563fd63SAmir Ayupov const std::optional<MCPlus::MCLandingPad> EHInfo = MIB->getEHInfo(Inst);
62a34c753fSRafael Auler if (!EHInfo || EHInfo->first != BB.getLabel())
63a34c753fSRafael Auler continue;
64a34c753fSRafael Auler Task(ProgramPoint(&Inst));
65a34c753fSRafael Auler }
66a34c753fSRafael Auler }
67a34c753fSRafael Auler }
68a34c753fSRafael Auler
69a34c753fSRafael Auler /// Operates on all successors of a basic block.
doForAllSuccs(const BinaryBasicBlock & BB,std::function<void (ProgramPoint)> Task)70a34c753fSRafael Auler void doForAllSuccs(const BinaryBasicBlock &BB,
71a34c753fSRafael Auler std::function<void(ProgramPoint)> Task) {
72f92ab6afSAmir Ayupov for (BinaryBasicBlock *Succ : BB.successors())
73a34c753fSRafael Auler if (Succ->isValid())
74a34c753fSRafael Auler Task(ProgramPoint::getFirstPointAt(*Succ));
75a34c753fSRafael Auler }
76a34c753fSRafael Auler
print(raw_ostream & OS,const BitVector & State) const77a34c753fSRafael Auler void RegStatePrinter::print(raw_ostream &OS, const BitVector &State) const {
78a34c753fSRafael Auler if (State.all()) {
79a34c753fSRafael Auler OS << "(all)";
80a34c753fSRafael Auler return;
81a34c753fSRafael Auler }
82a34c753fSRafael Auler if (State.count() > (State.size() >> 1)) {
83a34c753fSRafael Auler OS << "all, except: ";
84a34c753fSRafael Auler BitVector BV = State;
85a34c753fSRafael Auler BV.flip();
86d63c5a38SAmir Ayupov for (int I : BV.set_bits())
87a34c753fSRafael Auler OS << BC.MRI->getName(I) << " ";
88a34c753fSRafael Auler return;
89a34c753fSRafael Auler }
90d63c5a38SAmir Ayupov for (int I : State.set_bits())
91a34c753fSRafael Auler OS << BC.MRI->getName(I) << " ";
92a34c753fSRafael Auler }
93a34c753fSRafael Auler
94a34c753fSRafael Auler } // namespace bolt
95a34c753fSRafael Auler } // namespace llvm
96