OpenASIP  2.0
TCEInstrInfo.cc
Go to the documentation of this file.
1 /*
2  Copyright (c) 2002-2009 Tampere University.
3 
4  This file is part of TTA-Based Codesign Environment (TCE).
5 
6  Permission is hereby granted, free of charge, to any person obtaining a
7  copy of this software and associated documentation files (the "Software"),
8  to deal in the Software without restriction, including without limitation
9  the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  and/or sell copies of the Software, and to permit persons to whom the
11  Software is furnished to do so, subject to the following conditions:
12 
13  The above copyright notice and this permission notice shall be included in
14  all copies or substantial portions of the Software.
15 
16  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  DEALINGS IN THE SOFTWARE.
23  */
24 /**
25  * @file TCEInstrInfo.cpp
26  *
27  * Implementation of TCEInstrInfo class.
28  *
29  * NOTE: Normal TCE coding guidelines do not apply here to makeo it
30  * easier to track and copy paste changes from LLVM.
31  * So please follow LLVM style when adding or fixing things.
32  *
33  * @author Veli-Pekka Jääskeläinen 2007 (vjaaskel-no.spam-cs.tut.fi)
34  * @author Mikael Lepistö 2009 (mikael.lepisto-no.spam-tut.fi)
35  * @author Heikki Kultala 2011-2012 (heikki.kultala-no.spam-tut.fi)
36  */
37 
38 #include "TCEInstrInfo.hh"
39 
40 #include <llvm/ADT/STLExtras.h>
41 #include <llvm/CodeGen/DFAPacketizer.h>
42 #include <llvm/CodeGen/MachineInstrBuilder.h>
43 #include <llvm/CodeGen/MachineRegisterInfo.h>
44 #include <llvm/Support/ErrorHandling.h>
45 
46 #include "TCETargetMachine.hh"
48 /*
49 #include <llvm/CodeGen/MachineInstrBuilder.h>
50 #include <llvm/ADT/SmallVector.h>
51 
52 #include "TCEInstrInfo.hh"
53 */
54 #include "TCEPlugin.hh"
55 //#include "tce_config.h"
56 
57 // Include code generated with tceplugingen:
58 
59 #define GET_INSTRINFO_CTOR_DTOR
60 #define GET_INSTRINFO_MC_DESC
61 #include "TCEGenInstrInfo.inc"
62 #undef GET_INSTRINFO_CTOR_DTOR
63 #undef GET_INSTRINFO_MC_DESC
64 
65 using namespace llvm;
66 
67 #define GET_INSTRMAP_INFO
68 #include "TCEGenDFAPacketizer.inc"
69 
70 /**
71  * Constructor.
72  */
74  const TCETargetMachinePlugin* plugin) :
75  TCEGenInstrInfo(TCE::ADJCALLSTACKDOWN, TCE::ADJCALLSTACKUP),
76  ri_(*this), plugin_(plugin) {
77 }
78 
79 /**
80  * Destructor.
81  */
83 }
84 
85 /**
86  * Inserts a branch instruction or brach instructions into llvm MBB.
87  *
88  * If the MBB already has an unconditional branch at end, does nothing.
89  *
90  * @param mbb where to insert the branch instructions.
91  * @param tbb jump target basic block
92  * @param fbb false condition jump target, if insertin 2 branches
93  *
94  * @return number of branch instructions inserted
95  */
96 unsigned
98  MachineBasicBlock& mbb,
99  MachineBasicBlock* tbb,
100  MachineBasicBlock* fbb,
101  ArrayRef<MachineOperand> cond,
102  const DebugLoc& dl
103  , int *BytesAdded) const {
104  assert(cond.size() == 0 || cond.size() == 2 || cond.size() == 3);
105 
106  if (mbb.size() != 0) {
107  // already has a uncond branch, no need for another.
108  // asserts to make sure it's to same BB in order to not create
109  // broken code.
110  if (mbb.back().getOpcode() == TCE::TCEBR ||
111  mbb.back().getOpcode() == TCE::TCEBRIND) {
112  assert(cond.size() == 0);
113  return 0;
114  }
115  if (cond.size() != 0) {
116  assert (mbb.back().getOpcode() != TCE::TCEBRCOND && "c branch!");
117  assert (mbb.back().getOpcode() != TCE::TCEBRICOND && "ic branch!");
118  assert (mbb.back().getOpcode() != TCE::TCEBR && "has branch!(1)");
119  } else {
120  assert (mbb.back().getOpcode() != TCE::TCEBR && "has branch(2)!");
121  }
122 
123  }
124 
125  if (fbb == 0) {
126  if (cond.empty()) {
127  // Can only insert uncond branches so far.
128  BuildMI(&mbb, dl, get(TCE::TCEBR)).addMBB(tbb);
129  return 1;
130  } else {
131  if (cond.size() == 2 && cond[1].getImm() == false) {
132  // false jump
133  BuildMI(&mbb, dl, get(TCE::TCEBRICOND)).
134  addReg(cond[0].getReg()).addMBB(tbb);
135  return 1;
136  } else if (cond.size() == 2 && cond[1].getImm() == true) {
137  BuildMI(&mbb, dl, get(TCE::TCEBRCOND)).addReg(cond[0].getReg())
138  .addMBB(tbb);
139  return 1;
140  } else {
141  insertCCBranch(mbb, *tbb, cond, dl);
142  return 1;
143  }
144  }
145  }
146 
147  assert(
148  !cond.empty() &&
149  "Two jumps need a condition"); // not allowed to have conditional
150  // jump because we have an fbb
151 
152  if (cond.size() == 2 && cond[1].getImm() == false) {
153  BuildMI(&mbb, dl, get(TCE::TCEBRICOND)).
154  addReg(cond[0].getReg()).addMBB(tbb);
155  } else if (cond.size() == 1 ||
156  (cond.size() == 2 && cond[1].getImm() == true)) {
157  BuildMI(&mbb, dl, get(TCE::TCEBRCOND)).
158  addReg(cond[0].getReg()).addMBB(tbb);
159  } else {
160  insertCCBranch(mbb, *tbb, cond, dl);
161  }
162  BuildMI(&mbb, dl, get(TCE::TCEBR)).addMBB(fbb);
163 
164  return 2;
165 }
166 
167 /**
168  * Removes branch or branches form end of llvm MachineBasicBlock
169  *
170  * @param mbb where to remove the branches from
171  * @return number of braches removed
172  */
173 unsigned
175  MachineBasicBlock &mbb, int *BytesRemoved) const {
176  int j = 0;
177  MachineBasicBlock::iterator i = mbb.end();
178  while (i != mbb.begin()) {
179  i--;
180  int opc = i->getOpcode();
181  if (i->getDesc().isBranch()) {
182  i->eraseFromParent();
183  i = mbb.end(); // not optimal, but we will not miss any
184  // instruction
185  j++;
186  }
187  }
188  return j;
189 }
190 
191 /**
192  * Returns true if program control can't fall through the last instruction
193  * in the basic block, false otherwise.
194  */
195 bool
196 TCEInstrInfo::BlockHasNoFallThrough(const MachineBasicBlock& MBB) const {
197  /* Mips inspired */
198  if (MBB.empty()) return false;
199  switch (MBB.back().getOpcode()) {
200  case TCE::RETL: // Return.
201  case TCE::TCEBR: // Uncond branch.
202  case TCE::TCEBRIND: // Uncond indirect branch.
203  return true;
204  default: return false;
205  }
206 }
207 
208 void TCEInstrInfo::
209 storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
210  unsigned SrcReg, bool isKill, int FI,
211  const TargetRegisterClass *RC) const {
212  DebugLoc DL;
213 
214  if (I != MBB.end()) DL = I->getDebugLoc();
215 
216  BuildMI(MBB, I, DL, get(plugin_->getStore(RC))).addFrameIndex(FI).addImm(0)
217  .addReg(SrcReg, getKillRegState(isKill));
218 
219  LLVMContext& context = MBB.getParent()->getFunction().getContext();
220  llvm::Metadata* md = llvm::MDString::get(context, "AA_CATEGORY_STACK_SLOT");
221  MDNode* mdNode =
222  MDNode::get(context, llvm::ArrayRef<llvm::Metadata*>(&md, 1));
223  MachineOperand metaDataOperand = MachineOperand::CreateMetadata(mdNode);
224  I--; // buildmi moves the iterator to next ins, point to the created one.
225  I->addOperand(metaDataOperand);
226 }
227 
228 void TCEInstrInfo::
229 loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
230  unsigned DestReg, int FI,
231  const TargetRegisterClass *RC) const {
232  DebugLoc DL;
233 
234  if (I != MBB.end()) DL = I->getDebugLoc();
235  BuildMI(MBB, I, DL, get(plugin_->getLoad(RC)), DestReg).addFrameIndex(FI)
236  .addImm(0);
237 
238  LLVMContext& context = MBB.getParent()->getFunction().getContext();
239  llvm::Metadata* md = llvm::MDString::get(context, "AA_CATEGORY_STACK_SLOT");
240  MDNode* mdNode =
241  MDNode::get(context, llvm::ArrayRef<llvm::Metadata*>(&md, 1));
242  MachineOperand metaDataOperand = MachineOperand::CreateMetadata(mdNode);
243  I--; // buildmi moves the iterator to next ins, point to the created one.
244  I->addOperand(metaDataOperand);
245 }
246 
247 /**
248  * Creates instruction for copying value from a register to another.
249  *
250  * @param mbb Basic block where the copy is done.
251  * @param mbbi Iterator to the place where the copy instruction is added.
252  * @param srcReg Register where the value is copied from.
253  * @param destReg Register where the value is copied to.
254  * @param rc Class of the register to copy.
255  */
257  MachineBasicBlock& mbb,
258  MachineBasicBlock::iterator mbbi,
259  const DebugLoc& DL,
260  MCRegister destReg, MCRegister srcReg,
261  bool killSrc) const
262 {
263  DebugLoc dl;
264  if (mbbi != mbb.end()) dl = mbbi->getDebugLoc();
265 /*
266  BuildMI(mbb, mbbi, dl,
267  get(plugin_->getRegCopy(destReg, srcReg)), destReg).
268  .addReg(SrcReg, getKillRegState(isKillSrc));
269 */
270  if (copyPhysVectorReg(mbb, mbbi, dl, destReg, srcReg, killSrc)) {
271  return;
272  }
273 
274  if (TCE::R1RegsRegClass.contains(destReg, srcReg)) {
275  BuildMI(mbb, mbbi, dl, get(TCE::MOVI1rr), destReg)
276  .addReg(srcReg, getKillRegState(killSrc));
277  } else if (TCE::R32IRegsRegClass.contains(destReg, srcReg)) {
278  BuildMI(mbb, mbbi, dl, get(TCE::MOVI32rr), destReg)
279  .addReg(srcReg, getKillRegState(killSrc));
280  } else if (TCE::R64RegsRegClass.contains(destReg, srcReg)) {
281  BuildMI(mbb, mbbi, dl, get(TCE::MOV64ss), destReg)
282  .addReg(srcReg, getKillRegState(killSrc));
283  } else if (TCE::FPRegsRegClass.contains(destReg, srcReg)) {
284  BuildMI(mbb, mbbi, dl, get(TCE::MOVff), destReg)
285  .addReg(srcReg, getKillRegState(killSrc));
286  } else if (TCE::HFPRegsRegClass.contains(destReg, srcReg)) {
287  BuildMI(mbb, mbbi, dl, get(TCE::MOVhh), destReg)
288  .addReg(srcReg, getKillRegState(killSrc));
289  } else if (TCE::R1RegsRegClass.contains(destReg) &&
290  TCE::R32IRegsRegClass.contains(srcReg)) {
291  BuildMI(mbb, mbbi, dl, get(TCE::MOVI32I1rr), destReg)
292  .addReg(srcReg, getKillRegState(killSrc));
293  } else if (TCE::R1RegsRegClass.contains(srcReg) &&
294  TCE::R32IRegsRegClass.contains(destReg)) {
295  BuildMI(mbb, mbbi, dl, get(TCE::MOVI1I32rr), destReg)
296  .addReg(srcReg, getKillRegState(killSrc));
297  } else if (TCE::GuardRegsRegClass.contains(destReg, srcReg)) {
298  BuildMI(mbb, mbbi, dl, get(TCE::MOVGrr), destReg)
299  .addReg(srcReg, getKillRegState(killSrc));
300  } else if (TCE::GuardRegsRegClass.contains(srcReg) &&
301  TCE::R32IRegsRegClass.contains(destReg)) {
302  BuildMI(mbb, mbbi, dl, get(TCE::MOVGI32rr), destReg)
303  .addReg(srcReg, getKillRegState(killSrc));
304  } else if (TCE::R32IRegsRegClass.contains(srcReg) &&
305  TCE::GuardRegsRegClass.contains(destReg)) {
306  BuildMI(mbb, mbbi, dl, get(TCE::MOVI32Grr), destReg)
307  .addReg(srcReg, getKillRegState(killSrc));
308  } else if (TCE::GuardRegsRegClass.contains(srcReg) &&
309  TCE::R1RegsRegClass.contains(destReg)) {
310  BuildMI(mbb, mbbi, dl, get(TCE::MOVGI1rr), destReg)
311  .addReg(srcReg, getKillRegState(killSrc));
312  } else if (TCE::R1RegsRegClass.contains(srcReg) &&
313  TCE::GuardRegsRegClass.contains(destReg)) {
314  BuildMI(mbb, mbbi, dl, get(TCE::MOVI1Grr), destReg)
315  .addReg(srcReg, getKillRegState(killSrc));
316  } else {
317  assert(
318  false && "TCERegisterInfo::copyPhysReg(): Can't copy register");
319 
320  }
321 }
322 
323 /*
324  * Reverses a condition.
325  *
326  * @param cond condition to reverse. This is modified.
327  *
328  * @return false if did reverse condition, true if could not.
329  */
330 bool
332  llvm::SmallVectorImpl<llvm::MachineOperand>& cond) const {
333  assert(cond.size() != 0);
334 
335  // from true to false
336  if (cond.size() == 1) {
337  cond.push_back(MachineOperand::CreateImm(false));
338  return false;
339  } else if (cond.size() == 2) {
340  // from false to true
341  if (cond[1].getImm() == false) {
342  cond[1].setImm(true);
343  } else {
344  // from true to false
345  assert(cond[1].getImm() == true);
346  cond[1].setImm(false);
347  }
348  return false;
349  } else if (cond.size() == 3) {
350  switch (cond[2].getImm()) {
351  case 2:
352  // eq -> ne
353  cond[2].setImm(3);
354  return false;
355  case 3:
356  // ne -> eq
357  cond[2].setImm(2);
358  return false;
359  case 4:
360  // gt -> le
361  cond[2].setImm(5);
362  return false;
363  case 5:
364  // le -> gt
365  cond[2].setImm(4);
366  return false;
367  case 6:
368  // ltu -> geu
369  cond[2].setImm(7);
370  return false;
371  case 7:
372  // geu -> ltu
373  cond[2].setImm(6);
374  return false;
375  case 14:
376  // lt -> ge
377  cond[2].setImm(16);
378  return false;
379  case 15:
380  // ltu -> geu
381  cond[2].setImm(17);
382  return false;
383  case 16:
384  // ge -> lt
385  cond[2].setImm(14);
386  return false;
387  case 17:
388  // geu -> ltu
389  cond[2].setImm(15);
390  return false;
391  // case 100+: register-immediate versions of branch ops
392  case 102:
393  // eg -> ne
394  cond[2].setImm(103);
395  return false;
396  case 103:
397  // ne -> eq
398  cond[2].setImm(102);
399  return false;
400  case 104:
401  // gt -> le
402  cond[2].setImm(105);
403  return false;
404  case 105:
405  // le -> gt
406  cond[2].setImm(104);
407  return false;
408  case 106:
409  // ltu -> geu
410  cond[2].setImm(107);
411  return false;
412  case 107:
413  // geu -> ltu
414  cond[2].setImm(106);
415  return false;
416  case 114:
417  // lt -> ge
418  cond[2].setImm(116);
419  return false;
420  case 115:
421  // ltu -> geu
422  cond[2].setImm(117);
423  return false;
424  case 116:
425  // ge -> lt
426  cond[2].setImm(114);
427  return false;
428  case 117:
429  // geu -> ltu
430  cond[2].setImm(115);
431  return false;
432  default:
433  return true;
434  }
435  }
436  return true;
437 }
438 
439 /**
440  * Analyzes branches of MBB.
441  *
442  * @param mbb MBB to analyze
443  * @param tbb Puts the jump target or condition true target MBB here
444  * @param fbb Puts the condition false target here, if not fall-thru
445  * @param cond puts the condition data (predcate reg and T/F) here
446  * @return false if could analyze, true if could not analyze
447  */
448 bool
450  MachineBasicBlock &mbb, MachineBasicBlock *&tbb,
451  MachineBasicBlock *&fbb,
452  llvm::SmallVectorImpl<llvm::MachineOperand>& cond, bool allowModify)
453  const {
454  if (mbb.empty()) {
455  return false;
456  }
457 
458  MachineBasicBlock::iterator i = mbb.end(); i--;
459 
460  MachineInstr& lastIns = *i;
461  switch (lastIns.getOpcode()) {
462  case TCE::TCEBRCOND:
463  tbb = lastIns.getOperand(1).getMBB();
464  cond.push_back(i->getOperand(0));
465  cond.push_back(MachineOperand::CreateImm(true));
466  return false;
467  case TCE::TCEBRICOND:
468  tbb = lastIns.getOperand(1).getMBB();
469  cond.push_back(i->getOperand(0));
470  cond.push_back(MachineOperand::CreateImm(false));
471  return false;
472  case TCE::TCEBRIND:
473  case TCE::TCEBR: {
474  // indirect jump cannot be analyzed
475  if (!lastIns.getOperand(0).isMBB()) {
476  return true;
477  }
478 
479  if (i == mbb.begin()) {
480  tbb = lastIns.getOperand(0).getMBB();
481  return false; // uncond jump only ins in mbb.
482  }
483  i--;
484  if (i->getOpcode() == TCE::TCEBRCOND) {
485  tbb = i->getOperand(1).getMBB();
486  fbb = lastIns.getOperand(0).getMBB();
487  cond.push_back(i->getOperand(0));
488  cond.push_back(MachineOperand::CreateImm(true));
489  return false;
490  }
491  if (i->getOpcode() == TCE::TCEBRICOND) {
492  tbb = i->getOperand(1).getMBB();
493  fbb = lastIns.getOperand(0).getMBB();
494  cond.push_back(i->getOperand(0));
495  cond.push_back(MachineOperand::CreateImm(false));
496  return false;
497  }
498  // two uncond branches not allowed
499  assert(i->getOpcode() != TCE::TCEBR);
500 
501  if (i->getDesc().isBranch()) {
502  tbb = i->getOperand(2).getMBB();
503  fbb = lastIns.getOperand(0).getMBB();
504  return plugin_->analyzeCCBranch(*i, cond);
505  } else { // only conditional branch.
506  tbb = lastIns.getOperand(0).getMBB();
507  return false;
508  }
509  }
510  default:
511  // if some another branch, it's unknown brach
512  // if not brannch, it's fallthourgh
513  if (lastIns.getDesc().isBranch()) {
514  tbb = lastIns.getOperand(2).getMBB();
515  return plugin_->analyzeCCBranch(lastIns, cond);
516  } else {
517  return false;
518  }
519  }
520  // should never be here
521  return true;
522 }
523 
524 namespace {
525 class TCEPipelinerLoopInfo : public TargetInstrInfo::PipelinerLoopInfo {
526 public:
527  TCEPipelinerLoopInfo() {}
528  bool
529  shouldIgnoreForPipelining(const MachineInstr *MI) const override {
530  return false;
531  }
532 
533  // If the trip count is statically known to be greater than TC, return
534  // true. If the trip count is statically known to be not greater than TC,
535  // return false. Otherwise return nullopt and fill out Cond with the test
536  // condition.
537 
538  Optional<bool>
539  createTripCountGreaterCondition(
540  int TC, MachineBasicBlock &MBB,
541  SmallVectorImpl<MachineOperand> &Cond) override {
542  return true;
543  }
544 
545  void setPreheader(MachineBasicBlock *NewPreheader) override{};
546 
547  void adjustTripCount(int TripCountAdjust) override{};
548 
549  void disposed() override{};
550 };
551 } // namespace
552 
553 std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo>
554 TCEInstrInfo::analyzeLoopForPipelining(MachineBasicBlock *LoopBB) const {
555  return std::make_unique<TCEPipelinerLoopInfo>();
556 }
557 
558 bool
559 TCEInstrInfo::isPredicated(const MachineInstr& mi_ref) const {
560  const MachineInstr* mi = &mi_ref;
561  // TODO: should be conditional move here..
562  if (mi->getOpcode() == TCE::RETL) {
563  return false;
564  }
565 
566  // KILL is not a predicated instruction.
567  if (mi->getOpcode() == TCE::KILL) {
568  return false;
569  }
570 
571  TCEString opName = plugin_->operationName(mi->getOpcode());
572  return opName[0] == '?' || opName[0] == '!';
573 }
574 
575 bool
576 TCEInstrInfo::isPredicable(const MachineInstr& mi_ref) const {
577  const MachineInstr* mi = &mi_ref;
578  if (mi->getOpcode() == TCE::COPY) {
579  return false;
580  }
581 
582  // TODO: why is RETL not predicable?
583  if (mi->getOpcode() == TCE::RETL) {
584  return false;
585  }
586 
587  if (isPredicated(*mi)) {
588  return false;
589  }
590 
591  if (getMatchingCondBranchOpcode(mi->getOpcode(),false) == -1) {
592  return false;
593  }
594 
595  for (int oper = mi->getNumOperands() - 1; oper >= 0; --oper) {
596  MachineOperand mo = mi->getOperand(oper);
597 
598  if ((mo.isReg() && !mo.isUse() && !mo.isImplicit())) {
599  continue;
600  }
601 
602  // TODO: support operand changing for fp imms etc.!
603  if (!mo.isReg() && !mo.isImm()) {
604  return false;
605  }
606  }
607  return true;
608 }
609 
610 // todo: mostlly ripped from hexagon.
611 // check the legal things
613  MachineInstr& mi_ref,
614  ArrayRef<MachineOperand> cond
615 ) const {
616 
617  MachineInstr *mi = &mi_ref;
618 
619  int opc = mi->getOpcode();
620 
621  assert (isPredicable(*mi) && "Expected predicable instruction");
622 
623  bool invertJump = (cond.size() >1 && cond[1].isImm() &&
624  (cond[1].getImm() == 0));
625 
626  mi->setDesc(get(getMatchingCondBranchOpcode(opc, invertJump)));
627  //
628  // This assumes that the predicate is always the first operand
629  // in the set of inputs.
630  //
631  mi->addOperand(mi->getOperand(mi->getNumOperands()-1));
632  int oper;
633  // why -3 in hexagon?
634  for (oper = mi->getNumOperands() - 2; oper >= 0; --oper) {
635  MachineOperand mo = mi->getOperand(oper);
636  // todo: why this break in hexagon?
637  if ((mo.isReg() && !mo.isUse() && !mo.isImplicit())) {
638  break;
639  }
640 
641  if (mo.isReg()) {
642  mi->getOperand(oper+1).ChangeToRegister(mo.getReg(), mo.isDef(),
643  mo.isImplicit(), mo.isKill(),
644  mo.isDead(), mo.isUndef(),
645  mo.isDebug());
646  } else if (mo.isImm()) {
647  mi->getOperand(oper+1).ChangeToImmediate(mo.getImm());
648  } else if (mo.isFPImm()) {
649  mi->getOperand(oper+1).ChangeToFPImmediate(mo.getFPImm());
650  } else if (mo.isGlobal()) {
651  // TODO: what to do here?
652  llvm_unreachable("Unexpected operand type");
653  mi->getOperand(oper+1).ChangeToImmediate(mo.getImm());
654  } else {
655  llvm_unreachable("Unexpected operand type");
656  }
657  }
658 
659  MachineOperand PredMO = cond[0];
660  mi->getOperand(oper+1).ChangeToRegister(PredMO.getReg(), PredMO.isDef(),
661  PredMO.isImplicit(), PredMO.isKill(),
662  PredMO.isDead(), PredMO.isUndef(),
663  PredMO.isDebug());
664 
665  return true;
666 }
667 
668 
669 int TCEInstrInfo::getMatchingCondBranchOpcode(int opc, bool inv) const {
670 
671  if (!inv) {
672  return plugin_->getTruePredicateOpcode(opc);
673  } else {
674  return plugin_->getFalsePredicateOpcode(opc);
675  }
676 }
677 
678 
679 bool
681  MachineInstr& MI, std::vector<MachineOperand>& Pred,
682  bool SkipDead) const {
683  for (unsigned oper = 0; oper < MI.getNumOperands(); ++oper) {
684  MachineOperand MO = MI.getOperand(oper);
685  if (MO.isReg() && MO.isDef()) {
686  const TargetRegisterClass* RC =
687  ri_.getMinimalPhysRegClass(MO.getReg());
688  if (RC == &TCE::GuardRegsRegClass || RC == &TCE::R1RegsRegClass) {
689  Pred.push_back(MO);
690  return true;
691  }
692  }
693  }
694  return false;
695 }
696 
697 bool
699 isProfitableToIfCvt(MachineBasicBlock &MBB,
700  unsigned NumCycles,
701  unsigned ExtraPredCycles,
702  BranchProbability Probability) const {
703  return true;
704 }
705 
706 
707 bool
709 isProfitableToIfCvt(MachineBasicBlock &TMBB,
710  unsigned NumTCycles,
711  unsigned ExtraTCycles,
712  MachineBasicBlock &FMBB,
713  unsigned NumFCycles,
714  unsigned ExtraFCycles,
715  BranchProbability Probability) const {
716  return true;
717 }
718 
719 
720 std::tuple<int, int>
722  return plugin_->getPointerAdjustment(offset);
723 }
724 
725 DFAPacketizer *
727  const TargetSubtargetInfo &STI) const {
728  const InstrItineraryData *II = STI.getInstrItineraryData();
729  DFAPacketizer *dfa =
730  static_cast<const TCESubtarget &>(STI).createDFAPacketizer(II);
731  assert(dfa != nullptr);
732  return dfa;
733 }
734 
llvm::TCETargetMachinePlugin::getStore
virtual int getStore(const TargetRegisterClass *rc) const =0
llvm
Definition: InlineAsmParser.hh:49
TCETargetMachinePlugin.hh
llvm::TCEInstrInfo::isPredicated
virtual bool isPredicated(const MachineInstr &MI) const override
Definition: TCEInstrInfo.cc:559
llvm::TCESubtarget
Definition: TCESubtarget.hh:56
llvm::TCEInstrInfo::loadRegFromStackSlot
virtual void loadRegFromStackSlot(MachineBasicBlock &mbb, MachineBasicBlock::iterator mbbi, unsigned destReg, int frameIndex, const TargetRegisterClass *rc) const
Definition: TCEInstrInfo.cc:229
llvm::TCEInstrInfo::TCEInstrInfo
TCEInstrInfo(const TCETargetMachinePlugin *plugin)
Definition: TCEInstrInfo.cc:73
llvm::TCETargetMachinePlugin::analyzeCCBranch
virtual bool analyzeCCBranch(llvm::MachineInstr &i, llvm::SmallVectorImpl< llvm::MachineOperand > &cond) const
Definition: TCETargetMachinePlugin.hh:238
llvm::TCEInstrInfo::isPredicable
virtual bool isPredicable(const MachineInstr &MI) const override
Definition: TCEInstrInfo.cc:576
llvm::TCEInstrInfo::PredicateInstruction
virtual bool PredicateInstruction(MachineInstr &mi, ArrayRef< MachineOperand > cond) const override
Definition: TCEInstrInfo.cc:612
llvm::TCEInstrInfo::~TCEInstrInfo
virtual ~TCEInstrInfo()
Definition: TCEInstrInfo.cc:82
llvm::TCEInstrInfo::isProfitableToIfCvt
virtual bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, unsigned ExtraPredCycles, BranchProbability Probability) const override
Definition: TCEInstrInfo.cc:699
assert
#define assert(condition)
Definition: Application.hh:86
llvm::TCETargetMachinePlugin::getFalsePredicateOpcode
virtual int getFalsePredicateOpcode(unsigned opc) const =0
TCETargetMachine.hh
llvm::TCEInstrInfo::CreateTargetScheduleState
virtual DFAPacketizer * CreateTargetScheduleState(const TargetSubtargetInfo &) const override
Definition: TCEInstrInfo.cc:726
llvm::TCEInstrInfo::copyPhysReg
virtual void copyPhysReg(MachineBasicBlock &mbb, MachineBasicBlock::iterator mbbi, const DebugLoc &DL, MCRegister destReg, MCRegister srcReg, bool KillSrc) const override
Definition: TCEInstrInfo.cc:256
llvm::TCEInstrInfo::insertCCBranch
virtual void insertCCBranch(MachineBasicBlock &mbb, MachineBasicBlock &tbb, ArrayRef< MachineOperand > cond, const DebugLoc &dl) const
llvm::TCEInstrInfo::plugin_
const TCETargetMachinePlugin * plugin_
Definition: TCEInstrInfo.hh:193
llvm::TCEInstrInfo::analyzeBranch
virtual bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, llvm::SmallVectorImpl< llvm::MachineOperand > &cond, bool allowModify=false) const override
Definition: TCEInstrInfo.cc:449
llvm::TCETargetMachinePlugin::getLoad
virtual int getLoad(const TargetRegisterClass *rc) const =0
llvm::TCEInstrInfo::insertBranch
virtual unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
Definition: TCEInstrInfo.cc:97
llvm::TCEInstrInfo::storeRegToStackSlot
virtual void storeRegToStackSlot(MachineBasicBlock &mbb, MachineBasicBlock::iterator mbbi, unsigned srcReg, bool isKill, int frameIndex, const TargetRegisterClass *rc) const
Definition: TCEInstrInfo.cc:209
llvm::TCETargetMachinePlugin
Definition: TCETargetMachinePlugin.hh:109
llvm::TCETargetMachinePlugin::getPointerAdjustment
virtual std::tuple< int, int > getPointerAdjustment(int offset) const =0
llvm::TCEInstrInfo::copyPhysVectorReg
bool copyPhysVectorReg(MachineBasicBlock &mbb, MachineBasicBlock::iterator mbbi, const DebugLoc &DL, MCRegister destReg, MCRegister srcReg, bool killSrc) const
llvm::TCEInstrInfo::getMatchingCondBranchOpcode
int getMatchingCondBranchOpcode(int Opc, bool inverted) const
Definition: TCEInstrInfo.cc:669
llvm::TCETargetMachinePlugin::getTruePredicateOpcode
virtual int getTruePredicateOpcode(unsigned opc) const =0
llvm::TCEInstrInfo::removeBranch
unsigned removeBranch(MachineBasicBlock &mbb, int *BytesRemoved=nullptr) const override
Definition: TCEInstrInfo.cc:174
TCEPlugin.hh
TCEString
Definition: TCEString.hh:53
llvm::TCEInstrInfo::analyzeLoopForPipelining
std::unique_ptr< PipelinerLoopInfo > analyzeLoopForPipelining(MachineBasicBlock *LoopBB) const override
Analyze loop L, which must be a single-basic-block loop, and if the conditions can be understood enou...
Definition: TCEInstrInfo.cc:554
llvm::TCEInstrInfo::getPointerAdjustment
std::tuple< int, int > getPointerAdjustment(int offset) const
Definition: TCEInstrInfo.cc:721
llvm::TCEInstrInfo::ri_
const TCERegisterInfo ri_
Definition: TCEInstrInfo.hh:192
llvm::TCETargetMachinePlugin::operationName
virtual std::string operationName(unsigned opc) const =0
Returns operation name corresponding to llvm target opcode.
llvm::TCEInstrInfo::reverseBranchCondition
virtual bool reverseBranchCondition(llvm::SmallVectorImpl< llvm::MachineOperand > &cond) const override
Definition: TCEInstrInfo.cc:331
TCEInstrInfo.hh
llvm::TCEInstrInfo::ClobbersPredicate
virtual bool ClobbersPredicate(MachineInstr &MI, std::vector< MachineOperand > &Pred, bool SkipDead) const override
Definition: TCEInstrInfo.cc:680
llvm::TCEInstrInfo::BlockHasNoFallThrough
virtual bool BlockHasNoFallThrough(const MachineBasicBlock &MBB) const
Definition: TCEInstrInfo.cc:196