blob: 1fa1db537860f6410a564adc6d1d3ddd8122b3ed [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===- IteratedDominanceFrontier.h - Calculate IDF --------------*- C++ -*-===//
2//
Andrew Walbran16937d02019-10-22 13:54:20 +01003// 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
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01006//
7//===----------------------------------------------------------------------===//
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01008
9#ifndef LLVM_ANALYSIS_IDF_H
10#define LLVM_ANALYSIS_IDF_H
11
Andrew Scull0372a572018-11-16 15:47:06 +000012#include "llvm/IR/CFGDiff.h"
Andrew Walbran3d2c1972020-04-07 12:24:26 +010013#include "llvm/Support/GenericIteratedDominanceFrontier.h"
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010014
15namespace llvm {
16
Andrew Walbran3d2c1972020-04-07 12:24:26 +010017class BasicBlock;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010018
Andrew Walbran3d2c1972020-04-07 12:24:26 +010019namespace IDFCalculatorDetail {
Andrew Scull0372a572018-11-16 15:47:06 +000020
Andrew Walbran3d2c1972020-04-07 12:24:26 +010021/// Specialization for BasicBlock for the optional use of GraphDiff.
22template <bool IsPostDom> struct ChildrenGetterTy<BasicBlock, IsPostDom> {
23 using NodeRef = BasicBlock *;
24 using ChildrenTy = SmallVector<BasicBlock *, 8>;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010025
Andrew Walbran3d2c1972020-04-07 12:24:26 +010026 ChildrenGetterTy() = default;
27 ChildrenGetterTy(const GraphDiff<BasicBlock *, IsPostDom> *GD) : GD(GD) {
28 assert(GD);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010029 }
30
Andrew Walbran3d2c1972020-04-07 12:24:26 +010031 ChildrenTy get(const NodeRef &N);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010032
Andrew Walbran3d2c1972020-04-07 12:24:26 +010033 const GraphDiff<BasicBlock *, IsPostDom> *GD = nullptr;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010034};
Andrew Walbran3d2c1972020-04-07 12:24:26 +010035
36} // end of namespace IDFCalculatorDetail
37
38template <bool IsPostDom>
39class IDFCalculator final : public IDFCalculatorBase<BasicBlock, IsPostDom> {
40public:
41 using IDFCalculatorBase =
42 typename llvm::IDFCalculatorBase<BasicBlock, IsPostDom>;
43 using ChildrenGetterTy = typename IDFCalculatorBase::ChildrenGetterTy;
44
45 IDFCalculator(DominatorTreeBase<BasicBlock, IsPostDom> &DT)
46 : IDFCalculatorBase(DT) {}
47
48 IDFCalculator(DominatorTreeBase<BasicBlock, IsPostDom> &DT,
49 const GraphDiff<BasicBlock *, IsPostDom> *GD)
50 : IDFCalculatorBase(DT, ChildrenGetterTy(GD)) {
51 assert(GD);
52 }
53};
54
55using ForwardIDFCalculator = IDFCalculator<false>;
56using ReverseIDFCalculator = IDFCalculator<true>;
57
58//===----------------------------------------------------------------------===//
59// Implementation.
60//===----------------------------------------------------------------------===//
61
62namespace IDFCalculatorDetail {
63
64template <bool IsPostDom>
65typename ChildrenGetterTy<BasicBlock, IsPostDom>::ChildrenTy
66ChildrenGetterTy<BasicBlock, IsPostDom>::get(
67 const ChildrenGetterTy<BasicBlock, IsPostDom>::NodeRef &N) {
68
69 using OrderedNodeTy =
70 typename IDFCalculatorBase<BasicBlock, IsPostDom>::OrderedNodeTy;
71
72 if (!GD) {
73 auto Children = children<OrderedNodeTy>(N);
74 return {Children.begin(), Children.end()};
75 }
76
77 using SnapShotBBPairTy =
78 std::pair<const GraphDiff<BasicBlock *, IsPostDom> *, OrderedNodeTy>;
79
80 ChildrenTy Ret;
81 for (const auto &SnapShotBBPair : children<SnapShotBBPairTy>({GD, N}))
82 Ret.emplace_back(SnapShotBBPair.second);
83 return Ret;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010084}
Andrew Walbran3d2c1972020-04-07 12:24:26 +010085
86} // end of namespace IDFCalculatorDetail
87
88} // end of namespace llvm
89
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010090#endif