• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //=== HexagonMCCompound.cpp - Hexagon Compound checker  -------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file is looks at a packet and tries to form compound insns
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "Hexagon.h"
15 #include "MCTargetDesc/HexagonBaseInfo.h"
16 #include "MCTargetDesc/HexagonMCInstrInfo.h"
17 #include "MCTargetDesc/HexagonMCShuffler.h"
18 #include "llvm/MC/MCContext.h"
19 #include "llvm/MC/MCInst.h"
20 #include "llvm/Support/Debug.h"
21 #include "llvm/Support/ErrorHandling.h"
22 #include "llvm/Support/raw_ostream.h"
23 #include <cassert>
24 #include <cstdint>
25 
26 using namespace llvm;
27 using namespace Hexagon;
28 
29 #define DEBUG_TYPE "hexagon-mccompound"
30 
31 enum OpcodeIndex {
32   fp0_jump_nt = 0,
33   fp0_jump_t,
34   fp1_jump_nt,
35   fp1_jump_t,
36   tp0_jump_nt,
37   tp0_jump_t,
38   tp1_jump_nt,
39   tp1_jump_t
40 };
41 
42 static const unsigned tstBitOpcode[8] = {
43     J4_tstbit0_fp0_jump_nt, J4_tstbit0_fp0_jump_t,  J4_tstbit0_fp1_jump_nt,
44     J4_tstbit0_fp1_jump_t,  J4_tstbit0_tp0_jump_nt, J4_tstbit0_tp0_jump_t,
45     J4_tstbit0_tp1_jump_nt, J4_tstbit0_tp1_jump_t};
46 static const unsigned cmpeqBitOpcode[8] = {
47     J4_cmpeq_fp0_jump_nt, J4_cmpeq_fp0_jump_t,  J4_cmpeq_fp1_jump_nt,
48     J4_cmpeq_fp1_jump_t,  J4_cmpeq_tp0_jump_nt, J4_cmpeq_tp0_jump_t,
49     J4_cmpeq_tp1_jump_nt, J4_cmpeq_tp1_jump_t};
50 static const unsigned cmpgtBitOpcode[8] = {
51     J4_cmpgt_fp0_jump_nt, J4_cmpgt_fp0_jump_t,  J4_cmpgt_fp1_jump_nt,
52     J4_cmpgt_fp1_jump_t,  J4_cmpgt_tp0_jump_nt, J4_cmpgt_tp0_jump_t,
53     J4_cmpgt_tp1_jump_nt, J4_cmpgt_tp1_jump_t};
54 static const unsigned cmpgtuBitOpcode[8] = {
55     J4_cmpgtu_fp0_jump_nt, J4_cmpgtu_fp0_jump_t,  J4_cmpgtu_fp1_jump_nt,
56     J4_cmpgtu_fp1_jump_t,  J4_cmpgtu_tp0_jump_nt, J4_cmpgtu_tp0_jump_t,
57     J4_cmpgtu_tp1_jump_nt, J4_cmpgtu_tp1_jump_t};
58 static const unsigned cmpeqiBitOpcode[8] = {
59     J4_cmpeqi_fp0_jump_nt, J4_cmpeqi_fp0_jump_t,  J4_cmpeqi_fp1_jump_nt,
60     J4_cmpeqi_fp1_jump_t,  J4_cmpeqi_tp0_jump_nt, J4_cmpeqi_tp0_jump_t,
61     J4_cmpeqi_tp1_jump_nt, J4_cmpeqi_tp1_jump_t};
62 static const unsigned cmpgtiBitOpcode[8] = {
63     J4_cmpgti_fp0_jump_nt, J4_cmpgti_fp0_jump_t,  J4_cmpgti_fp1_jump_nt,
64     J4_cmpgti_fp1_jump_t,  J4_cmpgti_tp0_jump_nt, J4_cmpgti_tp0_jump_t,
65     J4_cmpgti_tp1_jump_nt, J4_cmpgti_tp1_jump_t};
66 static const unsigned cmpgtuiBitOpcode[8] = {
67     J4_cmpgtui_fp0_jump_nt, J4_cmpgtui_fp0_jump_t,  J4_cmpgtui_fp1_jump_nt,
68     J4_cmpgtui_fp1_jump_t,  J4_cmpgtui_tp0_jump_nt, J4_cmpgtui_tp0_jump_t,
69     J4_cmpgtui_tp1_jump_nt, J4_cmpgtui_tp1_jump_t};
70 static const unsigned cmpeqn1BitOpcode[8] = {
71     J4_cmpeqn1_fp0_jump_nt, J4_cmpeqn1_fp0_jump_t,  J4_cmpeqn1_fp1_jump_nt,
72     J4_cmpeqn1_fp1_jump_t,  J4_cmpeqn1_tp0_jump_nt, J4_cmpeqn1_tp0_jump_t,
73     J4_cmpeqn1_tp1_jump_nt, J4_cmpeqn1_tp1_jump_t};
74 static const unsigned cmpgtn1BitOpcode[8] = {
75     J4_cmpgtn1_fp0_jump_nt, J4_cmpgtn1_fp0_jump_t,  J4_cmpgtn1_fp1_jump_nt,
76     J4_cmpgtn1_fp1_jump_t,  J4_cmpgtn1_tp0_jump_nt, J4_cmpgtn1_tp0_jump_t,
77     J4_cmpgtn1_tp1_jump_nt, J4_cmpgtn1_tp1_jump_t,
78 };
79 
80 // enum HexagonII::CompoundGroup
getCompoundCandidateGroup(MCInst const & MI,bool IsExtended)81 static unsigned getCompoundCandidateGroup(MCInst const &MI, bool IsExtended) {
82   unsigned DstReg, SrcReg, Src1Reg, Src2Reg;
83 
84   switch (MI.getOpcode()) {
85   default:
86     return HexagonII::HCG_None;
87   //
88   // Compound pairs.
89   // "p0=cmp.eq(Rs16,Rt16); if (p0.new) jump:nt #r9:2"
90   // "Rd16=#U6 ; jump #r9:2"
91   // "Rd16=Rs16 ; jump #r9:2"
92   //
93   case Hexagon::C2_cmpeq:
94   case Hexagon::C2_cmpgt:
95   case Hexagon::C2_cmpgtu:
96     if (IsExtended)
97       return false;
98     DstReg = MI.getOperand(0).getReg();
99     Src1Reg = MI.getOperand(1).getReg();
100     Src2Reg = MI.getOperand(2).getReg();
101     if ((Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
102         HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
103         HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg))
104       return HexagonII::HCG_A;
105     break;
106   case Hexagon::C2_cmpeqi:
107   case Hexagon::C2_cmpgti:
108   case Hexagon::C2_cmpgtui:
109     if (IsExtended)
110       return false;
111     // P0 = cmp.eq(Rs,#u2)
112     DstReg = MI.getOperand(0).getReg();
113     SrcReg = MI.getOperand(1).getReg();
114     if ((Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
115         HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
116         (HexagonMCInstrInfo::inRange<5>(MI, 2) ||
117          HexagonMCInstrInfo::minConstant(MI, 2) == -1))
118       return HexagonII::HCG_A;
119     break;
120   case Hexagon::A2_tfr:
121     if (IsExtended)
122       return false;
123     // Rd = Rs
124     DstReg = MI.getOperand(0).getReg();
125     SrcReg = MI.getOperand(1).getReg();
126     if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
127         HexagonMCInstrInfo::isIntRegForSubInst(SrcReg))
128       return HexagonII::HCG_A;
129     break;
130   case Hexagon::A2_tfrsi:
131     if (IsExtended)
132       return false;
133     // Rd = #u6
134     DstReg = MI.getOperand(0).getReg();
135     if (HexagonMCInstrInfo::minConstant(MI, 1) <= 63 &&
136         HexagonMCInstrInfo::minConstant(MI, 1) >= 0 &&
137         HexagonMCInstrInfo::isIntRegForSubInst(DstReg))
138       return HexagonII::HCG_A;
139     break;
140   case Hexagon::S2_tstbit_i:
141     if (IsExtended)
142       return false;
143     DstReg = MI.getOperand(0).getReg();
144     Src1Reg = MI.getOperand(1).getReg();
145     if ((Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
146         HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
147         HexagonMCInstrInfo::minConstant(MI, 2) == 0)
148       return HexagonII::HCG_A;
149     break;
150   // The fact that .new form is used pretty much guarantees
151   // that predicate register will match. Nevertheless,
152   // there could be some false positives without additional
153   // checking.
154   case Hexagon::J2_jumptnew:
155   case Hexagon::J2_jumpfnew:
156   case Hexagon::J2_jumptnewpt:
157   case Hexagon::J2_jumpfnewpt:
158     Src1Reg = MI.getOperand(0).getReg();
159     if (Hexagon::P0 == Src1Reg || Hexagon::P1 == Src1Reg)
160       return HexagonII::HCG_B;
161     break;
162   // Transfer and jump:
163   // Rd=#U6 ; jump #r9:2
164   // Rd=Rs ; jump #r9:2
165   // Do not test for jump range here.
166   case Hexagon::J2_jump:
167   case Hexagon::RESTORE_DEALLOC_RET_JMP_V4:
168     return HexagonII::HCG_C;
169     break;
170   }
171 
172   return HexagonII::HCG_None;
173 }
174 
175 /// getCompoundOp - Return the index from 0-7 into the above opcode lists.
getCompoundOp(MCInst const & HMCI)176 static unsigned getCompoundOp(MCInst const &HMCI) {
177   const MCOperand &Predicate = HMCI.getOperand(0);
178   unsigned PredReg = Predicate.getReg();
179 
180   assert((PredReg == Hexagon::P0) || (PredReg == Hexagon::P1) ||
181          (PredReg == Hexagon::P2) || (PredReg == Hexagon::P3));
182 
183   switch (HMCI.getOpcode()) {
184   default:
185     llvm_unreachable("Expected match not found.\n");
186     break;
187   case Hexagon::J2_jumpfnew:
188     return (PredReg == Hexagon::P0) ? fp0_jump_nt : fp1_jump_nt;
189   case Hexagon::J2_jumpfnewpt:
190     return (PredReg == Hexagon::P0) ? fp0_jump_t : fp1_jump_t;
191   case Hexagon::J2_jumptnew:
192     return (PredReg == Hexagon::P0) ? tp0_jump_nt : tp1_jump_nt;
193   case Hexagon::J2_jumptnewpt:
194     return (PredReg == Hexagon::P0) ? tp0_jump_t : tp1_jump_t;
195   }
196 }
197 
getCompoundInsn(MCContext & Context,MCInst const & L,MCInst const & R)198 static MCInst *getCompoundInsn(MCContext &Context, MCInst const &L,
199                                MCInst const &R) {
200   MCInst *CompoundInsn = nullptr;
201   unsigned compoundOpcode;
202   MCOperand Rs, Rt;
203   int64_t Value;
204   bool Success;
205 
206   switch (L.getOpcode()) {
207   default:
208     LLVM_DEBUG(dbgs() << "Possible compound ignored\n");
209     return CompoundInsn;
210 
211   case Hexagon::A2_tfrsi:
212     Rt = L.getOperand(0);
213     compoundOpcode = J4_jumpseti;
214     CompoundInsn = new (Context) MCInst;
215     CompoundInsn->setOpcode(compoundOpcode);
216 
217     CompoundInsn->addOperand(Rt);
218     CompoundInsn->addOperand(L.getOperand(1)); // Immediate
219     CompoundInsn->addOperand(R.getOperand(0)); // Jump target
220     break;
221 
222   case Hexagon::A2_tfr:
223     Rt = L.getOperand(0);
224     Rs = L.getOperand(1);
225 
226     compoundOpcode = J4_jumpsetr;
227     CompoundInsn = new (Context) MCInst;
228     CompoundInsn->setOpcode(compoundOpcode);
229     CompoundInsn->addOperand(Rt);
230     CompoundInsn->addOperand(Rs);
231     CompoundInsn->addOperand(R.getOperand(0)); // Jump target.
232 
233     break;
234 
235   case Hexagon::C2_cmpeq:
236     LLVM_DEBUG(dbgs() << "CX: C2_cmpeq\n");
237     Rs = L.getOperand(1);
238     Rt = L.getOperand(2);
239 
240     compoundOpcode = cmpeqBitOpcode[getCompoundOp(R)];
241     CompoundInsn = new (Context) MCInst;
242     CompoundInsn->setOpcode(compoundOpcode);
243     CompoundInsn->addOperand(Rs);
244     CompoundInsn->addOperand(Rt);
245     CompoundInsn->addOperand(R.getOperand(1));
246     break;
247 
248   case Hexagon::C2_cmpgt:
249     LLVM_DEBUG(dbgs() << "CX: C2_cmpgt\n");
250     Rs = L.getOperand(1);
251     Rt = L.getOperand(2);
252 
253     compoundOpcode = cmpgtBitOpcode[getCompoundOp(R)];
254     CompoundInsn = new (Context) MCInst;
255     CompoundInsn->setOpcode(compoundOpcode);
256     CompoundInsn->addOperand(Rs);
257     CompoundInsn->addOperand(Rt);
258     CompoundInsn->addOperand(R.getOperand(1));
259     break;
260 
261   case Hexagon::C2_cmpgtu:
262     LLVM_DEBUG(dbgs() << "CX: C2_cmpgtu\n");
263     Rs = L.getOperand(1);
264     Rt = L.getOperand(2);
265 
266     compoundOpcode = cmpgtuBitOpcode[getCompoundOp(R)];
267     CompoundInsn = new (Context) MCInst;
268     CompoundInsn->setOpcode(compoundOpcode);
269     CompoundInsn->addOperand(Rs);
270     CompoundInsn->addOperand(Rt);
271     CompoundInsn->addOperand(R.getOperand(1));
272     break;
273 
274   case Hexagon::C2_cmpeqi:
275     LLVM_DEBUG(dbgs() << "CX: C2_cmpeqi\n");
276     Success = L.getOperand(2).getExpr()->evaluateAsAbsolute(Value);
277     (void)Success;
278     assert(Success);
279     if (Value == -1)
280       compoundOpcode = cmpeqn1BitOpcode[getCompoundOp(R)];
281     else
282       compoundOpcode = cmpeqiBitOpcode[getCompoundOp(R)];
283 
284     Rs = L.getOperand(1);
285     CompoundInsn = new (Context) MCInst;
286     CompoundInsn->setOpcode(compoundOpcode);
287     CompoundInsn->addOperand(Rs);
288     CompoundInsn->addOperand(L.getOperand(2));
289     CompoundInsn->addOperand(R.getOperand(1));
290     break;
291 
292   case Hexagon::C2_cmpgti:
293     LLVM_DEBUG(dbgs() << "CX: C2_cmpgti\n");
294     Success = L.getOperand(2).getExpr()->evaluateAsAbsolute(Value);
295     (void)Success;
296     assert(Success);
297     if (Value == -1)
298       compoundOpcode = cmpgtn1BitOpcode[getCompoundOp(R)];
299     else
300       compoundOpcode = cmpgtiBitOpcode[getCompoundOp(R)];
301 
302     Rs = L.getOperand(1);
303     CompoundInsn = new (Context) MCInst;
304     CompoundInsn->setOpcode(compoundOpcode);
305     CompoundInsn->addOperand(Rs);
306     CompoundInsn->addOperand(L.getOperand(2));
307     CompoundInsn->addOperand(R.getOperand(1));
308     break;
309 
310   case Hexagon::C2_cmpgtui:
311     LLVM_DEBUG(dbgs() << "CX: C2_cmpgtui\n");
312     Rs = L.getOperand(1);
313     compoundOpcode = cmpgtuiBitOpcode[getCompoundOp(R)];
314     CompoundInsn = new (Context) MCInst;
315     CompoundInsn->setOpcode(compoundOpcode);
316     CompoundInsn->addOperand(Rs);
317     CompoundInsn->addOperand(L.getOperand(2));
318     CompoundInsn->addOperand(R.getOperand(1));
319     break;
320 
321   case Hexagon::S2_tstbit_i:
322     LLVM_DEBUG(dbgs() << "CX: S2_tstbit_i\n");
323     Rs = L.getOperand(1);
324     compoundOpcode = tstBitOpcode[getCompoundOp(R)];
325     CompoundInsn = new (Context) MCInst;
326     CompoundInsn->setOpcode(compoundOpcode);
327     CompoundInsn->addOperand(Rs);
328     CompoundInsn->addOperand(R.getOperand(1));
329     break;
330   }
331 
332   return CompoundInsn;
333 }
334 
335 /// Non-Symmetrical. See if these two instructions are fit for compound pair.
isOrderedCompoundPair(MCInst const & MIa,bool IsExtendedA,MCInst const & MIb,bool IsExtendedB)336 static bool isOrderedCompoundPair(MCInst const &MIa, bool IsExtendedA,
337                                   MCInst const &MIb, bool IsExtendedB) {
338   unsigned MIaG = getCompoundCandidateGroup(MIa, IsExtendedA);
339   unsigned MIbG = getCompoundCandidateGroup(MIb, IsExtendedB);
340   // We have two candidates - check that this is the same register
341   // we are talking about.
342   unsigned Opca = MIa.getOpcode();
343   if (MIaG == HexagonII::HCG_A && MIbG == HexagonII::HCG_C &&
344       (Opca == Hexagon::A2_tfr || Opca == Hexagon::A2_tfrsi))
345     return true;
346   return ((MIaG == HexagonII::HCG_A && MIbG == HexagonII::HCG_B) &&
347           (MIa.getOperand(0).getReg() == MIb.getOperand(0).getReg()));
348 }
349 
lookForCompound(MCInstrInfo const & MCII,MCContext & Context,MCInst & MCI)350 static bool lookForCompound(MCInstrInfo const &MCII, MCContext &Context,
351                             MCInst &MCI) {
352   assert(HexagonMCInstrInfo::isBundle(MCI));
353   bool JExtended = false;
354   for (MCInst::iterator J =
355            MCI.begin() + HexagonMCInstrInfo::bundleInstructionsOffset;
356        J != MCI.end(); ++J) {
357     MCInst const *JumpInst = J->getInst();
358     if (HexagonMCInstrInfo::isImmext(*JumpInst)) {
359       JExtended = true;
360       continue;
361     }
362     if (HexagonMCInstrInfo::getType(MCII, *JumpInst) == HexagonII::TypeJ) {
363       // Try to pair with another insn (B)undled with jump.
364       bool BExtended = false;
365       for (MCInst::iterator B =
366                MCI.begin() + HexagonMCInstrInfo::bundleInstructionsOffset;
367            B != MCI.end(); ++B) {
368         MCInst const *Inst = B->getInst();
369         if (JumpInst == Inst)
370           continue;
371         if (HexagonMCInstrInfo::isImmext(*Inst)) {
372           BExtended = true;
373           continue;
374         }
375         LLVM_DEBUG(dbgs() << "J,B: " << JumpInst->getOpcode() << ","
376                           << Inst->getOpcode() << "\n");
377         if (isOrderedCompoundPair(*Inst, BExtended, *JumpInst, JExtended)) {
378           MCInst *CompoundInsn = getCompoundInsn(Context, *Inst, *JumpInst);
379           if (CompoundInsn) {
380             LLVM_DEBUG(dbgs() << "B: " << Inst->getOpcode() << ","
381                               << JumpInst->getOpcode() << " Compounds to "
382                               << CompoundInsn->getOpcode() << "\n");
383             J->setInst(CompoundInsn);
384             MCI.erase(B);
385             return true;
386           }
387         }
388         BExtended = false;
389       }
390     }
391     JExtended = false;
392   }
393   return false;
394 }
395 
396 /// tryCompound - Given a bundle check for compound insns when one
397 /// is found update the contents fo the bundle with the compound insn.
398 /// If a compound instruction is found then the bundle will have one
399 /// additional slot.
tryCompound(MCInstrInfo const & MCII,MCSubtargetInfo const & STI,MCContext & Context,MCInst & MCI)400 void HexagonMCInstrInfo::tryCompound(MCInstrInfo const &MCII, MCSubtargetInfo const &STI,
401                                      MCContext &Context, MCInst &MCI) {
402   assert(HexagonMCInstrInfo::isBundle(MCI) &&
403          "Non-Bundle where Bundle expected");
404 
405   // By definition a compound must have 2 insn.
406   if (MCI.size() < 2)
407     return;
408 
409   bool StartedValid = llvm::HexagonMCShuffle(Context, false, MCII, STI, MCI);
410 
411   // Create a vector, needed to keep the order of jump instructions.
412   MCInst CheckList(MCI);
413 
414   // Look for compounds until none are found, only update the bundle when
415   // a compound is found.
416   while (lookForCompound(MCII, Context, CheckList)) {
417     // Keep the original bundle around in case the shuffle fails.
418     MCInst OriginalBundle(MCI);
419 
420     // Need to update the bundle.
421     MCI = CheckList;
422 
423     if (StartedValid &&
424         !llvm::HexagonMCShuffle(Context, false, MCII, STI, MCI)) {
425       LLVM_DEBUG(dbgs() << "Found ERROR\n");
426       MCI = OriginalBundle;
427     }
428   }
429 }
430