xref: /llvm-project/bolt/lib/Passes/DataflowAnalysis.cpp (revision 2563fd63c6f774e2b723d3f5246629e60da01eaa)
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 
operator <<(raw_ostream & OS,const BitVector & State)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.set_bits()) {
29         OS << Sep << I;
30         Sep = " ";
31       }
32       OS << ")";
33       return OS;
34     }
35     for (int I : State.set_bits()) {
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 
doForAllPreds(const BinaryBasicBlock & BB,std::function<void (ProgramPoint)> Task)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 std::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.
doForAllSuccs(const BinaryBasicBlock & BB,std::function<void (ProgramPoint)> Task)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 
print(raw_ostream & OS,const BitVector & State) const77 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.set_bits())
87       OS << BC.MRI->getName(I) << " ";
88     return;
89   }
90   for (int I : State.set_bits())
91     OS << BC.MRI->getName(I) << " ";
92 }
93 
94 } // namespace bolt
95 } // namespace llvm
96