Skip to content

Commit b14e30f

Browse files
committed
[LLVM] refactor GenericSSAContext and its specializations
Fix the GenericSSAContext template so that it actually declares all the necessary typenames and the methods that must be implemented by its specializations SSAContext and MachineSSAContext. Reviewed By: arsenm Differential Revision: https://reviews.llvm.org/D156288
1 parent fe9c3c7 commit b14e30f

11 files changed

+116
-192
lines changed

llvm/include/llvm/ADT/GenericCycleImpl.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -354,11 +354,11 @@ template <typename ContextT> void GenericCycleInfo<ContextT>::clear() {
354354
template <typename ContextT>
355355
void GenericCycleInfo<ContextT>::compute(FunctionT &F) {
356356
GenericCycleInfoCompute<ContextT> Compute(*this);
357-
Context.setFunction(F);
357+
Context = ContextT(&F);
358358

359359
LLVM_DEBUG(errs() << "Computing cycles for function: " << F.getName()
360360
<< "\n");
361-
Compute.run(ContextT::getEntryBlock(F));
361+
Compute.run(&F.front());
362362

363363
assert(validateTree());
364364
}

llvm/include/llvm/ADT/GenericCycleInfo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ template <typename ContextT> class GenericCycleInfo {
256256
void clear();
257257
void compute(FunctionT &F);
258258

259-
FunctionT *getFunction() const { return Context.getFunction(); }
259+
const FunctionT *getFunction() const { return Context.getFunction(); }
260260
const ContextT &getSSAContext() const { return Context; }
261261

262262
CycleT *getCycle(const BlockT *Block) const;

llvm/include/llvm/ADT/GenericSSAContext.h

Lines changed: 49 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -21,87 +21,78 @@
2121

2222
namespace llvm {
2323

24+
template <typename, bool> class DominatorTreeBase;
25+
template <typename> class SmallVectorImpl;
26+
27+
// Specializations of this template should provide the types used by the
28+
// template GenericSSAContext below.
29+
template <typename _FunctionT> struct GenericSSATraits;
30+
31+
// Ideally this should have been a stateless traits class. But the print methods
32+
// for Machine IR need access to the owning function. So we track that state in
33+
// the template itself.
34+
//
35+
// We use FunctionT as a template argument and not GenericSSATraits to allow
36+
// forward declarations using well-known typenames.
2437
template <typename _FunctionT> class GenericSSAContext {
25-
public:
26-
// Specializations should provide the following types that are similar to how
27-
// LLVM IR is structured:
38+
using SSATraits = GenericSSATraits<_FunctionT>;
39+
const typename SSATraits::FunctionT *F;
2840

41+
public:
2942
// The smallest unit of the IR is a ValueT. The SSA context uses a ValueRefT,
3043
// which is a pointer to a ValueT, since Machine IR does not have the
3144
// equivalent of a ValueT.
32-
//
33-
// using ValueRefT = ...
34-
//
45+
using ValueRefT = typename SSATraits::ValueRefT;
46+
3547
// The ConstValueRefT is needed to work with "const Value *", where const
3648
// needs to bind to the pointee and not the pointer.
37-
//
38-
// using ConstValueRefT = ...
39-
//
40-
// The null value for ValueRefT.
41-
//
42-
// static constexpr ValueRefT ValueRefNull;
49+
using ConstValueRefT = typename SSATraits::ConstValueRefT;
50+
51+
// The null value for ValueRefT. For LLVM IR and MIR, this is simply the
52+
// default constructed value.
53+
static constexpr ValueRefT *ValueRefNull = {};
4354

4455
// An InstructionT usually defines one or more ValueT objects.
45-
//
46-
// using InstructionT = ... must be a subclass of Value
56+
using InstructionT = typename SSATraits::InstructionT;
4757

4858
// A UseT represents a data-edge from the defining instruction to the using
4959
// instruction.
50-
//
51-
// using UseT = ...
60+
using UseT = typename SSATraits::UseT;
5261

5362
// A BlockT is a sequence of InstructionT, and forms a node of the CFG. It
5463
// has global methods predecessors() and successors() that return
5564
// the list of incoming CFG edges and outgoing CFG edges
5665
// respectively.
57-
//
58-
// using BlockT = ...
66+
using BlockT = typename SSATraits::BlockT;
5967

6068
// A FunctionT represents a CFG along with arguments and return values. It is
6169
// the smallest complete unit of code in a Module.
62-
//
63-
// The compiler produces an error here if this class is implicitly
64-
// specialized due to an instantiation. An explicit specialization
65-
// of this template needs to be added before the instantiation point
66-
// indicated by the compiler.
67-
using FunctionT = typename _FunctionT::invalidTemplateInstanceError;
70+
using FunctionT = typename SSATraits::FunctionT;
6871

6972
// A dominator tree provides the dominance relation between basic blocks in
7073
// a given funciton.
71-
//
72-
// using DominatorTreeT = ...
73-
74-
// Initialize the SSA context with information about the FunctionT being
75-
// processed.
76-
//
77-
// void setFunction(FunctionT &function);
78-
// FunctionT* getFunction() const;
79-
80-
// Every FunctionT has a unique BlockT marked as its entry.
81-
//
82-
// static BlockT* getEntryBlock(FunctionT &F);
83-
84-
// Methods to examine basic blocks and values
85-
//
86-
// static void appendBlockDefs(SmallVectorImpl<ValueRefT> &defs,
87-
// BlockT &block);
88-
// static void appendBlockDefs(SmallVectorImpl<const ValueRefT> &defs,
89-
// const BlockT &block);
90-
91-
// static void appendBlockTerms(SmallVectorImpl<InstructionT *> &terms,
92-
// BlockT &block);
93-
// static void appendBlockTerms(SmallVectorImpl<const InstructionT *> &terms,
94-
// const BlockT &block);
95-
//
96-
// static bool comesBefore(const InstructionT *lhs, const InstructionT *rhs);
97-
// static bool isConstantOrUndefValuePhi(const InstructionT &Instr);
98-
// const BlockT *getDefBlock(const ValueRefT value) const;
99-
100-
// Methods to print various objects.
101-
//
102-
// Printable print(BlockT *block) const;
103-
// Printable print(InstructionT *inst) const;
104-
// Printable print(ValueRefT value) const;
74+
using DominatorTreeT = DominatorTreeBase<BlockT, false>;
75+
76+
GenericSSAContext() = default;
77+
GenericSSAContext(const FunctionT *F) : F(F) {}
78+
79+
const FunctionT *getFunction() const { return F; }
80+
81+
static void appendBlockDefs(SmallVectorImpl<ValueRefT> &defs, BlockT &block);
82+
static void appendBlockDefs(SmallVectorImpl<ConstValueRefT> &defs,
83+
const BlockT &block);
84+
85+
static void appendBlockTerms(SmallVectorImpl<InstructionT *> &terms,
86+
BlockT &block);
87+
static void appendBlockTerms(SmallVectorImpl<const InstructionT *> &terms,
88+
const BlockT &block);
89+
90+
static bool isConstantOrUndefValuePhi(const InstructionT &Instr);
91+
const BlockT *getDefBlock(ConstValueRefT value) const;
92+
93+
Printable print(const BlockT *block) const;
94+
Printable print(const InstructionT *inst) const;
95+
Printable print(ConstValueRefT value) const;
10596
};
10697
} // namespace llvm
10798

llvm/include/llvm/ADT/GenericUniformityImpl.h

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -129,11 +129,11 @@ template <typename ContextT> class ModifiedPostOrder {
129129
const ContextT &Context;
130130

131131
void computeCyclePO(const CycleInfoT &CI, const CycleT *Cycle,
132-
SmallPtrSetImpl<BlockT *> &Finalized);
132+
SmallPtrSetImpl<const BlockT *> &Finalized);
133133

134-
void computeStackPO(SmallVectorImpl<BlockT *> &Stack, const CycleInfoT &CI,
135-
const CycleT *Cycle,
136-
SmallPtrSetImpl<BlockT *> &Finalized);
134+
void computeStackPO(SmallVectorImpl<const BlockT *> &Stack,
135+
const CycleInfoT &CI, const CycleT *Cycle,
136+
SmallPtrSetImpl<const BlockT *> &Finalized);
137137
};
138138

139139
template <typename> class DivergencePropagator;
@@ -342,11 +342,10 @@ template <typename ContextT> class GenericUniformityAnalysisImpl {
342342
typename SyncDependenceAnalysisT::DivergenceDescriptor;
343343
using BlockLabelMapT = typename SyncDependenceAnalysisT::BlockLabelMap;
344344

345-
GenericUniformityAnalysisImpl(const FunctionT &F, const DominatorTreeT &DT,
346-
const CycleInfoT &CI,
345+
GenericUniformityAnalysisImpl(const DominatorTreeT &DT, const CycleInfoT &CI,
347346
const TargetTransformInfo *TTI)
348-
: Context(CI.getSSAContext()), F(F), CI(CI), TTI(TTI), DT(DT),
349-
SDA(Context, DT, CI) {}
347+
: Context(CI.getSSAContext()), F(*Context.getFunction()), CI(CI),
348+
TTI(TTI), DT(DT), SDA(Context, DT, CI) {}
350349

351350
void initialize();
352351

@@ -1135,10 +1134,9 @@ bool GenericUniformityAnalysisImpl<ContextT>::isAlwaysUniform(
11351134

11361135
template <typename ContextT>
11371136
GenericUniformityInfo<ContextT>::GenericUniformityInfo(
1138-
FunctionT &Func, const DominatorTreeT &DT, const CycleInfoT &CI,
1139-
const TargetTransformInfo *TTI)
1140-
: F(&Func) {
1141-
DA.reset(new ImplT{Func, DT, CI, TTI});
1137+
const DominatorTreeT &DT, const CycleInfoT &CI,
1138+
const TargetTransformInfo *TTI) {
1139+
DA.reset(new ImplT{DT, CI, TTI});
11421140
}
11431141

11441142
template <typename ContextT>
@@ -1214,6 +1212,12 @@ bool GenericUniformityInfo<ContextT>::hasDivergence() const {
12141212
return DA->hasDivergence();
12151213
}
12161214

1215+
template <typename ContextT>
1216+
const typename ContextT::FunctionT &
1217+
GenericUniformityInfo<ContextT>::getFunction() const {
1218+
return DA->getFunction();
1219+
}
1220+
12171221
/// Whether \p V is divergent at its definition.
12181222
template <typename ContextT>
12191223
bool GenericUniformityInfo<ContextT>::isDivergent(ConstValueRefT V) const {
@@ -1243,8 +1247,8 @@ void GenericUniformityInfo<ContextT>::print(raw_ostream &out) const {
12431247

12441248
template <typename ContextT>
12451249
void llvm::ModifiedPostOrder<ContextT>::computeStackPO(
1246-
SmallVectorImpl<BlockT *> &Stack, const CycleInfoT &CI, const CycleT *Cycle,
1247-
SmallPtrSetImpl<BlockT *> &Finalized) {
1250+
SmallVectorImpl<const BlockT *> &Stack, const CycleInfoT &CI,
1251+
const CycleT *Cycle, SmallPtrSetImpl<const BlockT *> &Finalized) {
12481252
LLVM_DEBUG(dbgs() << "inside computeStackPO\n");
12491253
while (!Stack.empty()) {
12501254
auto *NextBB = Stack.back();
@@ -1313,9 +1317,9 @@ void llvm::ModifiedPostOrder<ContextT>::computeStackPO(
13131317
template <typename ContextT>
13141318
void ModifiedPostOrder<ContextT>::computeCyclePO(
13151319
const CycleInfoT &CI, const CycleT *Cycle,
1316-
SmallPtrSetImpl<BlockT *> &Finalized) {
1320+
SmallPtrSetImpl<const BlockT *> &Finalized) {
13171321
LLVM_DEBUG(dbgs() << "inside computeCyclePO\n");
1318-
SmallVector<BlockT *> Stack;
1322+
SmallVector<const BlockT *> Stack;
13191323
auto *CycleHeader = Cycle->getHeader();
13201324

13211325
LLVM_DEBUG(dbgs() << " noted header: "
@@ -1352,11 +1356,11 @@ void ModifiedPostOrder<ContextT>::computeCyclePO(
13521356
/// \brief Generically compute the modified post order.
13531357
template <typename ContextT>
13541358
void llvm::ModifiedPostOrder<ContextT>::compute(const CycleInfoT &CI) {
1355-
SmallPtrSet<BlockT *, 32> Finalized;
1356-
SmallVector<BlockT *> Stack;
1359+
SmallPtrSet<const BlockT *, 32> Finalized;
1360+
SmallVector<const BlockT *> Stack;
13571361
auto *F = CI.getFunction();
13581362
Stack.reserve(24); // FIXME made-up number
1359-
Stack.push_back(GraphTraits<FunctionT *>::getEntryNode(F));
1363+
Stack.push_back(&F->front());
13601364
computeStackPO(Stack, CI, nullptr, Finalized);
13611365
}
13621366

llvm/include/llvm/ADT/GenericUniformityInfo.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,7 @@ template <typename ContextT> class GenericUniformityInfo {
4040
using CycleInfoT = GenericCycleInfo<ContextT>;
4141
using CycleT = typename CycleInfoT::CycleT;
4242

43-
GenericUniformityInfo(FunctionT &F, const DominatorTreeT &DT,
44-
const CycleInfoT &CI,
43+
GenericUniformityInfo(const DominatorTreeT &DT, const CycleInfoT &CI,
4544
const TargetTransformInfo *TTI = nullptr);
4645
GenericUniformityInfo() = default;
4746
GenericUniformityInfo(GenericUniformityInfo &&) = default;
@@ -56,7 +55,7 @@ template <typename ContextT> class GenericUniformityInfo {
5655
bool hasDivergence() const;
5756

5857
/// The GPU kernel this analysis result is for
59-
const FunctionT &getFunction() const { return *F; }
58+
const FunctionT &getFunction() const;
6059

6160
/// Whether \p V is divergent at its definition.
6261
bool isDivergent(ConstValueRefT V) const;
@@ -82,7 +81,6 @@ template <typename ContextT> class GenericUniformityInfo {
8281
private:
8382
using ImplT = GenericUniformityAnalysisImpl<ContextT>;
8483

85-
FunctionT *F;
8684
std::unique_ptr<ImplT, GenericUniformityAnalysisImplDeleter<ImplT>> DA;
8785

8886
GenericUniformityInfo(const GenericUniformityInfo &) = delete;

llvm/include/llvm/CodeGen/MachineSSAContext.h

Lines changed: 2 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#ifndef LLVM_CODEGEN_MACHINESSACONTEXT_H
1616
#define LLVM_CODEGEN_MACHINESSACONTEXT_H
1717

18+
#include "llvm/ADT/GenericSSAContext.h"
1819
#include "llvm/CodeGen/MachineBasicBlock.h"
1920
#include "llvm/Support/Printable.h"
2021

@@ -23,8 +24,6 @@ class MachineRegisterInfo;
2324
class MachineInstr;
2425
class MachineFunction;
2526
class Register;
26-
template <typename _FunctionT> class GenericSSAContext;
27-
template <typename, bool> class DominatorTreeBase;
2827

2928
inline unsigned succ_size(const MachineBasicBlock *BB) {
3029
return BB->succ_size();
@@ -34,37 +33,13 @@ inline unsigned pred_size(const MachineBasicBlock *BB) {
3433
}
3534
inline auto instrs(const MachineBasicBlock &BB) { return BB.instrs(); }
3635

37-
template <> class GenericSSAContext<MachineFunction> {
38-
const MachineRegisterInfo *RegInfo = nullptr;
39-
MachineFunction *MF = nullptr;
40-
41-
public:
36+
template <> struct GenericSSATraits<MachineFunction> {
4237
using BlockT = MachineBasicBlock;
4338
using FunctionT = MachineFunction;
4439
using InstructionT = MachineInstr;
4540
using ValueRefT = Register;
4641
using ConstValueRefT = Register;
4742
using UseT = MachineOperand;
48-
using DominatorTreeT = DominatorTreeBase<BlockT, false>;
49-
50-
static constexpr Register ValueRefNull = 0;
51-
52-
void setFunction(MachineFunction &Fn);
53-
MachineFunction *getFunction() const { return MF; }
54-
55-
static MachineBasicBlock *getEntryBlock(MachineFunction &F);
56-
static void appendBlockDefs(SmallVectorImpl<Register> &defs,
57-
const MachineBasicBlock &block);
58-
static void appendBlockTerms(SmallVectorImpl<MachineInstr *> &terms,
59-
MachineBasicBlock &block);
60-
static void appendBlockTerms(SmallVectorImpl<const MachineInstr *> &terms,
61-
const MachineBasicBlock &block);
62-
MachineBasicBlock *getDefBlock(Register) const;
63-
static bool isConstantOrUndefValuePhi(const MachineInstr &Phi);
64-
65-
Printable print(const MachineBasicBlock *Block) const;
66-
Printable print(const MachineInstr *Inst) const;
67-
Printable print(Register Value) const;
6843
};
6944

7045
using MachineSSAContext = GenericSSAContext<MachineFunction>;

0 commit comments

Comments
 (0)