xref: /llvm-project/bolt/lib/Passes/DataflowAnalysis.cpp (revision 2563fd63c6f774e2b723d3f5246629e60da01eaa)
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