blob: 6d9fb9b9100a8dd418685c416472ce804159608b [file] [log] [blame]
//===- llvm/CodeGen/MachineRegionInfo.h -------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CODEGEN_MACHINEREGIONINFO_H
#define LLVM_CODEGEN_MACHINEREGIONINFO_H
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/Analysis/RegionInfo.h"
#include "llvm/Analysis/RegionIterator.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineDominanceFrontier.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
#include <cassert>
namespace llvm {
struct MachinePostDominatorTree;
class MachineRegion;
class MachineRegionNode;
class MachineRegionInfo;
template <> struct RegionTraits<MachineFunction> {
using FuncT = MachineFunction;
using BlockT = MachineBasicBlock;
using RegionT = MachineRegion;
using RegionNodeT = MachineRegionNode;
using RegionInfoT = MachineRegionInfo;
using DomTreeT = MachineDominatorTree;
using DomTreeNodeT = MachineDomTreeNode;
using PostDomTreeT = MachinePostDominatorTree;
using DomFrontierT = MachineDominanceFrontier;
using InstT = MachineInstr;
using LoopT = MachineLoop;
using LoopInfoT = MachineLoopInfo;
static unsigned getNumSuccessors(MachineBasicBlock *BB) {
return BB->succ_size();
}
};
class MachineRegionNode : public RegionNodeBase<RegionTraits<MachineFunction>> {
public:
inline MachineRegionNode(MachineRegion *Parent, MachineBasicBlock *Entry,
bool isSubRegion = false)
: RegionNodeBase<RegionTraits<MachineFunction>>(Parent, Entry,
isSubRegion) {}
bool operator==(const MachineRegion &RN) const {
return this == reinterpret_cast<const MachineRegionNode *>(&RN);
}
};
class MachineRegion : public RegionBase<RegionTraits<MachineFunction>> {
public:
MachineRegion(MachineBasicBlock *Entry, MachineBasicBlock *Exit,
MachineRegionInfo *RI, MachineDominatorTree *DT,
MachineRegion *Parent = nullptr);
~MachineRegion();
bool operator==(const MachineRegionNode &RN) const {
return &RN == reinterpret_cast<const MachineRegionNode *>(this);
}
};
class MachineRegionInfo : public RegionInfoBase<RegionTraits<MachineFunction>> {
public:
explicit MachineRegionInfo();
~MachineRegionInfo() override;
// updateStatistics - Update statistic about created regions.
void updateStatistics(MachineRegion *R) final;
void recalculate(MachineFunction &F, MachineDominatorTree *DT,
MachinePostDominatorTree *PDT, MachineDominanceFrontier *DF);
};
class MachineRegionInfoPass : public MachineFunctionPass {
MachineRegionInfo RI;
public:
static char ID;
explicit MachineRegionInfoPass();
~MachineRegionInfoPass() override;
MachineRegionInfo &getRegionInfo() { return RI; }
const MachineRegionInfo &getRegionInfo() const { return RI; }
/// @name MachineFunctionPass interface
//@{
bool runOnMachineFunction(MachineFunction &F) override;
void releaseMemory() override;
void verifyAnalysis() const override;
void getAnalysisUsage(AnalysisUsage &AU) const override;
void print(raw_ostream &OS, const Module *) const override;
void dump() const;
//@}
};
template <>
template <>
inline MachineBasicBlock *
RegionNodeBase<RegionTraits<MachineFunction>>::getNodeAs<MachineBasicBlock>()
const {
assert(!isSubRegion() && "This is not a MachineBasicBlock RegionNode!");
return getEntry();
}
template <>
template <>
inline MachineRegion *
RegionNodeBase<RegionTraits<MachineFunction>>::getNodeAs<MachineRegion>()
const {
assert(isSubRegion() && "This is not a subregion RegionNode!");
auto Unconst =
const_cast<RegionNodeBase<RegionTraits<MachineFunction>> *>(this);
return reinterpret_cast<MachineRegion *>(Unconst);
}
RegionNodeGraphTraits(MachineRegionNode, MachineBasicBlock, MachineRegion);
RegionNodeGraphTraits(const MachineRegionNode, MachineBasicBlock,
MachineRegion);
RegionGraphTraits(MachineRegion, MachineRegionNode);
RegionGraphTraits(const MachineRegion, const MachineRegionNode);
template <>
struct GraphTraits<MachineRegionInfo *>
: public GraphTraits<FlatIt<MachineRegionNode *>> {
using nodes_iterator = df_iterator<NodeRef, df_iterator_default_set<NodeRef>,
false, GraphTraits<FlatIt<NodeRef>>>;
static NodeRef getEntryNode(MachineRegionInfo *RI) {
return GraphTraits<FlatIt<MachineRegion *>>::getEntryNode(
RI->getTopLevelRegion());
}
static nodes_iterator nodes_begin(MachineRegionInfo *RI) {
return nodes_iterator::begin(getEntryNode(RI));
}
static nodes_iterator nodes_end(MachineRegionInfo *RI) {
return nodes_iterator::end(getEntryNode(RI));
}
};
template <>
struct GraphTraits<MachineRegionInfoPass *>
: public GraphTraits<MachineRegionInfo *> {
using nodes_iterator = df_iterator<NodeRef, df_iterator_default_set<NodeRef>,
false, GraphTraits<FlatIt<NodeRef>>>;
static NodeRef getEntryNode(MachineRegionInfoPass *RI) {
return GraphTraits<MachineRegionInfo *>::getEntryNode(&RI->getRegionInfo());
}
static nodes_iterator nodes_begin(MachineRegionInfoPass *RI) {
return GraphTraits<MachineRegionInfo *>::nodes_begin(&RI->getRegionInfo());
}
static nodes_iterator nodes_end(MachineRegionInfoPass *RI) {
return GraphTraits<MachineRegionInfo *>::nodes_end(&RI->getRegionInfo());
}
};
extern template class RegionBase<RegionTraits<MachineFunction>>;
extern template class RegionNodeBase<RegionTraits<MachineFunction>>;
extern template class RegionInfoBase<RegionTraits<MachineFunction>>;
} // end namespace llvm
#endif // LLVM_CODEGEN_MACHINEREGIONINFO_H