1
+ // ===- llvm/CodeGen/SSAIfConv.h - SSAIfConv ----------------------*- C++-*-===//
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-exception
6
+ //
7
+ // ===----------------------------------------------------------------------===//
8
+ //
9
+ // The SSAIfConv class performs if-conversion on SSA form machine code after
10
+ // determining if it is possible. The class contains no heuristics; external
11
+ // code should be used to determine when if-conversion is a good idea.
12
+ //
13
+ // SSAIfConv can convert both triangles and diamonds:
14
+ //
15
+ // Triangle: Head Diamond: Head
16
+ // | \ / \_
17
+ // | \ / |
18
+ // | [TF]BB FBB TBB
19
+ // | / \ /
20
+ // | / \ /
21
+ // Tail Tail
22
+ //
23
+ // Instructions in the conditional blocks TBB and/or FBB are spliced into the
24
+ // Head block, and phis in the Tail block are converted to select instructions.
25
+ //
26
+ // ===----------------------------------------------------------------------===//
27
+
28
+ #include " llvm/ADT/BitVector.h"
29
+ #include " llvm/ADT/SmallPtrSet.h"
30
+ #include " llvm/ADT/SparseSet.h"
31
+ #include " llvm/CodeGen/MachineDominators.h"
32
+ #include " llvm/CodeGen/MachineLoopInfo.h"
33
+ #include " llvm/CodeGen/MachineTraceMetrics.h"
34
+
35
+ #ifndef LLVM_CODEGEN_SSA_IF_CONV_H
36
+ #define LLVM_CODEGEN_SSA_IF_CONV_H
37
+ namespace llvm {
38
+ class SSAIfConv {
39
+ const TargetInstrInfo *TII;
40
+ const TargetRegisterInfo *TRI;
41
+ MachineRegisterInfo *MRI;
42
+ MachineDominatorTree *DomTree;
43
+ MachineLoopInfo *Loops;
44
+ MachineTraceMetrics *Traces;
45
+
46
+ public:
47
+ // / The block containing the conditional branch.
48
+ MachineBasicBlock *Head;
49
+
50
+ // / The block containing phis after the if-then-else.
51
+ MachineBasicBlock *Tail;
52
+
53
+ // / The 'true' conditional block as determined by analyzeBranch.
54
+ MachineBasicBlock *TBB;
55
+
56
+ // / The 'false' conditional block as determined by analyzeBranch.
57
+ MachineBasicBlock *FBB;
58
+
59
+ // / isTriangle - When there is no 'else' block, either TBB or FBB will be
60
+ // / equal to Tail.
61
+ bool isTriangle () const { return TBB == Tail || FBB == Tail; }
62
+
63
+ // / Returns the Tail predecessor for the True side.
64
+ MachineBasicBlock *getTPred () const { return TBB == Tail ? Head : TBB; }
65
+
66
+ // / Returns the Tail predecessor for the False side.
67
+ MachineBasicBlock *getFPred () const { return FBB == Tail ? Head : FBB; }
68
+
69
+ // / Information about each phi in the Tail block.
70
+ struct PHIInfo {
71
+ MachineInstr *PHI;
72
+ unsigned TReg = 0 , FReg = 0 ;
73
+ // Latencies from Cond+Branch, TReg, and FReg to DstReg.
74
+ int CondCycles = 0 , TCycles = 0 , FCycles = 0 ;
75
+
76
+ PHIInfo (MachineInstr *phi) : PHI(phi) {}
77
+ };
78
+
79
+ SmallVector<PHIInfo, 8 > PHIs;
80
+
81
+ // / The branch condition determined by analyzeBranch.
82
+ SmallVector<MachineOperand, 4 > Cond;
83
+
84
+ struct PredicationStrategyBase {
85
+ virtual bool canConvertIf (MachineBasicBlock *Tail) { return true ; }
86
+ virtual bool canPredicateInstr (const MachineInstr &I) = 0;
87
+ // / Apply cost model and heuristics to the if-conversion in IfConv.
88
+ // / Return true if the conversion is a good idea.
89
+ virtual bool shouldConvertIf (SSAIfConv &) = 0;
90
+ virtual void predicateBlock (MachineBasicBlock *MBB,
91
+ ArrayRef<MachineOperand> Cond,
92
+ bool Reverse) = 0;
93
+ virtual ~PredicationStrategyBase () = default ;
94
+ };
95
+
96
+ PredicationStrategyBase &Predicate;
97
+
98
+ public:
99
+ SSAIfConv (PredicationStrategyBase &Predicate, MachineFunction &MF,
100
+ MachineDominatorTree *DomTree, MachineLoopInfo *Loops,
101
+ MachineTraceMetrics *Traces = nullptr );
102
+
103
+ bool run ();
104
+
105
+ MachineTraceMetrics::Ensemble *getEnsemble (MachineTraceStrategy S);
106
+
107
+ private:
108
+ // / Instructions in Head that define values used by the conditional blocks.
109
+ // / The hoisted instructions must be inserted after these instructions.
110
+ SmallPtrSet<MachineInstr *, 8 > InsertAfter;
111
+
112
+ // / Register units clobbered by the conditional blocks.
113
+ BitVector ClobberedRegUnits;
114
+
115
+ // Scratch pad for findInsertionPoint.
116
+ SparseSet<unsigned > LiveRegUnits;
117
+
118
+ // / Insertion point in Head for speculatively executed instructions form TBB
119
+ // / and FBB.
120
+ MachineBasicBlock::iterator InsertionPoint;
121
+
122
+ // / Return true if all non-terminator instructions in MBB can be safely
123
+ // / predicated.
124
+ bool canPredicateInstrs (MachineBasicBlock *MBB);
125
+
126
+ // / Scan through instruction dependencies and update InsertAfter array.
127
+ // / Return false if any dependency is incompatible with if conversion.
128
+ bool InstrDependenciesAllowIfConv (MachineInstr *I);
129
+
130
+ // / Find a valid insertion point in Head.
131
+ bool findInsertionPoint ();
132
+
133
+ // / Replace PHI instructions in Tail with selects.
134
+ void replacePHIInstrs ();
135
+
136
+ // / Insert selects and rewrite PHI operands to use them.
137
+ void rewritePHIOperands ();
138
+
139
+ // / canConvertIf - If the sub-CFG headed by MBB can be if-converted,
140
+ // / initialize the internal state, and return true.
141
+ bool canConvertIf (MachineBasicBlock *MBB);
142
+
143
+ // / convertIf - If-convert the last block passed to canConvertIf(), assuming
144
+ // / it is possible. Add any blocks that are to be erased to RemoveBlocks.
145
+ void convertIf (SmallVectorImpl<MachineBasicBlock *> &RemoveBlocks);
146
+
147
+ // / Attempt repeated if-conversion on MBB, return true if successful.
148
+ bool tryConvertIf (MachineBasicBlock *);
149
+
150
+ // / Invalidate MachineTraceMetrics before if-conversion.
151
+ void invalidateTraces ();
152
+
153
+ // / Update the dominator tree after if-conversion erased some blocks.
154
+ void updateDomTree (ArrayRef<MachineBasicBlock *> Removed);
155
+
156
+ // / Update LoopInfo after if-conversion.
157
+ void updateLoops (ArrayRef<MachineBasicBlock *> Removed);
158
+ };
159
+
160
+ } // namespace llvm
161
+
162
+ #endif
0 commit comments