1*9880d681SAndroid Build Coastguard Worker //===--- HexagonExpandCondsets.cpp ----------------------------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker
10*9880d681SAndroid Build Coastguard Worker // Replace mux instructions with the corresponding legal instructions.
11*9880d681SAndroid Build Coastguard Worker // It is meant to work post-SSA, but still on virtual registers. It was
12*9880d681SAndroid Build Coastguard Worker // originally placed between register coalescing and machine instruction
13*9880d681SAndroid Build Coastguard Worker // scheduler.
14*9880d681SAndroid Build Coastguard Worker // In this place in the optimization sequence, live interval analysis had
15*9880d681SAndroid Build Coastguard Worker // been performed, and the live intervals should be preserved. A large part
16*9880d681SAndroid Build Coastguard Worker // of the code deals with preserving the liveness information.
17*9880d681SAndroid Build Coastguard Worker //
18*9880d681SAndroid Build Coastguard Worker // Liveness tracking aside, the main functionality of this pass is divided
19*9880d681SAndroid Build Coastguard Worker // into two steps. The first step is to replace an instruction
20*9880d681SAndroid Build Coastguard Worker // vreg0 = C2_mux vreg1, vreg2, vreg3
21*9880d681SAndroid Build Coastguard Worker // with a pair of conditional transfers
22*9880d681SAndroid Build Coastguard Worker // vreg0 = A2_tfrt vreg1, vreg2
23*9880d681SAndroid Build Coastguard Worker // vreg0 = A2_tfrf vreg1, vreg3
24*9880d681SAndroid Build Coastguard Worker // It is the intention that the execution of this pass could be terminated
25*9880d681SAndroid Build Coastguard Worker // after this step, and the code generated would be functionally correct.
26*9880d681SAndroid Build Coastguard Worker //
27*9880d681SAndroid Build Coastguard Worker // If the uses of the source values vreg1 and vreg2 are kills, and their
28*9880d681SAndroid Build Coastguard Worker // definitions are predicable, then in the second step, the conditional
29*9880d681SAndroid Build Coastguard Worker // transfers will then be rewritten as predicated instructions. E.g.
30*9880d681SAndroid Build Coastguard Worker // vreg0 = A2_or vreg1, vreg2
31*9880d681SAndroid Build Coastguard Worker // vreg3 = A2_tfrt vreg99, vreg0<kill>
32*9880d681SAndroid Build Coastguard Worker // will be rewritten as
33*9880d681SAndroid Build Coastguard Worker // vreg3 = A2_port vreg99, vreg1, vreg2
34*9880d681SAndroid Build Coastguard Worker //
35*9880d681SAndroid Build Coastguard Worker // This replacement has two variants: "up" and "down". Consider this case:
36*9880d681SAndroid Build Coastguard Worker // vreg0 = A2_or vreg1, vreg2
37*9880d681SAndroid Build Coastguard Worker // ... [intervening instructions] ...
38*9880d681SAndroid Build Coastguard Worker // vreg3 = A2_tfrt vreg99, vreg0<kill>
39*9880d681SAndroid Build Coastguard Worker // variant "up":
40*9880d681SAndroid Build Coastguard Worker // vreg3 = A2_port vreg99, vreg1, vreg2
41*9880d681SAndroid Build Coastguard Worker // ... [intervening instructions, vreg0->vreg3] ...
42*9880d681SAndroid Build Coastguard Worker // [deleted]
43*9880d681SAndroid Build Coastguard Worker // variant "down":
44*9880d681SAndroid Build Coastguard Worker // [deleted]
45*9880d681SAndroid Build Coastguard Worker // ... [intervening instructions] ...
46*9880d681SAndroid Build Coastguard Worker // vreg3 = A2_port vreg99, vreg1, vreg2
47*9880d681SAndroid Build Coastguard Worker //
48*9880d681SAndroid Build Coastguard Worker // Both, one or none of these variants may be valid, and checks are made
49*9880d681SAndroid Build Coastguard Worker // to rule out inapplicable variants.
50*9880d681SAndroid Build Coastguard Worker //
51*9880d681SAndroid Build Coastguard Worker // As an additional optimization, before either of the two steps above is
52*9880d681SAndroid Build Coastguard Worker // executed, the pass attempts to coalesce the target register with one of
53*9880d681SAndroid Build Coastguard Worker // the source registers, e.g. given an instruction
54*9880d681SAndroid Build Coastguard Worker // vreg3 = C2_mux vreg0, vreg1, vreg2
55*9880d681SAndroid Build Coastguard Worker // vreg3 will be coalesced with either vreg1 or vreg2. If this succeeds,
56*9880d681SAndroid Build Coastguard Worker // the instruction would then be (for example)
57*9880d681SAndroid Build Coastguard Worker // vreg3 = C2_mux vreg0, vreg3, vreg2
58*9880d681SAndroid Build Coastguard Worker // and, under certain circumstances, this could result in only one predicated
59*9880d681SAndroid Build Coastguard Worker // instruction:
60*9880d681SAndroid Build Coastguard Worker // vreg3 = A2_tfrf vreg0, vreg2
61*9880d681SAndroid Build Coastguard Worker //
62*9880d681SAndroid Build Coastguard Worker
63*9880d681SAndroid Build Coastguard Worker // Splitting a definition of a register into two predicated transfers
64*9880d681SAndroid Build Coastguard Worker // creates a complication in liveness tracking. Live interval computation
65*9880d681SAndroid Build Coastguard Worker // will see both instructions as actual definitions, and will mark the
66*9880d681SAndroid Build Coastguard Worker // first one as dead. The definition is not actually dead, and this
67*9880d681SAndroid Build Coastguard Worker // situation will need to be fixed. For example:
68*9880d681SAndroid Build Coastguard Worker // vreg1<def,dead> = A2_tfrt ... ; marked as dead
69*9880d681SAndroid Build Coastguard Worker // vreg1<def> = A2_tfrf ...
70*9880d681SAndroid Build Coastguard Worker //
71*9880d681SAndroid Build Coastguard Worker // Since any of the individual predicated transfers may end up getting
72*9880d681SAndroid Build Coastguard Worker // removed (in case it is an identity copy), some pre-existing def may
73*9880d681SAndroid Build Coastguard Worker // be marked as dead after live interval recomputation:
74*9880d681SAndroid Build Coastguard Worker // vreg1<def,dead> = ... ; marked as dead
75*9880d681SAndroid Build Coastguard Worker // ...
76*9880d681SAndroid Build Coastguard Worker // vreg1<def> = A2_tfrf ... ; if A2_tfrt is removed
77*9880d681SAndroid Build Coastguard Worker // This case happens if vreg1 was used as a source in A2_tfrt, which means
78*9880d681SAndroid Build Coastguard Worker // that is it actually live at the A2_tfrf, and so the now dead definition
79*9880d681SAndroid Build Coastguard Worker // of vreg1 will need to be updated to non-dead at some point.
80*9880d681SAndroid Build Coastguard Worker //
81*9880d681SAndroid Build Coastguard Worker // This issue could be remedied by adding implicit uses to the predicated
82*9880d681SAndroid Build Coastguard Worker // transfers, but this will create a problem with subsequent predication,
83*9880d681SAndroid Build Coastguard Worker // since the transfers will no longer be possible to reorder. To avoid
84*9880d681SAndroid Build Coastguard Worker // that, the initial splitting will not add any implicit uses. These
85*9880d681SAndroid Build Coastguard Worker // implicit uses will be added later, after predication. The extra price,
86*9880d681SAndroid Build Coastguard Worker // however, is that finding the locations where the implicit uses need
87*9880d681SAndroid Build Coastguard Worker // to be added, and updating the live ranges will be more involved.
88*9880d681SAndroid Build Coastguard Worker //
89*9880d681SAndroid Build Coastguard Worker // An additional problem appears when subregister liveness tracking is
90*9880d681SAndroid Build Coastguard Worker // enabled. In such a scenario, the live interval for the super-register
91*9880d681SAndroid Build Coastguard Worker // will have live ranges for each subregister (i.e. subranges). This sub-
92*9880d681SAndroid Build Coastguard Worker // range contains all liveness information about the subregister, except
93*9880d681SAndroid Build Coastguard Worker // for one case: a "read-undef" flag from another subregister will not
94*9880d681SAndroid Build Coastguard Worker // be reflected: given
95*9880d681SAndroid Build Coastguard Worker // vreg1:subreg_hireg<def,read-undef> = ... ; "undefines" subreg_loreg
96*9880d681SAndroid Build Coastguard Worker // the subrange for subreg_loreg will not have any indication that it is
97*9880d681SAndroid Build Coastguard Worker // undefined at this point. Calculating subregister liveness based only
98*9880d681SAndroid Build Coastguard Worker // on the information from the subrange may create a segment which spans
99*9880d681SAndroid Build Coastguard Worker // over such a "read-undef" flag. This would create inconsistencies in
100*9880d681SAndroid Build Coastguard Worker // the liveness data, resulting in assertions or incorrect code.
101*9880d681SAndroid Build Coastguard Worker // Example:
102*9880d681SAndroid Build Coastguard Worker // vreg1:subreg_loreg<def> = ...
103*9880d681SAndroid Build Coastguard Worker // vreg1:subreg_hireg<def, read-undef> = ... ; "undefines" subreg_loreg
104*9880d681SAndroid Build Coastguard Worker // ...
105*9880d681SAndroid Build Coastguard Worker // vreg1:subreg_loreg<def> = A2_tfrt ... ; may end up with imp-use
106*9880d681SAndroid Build Coastguard Worker // ; of subreg_loreg
107*9880d681SAndroid Build Coastguard Worker // The remedy takes advantage of the fact, that at this point we have
108*9880d681SAndroid Build Coastguard Worker // an unconditional definition of the subregister. What this means is
109*9880d681SAndroid Build Coastguard Worker // that any preceding value in this subregister will be overwritten,
110*9880d681SAndroid Build Coastguard Worker // or in other words, the last use before this def is a kill. This also
111*9880d681SAndroid Build Coastguard Worker // implies that the first of the predicated transfers at this location
112*9880d681SAndroid Build Coastguard Worker // should not have any implicit uses.
113*9880d681SAndroid Build Coastguard Worker // Assume for a moment that no part of the corresponding super-register
114*9880d681SAndroid Build Coastguard Worker // is used as a source. In such case, the entire super-register can be
115*9880d681SAndroid Build Coastguard Worker // considered undefined immediately before this instruction. Because of
116*9880d681SAndroid Build Coastguard Worker // that, we can insert an IMPLICIT_DEF of the super-register at this
117*9880d681SAndroid Build Coastguard Worker // location, which will cause it to be reflected in all the associated
118*9880d681SAndroid Build Coastguard Worker // subranges. What is important here is that if an IMPLICIT_DEF of
119*9880d681SAndroid Build Coastguard Worker // subreg_loreg was used, we would lose the indication that subreg_hireg
120*9880d681SAndroid Build Coastguard Worker // is also considered undefined. This could lead to having implicit uses
121*9880d681SAndroid Build Coastguard Worker // incorrectly added.
122*9880d681SAndroid Build Coastguard Worker //
123*9880d681SAndroid Build Coastguard Worker // What is left is the two cases when the super-register is used as a
124*9880d681SAndroid Build Coastguard Worker // source.
125*9880d681SAndroid Build Coastguard Worker // * Case 1: the used part is the same as the one that is defined:
126*9880d681SAndroid Build Coastguard Worker // vreg1<def> = ...
127*9880d681SAndroid Build Coastguard Worker // ...
128*9880d681SAndroid Build Coastguard Worker // vreg1:subreg_loreg<def,read-undef> = C2_mux ..., vreg1:subreg_loreg
129*9880d681SAndroid Build Coastguard Worker // In the end, the subreg_loreg should be marked as live at the point of
130*9880d681SAndroid Build Coastguard Worker // the splitting:
131*9880d681SAndroid Build Coastguard Worker // vreg1:subreg_loreg<def,read-undef> = A2_tfrt ; should have imp-use
132*9880d681SAndroid Build Coastguard Worker // vreg1:subreg_loreg<def,read-undef> = A2_tfrf ; should have imp-use
133*9880d681SAndroid Build Coastguard Worker // Hence, an IMPLICIT_DEF of only vreg1:subreg_hireg would be sufficient.
134*9880d681SAndroid Build Coastguard Worker // * Case 2: the used part does not overlap the part being defined:
135*9880d681SAndroid Build Coastguard Worker // vreg1<def> = ...
136*9880d681SAndroid Build Coastguard Worker // ...
137*9880d681SAndroid Build Coastguard Worker // vreg1:subreg_loreg<def,read-undef> = C2_mux ..., vreg1:subreg_hireg
138*9880d681SAndroid Build Coastguard Worker // For this case, we insert an IMPLICIT_DEF of vreg1:subreg_hireg after
139*9880d681SAndroid Build Coastguard Worker // the C2_mux.
140*9880d681SAndroid Build Coastguard Worker
141*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "expand-condsets"
142*9880d681SAndroid Build Coastguard Worker
143*9880d681SAndroid Build Coastguard Worker #include "HexagonTargetMachine.h"
144*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SetVector.h"
145*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/Passes.h"
146*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/LiveInterval.h"
147*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/LiveIntervalAnalysis.h"
148*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineDominators.h"
149*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunction.h"
150*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineInstrBuilder.h"
151*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h"
152*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetInstrInfo.h"
153*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetMachine.h"
154*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetRegisterInfo.h"
155*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/CommandLine.h"
156*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
157*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
158*9880d681SAndroid Build Coastguard Worker
159*9880d681SAndroid Build Coastguard Worker #include <algorithm>
160*9880d681SAndroid Build Coastguard Worker #include <iterator>
161*9880d681SAndroid Build Coastguard Worker #include <set>
162*9880d681SAndroid Build Coastguard Worker #include <utility>
163*9880d681SAndroid Build Coastguard Worker
164*9880d681SAndroid Build Coastguard Worker using namespace llvm;
165*9880d681SAndroid Build Coastguard Worker
166*9880d681SAndroid Build Coastguard Worker static cl::opt<unsigned> OptTfrLimit("expand-condsets-tfr-limit",
167*9880d681SAndroid Build Coastguard Worker cl::init(~0U), cl::Hidden, cl::desc("Max number of mux expansions"));
168*9880d681SAndroid Build Coastguard Worker static cl::opt<unsigned> OptCoaLimit("expand-condsets-coa-limit",
169*9880d681SAndroid Build Coastguard Worker cl::init(~0U), cl::Hidden, cl::desc("Max number of segment coalescings"));
170*9880d681SAndroid Build Coastguard Worker
171*9880d681SAndroid Build Coastguard Worker namespace llvm {
172*9880d681SAndroid Build Coastguard Worker void initializeHexagonExpandCondsetsPass(PassRegistry&);
173*9880d681SAndroid Build Coastguard Worker FunctionPass *createHexagonExpandCondsets();
174*9880d681SAndroid Build Coastguard Worker }
175*9880d681SAndroid Build Coastguard Worker
176*9880d681SAndroid Build Coastguard Worker namespace {
177*9880d681SAndroid Build Coastguard Worker class HexagonExpandCondsets : public MachineFunctionPass {
178*9880d681SAndroid Build Coastguard Worker public:
179*9880d681SAndroid Build Coastguard Worker static char ID;
HexagonExpandCondsets()180*9880d681SAndroid Build Coastguard Worker HexagonExpandCondsets() :
181*9880d681SAndroid Build Coastguard Worker MachineFunctionPass(ID), HII(0), TRI(0), MRI(0),
182*9880d681SAndroid Build Coastguard Worker LIS(0), CoaLimitActive(false),
183*9880d681SAndroid Build Coastguard Worker TfrLimitActive(false), CoaCounter(0), TfrCounter(0) {
184*9880d681SAndroid Build Coastguard Worker if (OptCoaLimit.getPosition())
185*9880d681SAndroid Build Coastguard Worker CoaLimitActive = true, CoaLimit = OptCoaLimit;
186*9880d681SAndroid Build Coastguard Worker if (OptTfrLimit.getPosition())
187*9880d681SAndroid Build Coastguard Worker TfrLimitActive = true, TfrLimit = OptTfrLimit;
188*9880d681SAndroid Build Coastguard Worker initializeHexagonExpandCondsetsPass(*PassRegistry::getPassRegistry());
189*9880d681SAndroid Build Coastguard Worker }
190*9880d681SAndroid Build Coastguard Worker
getPassName() const191*9880d681SAndroid Build Coastguard Worker const char *getPassName() const override {
192*9880d681SAndroid Build Coastguard Worker return "Hexagon Expand Condsets";
193*9880d681SAndroid Build Coastguard Worker }
getAnalysisUsage(AnalysisUsage & AU) const194*9880d681SAndroid Build Coastguard Worker void getAnalysisUsage(AnalysisUsage &AU) const override {
195*9880d681SAndroid Build Coastguard Worker AU.addRequired<LiveIntervals>();
196*9880d681SAndroid Build Coastguard Worker AU.addPreserved<LiveIntervals>();
197*9880d681SAndroid Build Coastguard Worker AU.addPreserved<SlotIndexes>();
198*9880d681SAndroid Build Coastguard Worker AU.addRequired<MachineDominatorTree>();
199*9880d681SAndroid Build Coastguard Worker AU.addPreserved<MachineDominatorTree>();
200*9880d681SAndroid Build Coastguard Worker MachineFunctionPass::getAnalysisUsage(AU);
201*9880d681SAndroid Build Coastguard Worker }
202*9880d681SAndroid Build Coastguard Worker bool runOnMachineFunction(MachineFunction &MF) override;
203*9880d681SAndroid Build Coastguard Worker
204*9880d681SAndroid Build Coastguard Worker private:
205*9880d681SAndroid Build Coastguard Worker const HexagonInstrInfo *HII;
206*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo *TRI;
207*9880d681SAndroid Build Coastguard Worker MachineDominatorTree *MDT;
208*9880d681SAndroid Build Coastguard Worker MachineRegisterInfo *MRI;
209*9880d681SAndroid Build Coastguard Worker LiveIntervals *LIS;
210*9880d681SAndroid Build Coastguard Worker std::set<MachineInstr*> LocalImpDefs;
211*9880d681SAndroid Build Coastguard Worker
212*9880d681SAndroid Build Coastguard Worker bool CoaLimitActive, TfrLimitActive;
213*9880d681SAndroid Build Coastguard Worker unsigned CoaLimit, TfrLimit, CoaCounter, TfrCounter;
214*9880d681SAndroid Build Coastguard Worker
215*9880d681SAndroid Build Coastguard Worker struct RegisterRef {
RegisterRef__anon8b6b7a040111::HexagonExpandCondsets::RegisterRef216*9880d681SAndroid Build Coastguard Worker RegisterRef(const MachineOperand &Op) : Reg(Op.getReg()),
217*9880d681SAndroid Build Coastguard Worker Sub(Op.getSubReg()) {}
RegisterRef__anon8b6b7a040111::HexagonExpandCondsets::RegisterRef218*9880d681SAndroid Build Coastguard Worker RegisterRef(unsigned R = 0, unsigned S = 0) : Reg(R), Sub(S) {}
operator ==__anon8b6b7a040111::HexagonExpandCondsets::RegisterRef219*9880d681SAndroid Build Coastguard Worker bool operator== (RegisterRef RR) const {
220*9880d681SAndroid Build Coastguard Worker return Reg == RR.Reg && Sub == RR.Sub;
221*9880d681SAndroid Build Coastguard Worker }
operator !=__anon8b6b7a040111::HexagonExpandCondsets::RegisterRef222*9880d681SAndroid Build Coastguard Worker bool operator!= (RegisterRef RR) const { return !operator==(RR); }
operator <__anon8b6b7a040111::HexagonExpandCondsets::RegisterRef223*9880d681SAndroid Build Coastguard Worker bool operator< (RegisterRef RR) const {
224*9880d681SAndroid Build Coastguard Worker return Reg < RR.Reg || (Reg == RR.Reg && Sub < RR.Sub);
225*9880d681SAndroid Build Coastguard Worker }
226*9880d681SAndroid Build Coastguard Worker unsigned Reg, Sub;
227*9880d681SAndroid Build Coastguard Worker };
228*9880d681SAndroid Build Coastguard Worker
229*9880d681SAndroid Build Coastguard Worker typedef DenseMap<unsigned,unsigned> ReferenceMap;
230*9880d681SAndroid Build Coastguard Worker enum { Sub_Low = 0x1, Sub_High = 0x2, Sub_None = (Sub_Low | Sub_High) };
231*9880d681SAndroid Build Coastguard Worker enum { Exec_Then = 0x10, Exec_Else = 0x20 };
232*9880d681SAndroid Build Coastguard Worker unsigned getMaskForSub(unsigned Sub);
233*9880d681SAndroid Build Coastguard Worker bool isCondset(const MachineInstr &MI);
234*9880d681SAndroid Build Coastguard Worker LaneBitmask getLaneMask(unsigned Reg, unsigned Sub);
235*9880d681SAndroid Build Coastguard Worker
236*9880d681SAndroid Build Coastguard Worker void addRefToMap(RegisterRef RR, ReferenceMap &Map, unsigned Exec);
237*9880d681SAndroid Build Coastguard Worker bool isRefInMap(RegisterRef, ReferenceMap &Map, unsigned Exec);
238*9880d681SAndroid Build Coastguard Worker
239*9880d681SAndroid Build Coastguard Worker void removeImpDefSegments(LiveRange &Range);
240*9880d681SAndroid Build Coastguard Worker void updateDeadsInRange(unsigned Reg, LaneBitmask LM, LiveRange &Range);
241*9880d681SAndroid Build Coastguard Worker void updateKillFlags(unsigned Reg);
242*9880d681SAndroid Build Coastguard Worker void updateDeadFlags(unsigned Reg);
243*9880d681SAndroid Build Coastguard Worker void recalculateLiveInterval(unsigned Reg);
244*9880d681SAndroid Build Coastguard Worker void removeInstr(MachineInstr &MI);
245*9880d681SAndroid Build Coastguard Worker void updateLiveness(std::set<unsigned> &RegSet, bool Recalc,
246*9880d681SAndroid Build Coastguard Worker bool UpdateKills, bool UpdateDeads);
247*9880d681SAndroid Build Coastguard Worker
248*9880d681SAndroid Build Coastguard Worker unsigned getCondTfrOpcode(const MachineOperand &SO, bool Cond);
249*9880d681SAndroid Build Coastguard Worker MachineInstr *genCondTfrFor(MachineOperand &SrcOp,
250*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator At, unsigned DstR,
251*9880d681SAndroid Build Coastguard Worker unsigned DstSR, const MachineOperand &PredOp, bool PredSense,
252*9880d681SAndroid Build Coastguard Worker bool ReadUndef, bool ImpUse);
253*9880d681SAndroid Build Coastguard Worker bool split(MachineInstr &MI, std::set<unsigned> &UpdRegs);
254*9880d681SAndroid Build Coastguard Worker bool splitInBlock(MachineBasicBlock &B, std::set<unsigned> &UpdRegs);
255*9880d681SAndroid Build Coastguard Worker
256*9880d681SAndroid Build Coastguard Worker bool isPredicable(MachineInstr *MI);
257*9880d681SAndroid Build Coastguard Worker MachineInstr *getReachingDefForPred(RegisterRef RD,
258*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator UseIt, unsigned PredR, bool Cond);
259*9880d681SAndroid Build Coastguard Worker bool canMoveOver(MachineInstr &MI, ReferenceMap &Defs, ReferenceMap &Uses);
260*9880d681SAndroid Build Coastguard Worker bool canMoveMemTo(MachineInstr &MI, MachineInstr &ToI, bool IsDown);
261*9880d681SAndroid Build Coastguard Worker void predicateAt(const MachineOperand &DefOp, MachineInstr &MI,
262*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator Where,
263*9880d681SAndroid Build Coastguard Worker const MachineOperand &PredOp, bool Cond,
264*9880d681SAndroid Build Coastguard Worker std::set<unsigned> &UpdRegs);
265*9880d681SAndroid Build Coastguard Worker void renameInRange(RegisterRef RO, RegisterRef RN, unsigned PredR,
266*9880d681SAndroid Build Coastguard Worker bool Cond, MachineBasicBlock::iterator First,
267*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator Last);
268*9880d681SAndroid Build Coastguard Worker bool predicate(MachineInstr &TfrI, bool Cond, std::set<unsigned> &UpdRegs);
269*9880d681SAndroid Build Coastguard Worker bool predicateInBlock(MachineBasicBlock &B,
270*9880d681SAndroid Build Coastguard Worker std::set<unsigned> &UpdRegs);
271*9880d681SAndroid Build Coastguard Worker
272*9880d681SAndroid Build Coastguard Worker bool isIntReg(RegisterRef RR, unsigned &BW);
273*9880d681SAndroid Build Coastguard Worker bool isIntraBlocks(LiveInterval &LI);
274*9880d681SAndroid Build Coastguard Worker bool coalesceRegisters(RegisterRef R1, RegisterRef R2);
275*9880d681SAndroid Build Coastguard Worker bool coalesceSegments(MachineFunction &MF);
276*9880d681SAndroid Build Coastguard Worker };
277*9880d681SAndroid Build Coastguard Worker }
278*9880d681SAndroid Build Coastguard Worker
279*9880d681SAndroid Build Coastguard Worker char HexagonExpandCondsets::ID = 0;
280*9880d681SAndroid Build Coastguard Worker
281*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_BEGIN(HexagonExpandCondsets, "expand-condsets",
282*9880d681SAndroid Build Coastguard Worker "Hexagon Expand Condsets", false, false)
INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)283*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
284*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_DEPENDENCY(SlotIndexes)
285*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
286*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_END(HexagonExpandCondsets, "expand-condsets",
287*9880d681SAndroid Build Coastguard Worker "Hexagon Expand Condsets", false, false)
288*9880d681SAndroid Build Coastguard Worker
289*9880d681SAndroid Build Coastguard Worker unsigned HexagonExpandCondsets::getMaskForSub(unsigned Sub) {
290*9880d681SAndroid Build Coastguard Worker switch (Sub) {
291*9880d681SAndroid Build Coastguard Worker case Hexagon::subreg_loreg:
292*9880d681SAndroid Build Coastguard Worker return Sub_Low;
293*9880d681SAndroid Build Coastguard Worker case Hexagon::subreg_hireg:
294*9880d681SAndroid Build Coastguard Worker return Sub_High;
295*9880d681SAndroid Build Coastguard Worker case Hexagon::NoSubRegister:
296*9880d681SAndroid Build Coastguard Worker return Sub_None;
297*9880d681SAndroid Build Coastguard Worker }
298*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Invalid subregister");
299*9880d681SAndroid Build Coastguard Worker }
300*9880d681SAndroid Build Coastguard Worker
isCondset(const MachineInstr & MI)301*9880d681SAndroid Build Coastguard Worker bool HexagonExpandCondsets::isCondset(const MachineInstr &MI) {
302*9880d681SAndroid Build Coastguard Worker unsigned Opc = MI.getOpcode();
303*9880d681SAndroid Build Coastguard Worker switch (Opc) {
304*9880d681SAndroid Build Coastguard Worker case Hexagon::C2_mux:
305*9880d681SAndroid Build Coastguard Worker case Hexagon::C2_muxii:
306*9880d681SAndroid Build Coastguard Worker case Hexagon::C2_muxir:
307*9880d681SAndroid Build Coastguard Worker case Hexagon::C2_muxri:
308*9880d681SAndroid Build Coastguard Worker case Hexagon::MUX64_rr:
309*9880d681SAndroid Build Coastguard Worker return true;
310*9880d681SAndroid Build Coastguard Worker break;
311*9880d681SAndroid Build Coastguard Worker }
312*9880d681SAndroid Build Coastguard Worker return false;
313*9880d681SAndroid Build Coastguard Worker }
314*9880d681SAndroid Build Coastguard Worker
315*9880d681SAndroid Build Coastguard Worker
getLaneMask(unsigned Reg,unsigned Sub)316*9880d681SAndroid Build Coastguard Worker LaneBitmask HexagonExpandCondsets::getLaneMask(unsigned Reg, unsigned Sub) {
317*9880d681SAndroid Build Coastguard Worker assert(TargetRegisterInfo::isVirtualRegister(Reg));
318*9880d681SAndroid Build Coastguard Worker return Sub != 0 ? TRI->getSubRegIndexLaneMask(Sub)
319*9880d681SAndroid Build Coastguard Worker : MRI->getMaxLaneMaskForVReg(Reg);
320*9880d681SAndroid Build Coastguard Worker }
321*9880d681SAndroid Build Coastguard Worker
322*9880d681SAndroid Build Coastguard Worker
addRefToMap(RegisterRef RR,ReferenceMap & Map,unsigned Exec)323*9880d681SAndroid Build Coastguard Worker void HexagonExpandCondsets::addRefToMap(RegisterRef RR, ReferenceMap &Map,
324*9880d681SAndroid Build Coastguard Worker unsigned Exec) {
325*9880d681SAndroid Build Coastguard Worker unsigned Mask = getMaskForSub(RR.Sub) | Exec;
326*9880d681SAndroid Build Coastguard Worker ReferenceMap::iterator F = Map.find(RR.Reg);
327*9880d681SAndroid Build Coastguard Worker if (F == Map.end())
328*9880d681SAndroid Build Coastguard Worker Map.insert(std::make_pair(RR.Reg, Mask));
329*9880d681SAndroid Build Coastguard Worker else
330*9880d681SAndroid Build Coastguard Worker F->second |= Mask;
331*9880d681SAndroid Build Coastguard Worker }
332*9880d681SAndroid Build Coastguard Worker
333*9880d681SAndroid Build Coastguard Worker
isRefInMap(RegisterRef RR,ReferenceMap & Map,unsigned Exec)334*9880d681SAndroid Build Coastguard Worker bool HexagonExpandCondsets::isRefInMap(RegisterRef RR, ReferenceMap &Map,
335*9880d681SAndroid Build Coastguard Worker unsigned Exec) {
336*9880d681SAndroid Build Coastguard Worker ReferenceMap::iterator F = Map.find(RR.Reg);
337*9880d681SAndroid Build Coastguard Worker if (F == Map.end())
338*9880d681SAndroid Build Coastguard Worker return false;
339*9880d681SAndroid Build Coastguard Worker unsigned Mask = getMaskForSub(RR.Sub) | Exec;
340*9880d681SAndroid Build Coastguard Worker if (Mask & F->second)
341*9880d681SAndroid Build Coastguard Worker return true;
342*9880d681SAndroid Build Coastguard Worker return false;
343*9880d681SAndroid Build Coastguard Worker }
344*9880d681SAndroid Build Coastguard Worker
345*9880d681SAndroid Build Coastguard Worker
updateKillFlags(unsigned Reg)346*9880d681SAndroid Build Coastguard Worker void HexagonExpandCondsets::updateKillFlags(unsigned Reg) {
347*9880d681SAndroid Build Coastguard Worker auto KillAt = [this,Reg] (SlotIndex K, LaneBitmask LM) -> void {
348*9880d681SAndroid Build Coastguard Worker // Set the <kill> flag on a use of Reg whose lane mask is contained in LM.
349*9880d681SAndroid Build Coastguard Worker MachineInstr *MI = LIS->getInstructionFromIndex(K);
350*9880d681SAndroid Build Coastguard Worker for (auto &Op : MI->operands()) {
351*9880d681SAndroid Build Coastguard Worker if (!Op.isReg() || !Op.isUse() || Op.getReg() != Reg)
352*9880d681SAndroid Build Coastguard Worker continue;
353*9880d681SAndroid Build Coastguard Worker LaneBitmask SLM = getLaneMask(Reg, Op.getSubReg());
354*9880d681SAndroid Build Coastguard Worker if ((SLM & LM) == SLM) {
355*9880d681SAndroid Build Coastguard Worker // Only set the kill flag on the first encountered use of Reg in this
356*9880d681SAndroid Build Coastguard Worker // instruction.
357*9880d681SAndroid Build Coastguard Worker Op.setIsKill(true);
358*9880d681SAndroid Build Coastguard Worker break;
359*9880d681SAndroid Build Coastguard Worker }
360*9880d681SAndroid Build Coastguard Worker }
361*9880d681SAndroid Build Coastguard Worker };
362*9880d681SAndroid Build Coastguard Worker
363*9880d681SAndroid Build Coastguard Worker LiveInterval &LI = LIS->getInterval(Reg);
364*9880d681SAndroid Build Coastguard Worker for (auto I = LI.begin(), E = LI.end(); I != E; ++I) {
365*9880d681SAndroid Build Coastguard Worker if (!I->end.isRegister())
366*9880d681SAndroid Build Coastguard Worker continue;
367*9880d681SAndroid Build Coastguard Worker // Do not mark the end of the segment as <kill>, if the next segment
368*9880d681SAndroid Build Coastguard Worker // starts with a predicated instruction.
369*9880d681SAndroid Build Coastguard Worker auto NextI = std::next(I);
370*9880d681SAndroid Build Coastguard Worker if (NextI != E && NextI->start.isRegister()) {
371*9880d681SAndroid Build Coastguard Worker MachineInstr *DefI = LIS->getInstructionFromIndex(NextI->start);
372*9880d681SAndroid Build Coastguard Worker if (HII->isPredicated(*DefI))
373*9880d681SAndroid Build Coastguard Worker continue;
374*9880d681SAndroid Build Coastguard Worker }
375*9880d681SAndroid Build Coastguard Worker bool WholeReg = true;
376*9880d681SAndroid Build Coastguard Worker if (LI.hasSubRanges()) {
377*9880d681SAndroid Build Coastguard Worker auto EndsAtI = [I] (LiveInterval::SubRange &S) -> bool {
378*9880d681SAndroid Build Coastguard Worker LiveRange::iterator F = S.find(I->end);
379*9880d681SAndroid Build Coastguard Worker return F != S.end() && I->end == F->end;
380*9880d681SAndroid Build Coastguard Worker };
381*9880d681SAndroid Build Coastguard Worker // Check if all subranges end at I->end. If so, make sure to kill
382*9880d681SAndroid Build Coastguard Worker // the whole register.
383*9880d681SAndroid Build Coastguard Worker for (LiveInterval::SubRange &S : LI.subranges()) {
384*9880d681SAndroid Build Coastguard Worker if (EndsAtI(S))
385*9880d681SAndroid Build Coastguard Worker KillAt(I->end, S.LaneMask);
386*9880d681SAndroid Build Coastguard Worker else
387*9880d681SAndroid Build Coastguard Worker WholeReg = false;
388*9880d681SAndroid Build Coastguard Worker }
389*9880d681SAndroid Build Coastguard Worker }
390*9880d681SAndroid Build Coastguard Worker if (WholeReg)
391*9880d681SAndroid Build Coastguard Worker KillAt(I->end, MRI->getMaxLaneMaskForVReg(Reg));
392*9880d681SAndroid Build Coastguard Worker }
393*9880d681SAndroid Build Coastguard Worker }
394*9880d681SAndroid Build Coastguard Worker
395*9880d681SAndroid Build Coastguard Worker
removeImpDefSegments(LiveRange & Range)396*9880d681SAndroid Build Coastguard Worker void HexagonExpandCondsets::removeImpDefSegments(LiveRange &Range) {
397*9880d681SAndroid Build Coastguard Worker auto StartImpDef = [this] (LiveRange::Segment &S) -> bool {
398*9880d681SAndroid Build Coastguard Worker return S.start.isRegister() &&
399*9880d681SAndroid Build Coastguard Worker LocalImpDefs.count(LIS->getInstructionFromIndex(S.start));
400*9880d681SAndroid Build Coastguard Worker };
401*9880d681SAndroid Build Coastguard Worker Range.segments.erase(std::remove_if(Range.begin(), Range.end(), StartImpDef),
402*9880d681SAndroid Build Coastguard Worker Range.end());
403*9880d681SAndroid Build Coastguard Worker }
404*9880d681SAndroid Build Coastguard Worker
updateDeadsInRange(unsigned Reg,LaneBitmask LM,LiveRange & Range)405*9880d681SAndroid Build Coastguard Worker void HexagonExpandCondsets::updateDeadsInRange(unsigned Reg, LaneBitmask LM,
406*9880d681SAndroid Build Coastguard Worker LiveRange &Range) {
407*9880d681SAndroid Build Coastguard Worker assert(TargetRegisterInfo::isVirtualRegister(Reg));
408*9880d681SAndroid Build Coastguard Worker if (Range.empty())
409*9880d681SAndroid Build Coastguard Worker return;
410*9880d681SAndroid Build Coastguard Worker
411*9880d681SAndroid Build Coastguard Worker auto IsRegDef = [this,Reg,LM] (MachineOperand &Op) -> bool {
412*9880d681SAndroid Build Coastguard Worker if (!Op.isReg() || !Op.isDef())
413*9880d681SAndroid Build Coastguard Worker return false;
414*9880d681SAndroid Build Coastguard Worker unsigned DR = Op.getReg(), DSR = Op.getSubReg();
415*9880d681SAndroid Build Coastguard Worker if (!TargetRegisterInfo::isVirtualRegister(DR) || DR != Reg)
416*9880d681SAndroid Build Coastguard Worker return false;
417*9880d681SAndroid Build Coastguard Worker LaneBitmask SLM = getLaneMask(DR, DSR);
418*9880d681SAndroid Build Coastguard Worker return (SLM & LM) != 0;
419*9880d681SAndroid Build Coastguard Worker };
420*9880d681SAndroid Build Coastguard Worker
421*9880d681SAndroid Build Coastguard Worker // The splitting step will create pairs of predicated definitions without
422*9880d681SAndroid Build Coastguard Worker // any implicit uses (since implicit uses would interfere with predication).
423*9880d681SAndroid Build Coastguard Worker // This can cause the reaching defs to become dead after live range
424*9880d681SAndroid Build Coastguard Worker // recomputation, even though they are not really dead.
425*9880d681SAndroid Build Coastguard Worker // We need to identify predicated defs that need implicit uses, and
426*9880d681SAndroid Build Coastguard Worker // dead defs that are not really dead, and correct both problems.
427*9880d681SAndroid Build Coastguard Worker
428*9880d681SAndroid Build Coastguard Worker SetVector<MachineBasicBlock*> Defs;
429*9880d681SAndroid Build Coastguard Worker auto Dominate = [this] (SetVector<MachineBasicBlock*> &Defs,
430*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *Dest) -> bool {
431*9880d681SAndroid Build Coastguard Worker for (MachineBasicBlock *D : Defs)
432*9880d681SAndroid Build Coastguard Worker if (D != Dest && MDT->dominates(D, Dest))
433*9880d681SAndroid Build Coastguard Worker return true;
434*9880d681SAndroid Build Coastguard Worker
435*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *Entry = &Dest->getParent()->front();
436*9880d681SAndroid Build Coastguard Worker SetVector<MachineBasicBlock*> Work(Dest->pred_begin(), Dest->pred_end());
437*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i < Work.size(); ++i) {
438*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *B = Work[i];
439*9880d681SAndroid Build Coastguard Worker if (Defs.count(B))
440*9880d681SAndroid Build Coastguard Worker continue;
441*9880d681SAndroid Build Coastguard Worker if (B == Entry)
442*9880d681SAndroid Build Coastguard Worker return false;
443*9880d681SAndroid Build Coastguard Worker for (auto *P : B->predecessors())
444*9880d681SAndroid Build Coastguard Worker Work.insert(P);
445*9880d681SAndroid Build Coastguard Worker }
446*9880d681SAndroid Build Coastguard Worker return true;
447*9880d681SAndroid Build Coastguard Worker };
448*9880d681SAndroid Build Coastguard Worker
449*9880d681SAndroid Build Coastguard Worker // First, try to extend live range within individual basic blocks. This
450*9880d681SAndroid Build Coastguard Worker // will leave us only with dead defs that do not reach any predicated
451*9880d681SAndroid Build Coastguard Worker // defs in the same block.
452*9880d681SAndroid Build Coastguard Worker SmallVector<SlotIndex,4> PredDefs;
453*9880d681SAndroid Build Coastguard Worker for (auto &Seg : Range) {
454*9880d681SAndroid Build Coastguard Worker if (!Seg.start.isRegister())
455*9880d681SAndroid Build Coastguard Worker continue;
456*9880d681SAndroid Build Coastguard Worker MachineInstr *DefI = LIS->getInstructionFromIndex(Seg.start);
457*9880d681SAndroid Build Coastguard Worker if (LocalImpDefs.count(DefI))
458*9880d681SAndroid Build Coastguard Worker continue;
459*9880d681SAndroid Build Coastguard Worker Defs.insert(DefI->getParent());
460*9880d681SAndroid Build Coastguard Worker if (HII->isPredicated(*DefI))
461*9880d681SAndroid Build Coastguard Worker PredDefs.push_back(Seg.start);
462*9880d681SAndroid Build Coastguard Worker }
463*9880d681SAndroid Build Coastguard Worker for (auto &SI : PredDefs) {
464*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *BB = LIS->getMBBFromIndex(SI);
465*9880d681SAndroid Build Coastguard Worker if (Range.extendInBlock(LIS->getMBBStartIdx(BB), SI))
466*9880d681SAndroid Build Coastguard Worker SI = SlotIndex();
467*9880d681SAndroid Build Coastguard Worker }
468*9880d681SAndroid Build Coastguard Worker
469*9880d681SAndroid Build Coastguard Worker // Calculate reachability for those predicated defs that were not handled
470*9880d681SAndroid Build Coastguard Worker // by the in-block extension.
471*9880d681SAndroid Build Coastguard Worker SmallVector<SlotIndex,4> ExtTo;
472*9880d681SAndroid Build Coastguard Worker for (auto &SI : PredDefs) {
473*9880d681SAndroid Build Coastguard Worker if (!SI.isValid())
474*9880d681SAndroid Build Coastguard Worker continue;
475*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *BB = LIS->getMBBFromIndex(SI);
476*9880d681SAndroid Build Coastguard Worker if (BB->pred_empty())
477*9880d681SAndroid Build Coastguard Worker continue;
478*9880d681SAndroid Build Coastguard Worker // If the defs from this range reach SI via all predecessors, it is live.
479*9880d681SAndroid Build Coastguard Worker if (Dominate(Defs, BB))
480*9880d681SAndroid Build Coastguard Worker ExtTo.push_back(SI);
481*9880d681SAndroid Build Coastguard Worker }
482*9880d681SAndroid Build Coastguard Worker LIS->extendToIndices(Range, ExtTo);
483*9880d681SAndroid Build Coastguard Worker
484*9880d681SAndroid Build Coastguard Worker // Remove <dead> flags from all defs that are not dead after live range
485*9880d681SAndroid Build Coastguard Worker // extension, and collect all def operands. They will be used to generate
486*9880d681SAndroid Build Coastguard Worker // the necessary implicit uses.
487*9880d681SAndroid Build Coastguard Worker std::set<RegisterRef> DefRegs;
488*9880d681SAndroid Build Coastguard Worker for (auto &Seg : Range) {
489*9880d681SAndroid Build Coastguard Worker if (!Seg.start.isRegister())
490*9880d681SAndroid Build Coastguard Worker continue;
491*9880d681SAndroid Build Coastguard Worker MachineInstr *DefI = LIS->getInstructionFromIndex(Seg.start);
492*9880d681SAndroid Build Coastguard Worker if (LocalImpDefs.count(DefI))
493*9880d681SAndroid Build Coastguard Worker continue;
494*9880d681SAndroid Build Coastguard Worker for (auto &Op : DefI->operands()) {
495*9880d681SAndroid Build Coastguard Worker if (Seg.start.isDead() || !IsRegDef(Op))
496*9880d681SAndroid Build Coastguard Worker continue;
497*9880d681SAndroid Build Coastguard Worker DefRegs.insert(Op);
498*9880d681SAndroid Build Coastguard Worker Op.setIsDead(false);
499*9880d681SAndroid Build Coastguard Worker }
500*9880d681SAndroid Build Coastguard Worker }
501*9880d681SAndroid Build Coastguard Worker
502*9880d681SAndroid Build Coastguard Worker
503*9880d681SAndroid Build Coastguard Worker // Finally, add implicit uses to each predicated def that is reached
504*9880d681SAndroid Build Coastguard Worker // by other defs. Remove segments started by implicit-defs first, since
505*9880d681SAndroid Build Coastguard Worker // they do not define registers.
506*9880d681SAndroid Build Coastguard Worker removeImpDefSegments(Range);
507*9880d681SAndroid Build Coastguard Worker
508*9880d681SAndroid Build Coastguard Worker for (auto &Seg : Range) {
509*9880d681SAndroid Build Coastguard Worker if (!Seg.start.isRegister() || !Range.liveAt(Seg.start.getPrevSlot()))
510*9880d681SAndroid Build Coastguard Worker continue;
511*9880d681SAndroid Build Coastguard Worker MachineInstr *DefI = LIS->getInstructionFromIndex(Seg.start);
512*9880d681SAndroid Build Coastguard Worker if (!HII->isPredicated(*DefI))
513*9880d681SAndroid Build Coastguard Worker continue;
514*9880d681SAndroid Build Coastguard Worker MachineFunction &MF = *DefI->getParent()->getParent();
515*9880d681SAndroid Build Coastguard Worker // Construct the set of all necessary implicit uses, based on the def
516*9880d681SAndroid Build Coastguard Worker // operands in the instruction.
517*9880d681SAndroid Build Coastguard Worker std::set<RegisterRef> ImpUses;
518*9880d681SAndroid Build Coastguard Worker for (auto &Op : DefI->operands())
519*9880d681SAndroid Build Coastguard Worker if (Op.isReg() && Op.isDef() && DefRegs.count(Op))
520*9880d681SAndroid Build Coastguard Worker ImpUses.insert(Op);
521*9880d681SAndroid Build Coastguard Worker for (RegisterRef R : ImpUses)
522*9880d681SAndroid Build Coastguard Worker MachineInstrBuilder(MF, DefI).addReg(R.Reg, RegState::Implicit, R.Sub);
523*9880d681SAndroid Build Coastguard Worker }
524*9880d681SAndroid Build Coastguard Worker }
525*9880d681SAndroid Build Coastguard Worker
526*9880d681SAndroid Build Coastguard Worker
updateDeadFlags(unsigned Reg)527*9880d681SAndroid Build Coastguard Worker void HexagonExpandCondsets::updateDeadFlags(unsigned Reg) {
528*9880d681SAndroid Build Coastguard Worker LiveInterval &LI = LIS->getInterval(Reg);
529*9880d681SAndroid Build Coastguard Worker if (LI.hasSubRanges()) {
530*9880d681SAndroid Build Coastguard Worker for (LiveInterval::SubRange &S : LI.subranges()) {
531*9880d681SAndroid Build Coastguard Worker updateDeadsInRange(Reg, S.LaneMask, S);
532*9880d681SAndroid Build Coastguard Worker LIS->shrinkToUses(S, Reg);
533*9880d681SAndroid Build Coastguard Worker // LI::shrinkToUses will add segments started by implicit-defs.
534*9880d681SAndroid Build Coastguard Worker // Remove them again.
535*9880d681SAndroid Build Coastguard Worker removeImpDefSegments(S);
536*9880d681SAndroid Build Coastguard Worker }
537*9880d681SAndroid Build Coastguard Worker LI.clear();
538*9880d681SAndroid Build Coastguard Worker LIS->constructMainRangeFromSubranges(LI);
539*9880d681SAndroid Build Coastguard Worker } else {
540*9880d681SAndroid Build Coastguard Worker updateDeadsInRange(Reg, MRI->getMaxLaneMaskForVReg(Reg), LI);
541*9880d681SAndroid Build Coastguard Worker }
542*9880d681SAndroid Build Coastguard Worker }
543*9880d681SAndroid Build Coastguard Worker
544*9880d681SAndroid Build Coastguard Worker
recalculateLiveInterval(unsigned Reg)545*9880d681SAndroid Build Coastguard Worker void HexagonExpandCondsets::recalculateLiveInterval(unsigned Reg) {
546*9880d681SAndroid Build Coastguard Worker LIS->removeInterval(Reg);
547*9880d681SAndroid Build Coastguard Worker LIS->createAndComputeVirtRegInterval(Reg);
548*9880d681SAndroid Build Coastguard Worker }
549*9880d681SAndroid Build Coastguard Worker
removeInstr(MachineInstr & MI)550*9880d681SAndroid Build Coastguard Worker void HexagonExpandCondsets::removeInstr(MachineInstr &MI) {
551*9880d681SAndroid Build Coastguard Worker LIS->RemoveMachineInstrFromMaps(MI);
552*9880d681SAndroid Build Coastguard Worker MI.eraseFromParent();
553*9880d681SAndroid Build Coastguard Worker }
554*9880d681SAndroid Build Coastguard Worker
555*9880d681SAndroid Build Coastguard Worker
updateLiveness(std::set<unsigned> & RegSet,bool Recalc,bool UpdateKills,bool UpdateDeads)556*9880d681SAndroid Build Coastguard Worker void HexagonExpandCondsets::updateLiveness(std::set<unsigned> &RegSet,
557*9880d681SAndroid Build Coastguard Worker bool Recalc, bool UpdateKills, bool UpdateDeads) {
558*9880d681SAndroid Build Coastguard Worker UpdateKills |= UpdateDeads;
559*9880d681SAndroid Build Coastguard Worker for (auto R : RegSet) {
560*9880d681SAndroid Build Coastguard Worker if (Recalc)
561*9880d681SAndroid Build Coastguard Worker recalculateLiveInterval(R);
562*9880d681SAndroid Build Coastguard Worker if (UpdateKills)
563*9880d681SAndroid Build Coastguard Worker MRI->clearKillFlags(R);
564*9880d681SAndroid Build Coastguard Worker if (UpdateDeads)
565*9880d681SAndroid Build Coastguard Worker updateDeadFlags(R);
566*9880d681SAndroid Build Coastguard Worker // Fixing <dead> flags may extend live ranges, so reset <kill> flags
567*9880d681SAndroid Build Coastguard Worker // after that.
568*9880d681SAndroid Build Coastguard Worker if (UpdateKills)
569*9880d681SAndroid Build Coastguard Worker updateKillFlags(R);
570*9880d681SAndroid Build Coastguard Worker LIS->getInterval(R).verify();
571*9880d681SAndroid Build Coastguard Worker }
572*9880d681SAndroid Build Coastguard Worker }
573*9880d681SAndroid Build Coastguard Worker
574*9880d681SAndroid Build Coastguard Worker
575*9880d681SAndroid Build Coastguard Worker /// Get the opcode for a conditional transfer of the value in SO (source
576*9880d681SAndroid Build Coastguard Worker /// operand). The condition (true/false) is given in Cond.
getCondTfrOpcode(const MachineOperand & SO,bool IfTrue)577*9880d681SAndroid Build Coastguard Worker unsigned HexagonExpandCondsets::getCondTfrOpcode(const MachineOperand &SO,
578*9880d681SAndroid Build Coastguard Worker bool IfTrue) {
579*9880d681SAndroid Build Coastguard Worker using namespace Hexagon;
580*9880d681SAndroid Build Coastguard Worker if (SO.isReg()) {
581*9880d681SAndroid Build Coastguard Worker unsigned PhysR;
582*9880d681SAndroid Build Coastguard Worker RegisterRef RS = SO;
583*9880d681SAndroid Build Coastguard Worker if (TargetRegisterInfo::isVirtualRegister(RS.Reg)) {
584*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *VC = MRI->getRegClass(RS.Reg);
585*9880d681SAndroid Build Coastguard Worker assert(VC->begin() != VC->end() && "Empty register class");
586*9880d681SAndroid Build Coastguard Worker PhysR = *VC->begin();
587*9880d681SAndroid Build Coastguard Worker } else {
588*9880d681SAndroid Build Coastguard Worker assert(TargetRegisterInfo::isPhysicalRegister(RS.Reg));
589*9880d681SAndroid Build Coastguard Worker PhysR = RS.Reg;
590*9880d681SAndroid Build Coastguard Worker }
591*9880d681SAndroid Build Coastguard Worker unsigned PhysS = (RS.Sub == 0) ? PhysR : TRI->getSubReg(PhysR, RS.Sub);
592*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(PhysS);
593*9880d681SAndroid Build Coastguard Worker switch (RC->getSize()) {
594*9880d681SAndroid Build Coastguard Worker case 4:
595*9880d681SAndroid Build Coastguard Worker return IfTrue ? A2_tfrt : A2_tfrf;
596*9880d681SAndroid Build Coastguard Worker case 8:
597*9880d681SAndroid Build Coastguard Worker return IfTrue ? A2_tfrpt : A2_tfrpf;
598*9880d681SAndroid Build Coastguard Worker }
599*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Invalid register operand");
600*9880d681SAndroid Build Coastguard Worker }
601*9880d681SAndroid Build Coastguard Worker if (SO.isImm() || SO.isFPImm())
602*9880d681SAndroid Build Coastguard Worker return IfTrue ? C2_cmoveit : C2_cmoveif;
603*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Unexpected source operand");
604*9880d681SAndroid Build Coastguard Worker }
605*9880d681SAndroid Build Coastguard Worker
606*9880d681SAndroid Build Coastguard Worker
607*9880d681SAndroid Build Coastguard Worker /// Generate a conditional transfer, copying the value SrcOp to the
608*9880d681SAndroid Build Coastguard Worker /// destination register DstR:DstSR, and using the predicate register from
609*9880d681SAndroid Build Coastguard Worker /// PredOp. The Cond argument specifies whether the predicate is to be
610*9880d681SAndroid Build Coastguard Worker /// if(PredOp), or if(!PredOp).
genCondTfrFor(MachineOperand & SrcOp,MachineBasicBlock::iterator At,unsigned DstR,unsigned DstSR,const MachineOperand & PredOp,bool PredSense,bool ReadUndef,bool ImpUse)611*9880d681SAndroid Build Coastguard Worker MachineInstr *HexagonExpandCondsets::genCondTfrFor(MachineOperand &SrcOp,
612*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator At,
613*9880d681SAndroid Build Coastguard Worker unsigned DstR, unsigned DstSR, const MachineOperand &PredOp,
614*9880d681SAndroid Build Coastguard Worker bool PredSense, bool ReadUndef, bool ImpUse) {
615*9880d681SAndroid Build Coastguard Worker MachineInstr *MI = SrcOp.getParent();
616*9880d681SAndroid Build Coastguard Worker MachineBasicBlock &B = *At->getParent();
617*9880d681SAndroid Build Coastguard Worker const DebugLoc &DL = MI->getDebugLoc();
618*9880d681SAndroid Build Coastguard Worker
619*9880d681SAndroid Build Coastguard Worker // Don't avoid identity copies here (i.e. if the source and the destination
620*9880d681SAndroid Build Coastguard Worker // are the same registers). It is actually better to generate them here,
621*9880d681SAndroid Build Coastguard Worker // since this would cause the copy to potentially be predicated in the next
622*9880d681SAndroid Build Coastguard Worker // step. The predication will remove such a copy if it is unable to
623*9880d681SAndroid Build Coastguard Worker /// predicate.
624*9880d681SAndroid Build Coastguard Worker
625*9880d681SAndroid Build Coastguard Worker unsigned Opc = getCondTfrOpcode(SrcOp, PredSense);
626*9880d681SAndroid Build Coastguard Worker unsigned State = RegState::Define | (ReadUndef ? RegState::Undef : 0);
627*9880d681SAndroid Build Coastguard Worker MachineInstrBuilder MIB = BuildMI(B, At, DL, HII->get(Opc))
628*9880d681SAndroid Build Coastguard Worker .addReg(DstR, State, DstSR)
629*9880d681SAndroid Build Coastguard Worker .addOperand(PredOp)
630*9880d681SAndroid Build Coastguard Worker .addOperand(SrcOp);
631*9880d681SAndroid Build Coastguard Worker
632*9880d681SAndroid Build Coastguard Worker // We don't want any kills yet.
633*9880d681SAndroid Build Coastguard Worker MIB->clearKillInfo();
634*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "created an initial copy: " << *MIB);
635*9880d681SAndroid Build Coastguard Worker return &*MIB;
636*9880d681SAndroid Build Coastguard Worker }
637*9880d681SAndroid Build Coastguard Worker
638*9880d681SAndroid Build Coastguard Worker
639*9880d681SAndroid Build Coastguard Worker /// Replace a MUX instruction MI with a pair A2_tfrt/A2_tfrf. This function
640*9880d681SAndroid Build Coastguard Worker /// performs all necessary changes to complete the replacement.
split(MachineInstr & MI,std::set<unsigned> & UpdRegs)641*9880d681SAndroid Build Coastguard Worker bool HexagonExpandCondsets::split(MachineInstr &MI,
642*9880d681SAndroid Build Coastguard Worker std::set<unsigned> &UpdRegs) {
643*9880d681SAndroid Build Coastguard Worker if (TfrLimitActive) {
644*9880d681SAndroid Build Coastguard Worker if (TfrCounter >= TfrLimit)
645*9880d681SAndroid Build Coastguard Worker return false;
646*9880d681SAndroid Build Coastguard Worker TfrCounter++;
647*9880d681SAndroid Build Coastguard Worker }
648*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "\nsplitting BB#" << MI.getParent()->getNumber() << ": "
649*9880d681SAndroid Build Coastguard Worker << MI);
650*9880d681SAndroid Build Coastguard Worker MachineOperand &MD = MI.getOperand(0); // Definition
651*9880d681SAndroid Build Coastguard Worker MachineOperand &MP = MI.getOperand(1); // Predicate register
652*9880d681SAndroid Build Coastguard Worker MachineOperand &MS1 = MI.getOperand(2); // Source value #1
653*9880d681SAndroid Build Coastguard Worker MachineOperand &MS2 = MI.getOperand(3); // Source value #2
654*9880d681SAndroid Build Coastguard Worker assert(MD.isDef());
655*9880d681SAndroid Build Coastguard Worker unsigned DR = MD.getReg(), DSR = MD.getSubReg();
656*9880d681SAndroid Build Coastguard Worker bool ReadUndef = MD.isUndef();
657*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator At = MI;
658*9880d681SAndroid Build Coastguard Worker
659*9880d681SAndroid Build Coastguard Worker if (ReadUndef && DSR != 0 && MRI->shouldTrackSubRegLiveness(DR)) {
660*9880d681SAndroid Build Coastguard Worker unsigned NewSR = 0;
661*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator DefAt = At;
662*9880d681SAndroid Build Coastguard Worker bool SameReg = (MS1.isReg() && DR == MS1.getReg()) ||
663*9880d681SAndroid Build Coastguard Worker (MS2.isReg() && DR == MS2.getReg());
664*9880d681SAndroid Build Coastguard Worker if (SameReg) {
665*9880d681SAndroid Build Coastguard Worker NewSR = (DSR == Hexagon::subreg_loreg) ? Hexagon::subreg_hireg
666*9880d681SAndroid Build Coastguard Worker : Hexagon::subreg_loreg;
667*9880d681SAndroid Build Coastguard Worker // Advance the insertion point if the subregisters differ between
668*9880d681SAndroid Build Coastguard Worker // the source and the target (with the same super-register).
669*9880d681SAndroid Build Coastguard Worker // Note: this case has never occured during tests.
670*9880d681SAndroid Build Coastguard Worker if ((MS1.isReg() && NewSR == MS1.getSubReg()) ||
671*9880d681SAndroid Build Coastguard Worker (MS2.isReg() && NewSR == MS2.getSubReg()))
672*9880d681SAndroid Build Coastguard Worker ++DefAt;
673*9880d681SAndroid Build Coastguard Worker }
674*9880d681SAndroid Build Coastguard Worker // Use "At", since "DefAt" may be end().
675*9880d681SAndroid Build Coastguard Worker MachineBasicBlock &B = *At->getParent();
676*9880d681SAndroid Build Coastguard Worker DebugLoc DL = At->getDebugLoc();
677*9880d681SAndroid Build Coastguard Worker auto ImpD = BuildMI(B, DefAt, DL, HII->get(TargetOpcode::IMPLICIT_DEF))
678*9880d681SAndroid Build Coastguard Worker .addReg(DR, RegState::Define, NewSR);
679*9880d681SAndroid Build Coastguard Worker LIS->InsertMachineInstrInMaps(*ImpD);
680*9880d681SAndroid Build Coastguard Worker LocalImpDefs.insert(&*ImpD);
681*9880d681SAndroid Build Coastguard Worker }
682*9880d681SAndroid Build Coastguard Worker
683*9880d681SAndroid Build Coastguard Worker // First, create the two invididual conditional transfers, and add each
684*9880d681SAndroid Build Coastguard Worker // of them to the live intervals information. Do that first and then remove
685*9880d681SAndroid Build Coastguard Worker // the old instruction from live intervals.
686*9880d681SAndroid Build Coastguard Worker MachineInstr *TfrT =
687*9880d681SAndroid Build Coastguard Worker genCondTfrFor(MI.getOperand(2), At, DR, DSR, MP, true, ReadUndef, false);
688*9880d681SAndroid Build Coastguard Worker MachineInstr *TfrF =
689*9880d681SAndroid Build Coastguard Worker genCondTfrFor(MI.getOperand(3), At, DR, DSR, MP, false, ReadUndef, true);
690*9880d681SAndroid Build Coastguard Worker LIS->InsertMachineInstrInMaps(*TfrT);
691*9880d681SAndroid Build Coastguard Worker LIS->InsertMachineInstrInMaps(*TfrF);
692*9880d681SAndroid Build Coastguard Worker
693*9880d681SAndroid Build Coastguard Worker // Will need to recalculate live intervals for all registers in MI.
694*9880d681SAndroid Build Coastguard Worker for (auto &Op : MI.operands())
695*9880d681SAndroid Build Coastguard Worker if (Op.isReg())
696*9880d681SAndroid Build Coastguard Worker UpdRegs.insert(Op.getReg());
697*9880d681SAndroid Build Coastguard Worker
698*9880d681SAndroid Build Coastguard Worker removeInstr(MI);
699*9880d681SAndroid Build Coastguard Worker return true;
700*9880d681SAndroid Build Coastguard Worker }
701*9880d681SAndroid Build Coastguard Worker
702*9880d681SAndroid Build Coastguard Worker
703*9880d681SAndroid Build Coastguard Worker /// Split all MUX instructions in the given block into pairs of conditional
704*9880d681SAndroid Build Coastguard Worker /// transfers.
splitInBlock(MachineBasicBlock & B,std::set<unsigned> & UpdRegs)705*9880d681SAndroid Build Coastguard Worker bool HexagonExpandCondsets::splitInBlock(MachineBasicBlock &B,
706*9880d681SAndroid Build Coastguard Worker std::set<unsigned> &UpdRegs) {
707*9880d681SAndroid Build Coastguard Worker bool Changed = false;
708*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator I, E, NextI;
709*9880d681SAndroid Build Coastguard Worker for (I = B.begin(), E = B.end(); I != E; I = NextI) {
710*9880d681SAndroid Build Coastguard Worker NextI = std::next(I);
711*9880d681SAndroid Build Coastguard Worker if (isCondset(*I))
712*9880d681SAndroid Build Coastguard Worker Changed |= split(*I, UpdRegs);
713*9880d681SAndroid Build Coastguard Worker }
714*9880d681SAndroid Build Coastguard Worker return Changed;
715*9880d681SAndroid Build Coastguard Worker }
716*9880d681SAndroid Build Coastguard Worker
717*9880d681SAndroid Build Coastguard Worker
isPredicable(MachineInstr * MI)718*9880d681SAndroid Build Coastguard Worker bool HexagonExpandCondsets::isPredicable(MachineInstr *MI) {
719*9880d681SAndroid Build Coastguard Worker if (HII->isPredicated(*MI) || !HII->isPredicable(*MI))
720*9880d681SAndroid Build Coastguard Worker return false;
721*9880d681SAndroid Build Coastguard Worker if (MI->hasUnmodeledSideEffects() || MI->mayStore())
722*9880d681SAndroid Build Coastguard Worker return false;
723*9880d681SAndroid Build Coastguard Worker // Reject instructions with multiple defs (e.g. post-increment loads).
724*9880d681SAndroid Build Coastguard Worker bool HasDef = false;
725*9880d681SAndroid Build Coastguard Worker for (auto &Op : MI->operands()) {
726*9880d681SAndroid Build Coastguard Worker if (!Op.isReg() || !Op.isDef())
727*9880d681SAndroid Build Coastguard Worker continue;
728*9880d681SAndroid Build Coastguard Worker if (HasDef)
729*9880d681SAndroid Build Coastguard Worker return false;
730*9880d681SAndroid Build Coastguard Worker HasDef = true;
731*9880d681SAndroid Build Coastguard Worker }
732*9880d681SAndroid Build Coastguard Worker for (auto &Mo : MI->memoperands())
733*9880d681SAndroid Build Coastguard Worker if (Mo->isVolatile())
734*9880d681SAndroid Build Coastguard Worker return false;
735*9880d681SAndroid Build Coastguard Worker return true;
736*9880d681SAndroid Build Coastguard Worker }
737*9880d681SAndroid Build Coastguard Worker
738*9880d681SAndroid Build Coastguard Worker
739*9880d681SAndroid Build Coastguard Worker /// Find the reaching definition for a predicated use of RD. The RD is used
740*9880d681SAndroid Build Coastguard Worker /// under the conditions given by PredR and Cond, and this function will ignore
741*9880d681SAndroid Build Coastguard Worker /// definitions that set RD under the opposite conditions.
getReachingDefForPred(RegisterRef RD,MachineBasicBlock::iterator UseIt,unsigned PredR,bool Cond)742*9880d681SAndroid Build Coastguard Worker MachineInstr *HexagonExpandCondsets::getReachingDefForPred(RegisterRef RD,
743*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator UseIt, unsigned PredR, bool Cond) {
744*9880d681SAndroid Build Coastguard Worker MachineBasicBlock &B = *UseIt->getParent();
745*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator I = UseIt, S = B.begin();
746*9880d681SAndroid Build Coastguard Worker if (I == S)
747*9880d681SAndroid Build Coastguard Worker return 0;
748*9880d681SAndroid Build Coastguard Worker
749*9880d681SAndroid Build Coastguard Worker bool PredValid = true;
750*9880d681SAndroid Build Coastguard Worker do {
751*9880d681SAndroid Build Coastguard Worker --I;
752*9880d681SAndroid Build Coastguard Worker MachineInstr *MI = &*I;
753*9880d681SAndroid Build Coastguard Worker // Check if this instruction can be ignored, i.e. if it is predicated
754*9880d681SAndroid Build Coastguard Worker // on the complementary condition.
755*9880d681SAndroid Build Coastguard Worker if (PredValid && HII->isPredicated(*MI)) {
756*9880d681SAndroid Build Coastguard Worker if (MI->readsRegister(PredR) && (Cond != HII->isPredicatedTrue(*MI)))
757*9880d681SAndroid Build Coastguard Worker continue;
758*9880d681SAndroid Build Coastguard Worker }
759*9880d681SAndroid Build Coastguard Worker
760*9880d681SAndroid Build Coastguard Worker // Check the defs. If the PredR is defined, invalidate it. If RD is
761*9880d681SAndroid Build Coastguard Worker // defined, return the instruction or 0, depending on the circumstances.
762*9880d681SAndroid Build Coastguard Worker for (auto &Op : MI->operands()) {
763*9880d681SAndroid Build Coastguard Worker if (!Op.isReg() || !Op.isDef())
764*9880d681SAndroid Build Coastguard Worker continue;
765*9880d681SAndroid Build Coastguard Worker RegisterRef RR = Op;
766*9880d681SAndroid Build Coastguard Worker if (RR.Reg == PredR) {
767*9880d681SAndroid Build Coastguard Worker PredValid = false;
768*9880d681SAndroid Build Coastguard Worker continue;
769*9880d681SAndroid Build Coastguard Worker }
770*9880d681SAndroid Build Coastguard Worker if (RR.Reg != RD.Reg)
771*9880d681SAndroid Build Coastguard Worker continue;
772*9880d681SAndroid Build Coastguard Worker // If the "Reg" part agrees, there is still the subregister to check.
773*9880d681SAndroid Build Coastguard Worker // If we are looking for vreg1:loreg, we can skip vreg1:hireg, but
774*9880d681SAndroid Build Coastguard Worker // not vreg1 (w/o subregisters).
775*9880d681SAndroid Build Coastguard Worker if (RR.Sub == RD.Sub)
776*9880d681SAndroid Build Coastguard Worker return MI;
777*9880d681SAndroid Build Coastguard Worker if (RR.Sub == 0 || RD.Sub == 0)
778*9880d681SAndroid Build Coastguard Worker return 0;
779*9880d681SAndroid Build Coastguard Worker // We have different subregisters, so we can continue looking.
780*9880d681SAndroid Build Coastguard Worker }
781*9880d681SAndroid Build Coastguard Worker } while (I != S);
782*9880d681SAndroid Build Coastguard Worker
783*9880d681SAndroid Build Coastguard Worker return 0;
784*9880d681SAndroid Build Coastguard Worker }
785*9880d681SAndroid Build Coastguard Worker
786*9880d681SAndroid Build Coastguard Worker
787*9880d681SAndroid Build Coastguard Worker /// Check if the instruction MI can be safely moved over a set of instructions
788*9880d681SAndroid Build Coastguard Worker /// whose side-effects (in terms of register defs and uses) are expressed in
789*9880d681SAndroid Build Coastguard Worker /// the maps Defs and Uses. These maps reflect the conditional defs and uses
790*9880d681SAndroid Build Coastguard Worker /// that depend on the same predicate register to allow moving instructions
791*9880d681SAndroid Build Coastguard Worker /// over instructions predicated on the opposite condition.
canMoveOver(MachineInstr & MI,ReferenceMap & Defs,ReferenceMap & Uses)792*9880d681SAndroid Build Coastguard Worker bool HexagonExpandCondsets::canMoveOver(MachineInstr &MI, ReferenceMap &Defs,
793*9880d681SAndroid Build Coastguard Worker ReferenceMap &Uses) {
794*9880d681SAndroid Build Coastguard Worker // In order to be able to safely move MI over instructions that define
795*9880d681SAndroid Build Coastguard Worker // "Defs" and use "Uses", no def operand from MI can be defined or used
796*9880d681SAndroid Build Coastguard Worker // and no use operand can be defined.
797*9880d681SAndroid Build Coastguard Worker for (auto &Op : MI.operands()) {
798*9880d681SAndroid Build Coastguard Worker if (!Op.isReg())
799*9880d681SAndroid Build Coastguard Worker continue;
800*9880d681SAndroid Build Coastguard Worker RegisterRef RR = Op;
801*9880d681SAndroid Build Coastguard Worker // For physical register we would need to check register aliases, etc.
802*9880d681SAndroid Build Coastguard Worker // and we don't want to bother with that. It would be of little value
803*9880d681SAndroid Build Coastguard Worker // before the actual register rewriting (from virtual to physical).
804*9880d681SAndroid Build Coastguard Worker if (!TargetRegisterInfo::isVirtualRegister(RR.Reg))
805*9880d681SAndroid Build Coastguard Worker return false;
806*9880d681SAndroid Build Coastguard Worker // No redefs for any operand.
807*9880d681SAndroid Build Coastguard Worker if (isRefInMap(RR, Defs, Exec_Then))
808*9880d681SAndroid Build Coastguard Worker return false;
809*9880d681SAndroid Build Coastguard Worker // For defs, there cannot be uses.
810*9880d681SAndroid Build Coastguard Worker if (Op.isDef() && isRefInMap(RR, Uses, Exec_Then))
811*9880d681SAndroid Build Coastguard Worker return false;
812*9880d681SAndroid Build Coastguard Worker }
813*9880d681SAndroid Build Coastguard Worker return true;
814*9880d681SAndroid Build Coastguard Worker }
815*9880d681SAndroid Build Coastguard Worker
816*9880d681SAndroid Build Coastguard Worker
817*9880d681SAndroid Build Coastguard Worker /// Check if the instruction accessing memory (TheI) can be moved to the
818*9880d681SAndroid Build Coastguard Worker /// location ToI.
canMoveMemTo(MachineInstr & TheI,MachineInstr & ToI,bool IsDown)819*9880d681SAndroid Build Coastguard Worker bool HexagonExpandCondsets::canMoveMemTo(MachineInstr &TheI, MachineInstr &ToI,
820*9880d681SAndroid Build Coastguard Worker bool IsDown) {
821*9880d681SAndroid Build Coastguard Worker bool IsLoad = TheI.mayLoad(), IsStore = TheI.mayStore();
822*9880d681SAndroid Build Coastguard Worker if (!IsLoad && !IsStore)
823*9880d681SAndroid Build Coastguard Worker return true;
824*9880d681SAndroid Build Coastguard Worker if (HII->areMemAccessesTriviallyDisjoint(TheI, ToI))
825*9880d681SAndroid Build Coastguard Worker return true;
826*9880d681SAndroid Build Coastguard Worker if (TheI.hasUnmodeledSideEffects())
827*9880d681SAndroid Build Coastguard Worker return false;
828*9880d681SAndroid Build Coastguard Worker
829*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator StartI = IsDown ? TheI : ToI;
830*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator EndI = IsDown ? ToI : TheI;
831*9880d681SAndroid Build Coastguard Worker bool Ordered = TheI.hasOrderedMemoryRef();
832*9880d681SAndroid Build Coastguard Worker
833*9880d681SAndroid Build Coastguard Worker // Search for aliased memory reference in (StartI, EndI).
834*9880d681SAndroid Build Coastguard Worker for (MachineBasicBlock::iterator I = std::next(StartI); I != EndI; ++I) {
835*9880d681SAndroid Build Coastguard Worker MachineInstr *MI = &*I;
836*9880d681SAndroid Build Coastguard Worker if (MI->hasUnmodeledSideEffects())
837*9880d681SAndroid Build Coastguard Worker return false;
838*9880d681SAndroid Build Coastguard Worker bool L = MI->mayLoad(), S = MI->mayStore();
839*9880d681SAndroid Build Coastguard Worker if (!L && !S)
840*9880d681SAndroid Build Coastguard Worker continue;
841*9880d681SAndroid Build Coastguard Worker if (Ordered && MI->hasOrderedMemoryRef())
842*9880d681SAndroid Build Coastguard Worker return false;
843*9880d681SAndroid Build Coastguard Worker
844*9880d681SAndroid Build Coastguard Worker bool Conflict = (L && IsStore) || S;
845*9880d681SAndroid Build Coastguard Worker if (Conflict)
846*9880d681SAndroid Build Coastguard Worker return false;
847*9880d681SAndroid Build Coastguard Worker }
848*9880d681SAndroid Build Coastguard Worker return true;
849*9880d681SAndroid Build Coastguard Worker }
850*9880d681SAndroid Build Coastguard Worker
851*9880d681SAndroid Build Coastguard Worker
852*9880d681SAndroid Build Coastguard Worker /// Generate a predicated version of MI (where the condition is given via
853*9880d681SAndroid Build Coastguard Worker /// PredR and Cond) at the point indicated by Where.
predicateAt(const MachineOperand & DefOp,MachineInstr & MI,MachineBasicBlock::iterator Where,const MachineOperand & PredOp,bool Cond,std::set<unsigned> & UpdRegs)854*9880d681SAndroid Build Coastguard Worker void HexagonExpandCondsets::predicateAt(const MachineOperand &DefOp,
855*9880d681SAndroid Build Coastguard Worker MachineInstr &MI,
856*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator Where,
857*9880d681SAndroid Build Coastguard Worker const MachineOperand &PredOp, bool Cond,
858*9880d681SAndroid Build Coastguard Worker std::set<unsigned> &UpdRegs) {
859*9880d681SAndroid Build Coastguard Worker // The problem with updating live intervals is that we can move one def
860*9880d681SAndroid Build Coastguard Worker // past another def. In particular, this can happen when moving an A2_tfrt
861*9880d681SAndroid Build Coastguard Worker // over an A2_tfrf defining the same register. From the point of view of
862*9880d681SAndroid Build Coastguard Worker // live intervals, these two instructions are two separate definitions,
863*9880d681SAndroid Build Coastguard Worker // and each one starts another live segment. LiveIntervals's "handleMove"
864*9880d681SAndroid Build Coastguard Worker // does not allow such moves, so we need to handle it ourselves. To avoid
865*9880d681SAndroid Build Coastguard Worker // invalidating liveness data while we are using it, the move will be
866*9880d681SAndroid Build Coastguard Worker // implemented in 4 steps: (1) add a clone of the instruction MI at the
867*9880d681SAndroid Build Coastguard Worker // target location, (2) update liveness, (3) delete the old instruction,
868*9880d681SAndroid Build Coastguard Worker // and (4) update liveness again.
869*9880d681SAndroid Build Coastguard Worker
870*9880d681SAndroid Build Coastguard Worker MachineBasicBlock &B = *MI.getParent();
871*9880d681SAndroid Build Coastguard Worker DebugLoc DL = Where->getDebugLoc(); // "Where" points to an instruction.
872*9880d681SAndroid Build Coastguard Worker unsigned Opc = MI.getOpcode();
873*9880d681SAndroid Build Coastguard Worker unsigned PredOpc = HII->getCondOpcode(Opc, !Cond);
874*9880d681SAndroid Build Coastguard Worker MachineInstrBuilder MB = BuildMI(B, Where, DL, HII->get(PredOpc));
875*9880d681SAndroid Build Coastguard Worker unsigned Ox = 0, NP = MI.getNumOperands();
876*9880d681SAndroid Build Coastguard Worker // Skip all defs from MI first.
877*9880d681SAndroid Build Coastguard Worker while (Ox < NP) {
878*9880d681SAndroid Build Coastguard Worker MachineOperand &MO = MI.getOperand(Ox);
879*9880d681SAndroid Build Coastguard Worker if (!MO.isReg() || !MO.isDef())
880*9880d681SAndroid Build Coastguard Worker break;
881*9880d681SAndroid Build Coastguard Worker Ox++;
882*9880d681SAndroid Build Coastguard Worker }
883*9880d681SAndroid Build Coastguard Worker // Add the new def, then the predicate register, then the rest of the
884*9880d681SAndroid Build Coastguard Worker // operands.
885*9880d681SAndroid Build Coastguard Worker MB.addReg(DefOp.getReg(), getRegState(DefOp), DefOp.getSubReg());
886*9880d681SAndroid Build Coastguard Worker MB.addReg(PredOp.getReg(), PredOp.isUndef() ? RegState::Undef : 0,
887*9880d681SAndroid Build Coastguard Worker PredOp.getSubReg());
888*9880d681SAndroid Build Coastguard Worker while (Ox < NP) {
889*9880d681SAndroid Build Coastguard Worker MachineOperand &MO = MI.getOperand(Ox);
890*9880d681SAndroid Build Coastguard Worker if (!MO.isReg() || !MO.isImplicit())
891*9880d681SAndroid Build Coastguard Worker MB.addOperand(MO);
892*9880d681SAndroid Build Coastguard Worker Ox++;
893*9880d681SAndroid Build Coastguard Worker }
894*9880d681SAndroid Build Coastguard Worker
895*9880d681SAndroid Build Coastguard Worker MachineFunction &MF = *B.getParent();
896*9880d681SAndroid Build Coastguard Worker MachineInstr::mmo_iterator I = MI.memoperands_begin();
897*9880d681SAndroid Build Coastguard Worker unsigned NR = std::distance(I, MI.memoperands_end());
898*9880d681SAndroid Build Coastguard Worker MachineInstr::mmo_iterator MemRefs = MF.allocateMemRefsArray(NR);
899*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i < NR; ++i)
900*9880d681SAndroid Build Coastguard Worker MemRefs[i] = *I++;
901*9880d681SAndroid Build Coastguard Worker MB.setMemRefs(MemRefs, MemRefs+NR);
902*9880d681SAndroid Build Coastguard Worker
903*9880d681SAndroid Build Coastguard Worker MachineInstr *NewI = MB;
904*9880d681SAndroid Build Coastguard Worker NewI->clearKillInfo();
905*9880d681SAndroid Build Coastguard Worker LIS->InsertMachineInstrInMaps(*NewI);
906*9880d681SAndroid Build Coastguard Worker
907*9880d681SAndroid Build Coastguard Worker for (auto &Op : NewI->operands())
908*9880d681SAndroid Build Coastguard Worker if (Op.isReg())
909*9880d681SAndroid Build Coastguard Worker UpdRegs.insert(Op.getReg());
910*9880d681SAndroid Build Coastguard Worker }
911*9880d681SAndroid Build Coastguard Worker
912*9880d681SAndroid Build Coastguard Worker
913*9880d681SAndroid Build Coastguard Worker /// In the range [First, Last], rename all references to the "old" register RO
914*9880d681SAndroid Build Coastguard Worker /// to the "new" register RN, but only in instructions predicated on the given
915*9880d681SAndroid Build Coastguard Worker /// condition.
renameInRange(RegisterRef RO,RegisterRef RN,unsigned PredR,bool Cond,MachineBasicBlock::iterator First,MachineBasicBlock::iterator Last)916*9880d681SAndroid Build Coastguard Worker void HexagonExpandCondsets::renameInRange(RegisterRef RO, RegisterRef RN,
917*9880d681SAndroid Build Coastguard Worker unsigned PredR, bool Cond, MachineBasicBlock::iterator First,
918*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator Last) {
919*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator End = std::next(Last);
920*9880d681SAndroid Build Coastguard Worker for (MachineBasicBlock::iterator I = First; I != End; ++I) {
921*9880d681SAndroid Build Coastguard Worker MachineInstr *MI = &*I;
922*9880d681SAndroid Build Coastguard Worker // Do not touch instructions that are not predicated, or are predicated
923*9880d681SAndroid Build Coastguard Worker // on the opposite condition.
924*9880d681SAndroid Build Coastguard Worker if (!HII->isPredicated(*MI))
925*9880d681SAndroid Build Coastguard Worker continue;
926*9880d681SAndroid Build Coastguard Worker if (!MI->readsRegister(PredR) || (Cond != HII->isPredicatedTrue(*MI)))
927*9880d681SAndroid Build Coastguard Worker continue;
928*9880d681SAndroid Build Coastguard Worker
929*9880d681SAndroid Build Coastguard Worker for (auto &Op : MI->operands()) {
930*9880d681SAndroid Build Coastguard Worker if (!Op.isReg() || RO != RegisterRef(Op))
931*9880d681SAndroid Build Coastguard Worker continue;
932*9880d681SAndroid Build Coastguard Worker Op.setReg(RN.Reg);
933*9880d681SAndroid Build Coastguard Worker Op.setSubReg(RN.Sub);
934*9880d681SAndroid Build Coastguard Worker // In practice, this isn't supposed to see any defs.
935*9880d681SAndroid Build Coastguard Worker assert(!Op.isDef() && "Not expecting a def");
936*9880d681SAndroid Build Coastguard Worker }
937*9880d681SAndroid Build Coastguard Worker }
938*9880d681SAndroid Build Coastguard Worker }
939*9880d681SAndroid Build Coastguard Worker
940*9880d681SAndroid Build Coastguard Worker
941*9880d681SAndroid Build Coastguard Worker /// For a given conditional copy, predicate the definition of the source of
942*9880d681SAndroid Build Coastguard Worker /// the copy under the given condition (using the same predicate register as
943*9880d681SAndroid Build Coastguard Worker /// the copy).
predicate(MachineInstr & TfrI,bool Cond,std::set<unsigned> & UpdRegs)944*9880d681SAndroid Build Coastguard Worker bool HexagonExpandCondsets::predicate(MachineInstr &TfrI, bool Cond,
945*9880d681SAndroid Build Coastguard Worker std::set<unsigned> &UpdRegs) {
946*9880d681SAndroid Build Coastguard Worker // TfrI - A2_tfr[tf] Instruction (not A2_tfrsi).
947*9880d681SAndroid Build Coastguard Worker unsigned Opc = TfrI.getOpcode();
948*9880d681SAndroid Build Coastguard Worker (void)Opc;
949*9880d681SAndroid Build Coastguard Worker assert(Opc == Hexagon::A2_tfrt || Opc == Hexagon::A2_tfrf);
950*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "\nattempt to predicate if-" << (Cond ? "true" : "false")
951*9880d681SAndroid Build Coastguard Worker << ": " << TfrI);
952*9880d681SAndroid Build Coastguard Worker
953*9880d681SAndroid Build Coastguard Worker MachineOperand &MD = TfrI.getOperand(0);
954*9880d681SAndroid Build Coastguard Worker MachineOperand &MP = TfrI.getOperand(1);
955*9880d681SAndroid Build Coastguard Worker MachineOperand &MS = TfrI.getOperand(2);
956*9880d681SAndroid Build Coastguard Worker // The source operand should be a <kill>. This is not strictly necessary,
957*9880d681SAndroid Build Coastguard Worker // but it makes things a lot simpler. Otherwise, we would need to rename
958*9880d681SAndroid Build Coastguard Worker // some registers, which would complicate the transformation considerably.
959*9880d681SAndroid Build Coastguard Worker if (!MS.isKill())
960*9880d681SAndroid Build Coastguard Worker return false;
961*9880d681SAndroid Build Coastguard Worker // Avoid predicating instructions that define a subregister if subregister
962*9880d681SAndroid Build Coastguard Worker // liveness tracking is not enabled.
963*9880d681SAndroid Build Coastguard Worker if (MD.getSubReg() && !MRI->shouldTrackSubRegLiveness(MD.getReg()))
964*9880d681SAndroid Build Coastguard Worker return false;
965*9880d681SAndroid Build Coastguard Worker
966*9880d681SAndroid Build Coastguard Worker RegisterRef RT(MS);
967*9880d681SAndroid Build Coastguard Worker unsigned PredR = MP.getReg();
968*9880d681SAndroid Build Coastguard Worker MachineInstr *DefI = getReachingDefForPred(RT, TfrI, PredR, Cond);
969*9880d681SAndroid Build Coastguard Worker if (!DefI || !isPredicable(DefI))
970*9880d681SAndroid Build Coastguard Worker return false;
971*9880d681SAndroid Build Coastguard Worker
972*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "Source def: " << *DefI);
973*9880d681SAndroid Build Coastguard Worker
974*9880d681SAndroid Build Coastguard Worker // Collect the information about registers defined and used between the
975*9880d681SAndroid Build Coastguard Worker // DefI and the TfrI.
976*9880d681SAndroid Build Coastguard Worker // Map: reg -> bitmask of subregs
977*9880d681SAndroid Build Coastguard Worker ReferenceMap Uses, Defs;
978*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator DefIt = DefI, TfrIt = TfrI;
979*9880d681SAndroid Build Coastguard Worker
980*9880d681SAndroid Build Coastguard Worker // Check if the predicate register is valid between DefI and TfrI.
981*9880d681SAndroid Build Coastguard Worker // If it is, we can then ignore instructions predicated on the negated
982*9880d681SAndroid Build Coastguard Worker // conditions when collecting def and use information.
983*9880d681SAndroid Build Coastguard Worker bool PredValid = true;
984*9880d681SAndroid Build Coastguard Worker for (MachineBasicBlock::iterator I = std::next(DefIt); I != TfrIt; ++I) {
985*9880d681SAndroid Build Coastguard Worker if (!I->modifiesRegister(PredR, 0))
986*9880d681SAndroid Build Coastguard Worker continue;
987*9880d681SAndroid Build Coastguard Worker PredValid = false;
988*9880d681SAndroid Build Coastguard Worker break;
989*9880d681SAndroid Build Coastguard Worker }
990*9880d681SAndroid Build Coastguard Worker
991*9880d681SAndroid Build Coastguard Worker for (MachineBasicBlock::iterator I = std::next(DefIt); I != TfrIt; ++I) {
992*9880d681SAndroid Build Coastguard Worker MachineInstr *MI = &*I;
993*9880d681SAndroid Build Coastguard Worker // If this instruction is predicated on the same register, it could
994*9880d681SAndroid Build Coastguard Worker // potentially be ignored.
995*9880d681SAndroid Build Coastguard Worker // By default assume that the instruction executes on the same condition
996*9880d681SAndroid Build Coastguard Worker // as TfrI (Exec_Then), and also on the opposite one (Exec_Else).
997*9880d681SAndroid Build Coastguard Worker unsigned Exec = Exec_Then | Exec_Else;
998*9880d681SAndroid Build Coastguard Worker if (PredValid && HII->isPredicated(*MI) && MI->readsRegister(PredR))
999*9880d681SAndroid Build Coastguard Worker Exec = (Cond == HII->isPredicatedTrue(*MI)) ? Exec_Then : Exec_Else;
1000*9880d681SAndroid Build Coastguard Worker
1001*9880d681SAndroid Build Coastguard Worker for (auto &Op : MI->operands()) {
1002*9880d681SAndroid Build Coastguard Worker if (!Op.isReg())
1003*9880d681SAndroid Build Coastguard Worker continue;
1004*9880d681SAndroid Build Coastguard Worker // We don't want to deal with physical registers. The reason is that
1005*9880d681SAndroid Build Coastguard Worker // they can be aliased with other physical registers. Aliased virtual
1006*9880d681SAndroid Build Coastguard Worker // registers must share the same register number, and can only differ
1007*9880d681SAndroid Build Coastguard Worker // in the subregisters, which we are keeping track of. Physical
1008*9880d681SAndroid Build Coastguard Worker // registers ters no longer have subregisters---their super- and
1009*9880d681SAndroid Build Coastguard Worker // subregisters are other physical registers, and we are not checking
1010*9880d681SAndroid Build Coastguard Worker // that.
1011*9880d681SAndroid Build Coastguard Worker RegisterRef RR = Op;
1012*9880d681SAndroid Build Coastguard Worker if (!TargetRegisterInfo::isVirtualRegister(RR.Reg))
1013*9880d681SAndroid Build Coastguard Worker return false;
1014*9880d681SAndroid Build Coastguard Worker
1015*9880d681SAndroid Build Coastguard Worker ReferenceMap &Map = Op.isDef() ? Defs : Uses;
1016*9880d681SAndroid Build Coastguard Worker addRefToMap(RR, Map, Exec);
1017*9880d681SAndroid Build Coastguard Worker }
1018*9880d681SAndroid Build Coastguard Worker }
1019*9880d681SAndroid Build Coastguard Worker
1020*9880d681SAndroid Build Coastguard Worker // The situation:
1021*9880d681SAndroid Build Coastguard Worker // RT = DefI
1022*9880d681SAndroid Build Coastguard Worker // ...
1023*9880d681SAndroid Build Coastguard Worker // RD = TfrI ..., RT
1024*9880d681SAndroid Build Coastguard Worker
1025*9880d681SAndroid Build Coastguard Worker // If the register-in-the-middle (RT) is used or redefined between
1026*9880d681SAndroid Build Coastguard Worker // DefI and TfrI, we may not be able proceed with this transformation.
1027*9880d681SAndroid Build Coastguard Worker // We can ignore a def that will not execute together with TfrI, and a
1028*9880d681SAndroid Build Coastguard Worker // use that will. If there is such a use (that does execute together with
1029*9880d681SAndroid Build Coastguard Worker // TfrI), we will not be able to move DefI down. If there is a use that
1030*9880d681SAndroid Build Coastguard Worker // executed if TfrI's condition is false, then RT must be available
1031*9880d681SAndroid Build Coastguard Worker // unconditionally (cannot be predicated).
1032*9880d681SAndroid Build Coastguard Worker // Essentially, we need to be able to rename RT to RD in this segment.
1033*9880d681SAndroid Build Coastguard Worker if (isRefInMap(RT, Defs, Exec_Then) || isRefInMap(RT, Uses, Exec_Else))
1034*9880d681SAndroid Build Coastguard Worker return false;
1035*9880d681SAndroid Build Coastguard Worker RegisterRef RD = MD;
1036*9880d681SAndroid Build Coastguard Worker // If the predicate register is defined between DefI and TfrI, the only
1037*9880d681SAndroid Build Coastguard Worker // potential thing to do would be to move the DefI down to TfrI, and then
1038*9880d681SAndroid Build Coastguard Worker // predicate. The reaching def (DefI) must be movable down to the location
1039*9880d681SAndroid Build Coastguard Worker // of the TfrI.
1040*9880d681SAndroid Build Coastguard Worker // If the target register of the TfrI (RD) is not used or defined between
1041*9880d681SAndroid Build Coastguard Worker // DefI and TfrI, consider moving TfrI up to DefI.
1042*9880d681SAndroid Build Coastguard Worker bool CanUp = canMoveOver(TfrI, Defs, Uses);
1043*9880d681SAndroid Build Coastguard Worker bool CanDown = canMoveOver(*DefI, Defs, Uses);
1044*9880d681SAndroid Build Coastguard Worker // The TfrI does not access memory, but DefI could. Check if it's safe
1045*9880d681SAndroid Build Coastguard Worker // to move DefI down to TfrI.
1046*9880d681SAndroid Build Coastguard Worker if (DefI->mayLoad() || DefI->mayStore())
1047*9880d681SAndroid Build Coastguard Worker if (!canMoveMemTo(*DefI, TfrI, true))
1048*9880d681SAndroid Build Coastguard Worker CanDown = false;
1049*9880d681SAndroid Build Coastguard Worker
1050*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "Can move up: " << (CanUp ? "yes" : "no")
1051*9880d681SAndroid Build Coastguard Worker << ", can move down: " << (CanDown ? "yes\n" : "no\n"));
1052*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator PastDefIt = std::next(DefIt);
1053*9880d681SAndroid Build Coastguard Worker if (CanUp)
1054*9880d681SAndroid Build Coastguard Worker predicateAt(MD, *DefI, PastDefIt, MP, Cond, UpdRegs);
1055*9880d681SAndroid Build Coastguard Worker else if (CanDown)
1056*9880d681SAndroid Build Coastguard Worker predicateAt(MD, *DefI, TfrIt, MP, Cond, UpdRegs);
1057*9880d681SAndroid Build Coastguard Worker else
1058*9880d681SAndroid Build Coastguard Worker return false;
1059*9880d681SAndroid Build Coastguard Worker
1060*9880d681SAndroid Build Coastguard Worker if (RT != RD) {
1061*9880d681SAndroid Build Coastguard Worker renameInRange(RT, RD, PredR, Cond, PastDefIt, TfrIt);
1062*9880d681SAndroid Build Coastguard Worker UpdRegs.insert(RT.Reg);
1063*9880d681SAndroid Build Coastguard Worker }
1064*9880d681SAndroid Build Coastguard Worker
1065*9880d681SAndroid Build Coastguard Worker removeInstr(TfrI);
1066*9880d681SAndroid Build Coastguard Worker removeInstr(*DefI);
1067*9880d681SAndroid Build Coastguard Worker return true;
1068*9880d681SAndroid Build Coastguard Worker }
1069*9880d681SAndroid Build Coastguard Worker
1070*9880d681SAndroid Build Coastguard Worker
1071*9880d681SAndroid Build Coastguard Worker /// Predicate all cases of conditional copies in the specified block.
predicateInBlock(MachineBasicBlock & B,std::set<unsigned> & UpdRegs)1072*9880d681SAndroid Build Coastguard Worker bool HexagonExpandCondsets::predicateInBlock(MachineBasicBlock &B,
1073*9880d681SAndroid Build Coastguard Worker std::set<unsigned> &UpdRegs) {
1074*9880d681SAndroid Build Coastguard Worker bool Changed = false;
1075*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator I, E, NextI;
1076*9880d681SAndroid Build Coastguard Worker for (I = B.begin(), E = B.end(); I != E; I = NextI) {
1077*9880d681SAndroid Build Coastguard Worker NextI = std::next(I);
1078*9880d681SAndroid Build Coastguard Worker unsigned Opc = I->getOpcode();
1079*9880d681SAndroid Build Coastguard Worker if (Opc == Hexagon::A2_tfrt || Opc == Hexagon::A2_tfrf) {
1080*9880d681SAndroid Build Coastguard Worker bool Done = predicate(*I, (Opc == Hexagon::A2_tfrt), UpdRegs);
1081*9880d681SAndroid Build Coastguard Worker if (!Done) {
1082*9880d681SAndroid Build Coastguard Worker // If we didn't predicate I, we may need to remove it in case it is
1083*9880d681SAndroid Build Coastguard Worker // an "identity" copy, e.g. vreg1 = A2_tfrt vreg2, vreg1.
1084*9880d681SAndroid Build Coastguard Worker if (RegisterRef(I->getOperand(0)) == RegisterRef(I->getOperand(2))) {
1085*9880d681SAndroid Build Coastguard Worker for (auto &Op : I->operands())
1086*9880d681SAndroid Build Coastguard Worker if (Op.isReg())
1087*9880d681SAndroid Build Coastguard Worker UpdRegs.insert(Op.getReg());
1088*9880d681SAndroid Build Coastguard Worker removeInstr(*I);
1089*9880d681SAndroid Build Coastguard Worker }
1090*9880d681SAndroid Build Coastguard Worker }
1091*9880d681SAndroid Build Coastguard Worker Changed |= Done;
1092*9880d681SAndroid Build Coastguard Worker }
1093*9880d681SAndroid Build Coastguard Worker }
1094*9880d681SAndroid Build Coastguard Worker return Changed;
1095*9880d681SAndroid Build Coastguard Worker }
1096*9880d681SAndroid Build Coastguard Worker
1097*9880d681SAndroid Build Coastguard Worker
isIntReg(RegisterRef RR,unsigned & BW)1098*9880d681SAndroid Build Coastguard Worker bool HexagonExpandCondsets::isIntReg(RegisterRef RR, unsigned &BW) {
1099*9880d681SAndroid Build Coastguard Worker if (!TargetRegisterInfo::isVirtualRegister(RR.Reg))
1100*9880d681SAndroid Build Coastguard Worker return false;
1101*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC = MRI->getRegClass(RR.Reg);
1102*9880d681SAndroid Build Coastguard Worker if (RC == &Hexagon::IntRegsRegClass) {
1103*9880d681SAndroid Build Coastguard Worker BW = 32;
1104*9880d681SAndroid Build Coastguard Worker return true;
1105*9880d681SAndroid Build Coastguard Worker }
1106*9880d681SAndroid Build Coastguard Worker if (RC == &Hexagon::DoubleRegsRegClass) {
1107*9880d681SAndroid Build Coastguard Worker BW = (RR.Sub != 0) ? 32 : 64;
1108*9880d681SAndroid Build Coastguard Worker return true;
1109*9880d681SAndroid Build Coastguard Worker }
1110*9880d681SAndroid Build Coastguard Worker return false;
1111*9880d681SAndroid Build Coastguard Worker }
1112*9880d681SAndroid Build Coastguard Worker
1113*9880d681SAndroid Build Coastguard Worker
isIntraBlocks(LiveInterval & LI)1114*9880d681SAndroid Build Coastguard Worker bool HexagonExpandCondsets::isIntraBlocks(LiveInterval &LI) {
1115*9880d681SAndroid Build Coastguard Worker for (LiveInterval::iterator I = LI.begin(), E = LI.end(); I != E; ++I) {
1116*9880d681SAndroid Build Coastguard Worker LiveRange::Segment &LR = *I;
1117*9880d681SAndroid Build Coastguard Worker // Range must start at a register...
1118*9880d681SAndroid Build Coastguard Worker if (!LR.start.isRegister())
1119*9880d681SAndroid Build Coastguard Worker return false;
1120*9880d681SAndroid Build Coastguard Worker // ...and end in a register or in a dead slot.
1121*9880d681SAndroid Build Coastguard Worker if (!LR.end.isRegister() && !LR.end.isDead())
1122*9880d681SAndroid Build Coastguard Worker return false;
1123*9880d681SAndroid Build Coastguard Worker }
1124*9880d681SAndroid Build Coastguard Worker return true;
1125*9880d681SAndroid Build Coastguard Worker }
1126*9880d681SAndroid Build Coastguard Worker
1127*9880d681SAndroid Build Coastguard Worker
coalesceRegisters(RegisterRef R1,RegisterRef R2)1128*9880d681SAndroid Build Coastguard Worker bool HexagonExpandCondsets::coalesceRegisters(RegisterRef R1, RegisterRef R2) {
1129*9880d681SAndroid Build Coastguard Worker if (CoaLimitActive) {
1130*9880d681SAndroid Build Coastguard Worker if (CoaCounter >= CoaLimit)
1131*9880d681SAndroid Build Coastguard Worker return false;
1132*9880d681SAndroid Build Coastguard Worker CoaCounter++;
1133*9880d681SAndroid Build Coastguard Worker }
1134*9880d681SAndroid Build Coastguard Worker unsigned BW1, BW2;
1135*9880d681SAndroid Build Coastguard Worker if (!isIntReg(R1, BW1) || !isIntReg(R2, BW2) || BW1 != BW2)
1136*9880d681SAndroid Build Coastguard Worker return false;
1137*9880d681SAndroid Build Coastguard Worker if (MRI->isLiveIn(R1.Reg))
1138*9880d681SAndroid Build Coastguard Worker return false;
1139*9880d681SAndroid Build Coastguard Worker if (MRI->isLiveIn(R2.Reg))
1140*9880d681SAndroid Build Coastguard Worker return false;
1141*9880d681SAndroid Build Coastguard Worker
1142*9880d681SAndroid Build Coastguard Worker LiveInterval &L1 = LIS->getInterval(R1.Reg);
1143*9880d681SAndroid Build Coastguard Worker LiveInterval &L2 = LIS->getInterval(R2.Reg);
1144*9880d681SAndroid Build Coastguard Worker bool Overlap = L1.overlaps(L2);
1145*9880d681SAndroid Build Coastguard Worker
1146*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "compatible registers: ("
1147*9880d681SAndroid Build Coastguard Worker << (Overlap ? "overlap" : "disjoint") << ")\n "
1148*9880d681SAndroid Build Coastguard Worker << PrintReg(R1.Reg, TRI, R1.Sub) << " " << L1 << "\n "
1149*9880d681SAndroid Build Coastguard Worker << PrintReg(R2.Reg, TRI, R2.Sub) << " " << L2 << "\n");
1150*9880d681SAndroid Build Coastguard Worker if (R1.Sub || R2.Sub)
1151*9880d681SAndroid Build Coastguard Worker return false;
1152*9880d681SAndroid Build Coastguard Worker if (Overlap)
1153*9880d681SAndroid Build Coastguard Worker return false;
1154*9880d681SAndroid Build Coastguard Worker
1155*9880d681SAndroid Build Coastguard Worker // Coalescing could have a negative impact on scheduling, so try to limit
1156*9880d681SAndroid Build Coastguard Worker // to some reasonable extent. Only consider coalescing segments, when one
1157*9880d681SAndroid Build Coastguard Worker // of them does not cross basic block boundaries.
1158*9880d681SAndroid Build Coastguard Worker if (!isIntraBlocks(L1) && !isIntraBlocks(L2))
1159*9880d681SAndroid Build Coastguard Worker return false;
1160*9880d681SAndroid Build Coastguard Worker
1161*9880d681SAndroid Build Coastguard Worker MRI->replaceRegWith(R2.Reg, R1.Reg);
1162*9880d681SAndroid Build Coastguard Worker
1163*9880d681SAndroid Build Coastguard Worker // Move all live segments from L2 to L1.
1164*9880d681SAndroid Build Coastguard Worker typedef DenseMap<VNInfo*,VNInfo*> ValueInfoMap;
1165*9880d681SAndroid Build Coastguard Worker ValueInfoMap VM;
1166*9880d681SAndroid Build Coastguard Worker for (LiveInterval::iterator I = L2.begin(), E = L2.end(); I != E; ++I) {
1167*9880d681SAndroid Build Coastguard Worker VNInfo *NewVN, *OldVN = I->valno;
1168*9880d681SAndroid Build Coastguard Worker ValueInfoMap::iterator F = VM.find(OldVN);
1169*9880d681SAndroid Build Coastguard Worker if (F == VM.end()) {
1170*9880d681SAndroid Build Coastguard Worker NewVN = L1.getNextValue(I->valno->def, LIS->getVNInfoAllocator());
1171*9880d681SAndroid Build Coastguard Worker VM.insert(std::make_pair(OldVN, NewVN));
1172*9880d681SAndroid Build Coastguard Worker } else {
1173*9880d681SAndroid Build Coastguard Worker NewVN = F->second;
1174*9880d681SAndroid Build Coastguard Worker }
1175*9880d681SAndroid Build Coastguard Worker L1.addSegment(LiveRange::Segment(I->start, I->end, NewVN));
1176*9880d681SAndroid Build Coastguard Worker }
1177*9880d681SAndroid Build Coastguard Worker while (L2.begin() != L2.end())
1178*9880d681SAndroid Build Coastguard Worker L2.removeSegment(*L2.begin());
1179*9880d681SAndroid Build Coastguard Worker
1180*9880d681SAndroid Build Coastguard Worker updateKillFlags(R1.Reg);
1181*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "coalesced: " << L1 << "\n");
1182*9880d681SAndroid Build Coastguard Worker L1.verify();
1183*9880d681SAndroid Build Coastguard Worker
1184*9880d681SAndroid Build Coastguard Worker return true;
1185*9880d681SAndroid Build Coastguard Worker }
1186*9880d681SAndroid Build Coastguard Worker
1187*9880d681SAndroid Build Coastguard Worker
1188*9880d681SAndroid Build Coastguard Worker /// Attempt to coalesce one of the source registers to a MUX intruction with
1189*9880d681SAndroid Build Coastguard Worker /// the destination register. This could lead to having only one predicated
1190*9880d681SAndroid Build Coastguard Worker /// instruction in the end instead of two.
coalesceSegments(MachineFunction & MF)1191*9880d681SAndroid Build Coastguard Worker bool HexagonExpandCondsets::coalesceSegments(MachineFunction &MF) {
1192*9880d681SAndroid Build Coastguard Worker SmallVector<MachineInstr*,16> Condsets;
1193*9880d681SAndroid Build Coastguard Worker for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) {
1194*9880d681SAndroid Build Coastguard Worker MachineBasicBlock &B = *I;
1195*9880d681SAndroid Build Coastguard Worker for (MachineBasicBlock::iterator J = B.begin(), F = B.end(); J != F; ++J) {
1196*9880d681SAndroid Build Coastguard Worker MachineInstr *MI = &*J;
1197*9880d681SAndroid Build Coastguard Worker if (!isCondset(*MI))
1198*9880d681SAndroid Build Coastguard Worker continue;
1199*9880d681SAndroid Build Coastguard Worker MachineOperand &S1 = MI->getOperand(2), &S2 = MI->getOperand(3);
1200*9880d681SAndroid Build Coastguard Worker if (!S1.isReg() && !S2.isReg())
1201*9880d681SAndroid Build Coastguard Worker continue;
1202*9880d681SAndroid Build Coastguard Worker Condsets.push_back(MI);
1203*9880d681SAndroid Build Coastguard Worker }
1204*9880d681SAndroid Build Coastguard Worker }
1205*9880d681SAndroid Build Coastguard Worker
1206*9880d681SAndroid Build Coastguard Worker bool Changed = false;
1207*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, n = Condsets.size(); i < n; ++i) {
1208*9880d681SAndroid Build Coastguard Worker MachineInstr *CI = Condsets[i];
1209*9880d681SAndroid Build Coastguard Worker RegisterRef RD = CI->getOperand(0);
1210*9880d681SAndroid Build Coastguard Worker RegisterRef RP = CI->getOperand(1);
1211*9880d681SAndroid Build Coastguard Worker MachineOperand &S1 = CI->getOperand(2), &S2 = CI->getOperand(3);
1212*9880d681SAndroid Build Coastguard Worker bool Done = false;
1213*9880d681SAndroid Build Coastguard Worker // Consider this case:
1214*9880d681SAndroid Build Coastguard Worker // vreg1 = instr1 ...
1215*9880d681SAndroid Build Coastguard Worker // vreg2 = instr2 ...
1216*9880d681SAndroid Build Coastguard Worker // vreg0 = C2_mux ..., vreg1, vreg2
1217*9880d681SAndroid Build Coastguard Worker // If vreg0 was coalesced with vreg1, we could end up with the following
1218*9880d681SAndroid Build Coastguard Worker // code:
1219*9880d681SAndroid Build Coastguard Worker // vreg0 = instr1 ...
1220*9880d681SAndroid Build Coastguard Worker // vreg2 = instr2 ...
1221*9880d681SAndroid Build Coastguard Worker // vreg0 = A2_tfrf ..., vreg2
1222*9880d681SAndroid Build Coastguard Worker // which will later become:
1223*9880d681SAndroid Build Coastguard Worker // vreg0 = instr1 ...
1224*9880d681SAndroid Build Coastguard Worker // vreg0 = instr2_cNotPt ...
1225*9880d681SAndroid Build Coastguard Worker // i.e. there will be an unconditional definition (instr1) of vreg0
1226*9880d681SAndroid Build Coastguard Worker // followed by a conditional one. The output dependency was there before
1227*9880d681SAndroid Build Coastguard Worker // and it unavoidable, but if instr1 is predicable, we will no longer be
1228*9880d681SAndroid Build Coastguard Worker // able to predicate it here.
1229*9880d681SAndroid Build Coastguard Worker // To avoid this scenario, don't coalesce the destination register with
1230*9880d681SAndroid Build Coastguard Worker // a source register that is defined by a predicable instruction.
1231*9880d681SAndroid Build Coastguard Worker if (S1.isReg()) {
1232*9880d681SAndroid Build Coastguard Worker RegisterRef RS = S1;
1233*9880d681SAndroid Build Coastguard Worker MachineInstr *RDef = getReachingDefForPred(RS, CI, RP.Reg, true);
1234*9880d681SAndroid Build Coastguard Worker if (!RDef || !HII->isPredicable(*RDef))
1235*9880d681SAndroid Build Coastguard Worker Done = coalesceRegisters(RD, RegisterRef(S1));
1236*9880d681SAndroid Build Coastguard Worker }
1237*9880d681SAndroid Build Coastguard Worker if (!Done && S2.isReg()) {
1238*9880d681SAndroid Build Coastguard Worker RegisterRef RS = S2;
1239*9880d681SAndroid Build Coastguard Worker MachineInstr *RDef = getReachingDefForPred(RS, CI, RP.Reg, false);
1240*9880d681SAndroid Build Coastguard Worker if (!RDef || !HII->isPredicable(*RDef))
1241*9880d681SAndroid Build Coastguard Worker Done = coalesceRegisters(RD, RegisterRef(S2));
1242*9880d681SAndroid Build Coastguard Worker }
1243*9880d681SAndroid Build Coastguard Worker Changed |= Done;
1244*9880d681SAndroid Build Coastguard Worker }
1245*9880d681SAndroid Build Coastguard Worker return Changed;
1246*9880d681SAndroid Build Coastguard Worker }
1247*9880d681SAndroid Build Coastguard Worker
1248*9880d681SAndroid Build Coastguard Worker
runOnMachineFunction(MachineFunction & MF)1249*9880d681SAndroid Build Coastguard Worker bool HexagonExpandCondsets::runOnMachineFunction(MachineFunction &MF) {
1250*9880d681SAndroid Build Coastguard Worker if (skipFunction(*MF.getFunction()))
1251*9880d681SAndroid Build Coastguard Worker return false;
1252*9880d681SAndroid Build Coastguard Worker
1253*9880d681SAndroid Build Coastguard Worker HII = static_cast<const HexagonInstrInfo*>(MF.getSubtarget().getInstrInfo());
1254*9880d681SAndroid Build Coastguard Worker TRI = MF.getSubtarget().getRegisterInfo();
1255*9880d681SAndroid Build Coastguard Worker MDT = &getAnalysis<MachineDominatorTree>();
1256*9880d681SAndroid Build Coastguard Worker LIS = &getAnalysis<LiveIntervals>();
1257*9880d681SAndroid Build Coastguard Worker MRI = &MF.getRegInfo();
1258*9880d681SAndroid Build Coastguard Worker LocalImpDefs.clear();
1259*9880d681SAndroid Build Coastguard Worker
1260*9880d681SAndroid Build Coastguard Worker DEBUG(LIS->print(dbgs() << "Before expand-condsets\n",
1261*9880d681SAndroid Build Coastguard Worker MF.getFunction()->getParent()));
1262*9880d681SAndroid Build Coastguard Worker
1263*9880d681SAndroid Build Coastguard Worker bool Changed = false;
1264*9880d681SAndroid Build Coastguard Worker std::set<unsigned> SplitUpd, PredUpd;
1265*9880d681SAndroid Build Coastguard Worker
1266*9880d681SAndroid Build Coastguard Worker // Try to coalesce the target of a mux with one of its sources.
1267*9880d681SAndroid Build Coastguard Worker // This could eliminate a register copy in some circumstances.
1268*9880d681SAndroid Build Coastguard Worker Changed |= coalesceSegments(MF);
1269*9880d681SAndroid Build Coastguard Worker
1270*9880d681SAndroid Build Coastguard Worker // First, simply split all muxes into a pair of conditional transfers
1271*9880d681SAndroid Build Coastguard Worker // and update the live intervals to reflect the new arrangement. The
1272*9880d681SAndroid Build Coastguard Worker // goal is to update the kill flags, since predication will rely on
1273*9880d681SAndroid Build Coastguard Worker // them.
1274*9880d681SAndroid Build Coastguard Worker for (auto &B : MF)
1275*9880d681SAndroid Build Coastguard Worker Changed |= splitInBlock(B, SplitUpd);
1276*9880d681SAndroid Build Coastguard Worker updateLiveness(SplitUpd, true, true, false);
1277*9880d681SAndroid Build Coastguard Worker
1278*9880d681SAndroid Build Coastguard Worker // Traverse all blocks and collapse predicable instructions feeding
1279*9880d681SAndroid Build Coastguard Worker // conditional transfers into predicated instructions.
1280*9880d681SAndroid Build Coastguard Worker // Walk over all the instructions again, so we may catch pre-existing
1281*9880d681SAndroid Build Coastguard Worker // cases that were not created in the previous step.
1282*9880d681SAndroid Build Coastguard Worker for (auto &B : MF)
1283*9880d681SAndroid Build Coastguard Worker Changed |= predicateInBlock(B, PredUpd);
1284*9880d681SAndroid Build Coastguard Worker
1285*9880d681SAndroid Build Coastguard Worker updateLiveness(PredUpd, true, true, true);
1286*9880d681SAndroid Build Coastguard Worker // Remove from SplitUpd all registers contained in PredUpd to avoid
1287*9880d681SAndroid Build Coastguard Worker // unnecessary liveness recalculation.
1288*9880d681SAndroid Build Coastguard Worker std::set<unsigned> Diff;
1289*9880d681SAndroid Build Coastguard Worker std::set_difference(SplitUpd.begin(), SplitUpd.end(),
1290*9880d681SAndroid Build Coastguard Worker PredUpd.begin(), PredUpd.end(),
1291*9880d681SAndroid Build Coastguard Worker std::inserter(Diff, Diff.begin()));
1292*9880d681SAndroid Build Coastguard Worker updateLiveness(Diff, false, false, true);
1293*9880d681SAndroid Build Coastguard Worker
1294*9880d681SAndroid Build Coastguard Worker for (auto *ImpD : LocalImpDefs)
1295*9880d681SAndroid Build Coastguard Worker removeInstr(*ImpD);
1296*9880d681SAndroid Build Coastguard Worker
1297*9880d681SAndroid Build Coastguard Worker DEBUG({
1298*9880d681SAndroid Build Coastguard Worker if (Changed)
1299*9880d681SAndroid Build Coastguard Worker LIS->print(dbgs() << "After expand-condsets\n",
1300*9880d681SAndroid Build Coastguard Worker MF.getFunction()->getParent());
1301*9880d681SAndroid Build Coastguard Worker });
1302*9880d681SAndroid Build Coastguard Worker
1303*9880d681SAndroid Build Coastguard Worker return Changed;
1304*9880d681SAndroid Build Coastguard Worker }
1305*9880d681SAndroid Build Coastguard Worker
1306*9880d681SAndroid Build Coastguard Worker
1307*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
1308*9880d681SAndroid Build Coastguard Worker // Public Constructor Functions
1309*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
1310*9880d681SAndroid Build Coastguard Worker
createHexagonExpandCondsets()1311*9880d681SAndroid Build Coastguard Worker FunctionPass *llvm::createHexagonExpandCondsets() {
1312*9880d681SAndroid Build Coastguard Worker return new HexagonExpandCondsets();
1313*9880d681SAndroid Build Coastguard Worker }
1314