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