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