LLVM  8.0.1
CFGUpdate.h
Go to the documentation of this file.
1 //===- CFGUpdate.h - Encode a CFG Edge Update. ------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines a CFG Edge Update: Insert or Delete, and two Nodes as the
11 // Edge ends.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_SUPPORT_CFGUPDATE_H
16 #define LLVM_SUPPORT_CFGUPDATE_H
17 
18 #include "llvm/ADT/APInt.h"
19 #include "llvm/ADT/DenseMap.h"
21 #include "llvm/Support/Compiler.h"
22 #include "llvm/Support/Debug.h"
24 
25 namespace llvm {
26 namespace cfg {
27 enum class UpdateKind : unsigned char { Insert, Delete };
28 
29 template <typename NodePtr> class Update {
31  NodePtr From;
32  NodeKindPair ToAndKind;
33 
34 public:
36  : From(From), ToAndKind(To, Kind) {}
37 
38  UpdateKind getKind() const { return ToAndKind.getInt(); }
39  NodePtr getFrom() const { return From; }
40  NodePtr getTo() const { return ToAndKind.getPointer(); }
41  bool operator==(const Update &RHS) const {
42  return From == RHS.From && ToAndKind == RHS.ToAndKind;
43  }
44 
45  void print(raw_ostream &OS) const {
46  OS << (getKind() == UpdateKind::Insert ? "Insert " : "Delete ");
47  getFrom()->printAsOperand(OS, false);
48  OS << " -> ";
49  getTo()->printAsOperand(OS, false);
50  }
51 
52 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
53  LLVM_DUMP_METHOD void dump() const { print(dbgs()); }
54 #endif
55 };
56 
57 // LegalizeUpdates function simplifies updates assuming a graph structure.
58 // This function serves double purpose:
59 // a) It removes redundant updates, which makes it easier to reverse-apply
60 // them when traversing CFG.
61 // b) It optimizes away updates that cancel each other out, as the end result
62 // is the same.
63 template <typename NodePtr>
66  bool InverseGraph) {
67  // Count the total number of inserions of each edge.
68  // Each insertion adds 1 and deletion subtracts 1. The end number should be
69  // one of {-1 (deletion), 0 (NOP), +1 (insertion)}. Otherwise, the sequence
70  // of updates contains multiple updates of the same kind and we assert for
71  // that case.
73  Operations.reserve(AllUpdates.size());
74 
75  for (const auto &U : AllUpdates) {
76  NodePtr From = U.getFrom();
77  NodePtr To = U.getTo();
78  if (InverseGraph)
79  std::swap(From, To); // Reverse edge for postdominators.
80 
81  Operations[{From, To}] += (U.getKind() == UpdateKind::Insert ? 1 : -1);
82  }
83 
84  Result.clear();
85  Result.reserve(Operations.size());
86  for (auto &Op : Operations) {
87  const int NumInsertions = Op.second;
88  assert(std::abs(NumInsertions) <= 1 && "Unbalanced operations!");
89  if (NumInsertions == 0)
90  continue;
91  const UpdateKind UK =
92  NumInsertions > 0 ? UpdateKind::Insert : UpdateKind::Delete;
93  Result.push_back({UK, Op.first.first, Op.first.second});
94  }
95 
96  // Make the order consistent by not relying on pointer values within the
97  // set. Reuse the old Operations map.
98  // In the future, we should sort by something else to minimize the amount
99  // of work needed to perform the series of updates.
100  for (size_t i = 0, e = AllUpdates.size(); i != e; ++i) {
101  const auto &U = AllUpdates[i];
102  if (!InverseGraph)
103  Operations[{U.getFrom(), U.getTo()}] = int(i);
104  else
105  Operations[{U.getTo(), U.getFrom()}] = int(i);
106  }
107 
108  llvm::sort(Result,
109  [&Operations](const Update<NodePtr> &A, const Update<NodePtr> &B) {
110  return Operations[{A.getFrom(), A.getTo()}] >
111  Operations[{B.getFrom(), B.getTo()}];
112  });
113 }
114 
115 } // end namespace cfg
116 } // end namespace llvm
117 
118 #endif // LLVM_SUPPORT_CFGUPDATE_H
NodePtr getTo() const
Definition: CFGUpdate.h:40
This class represents lattice values for constants.
Definition: AllocatorList.h:24
PointerTy getPointer() const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:42
#define LLVM_DUMP_METHOD
Definition: Compiler.h:74
NodePtr getFrom() const
Definition: CFGUpdate.h:39
This file implements a class to represent arbitrary precision integral constant values and operations...
void print(raw_ostream &OS) const
Definition: CFGUpdate.h:45
IntType getInt() const
LLVM_DUMP_METHOD void dump() const
Definition: CFGUpdate.h:53
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:33
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
std::shared_ptr< Node > NodePtr
Short-hand for a Node pointer.
Definition: MsgPackTypes.h:33
void LegalizeUpdates(ArrayRef< Update< NodePtr >> AllUpdates, SmallVectorImpl< Update< NodePtr >> &Result, bool InverseGraph)
Definition: CFGUpdate.h:64
bool operator==(const Update &RHS) const
Definition: CFGUpdate.h:41
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
void reserve(size_type NumEntries)
Grow the densemap so that it can contain at least NumEntries items before resizing again...
Definition: DenseMap.h:130
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1116
BlockVerifier::State From
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:133
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:941
APFloat abs(APFloat X)
Returns the absolute value of the argument.
Definition: APFloat.h:1213
const unsigned Kind
UpdateKind getKind() const
Definition: CFGUpdate.h:38
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:46
Update(UpdateKind Kind, NodePtr From, NodePtr To)
Definition: CFGUpdate.h:35