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