@@ -641,6 +641,145 @@ unsigned SparcInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
641641 return get (Opcode).getSize ();
642642}
643643
644+ bool SparcInstrInfo::analyzeCompare (const MachineInstr &MI, Register &SrcReg,
645+ Register &SrcReg2, int64_t &CmpMask,
646+ int64_t &CmpValue) const {
647+ Register DstReg;
648+ switch (MI.getOpcode ()) {
649+ default :
650+ break ;
651+ case SP::SUBCCri:
652+ DstReg = MI.getOperand (0 ).getReg ();
653+ SrcReg = MI.getOperand (1 ).getReg ();
654+ SrcReg2 = 0 ;
655+ CmpMask = ~0 ;
656+ CmpValue = MI.getOperand (2 ).getImm ();
657+ return DstReg == SP::G0 && CmpValue == 0 ;
658+ case SP::SUBCCrr:
659+ DstReg = MI.getOperand (0 ).getReg ();
660+ SrcReg = MI.getOperand (1 ).getReg ();
661+ SrcReg2 = MI.getOperand (2 ).getReg ();
662+ CmpMask = ~0 ;
663+ CmpValue = 0 ;
664+ return DstReg == SP::G0 && SrcReg2 == SP::G0;
665+ }
666+
667+ return false ;
668+ }
669+
670+ bool SparcInstrInfo::optimizeCompareInstr (
671+ MachineInstr &CmpInstr, Register SrcReg, Register SrcReg2, int64_t CmpMask,
672+ int64_t CmpValue, const MachineRegisterInfo *MRI) const {
673+
674+ // Get the unique definition of SrcReg.
675+ MachineInstr *MI = MRI->getUniqueVRegDef (SrcReg);
676+ if (!MI)
677+ return false ;
678+
679+ // Only optimize if defining and comparing instruction in same block.
680+ if (MI->getParent () != CmpInstr.getParent ())
681+ return false ;
682+
683+ unsigned NewOpcode;
684+ switch (MI->getOpcode ()) {
685+ case SP::ANDNrr:
686+ NewOpcode = SP::ANDNCCrr;
687+ break ;
688+ case SP::ANDNri:
689+ NewOpcode = SP::ANDNCCri;
690+ break ;
691+ case SP::ANDrr:
692+ NewOpcode = SP::ANDCCrr;
693+ break ;
694+ case SP::ANDri:
695+ NewOpcode = SP::ANDCCri;
696+ break ;
697+ case SP::ORrr:
698+ NewOpcode = SP::ORCCrr;
699+ break ;
700+ case SP::ORri:
701+ NewOpcode = SP::ORCCri;
702+ break ;
703+ case SP::ORNCCrr:
704+ NewOpcode = SP::ORNCCrr;
705+ break ;
706+ case SP::ORNri:
707+ NewOpcode = SP::ORNCCri;
708+ break ;
709+ case SP::XORrr:
710+ NewOpcode = SP::XORCCrr;
711+ break ;
712+ case SP::XNORri:
713+ NewOpcode = SP::XNORCCri;
714+ break ;
715+ case SP::XNORrr:
716+ NewOpcode = SP::XNORCCrr;
717+ break ;
718+ case SP::ADDrr:
719+ NewOpcode = SP::ADDCCrr;
720+ break ;
721+ case SP::ADDri:
722+ NewOpcode = SP::ADDCCri;
723+ break ;
724+ case SP::SUBrr:
725+ NewOpcode = SP::SUBCCrr;
726+ break ;
727+ case SP::SUBri:
728+ NewOpcode = SP::SUBCCri;
729+ break ;
730+ default :
731+ return false ;
732+ }
733+
734+ bool IsICCModified = false ;
735+ MachineBasicBlock::iterator I = MI;
736+ MachineBasicBlock::iterator C = CmpInstr;
737+ MachineBasicBlock::iterator E = CmpInstr.getParent ()->end ();
738+ const TargetRegisterInfo *TRI = &getRegisterInfo ();
739+
740+ // If ICC is used or modified between MI and CmpInstr we cannot optimize.
741+ while (++I != C) {
742+ if (I->modifiesRegister (SP::ICC, TRI) || I->readsRegister (SP::ICC, TRI))
743+ return false ;
744+ }
745+
746+ while (++I != E) {
747+ // Only allow conditionals on equality.
748+ if (I->readsRegister (SP::ICC, TRI)) {
749+ bool IsICCBranch = I->getOpcode () == SP::BCOND ||
750+ I->getOpcode () == SP::BPICC ||
751+ I->getOpcode () == SP::BPXCC;
752+ bool IsICCMove =
753+ I->getOpcode () == SP::MOVICCrr || I->getOpcode () == SP::MOVICCri ||
754+ I->getOpcode () == SP::MOVXCCrr || I->getOpcode () == SP::MOVXCCri;
755+ bool IsICCConditional = IsICCBranch || IsICCMove;
756+ if (!IsICCConditional ||
757+ (I->getOperand (IsICCBranch ? 1 : 3 ).getImm () != SPCC::ICC_E &&
758+ I->getOperand (IsICCBranch ? 1 : 3 ).getImm () != SPCC::ICC_NE))
759+ return false ;
760+ } else if (I->modifiesRegister (SP::ICC, TRI)) {
761+ IsICCModified = true ;
762+ break ;
763+ }
764+ }
765+
766+ if (!IsICCModified) {
767+ MachineBasicBlock *MBB = CmpInstr.getParent ();
768+ if (any_of (MBB->successors (),
769+ [](MachineBasicBlock *Succ) { return Succ->isLiveIn (SP::ICC); }))
770+ return false ;
771+ }
772+
773+ if (MRI->hasOneNonDBGUse (SrcReg))
774+ MI->getOperand (0 ).setReg (SP::G0);
775+
776+ MI->setDesc (get (NewOpcode));
777+ MI->addRegisterDefined (SP::ICC);
778+ CmpInstr.eraseFromParent ();
779+
780+ return true ;
781+ }
782+
644783bool SparcInstrInfo::expandPostRAPseudo (MachineInstr &MI) const {
645784 switch (MI.getOpcode ()) {
646785 case TargetOpcode::LOAD_STACK_GUARD: {
0 commit comments