96 lines · cpp
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-exception6//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 18namespace llvm {19 20raw_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 46namespace bolt {47 48void 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.70void 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 77void 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 bolt95} // namespace llvm96