<s> MachineInstr * PN = & * I ; assert ( PN -> getNumOperands ( ) == <NUM_LIT> && <STR_LIT> ) ; MachineOperand & UO = PN -> getOperand ( <NUM_LIT> ) ; unsigned UseR = UO . getReg ( ) , UseSR = UO . getSubReg ( ) ; unsigned DefR = PN -> getOperand ( <NUM_LIT> ) . getReg ( ) ; unsigned NewR = UseR ; if ( UseSR ) { const DebugLoc & DL = PN -> getDebugLoc ( ) ; const TargetRegisterClass * RC = MRI -> getRegClass ( DefR ) ; NewR = MRI -> createVirtualRegister ( RC ) ; NonPHI = BuildMI ( * B , NonPHI , DL , HII -> get ( TargetOpcode :: COPY ) , NewR ) . addReg ( UseR , <NUM_LIT> , UseSR ) ; } MRI -> replaceRegWith ( DefR , NewR ) ; B -> erase ( I ) ;


<s> unsigned DefR = PN -> getOperand ( <NUM_LIT> ) . getReg ( ) ; unsigned NewR = UseR ; if ( UseSR ) { const DebugLoc & DL = PN -> getDebugLoc ( ) ; const TargetRegisterClass * RC = MRI -> getRegClass ( DefR ) ; NewR = MRI -> createVirtualRegister ( RC ) ; NonPHI = BuildMI ( * B , NonPHI , DL , HII -> get ( TargetOpcode :: COPY ) , NewR ) . addReg ( UseR , <NUM_LIT> , UseSR ) ; } MRI -> replaceRegWith ( DefR , NewR ) ; B -> erase ( I ) ; }


<s> for ( auto & MI : * B ) { if ( MI . isDebugInstr ( ) ) continue ; if ( MI . isConditionalBranch ( ) ) return false ; unsigned Opc = MI . getOpcode ( ) ; bool IsJMP = ( Opc == <STR_LIT> ) ; if ( ! isPredicableStore ( & MI ) && ! IsJMP && ! isSafeToSpeculate ( & MI ) ) return false ; for ( const MachineOperand & MO : MI . operands ( ) ) { if ( ! MO . isReg ( ) || ! MO . isDef ( ) ) continue ; unsigned R = MO . getReg ( ) ; if ( ! TargetRegisterInfo :: isVirtualRegister ( R ) ) continue ;


<s> if ( ! B ) return true ; if ( B -> isEHPad ( ) || B -> hasAddressTaken ( ) ) return false ; if ( B -> succ_size ( ) == <NUM_LIT> ) return false ; for ( auto & MI : * B ) { if ( MI . isDebugInstr ( ) ) continue ; if ( MI . isConditionalBranch ( ) ) return false ; unsigned Opc = MI . getOpcode ( ) ; bool IsJMP = ( Opc == <STR_LIT> ) ; if ( ! isPredicableStore ( & MI ) && ! IsJMP && ! isSafeToSpeculate ( & MI ) ) return false ; for ( const MachineOperand & MO : MI . operands ( ) ) { if ( ! MO . isReg ( ) || ! MO . isDef ( ) ) continue ; unsigned R = MO . getReg ( ) ; if ( ! TargetRegisterInfo :: isVirtualRegister ( R ) ) continue ;


<s> unsigned TNS = TB -> succ_size ( ) , FNS = FB -> succ_size ( ) ; bool TOk = ( TNP == <NUM_LIT> && TNS == <NUM_LIT> && MLI -> getLoopFor ( TB ) == L ) ; bool FOk = ( FNP == <NUM_LIT> && FNS == <NUM_LIT> && MLI -> getLoopFor ( FB ) == L ) ; if ( SkipExitBranches && MLI -> getLoopFor ( TB ) != MLI -> getLoopFor ( FB ) ) return false ; if ( ! TOk && ! FOk ) return false ; MachineBasicBlock * TSB = ( TNS > <NUM_LIT> ) ? * TB -> succ_begin ( ) : nullptr ; MachineBasicBlock * FSB = ( FNS > <NUM_LIT> ) ? * FB -> succ_begin ( ) : nullptr ; MachineBasicBlock * JB = nullptr ; if ( TOk ) { if ( FOk ) { if ( TSB == FSB ) JB = TSB ; } else { if ( TSB == FB ) JB = FB ; FB = nullptr ; } } else { if ( FSB == TB ) JB = TB ; TB = nullptr ;


<s> return false ; } if ( Opc == <STR_LIT> ) TB = T1B , FB = T2B ; else TB = T2B , FB = T1B ; if ( ! MDT -> properlyDominates ( B , TB ) || ! MDT -> properlyDominates ( B , FB ) ) return false ; unsigned TNP = TB -> pred_size ( ) , FNP = FB -> pred_size ( ) ; unsigned TNS = TB -> succ_size ( ) , FNS = FB -> succ_size ( ) ; bool TOk = ( TNP == <NUM_LIT> && TNS == <NUM_LIT> && MLI -> getLoopFor ( TB ) == L ) ; bool FOk = ( FNP == <NUM_LIT> && FNS == <NUM_LIT> && MLI -> getLoopFor ( FB ) == L ) ; if ( SkipExitBranches && MLI -> getLoopFor ( TB ) != MLI -> getLoopFor ( FB ) ) return false ; if ( ! TOk && ! FOk ) return false ; MachineBasicBlock * TSB = ( TNS > <NUM_LIT> ) ? * TB -> succ_begin ( ) : nullptr ; MachineBasicBlock * FSB = ( FNS > <NUM_LIT> ) ? * FB -> succ_begin ( ) : nullptr ; MachineBasicBlock * JB = nullptr ; if ( TOk ) { if ( FOk ) { if ( TSB == FSB ) JB = TSB ; } else { if ( TSB == FB ) JB = FB ; FB = nullptr ;


<s> unsigned Opc = MI . getOpcode ( ) ; bool IsJMP = ( Opc == <STR_LIT> ) ; if ( ! isPredicableStore ( & MI ) && ! IsJMP && ! isSafeToSpeculate ( & MI ) ) return false ; for ( const MachineOperand & MO : MI . operands ( ) ) { if ( ! MO . isReg ( ) || ! MO . isDef ( ) ) continue ; Register R = MO . getReg ( ) ; if ( ! R . isVirtual ( ) ) continue ; if ( ! isPredicate ( R ) ) continue ; for ( auto U = MRI -> use_begin ( R ) ; U != MRI -> use_end ( ) ; ++ U ) if ( U -> getParent ( ) -> isPHI ( ) ) return false ; }


<s> if ( B -> pred_size ( ) < <NUM_LIT> ) return <NUM_LIT> ; unsigned Cost = <NUM_LIT> ; MachineBasicBlock :: const_iterator I , E = B -> getFirstNonPHI ( ) ; for ( I = B -> begin ( ) ; I != E ; ++ I ) { const MachineOperand & RO1 = I -> getOperand ( <NUM_LIT> ) ; const MachineOperand & RO3 = I -> getOperand ( <NUM_LIT> ) ; assert ( RO1 . isReg ( ) && RO3 . isReg ( ) ) ; if ( RO1 . getSubReg ( ) != <NUM_LIT> || RO3 . getSubReg ( ) != <NUM_LIT> ) { Cost ++ ; continue ; } MachineInstr * Def1 = MRI -> getVRegDef ( RO1 . getReg ( ) ) ; MachineInstr * Def3 = MRI -> getVRegDef ( RO3 . getReg ( ) ) ; if ( ! TII -> isPredicable ( * Def1 ) || ! TII -> isPredicable ( * Def3 ) ) Cost ++ ; } return Cost ;


<s> unsigned <ISA_LIT>EarlyIfConversion :: computePhiCost ( MachineBasicBlock * B ) const { assert ( B -> pred_size ( ) <= <NUM_LIT> ) ; if ( B -> pred_size ( ) < <NUM_LIT> ) return <NUM_LIT> ; unsigned Cost = <NUM_LIT> ; MachineBasicBlock :: const_iterator I , E = B -> getFirstNonPHI ( ) ; for ( I = B -> begin ( ) ; I != E ; ++ I ) { const MachineOperand & RO1 = I -> getOperand ( <NUM_LIT> ) ; const MachineOperand & RO3 = I -> getOperand ( <NUM_LIT> ) ; assert ( RO1 . isReg ( ) && RO3 . isReg ( ) ) ;

if ( RO1 . getSubReg ( ) != <NUM_LIT> || RO3 . getSubReg ( ) != <NUM_LIT> ) {


<s> DebugLoc DL ; if ( At != ToB -> end ( ) ) DL = At -> getDebugLoc ( ) ; else if ( ! ToB -> empty ( ) ) DL = ToB -> back ( ) . getDebugLoc ( ) ; unsigned Opc = MI -> getOpcode ( ) ; if ( isPredicableStore ( MI ) ) { unsigned COpc = getCondStoreOpcode ( Opc , IfTrue ) ; assert ( COpc ) ; MachineInstrBuilder MIB = BuildMI ( * ToB , At , DL , TII -> get ( COpc ) ) . addReg ( PredR ) ; for ( MIOperands MO ( * MI ) ; MO . isValid ( ) ; ++ MO ) MIB . addOperand ( * MO ) ; MachineInstr :: mmo_iterator MMOBegin = MI -> memoperands_begin ( ) ; MachineInstr :: mmo_iterator MMOEnd = MI -> memoperands_end ( ) ; MIB . setMemRefs ( MMOBegin , MMOEnd ) ; MI -> eraseFromParent ( ) ; return ; } if ( Opc == <STR_LIT> ) { MachineBasicBlock * TB = MI -> getOperand ( <NUM_LIT> ) . getMBB ( ) ; const MCInstrDesc & D = TII -> get ( IfTrue ? <STR_LIT> : <STR_LIT> ) ; BuildMI ( * ToB , At , DL , D ) . addReg ( PredR ) . addMBB ( TB ) ; MI -> eraseFromParent ( ) ;


<s> MachineInstrBuilder MIB = BuildMI ( * ToB , At , DL , TII -> get ( COpc ) ) . addReg ( PredR ) ; for ( MIOperands MO ( * MI ) ; MO . isValid ( ) ; ++ MO ) MIB . addOperand ( * MO ) ; MachineInstr :: mmo_iterator MMOBegin = MI -> memoperands_begin ( ) ; MachineInstr :: mmo_iterator MMOEnd = MI -> memoperands_end ( ) ; MIB . setMemRefs ( MMOBegin , MMOEnd ) ;


<s> TRI = ST . getRegisterInfo ( ) ; MFN = & MF ; MRI = & MF . getRegInfo ( ) ; MDT = & getAnalysis < MachineDominatorTree > ( ) ; MLI = & getAnalysis < MachineLoopInfo > ( ) ; MBPI = Enable<ISA_LIT>BP ? & getAnalysis < MachineBranchProbabilityInfo > ( ) : nullptr ; Deleted . clear ( ) ;


<s> TII = ST . getInstrInfo ( ) ; TRI = ST . getRegisterInfo ( ) ; MFN = & MF ; MRI = & MF . getRegInfo ( ) ; MDT = & getAnalysis < MachineDominatorTree > ( ) ; MLI = & getAnalysis < MachineLoopInfo > ( ) ; MBPI = Enable<ISA_LIT>BP ? & getAnalysis < MachineBranchProbabilityInfo > ( ) : nullptr ; Deleted . clear ( ) ; bool Changed = false ; for ( MachineLoopInfo :: iterator I = MLI -> begin ( ) , E = MLI -> end ( ) ; I != E ; ++ I ) Changed |= visitLoop ( * I ) ;


<s> DEBUG ( dbgs ( ) << <STR_LIT> << PrintMB ( B ) << <STR_LIT> ) ; MachineDomTreeNode * N = MDT -> getNode ( B ) ; MachineDomTreeNode * IDN = N -> getIDom ( ) ; if ( IDN ) { MachineBasicBlock * IDB = IDN -> getBlock ( ) ; typedef GraphTraits < MachineDomTreeNode * > GTN ; typedef SmallVector < MachineDomTreeNode * , <NUM_LIT> > DTNodeVectType ; DTNodeVectType Cn ( GTN :: child_begin ( N ) , GTN :: child_end ( N ) ) ; for ( DTNodeVectType :: iterator I = Cn . begin ( ) , E = Cn . end ( ) ; I != E ; ++ I ) { MachineBasicBlock * SB = ( * I ) -> getBlock ( ) ; MDT -> changeImmediateDominator ( SB , IDB ) ; } }

while ( B -> succ_size ( ) > <NUM_LIT> ) B -> removeSuccessor ( B -> succ_begin ( ) ) ;


<s> } } while ( B -> succ_size ( ) > <NUM_LIT> ) B -> removeSuccessor ( B -> succ_begin ( ) ) ; for ( auto I = B -> pred_begin ( ) , E = B -> pred_end ( ) ; I != E ; ++ I ) ( * I ) -> removeSuccessor ( B ) ; Deleted . insert ( B ) ;


<s> DEBUG ( dbgs ( ) << <STR_LIT> << PrintMB ( B ) << <STR_LIT> ) ; MachineBasicBlock :: iterator I , NextI , NonPHI = B -> getFirstNonPHI ( ) ; for ( I = B -> begin ( ) ; I != NonPHI ; I = NextI ) { NextI = std :: next ( I ) ; MachineInstr * PN = & * I ;

assert ( PN -> getNumOperands ( ) == <NUM_LIT> && <STR_LIT> ) ;


<s> MachineBasicBlock :: iterator At = FP . SplitB -> getFirstTerminator ( ) ; predicateBlockNB ( FP . SplitB , At , FP . FalseB , FP . PredR , false ) ; } MachineBasicBlock * SSB = <NUM_LIT> ; FP . SplitB -> erase ( OldTI , FP . SplitB -> end ( ) ) ; while ( FP . SplitB -> succ_size ( ) > <NUM_LIT> ) { MachineBasicBlock * T = * FP . SplitB -> succ_begin ( ) ; if ( T != FP . TrueB && T != FP . FalseB ) { assert ( ! SSB ) ; SSB = T ; } FP . SplitB -> removeSuccessor ( FP . SplitB -> succ_begin ( ) ) ; } if ( FP . JoinB ) { assert ( ! SSB || SSB == FP . JoinB ) ; BuildMI ( * FP . SplitB , FP . SplitB -> end ( ) , DL , HII -> get ( <STR_LIT> ) ) . addMBB ( FP . JoinB ) ; FP . SplitB -> addSuccessor ( FP . JoinB ) ; } else { bool HasBranch = false ; if ( TSB ) { BuildMI ( * FP . SplitB , FP . SplitB -> end ( ) , DL , HII -> get ( <STR_LIT> ) ) . addReg ( FP . PredR ) . addMBB ( TSB ) ; FP . SplitB -> addSuccessor ( TSB ) ; HasBranch = true ; } if ( FSB ) { const MCInstrDesc & D = HasBranch ? HII -> get ( <STR_LIT> ) : HII -> get ( <STR_LIT> ) ; MachineInstrBuilder MIB = BuildMI ( * FP . SplitB , FP . SplitB -> end ( ) , DL , D ) ; if ( ! HasBranch ) MIB . addReg ( FP . PredR ) ; MIB . addMBB ( FSB ) ; FP . SplitB -> addSuccessor ( FSB ) ; } if ( SSB ) { BuildMI ( * FP . SplitB , FP . SplitB -> end ( ) , DL , HII -> get ( <STR_LIT> ) ) . addMBB ( SSB ) ; FP . SplitB -> addSuccessor ( SSB ) ; } } if ( FP . JoinB ) { updatePhiNodes ( FP . JoinB , FP ) ; } else {

if ( TSB ) updatePhiNodes ( TSB , FP ) ;


<s> SSB = T ; } FP . SplitB -> removeSuccessor ( FP . SplitB -> succ_begin ( ) ) ; } if ( FP . JoinB ) { assert ( ! SSB || SSB == FP . JoinB ) ; BuildMI ( * FP . SplitB , FP . SplitB -> end ( ) , DL , HII -> get ( <STR_LIT> ) ) . addMBB ( FP . JoinB ) ; FP . SplitB -> addSuccessor ( FP . JoinB ) ; } else { bool HasBranch = false ; if ( TSB ) { BuildMI ( * FP . SplitB , FP . SplitB -> end ( ) , DL , HII -> get ( <STR_LIT> ) ) . addReg ( FP . PredR ) . addMBB ( TSB ) ; FP . SplitB -> addSuccessor ( TSB ) ; HasBranch = true ; } if ( FSB ) { const MCInstrDesc & D = HasBranch ? HII -> get ( <STR_LIT> ) : HII -> get ( <STR_LIT> ) ; MachineInstrBuilder MIB = BuildMI ( * FP . SplitB , FP . SplitB -> end ( ) , DL , D ) ;

if ( ! HasBranch ) MIB . addReg ( FP . PredR ) ;


<s> for ( auto & MI : * B ) { for ( ConstMIOperands MO ( MI ) ; MO . isValid ( ) ; ++ MO ) { if ( ! MO -> isReg ( ) || ! MO -> isDef ( ) ) continue ; unsigned R = MO -> getReg ( ) ; if ( ! TargetRegisterInfo :: isVirtualRegister ( R ) ) continue ; if ( MRI -> getRegClass ( R ) == & <STR_LIT> ) PredDefs ++ ; } } return PredDefs ;


<s> <ISA_LIT>EarlyIfConversion ( ) : MachineFunctionPass ( ID ) , HII ( <NUM_LIT> ) , TRI ( <NUM_LIT> ) , MFN ( <NUM_LIT> ) , MRI ( <NUM_LIT> ) , MDT ( <NUM_LIT> ) , MLI ( <NUM_LIT> ) {


<s> if ( MI . isDebugValue ( ) ) continue ; if ( MI . isConditionalBranch ( ) ) return false ; unsigned Opc = MI . getOpcode ( ) ; bool IsJMP = ( Opc == <STR_LIT> ) ; if ( ! isPredicableStore ( & MI ) && ! IsJMP && ! isSafeToSpeculate ( & MI ) ) return false ; for ( ConstMIOperands MO ( MI ) ; MO . isValid ( ) ; ++ MO ) { if ( ! MO -> isReg ( ) || ! MO -> isDef ( ) ) continue ;


<s> if ( MI . isConditionalBranch ( ) ) return false ; unsigned Opc = MI . getOpcode ( ) ; bool IsJMP = ( Opc == <STR_LIT> ) ; if ( ! isPredicableStore ( & MI ) && ! IsJMP && ! isSafeToSpeculate ( & MI ) ) return false ; for ( ConstMIOperands MO ( MI ) ; MO . isValid ( ) ; ++ MO ) { if ( ! MO -> isReg ( ) || ! MO -> isDef ( ) ) continue ; unsigned R = MO -> getReg ( ) ; if ( ! TargetRegisterInfo :: isVirtualRegister ( R ) ) continue ; if ( MRI -> getRegClass ( R ) != & <STR_LIT> ) continue ; for ( auto U = MRI -> use_begin ( R ) ; U != MRI -> use_end ( ) ; ++ U ) if ( U -> getParent ( ) -> isPHI ( ) ) return false ;


<s> void <ISA_LIT>EarlyIfConversion :: mergeBlocks ( MachineBasicBlock * PredB , MachineBasicBlock * SuccB ) { DEBUG ( dbgs ( ) << <STR_LIT> << PrintMB ( PredB ) << <STR_LIT> << PrintMB ( SuccB ) << <STR_LIT> ) ; bool TermOk = hasUncondBranch ( SuccB ) ; eliminatePhis ( SuccB ) ; HII -> RemoveBranch ( * PredB ) ; PredB -> removeSuccessor ( SuccB ) ; PredB -> splice ( PredB -> end ( ) , SuccB , SuccB -> begin ( ) , SuccB -> end ( ) ) ; MachineBasicBlock :: succ_iterator I , E = SuccB -> succ_end ( ) ; for ( I = SuccB -> succ_begin ( ) ; I != E ; ++ I ) PredB -> addSuccessor ( * I ) ; PredB -> normalizeSuccProbs ( ) ; replacePhiEdges ( SuccB , PredB ) ; removeBlock ( SuccB ) ; if ( ! TermOk ) PredB -> updateTerminator ( ) ;


<s> for ( ; MO . isValid ( ) ; ++ MO ) MIB . addOperand ( * MO ) ; MachineInstr :: mmo_iterator MMOBegin = MI -> memoperands_begin ( ) ; MachineInstr :: mmo_iterator MMOEnd = MI -> memoperands_end ( ) ; MIB . setMemRefs ( MMOBegin , MMOEnd ) ; MI -> eraseFromParent ( ) ; return ; } if ( Opc == <STR_LIT> ) { MachineBasicBlock * TB = MI -> getOperand ( <NUM_LIT> ) . getMBB ( ) ; const MCInstrDesc & D = HII -> get ( IfTrue ? <STR_LIT> : <STR_LIT> ) ;

BuildMI ( * ToB , At , DL , D ) . addReg ( PredR ) . addMBB ( TB ) ;


<s> ++ MO ; } MIB . addReg ( PredR ) ; for ( ; MO . isValid ( ) ; ++ MO ) MIB . addOperand ( * MO ) ; MachineInstr :: mmo_iterator MMOBegin = MI -> memoperands_begin ( ) ; MachineInstr :: mmo_iterator MMOEnd = MI -> memoperands_end ( ) ; MIB . setMemRefs ( MMOBegin , MMOEnd ) ; MI -> eraseFromParent ( ) ; return ; } if ( Opc == <STR_LIT> ) { MachineBasicBlock * TB = MI -> getOperand ( <NUM_LIT> ) . getMBB ( ) ; const MCInstrDesc & D = HII -> get ( IfTrue ? <STR_LIT> : <STR_LIT> ) ; BuildMI ( * ToB , At , DL , D ) . addReg ( PredR ) . addMBB ( TB ) ;


<s> MachineInstr & PN = * P ; for ( MIOperands MO ( PN ) ; MO . isValid ( ) ; ++ MO ) if ( MO -> isMBB ( ) && MO -> getMBB ( ) == OldB ) MO -> setMBB ( NewB ) ; }


<s> bool <ISA_LIT>EarlyIfConversion :: runOnMachineFunction ( MachineFunction & MF ) { if ( skipFunction ( * MF . getFunction ( ) ) ) return false ; auto & ST = MF . getSubtarget < <ISA_LIT>Subtarget > ( ) ; HII = ST . getInstrInfo ( ) ; TRI = ST . getRegisterInfo ( ) ; MFN = & MF ; MRI = & MF . getRegInfo ( ) ; MDT = & getAnalysis < MachineDominatorTree > ( ) ; MLI = & getAnalysis < MachineLoopInfo > ( ) ; MBPI = Enable<ISA_LIT>BP ? & getAnalysis < MachineBranchProbabilityInfo > ( ) : nullptr ; Deleted . clear ( ) ; bool Changed = false ; for ( MachineLoopInfo :: iterator I = MLI -> begin ( ) , E = MLI -> end ( ) ; I != E ; ++ I ) Changed |= visitLoop ( * I ) ;


<s> bool <ISA_LIT>EarlyIfConversion :: usesUndefVReg ( const MachineInstr * MI ) const { for ( ConstMIOperands MO ( * MI ) ; MO . isValid ( ) ; ++ MO ) { if ( ! MO -> isReg ( ) || ! MO -> isUse ( ) ) continue ;


<s> DEBUG ( dbgs ( ) << <STR_LIT> << TotalIn << <STR_LIT> << Spare << <STR_LIT> ) ; if ( TotalIn >= SizeLimit + Spare ) return false ; unsigned TotalPh = <NUM_LIT> ; unsigned PredDefs = countPredicateDefs ( FP . SplitB ) ; if ( FP . JoinB ) { TotalPh = computePhiCost ( FP . JoinB , FP ) ; PredDefs += countPredicateDefs ( FP . JoinB ) ; } else { if ( FP . TrueB && FP . TrueB -> succ_size ( ) > <NUM_LIT> ) { MachineBasicBlock * SB = * FP . TrueB -> succ_begin ( ) ; TotalPh += computePhiCost ( SB , FP ) ; PredDefs += countPredicateDefs ( SB ) ; } if ( FP . FalseB && FP . FalseB -> succ_size ( ) > <NUM_LIT> ) { MachineBasicBlock * SB = * FP . FalseB -> succ_begin ( ) ; TotalPh += computePhiCost ( SB , FP ) ; PredDefs += countPredicateDefs ( SB ) ; } } DEBUG ( dbgs ( ) << <STR_LIT> << TotalPh << <STR_LIT> ) ; if ( TotalIn + TotalPh >= SizeLimit + Spare ) return false ;

DEBUG ( dbgs ( ) << <STR_LIT> << PredDefs << <STR_LIT> ) ;


<s> if ( MI . isDebugValue ( ) ) continue ; if ( MI . isConditionalBranch ( ) ) return false ; unsigned Opc = MI . getOpcode ( ) ; bool IsJMP = ( Opc == <STR_LIT> ) ; if ( ! isPredicableStore ( & MI ) && ! IsJMP && ! isSafeToSpeculate ( & MI ) ) return false ; for ( const MachineOperand & MO : MI . operands ( ) ) {

if ( ! MO . isReg ( ) || ! MO . isDef ( ) ) continue ;


<s> bool TermOk = hasUncondBranch ( SuccB ) ; eliminatePhis ( SuccB ) ; HII -> removeBranch ( * PredB ) ; PredB -> removeSuccessor ( SuccB ) ; PredB -> splice ( PredB -> end ( ) , SuccB , SuccB -> begin ( ) , SuccB -> end ( ) ) ; PredB -> transferSuccessorsAndUpdatePHIs ( SuccB ) ; removeBlock ( SuccB ) ;

if ( ! TermOk ) PredB -> updateTerminator ( ) ;


<s> void <ISA_LIT>EarlyIfConversion :: mergeBlocks ( MachineBasicBlock * PredB , MachineBasicBlock * SuccB ) { DEBUG ( dbgs ( ) << <STR_LIT> << PrintMB ( PredB ) << <STR_LIT> << PrintMB ( SuccB ) << <STR_LIT> ) ; bool TermOk = hasUncondBranch ( SuccB ) ; eliminatePhis ( SuccB ) ;


<s> for ( DTNodeVectType :: iterator I = Cn . begin ( ) , E = Cn . end ( ) ; I != E ; ++ I ) { MachineBasicBlock * SB = ( * I ) -> getBlock ( ) ; MDT -> changeImmediateDominator ( SB , IDB ) ; } } while ( B -> succ_size ( ) > <NUM_LIT> ) B -> removeSuccessor ( B -> succ_begin ( ) ) ;

for ( auto I = B -> pred_begin ( ) , E = B -> pred_end ( ) ; I != E ; ++ I ) ( * I ) -> removeSuccessor ( B ) ;


<s> typedef SmallVector < MachineDomTreeNode * , <NUM_LIT> > DTNodeVectType ; DTNodeVectType Cn ( GTN :: child_begin ( N ) , GTN :: child_end ( N ) ) ; for ( DTNodeVectType :: iterator I = Cn . begin ( ) , E = Cn . end ( ) ; I != E ; ++ I ) { MachineBasicBlock * SB = ( * I ) -> getBlock ( ) ; MDT -> changeImmediateDominator ( SB , IDB ) ; } } while ( B -> succ_size ( ) > <NUM_LIT> ) B -> removeSuccessor ( B -> succ_begin ( ) ) ; for ( auto I = B -> pred_begin ( ) , E = B -> pred_end ( ) ; I != E ; ++ I ) ( * I ) -> removeSuccessor ( B ) ; Deleted . insert ( B ) ; MDT -> eraseNode ( B ) ; MachineFunction :: iterator BI = B ;


<s> void <ISA_LIT>ELFDynamic :: applyTargetEntries ( const ELFFileFormat & pFormat ) { if ( pFormat . hasGOTPLT ( ) ) applyOne ( llvm :: ELF :: DT_PLTGOT , pFormat . getGOTPLT ( ) . addr ( ) ) ;


<s> <ISA_LIT>ELFDynamic :: <ISA_LIT>ELFDynamic ( const GNULDBackend & pParent , const LinkerConfig & pConfig ) : ELFDynamic ( pParent , pConfig ) {


<s> if ( pFormat . hasGOTPLT ( ) ) reserveOne ( llvm :: ELF :: DT_PLTGOT ) ;


<s> <ISA_LIT>ELFDynamic :: ~ <ISA_LIT>ELFDynamic ( ) {


<s> MCObjectWriter * llvm :: create<ISA_LIT>ELFObjectWriter ( raw_ostream & OS , uint8_t OSABI , StringRef CPU ) { MCELFObjectTargetWriter * MOTW = new <ISA_LIT>ELFObjectWriter ( OSABI , CPU ) ; return createELFObjectWriter ( MOTW , OS , true ) ;


<s> MCObjectWriter * llvm :: create<ISA_LIT>ELFObjectWriter ( raw_ostream & OS , uint8_t OSABI , StringRef CPU ) {

MCELFObjectTargetWriter * MOTW = new <ISA_LIT>ELFObjectWriter ( OSABI , CPU ) ;


<s> std :: unique_ptr < MCObjectTargetWriter > llvm :: create<ISA_LIT>ELFObjectWriter ( uint8_t OSABI , StringRef CPU ) { return std :: make_unique < <ISA_LIT>ELFObjectWriter > ( OSABI , CPU ) ;


<s> case fixup_<ISA_LIT>_LD_GOT_HI16 : return ELF :: R_HEX_LD_GOT_HI16 ; case fixup_<ISA_LIT>_LD_GOT_32 : return ELF :: R_HEX_LD_GOT_32 ; case fixup_<ISA_LIT>_LD_GOT_16 : return ELF :: R_HEX_LD_GOT_16 ; case fixup_<ISA_LIT>_IE_LO16 : return ELF :: R_HEX_IE_LO16 ; case fixup_<ISA_LIT>_IE_HI16 : return ELF :: R_HEX_IE_HI16 ; case fixup_<ISA_LIT>_IE_32 : return ELF :: R_HEX_IE_32 ; case fixup_<ISA_LIT>_IE_GOT_LO16 : return ELF :: R_HEX_IE_GOT_LO16 ; case fixup_<ISA_LIT>_IE_GOT_HI16 : return ELF :: R_HEX_IE_GOT_HI16 ; case fixup_<ISA_LIT>_IE_GOT_32 : return ELF :: R_HEX_IE_GOT_32 ; case fixup_<ISA_LIT>_IE_GOT_16 : return ELF :: R_HEX_IE_GOT_16 ; case fixup_<ISA_LIT>_TPREL_LO16 : return ELF :: R_HEX_TPREL_LO16 ; case fixup_<ISA_LIT>_TPREL_HI16 : return ELF :: R_HEX_TPREL_HI16 ; case fixup_<ISA_LIT>_TPREL_32 : return ELF :: R_HEX_TPREL_32 ; case fixup_<ISA_LIT>_TPREL_16 : return ELF :: R_HEX_TPREL_16 ; case fixup_<ISA_LIT>_6_PCREL_X : return ELF :: R_HEX_6_PCREL_X ; case fixup_<ISA_LIT>_GOTREL_32_6_X : return ELF :: R_HEX_GOTREL_32_6_X ; case fixup_<ISA_LIT>_GOTREL_16_X : return ELF :: R_HEX_GOTREL_16_X ; case fixup_<ISA_LIT>_GOTREL_11_X : return ELF :: R_HEX_GOTREL_11_X ; case fixup_<ISA_LIT>_GOT_32_6_X : return ELF :: R_HEX_GOT_32_6_X ; case fixup_<ISA_LIT>_GOT_16_X : return ELF :: R_HEX_GOT_16_X ; case fixup_<ISA_LIT>_GOT_11_X : return ELF :: R_HEX_GOT_11_X ; case fixup_<ISA_LIT>_DTPREL_32_6_X : return ELF :: R_HEX_DTPREL_32_6_X ; case fixup_<ISA_LIT>_DTPREL_16_X : return ELF :: R_HEX_DTPREL_16_X ; case fixup_<ISA_LIT>_DTPREL_11_X : return ELF :: R_HEX_DTPREL_11_X ; case fixup_<ISA_LIT>_GD_GOT_32_6_X : return ELF :: R_HEX_GD_GOT_32_6_X ; case fixup_<ISA_LIT>_GD_GOT_16_X : return ELF :: R_HEX_GD_GOT_16_X ; case fixup_<ISA_LIT>_GD_GOT_11_X : return ELF :: R_HEX_GD_GOT_11_X ; case fixup_<ISA_LIT>_LD_GOT_32_6_X : return ELF :: R_HEX_LD_GOT_32_6_X ; case fixup_<ISA_LIT>_LD_GOT_16_X : return ELF :: R_HEX_LD_GOT_16_X ; case fixup_<ISA_LIT>_LD_GOT_11_X : return ELF :: R_HEX_LD_GOT_11_X ; case fixup_<ISA_LIT>_IE_32_6_X : return ELF :: R_HEX_IE_32_6_X ; case fixup_<ISA_LIT>_IE_16_X : return ELF :: R_HEX_IE_16_X ; case fixup_<ISA_LIT>_IE_GOT_32_6_X : return ELF :: R_HEX_IE_GOT_32_6_X ; case fixup_<ISA_LIT>_IE_GOT_16_X : return ELF :: R_HEX_IE_GOT_16_X ; case fixup_<ISA_LIT>_IE_GOT_11_X : return ELF :: R_HEX_IE_GOT_11_X ; case fixup_<ISA_LIT>_TPREL_32_6_X : return ELF :: R_HEX_TPREL_32_6_X ; case fixup_<ISA_LIT>_TPREL_16_X : return ELF :: R_HEX_TPREL_16_X ; case fixup_<ISA_LIT>_TPREL_11_X : return ELF :: R_HEX_TPREL_11_X ; case fixup_<ISA_LIT>_23_REG : return ELF :: R_HEX_23_REG ; case fixup_<ISA_LIT>_27_REG : return ELF :: R_HEX_27_REG ; case fixup_<ISA_LIT>_GD_PLT_B22_PCREL_X : return ELF :: R_HEX_GD_PLT_B22_PCREL_X ; case fixup_<ISA_LIT>_GD_PLT_B32_PCREL_X : return ELF :: R_HEX_GD_PLT_B32_PCREL_X ; case fixup_<ISA_LIT>_LD_PLT_B22_PCREL_X : return ELF :: R_HEX_LD_PLT_B22_PCREL_X ;


<s> case fixup_<ISA_LIT>_DTPREL_LO16 : return ELF :: R_HEX_DTPREL_LO16 ; case fixup_<ISA_LIT>_DTPREL_HI16 : return ELF :: R_HEX_DTPREL_HI16 ; case fixup_<ISA_LIT>_DTPREL_32 : return ELF :: R_HEX_DTPREL_32 ; case fixup_<ISA_LIT>_DTPREL_16 : return ELF :: R_HEX_DTPREL_16 ; case fixup_<ISA_LIT>_GD_PLT_B22_PCREL : return ELF :: R_HEX_GD_PLT_B22_PCREL ; case fixup_<ISA_LIT>_LD_PLT_B22_PCREL : return ELF :: R_HEX_LD_PLT_B22_PCREL ; case fixup_<ISA_LIT>_GD_GOT_LO16 : return ELF :: R_HEX_GD_GOT_LO16 ; case fixup_<ISA_LIT>_GD_GOT_HI16 : return ELF :: R_HEX_GD_GOT_HI16 ; case fixup_<ISA_LIT>_GD_GOT_32 : return ELF :: R_HEX_GD_GOT_32 ; case fixup_<ISA_LIT>_GD_GOT_16 : return ELF :: R_HEX_GD_GOT_16 ; case fixup_<ISA_LIT>_LD_GOT_LO16 : return ELF :: R_HEX_LD_GOT_LO16 ; case fixup_<ISA_LIT>_LD_GOT_HI16 : return ELF :: R_HEX_LD_GOT_HI16 ; case fixup_<ISA_LIT>_LD_GOT_32 : return ELF :: R_HEX_LD_GOT_32 ; case fixup_<ISA_LIT>_LD_GOT_16 : return ELF :: R_HEX_LD_GOT_16 ; case fixup_<ISA_LIT>_IE_LO16 : return ELF :: R_HEX_IE_LO16 ; case fixup_<ISA_LIT>_IE_HI16 : return ELF :: R_HEX_IE_HI16 ; case fixup_<ISA_LIT>_IE_32 : return ELF :: R_HEX_IE_32 ; case fixup_<ISA_LIT>_IE_GOT_LO16 : return ELF :: R_HEX_IE_GOT_LO16 ; case fixup_<ISA_LIT>_IE_GOT_HI16 : return ELF :: R_HEX_IE_GOT_HI16 ; case fixup_<ISA_LIT>_IE_GOT_32 : return ELF :: R_HEX_IE_GOT_32 ; case fixup_<ISA_LIT>_IE_GOT_16 : return ELF :: R_HEX_IE_GOT_16 ; case fixup_<ISA_LIT>_TPREL_LO16 : return ELF :: R_HEX_TPREL_LO16 ; case fixup_<ISA_LIT>_TPREL_HI16 : return ELF :: R_HEX_TPREL_HI16 ; case fixup_<ISA_LIT>_TPREL_32 : return ELF :: R_HEX_TPREL_32 ; case fixup_<ISA_LIT>_TPREL_16 : return ELF :: R_HEX_TPREL_16 ; case fixup_<ISA_LIT>_6_PCREL_X : return ELF :: R_HEX_6_PCREL_X ; case fixup_<ISA_LIT>_GOTREL_32_6_X : return ELF :: R_HEX_GOTREL_32_6_X ; case fixup_<ISA_LIT>_GOTREL_16_X : return ELF :: R_HEX_GOTREL_16_X ; case fixup_<ISA_LIT>_GOTREL_11_X : return ELF :: R_HEX_GOTREL_11_X ; case fixup_<ISA_LIT>_GOT_32_6_X : return ELF :: R_HEX_GOT_32_6_X ; case fixup_<ISA_LIT>_GOT_16_X : return ELF :: R_HEX_GOT_16_X ; case fixup_<ISA_LIT>_GOT_11_X : return ELF :: R_HEX_GOT_11_X ; case fixup_<ISA_LIT>_DTPREL_32_6_X : return ELF :: R_HEX_DTPREL_32_6_X ; case fixup_<ISA_LIT>_DTPREL_16_X : return ELF :: R_HEX_DTPREL_16_X ; case fixup_<ISA_LIT>_DTPREL_11_X : return ELF :: R_HEX_DTPREL_11_X ; case fixup_<ISA_LIT>_GD_GOT_32_6_X : return ELF :: R_HEX_GD_GOT_32_6_X ; case fixup_<ISA_LIT>_GD_GOT_16_X : return ELF :: R_HEX_GD_GOT_16_X ; case fixup_<ISA_LIT>_GD_GOT_11_X : return ELF :: R_HEX_GD_GOT_11_X ; case fixup_<ISA_LIT>_LD_GOT_32_6_X : return ELF :: R_HEX_LD_GOT_32_6_X ; case fixup_<ISA_LIT>_LD_GOT_16_X : return ELF :: R_HEX_LD_GOT_16_X ; case fixup_<ISA_LIT>_LD_GOT_11_X : return ELF :: R_HEX_LD_GOT_11_X ; case fixup_<ISA_LIT>_IE_32_6_X : return ELF :: R_HEX_IE_32_6_X ; case fixup_<ISA_LIT>_IE_16_X : return ELF :: R_HEX_IE_16_X ; case fixup_<ISA_LIT>_IE_GOT_32_6_X : return ELF :: R_HEX_IE_GOT_32_6_X ; case fixup_<ISA_LIT>_IE_GOT_16_X : return ELF :: R_HEX_IE_GOT_16_X ; case fixup_<ISA_LIT>_IE_GOT_11_X : return ELF :: R_HEX_IE_GOT_11_X ; case fixup_<ISA_LIT>_TPREL_32_6_X :


<s> MCELFObjectTargetWriter * MOTW = new <ISA_LIT>ELFObjectWriter ( OSABI , CPU ) ; return createELFObjectWriter ( MOTW , OS , true ) ;


<s> std :: unique_ptr < MCObjectTargetWriter > llvm :: create<ISA_LIT>ELFObjectWriter ( uint8_t OSABI , StringRef CPU ) {

return llvm :: make_unique < <ISA_LIT>ELFObjectWriter > ( OSABI , CPU ) ;


<s> return createELFObjectWriter ( std :: move ( MOTW ) , OS , true ) ;


<s> auto MOTW = llvm :: make_unique < <ISA_LIT>ELFObjectWriter > ( OSABI , CPU ) ; return createELFObjectWriter ( std :: move ( MOTW ) , OS , true ) ;


<s> <ISA_LIT>ELFObjectWriter :: <ISA_LIT>ELFObjectWriter ( uint8_t OSABI , StringRef C ) : MCELFObjectTargetWriter ( false , OSABI , ELF :: EM_HEXAGON , true ) , CPU ( C ) {


<s> return false ; } if ( pConfig . targets ( ) . triple ( ) . isOSWindows ( ) ) { assert ( <NUM_LIT> && <STR_LIT> ) ;


<s> } if ( pConfig . targets ( ) . triple ( ) . isOSWindows ( ) ) {


<s> static bool MCLDEmulate<ISA_LIT>ELF ( LinkerScript & pScript , LinkerConfig & pConfig ) { if ( ! MCLDEmulateELF ( pScript , pConfig ) ) return false ; pConfig . targets ( ) . setEndian ( TargetOptions :: Little ) ; pConfig . targets ( ) . setBitClass ( <NUM_LIT> ) ; pConfig . attribute ( ) . constraint ( ) . enableWholeArchive ( ) ; pConfig . attribute ( ) . constraint ( ) . enableAsNeeded ( ) ; pConfig . attribute ( ) . constraint ( ) . setSharedSystem ( ) ; pConfig . attribute ( ) . predefined ( ) . unsetWholeArchive ( ) ; pConfig . attribute ( ) . predefined ( ) . unsetAsNeeded ( ) ;

pConfig . attribute ( ) . predefined ( ) . setDynamic ( ) ;


<s> pConfig . attribute ( ) . predefined ( ) . unsetWholeArchive ( ) ; pConfig . attribute ( ) . predefined ( ) . unsetAsNeeded ( ) ; pConfig . attribute ( ) . predefined ( ) . setDynamic ( ) ; return true ;


<s> mcld :: TargetRegistry :: RegisterEmulation ( mcld :: The<ISA_LIT>Target , mcld :: emulate<ISA_LIT>LD ) ;


<s> bool <ISA_LIT>ExpandCondsets :: coalesceRegisters ( RegisterRef R1 , RegisterRef R2 ) { if ( CoaLimitActive ) { if ( CoaCounter >= CoaLimit ) return false ; CoaCounter ++ ; } unsigned BW1 , BW2 ; if ( ! isIntReg ( R1 , BW1 ) || ! isIntReg ( R2 , BW2 ) || BW1 != BW2 ) return false ; if ( MRI -> isLiveIn ( R1 . Reg ) ) return false ; if ( MRI -> isLiveIn ( R2 . Reg ) ) return false ; LiveInterval & L1 = LIS -> getInterval ( R1 . Reg ) ; LiveInterval & L2 = LIS -> getInterval ( R2 . Reg ) ; if ( L2 . empty ( ) ) return false ; if ( L1 . hasSubRanges ( ) || L2 . hasSubRanges ( ) ) return false ; bool Overlap = L1 . overlaps ( L2 ) ; DEBUG ( dbgs ( ) << <STR_LIT> << ( Overlap ? <STR_LIT> : <STR_LIT> ) << <STR_LIT> << PrintReg ( R1 . Reg , TRI , R1 . Sub ) << <STR_LIT> << L1 << <STR_LIT> << PrintReg ( R2 . Reg , TRI , R2 . Sub ) << <STR_LIT> << L2 << <STR_LIT> ) ; if ( R1 . Sub || R2 . Sub ) return false ;


<s> unsigned <ISA_LIT>ExpandCondsets :: getCondTfrOpcode ( const MachineOperand & SO , bool IfTrue ) { using namespace <ISA_LIT> ; if ( SO . isReg ( ) ) { unsigned PhysR ; RegisterRef RS = SO ; if ( TargetRegisterInfo :: isVirtualRegister ( RS . Reg ) ) { const TargetRegisterClass * VC = MRI -> getRegClass ( RS . Reg ) ; assert ( VC -> begin ( ) != VC -> end ( ) && <STR_LIT> ) ; PhysR = * VC -> begin ( ) ; } else { assert ( TargetRegisterInfo :: isPhysicalRegister ( RS . Reg ) ) ; PhysR = RS . Reg ; } unsigned PhysS = ( RS . Sub == <NUM_LIT> ) ? PhysR : TRI -> getSubReg ( PhysR , RS . Sub ) ; const TargetRegisterClass * RC = TRI -> getMinimalPhysRegClass ( PhysS ) ; switch ( TRI -> getRegSizeInBits ( * RC ) ) { case <NUM_LIT> : return IfTrue ? A2_tfrt : A2_tfrf ; case <NUM_LIT> : return IfTrue ? A2_tfrpt : A2_tfrpf ; } llvm_unreachable ( <STR_LIT> ) ; } if ( SO . isImm ( ) || SO . isFPImm ( ) ) return IfTrue ? C2_cmoveit : C2_cmoveif ; llvm_unreachable ( <STR_LIT> ) ;


<s> <ISA_LIT>ExpandCondsets ( ) : MachineFunctionPass ( ID ) , HII ( nullptr ) , TRI ( nullptr ) , MRI ( nullptr ) , LIS ( nullptr ) , CoaLimitActive ( false ) , TfrLimitActive ( false ) , CoaCounter ( <NUM_LIT> ) , TfrCounter ( <NUM_LIT> ) { if ( OptCoaLimit . getPosition ( ) ) CoaLimitActive = true , CoaLimit = OptCoaLimit ; if ( OptTfrLimit . getPosition ( ) ) TfrLimitActive = true , TfrLimit = OptTfrLimit ;

initialize<ISA_LIT>ExpandCondsetsPass ( * PassRegistry :: getPassRegistry ( ) ) ;


<s> MachineFunctionPass ( ID ) , HII ( nullptr ) , TRI ( nullptr ) , MRI ( nullptr ) , LIS ( nullptr ) , CoaLimitActive ( false ) , TfrLimitActive ( false ) , CoaCounter ( <NUM_LIT> ) , TfrCounter ( <NUM_LIT> ) { if ( OptCoaLimit . getPosition ( ) ) CoaLimitActive = true , CoaLimit = OptCoaLimit ; if ( OptTfrLimit . getPosition ( ) ) TfrLimitActive = true , TfrLimit = OptTfrLimit ; initialize<ISA_LIT>ExpandCondsetsPass ( * PassRegistry :: getPassRegistry ( ) ) ;


<s> MRI = & MF . getRegInfo ( ) ; DEBUG ( LIS -> print ( dbgs ( ) << <STR_LIT> , MF . getFunction ( ) -> getParent ( ) ) ) ; bool Changed = false ; std :: set < unsigned > CoalUpd , PredUpd ; SmallVector < MachineInstr * , <NUM_LIT> > Condsets ; for ( auto & B : MF ) for ( auto & I : B ) if ( isCondset ( I ) ) Condsets . push_back ( & I ) ; Changed |= coalesceSegments ( Condsets , CoalUpd ) ; std :: set < unsigned > KillUpd ; for ( MachineInstr * MI : Condsets ) for ( MachineOperand & Op : MI -> operands ( ) ) if ( Op . isReg ( ) && Op . isUse ( ) ) if ( ! CoalUpd . count ( Op . getReg ( ) ) ) KillUpd . insert ( Op . getReg ( ) ) ; updateLiveness ( KillUpd , false , true , false ) ; DEBUG ( LIS -> print ( dbgs ( ) << <STR_LIT> , MF . getFunction ( ) -> getParent ( ) ) ) ; for ( MachineInstr * MI : Condsets ) Changed |= split ( * MI , PredUpd ) ; Condsets . clear ( ) ; DEBUG ( LIS -> print ( dbgs ( ) << <STR_LIT> , MF . getFunction ( ) -> getParent ( ) ) ) ; for ( auto & B : MF ) Changed |= predicateInBlock ( B , PredUpd ) ;


<s> std :: set < unsigned > CoalUpd , PredUpd ; SmallVector < MachineInstr * , <NUM_LIT> > Condsets ; for ( auto & B : MF ) for ( auto & I : B ) if ( isCondset ( I ) ) Condsets . push_back ( & I ) ; Changed |= coalesceSegments ( Condsets , CoalUpd ) ; std :: set < unsigned > KillUpd ; for ( MachineInstr * MI : Condsets ) for ( MachineOperand & Op : MI -> operands ( ) ) if ( Op . isReg ( ) && Op . isUse ( ) ) if ( ! CoalUpd . count ( Op . getReg ( ) ) ) KillUpd . insert ( Op . getReg ( ) ) ; updateLiveness ( KillUpd , false , true , false ) ;


<s> MachineInstr * DefI = LIS -> getInstructionFromIndex ( Seg . start ) ; Defs . insert ( DefI -> getParent ( ) ) ; if ( HII -> isPredicated ( * DefI ) ) PredDefs . push_back ( Seg . start ) ; } SmallVector < SlotIndex , <NUM_LIT> > Undefs ; LiveInterval & LI = LIS -> getInterval ( Reg ) ; LI . computeSubRangeUndefs ( Undefs , LM , * MRI , * LIS -> getSlotIndexes ( ) ) ; for ( auto & SI : PredDefs ) { MachineBasicBlock * BB = LIS -> getMBBFromIndex ( SI ) ; auto P = Range . extendInBlock ( Undefs , LIS -> getMBBStartIdx ( BB ) , SI ) ; if ( P . first != nullptr || P . second ) SI = SlotIndex ( ) ; } SmallVector < SlotIndex , <NUM_LIT> > ExtTo ; for ( auto & SI : PredDefs ) { if ( ! SI . isValid ( ) ) continue ; MachineBasicBlock * BB = LIS -> getMBBFromIndex ( SI ) ; if ( BB -> pred_empty ( ) ) continue ; if ( Dominate ( Defs , BB ) ) ExtTo . push_back ( SI ) ; } if ( ! ExtTo . empty ( ) ) LIS -> extendToIndices ( Range , ExtTo , Undefs ) ; std :: set < RegisterRef > DefRegs ; for ( auto & Seg : Range ) { if ( ! Seg . start . isRegister ( ) ) continue ; MachineInstr * DefI = LIS -> getInstructionFromIndex ( Seg . start ) ; for ( auto & Op : DefI -> operands ( ) ) { auto P = IsRegDef ( Op ) ; if ( P . second && Seg . end . isDead ( ) ) { Op . setIsDead ( true ) ; } else if ( P . first ) { DefRegs . insert ( Op ) ; Op . setIsDead ( false ) ; }


<s> ValueInfoMap VM ; for ( LiveInterval :: iterator I = L2 . begin ( ) , E = L2 . end ( ) ; I != E ; ++ I ) { VNInfo * NewVN , * OldVN = I -> valno ; ValueInfoMap :: iterator F = VM . find ( OldVN ) ; if ( F == VM . end ( ) ) { NewVN = L1 . getNextValue ( I -> valno -> def , LIS -> getVNInfoAllocator ( ) ) ; VM . insert ( std :: make_pair ( OldVN , NewVN ) ) ; } else { NewVN = F -> second ; } L1 . addSegment ( LiveRange :: Segment ( I -> start , I -> end , NewVN ) ) ; } while ( L2 . begin ( ) != L2 . end ( ) ) L2 . removeSegment ( * L2 . begin ( ) ) ; LIS -> removeInterval ( R2 . Reg ) ;


<s> unsigned PredState = getRegState ( PredOp ) & ~ RegState :: Kill ; MachineInstrBuilder MIB ; if ( SrcOp . isReg ( ) ) { unsigned SrcState = getRegState ( SrcOp ) ; if ( RegisterRef ( SrcOp ) == RegisterRef ( DstR , DstSR ) ) SrcState &= ~ RegState :: Kill ; MIB = BuildMI ( B , At , DL , HII -> get ( Opc ) ) . addReg ( DstR , DstState , DstSR ) . addReg ( PredOp . getReg ( ) , PredState , PredOp . getSubReg ( ) ) . addReg ( SrcOp . getReg ( ) , SrcState , SrcOp . getSubReg ( ) ) ; } else { MIB = BuildMI ( B , At , DL , HII -> get ( Opc ) ) . addReg ( DstR , DstState , DstSR ) . addReg ( PredOp . getReg ( ) , PredState , PredOp . getSubReg ( ) ) . add ( SrcOp ) ; }

LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << * MIB ) ;


<s> ( void ) Opc ; assert ( Opc == <STR_LIT> || Opc == <STR_LIT> ) ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << ( Cond ? <STR_LIT> : <STR_LIT> ) << <STR_LIT> << TfrI ) ; MachineOperand & MD = TfrI . getOperand ( <NUM_LIT> ) ; MachineOperand & MP = TfrI . getOperand ( <NUM_LIT> ) ; MachineOperand & MS = TfrI . getOperand ( <NUM_LIT> ) ; if ( ! MS . isKill ( ) ) return false ; if ( MD . getSubReg ( ) && ! MRI -> shouldTrackSubRegLiveness ( MD . getReg ( ) ) ) return false ; RegisterRef RT ( MS ) ; unsigned PredR = MP . getReg ( ) ; MachineInstr * DefI = getReachingDefForPred ( RT , TfrI , PredR , Cond ) ; if ( ! DefI || ! isPredicable ( DefI ) ) return false ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << * DefI ) ; ReferenceMap Uses , Defs ; MachineBasicBlock :: iterator DefIt = DefI , TfrIt = TfrI ; bool PredValid = true ; for ( MachineBasicBlock :: iterator I = std :: next ( DefIt ) ; I != TfrIt ; ++ I ) { if ( ! I -> modifiesRegister ( PredR , nullptr ) ) continue ; PredValid = false ; break ; } for ( MachineBasicBlock :: iterator I = std :: next ( DefIt ) ; I != TfrIt ; ++ I ) { MachineInstr * MI = & * I ; unsigned Exec = Exec_Then | Exec_Else ; if ( PredValid && HII -> isPredicated ( * MI ) && MI -> readsRegister ( PredR ) ) Exec = ( Cond == HII -> isPredicatedTrue ( * MI ) ) ? Exec_Then : Exec_Else ; for ( auto & Op : MI -> operands ( ) ) { if ( ! Op . isReg ( ) ) continue ;


<s> if ( ! Op . isReg ( ) ) continue ; RegisterRef RR = Op ; if ( ! TargetRegisterInfo :: isVirtualRegister ( RR . Reg ) ) return false ; ReferenceMap & Map = Op . isDef ( ) ? Defs : Uses ; if ( Op . isDef ( ) && Op . isUndef ( ) ) { assert ( RR . Sub && <STR_LIT> ) ; RR . Sub = <NUM_LIT> ; } addRefToMap ( RR , Map , Exec ) ; } } if ( isRefInMap ( RT , Defs , Exec_Then ) || isRefInMap ( RT , Uses , Exec_Else ) ) return false ; RegisterRef RD = MD ; bool CanUp = canMoveOver ( TfrI , Defs , Uses ) ; bool CanDown = canMoveOver ( * DefI , Defs , Uses ) ; if ( DefI -> mayLoad ( ) || DefI -> mayStore ( ) ) if ( ! canMoveMemTo ( * DefI , TfrI , true ) ) CanDown = false ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << ( CanUp ? <STR_LIT> : <STR_LIT> ) << <STR_LIT> << ( CanDown ? <STR_LIT> : <STR_LIT> ) ) ;

MachineBasicBlock :: iterator PastDefIt = std :: next ( DefIt ) ;


<s> LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << printMBBReference ( * MI . getParent ( ) ) << <STR_LIT> << MI ) ; MachineOperand & MD = MI . getOperand ( <NUM_LIT> ) ; MachineOperand & MP = MI . getOperand ( <NUM_LIT> ) ; assert ( MD . isDef ( ) ) ; unsigned DR = MD . getReg ( ) , DSR = MD . getSubReg ( ) ; bool ReadUndef = MD . isUndef ( ) ; MachineBasicBlock :: iterator At = MI ; auto updateRegs = [ & UpdRegs ] ( const MachineInstr & MI ) -> void { for ( auto & Op : MI . operands ( ) ) if ( Op . isReg ( ) ) UpdRegs . insert ( Op . getReg ( ) ) ; } ; MachineOperand & ST = MI . getOperand ( <NUM_LIT> ) ; MachineOperand & SF = MI . getOperand ( <NUM_LIT> ) ; if ( ST . isReg ( ) && SF . isReg ( ) ) { RegisterRef RT ( ST ) ; if ( RT == RegisterRef ( SF ) ) { updateRegs ( MI ) ; MI . setDesc ( HII -> get ( TargetOpcode :: COPY ) ) ; unsigned S = getRegState ( ST ) ; while ( MI . getNumOperands ( ) > <NUM_LIT> ) MI . RemoveOperand ( MI . getNumOperands ( ) - <NUM_LIT> ) ; MachineFunction & MF = * MI . getParent ( ) -> getParent ( ) ;

MachineInstrBuilder ( MF , MI ) . addReg ( RT . Reg , S , RT . Sub ) ;


<s> if ( TfrLimitActive ) { if ( TfrCounter >= TfrLimit ) return false ; TfrCounter ++ ; } LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << printMBBReference ( * MI . getParent ( ) ) << <STR_LIT> << MI ) ; MachineOperand & MD = MI . getOperand ( <NUM_LIT> ) ; MachineOperand & MP = MI . getOperand ( <NUM_LIT> ) ; assert ( MD . isDef ( ) ) ; unsigned DR = MD . getReg ( ) , DSR = MD . getSubReg ( ) ; bool ReadUndef = MD . isUndef ( ) ; MachineBasicBlock :: iterator At = MI ; auto updateRegs = [ & UpdRegs ] ( const MachineInstr & MI ) -> void { for ( auto & Op : MI . operands ( ) ) if ( Op . isReg ( ) ) UpdRegs . insert ( Op . getReg ( ) ) ; } ; MachineOperand & ST = MI . getOperand ( <NUM_LIT> ) ; MachineOperand & SF = MI . getOperand ( <NUM_LIT> ) ; if ( ST . isReg ( ) && SF . isReg ( ) ) { RegisterRef RT ( ST ) ; if ( RT == RegisterRef ( SF ) ) { updateRegs ( MI ) ; MI . setDesc ( HII -> get ( TargetOpcode :: COPY ) ) ; unsigned S = getRegState ( ST ) ; while ( MI . getNumOperands ( ) > <NUM_LIT> ) MI . RemoveOperand ( MI . getNumOperands ( ) - <NUM_LIT> ) ; MachineFunction & MF = * MI . getParent ( ) -> getParent ( ) ; MachineInstrBuilder ( MF , MI ) . addReg ( RT . Reg , S , RT . Sub ) ;


<s> auto KillAt = [ this , Reg ] ( SlotIndex K , LaneBitmask LM ) -> void { MachineInstr * MI = LIS -> getInstructionFromIndex ( K ) ; for ( unsigned i = <NUM_LIT> , e = MI -> getNumOperands ( ) ; i != e ; ++ i ) { MachineOperand & Op = MI -> getOperand ( i ) ; if ( ! Op . isReg ( ) || ! Op . isUse ( ) || Op . getReg ( ) != Reg || MI -> isRegTiedToDefOperand ( i ) ) continue ; LaneBitmask SLM = getLaneMask ( Reg , Op . getSubReg ( ) ) ; if ( ( SLM & LM ) == SLM ) { Op . setIsKill ( true ) ; break ; } } } ;

LiveInterval & LI = LIS -> getInterval ( Reg ) ;


<s> assert ( TargetRegisterInfo :: isPhysicalRegister ( R ) ) ; assert ( MRI -> isReserved ( R ) ) ; continue ; } if ( Recalc ) recalculateLiveInterval ( R ) ;

if ( UpdateKills ) MRI -> clearKillFlags ( R ) ;


<s> unsigned DstState = RegState :: Define | ( ReadUndef ? RegState :: Undef : <NUM_LIT> ) ; unsigned PredState = getRegState ( PredOp ) & ~ RegState :: Kill ; MachineInstrBuilder MIB ; if ( SrcOp . isReg ( ) ) { unsigned SrcState = getRegState ( SrcOp ) ; if ( RegisterRef ( SrcOp ) == RegisterRef ( DstR , DstSR ) ) SrcState &= ~ RegState :: Kill ; MIB = BuildMI ( B , At , DL , HII -> get ( Opc ) ) . addReg ( DstR , DstState , DstSR ) . addReg ( PredOp . getReg ( ) , PredState , PredOp . getSubReg ( ) ) . addReg ( SrcOp . getReg ( ) , SrcState , SrcOp . getSubReg ( ) ) ; } else { MIB = BuildMI ( B , At , DL , HII -> get ( Opc ) ) . addReg ( DstR , DstState , DstSR ) . addReg ( PredOp . getReg ( ) , PredState , PredOp . getSubReg ( ) ) . addOperand ( SrcOp ) ;


<s> assert ( TargetRegisterInfo :: isPhysicalRegister ( RS . Reg ) ) ; PhysR = RS . Reg ; } unsigned PhysS = ( RS . Sub == <NUM_LIT> ) ? PhysR : TRI -> getSubReg ( PhysR , RS . Sub ) ; const TargetRegisterClass * RC = TRI -> getMinimalPhysRegClass ( PhysS ) ; switch ( RC -> getSize ( ) ) { case <NUM_LIT> : return IfTrue ? A2_tfrt : A2_tfrf ; case <NUM_LIT> : return IfTrue ? A2_tfrpt : A2_tfrpf ; }


<s> unsigned PhysR ; RegisterRef RS = SO ; if ( TargetRegisterInfo :: isVirtualRegister ( RS . Reg ) ) { const TargetRegisterClass * VC = MRI -> getRegClass ( RS . Reg ) ; assert ( VC -> begin ( ) != VC -> end ( ) && <STR_LIT> ) ; PhysR = * VC -> begin ( ) ; } else { assert ( TargetRegisterInfo :: isPhysicalRegister ( RS . Reg ) ) ; PhysR = RS . Reg ; }

unsigned PhysS = ( RS . Sub == <NUM_LIT> ) ? PhysR : TRI -> getSubReg ( PhysR , RS . Sub ) ;


<s> unsigned Opc = MI . getOpcode ( ) ; unsigned PredOpc = HII -> getCondOpcode ( Opc , ! Cond ) ; MachineInstrBuilder MB = BuildMI ( B , Where , DL , HII -> get ( PredOpc ) ) ; unsigned Ox = <NUM_LIT> , NP = MI . getNumOperands ( ) ; while ( Ox < NP ) { MachineOperand & MO = MI . getOperand ( Ox ) ; if ( ! MO . isReg ( ) || ! MO . isDef ( ) ) break ; Ox ++ ; } MB . addReg ( DefOp . getReg ( ) , getRegState ( DefOp ) , DefOp . getSubReg ( ) ) ;

MB . addReg ( PredOp . getReg ( ) , PredOp . isUndef ( ) ? RegState :: Undef : <NUM_LIT> , PredOp . getSubReg ( ) ) ;


<s> void <ISA_LIT>ExpandCondsets :: predicateAt ( const MachineOperand & DefOp , MachineInstr & MI , MachineBasicBlock :: iterator Where , const MachineOperand & PredOp , bool Cond , std :: set < unsigned > & UpdRegs ) { MachineBasicBlock & B = * MI . getParent ( ) ; DebugLoc DL = Where -> getDebugLoc ( ) ; unsigned Opc = MI . getOpcode ( ) ; unsigned PredOpc = HII -> getCondOpcode ( Opc , ! Cond ) ; MachineInstrBuilder MB = BuildMI ( B , Where , DL , HII -> get ( PredOpc ) ) ; unsigned Ox = <NUM_LIT> , NP = MI . getNumOperands ( ) ; while ( Ox < NP ) { MachineOperand & MO = MI . getOperand ( Ox ) ; if ( ! MO . isReg ( ) || ! MO . isDef ( ) ) break ; Ox ++ ; } MB . addReg ( DefOp . getReg ( ) , getRegState ( DefOp ) , DefOp . getSubReg ( ) ) ; MB . addReg ( PredOp . getReg ( ) , PredOp . isUndef ( ) ? RegState :: Undef : <NUM_LIT> , PredOp . getSubReg ( ) ) ; while ( Ox < NP ) { MachineOperand & MO = MI . getOperand ( Ox ) ; if ( ! MO . isReg ( ) || ! MO . isImplicit ( ) ) MB . addOperand ( MO ) ;


<s> MachineOperand & ST = MI . getOperand ( <NUM_LIT> ) ; MachineOperand & SF = MI . getOperand ( <NUM_LIT> ) ; if ( ST . isReg ( ) && SF . isReg ( ) ) { RegisterRef RT ( ST ) ; if ( RT == RegisterRef ( SF ) ) { MI . setDesc ( HII -> get ( TargetOpcode :: COPY ) ) ; unsigned S = getRegState ( ST ) ; while ( MI . getNumOperands ( ) > <NUM_LIT> ) MI . RemoveOperand ( MI . getNumOperands ( ) - <NUM_LIT> ) ; MachineFunction & MF = * MI . getParent ( ) -> getParent ( ) ; MachineInstrBuilder ( MF , MI ) . addReg ( RT . Reg , S , RT . Sub ) ; return true ; } } MachineInstr * TfrT = genCondTfrFor ( ST , At , DR , DSR , MP , true , ReadUndef , false ) ; MachineInstr * TfrF = genCondTfrFor ( SF , At , DR , DSR , MP , false , ReadUndef , true ) ; LIS -> InsertMachineInstrInMaps ( * TfrT ) ; LIS -> InsertMachineInstrInMaps ( * TfrF ) ; for ( auto & Op : MI . operands ( ) ) if ( Op . isReg ( ) ) UpdRegs . insert ( Op . getReg ( ) ) ; removeInstr ( MI ) ;


<s> TfrCounter ++ ; } DEBUG ( dbgs ( ) << <STR_LIT> << MI . getParent ( ) -> getNumber ( ) << <STR_LIT> << MI ) ; MachineOperand & MD = MI . getOperand ( <NUM_LIT> ) ; MachineOperand & MP = MI . getOperand ( <NUM_LIT> ) ; assert ( MD . isDef ( ) ) ; unsigned DR = MD . getReg ( ) , DSR = MD . getSubReg ( ) ; bool ReadUndef = MD . isUndef ( ) ; MachineBasicBlock :: iterator At = MI ; MachineOperand & ST = MI . getOperand ( <NUM_LIT> ) ; MachineOperand & SF = MI . getOperand ( <NUM_LIT> ) ; if ( ST . isReg ( ) && SF . isReg ( ) ) { RegisterRef RT ( ST ) ;


<s> LaneBitmask SLM = getLaneMask ( DR , DSR ) ; return ( SLM & LM ) . any ( ) ; } ; auto Dominate = [ this ] ( SetVector < MachineBasicBlock * > & Defs , MachineBasicBlock * Dest ) -> bool { for ( MachineBasicBlock * D : Defs ) if ( D != Dest && MDT -> dominates ( D , Dest ) ) return true ; MachineBasicBlock * Entry = & Dest -> getParent ( ) -> front ( ) ; SetVector < MachineBasicBlock * > Work ( Dest -> pred_begin ( ) , Dest -> pred_end ( ) ) ; for ( unsigned i = <NUM_LIT> ; i < Work . size ( ) ; ++ i ) { MachineBasicBlock * B = Work [ i ] ; if ( Defs . count ( B ) ) continue ; if ( B == Entry ) return false ; for ( auto * P : B -> predecessors ( ) ) Work . insert ( P ) ; } return true ; } ; SetVector < MachineBasicBlock * > Defs ; SmallVector < SlotIndex , <NUM_LIT> > PredDefs ; for ( auto & Seg : Range ) { if ( ! Seg . start . isRegister ( ) ) continue ; MachineInstr * DefI = LIS -> getInstructionFromIndex ( Seg . start ) ; Defs . insert ( DefI -> getParent ( ) ) ; if ( HII -> isPredicated ( * DefI ) ) PredDefs . push_back ( Seg . start ) ; } SmallVector < SlotIndex , <NUM_LIT> > Undefs ; LiveInterval & LI = LIS -> getInterval ( Reg ) ; LI . computeSubRangeUndefs ( Undefs , LM , * MRI , * LIS -> getSlotIndexes ( ) ) ; for ( auto & SI : PredDefs ) { MachineBasicBlock * BB = LIS -> getMBBFromIndex ( SI ) ; auto P = Range . extendInBlock ( Undefs , LIS -> getMBBStartIdx ( BB ) , SI ) ; if ( P . first != nullptr || P . second ) SI = SlotIndex ( ) ; } SmallVector < SlotIndex , <NUM_LIT> > ExtTo ; for ( auto & SI : PredDefs ) { if ( ! SI . isValid ( ) ) continue ; MachineBasicBlock * BB = LIS -> getMBBFromIndex ( SI ) ; if ( BB -> pred_empty ( ) ) continue ;

if ( Dominate ( Defs , BB ) ) ExtTo . push_back ( SI ) ;


<s> unsigned Opc = MI . getOpcode ( ) ; unsigned PredOpc = HII -> getCondOpcode ( Opc , ! Cond ) ; MachineInstrBuilder MB = BuildMI ( B , Where , DL , HII -> get ( PredOpc ) ) ; unsigned Ox = <NUM_LIT> , NP = MI . getNumOperands ( ) ; while ( Ox < NP ) { MachineOperand & MO = MI . getOperand ( Ox ) ; if ( ! MO . isReg ( ) || ! MO . isDef ( ) ) break ;


<s> RegisterRef RR = Op ; if ( ! Register :: isVirtualRegister ( RR . Reg ) ) return false ; if ( isRefInMap ( RR , Defs , Exec_Then ) ) return false ; if ( Op . isDef ( ) && isRefInMap ( RR , Uses , Exec_Then ) ) return false ; } return true ;


<s> RegisterRef RS = SO ; if ( Register :: isVirtualRegister ( RS . Reg ) ) { const TargetRegisterClass * VC = MRI -> getRegClass ( RS . Reg ) ; assert ( VC -> begin ( ) != VC -> end ( ) && <STR_LIT> ) ; PhysR = * VC -> begin ( ) ; } else { assert ( Register :: isPhysicalRegister ( RS . Reg ) ) ; PhysR = RS . Reg ;


<s> assert ( Register :: isPhysicalRegister ( RS . Reg ) ) ; PhysR = RS . Reg ; } Register PhysS = ( RS . Sub == <NUM_LIT> ) ? PhysR : TRI -> getSubReg ( PhysR , RS . Sub ) ; const TargetRegisterClass * RC = TRI -> getMinimalPhysRegClass ( PhysS ) ; switch ( TRI -> getRegSizeInBits ( * RC ) ) { case <NUM_LIT> : return IfTrue ? A2_tfrt : A2_tfrf ; case <NUM_LIT> : return IfTrue ? A2_tfrpt : A2_tfrpf ; } llvm_unreachable ( <STR_LIT> ) ; }


<s> assert ( Register :: isVirtualRegister ( Reg ) ) ;

return Sub != <NUM_LIT> ? TRI -> getSubRegIndexLaneMask ( Sub ) : MRI -> getMaxLaneMaskForVReg ( Reg ) ;


<s> if ( RC == & <STR_LIT> ) { BW = ( RR . Sub != <NUM_LIT> ) ? <NUM_LIT> : <NUM_LIT> ; return true ; } return false ;


<s> for ( auto & Op : MI -> operands ( ) ) { if ( ! Op . isReg ( ) || ! Op . isDef ( ) ) continue ; if ( HasDef ) return false ; HasDef = true ; } for ( auto & Mo : MI -> memoperands ( ) ) if ( Mo -> isVolatile ( ) || Mo -> isAtomic ( ) ) return false ;


<s> if ( MI -> hasUnmodeledSideEffects ( ) || MI -> mayStore ( ) ) return false ; bool HasDef = false ; for ( auto & Op : MI -> operands ( ) ) {

if ( ! Op . isReg ( ) || ! Op . isDef ( ) ) continue ;


<s> LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << * DefI ) ; ReferenceMap Uses , Defs ; MachineBasicBlock :: iterator DefIt = DefI , TfrIt = TfrI ; bool PredValid = true ; for ( MachineBasicBlock :: iterator I = std :: next ( DefIt ) ; I != TfrIt ; ++ I ) { if ( ! I -> modifiesRegister ( PredR , nullptr ) ) continue ; PredValid = false ; break ; } for ( MachineBasicBlock :: iterator I = std :: next ( DefIt ) ; I != TfrIt ; ++ I ) { MachineInstr * MI = & * I ; unsigned Exec = Exec_Then | Exec_Else ; if ( PredValid && HII -> isPredicated ( * MI ) && MI -> readsRegister ( PredR ) ) Exec = ( Cond == HII -> isPredicatedTrue ( * MI ) ) ? Exec_Then : Exec_Else ; for ( auto & Op : MI -> operands ( ) ) { if ( ! Op . isReg ( ) ) continue ; RegisterRef RR = Op ; if ( ! Register :: isVirtualRegister ( RR . Reg ) ) return false ; ReferenceMap & Map = Op . isDef ( ) ? Defs : Uses ; if ( Op . isDef ( ) && Op . isUndef ( ) ) { assert ( RR . Sub && <STR_LIT> ) ; RR . Sub = <NUM_LIT> ; } addRefToMap ( RR , Map , Exec ) ; } } if ( isRefInMap ( RT , Defs , Exec_Then ) || isRefInMap ( RT , Uses , Exec_Else ) ) return false ; RegisterRef RD = MD ; bool CanUp = canMoveOver ( TfrI , Defs , Uses ) ; bool CanDown = canMoveOver ( * DefI , Defs , Uses ) ; if ( DefI -> mayLoad ( ) || DefI -> mayStore ( ) ) if ( ! canMoveMemTo ( * DefI , TfrI , true ) ) CanDown = false ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << ( CanUp ? <STR_LIT> : <STR_LIT> ) << <STR_LIT> << ( CanDown ? <STR_LIT> : <STR_LIT> ) ) ; MachineBasicBlock :: iterator PastDefIt = std :: next ( DefIt ) ;

if ( CanUp ) predicateAt ( MD , * DefI , PastDefIt , MP , Cond , UpdRegs ) ;


<s> auto updateRegs = [ & UpdRegs ] ( const MachineInstr & MI ) -> void { for ( auto & Op : MI . operands ( ) ) if ( Op . isReg ( ) ) UpdRegs . insert ( Op . getReg ( ) ) ; } ; MachineOperand & ST = MI . getOperand ( <NUM_LIT> ) ; MachineOperand & SF = MI . getOperand ( <NUM_LIT> ) ; if ( ST . isReg ( ) && SF . isReg ( ) ) { RegisterRef RT ( ST ) ; if ( RT == RegisterRef ( SF ) ) { updateRegs ( MI ) ; MI . setDesc ( HII -> get ( TargetOpcode :: COPY ) ) ; unsigned S = getRegState ( ST ) ;

while ( MI . getNumOperands ( ) > <NUM_LIT> ) MI . RemoveOperand ( MI . getNumOperands ( ) - <NUM_LIT> ) ;


<s> bool <ISA_LIT>ExpandCondsets :: split ( MachineInstr & MI , std :: set < unsigned > & UpdRegs ) { if ( TfrLimitActive ) { if ( TfrCounter >= TfrLimit ) return false ; TfrCounter ++ ; } LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << printMBBReference ( * MI . getParent ( ) ) << <STR_LIT> << MI ) ; MachineOperand & MD = MI . getOperand ( <NUM_LIT> ) ; MachineOperand & MP = MI . getOperand ( <NUM_LIT> ) ; assert ( MD . isDef ( ) ) ; Register DR = MD . getReg ( ) , DSR = MD . getSubReg ( ) ; bool ReadUndef = MD . isUndef ( ) ; MachineBasicBlock :: iterator At = MI ; auto updateRegs = [ & UpdRegs ] ( const MachineInstr & MI ) -> void {

for ( auto & Op : MI . operands ( ) ) if ( Op . isReg ( ) ) UpdRegs . insert ( Op . getReg ( ) ) ;


<s> for ( unsigned R : RegSet ) { if ( ! Register :: isVirtualRegister ( R ) ) { assert ( Register :: isPhysicalRegister ( R ) ) ;


<s> if ( ! RR . Reg . isVirtual ( ) ) return false ; if ( isRefInMap ( RR , Defs , Exec_Then ) ) return false ; if ( Op . isDef ( ) && isRefInMap ( RR , Uses , Exec_Then ) ) return false ; } return true ;


<s> if ( ! Op . isReg ( ) ) continue ; RegisterRef RR = Op ; if ( ! RR . Reg . isVirtual ( ) ) return false ;

if ( isRefInMap ( RR , Defs , Exec_Then ) ) return false ;


<s> unsigned BW1 , BW2 ; if ( ! isIntReg ( R1 , BW1 ) || ! isIntReg ( R2 , BW2 ) || BW1 != BW2 ) return false ; if ( MRI -> isLiveIn ( R1 . Reg ) ) return false ; if ( MRI -> isLiveIn ( R2 . Reg ) ) return false ; LiveInterval & L1 = LIS -> getInterval ( R1 . Reg ) ; LiveInterval & L2 = LIS -> getInterval ( R2 . Reg ) ; if ( L2 . empty ( ) ) return false ; if ( L1 . hasSubRanges ( ) || L2 . hasSubRanges ( ) ) return false ; bool Overlap = L1 . overlaps ( L2 ) ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << ( Overlap ? <STR_LIT> : <STR_LIT> ) << <STR_LIT> << printReg ( R1 . Reg , TRI , R1 . Sub ) << <STR_LIT> << L1 << <STR_LIT> << printReg ( R2 . Reg , TRI , R2 . Sub ) << <STR_LIT> << L2 << <STR_LIT> ) ; if ( R1 . Sub || R2 . Sub ) return false ; if ( Overlap ) return false ; if ( ! isIntraBlocks ( L1 ) && ! isIntraBlocks ( L2 ) ) return false ; MRI -> replaceRegWith ( R2 . Reg , R1 . Reg ) ; using ValueInfoMap = DenseMap < VNInfo * , VNInfo * > ; ValueInfoMap VM ; for ( LiveRange :: Segment & I : L2 ) { VNInfo * NewVN , * OldVN = I . valno ; ValueInfoMap :: iterator F = VM . find ( OldVN ) ; if ( F == VM . end ( ) ) { NewVN = L1 . getNextValue ( I . valno -> def , LIS -> getVNInfoAllocator ( ) ) ; VM . insert ( std :: make_pair ( OldVN , NewVN ) ) ; } else { NewVN = F -> second ; } L1 . addSegment ( LiveRange :: Segment ( I . start , I . end , NewVN ) ) ; } while ( ! L2 . empty ( ) ) L2 . removeSegment ( * L2 . begin ( ) ) ; LIS -> removeInterval ( R2 . Reg ) ; updateKillFlags ( R1 . Reg ) ;

LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << L1 << <STR_LIT> ) ;


<s> MachineOperand & S1 = MI -> getOperand ( <NUM_LIT> ) , & S2 = MI -> getOperand ( <NUM_LIT> ) ; if ( ! S1 . isReg ( ) && ! S2 . isReg ( ) ) continue ; TwoRegs . push_back ( MI ) ; } bool Changed = false ; for ( MachineInstr * CI : TwoRegs ) { RegisterRef RD = CI -> getOperand ( <NUM_LIT> ) ; RegisterRef RP = CI -> getOperand ( <NUM_LIT> ) ; MachineOperand & S1 = CI -> getOperand ( <NUM_LIT> ) , & S2 = CI -> getOperand ( <NUM_LIT> ) ; bool Done = false ; if ( S1 . isReg ( ) ) {


<s> } else { PhysR = RS . Reg ; } MCRegister PhysS = ( RS . Sub == <NUM_LIT> ) ? PhysR : TRI -> getSubReg ( PhysR , RS . Sub ) ; const TargetRegisterClass * RC = TRI -> getMinimalPhysRegClass ( PhysS ) ; switch ( TRI -> getRegSizeInBits ( * RC ) ) { case <NUM_LIT> : return IfTrue ? A2_tfrt : A2_tfrf ; case <NUM_LIT> : return IfTrue ? A2_tfrpt : A2_tfrpf ; } llvm_unreachable ( <STR_LIT> ) ; } switch ( SO . getType ( ) ) { case MachineOperand :: MO_Immediate : case MachineOperand :: MO_FPImmediate : case MachineOperand :: MO_ConstantPoolIndex : case MachineOperand :: MO_TargetIndex : case MachineOperand :: MO_JumpTableIndex : case MachineOperand :: MO_ExternalSymbol : case MachineOperand :: MO_GlobalAddress : case MachineOperand :: MO_BlockAddress : return IfTrue ? C2_cmoveit : C2_cmoveif ; default : break ; }


<s> return Sub != <NUM_LIT> ? TRI -> getSubRegIndexLaneMask ( Sub ) : MRI -> getMaxLaneMaskForVReg ( Reg ) ;


<s> bool <ISA_LIT>ExpandCondsets :: isIntraBlocks ( LiveInterval & LI ) { for ( LiveRange :: Segment & LR : LI ) { if ( ! LR . start . isRegister ( ) ) return false ; if ( ! LR . end . isRegister ( ) && ! LR . end . isDead ( ) ) return false ;


<s> if ( ! RR . Reg . isVirtual ( ) ) return false ;

const TargetRegisterClass * RC = MRI -> getRegClass ( RR . Reg ) ;


<s> BW = <NUM_LIT> ; return true ; } if ( RC == & <STR_LIT> ) { BW = ( RR . Sub != <NUM_LIT> ) ? <NUM_LIT> : <NUM_LIT> ; return true ;


<s> } addRefToMap ( RR , Map , Exec ) ; } } if ( isRefInMap ( RT , Defs , Exec_Then ) || isRefInMap ( RT , Uses , Exec_Else ) ) return false ; RegisterRef RD = MD ; bool CanUp = canMoveOver ( TfrI , Defs , Uses ) ; bool CanDown = canMoveOver ( * DefI , Defs , Uses ) ; if ( DefI -> mayLoadOrStore ( ) ) if ( ! canMoveMemTo ( * DefI , TfrI , true ) ) CanDown = false ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << ( CanUp ? <STR_LIT> : <STR_LIT> ) << <STR_LIT> << ( CanDown ? <STR_LIT> : <STR_LIT> ) ) ; MachineBasicBlock :: iterator PastDefIt = std :: next ( DefIt ) ; if ( CanUp ) predicateAt ( MD , * DefI , PastDefIt , MP , Cond , UpdRegs ) ; else if ( CanDown ) predicateAt ( MD , * DefI , TfrIt , MP , Cond , UpdRegs ) ; else return false ; if ( RT != RD ) { renameInRange ( RT , RD , PredR , Cond , PastDefIt , TfrIt ) ; UpdRegs . insert ( RT . Reg ) ;


<s> unsigned Opc = MI . getOpcode ( ) ; if ( Opc == <STR_LIT> || Opc == <STR_LIT> ) { bool Done = predicate ( MI , ( Opc == <STR_LIT> ) , UpdRegs ) ; if ( ! Done ) { if ( RegisterRef ( MI . getOperand ( <NUM_LIT> ) ) == RegisterRef ( MI . getOperand ( <NUM_LIT> ) ) ) { for ( auto & Op : MI . operands ( ) ) if ( Op . isReg ( ) ) UpdRegs . insert ( Op . getReg ( ) ) ; removeInstr ( MI ) ;


<s> void <ISA_LIT>ExpandCondsets :: recalculateLiveInterval ( Register Reg ) {


<s> LIS -> createAndComputeVirtRegInterval ( Reg ) ;


<s> MDT = & getAnalysis < MachineDominatorTree > ( ) ; LIS = & getAnalysis < LiveIntervals > ( ) ; MRI = & MF . getRegInfo ( ) ; LLVM_DEBUG ( LIS -> print ( dbgs ( ) << <STR_LIT> , MF . getFunction ( ) . getParent ( ) ) ) ; bool Changed = false ; std :: set < Register > CoalUpd , PredUpd ; SmallVector < MachineInstr * , <NUM_LIT> > Condsets ; for ( auto & B : MF ) for ( auto & I : B ) if ( isCondset ( I ) ) Condsets . push_back ( & I ) ; Changed |= coalesceSegments ( Condsets , CoalUpd ) ; std :: set < Register > KillUpd ;

for ( MachineInstr * MI : Condsets ) for ( MachineOperand & Op : MI -> operands ( ) ) if ( Op . isReg ( ) && Op . isUse ( ) ) if ( ! CoalUpd . count ( Op . getReg ( ) ) ) KillUpd . insert ( Op . getReg ( ) ) ;


<s> MachineBasicBlock :: iterator At = MI ; auto updateRegs = [ & UpdRegs ] ( const MachineInstr & MI ) -> void { for ( auto & Op : MI . operands ( ) ) if ( Op . isReg ( ) ) UpdRegs . insert ( Op . getReg ( ) ) ; } ; MachineOperand & ST = MI . getOperand ( <NUM_LIT> ) ; MachineOperand & SF = MI . getOperand ( <NUM_LIT> ) ; if ( ST . isReg ( ) && SF . isReg ( ) ) { RegisterRef RT ( ST ) ; if ( RT == RegisterRef ( SF ) ) { updateRegs ( MI ) ; MI . setDesc ( HII -> get ( TargetOpcode :: COPY ) ) ; unsigned S = getRegState ( ST ) ; while ( MI . getNumOperands ( ) > <NUM_LIT> ) MI . removeOperand ( MI . getNumOperands ( ) - <NUM_LIT> ) ; MachineFunction & MF = * MI . getParent ( ) -> getParent ( ) ;


<s> } LI . clear ( ) ; LIS -> constructMainRangeFromSubranges ( LI ) ; } else { updateDeadsInRange ( Reg , MRI -> getMaxLaneMaskForVReg ( Reg ) , LI ) ;


<s> if ( ! DR . isVirtual ( ) || DR != Reg ) return { false , false } ; LaneBitmask SLM = getLaneMask ( DR , DSR ) ; LaneBitmask A = SLM & LM ; return { A . any ( ) , A == SLM } ; } ; auto Dominate = [ this ] ( SetVector < MachineBasicBlock * > & Defs , MachineBasicBlock * Dest ) -> bool { for ( MachineBasicBlock * D : Defs ) if ( D != Dest && MDT -> dominates ( D , Dest ) ) return true ; MachineBasicBlock * Entry = & Dest -> getParent ( ) -> front ( ) ; SetVector < MachineBasicBlock * > Work ( Dest -> pred_begin ( ) , Dest -> pred_end ( ) ) ; for ( unsigned i = <NUM_LIT> ; i < Work . size ( ) ; ++ i ) { MachineBasicBlock * B = Work [ i ] ; if ( Defs . count ( B ) ) continue ; if ( B == Entry ) return false ; for ( auto * P : B -> predecessors ( ) ) Work . insert ( P ) ; } return true ; } ; SetVector < MachineBasicBlock * > Defs ; SmallVector < SlotIndex , <NUM_LIT> > PredDefs ; for ( auto & Seg : Range ) { if ( ! Seg . start . isRegister ( ) ) continue ; MachineInstr * DefI = LIS -> getInstructionFromIndex ( Seg . start ) ; Defs . insert ( DefI -> getParent ( ) ) ; if ( HII -> isPredicated ( * DefI ) ) PredDefs . push_back ( Seg . start ) ; }

SmallVector < SlotIndex , <NUM_LIT> > Undefs ;


<s> } if ( Recalc ) recalculateLiveInterval ( R ) ; if ( UpdateKills ) MRI -> clearKillFlags ( R ) ; if ( UpdateDeads ) updateDeadFlags ( R ) ;

if ( UpdateKills ) updateKillFlags ( R ) ;


<s> MachineBasicBlock * PB = LIS -> getMBBFromIndex ( PE ) ; if ( PB != MB && ! LIS -> isLiveInToMBB ( LID , MB ) ) Undef = true ; } if ( ! Undef ) { makeUndead ( DefR , P -> valno -> def ) ; P -> end = MX ; } else { ImpUse . setIsUndef ( true ) ; } if ( ! MI -> readsRegister ( DefR ) ) MI -> addOperand ( ImpUse ) ; if ( N != LID . end ( ) ) makeDefined ( DefR , N -> start , true ) ; } LiveRange :: Segment NR = LiveRange :: Segment ( MX , EX , VN ) ; LID . addSegment ( NR ) ; DEBUG ( dbgs ( ) << <STR_LIT> << NR << <STR_LIT> << LID << <STR_LIT> ) ; shrinkToUses ( DefR , LID ) ; DEBUG ( dbgs ( ) << <STR_LIT> << * MI ) ; LID . verify ( ) ; } for ( auto & Op : MI -> operands ( ) ) { if ( ! Op . isReg ( ) || ! Op . isUse ( ) || Op . isImplicit ( ) || Op . isUndef ( ) ) continue ; unsigned UseR = Op . getReg ( ) ; LiveInterval & LIU = LIS -> getInterval ( UseR ) ; LiveInterval :: iterator P = LIU . FindSegmentContaining ( MX ) ; if ( P == LIU . end ( ) ) P = prevSegment ( LIU , MX ) ; assert ( P != LIU . end ( ) && <STR_LIT> ) ; SlotIndex EX = P -> end ; if ( EX > MX ) {


<s> if ( TheI -> hasUnmodeledSideEffects ( ) ) return false ; MachineBasicBlock :: iterator StartI = IsDown ? TheI : ToI ; MachineBasicBlock :: iterator EndI = IsDown ? ToI : TheI ; bool Ordered = TheI -> hasOrderedMemoryRef ( ) ; for ( MachineBasicBlock :: iterator I = std :: next ( StartI ) ; I != EndI ; ++ I ) { MachineInstr * MI = & * I ; if ( MI -> hasUnmodeledSideEffects ( ) ) return false ; bool L = MI -> mayLoad ( ) , S = MI -> mayStore ( ) ; if ( ! L && ! S ) continue ; if ( Ordered && MI -> hasOrderedMemoryRef ( ) ) return false ; bool Conflict = ( L && IsStore ) || S ;


<s> if ( ! TargetRegisterInfo :: isVirtualRegister ( RR . Reg ) ) return false ; if ( isRefInMap ( RR , Defs , Exec_Then ) ) return false ;

if ( Op . isDef ( ) && isRefInMap ( RR , Uses , Exec_Then ) ) return false ;


<s> if ( ! TargetRegisterInfo :: isVirtualRegister ( RR . Reg ) ) return false ; if ( isRefInMap ( RR , Defs , Exec_Then ) ) return false ; if ( Op . isDef ( ) && isRefInMap ( RR , Uses , Exec_Then ) ) return false ;


<s> if ( MRI -> isLiveIn ( R2 . Reg ) ) return false ; LiveInterval & L1 = LIS -> getInterval ( R1 . Reg ) ; LiveInterval & L2 = LIS -> getInterval ( R2 . Reg ) ; bool Overlap = L1 . overlaps ( L2 ) ; DEBUG ( dbgs ( ) << <STR_LIT> << ( Overlap ? <STR_LIT> : <STR_LIT> ) << <STR_LIT> << PrintReg ( R1 . Reg , TRI , R1 . Sub ) << <STR_LIT> << L1 << <STR_LIT> << PrintReg ( R2 . Reg , TRI , R2 . Sub ) << <STR_LIT> << L2 << <STR_LIT> ) ; if ( R1 . Sub || R2 . Sub ) return false ; if ( Overlap ) return false ; if ( ! isIntraBlocks ( L1 ) && ! isIntraBlocks ( L2 ) ) return false ; MRI -> replaceRegWith ( R2 . Reg , R1 . Reg ) ; typedef DenseMap < VNInfo * , VNInfo * > ValueInfoMap ; ValueInfoMap VM ; for ( LiveInterval :: iterator I = L2 . begin ( ) , E = L2 . end ( ) ; I != E ; ++ I ) { VNInfo * NewVN , * OldVN = I -> valno ; ValueInfoMap :: iterator F = VM . find ( OldVN ) ; if ( F == VM . end ( ) ) {

NewVN = L1 . getNextValue ( I -> valno -> def , LIS -> getVNInfoAllocator ( ) ) ;


<s> for ( MachineBasicBlock :: iterator J = B . begin ( ) , F = B . end ( ) ; J != F ; ++ J ) { MachineInstr * MI = & * J ; if ( ! isCondset ( MI ) ) continue ; MachineOperand & S1 = MI -> getOperand ( <NUM_LIT> ) , & S2 = MI -> getOperand ( <NUM_LIT> ) ; if ( ! S1 . isReg ( ) && ! S2 . isReg ( ) ) continue ; Condsets . push_back ( MI ) ; } } bool Changed = false ; for ( unsigned i = <NUM_LIT> , n = Condsets . size ( ) ; i < n ; ++ i ) { MachineInstr * CI = Condsets [ i ] ; RegisterRef RD = CI -> getOperand ( <NUM_LIT> ) ; RegisterRef RP = CI -> getOperand ( <NUM_LIT> ) ; MachineOperand & S1 = CI -> getOperand ( <NUM_LIT> ) , & S2 = CI -> getOperand ( <NUM_LIT> ) ; bool Done = false ; if ( S1 . isReg ( ) ) { RegisterRef RS = S1 ; MachineInstr * RDef = getReachingDefForPred ( RS , CI , RP . Reg , true ) ; if ( ! RDef || ! HII -> isPredicable ( * RDef ) ) Done = coalesceRegisters ( RD , RegisterRef ( S1 ) ) ; }


<s> RegisterRef RD = CI -> getOperand ( <NUM_LIT> ) ; RegisterRef RP = CI -> getOperand ( <NUM_LIT> ) ; MachineOperand & S1 = CI -> getOperand ( <NUM_LIT> ) , & S2 = CI -> getOperand ( <NUM_LIT> ) ; bool Done = false ; if ( S1 . isReg ( ) ) { RegisterRef RS = S1 ; MachineInstr * RDef = getReachingDefForPred ( RS , CI , RP . Reg , true ) ; if ( ! RDef || ! HII -> isPredicable ( * RDef ) ) Done = coalesceRegisters ( RD , RegisterRef ( S1 ) ) ; } if ( ! Done && S2 . isReg ( ) ) { RegisterRef RS = S2 ;

MachineInstr * RDef = getReachingDefForPred ( RS , CI , RP . Reg , false ) ;


<s> MachineInstr * MI = SrcOp . getParent ( ) ; MachineBasicBlock & B = * MI -> getParent ( ) ; MachineBasicBlock :: iterator At = MI ; DebugLoc DL = MI -> getDebugLoc ( ) ; unsigned Opc = getCondTfrOpcode ( SrcOp , Cond ) ; MachineInstr * TfrI = BuildMI ( B , At , DL , HII -> get ( Opc ) ) . addReg ( DstR , RegState :: Define , DstSR ) . addOperand ( PredOp ) . addOperand ( SrcOp ) ; TfrI -> clearKillInfo ( ) ; DEBUG ( dbgs ( ) << <STR_LIT> << * TfrI ) ; return TfrI ;


<s> MachineInstr * TfrI = BuildMI ( B , At , DL , HII -> get ( Opc ) ) . addReg ( DstR , RegState :: Define , DstSR ) . addOperand ( PredOp ) . addOperand ( SrcOp ) ; TfrI -> clearKillInfo ( ) ; DEBUG ( dbgs ( ) << <STR_LIT> << * TfrI ) ; return TfrI ;


<s> AU . addPreserved < SlotIndexes > ( ) ;

MachineFunctionPass :: getAnalysisUsage ( AU ) ;


<s> AU . addRequired < LiveIntervals > ( ) ;

AU . addPreserved < LiveIntervals > ( ) ;


<s> using namespace <ISA_LIT> ; if ( SO . isReg ( ) ) { unsigned PhysR ; RegisterRef RS = SO ; if ( TargetRegisterInfo :: isVirtualRegister ( RS . Reg ) ) { const TargetRegisterClass * VC = MRI -> getRegClass ( RS . Reg ) ; assert ( VC -> begin ( ) != VC -> end ( ) && <STR_LIT> ) ;


<s> return Sub_Low ; case <STR_LIT> : return Sub_High ; case <STR_LIT> : return Sub_None ; }


<s> unsigned <ISA_LIT>ExpandCondsets :: getMaskForSub ( unsigned Sub ) { switch ( Sub ) { case <STR_LIT> : return Sub_Low ; case <STR_LIT> : return Sub_High ; case <STR_LIT> : return Sub_None ;


<s> virtual const char * getPassName ( ) const { return <STR_LIT> ;


<s> bool PredValid = true ; do { -- I ; MachineInstr * MI = & * I ; if ( PredValid && HII -> isPredicated ( * MI ) ) { if ( MI -> readsRegister ( PredR ) && ( Cond != HII -> isPredicatedTrue ( * MI ) ) ) continue ; } for ( auto & Op : MI -> operands ( ) ) { if ( ! Op . isReg ( ) || ! Op . isDef ( ) ) continue ; RegisterRef RR = Op ;


MachineFunctionPass ( ID ) , HII ( <NUM_LIT> ) , TRI ( <NUM_LIT> ) , MRI ( <NUM_LIT> ) , LIS ( <NUM_LIT> ) , CoaLimitActive ( false ) , TfrLimitActive ( false ) , CoaCounter ( <NUM_LIT> ) , TfrCounter ( <NUM_LIT> ) {


<s> PassInfo * PI = new PassInfo ( Name , <STR_LIT> , & <ISA_LIT>ExpandCondsets :: ID , <NUM_LIT> , false , false ) ; Registry . registerPass ( * PI , true ) ;


<s> case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : return true ; break ; }


<s> unsigned Opc = MI -> getOpcode ( ) ; switch ( Opc ) { case <STR_LIT> : case <STR_LIT> :


<s> for ( auto & Op : MI -> operands ( ) ) {

if ( ! Op . isReg ( ) || ! Op . isUse ( ) || Op . getReg ( ) != Reg ) continue ;


<s> Defs . push_back ( MI ) ; } for ( unsigned i = <NUM_LIT> , n = Defs . size ( ) ; i < n ; ++ i ) { MachineInstr * MI = Defs [ i ] ; for ( auto & Op : MI -> operands ( ) ) { if ( ! Op . isReg ( ) || ! Op . isDef ( ) || Op . getReg ( ) != Reg ) continue ; Op . setIsDead ( false ) ; }


<s> LiveInterval & LI = LIS -> getInterval ( Reg ) ; for ( LiveInterval :: iterator I = LI . begin ( ) , E = LI . end ( ) ; I != E ; ++ I ) { if ( ! I -> start . isRegister ( ) || ! I -> end . isBlock ( ) ) continue ; MachineInstr * MI = LIS -> getInstructionFromIndex ( I -> start ) ; Defs . push_back ( MI ) ; } } else if ( S . isRegister ( ) ) { MachineInstr * MI = LIS -> getInstructionFromIndex ( S ) ; Defs . push_back ( MI ) ; } for ( unsigned i = <NUM_LIT> , n = Defs . size ( ) ; i < n ; ++ i ) { MachineInstr * MI = Defs [ i ] ; for ( auto & Op : MI -> operands ( ) ) {

if ( ! Op . isReg ( ) || ! Op . isDef ( ) || Op . getReg ( ) != Reg ) continue ;


<s> if ( I -> start >= S ) return I ; } return LI . end ( ) ;


<s> MachineInstr * MI = & * I ; RegisterSet Undefs ; for ( unsigned i = MI -> getNumOperands ( ) ; i > <NUM_LIT> ; -- i ) { MachineOperand & MO = MI -> getOperand ( i - <NUM_LIT> ) ; if ( MO . isReg ( ) && MO . isUse ( ) && MO . isImplicit ( ) && MO . isUndef ( ) ) { MI -> RemoveOperand ( i - <NUM_LIT> ) ;


<s> } } for ( auto & Op : MI -> operands ( ) ) { if ( ! Op . isReg ( ) || ! Op . isDef ( ) || ! Op . getSubReg ( ) ) continue ; if ( Undefs . count ( Op . getReg ( ) ) ) Op . setIsUndef ( true ) ; }


<s> DEBUG ( dbgs ( ) << <STR_LIT> << * DefI ) ; ReferenceMap Uses , Defs ; MachineBasicBlock :: iterator DefIt = DefI , TfrIt = TfrI ; bool PredValid = true ; for ( MachineBasicBlock :: iterator I = std :: next ( DefIt ) ; I != TfrIt ; ++ I ) { if ( ! I -> modifiesRegister ( PredR , <NUM_LIT> ) ) continue ; PredValid = false ; break ; } for ( MachineBasicBlock :: iterator I = std :: next ( DefIt ) ; I != TfrIt ; ++ I ) { MachineInstr * MI = & * I ; unsigned Exec = Exec_Then | Exec_Else ; if ( PredValid && HII -> isPredicated ( * MI ) && MI -> readsRegister ( PredR ) ) Exec = ( Cond == HII -> isPredicatedTrue ( * MI ) ) ? Exec_Then : Exec_Else ; for ( auto & Op : MI -> operands ( ) ) { if ( ! Op . isReg ( ) ) continue ; RegisterRef RR = Op ; if ( ! TargetRegisterInfo :: isVirtualRegister ( RR . Reg ) ) return false ; ReferenceMap & Map = Op . isDef ( ) ? Defs : Uses ; addRefToMap ( RR , Map , Exec ) ; } } if ( isRefInMap ( RT , Defs , Exec_Then ) || isRefInMap ( RT , Uses , Exec_Else ) ) return false ; RegisterRef RD = MD ; bool CanUp = canMoveOver ( TfrI , Defs , Uses ) ; bool CanDown = canMoveOver ( DefI , Defs , Uses ) ; if ( DefI -> mayLoad ( ) || DefI -> mayStore ( ) ) if ( ! canMoveMemTo ( DefI , TfrI , true ) ) CanDown = false ; DEBUG ( dbgs ( ) << <STR_LIT> << ( CanUp ? <STR_LIT> : <STR_LIT> ) << <STR_LIT> << ( CanDown ? <STR_LIT> : <STR_LIT> ) ) ; MachineBasicBlock :: iterator PastDefIt = std :: next ( DefIt ) ;

if ( CanUp ) predicateAt ( RD , DefI , PastDefIt , PredR , Cond ) ;


<s> for ( MachineBasicBlock :: iterator I = std :: next ( DefIt ) ; I != TfrIt ; ++ I ) { if ( ! I -> modifiesRegister ( PredR , <NUM_LIT> ) ) continue ; PredValid = false ; break ; } for ( MachineBasicBlock :: iterator I = std :: next ( DefIt ) ; I != TfrIt ; ++ I ) { MachineInstr * MI = & * I ; unsigned Exec = Exec_Then | Exec_Else ; if ( PredValid && HII -> isPredicated ( * MI ) && MI -> readsRegister ( PredR ) ) Exec = ( Cond == HII -> isPredicatedTrue ( * MI ) ) ? Exec_Then : Exec_Else ; for ( auto & Op : MI -> operands ( ) ) { if ( ! Op . isReg ( ) ) continue ; RegisterRef RR = Op ; if ( ! TargetRegisterInfo :: isVirtualRegister ( RR . Reg ) ) return false ; ReferenceMap & Map = Op . isDef ( ) ? Defs : Uses ; addRefToMap ( RR , Map , Exec ) ; } } if ( isRefInMap ( RT , Defs , Exec_Then ) || isRefInMap ( RT , Uses , Exec_Else ) ) return false ;


<s> for ( I = B . begin ( ) , E = B . end ( ) ; I != E ; I = NextI ) { NextI = std :: next ( I ) ; unsigned Opc = I -> getOpcode ( ) ; if ( Opc == <STR_LIT> || Opc == <STR_LIT> ) { bool Done = predicate ( I , ( Opc == <STR_LIT> ) ) ; if ( ! Done ) { if ( RegisterRef ( I -> getOperand ( <NUM_LIT> ) ) == RegisterRef ( I -> getOperand ( <NUM_LIT> ) ) ) removeInstrFromLiveness ( I ) ; } Changed |= Done ; }


<s> void <ISA_LIT>ExpandCondsets :: removeImplicitUses ( MachineBasicBlock & B ) { for ( MachineInstr & MI : B ) if ( HII -> isPredicated ( MI ) ) removeImplicitUses ( & MI ) ;


<s> void <ISA_LIT>ExpandCondsets :: removeImplicitUses ( MachineBasicBlock & B ) {

for ( MachineInstr & MI : B ) if ( HII -> isPredicated ( MI ) ) removeImplicitUses ( & MI ) ;


<s> unsigned DefR = Op . getReg ( ) ; LiveInterval & LID = LIS -> getInterval ( DefR ) ; LiveInterval :: iterator LT = LID . FindSegmentContaining ( MX ) ; assert ( LT != LID . end ( ) && <STR_LIT> ) ; DEBUG ( dbgs ( ) << <STR_LIT> << MX << <STR_LIT> << PrintReg ( DefR , TRI ) << <STR_LIT> << LID << <STR_LIT> ) ; if ( LT -> start != MX ) continue ; VNInfo * MVN = LT -> valno ; if ( LT != LID . begin ( ) ) { LiveInterval :: iterator P = std :: prev ( LT ) ; SlotIndex PE = P -> end . isBlock ( ) ? P -> end . getPrevIndex ( ) : P -> end ; MachineBasicBlock * MB = MI -> getParent ( ) ; MachineBasicBlock * PB = LIS -> getMBBFromIndex ( PE ) ; if ( PB != MB && ! LIS -> isLiveInToMBB ( LID , MB ) ) { makeDefined ( DefR , LT -> end , false ) ; LID . removeSegment ( * LT ) ; } else { P -> end = LT -> start ; makeUndead ( DefR , P -> valno -> def ) ; LID . MergeValueNumberInto ( MVN , P -> valno ) ; } } else { LiveInterval :: iterator N = std :: next ( LT ) ; LiveInterval :: iterator RmB = LT , RmE = N ; while ( N != LID . end ( ) ) { LiveInterval :: iterator Next = std :: next ( N ) ; if ( N -> start . isRegister ( ) ) { makeDefined ( DefR , N -> start , false ) ; break ; } if ( N -> end . isRegister ( ) ) { makeDefined ( DefR , N -> end , false ) ; RmE = Next ; break ; } RmE = Next ; N = Next ; } LID . segments . erase ( RmB , RmE ) ; } bool VNUsed = false ; for ( LiveInterval :: iterator I = LID . begin ( ) , E = LID . end ( ) ; I != E ; ++ I ) { if ( I -> valno != MVN ) continue ; VNUsed = true ; break ; } if ( ! VNUsed ) MVN -> markUnused ( ) ; DEBUG ( dbgs ( ) << <STR_LIT> ) ; if ( ! LID . empty ( ) ) { DEBUG ( dbgs ( ) << LID << <STR_LIT> ) ; LID . verify ( ) ; } else { DEBUG ( dbgs ( ) << <STR_LIT> ) ; LIS -> removeInterval ( DefR ) ; } }

SmallVector < unsigned , <NUM_LIT> > Uses ;


<s> RmE = Next ; break ; } RmE = Next ; N = Next ; } LID . segments . erase ( RmB , RmE ) ; } bool VNUsed = false ; for ( LiveInterval :: iterator I = LID . begin ( ) , E = LID . end ( ) ; I != E ; ++ I ) { if ( I -> valno != MVN ) continue ; VNUsed = true ; break ; } if ( ! VNUsed ) MVN -> markUnused ( ) ; DEBUG ( dbgs ( ) << <STR_LIT> ) ; if ( ! LID . empty ( ) ) { DEBUG ( dbgs ( ) << LID << <STR_LIT> ) ; LID . verify ( ) ; } else { DEBUG ( dbgs ( ) << <STR_LIT> ) ; LIS -> removeInterval ( DefR ) ; } } SmallVector < unsigned , <NUM_LIT> > Uses ; for ( auto & Op : MI -> operands ( ) ) { if ( ! Op . isReg ( ) || ! Op . isUse ( ) ) continue ; unsigned R = Op . getReg ( ) ; if ( ! TargetRegisterInfo :: isVirtualRegister ( R ) ) continue ; Uses . push_back ( R ) ; } LIS -> RemoveMachineInstrFromMaps ( * MI ) ; MI -> eraseFromParent ( ) ; for ( unsigned i = <NUM_LIT> , n = Uses . size ( ) ; i < n ; ++ i ) {

LiveInterval & LI = LIS -> getInterval ( Uses [ i ] ) ;


<s> MRI = & MF . getRegInfo ( ) ; bool Changed = false ; Changed |= coalesceSegments ( MF ) ; for ( MachineFunction :: iterator I = MF . begin ( ) , E = MF . end ( ) ; I != E ; ++ I ) { Changed |= splitInBlock ( * I ) ; Changed |= predicateInBlock ( * I ) ;


<s> } LiveInterval :: iterator End = LI . end ( ) ; SlotIndex S = LIS -> getInstructionIndex ( * MI ) . getRegSlot ( ) ; LiveInterval :: iterator T = LI . FindSegmentContaining ( S ) ; assert ( T != End ) ; LiveInterval :: iterator N = std :: next ( T ) ;


<s> bool <ISA_LIT>ExpandCondsets :: split ( MachineInstr * MI ) { if ( TfrLimitActive ) { if ( TfrCounter >= TfrLimit ) return false ; TfrCounter ++ ; } DEBUG ( dbgs ( ) << <STR_LIT> << MI -> getParent ( ) -> getNumber ( ) << <STR_LIT> << * MI ) ; MachineOperand & MD = MI -> getOperand ( <NUM_LIT> ) ; MachineOperand & MP = MI -> getOperand ( <NUM_LIT> ) ; assert ( MD . isDef ( ) ) ; unsigned DR = MD . getReg ( ) , DSR = MD . getSubReg ( ) ; if ( MachineInstr * TfrT = genTfrFor ( MI -> getOperand ( <NUM_LIT> ) , DR , DSR , MP , true ) ) addInstrToLiveness ( TfrT ) ; if ( MachineInstr * TfrF = genTfrFor ( MI -> getOperand ( <NUM_LIT> ) , DR , DSR , MP , false ) ) addInstrToLiveness ( TfrF ) ; removeInstrFromLiveness ( MI ) ; return true ;


<s> MachineBasicBlock :: iterator I , E , NextI ; for ( I = B . begin ( ) , E = B . end ( ) ; I != E ; I = NextI ) { NextI = std :: next ( I ) ;

if ( isCondset ( I ) ) Changed |= split ( I ) ;


<s> bool Changed = false ; MachineBasicBlock :: iterator I , E , NextI ; for ( I = B . begin ( ) , E = B . end ( ) ; I != E ; I = NextI ) {


<s> if ( ! EX . isBlock ( ) ) return ; VNInfo * NewVN = <NUM_LIT> ; for ( LiveInterval :: iterator I = LI . begin ( ) , E = LI . end ( ) ; I != E ; ++ I ) {

if ( ! I -> start . isBlock ( ) || I -> valno != OldVN ) continue ;


<s> if ( ! I -> start . isBlock ( ) || I -> valno != OldVN ) continue ; if ( ! NewVN ) NewVN = LI . getNextValue ( I -> start , LIS -> getVNInfoAllocator ( ) ) ; I -> valno = NewVN ;


<s> void <ISA_LIT>ExpandCondsets :: updateKillFlags ( unsigned Reg , LiveInterval & LI ) { MRI -> clearKillFlags ( Reg ) ; for ( LiveInterval :: iterator I = LI . begin ( ) , E = LI . end ( ) ; I != E ; ++ I ) { SlotIndex EX = I -> end ; if ( ! EX . isRegister ( ) ) continue ; MachineInstr * MI = LIS -> getInstructionFromIndex ( EX ) ; for ( auto & Op : MI -> operands ( ) ) {


<s> for ( auto & Op : MI -> operands ( ) ) { if ( ! Op . isReg ( ) || ! Op . isUse ( ) || Op . getReg ( ) != Reg ) continue ;


<s> NextI = std :: next ( I ) ; unsigned Opc = I -> getOpcode ( ) ; if ( Opc == <STR_LIT> || Opc == <STR_LIT> ) { bool Done = predicate ( * I , ( Opc == <STR_LIT> ) , UpdRegs ) ; if ( ! Done ) { if ( RegisterRef ( I -> getOperand ( <NUM_LIT> ) ) == RegisterRef ( I -> getOperand ( <NUM_LIT> ) ) ) { for ( auto & Op : I -> operands ( ) ) if ( Op . isReg ( ) ) UpdRegs . insert ( Op . getReg ( ) ) ; removeInstr ( * I ) ; } } Changed |= Done ; }


<s> bool Done = predicate ( * I , ( Opc == <STR_LIT> ) , UpdRegs ) ; if ( ! Done ) { if ( RegisterRef ( I -> getOperand ( <NUM_LIT> ) ) == RegisterRef ( I -> getOperand ( <NUM_LIT> ) ) ) { for ( auto & Op : I -> operands ( ) ) if ( Op . isReg ( ) ) UpdRegs . insert ( Op . getReg ( ) ) ; removeInstr ( * I ) ; } } Changed |= Done ; } } return Changed ;


<s> Register DR = MD . getReg ( ) , DSR = MD . getSubReg ( ) ; bool ReadUndef = MD . isUndef ( ) ; MachineBasicBlock :: iterator At = MI ; auto updateRegs = [ & UpdRegs ] ( const MachineInstr & MI ) -> void { for ( auto & Op : MI . operands ( ) ) if ( Op . isReg ( ) ) UpdRegs . insert ( Op . getReg ( ) ) ; } ; MachineOperand & ST = MI . getOperand ( <NUM_LIT> ) ; MachineOperand & SF = MI . getOperand ( <NUM_LIT> ) ; if ( ST . isReg ( ) && SF . isReg ( ) ) { RegisterRef RT ( ST ) ; if ( RT == RegisterRef ( SF ) ) { updateRegs ( MI ) ; MI . setDesc ( HII -> get ( TargetOpcode :: COPY ) ) ;


<s> unsigned DefR = Defs [ i ] . Reg ; LiveInterval & LID = LIS -> getInterval ( DefR ) ; DEBUG ( dbgs ( ) << <STR_LIT> << PrintReg ( DefR , TRI ) << <STR_LIT> << LID << <STR_LIT> ) ; LiveInterval :: iterator LT = LID . FindSegmentContaining ( MX ) ; if ( LT != LID . end ( ) ) terminateSegment ( LT , MX , LID ) ; DEBUG ( dbgs ( ) << <STR_LIT> << LID << <STR_LIT> ) ; LiveInterval :: iterator P = prevSegment ( LID , MX ) , N = nextSegment ( LID , MX ) ; SlotIndex EX ; VNInfo * VN = LID . getNextValue ( MX , LIS -> getVNInfoAllocator ( ) ) ; if ( N == LID . end ( ) ) { EX = LIS -> getMBBEndIdx ( MB ) ; } else { EX = N -> start . isBlock ( ) ? N -> start . getPrevIndex ( ) : N -> start ; } if ( Predicated ) { MachineOperand ImpUse = MachineOperand :: CreateReg ( DefR , false , true ) ; ImpUse . setSubReg ( Defs [ i ] . Sub ) ; bool Undef = false ; if ( P == LID . end ( ) ) Undef = true ; else { SlotIndex PE = P -> end . isBlock ( ) ? P -> end . getPrevIndex ( ) : P -> end ; MachineBasicBlock * PB = LIS -> getMBBFromIndex ( PE ) ; if ( PB != MB && ! LIS -> isLiveInToMBB ( LID , MB ) ) Undef = true ; } if ( ! Undef ) { makeUndead ( DefR , P -> valno -> def ) ; P -> end = MX ; } else { ImpUse . setIsUndef ( true ) ; } if ( ! MI -> readsRegister ( DefR ) ) MI -> addOperand ( ImpUse ) ; if ( N != LID . end ( ) ) makeDefined ( DefR , N -> start , true ) ; } LiveRange :: Segment NR = LiveRange :: Segment ( MX , EX , VN ) ; LID . addSegment ( NR ) ; DEBUG ( dbgs ( ) << <STR_LIT> << NR << <STR_LIT> << LID << <STR_LIT> ) ; shrinkToUses ( DefR , LID ) ;

DEBUG ( dbgs ( ) << <STR_LIT> << * MI ) ;


<s> bool Done = false ; if ( S1 . isReg ( ) ) { RegisterRef RS = S1 ; MachineInstr * RDef = getReachingDefForPred ( RS , CI , RP . Reg , true ) ; if ( ! RDef || ! HII -> isPredicable ( RDef ) ) Done = coalesceRegisters ( RD , RegisterRef ( S1 ) ) ; } if ( ! Done && S2 . isReg ( ) ) { RegisterRef RS = S2 ; MachineInstr * RDef = getReachingDefForPred ( RS , CI , RP . Reg , false ) ; if ( ! RDef || ! HII -> isPredicable ( RDef ) ) Done = coalesceRegisters ( RD , RegisterRef ( S2 ) ) ;


<s> if ( ! isCondset ( MI ) ) continue ; MachineOperand & S1 = MI -> getOperand ( <NUM_LIT> ) , & S2 = MI -> getOperand ( <NUM_LIT> ) ; if ( ! S1 . isReg ( ) && ! S2 . isReg ( ) ) continue ; Condsets . push_back ( MI ) ; } } bool Changed = false ; for ( unsigned i = <NUM_LIT> , n = Condsets . size ( ) ; i < n ; ++ i ) { MachineInstr * CI = Condsets [ i ] ; RegisterRef RD = CI -> getOperand ( <NUM_LIT> ) ; RegisterRef RP = CI -> getOperand ( <NUM_LIT> ) ; MachineOperand & S1 = CI -> getOperand ( <NUM_LIT> ) , & S2 = CI -> getOperand ( <NUM_LIT> ) ; bool Done = false ; if ( S1 . isReg ( ) ) { RegisterRef RS = S1 ; MachineInstr * RDef = getReachingDefForPred ( RS , CI , RP . Reg , true ) ;

if ( ! RDef || ! HII -> isPredicable ( RDef ) ) Done = coalesceRegisters ( RD , RegisterRef ( S1 ) ) ;


<s> if ( MI -> readsRegister ( PredR ) && ( Cond != HII -> isPredicatedTrue ( MI ) ) ) continue ; } for ( auto & Op : MI -> operands ( ) ) { if ( ! Op . isReg ( ) || ! Op . isDef ( ) ) continue ; RegisterRef RR = Op ; if ( RR . Reg == PredR ) { PredValid = false ; continue ; } if ( RR . Reg != RD . Reg ) continue ; if ( RR . Sub == RD . Sub ) return MI ; if ( RR . Sub == <NUM_LIT> || RD . Sub == <NUM_LIT> ) return <NUM_LIT> ; }


<s> for ( auto & Op : MI -> operands ( ) ) { if ( ! Op . isReg ( ) || ! Op . isDef ( ) ) continue ; RegisterRef RR = Op ; if ( RR . Reg == PredR ) { PredValid = false ; continue ; } if ( RR . Reg != RD . Reg ) continue ; if ( RR . Sub == RD . Sub ) return MI ; if ( RR . Sub == <NUM_LIT> || RD . Sub == <NUM_LIT> ) return <NUM_LIT> ; } } while ( I != S ) ; return <NUM_LIT> ;


<s> DEBUG ( dbgs ( ) << <STR_LIT> << ( Cond ? <STR_LIT> : <STR_LIT> ) << <STR_LIT> << * TfrI ) ; MachineOperand & MD = TfrI -> getOperand ( <NUM_LIT> ) ; MachineOperand & MP = TfrI -> getOperand ( <NUM_LIT> ) ; MachineOperand & MS = TfrI -> getOperand ( <NUM_LIT> ) ; if ( ! MS . isKill ( ) ) return false ; RegisterRef RT ( MS ) ; unsigned PredR = MP . getReg ( ) ; MachineInstr * DefI = getReachingDefForPred ( RT , TfrI , PredR , Cond ) ; if ( ! DefI || ! isPredicable ( DefI ) ) return false ; DEBUG ( dbgs ( ) << <STR_LIT> << * DefI ) ; ReferenceMap Uses , Defs ; MachineBasicBlock :: iterator DefIt = DefI , TfrIt = TfrI ; bool PredValid = true ; for ( MachineBasicBlock :: iterator I = std :: next ( DefIt ) ; I != TfrIt ; ++ I ) { if ( ! I -> modifiesRegister ( PredR , <NUM_LIT> ) ) continue ;


<s> MachineInstr * DefI = getReachingDefForPred ( RT , TfrI , PredR , Cond ) ; if ( ! DefI || ! isPredicable ( DefI ) ) return false ; DEBUG ( dbgs ( ) << <STR_LIT> << * DefI ) ; ReferenceMap Uses , Defs ; MachineBasicBlock :: iterator DefIt = DefI , TfrIt = TfrI ; bool PredValid = true ; for ( MachineBasicBlock :: iterator I = std :: next ( DefIt ) ; I != TfrIt ; ++ I ) { if ( ! I -> modifiesRegister ( PredR , <NUM_LIT> ) ) continue ; PredValid = false ; break ; } for ( MachineBasicBlock :: iterator I = std :: next ( DefIt ) ; I != TfrIt ; ++ I ) { MachineInstr * MI = & * I ; unsigned Exec = Exec_Then | Exec_Else ; if ( PredValid && HII -> isPredicated ( MI ) && MI -> readsRegister ( PredR ) ) Exec = ( Cond == HII -> isPredicatedTrue ( MI ) ) ? Exec_Then : Exec_Else ; for ( auto & Op : MI -> operands ( ) ) { if ( ! Op . isReg ( ) ) continue ; RegisterRef RR = Op ; if ( ! TargetRegisterInfo :: isVirtualRegister ( RR . Reg ) ) return false ; ReferenceMap & Map = Op . isDef ( ) ? Defs : Uses ; addRefToMap ( RR , Map , Exec ) ; } } if ( isRefInMap ( RT , Defs , Exec_Then ) || isRefInMap ( RT , Uses , Exec_Else ) ) return false ; RegisterRef RD = MD ; bool CanUp = canMoveOver ( TfrI , Defs , Uses ) ; bool CanDown = canMoveOver ( DefI , Defs , Uses ) ; if ( DefI -> mayLoad ( ) || DefI -> mayStore ( ) ) if ( ! canMoveMemTo ( DefI , TfrI , true ) ) CanDown = false ;

DEBUG ( dbgs ( ) << <STR_LIT> << ( CanUp ? <STR_LIT> : <STR_LIT> ) << <STR_LIT> << ( CanDown ? <STR_LIT> : <STR_LIT> ) ) ;


<s> void <ISA_LIT>ExpandCondsets :: removeImplicitUses ( MachineBasicBlock & B ) { for ( MachineBasicBlock :: iterator I = B . begin ( ) , E = B . end ( ) ; I != E ; ++ I ) {


<s> for ( MachineBasicBlock :: iterator I = B . begin ( ) , E = B . end ( ) ; I != E ; ++ I ) { MachineInstr * MI = & * I ; if ( HII -> isPredicated ( MI ) ) removeImplicitUses ( MI ) ;


<s> void <ISA_LIT>ExpandCondsets :: renameInRange ( RegisterRef RO , RegisterRef RN , unsigned PredR , bool Cond , MachineBasicBlock :: iterator First , MachineBasicBlock :: iterator Last ) { MachineBasicBlock :: iterator End = std :: next ( Last ) ; for ( MachineBasicBlock :: iterator I = First ; I != End ; ++ I ) { MachineInstr * MI = & * I ; if ( ! HII -> isPredicated ( MI ) ) continue ; if ( ! MI -> readsRegister ( PredR ) || ( Cond != HII -> isPredicatedTrue ( MI ) ) ) continue ; for ( auto & Op : MI -> operands ( ) ) { if ( ! Op . isReg ( ) || RO != RegisterRef ( Op ) ) continue ; Op . setReg ( RN . Reg ) ; Op . setSubReg ( RN . Sub ) ; assert ( ! Op . isDef ( ) && <STR_LIT> ) ; }


<s> for ( auto & Op : MI -> operands ( ) ) { if ( ! Op . isReg ( ) || ! Op . isDef ( ) || Op . getReg ( ) != Reg ) continue ; Op . setIsDead ( false ) ; } LiveInterval :: iterator End = LI . end ( ) ;

SlotIndex S = LIS -> getInstructionIndex ( MI ) . getRegSlot ( ) ;


<s> if ( CoaLimitActive ) { if ( CoaCounter >= CoaLimit ) return false ; CoaCounter ++ ; } unsigned BW1 , BW2 ; if ( ! isIntReg ( R1 , BW1 ) || ! isIntReg ( R2 , BW2 ) || BW1 != BW2 ) return false ; if ( MRI -> isLiveIn ( R1 . Reg ) ) return false ; if ( MRI -> isLiveIn ( R2 . Reg ) ) return false ; LiveInterval & L1 = LIS -> getInterval ( R1 . Reg ) ; LiveInterval & L2 = LIS -> getInterval ( R2 . Reg ) ; if ( L2 . empty ( ) ) return false ; if ( L1 . hasSubRanges ( ) || L2 . hasSubRanges ( ) ) return false ; bool Overlap = L1 . overlaps ( L2 ) ; DEBUG ( dbgs ( ) << <STR_LIT> << ( Overlap ? <STR_LIT> : <STR_LIT> ) << <STR_LIT> << PrintReg ( R1 . Reg , TRI , R1 . Sub ) << <STR_LIT> << L1 << <STR_LIT> << PrintReg ( R2 . Reg , TRI , R2 . Sub ) << <STR_LIT> << L2 << <STR_LIT> ) ; if ( R1 . Sub || R2 . Sub ) return false ; if ( Overlap ) return false ; if ( ! isIntraBlocks ( L1 ) && ! isIntraBlocks ( L2 ) ) return false ; MRI -> replaceRegWith ( R2 . Reg , R1 . Reg ) ;

using ValueInfoMap = DenseMap < VNInfo * , VNInfo * > ;


<s> virtual void getAnalysisUsage ( AnalysisUsage & AU ) const { AU . addRequired < LiveIntervals > ( ) ;


<s> AU . addPreserved < LiveIntervals > ( ) ; AU . addPreserved < SlotIndexes > ( ) ; AU . addPreservedID ( MachineDominatorsID ) ; MachineFunctionPass :: getAnalysisUsage ( AU ) ;


<s> DEBUG ( dbgs ( ) << <STR_LIT> << ( Cond ? <STR_LIT> : <STR_LIT> ) << <STR_LIT> << * TfrI ) ; MachineOperand & MD = TfrI -> getOperand ( <NUM_LIT> ) ; MachineOperand & MP = TfrI -> getOperand ( <NUM_LIT> ) ; MachineOperand & MS = TfrI -> getOperand ( <NUM_LIT> ) ; if ( ! MS . isKill ( ) ) return false ; if ( MD . getSubReg ( ) ) return false ; RegisterRef RT ( MS ) ; unsigned PredR = MP . getReg ( ) ; MachineInstr * DefI = getReachingDefForPred ( RT , TfrI , PredR , Cond ) ; if ( ! DefI || ! isPredicable ( DefI ) ) return false ; DEBUG ( dbgs ( ) << <STR_LIT> << * DefI ) ; ReferenceMap Uses , Defs ; MachineBasicBlock :: iterator DefIt = DefI , TfrIt = TfrI ; bool PredValid = true ; for ( MachineBasicBlock :: iterator I = std :: next ( DefIt ) ; I != TfrIt ; ++ I ) { if ( ! I -> modifiesRegister ( PredR , <NUM_LIT> ) ) continue ; PredValid = false ; break ; } for ( MachineBasicBlock :: iterator I = std :: next ( DefIt ) ; I != TfrIt ; ++ I ) { MachineInstr * MI = & * I ; unsigned Exec = Exec_Then | Exec_Else ; if ( PredValid && HII -> isPredicated ( * MI ) && MI -> readsRegister ( PredR ) ) Exec = ( Cond == HII -> isPredicatedTrue ( * MI ) ) ? Exec_Then : Exec_Else ; for ( auto & Op : MI -> operands ( ) ) { if ( ! Op . isReg ( ) ) continue ; RegisterRef RR = Op ;

if ( ! TargetRegisterInfo :: isVirtualRegister ( RR . Reg ) ) return false ;


<s> MachineOperand & MO = MI -> getOperand ( Ox ) ; if ( ! MO . isReg ( ) || ! MO . isImplicit ( ) ) MB . addOperand ( MO ) ; Ox ++ ; } MachineFunction & MF = * B . getParent ( ) ; MachineInstr :: mmo_iterator I = MI -> memoperands_begin ( ) ; unsigned NR = std :: distance ( I , MI -> memoperands_end ( ) ) ; MachineInstr :: mmo_iterator MemRefs = MF . allocateMemRefsArray ( NR ) ; for ( unsigned i = <NUM_LIT> ; i < NR ; ++ i ) MemRefs [ i ] = * I ++ ;

MB . setMemRefs ( MemRefs , MemRefs + NR ) ;


<s> Changed |= splitInBlock ( * I ) ; Changed |= predicateInBlock ( * I ) ; } for ( MachineFunction :: iterator I = MF . begin ( ) , E = MF . end ( ) ; I != E ; ++ I ) postprocessUndefImplicitUses ( * I ) ; if ( Changed ) DEBUG ( MF . print ( dbgs ( ) << <STR_LIT> , LIS -> getSlotIndexes ( ) ) ) ; return Changed ;


<s> MRI = & MF . getRegInfo ( ) ; DEBUG ( MF . print ( dbgs ( ) << <STR_LIT> , LIS -> getSlotIndexes ( ) ) ) ; bool Changed = false ; Changed |= coalesceSegments ( MF ) ; for ( MachineFunction :: iterator I = MF . begin ( ) , E = MF . end ( ) ; I != E ; ++ I ) { Changed |= splitInBlock ( * I ) ;


<s> if ( ! DefI || ! isPredicable ( DefI ) ) return false ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << * DefI ) ; ReferenceMap Uses , Defs ; MachineBasicBlock :: iterator DefIt = DefI , TfrIt = TfrI ; bool PredValid = true ; for ( MachineBasicBlock :: iterator I = std :: next ( DefIt ) ; I != TfrIt ; ++ I ) { if ( ! I -> modifiesRegister ( PredR , nullptr ) ) continue ; PredValid = false ; break ; } for ( MachineBasicBlock :: iterator I = std :: next ( DefIt ) ; I != TfrIt ; ++ I ) { MachineInstr * MI = & * I ; unsigned Exec = Exec_Then | Exec_Else ; if ( PredValid && HII -> isPredicated ( * MI ) && MI -> readsRegister ( PredR ) ) Exec = ( Cond == HII -> isPredicatedTrue ( * MI ) ) ? Exec_Then : Exec_Else ; for ( auto & Op : MI -> operands ( ) ) { if ( ! Op . isReg ( ) ) continue ; RegisterRef RR = Op ; if ( ! Register :: isVirtualRegister ( RR . Reg ) ) return false ; ReferenceMap & Map = Op . isDef ( ) ? Defs : Uses ; if ( Op . isDef ( ) && Op . isUndef ( ) ) { assert ( RR . Sub && <STR_LIT> ) ; RR . Sub = <NUM_LIT> ; } addRefToMap ( RR , Map , Exec ) ; } } if ( isRefInMap ( RT , Defs , Exec_Then ) || isRefInMap ( RT , Uses , Exec_Else ) ) return false ; RegisterRef RD = MD ; bool CanUp = canMoveOver ( TfrI , Defs , Uses ) ;

bool CanDown = canMoveOver ( * DefI , Defs , Uses ) ;


<s> if ( ! isIntReg ( R1 , BW1 ) || ! isIntReg ( R2 , BW2 ) || BW1 != BW2 ) return false ; if ( MRI -> isLiveIn ( R1 . Reg ) ) return false ; if ( MRI -> isLiveIn ( R2 . Reg ) ) return false ; LiveInterval & L1 = LIS -> getInterval ( R1 . Reg ) ; LiveInterval & L2 = LIS -> getInterval ( R2 . Reg ) ; bool Overlap = L1 . overlaps ( L2 ) ; DEBUG ( dbgs ( ) << <STR_LIT> << ( Overlap ? <STR_LIT> : <STR_LIT> ) << <STR_LIT> << PrintReg ( R1 . Reg , TRI , R1 . Sub ) << <STR_LIT> << L1 << <STR_LIT> << PrintReg ( R2 . Reg , TRI , R2 . Sub ) << <STR_LIT> << L2 << <STR_LIT> ) ; if ( R1 . Sub || R2 . Sub ) return false ; if ( Overlap ) return false ; if ( ! isIntraBlocks ( L1 ) && ! isIntraBlocks ( L2 ) ) return false ; MRI -> replaceRegWith ( R2 . Reg , R1 . Reg ) ; typedef DenseMap < VNInfo * , VNInfo * > ValueInfoMap ; ValueInfoMap VM ; for ( LiveInterval :: iterator I = L2 . begin ( ) , E = L2 . end ( ) ; I != E ; ++ I ) { VNInfo * NewVN , * OldVN = I -> valno ; ValueInfoMap :: iterator F = VM . find ( OldVN ) ; if ( F == VM . end ( ) ) { NewVN = L1 . getNextValue ( I -> valno -> def , LIS -> getVNInfoAllocator ( ) ) ; VM . insert ( std :: make_pair ( OldVN , NewVN ) ) ; } else { NewVN = F -> second ; } L1 . addSegment ( LiveRange :: Segment ( I -> start , I -> end , NewVN ) ) ; } while ( L2 . begin ( ) != L2 . end ( ) ) L2 . removeSegment ( * L2 . begin ( ) ) ; updateKillFlags ( R1 . Reg ) ; DEBUG ( dbgs ( ) << <STR_LIT> << L1 << <STR_LIT> ) ;


<s> } } bool Changed = false ; for ( unsigned i = <NUM_LIT> , n = Condsets . size ( ) ; i < n ; ++ i ) { MachineInstr * CI = Condsets [ i ] ; RegisterRef RD = CI -> getOperand ( <NUM_LIT> ) ; RegisterRef RP = CI -> getOperand ( <NUM_LIT> ) ; MachineOperand & S1 = CI -> getOperand ( <NUM_LIT> ) , & S2 = CI -> getOperand ( <NUM_LIT> ) ; bool Done = false ; if ( S1 . isReg ( ) ) { RegisterRef RS = S1 ; MachineInstr * RDef = getReachingDefForPred ( RS , CI , RP . Reg , true ) ; if ( ! RDef || ! HII -> isPredicable ( * RDef ) ) Done = coalesceRegisters ( RD , RegisterRef ( S1 ) ) ; } if ( ! Done && S2 . isReg ( ) ) {


<s> MachineInstr * <ISA_LIT>ExpandCondsets :: genCondTfrFor ( MachineOperand & SrcOp , MachineBasicBlock :: iterator At , unsigned DstR , unsigned DstSR , const MachineOperand & PredOp , bool PredSense , bool ReadUndef , bool ImpUse ) { MachineInstr * MI = SrcOp . getParent ( ) ; MachineBasicBlock & B = * At -> getParent ( ) ;

const DebugLoc & DL = MI -> getDebugLoc ( ) ;


<s> const char * getPassName ( ) const override {


<s> switch ( Opc ) { case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : return true ; break ;


Range . segments . erase ( std :: remove_if ( Range . begin ( ) , Range . end ( ) , StartImpDef ) , Range . end ( ) ) ;


<s> unsigned NewSR = <NUM_LIT> ; MachineBasicBlock :: iterator DefAt = At ; bool SameReg = ( MS1 . isReg ( ) && DR == MS1 . getReg ( ) ) || ( MS2 . isReg ( ) && DR == MS2 . getReg ( ) ) ; if ( SameReg ) { NewSR = ( DSR == <STR_LIT> ) ? <STR_LIT> : <STR_LIT> ; if ( ( MS1 . isReg ( ) && NewSR == MS1 . getSubReg ( ) ) || ( MS2 . isReg ( ) && NewSR == MS2 . getSubReg ( ) ) ) ++ DefAt ; } MachineBasicBlock & B = * At -> getParent ( ) ; DebugLoc DL = At -> getDebugLoc ( ) ; auto ImpD = BuildMI ( B , DefAt , DL , HII -> get ( TargetOpcode :: IMPLICIT_DEF ) ) . addReg ( DR , RegState :: Define , NewSR ) ; LIS -> InsertMachineInstrInMaps ( * ImpD ) ; LocalImpDefs . insert ( & * ImpD ) ; } MachineInstr * TfrT = genCondTfrFor ( MI . getOperand ( <NUM_LIT> ) , At , DR , DSR , MP , true , ReadUndef , false ) ;

MachineInstr * TfrF = genCondTfrFor ( MI . getOperand ( <NUM_LIT> ) , At , DR , DSR , MP , false , ReadUndef , true ) ;


<s> bool <ISA_LIT>ExpandCondsets :: splitInBlock ( MachineBasicBlock & B , std :: set < unsigned > & UpdRegs ) { bool Changed = false ; MachineBasicBlock :: iterator I , E , NextI ; for ( I = B . begin ( ) , E = B . end ( ) ; I != E ; I = NextI ) { NextI = std :: next ( I ) ; if ( isCondset ( * I ) ) Changed |= split ( * I , UpdRegs ) ; }


<s> for ( auto & Seg : Range ) { if ( ! Seg . start . isRegister ( ) ) continue ; MachineInstr * DefI = LIS -> getInstructionFromIndex ( Seg . start ) ; if ( LocalImpDefs . count ( DefI ) ) continue ; for ( auto & Op : DefI -> operands ( ) ) { if ( Seg . start . isDead ( ) || ! IsRegDef ( Op ) ) continue ; DefRegs . insert ( Op ) ; Op . setIsDead ( false ) ; } } removeImpDefSegments ( Range ) ; for ( auto & Seg : Range ) { if ( ! Seg . start . isRegister ( ) || ! Range . liveAt ( Seg . start . getPrevSlot ( ) ) ) continue ; MachineInstr * DefI = LIS -> getInstructionFromIndex ( Seg . start ) ; if ( ! HII -> isPredicated ( * DefI ) ) continue ; MachineFunction & MF = * DefI -> getParent ( ) -> getParent ( ) ; std :: set < RegisterRef > ImpUses ; for ( auto & Op : DefI -> operands ( ) ) if ( Op . isReg ( ) && Op . isDef ( ) && DefRegs . count ( Op ) ) ImpUses . insert ( Op ) ;

for ( RegisterRef R : ImpUses ) MachineInstrBuilder ( MF , DefI ) . addReg ( R . Reg , RegState :: Implicit , R . Sub ) ;


<s> if ( MRI -> isLiveIn ( R1 . Reg ) ) return false ; if ( MRI -> isLiveIn ( R2 . Reg ) ) return false ; LiveInterval & L1 = LIS -> getInterval ( R1 . Reg ) ; LiveInterval & L2 = LIS -> getInterval ( R2 . Reg ) ; if ( L2 . empty ( ) ) return false ; bool Overlap = L1 . overlaps ( L2 ) ; DEBUG ( dbgs ( ) << <STR_LIT> << ( Overlap ? <STR_LIT> : <STR_LIT> ) << <STR_LIT> << PrintReg ( R1 . Reg , TRI , R1 . Sub ) << <STR_LIT> << L1 << <STR_LIT> << PrintReg ( R2 . Reg , TRI , R2 . Sub ) << <STR_LIT> << L2 << <STR_LIT> ) ; if ( R1 . Sub || R2 . Sub ) return false ; if ( Overlap ) return false ; if ( ! isIntraBlocks ( L1 ) && ! isIntraBlocks ( L2 ) ) return false ; MRI -> replaceRegWith ( R2 . Reg , R1 . Reg ) ; typedef DenseMap < VNInfo * , VNInfo * > ValueInfoMap ; ValueInfoMap VM ; for ( LiveInterval :: iterator I = L2 . begin ( ) , E = L2 . end ( ) ; I != E ; ++ I ) { VNInfo * NewVN , * OldVN = I -> valno ; ValueInfoMap :: iterator F = VM . find ( OldVN ) ; if ( F == VM . end ( ) ) { NewVN = L1 . getNextValue ( I -> valno -> def , LIS -> getVNInfoAllocator ( ) ) ; VM . insert ( std :: make_pair ( OldVN , NewVN ) ) ; } else { NewVN = F -> second ; } L1 . addSegment ( LiveRange :: Segment ( I -> start , I -> end , NewVN ) ) ; } while ( L2 . begin ( ) != L2 . end ( ) ) L2 . removeSegment ( * L2 . begin ( ) ) ; updateKillFlags ( R1 . Reg ) ;

DEBUG ( dbgs ( ) << <STR_LIT> << L1 << <STR_LIT> ) ;


<s> if ( R1 . Sub || R2 . Sub ) return false ; if ( Overlap ) return false ; if ( ! isIntraBlocks ( L1 ) && ! isIntraBlocks ( L2 ) ) return false ; MRI -> replaceRegWith ( R2 . Reg , R1 . Reg ) ; typedef DenseMap < VNInfo * , VNInfo * > ValueInfoMap ; ValueInfoMap VM ; for ( LiveInterval :: iterator I = L2 . begin ( ) , E = L2 . end ( ) ; I != E ; ++ I ) { VNInfo * NewVN , * OldVN = I -> valno ; ValueInfoMap :: iterator F = VM . find ( OldVN ) ; if ( F == VM . end ( ) ) { NewVN = L1 . getNextValue ( I -> valno -> def , LIS -> getVNInfoAllocator ( ) ) ; VM . insert ( std :: make_pair ( OldVN , NewVN ) ) ; } else { NewVN = F -> second ; } L1 . addSegment ( LiveRange :: Segment ( I -> start , I -> end , NewVN ) ) ; } while ( L2 . begin ( ) != L2 . end ( ) ) L2 . removeSegment ( * L2 . begin ( ) ) ; updateKillFlags ( R1 . Reg ) ; DEBUG ( dbgs ( ) << <STR_LIT> << L1 << <STR_LIT> ) ; L1 . verify ( ) ;


<s> void <ISA_LIT>ExpandCondsets :: removeImpDefSegments ( LiveRange & Range ) {

auto StartImpDef = [ this ] ( LiveRange :: Segment & S ) -> bool {