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>
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
67 #define GET_INSTRMAP_INFO
68 #include "TCEGenDFAPacketizer.inc"
75 TCEGenInstrInfo(TCE::ADJCALLSTACKDOWN, TCE::ADJCALLSTACKUP),
76 ri_(*this), plugin_(plugin) {
98 MachineBasicBlock& mbb,
99 MachineBasicBlock* tbb,
100 MachineBasicBlock* fbb,
101 ArrayRef<MachineOperand> cond,
103 ,
int *BytesAdded)
const {
104 assert(cond.size() == 0 || cond.size() == 2 || cond.size() == 3);
106 if (mbb.size() != 0) {
110 if (mbb.back().getOpcode() == TCE::TCEBR ||
111 mbb.back().getOpcode() == TCE::TCEBRIND) {
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)");
120 assert (mbb.back().getOpcode() != TCE::TCEBR &&
"has branch(2)!");
128 BuildMI(&mbb, dl, get(TCE::TCEBR)).addMBB(tbb);
131 if (cond.size() == 2 && cond[1].getImm() ==
false) {
133 BuildMI(&mbb, dl, get(TCE::TCEBRICOND)).
134 addReg(cond[0].getReg()).addMBB(tbb);
136 }
else if (cond.size() == 2 && cond[1].getImm() ==
true) {
137 BuildMI(&mbb, dl, get(TCE::TCEBRCOND)).addReg(cond[0].getReg())
149 "Two jumps need a condition");
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);
162 BuildMI(&mbb, dl, get(TCE::TCEBR)).addMBB(fbb);
175 MachineBasicBlock &mbb,
int *BytesRemoved)
const {
177 MachineBasicBlock::iterator i = mbb.end();
178 while (i != mbb.begin()) {
180 int opc = i->getOpcode();
181 if (i->getDesc().isBranch()) {
182 i->eraseFromParent();
198 if (MBB.empty())
return false;
199 switch (MBB.back().getOpcode()) {
204 default:
return false;
210 unsigned SrcReg,
bool isKill,
int FI,
211 const TargetRegisterClass *RC)
const {
214 if (I != MBB.end()) DL = I->getDebugLoc();
216 BuildMI(MBB, I, DL, get(
plugin_->
getStore(RC))).addFrameIndex(FI).addImm(0)
217 .addReg(SrcReg, getKillRegState(isKill));
219 LLVMContext& context = MBB.getParent()->getFunction().getContext();
220 llvm::Metadata* md = llvm::MDString::get(context,
"AA_CATEGORY_STACK_SLOT");
222 MDNode::get(context, llvm::ArrayRef<llvm::Metadata*>(&md, 1));
223 MachineOperand metaDataOperand = MachineOperand::CreateMetadata(mdNode);
225 I->addOperand(metaDataOperand);
230 unsigned DestReg,
int FI,
231 const TargetRegisterClass *RC)
const {
234 if (I != MBB.end()) DL = I->getDebugLoc();
235 BuildMI(MBB, I, DL, get(
plugin_->
getLoad(RC)), DestReg).addFrameIndex(FI)
238 LLVMContext& context = MBB.getParent()->getFunction().getContext();
239 llvm::Metadata* md = llvm::MDString::get(context,
"AA_CATEGORY_STACK_SLOT");
241 MDNode::get(context, llvm::ArrayRef<llvm::Metadata*>(&md, 1));
242 MachineOperand metaDataOperand = MachineOperand::CreateMetadata(mdNode);
244 I->addOperand(metaDataOperand);
257 MachineBasicBlock& mbb,
258 MachineBasicBlock::iterator mbbi,
260 MCRegister destReg, MCRegister srcReg,
264 if (mbbi != mbb.end()) dl = mbbi->getDebugLoc();
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));
318 false &&
"TCERegisterInfo::copyPhysReg(): Can't copy register");
332 llvm::SmallVectorImpl<llvm::MachineOperand>& cond)
const {
336 if (cond.size() == 1) {
337 cond.push_back(MachineOperand::CreateImm(
false));
339 }
else if (cond.size() == 2) {
341 if (cond[1].getImm() ==
false) {
342 cond[1].setImm(
true);
345 assert(cond[1].getImm() ==
true);
346 cond[1].setImm(
false);
349 }
else if (cond.size() == 3) {
350 switch (cond[2].getImm()) {
450 MachineBasicBlock &mbb, MachineBasicBlock *&tbb,
451 MachineBasicBlock *&fbb,
452 llvm::SmallVectorImpl<llvm::MachineOperand>& cond,
bool allowModify)
458 MachineBasicBlock::iterator i = mbb.end(); i--;
460 MachineInstr& lastIns = *i;
461 switch (lastIns.getOpcode()) {
463 tbb = lastIns.getOperand(1).getMBB();
464 cond.push_back(i->getOperand(0));
465 cond.push_back(MachineOperand::CreateImm(
true));
467 case TCE::TCEBRICOND:
468 tbb = lastIns.getOperand(1).getMBB();
469 cond.push_back(i->getOperand(0));
470 cond.push_back(MachineOperand::CreateImm(
false));
475 if (!lastIns.getOperand(0).isMBB()) {
479 if (i == mbb.begin()) {
480 tbb = lastIns.getOperand(0).getMBB();
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));
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));
499 assert(i->getOpcode() != TCE::TCEBR);
501 if (i->getDesc().isBranch()) {
502 tbb = i->getOperand(2).getMBB();
503 fbb = lastIns.getOperand(0).getMBB();
506 tbb = lastIns.getOperand(0).getMBB();
513 if (lastIns.getDesc().isBranch()) {
514 tbb = lastIns.getOperand(2).getMBB();
525 class TCEPipelinerLoopInfo :
public TargetInstrInfo::PipelinerLoopInfo {
527 TCEPipelinerLoopInfo() {}
529 shouldIgnoreForPipelining(
const MachineInstr *MI)
const override {
539 createTripCountGreaterCondition(
540 int TC, MachineBasicBlock &MBB,
541 SmallVectorImpl<MachineOperand> &Cond)
override {
545 void setPreheader(MachineBasicBlock *NewPreheader)
override{};
547 void adjustTripCount(
int TripCountAdjust)
override{};
549 void disposed()
override{};
553 std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo>
555 return std::make_unique<TCEPipelinerLoopInfo>();
560 const MachineInstr* mi = &mi_ref;
562 if (mi->getOpcode() == TCE::RETL) {
567 if (mi->getOpcode() == TCE::KILL) {
572 return opName[0] ==
'?' || opName[0] ==
'!';
577 const MachineInstr* mi = &mi_ref;
578 if (mi->getOpcode() == TCE::COPY) {
583 if (mi->getOpcode() == TCE::RETL) {
595 for (
int oper = mi->getNumOperands() - 1; oper >= 0; --oper) {
596 MachineOperand mo = mi->getOperand(oper);
598 if ((mo.isReg() && !mo.isUse() && !mo.isImplicit())) {
603 if (!mo.isReg() && !mo.isImm()) {
613 MachineInstr& mi_ref,
614 ArrayRef<MachineOperand> cond
617 MachineInstr *mi = &mi_ref;
619 int opc = mi->getOpcode();
623 bool invertJump = (cond.size() >1 && cond[1].isImm() &&
624 (cond[1].getImm() == 0));
631 mi->addOperand(mi->getOperand(mi->getNumOperands()-1));
634 for (oper = mi->getNumOperands() - 2; oper >= 0; --oper) {
635 MachineOperand mo = mi->getOperand(oper);
637 if ((mo.isReg() && !mo.isUse() && !mo.isImplicit())) {
642 mi->getOperand(oper+1).ChangeToRegister(mo.getReg(), mo.isDef(),
643 mo.isImplicit(), mo.isKill(),
644 mo.isDead(), mo.isUndef(),
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()) {
652 llvm_unreachable(
"Unexpected operand type");
653 mi->getOperand(oper+1).ChangeToImmediate(mo.getImm());
655 llvm_unreachable(
"Unexpected operand type");
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(),
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) {
701 unsigned ExtraPredCycles,
702 BranchProbability Probability)
const {
711 unsigned ExtraTCycles,
712 MachineBasicBlock &FMBB,
714 unsigned ExtraFCycles,
715 BranchProbability Probability)
const {
727 const TargetSubtargetInfo &STI)
const {
728 const InstrItineraryData *II = STI.getInstrItineraryData();
730 static_cast<const TCESubtarget &
>(STI).createDFAPacketizer(II);