<s> if ( skipFunction ( F ) ) return false ; DT = & getAnalysis < DominatorTreeWrapperPass > ( ) . getDomTree ( ) ; bool Changed ; BasicBlock * Entry = GraphTraits < Function * > :: getEntryNode ( & F ) ;


<s> while ( true ) { if ( HasCutoff && ( ExtractCount >= Cutoff ) ) return Changed ; bool Last = ( I == Begin ) ; if ( ! Last ) NextI = std :: prev ( I ) ; Instruction * In = & * I ; bool Done = convert ( In ) ; if ( HasCutoff && Done ) ExtractCount ++ ;


<s> if ( ! Last ) NextI = std :: prev ( I ) ; Instruction * In = & * I ; bool Done = convert ( In ) ; if ( HasCutoff && Done ) ExtractCount ++ ; Changed |= Done ; if ( Last ) break ; I = NextI ; } return Changed ;


<s> BitValueOrdering ( const RegisterOrdering & RB ) : BaseOrd ( RB ) {


<s> for ( RegisterOrdering :: iterator I = RB . begin ( ) , E = RB . end ( ) ; I != E ; ++ I ) VRs . push_back ( I -> first ) ; std :: sort ( VRs . begin ( ) , VRs . end ( ) , LexCmp ) ;

for ( unsigned i = <NUM_LIT> , n = VRs . size ( ) ; i < n ; ++ i ) RO . insert ( std :: make_pair ( VRs [ i ] , i ) ) ;


<s> typedef std :: vector < unsigned > SortableVectorType ; SortableVectorType VRs ; for ( RegisterOrdering :: iterator I = RB . begin ( ) , E = RB . end ( ) ; I != E ; ++ I ) VRs . push_back ( I -> first ) ;

std :: sort ( VRs . begin ( ) , VRs . end ( ) , LexCmp ) ;


<s> if ( ! CMS -> BT . reached ( & B ) ) continue ; typedef MachineBasicBlock :: const_iterator mb_iterator ; for ( mb_iterator I = B . begin ( ) , E = B . end ( ) ; I != E ; ++ I ) { const MachineInstr * MI = & * I ; for ( unsigned i = <NUM_LIT> , n = MI -> getNumOperands ( ) ; i < n ; ++ i ) { const MachineOperand & MO = MI -> getOperand ( i ) ; if ( MO . isReg ( ) && MO . isDef ( ) ) { unsigned R = MO . getReg ( ) ; assert ( MO . getSubReg ( ) == <NUM_LIT> && <STR_LIT> ) ; if ( TargetRegisterInfo :: isVirtualRegister ( R ) ) RO . insert ( std :: make_pair ( R , Index ++ ) ) ; } } } }


<s> const MachineBasicBlock & B = * A ; if ( ! CMS -> BT . reached ( & B ) ) continue ; typedef MachineBasicBlock :: const_iterator mb_iterator ; for ( mb_iterator I = B . begin ( ) , E = B . end ( ) ; I != E ; ++ I ) { const MachineInstr * MI = & * I ; for ( unsigned i = <NUM_LIT> , n = MI -> getNumOperands ( ) ; i < n ; ++ i ) { const MachineOperand & MO = MI -> getOperand ( i ) ; if ( MO . isReg ( ) && MO . isDef ( ) ) { unsigned R = MO . getReg ( ) ; assert ( MO . getSubReg ( ) == <NUM_LIT> && <STR_LIT> ) ; if ( TargetRegisterInfo :: isVirtualRegister ( R ) ) RO . insert ( std :: make_pair ( R , Index ++ ) ) ; } }


<s> CellMapShadow ( const BitTracker & T ) : BT ( T ) {


<s> RegisterSet BlockDefs , InsDefs ; for ( MachineBasicBlock :: iterator I = B -> begin ( ) , E = B -> end ( ) ; I != E ; ++ I ) { MachineInstr * MI = & * I ; InsDefs . clear ( ) ; getInstrDefs ( MI , InsDefs ) ; bool Skip = MI -> isCopy ( ) || MI -> isRegSequence ( ) ; if ( ! Skip ) { for ( unsigned VR = InsDefs . find_first ( ) ; VR ; VR = InsDefs . find_next ( VR ) ) { if ( ! DoConst && isConstant ( VR ) ) continue ; if ( findSelfReference ( VR ) || isSmallConstant ( VR ) ) continue ; findRecordInsertForms ( VR , AVs ) ; } } for ( unsigned VR = InsDefs . find_first ( ) ; VR ; VR = InsDefs . find_next ( VR ) ) AVs . insert ( VR ) ; BlockDefs . insert ( InsDefs ) ; } MachineDomTreeNode * N = MDT -> getNode ( B ) ; typedef GraphTraits < MachineDomTreeNode * > GTN ; typedef GTN :: ChildIteratorType ChildIter ; for ( ChildIter I = GTN :: child_begin ( N ) , E = GTN :: child_end ( N ) ; I != E ; ++ I ) { MachineBasicBlock * SB = ( * I ) -> getBlock ( ) ; collectInBlock ( SB , AVs ) ; } for ( unsigned VR = BlockDefs . find_first ( ) ; VR ; VR = BlockDefs . find_next ( VR ) ) AVs . remove ( VR ) ;


<s> for ( unsigned i = <NUM_LIT> , n = LL . size ( ) ; i < n ; ++ i ) findRemovableRegisters ( I -> first , LL [ i ] . first , LL [ i ] . second ) ;


<s> FunctionPass * llvm :: create<ISA_LIT>GenInsert ( ) {


<s> const_iterator end ( ) const { return Seq . end ( ) ;


<s> const BitTracker :: BitValue & V = RC [ i ] ;

if ( V . Type == BitTracker :: BitValue :: Ref && V . RefI . Reg != VR ) return true ;


<s> unsigned SrcR = * I ; int FDi = - <NUM_LIT> , LDi = - <NUM_LIT> ; const BitTracker :: RegisterCell & AC = CMS -> lookup ( SrcR ) ; uint16_t AW = AC . width ( ) ; for ( uint16_t i = <NUM_LIT> , w = std :: min ( W , AW ) ; i < w ; ++ i ) { if ( RC [ i ] == AC [ i ] ) continue ; if ( FDi == - <NUM_LIT> ) FDi = i ; LDi = i ; } if ( FDi == - <NUM_LIT> ) continue ; uint16_t FD = FDi , LD = LDi ; uint16_t MinL = LD - FD + <NUM_LIT> ; for ( uint16_t L = MinL ; L < W ; ++ L ) { LRSMapType :: iterator F = LM . find ( L ) ; if ( F == LM . end ( ) ) continue ; RSListType & LL = F -> second ; for ( unsigned i = <NUM_LIT> , n = LL . size ( ) ; i < n ; ++ i ) { uint16_t S = LL [ i ] . second ; if ( S > FD ) continue ; uint16_t EL = L - MinL ; uint16_t LowS = ( EL < FD ) ? FD - EL : <NUM_LIT> ; if ( S < LowS ) continue ; unsigned InsR = LL [ i ] . first ; if ( ! isValidInsertForm ( VR , SrcR , InsR , L , S ) ) continue ; if ( isDebug ( ) ) { dbgs ( ) << PrintReg ( VR , HRI ) << <STR_LIT> << PrintReg ( SrcR , HRI ) << ',' << PrintReg ( InsR , HRI ) << <STR_LIT> << L << <STR_LIT> << S << <STR_LIT> ; } IFRecordWithRegSet RR ( IFRecord ( SrcR , InsR , L , S ) , RegisterSet ( ) ) ; IFMap [ VR ] . push_back ( RR ) ; Recorded = true ; } } }


<s> for ( LRSMapType :: iterator I = LM . begin ( ) , E = LM . end ( ) ; I != E ; ++ I ) { dbgs ( ) << <STR_LIT> << I -> first << ':' ; const RSListType & LL = I -> second ; for ( unsigned i = <NUM_LIT> , n = LL . size ( ) ; i < n ; ++ i ) dbgs ( ) << <STR_LIT> << PrintReg ( LL [ i ] . first , HRI ) << <STR_LIT> << LL [ i ] . second << ')' ; dbgs ( ) << '\n' ; } } bool Recorded = false ; for ( iterator I = AVs . begin ( ) , E = AVs . end ( ) ; I != E ; ++ I ) { unsigned SrcR = * I ; int FDi = - <NUM_LIT> , LDi = - <NUM_LIT> ; const BitTracker :: RegisterCell & AC = CMS -> lookup ( SrcR ) ; uint16_t AW = AC . width ( ) ; for ( uint16_t i = <NUM_LIT> , w = std :: min ( W , AW ) ; i < w ; ++ i ) { if ( RC [ i ] == AC [ i ] ) continue ; if ( FDi == - <NUM_LIT> ) FDi = i ; LDi = i ; } if ( FDi == - <NUM_LIT> ) continue ; uint16_t FD = FDi , LD = LDi ; uint16_t MinL = LD - FD + <NUM_LIT> ; for ( uint16_t L = MinL ; L < W ; ++ L ) { LRSMapType :: iterator F = LM . find ( L ) ; if ( F == LM . end ( ) ) continue ; RSListType & LL = F -> second ; for ( unsigned i = <NUM_LIT> , n = LL . size ( ) ; i < n ; ++ i ) { uint16_t S = LL [ i ] . second ; if ( S > FD ) continue ; uint16_t EL = L - MinL ; uint16_t LowS = ( EL < FD ) ? FD - EL : <NUM_LIT> ; if ( S < LowS ) continue ; unsigned InsR = LL [ i ] . first ; if ( ! isValidInsertForm ( VR , SrcR , InsR , L , S ) ) continue ; if ( isDebug ( ) ) { dbgs ( ) << PrintReg ( VR , HRI ) << <STR_LIT> << PrintReg ( SrcR , HRI ) << ',' << PrintReg ( InsR , HRI ) << <STR_LIT> << L << <STR_LIT> << S << <STR_LIT> ; } IFRecordWithRegSet RR ( IFRecord ( SrcR , InsR , L , S ) , RegisterSet ( ) ) ; IFMap [ VR ] . push_back ( RR ) ; Recorded = true ;


<s> while ( ! Regs [ S ] . empty ( ) ) { unsigned OtherS = <NUM_LIT> - S ; Regs [ OtherS ] . clear ( ) ; for ( unsigned R = Regs [ S ] . find_first ( ) ; R ; R = Regs [ S ] . find_next ( R ) ) { Regs [ S ] . remove ( R ) ; if ( R == IF . SrcR || R == IF . InsR ) continue ; if ( ! findNonSelfReference ( R ) ) continue ; RMs . insert ( R ) ; const MachineInstr * DefI = MRI -> getVRegDef ( R ) ; assert ( DefI ) ; if ( DefI -> isPHI ( ) ) continue ; getInstrUses ( DefI , Regs [ OtherS ] ) ; }


<s> void <ISA_LIT>GenInsert :: findRemovableRegisters ( unsigned VR , IFRecord IF , RegisterSet & RMs ) const { RegisterSet Regs [ <NUM_LIT> ] ; unsigned S = <NUM_LIT> ; Regs [ S ] . insert ( VR ) ; while ( ! Regs [ S ] . empty ( ) ) { unsigned OtherS = <NUM_LIT> - S ; Regs [ OtherS ] . clear ( ) ; for ( unsigned R = Regs [ S ] . find_first ( ) ; R ; R = Regs [ S ] . find_next ( R ) ) { Regs [ S ] . remove ( R ) ; if ( R == IF . SrcR || R == IF . InsR ) continue ;

if ( ! findNonSelfReference ( R ) ) continue ;


<s> const BitTracker :: RegisterCell & RC = CMS -> lookup ( VR ) ; for ( uint16_t i = <NUM_LIT> , w = RC . width ( ) ; i < w ; ++ i ) { const BitTracker :: BitValue & V = RC [ i ] ; if ( V . Type == BitTracker :: BitValue :: Ref && V . RefI . Reg == VR ) return true ;


<s> UnsignedMap RegMap ; for ( IFMapType :: iterator I = IFMap . begin ( ) , E = IFMap . end ( ) ; I != E ; ++ I ) { unsigned VR = I -> first ; const TargetRegisterClass * RC = MRI -> getRegClass ( VR ) ; unsigned NewVR = MRI -> createVirtualRegister ( RC ) ; RegMap [ VR ] = NewVR ; } for ( IFMapType :: iterator I = IFMap . begin ( ) , E = IFMap . end ( ) ; I != E ; ++ I ) { MachineInstr * MI = MRI -> getVRegDef ( I -> first ) ; MachineBasicBlock & B = * MI -> getParent ( ) ; DebugLoc DL = MI -> getDebugLoc ( ) ; unsigned NewR = RegMap [ I -> first ] ; bool R32 = MRI -> getRegClass ( NewR ) == & <STR_LIT> ; const MCInstrDesc & D = R32 ? HII -> get ( <STR_LIT> ) : HII -> get ( <STR_LIT> ) ; IFRecord IF = I -> second [ <NUM_LIT> ] . first ; unsigned Wdh = IF . Wdh , Off = IF . Off ; unsigned InsS = <NUM_LIT> ; if ( R32 && MRI -> getRegClass ( IF . InsR ) == & <STR_LIT> ) { InsS = <STR_LIT> ; if ( Off >= <NUM_LIT> ) { InsS = <STR_LIT> ; Off -= <NUM_LIT> ; } } MachineBasicBlock :: iterator At = MI ; if ( MI -> isPHI ( ) ) At = B . getFirstNonPHI ( ) ; BuildMI ( B , At , DL , D , NewR ) . addReg ( IF . SrcR ) . addReg ( IF . InsR , <NUM_LIT> , InsS ) . addImm ( Wdh ) . addImm ( Off ) ; MRI -> clearKillFlags ( IF . SrcR ) ; MRI -> clearKillFlags ( IF . InsR ) ; }


<s> RegMap [ VR ] = NewVR ; } for ( IFMapType :: iterator I = IFMap . begin ( ) , E = IFMap . end ( ) ; I != E ; ++ I ) { MachineInstr * MI = MRI -> getVRegDef ( I -> first ) ; MachineBasicBlock & B = * MI -> getParent ( ) ; DebugLoc DL = MI -> getDebugLoc ( ) ; unsigned NewR = RegMap [ I -> first ] ; bool R32 = MRI -> getRegClass ( NewR ) == & <STR_LIT> ; const MCInstrDesc & D = R32 ? HII -> get ( <STR_LIT> ) : HII -> get ( <STR_LIT> ) ; IFRecord IF = I -> second [ <NUM_LIT> ] . first ; unsigned Wdh = IF . Wdh , Off = IF . Off ; unsigned InsS = <NUM_LIT> ; if ( R32 && MRI -> getRegClass ( IF . InsR ) == & <STR_LIT> ) { InsS = <STR_LIT> ; if ( Off >= <NUM_LIT> ) {


<s> const MachineOperand & MO = MI -> getOperand ( i ) ; if ( ! MO . isReg ( ) || ! MO . isDef ( ) ) continue ; unsigned R = MO . getReg ( ) ; if ( ! TargetRegisterInfo :: isVirtualRegister ( R ) ) continue ; Defs . insert ( R ) ; }


<s> const MachineOperand & MO = MI -> getOperand ( i ) ; if ( ! MO . isReg ( ) || ! MO . isUse ( ) ) continue ;


<s> initialize<ISA_LIT>GenInsertPass ( * PassRegistry :: getPassRegistry ( ) ) ;


<s> unsigned idx ( iterator It ) const {


<s> IFOrdering ( const UnsignedMap & UC , const RegisterOrdering & BO ) : UseC ( UC ) , BaseOrd ( BO ) {


<s> IFRecord ( unsigned SR = <NUM_LIT> , unsigned IR = <NUM_LIT> , uint16_t W = <NUM_LIT> , uint16_t O = <NUM_LIT> ) : SrcR ( SR ) , InsR ( IR ) , Wdh ( W ) , Off ( O ) {


<s> iterator L = std :: lower_bound ( Seq . begin ( ) , Seq . end ( ) , VR , Ord ) ; if ( L == Seq . end ( ) ) Seq . push_back ( VR ) ; else Seq . insert ( L , VR ) ;


<s> if ( L == Seq . end ( ) ) Seq . push_back ( VR ) ;


<s> for ( uint16_t i = <NUM_LIT> ; i < W ; ++ i ) { const BitTracker :: BitValue & BV = RC [ i ] ; if ( BV . is ( <NUM_LIT> ) || BV . is ( <NUM_LIT> ) ) continue ; return false ; }


<s> return RC == & <STR_LIT> || RC == & <STR_LIT> ;


<s> else if ( ! BV . is ( <NUM_LIT> ) ) return false ; B <<= <NUM_LIT> ; } if ( W == <NUM_LIT> ) return isInt < <NUM_LIT> > ( V ) ;

return isInt < <NUM_LIT> > ( Lo_32 ( V ) ) && isInt < <NUM_LIT> > ( Hi_32 ( V ) ) ;


<s> const BitTracker :: BitValue & BV = RC [ i ] ; if ( BV . is ( <NUM_LIT> ) ) V |= B ; else if ( ! BV . is ( <NUM_LIT> ) ) return false ; B <<= <NUM_LIT> ; }

if ( W == <NUM_LIT> ) return isInt < <NUM_LIT> > ( V ) ;


<s> if ( DstRC != SrcRC ) return false ; if ( DstRC == InsRC ) return true ; if ( DstRC == & <STR_LIT> ) return false ;

if ( S < <NUM_LIT> && S + L > <NUM_LIT> ) return false ;


<s> const TargetRegisterClass * InsRC = MRI -> getRegClass ( InsR ) ; if ( ! isIntClass ( DstRC ) || ! isIntClass ( SrcRC ) || ! isIntClass ( InsRC ) ) return false ;


<s> unsigned RInd = TargetRegisterInfo :: virtReg2Index ( VR ) ; if ( RInd >= CVect . size ( ) ) CVect . resize ( std :: max ( RInd + <NUM_LIT> , <NUM_LIT> ) , <NUM_LIT> ) ; const BitTracker :: RegisterCell * CP = CVect [ RInd ] ; if ( CP == <NUM_LIT> ) CP = CVect [ RInd ] = & BT . lookup ( VR ) ; return * CP ;


<s> if ( RInd >= CVect . size ( ) ) CVect . resize ( std :: max ( RInd + <NUM_LIT> , <NUM_LIT> ) , <NUM_LIT> ) ; const BitTracker :: RegisterCell * CP = CVect [ RInd ] ; if ( CP == <NUM_LIT> ) CP = CVect [ RInd ] = & BT . lookup ( VR ) ; return * CP ;


<s> OrderedRegisterList ( const RegisterOrdering & RO ) : Ord ( RO ) {


<s> PrintIFR ( const IFRecord & R , const TargetRegisterInfo * RI ) : IFR ( R ) , TRI ( RI ) {


<s> PrintORL ( const OrderedRegisterList & L , const TargetRegisterInfo * RI ) : RL ( L ) , TRI ( RI ) {


<s> for ( IFMapType :: iterator I = IFMap . begin ( ) , E = IFMap . end ( ) ; I != E ; ++ I ) pruneUsesTooFar ( I -> first , RPO , Memo ) ; pruneEmptyLists ( ) ;

for ( IFMapType :: iterator I = IFMap . begin ( ) , E = IFMap . end ( ) ; I != E ; ++ I ) pruneRegCopies ( I -> first ) ;


<s> for ( IFMapType :: iterator I = IFMap . begin ( ) , E = IFMap . end ( ) ; I != E ; ++ I ) pruneCoveredSets ( I -> first ) ; UnsignedMap RPO ; typedef ReversePostOrderTraversal < const MachineFunction * > RPOTType ; RPOTType RPOT ( MFN ) ;


<s> assert ( F != IFMap . end ( ) ) ; IFListType & LL = F -> second ; MachineInstr * DefVR = MRI -> getVRegDef ( VR ) ; bool DefEx = HII -> isConstExtended ( DefVR ) ; bool HasNE = false ; for ( unsigned i = <NUM_LIT> , n = LL . size ( ) ; i < n ; ++ i ) { if ( LL [ i ] . second . empty ( ) ) continue ; HasNE = true ; break ; } if ( ! DefEx || HasNE ) { auto IsEmpty = [ ] ( const IFRecordWithRegSet & IR ) -> bool { return IR . second . empty ( ) ; } ; auto End = std :: remove_if ( LL . begin ( ) , LL . end ( ) , IsEmpty ) ; if ( End != LL . end ( ) ) LL . erase ( End , LL . end ( ) ) ; } else { IFRecord MaxIF = LL [ <NUM_LIT> ] . first ; for ( unsigned i = <NUM_LIT> , n = LL . size ( ) ; i < n ; ++ i ) { const IFRecord & IF = LL [ i ] . first ; unsigned M0 = BaseOrd [ MaxIF . SrcR ] , M1 = BaseOrd [ MaxIF . InsR ] ; unsigned R0 = BaseOrd [ IF . SrcR ] , R1 = BaseOrd [ IF . InsR ] ; if ( M0 > R0 ) continue ; if ( M0 == R0 ) { if ( M1 > R1 ) continue ; if ( M1 == R1 ) { if ( MaxIF . Wdh > IF . Wdh ) continue ; if ( MaxIF . Wdh == IF . Wdh && MaxIF . Off >= IF . Off ) continue ; } } MaxIF = IF ; } LL . clear ( ) ; LL . push_back ( std :: make_pair ( MaxIF , RegisterSet ( ) ) ) ; } for ( unsigned i = <NUM_LIT> , n = LL . size ( ) ; i < n ; ) { const RegisterSet & RMi = LL [ i ] . second ; unsigned j = <NUM_LIT> ;


<s> void <ISA_LIT>GenInsert :: pruneEmptyLists ( ) { typedef SmallVector < IFMapType :: iterator , <NUM_LIT> > IterListType ; IterListType Prune ; for ( IFMapType :: iterator I = IFMap . begin ( ) , E = IFMap . end ( ) ; I != E ; ++ I ) { if ( I -> second . size ( ) == <NUM_LIT> ) Prune . push_back ( I ) ; }

for ( unsigned i = <NUM_LIT> , n = Prune . size ( ) ; i < n ; ++ i ) IFMap . erase ( Prune [ i ] ) ;


<s> IterListType Prune ; for ( IFMapType :: iterator I = IFMap . begin ( ) , E = IFMap . end ( ) ; I != E ; ++ I ) { if ( I -> second . size ( ) == <NUM_LIT> ) Prune . push_back ( I ) ;


<s> IFMapType :: iterator F = IFMap . find ( VR ) ; assert ( F != IFMap . end ( ) ) ; IFListType & LL = F -> second ; auto IsCopy = [ ] ( const IFRecordWithRegSet & IR ) -> bool {

return IR . first . Wdh == <NUM_LIT> && ( IR . first . Off == <NUM_LIT> || IR . first . Off == <NUM_LIT> ) ;


<s> } ; auto End = std :: remove_if ( LL . begin ( ) , LL . end ( ) , IsCopy ) ; if ( End != LL . end ( ) ) LL . erase ( End , LL . end ( ) ) ;


<s> const MachineInstr * DefV = MRI -> getVRegDef ( VR ) ; for ( unsigned i = LL . size ( ) ; i > <NUM_LIT> ; -- i ) { unsigned SR = LL [ i - <NUM_LIT> ] . first . SrcR , IR = LL [ i - <NUM_LIT> ] . first . InsR ; const MachineInstr * DefS = MRI -> getVRegDef ( SR ) ; const MachineInstr * DefI = MRI -> getVRegDef ( IR ) ; unsigned DSV = distance ( DefS , DefV , RPO , M ) ;


<s> RegisterCellBitCompareSel ( unsigned R , unsigned B , unsigned N , const BitValueOrdering & BO , CellMapShadow & M ) : SelR ( R ) , SelB ( B ) , BitN ( N ) , BitOrd ( BO ) , CM ( M ) {


<s> RegisterCellLexCompare ( const BitValueOrdering & BO , CellMapShadow & M ) : BitOrd ( BO ) , CM ( M ) {


<s> RegisterOrdering ( ) : UnsignedMap ( ) {


<s> iterator L = std :: lower_bound ( Seq . begin ( ) , Seq . end ( ) , VR , Ord ) ; assert ( L != Seq . end ( ) ) ; Seq . erase ( L ) ;


<s> iterator L = std :: lower_bound ( Seq . begin ( ) , Seq . end ( ) , VR , Ord ) ; assert ( L != Seq . end ( ) ) ;


<s> if ( MI -> isInlineAsm ( ) || ! MI -> isSafeToMove ( nullptr , Store ) ) continue ; bool AllDead = true ; SmallVector < unsigned , <NUM_LIT> > Regs ; for ( ConstMIOperands Op ( MI ) ; Op . isValid ( ) ; ++ Op ) { if ( ! Op -> isReg ( ) || ! Op -> isDef ( ) ) continue ; unsigned R = Op -> getReg ( ) ; if ( ! TargetRegisterInfo :: isVirtualRegister ( R ) || ! MRI -> use_nodbg_empty ( R ) ) { AllDead = false ; break ; } Regs . push_back ( R ) ; } if ( ! AllDead ) continue ; B -> erase ( MI ) ; for ( unsigned I = <NUM_LIT> , N = Regs . size ( ) ; I != N ; ++ I ) MRI -> markUsesInDebugValueAsUndef ( Regs [ I ] ) ;


<s> HII = ST . getInstrInfo ( ) ; HRI = ST . getRegisterInfo ( ) ; MFN = & MF ; MRI = & MF . getRegInfo ( ) ; MDT = & getAnalysis < MachineDominatorTree > ( ) ; Changed = removeDeadCode ( MDT -> getRootNode ( ) ) ; const <ISA_LIT>Evaluator HE ( * HRI , * MRI , * HII , MF ) ; BitTracker BTLoc ( HE , MF ) ; BTLoc . trace ( isDebug ( ) ) ; BTLoc . run ( ) ; CellMapShadow MS ( BTLoc ) ; CMS = & MS ; buildOrderingMF ( BaseOrd ) ; buildOrderingBT ( BaseOrd , CellOrd ) ; if ( isDebug ( ) ) { dbgs ( ) << <STR_LIT> ; for ( RegisterOrdering :: iterator I = CellOrd . begin ( ) , E = CellOrd . end ( ) ; I != E ; ++ I ) { unsigned VR = I -> first , Pos = I -> second ; dbgs ( ) << PrintReg ( VR , HRI ) << <STR_LIT> << Pos << <STR_LIT> ; } } MachineBasicBlock * RootB = MDT -> getRoot ( ) ; OrderedRegisterList AvailR ( CellOrd ) ; { NamedRegionTimer _T ( <STR_LIT> , <STR_LIT> , TimingDetail ) ; collectInBlock ( RootB , AvailR ) ; computeRemovableRegisters ( ) ; } if ( isDebug ( ) ) { dbgs ( ) << <STR_LIT> ; dump_map ( ) ; } if ( IFMap . empty ( ) ) return Changed ; {


<s> if ( UseC [ R ] == <NUM_LIT> ) continue ; All0 = false ; break ; } Accept = All0 ; } else if ( SelectHas0 ) { bool Has0 = false ; for ( unsigned R = Us . find_first ( ) ; R ; R = Us . find_next ( R ) ) { if ( UseC [ R ] != <NUM_LIT> ) continue ; Has0 = true ; break ; } Accept = Has0 ; } if ( Accept ) LL . push_back ( M ) ; } AllRMs . clear ( ) ; for ( IFMapType :: iterator I = IFMap . begin ( ) ; I != End ; ++ I ) { const IFListType & LL = I -> second ; if ( LL . size ( ) > <NUM_LIT> ) AllRMs . insert ( LL [ <NUM_LIT> ] . second ) ; } for ( IFMapType :: iterator I = IFMap . begin ( ) ; I != End ; ++ I ) { IFListType & LL = I -> second ; if ( LL . size ( ) == <NUM_LIT> ) continue ;

unsigned SR = LL [ <NUM_LIT> ] . first . SrcR , IR = LL [ <NUM_LIT> ] . first . InsR ;


<s> const IFListType & LL = I -> second ; RegisterSet TT ; for ( unsigned i = <NUM_LIT> , n = LL . size ( ) ; i < n ; ++ i ) TT . insert ( LL [ i ] . second ) ; for ( unsigned R = TT . find_first ( ) ; R ; R = TT . find_next ( R ) ) RemC [ R ] ++ ; AllRMs . insert ( TT ) ; } for ( unsigned R = AllRMs . find_first ( ) ; R ; R = AllRMs . find_next ( R ) ) { typedef MachineRegisterInfo :: use_nodbg_iterator use_iterator ; typedef SmallSet < const MachineInstr * , <NUM_LIT> > InstrSet ; InstrSet UIs ; use_iterator E = MRI -> use_nodbg_end ( ) ; for ( use_iterator I = MRI -> use_nodbg_begin ( R ) ; I != E ; ++ I ) UIs . insert ( I -> getParent ( ) ) ; unsigned C = UIs . size ( ) ; unsigned D = RemC [ R ] ; UseC [ R ] = ( C > D ) ? C - D : <NUM_LIT> ; } bool SelectAll0 = OptSelectAll0 , SelectHas0 = OptSelectHas0 ; if ( ! SelectAll0 && ! SelectHas0 ) SelectAll0 = true ; IFOrdering IFO ( UseC , BaseOrd ) ; for ( IFMapType :: iterator I = IFMap . begin ( ) ; I != End ; ++ I ) { IFListType & LL = I -> second ; if ( LL . empty ( ) ) continue ; IFListType :: iterator MinI = std :: min_element ( LL . begin ( ) , LL . end ( ) , IFO ) ; assert ( MinI != LL . end ( ) ) ; IFRecordWithRegSet M = * MinI ; LL . clear ( ) ; RegisterSet Us ; const MachineInstr * DefI = MRI -> getVRegDef ( I -> first ) ; getInstrUses ( DefI , Us ) ; bool Accept = false ; if ( SelectAll0 ) { bool All0 = true ; for ( unsigned R = Us . find_first ( ) ; R ; R = Us . find_next ( R ) ) { if ( UseC [ R ] == <NUM_LIT> ) continue ; All0 = false ; break ; } Accept = All0 ; } else if ( SelectHas0 ) { bool Has0 = false ;


<s> for ( unsigned R = Rs . find_first ( ) ; R ; R = Rs . find_next ( R ) ) { UnsignedMap :: const_iterator F = UseC . find ( R ) ; assert ( F != UseC . end ( ) ) ; unsigned UC = F -> second ;


<s> for ( unsigned i = <NUM_LIT> , n = VRs . size ( ) ; i < n ; ++ i ) RO . insert ( std :: make_pair ( VRs [ i ] , i ) ) ;


<s> for ( RegisterOrdering :: iterator I = RB . begin ( ) , E = RB . end ( ) ; I != E ; ++ I ) VRs . push_back ( I -> first ) ;


<s> for ( const MachineOperand & MO : MI . operands ( ) ) { if ( MO . isReg ( ) && MO . isDef ( ) ) { Register R = MO . getReg ( ) ; assert ( MO . getSubReg ( ) == <NUM_LIT> && <STR_LIT> ) ; if ( R . isVirtual ( ) ) RO . insert ( std :: make_pair ( R , Index ++ ) ) ; }


<s> bool Skip = MI . isCopy ( ) || MI . isRegSequence ( ) ; if ( ! Skip ) { for ( unsigned VR = InsDefs . find_first ( ) ; VR ; VR = InsDefs . find_next ( VR ) ) { if ( ! DoConst && isConstant ( VR ) ) continue ; if ( findSelfReference ( VR ) || isSmallConstant ( VR ) ) continue ; findRecordInsertForms ( VR , AVs ) ; if ( IFMap . size ( ) > MaxIFMSize ) return ; } } for ( unsigned VR = InsDefs . find_first ( ) ; VR ; VR = InsDefs . find_next ( VR ) ) AVs . insert ( VR ) ; BlockDefs . insert ( InsDefs ) ; } for ( auto * DTN : children < MachineDomTreeNode * > ( MDT -> getNode ( B ) ) ) {

MachineBasicBlock * SB = DTN -> getBlock ( ) ;


<s> if ( isDebug ( ) ) dbgs ( ) << <STR_LIT> << printMBBReference ( * B ) << <STR_LIT> ; if ( ! CMS -> BT . reached ( B ) ) return ; bool DoConst = OptConst ; RegisterSet BlockDefs , InsDefs ; for ( MachineInstr & MI : * B ) { InsDefs . clear ( ) ; getInstrDefs ( & MI , InsDefs ) ; bool Skip = MI . isCopy ( ) || MI . isRegSequence ( ) ; if ( ! Skip ) { for ( unsigned VR = InsDefs . find_first ( ) ; VR ; VR = InsDefs . find_next ( VR ) ) { if ( ! DoConst && isConstant ( VR ) ) continue ; if ( findSelfReference ( VR ) || isSmallConstant ( VR ) ) continue ; findRecordInsertForms ( VR , AVs ) ; if ( IFMap . size ( ) > MaxIFMSize ) return ; } } for ( unsigned VR = InsDefs . find_first ( ) ; VR ; VR = InsDefs . find_next ( VR ) ) AVs . insert ( VR ) ; BlockDefs . insert ( InsDefs ) ; } for ( auto * DTN : children < MachineDomTreeNode * > ( MDT -> getNode ( B ) ) ) { MachineBasicBlock * SB = DTN -> getBlock ( ) ; collectInBlock ( SB , AVs ) ;


<s> unsigned ToRPO = RPO . lookup ( ToN ) ; unsigned MaxD = <NUM_LIT> ; for ( const MachineBasicBlock * PB : ToB -> predecessors ( ) ) { if ( PB == FromB || RPO . lookup ( PB -> getNumber ( ) ) >= ToRPO ) continue ; unsigned D = PB -> size ( ) + distance ( FromB , PB , RPO , M ) ; if ( D > MaxD ) MaxD = D ;


<s> void <ISA_LIT>GenInsert :: dump_map ( ) const { using iterator = IFMapType :: const_iterator ; for ( iterator I = IFMap . begin ( ) , E = IFMap . end ( ) ; I != E ; ++ I ) { dbgs ( ) << <STR_LIT> << printReg ( I -> first , HRI ) << <STR_LIT> ;


<s> } } if ( isDebug ( ) ) { dbgs ( ) << <STR_LIT> << printReg ( VR , HRI ) << <STR_LIT> ; for ( LRSMapType :: iterator I = LM . begin ( ) , E = LM . end ( ) ; I != E ; ++ I ) { dbgs ( ) << <STR_LIT> << I -> first << ':' ; const RSListType & LL = I -> second ; for ( unsigned i = <NUM_LIT> , n = LL . size ( ) ; i < n ; ++ i ) dbgs ( ) << <STR_LIT> << printReg ( LL [ i ] . first , HRI ) << <STR_LIT> << LL [ i ] . second << ')' ; dbgs ( ) << '\n' ; } } bool Recorded = false ; for ( iterator I = AVs . begin ( ) , E = AVs . end ( ) ; I != E ; ++ I ) { unsigned SrcR = * I ; int FDi = - <NUM_LIT> , LDi = - <NUM_LIT> ; const BitTracker :: RegisterCell & AC = CMS -> lookup ( SrcR ) ; uint16_t AW = AC . width ( ) ; for ( uint16_t i = <NUM_LIT> , w = std :: min ( W , AW ) ; i < w ; ++ i ) { if ( RC [ i ] == AC [ i ] ) continue ; if ( FDi == - <NUM_LIT> ) FDi = i ; LDi = i ; } if ( FDi == - <NUM_LIT> ) continue ; uint16_t FD = FDi , LD = LDi ; uint16_t MinL = LD - FD + <NUM_LIT> ; for ( uint16_t L = MinL ; L < W ; ++ L ) { LRSMapType :: iterator F = LM . find ( L ) ; if ( F == LM . end ( ) ) continue ; RSListType & LL = F -> second ; for ( unsigned i = <NUM_LIT> , n = LL . size ( ) ; i < n ; ++ i ) { uint16_t S = LL [ i ] . second ; if ( S > FD ) continue ; uint16_t EL = L - MinL ; uint16_t LowS = ( EL < FD ) ? FD - EL : <NUM_LIT> ; if ( S < LowS ) continue ; unsigned InsR = LL [ i ] . first ; if ( ! isValidInsertForm ( VR , SrcR , InsR , L , S ) ) continue ; if ( isDebug ( ) ) { dbgs ( ) << printReg ( VR , HRI ) << <STR_LIT> << printReg ( SrcR , HRI ) << ',' << printReg ( InsR , HRI ) << <STR_LIT> << L << <STR_LIT> << S << <STR_LIT> ;


<s> UnsignedMap RegMap ; for ( IFMapType :: iterator I = IFMap . begin ( ) , E = IFMap . end ( ) ; I != E ; ++ I ) { unsigned VR = I -> first ; const TargetRegisterClass * RC = MRI -> getRegClass ( VR ) ; Register NewVR = MRI -> createVirtualRegister ( RC ) ; RegMap [ VR ] = NewVR ; } for ( IFMapType :: iterator I = IFMap . begin ( ) , E = IFMap . end ( ) ; I != E ; ++ I ) { MachineInstr * MI = MRI -> getVRegDef ( I -> first ) ; MachineBasicBlock & B = * MI -> getParent ( ) ; DebugLoc DL = MI -> getDebugLoc ( ) ; unsigned NewR = RegMap [ I -> first ] ; bool R32 = MRI -> getRegClass ( NewR ) == & <STR_LIT> ; const MCInstrDesc & D = R32 ? HII -> get ( <STR_LIT> ) : HII -> get ( <STR_LIT> ) ; IFRecord IF = I -> second [ <NUM_LIT> ] . first ; unsigned Wdh = IF . Wdh , Off = IF . Off ; unsigned InsS = <NUM_LIT> ; if ( R32 && MRI -> getRegClass ( IF . InsR ) == & <STR_LIT> ) { InsS = <STR_LIT> ; if ( Off >= <NUM_LIT> ) { InsS = <STR_LIT> ; Off -= <NUM_LIT> ; } } MachineBasicBlock :: iterator At = MI ;

if ( MI -> isPHI ( ) ) At = B . getFirstNonPHI ( ) ;


<s> for ( const MachineOperand & MO : MI -> operands ( ) ) {

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


<s> void <ISA_LIT>GenInsert :: getInstrUses ( const MachineInstr * MI , RegisterSet & Uses ) const { for ( const MachineOperand & MO : MI -> operands ( ) ) {

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


<s> initialize<ISA_LIT>GenInsertPass ( * PassRegistry :: getPassRegistry ( ) ) ;


<s> <ISA_LIT>GenInsert ( ) : MachineFunctionPass ( ID ) {

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


<s> if ( L == Seq . end ( ) ) Seq . push_back ( VR ) ; else Seq . insert ( L , VR ) ; unsigned S = Seq . size ( ) ; if ( S > MaxSize ) Seq . resize ( MaxSize ) ;


<s> void OrderedRegisterList :: insert ( unsigned VR ) { iterator L = llvm :: lower_bound ( Seq , VR , Ord ) ; if ( L == Seq . end ( ) ) Seq . push_back ( VR ) ; else Seq . insert ( L , VR ) ; unsigned S = Seq . size ( ) ; if ( S > MaxSize ) Seq . resize ( MaxSize ) ; assert ( Seq . size ( ) <= MaxSize ) ;


<s> return DebugFlag && isCurrentDebugType ( DEBUG_TYPE ) ;


<s> OrderedRegisterList ( const RegisterOrdering & RO ) : MaxSize ( MaxORLSize ) , Ord ( RO ) {


<s> PairMapType Memo ; for ( IFMapType :: iterator I = IFMap . begin ( ) , E = IFMap . end ( ) ; I != E ; ++ I ) pruneUsesTooFar ( I -> first , RPO , Memo ) ; pruneEmptyLists ( ) ;


<s> bool DefEx = HII -> isConstExtended ( * DefVR ) ; bool HasNE = false ; for ( unsigned i = <NUM_LIT> , n = LL . size ( ) ; i < n ; ++ i ) { if ( LL [ i ] . second . empty ( ) ) continue ; HasNE = true ; break ; } if ( ! DefEx || HasNE ) { auto IsEmpty = [ ] ( const IFRecordWithRegSet & IR ) -> bool { return IR . second . empty ( ) ; } ; llvm :: erase_if ( LL , IsEmpty ) ; } else { IFRecord MaxIF = LL [ <NUM_LIT> ] . first ; for ( unsigned i = <NUM_LIT> , n = LL . size ( ) ; i < n ; ++ i ) { const IFRecord & IF = LL [ i ] . first ; unsigned M0 = BaseOrd [ MaxIF . SrcR ] , M1 = BaseOrd [ MaxIF . InsR ] ; unsigned R0 = BaseOrd [ IF . SrcR ] , R1 = BaseOrd [ IF . InsR ] ; if ( M0 > R0 ) continue ; if ( M0 == R0 ) { if ( M1 > R1 ) continue ; if ( M1 == R1 ) { if ( MaxIF . Wdh > IF . Wdh ) continue ; if ( MaxIF . Wdh == IF . Wdh && MaxIF . Off >= IF . Off ) continue ; } } MaxIF = IF ; } LL . clear ( ) ; LL . push_back ( std :: make_pair ( MaxIF , RegisterSet ( ) ) ) ; } for ( unsigned i = <NUM_LIT> , n = LL . size ( ) ; i < n ; ) { const RegisterSet & RMi = LL [ i ] . second ; unsigned j = <NUM_LIT> ; while ( j < n ) {

if ( j != i && LL [ j ] . second . includes ( RMi ) ) break ;


<s> IterListType Prune ; for ( IFMapType :: iterator I = IFMap . begin ( ) , E = IFMap . end ( ) ; I != E ; ++ I ) { if ( I -> second . empty ( ) ) Prune . push_back ( I ) ; } for ( unsigned i = <NUM_LIT> , n = Prune . size ( ) ; i < n ; ++ i ) IFMap . erase ( Prune [ i ] ) ;


<s> void <ISA_LIT>GenInsert :: pruneEmptyLists ( ) { using IterListType = SmallVector < IFMapType :: iterator , <NUM_LIT> > ; IterListType Prune ; for ( IFMapType :: iterator I = IFMap . begin ( ) , E = IFMap . end ( ) ; I != E ; ++ I ) {

if ( I -> second . empty ( ) ) Prune . push_back ( I ) ;


<s> IFMapType :: iterator F = IFMap . find ( VR ) ; assert ( F != IFMap . end ( ) ) ; IFListType & LL = F -> second ; auto IsCopy = [ ] ( const IFRecordWithRegSet & IR ) -> bool {


<s> void OrderedRegisterList :: remove ( unsigned VR ) { iterator L = llvm :: lower_bound ( Seq , VR , Ord ) ; if ( L != Seq . end ( ) ) Seq . erase ( L ) ;


<s> if ( MI -> isInlineAsm ( ) || ! MI -> isSafeToMove ( nullptr , Store ) ) continue ; bool AllDead = true ; SmallVector < unsigned , <NUM_LIT> > Regs ; for ( const MachineOperand & MO : MI -> operands ( ) ) { if ( ! MO . isReg ( ) || ! MO . isDef ( ) ) continue ; Register R = MO . getReg ( ) ;

if ( ! R . isVirtual ( ) || ! MRI -> use_nodbg_empty ( R ) ) {


<s> BTLoc . run ( ) ; CellMapShadow MS ( BTLoc ) ; CMS = & MS ; buildOrderingMF ( BaseOrd ) ; buildOrderingBT ( BaseOrd , CellOrd ) ; if ( isDebug ( ) ) { dbgs ( ) << <STR_LIT> ; for ( RegisterOrdering :: iterator I = CellOrd . begin ( ) , E = CellOrd . end ( ) ; I != E ; ++ I ) { unsigned VR = I -> first , Pos = I -> second ; dbgs ( ) << printReg ( VR , HRI ) << <STR_LIT> << Pos << <STR_LIT> ; } } MachineBasicBlock * RootB = MDT -> getRoot ( ) ; OrderedRegisterList AvailR ( CellOrd ) ; const char * const TGName = <STR_LIT> ; const char * const TGDesc = <STR_LIT> ; { NamedRegionTimer _T ( <STR_LIT> , <STR_LIT> , TGName , TGDesc , TimingDetail ) ; collectInBlock ( RootB , AvailR ) ; computeRemovableRegisters ( ) ; } if ( isDebug ( ) ) { dbgs ( ) << <STR_LIT> ; dump_map ( ) ; } if ( IFMap . empty ( ) ) return Changed ; { NamedRegionTimer _T ( <STR_LIT> , <STR_LIT> , TGName , TGDesc , TimingDetail ) ; pruneCandidates ( ) ; } if ( isDebug ( ) ) { dbgs ( ) << <STR_LIT> ; dump_map ( ) ; } if ( IFMap . empty ( ) ) return Changed ; { NamedRegionTimer _T ( <STR_LIT> , <STR_LIT> , TGName , TGDesc , TimingDetail ) ; selectCandidates ( ) ; } if ( isDebug ( ) ) { dbgs ( ) << <STR_LIT> ; dump_map ( ) ; } if ( VRegIndexCutoff . getPosition ( ) ) { unsigned Cutoff = VRegIndexCutoff ; using IterListType = SmallVector < IFMapType :: iterator , <NUM_LIT> > ; IterListType Out ; for ( IFMapType :: iterator I = IFMap . begin ( ) , E = IFMap . end ( ) ; I != E ; ++ I ) { unsigned Idx = Register :: virtReg2Index ( I -> first ) ; if ( Idx >= Cutoff ) Out . push_back ( I ) ; } for ( unsigned i = <NUM_LIT> , n = Out . size ( ) ; i < n ; ++ i ) IFMap . erase ( Out [ i ] ) ;


<s> bool <ISA_LIT>GenInsert :: runOnMachineFunction ( MachineFunction & MF ) { if ( skipFunction ( MF . getFunction ( ) ) ) return false ; bool Timing = OptTiming , TimingDetail = Timing && OptTimingDetail ; bool Changed = false ; assert ( ! OptSelectAll0 || ! OptSelectHas0 ) ; IFMap . clear ( ) ; BaseOrd . clear ( ) ; CellOrd . clear ( ) ; const auto & ST = MF . getSubtarget < <ISA_LIT>Subtarget > ( ) ; HII = ST . getInstrInfo ( ) ; HRI = ST . getRegisterInfo ( ) ; MFN = & MF ; MRI = & MF . getRegInfo ( ) ; MDT = & getAnalysis < MachineDominatorTree > ( ) ; Changed = removeDeadCode ( MDT -> getRootNode ( ) ) ; const <ISA_LIT>Evaluator HE ( * HRI , * MRI , * HII , MF ) ; BitTracker BTLoc ( HE , MF ) ; BTLoc . trace ( isDebug ( ) ) ; BTLoc . run ( ) ; CellMapShadow MS ( BTLoc ) ; CMS = & MS ; buildOrderingMF ( BaseOrd ) ; buildOrderingBT ( BaseOrd , CellOrd ) ; if ( isDebug ( ) ) { dbgs ( ) << <STR_LIT> ; for ( RegisterOrdering :: iterator I = CellOrd . begin ( ) , E = CellOrd . end ( ) ; I != E ; ++ I ) { unsigned VR = I -> first , Pos = I -> second ; dbgs ( ) << printReg ( VR , HRI ) << <STR_LIT> << Pos << <STR_LIT> ; }


<s> bool Accept = false ; if ( SelectAll0 ) { bool All0 = true ; for ( unsigned R = Us . find_first ( ) ; R ; R = Us . find_next ( R ) ) { if ( UseC [ R ] == <NUM_LIT> ) continue ; All0 = false ; break ; } Accept = All0 ; } else if ( SelectHas0 ) { bool Has0 = false ; for ( unsigned R = Us . find_first ( ) ; R ; R = Us . find_next ( R ) ) { if ( UseC [ R ] != <NUM_LIT> ) continue ; Has0 = true ; break ; } Accept = Has0 ; } if ( Accept ) LL . push_back ( M ) ; } AllRMs . clear ( ) ; for ( IFMapType :: iterator I = IFMap . begin ( ) ; I != End ; ++ I ) { const IFListType & LL = I -> second ; if ( ! LL . empty ( ) ) AllRMs . insert ( LL [ <NUM_LIT> ] . second ) ; } for ( IFMapType :: iterator I = IFMap . begin ( ) ; I != End ; ++ I ) { IFListType & LL = I -> second ;


<s> IFMapType :: iterator End = IFMap . end ( ) ; for ( IFMapType :: iterator I = IFMap . begin ( ) ; I != End ; ++ I ) { const IFListType & LL = I -> second ; RegisterSet TT ; for ( unsigned i = <NUM_LIT> , n = LL . size ( ) ; i < n ; ++ i ) TT . insert ( LL [ i ] . second ) ; for ( unsigned R = TT . find_first ( ) ; R ; R = TT . find_next ( R ) ) RemC [ R ] ++ ; AllRMs . insert ( TT ) ; } for ( unsigned R = AllRMs . find_first ( ) ; R ; R = AllRMs . find_next ( R ) ) { using use_iterator = MachineRegisterInfo :: use_nodbg_iterator ; using InstrSet = SmallSet < const MachineInstr * , <NUM_LIT> > ; InstrSet UIs ; use_iterator E = MRI -> use_nodbg_end ( ) ; for ( use_iterator I = MRI -> use_nodbg_begin ( R ) ; I != E ; ++ I ) UIs . insert ( I -> getParent ( ) ) ; unsigned C = UIs . size ( ) ;


<s> for ( RegisterOrdering :: iterator I = RB . begin ( ) , E = RB . end ( ) ; I != E ; ++ I ) VRs . push_back ( I -> first ) ; std :: sort ( VRs . begin ( ) , VRs . end ( ) , LexCmp ) ;

for ( unsigned i = <NUM_LIT> , n = VRs . size ( ) ; i < n ; ++ i ) RO . insert ( std :: make_pair ( VRs [ i ] , i ) ) ;


<s> for ( mb_iterator I = B . begin ( ) , E = B . end ( ) ; I != E ; ++ I ) { const MachineInstr * MI = & * I ; for ( unsigned i = <NUM_LIT> , n = MI -> getNumOperands ( ) ; i < n ; ++ i ) { const MachineOperand & MO = MI -> getOperand ( i ) ; if ( MO . isReg ( ) && MO . isDef ( ) ) { unsigned R = MO . getReg ( ) ; assert ( MO . getSubReg ( ) == <NUM_LIT> && <STR_LIT> ) ; if ( TargetRegisterInfo :: isVirtualRegister ( R ) ) RO . insert ( std :: make_pair ( R , Index ++ ) ) ;


<s> RegisterSet BlockDefs , InsDefs ; for ( MachineBasicBlock :: iterator I = B -> begin ( ) , E = B -> end ( ) ; I != E ; ++ I ) { MachineInstr * MI = & * I ; InsDefs . clear ( ) ; getInstrDefs ( MI , InsDefs ) ; bool Skip = MI -> isCopy ( ) || MI -> isRegSequence ( ) ; if ( ! Skip ) { for ( unsigned VR = InsDefs . find_first ( ) ; VR ; VR = InsDefs . find_next ( VR ) ) { if ( ! DoConst && isConstant ( VR ) ) continue ; if ( findSelfReference ( VR ) || isSmallConstant ( VR ) ) continue ; findRecordInsertForms ( VR , AVs ) ;


<s> PairMapType :: iterator F = M . find ( std :: make_pair ( FromN , ToN ) ) ; if ( F != M . end ( ) ) return F -> second ; unsigned ToRPO = RPO . lookup ( ToN ) ; unsigned MaxD = <NUM_LIT> ; using pred_iterator = MachineBasicBlock :: const_pred_iterator ; for ( pred_iterator I = ToB -> pred_begin ( ) , E = ToB -> pred_end ( ) ; I != E ; ++ I ) { const MachineBasicBlock * PB = * I ; if ( PB == FromB || RPO . lookup ( PB -> getNumber ( ) ) >= ToRPO ) continue ; unsigned D = PB -> size ( ) + distance ( FromB , PB , RPO , M ) ; if ( D > MaxD ) MaxD = D ;


<s> unsigned FromN = FromB -> getNumber ( ) , ToN = ToB -> getNumber ( ) ; PairMapType :: iterator F = M . find ( std :: make_pair ( FromN , ToN ) ) ; if ( F != M . end ( ) ) return F -> second ; unsigned ToRPO = RPO . lookup ( ToN ) ; unsigned MaxD = <NUM_LIT> ; using pred_iterator = MachineBasicBlock :: const_pred_iterator ; for ( pred_iterator I = ToB -> pred_begin ( ) , E = ToB -> pred_end ( ) ; I != E ; ++ I ) { const MachineBasicBlock * PB = * I ;

if ( PB == FromB || RPO . lookup ( PB -> getNumber ( ) ) >= ToRPO ) continue ;


<s> void <ISA_LIT>GenInsert :: dump_map ( ) const { using iterator = IFMapType :: const_iterator ;

for ( iterator I = IFMap . begin ( ) , E = IFMap . end ( ) ; I != E ; ++ I ) {


<s> for ( iterator I = IFMap . begin ( ) , E = IFMap . end ( ) ; I != E ; ++ I ) {

dbgs ( ) << <STR_LIT> << PrintReg ( I -> first , HRI ) << <STR_LIT> ;


<s> dbgs ( ) << __func__ << <STR_LIT> << PrintReg ( VR , HRI ) << <STR_LIT> << PrintORL ( AVs , HRI ) << <STR_LIT> ; } if ( AVs . size ( ) == <NUM_LIT> ) return false ; using iterator = OrderedRegisterList :: iterator ; BitValueOrdering BVO ( BaseOrd ) ; const BitTracker :: RegisterCell & RC = CMS -> lookup ( VR ) ; uint16_t W = RC . width ( ) ; using RSRecord = std :: pair < unsigned , uint16_t > ; using RSListType = std :: vector < RSRecord > ; using LRSMapType = DenseMap < unsigned , RSListType > ; LRSMapType LM ; for ( uint16_t S = <NUM_LIT> ; S < W ; ++ S ) { iterator B = AVs . begin ( ) , E = AVs . end ( ) ; uint16_t L ; for ( L = <NUM_LIT> ; L < W - S ; ++ L ) { RegisterCellBitCompareSel RCB ( VR , S + L , L , BVO , * CMS ) ; iterator NewB = std :: lower_bound ( B , E , VR , RCB ) ; iterator NewE = std :: upper_bound ( NewB , E , VR , RCB ) ; if ( L > <NUM_LIT> ) { for ( iterator I = B ; I != NewB ; ++ I ) LM [ L ] . push_back ( std :: make_pair ( * I , S ) ) ; for ( iterator I = NewE ; I != E ; ++ I ) LM [ L ] . push_back ( std :: make_pair ( * I , S ) ) ; } B = NewB , E = NewE ; if ( B == E ) break ; } assert ( B == E || L == W - S ) ; if ( B != E ) { for ( iterator I = B ; I != E ; ++ I ) LM [ L ] . push_back ( std :: make_pair ( * I , S ) ) ;


<s> if ( M0 == R0 ) { if ( M1 > R1 ) continue ; if ( M1 == R1 ) { if ( MaxIF . Wdh > IF . Wdh ) continue ; if ( MaxIF . Wdh == IF . Wdh && MaxIF . Off >= IF . Off ) continue ; } } MaxIF = IF ; } LL . clear ( ) ; LL . push_back ( std :: make_pair ( MaxIF , RegisterSet ( ) ) ) ; } for ( unsigned i = <NUM_LIT> , n = LL . size ( ) ; i < n ; ) { const RegisterSet & RMi = LL [ i ] . second ; unsigned j = <NUM_LIT> ; while ( j < n ) { if ( j != i && LL [ j ] . second . includes ( RMi ) ) break ; j ++ ; } if ( j == n ) {


<s> return IR . first . Wdh == <NUM_LIT> && ( IR . first . Off == <NUM_LIT> || IR . first . Off == <NUM_LIT> ) ; } ; auto End = llvm :: remove_if ( LL , IsCopy ) ;

if ( End != LL . end ( ) ) LL . erase ( End , LL . end ( ) ) ;


<s> if ( ! MO . isReg ( ) || ! MO . isDef ( ) ) continue ; unsigned R = MO . getReg ( ) ; if ( ! TargetRegisterInfo :: isVirtualRegister ( R ) || ! MRI -> use_nodbg_empty ( R ) ) { AllDead = false ; break ; } Regs . push_back ( R ) ; } if ( ! AllDead ) continue ; B -> erase ( MI ) ;

for ( unsigned I = <NUM_LIT> , N = Regs . size ( ) ; I != N ; ++ I ) MRI -> markUsesInDebugValueAsUndef ( Regs [ I ] ) ;


<s> MFN = & MF ; MRI = & MF . getRegInfo ( ) ; MDT = & getAnalysis < MachineDominatorTree > ( ) ; Changed = removeDeadCode ( MDT -> getRootNode ( ) ) ; const <ISA_LIT>Evaluator HE ( * HRI , * MRI , * HII , MF ) ; BitTracker BTLoc ( HE , MF ) ; BTLoc . trace ( isDebug ( ) ) ; BTLoc . run ( ) ; CellMapShadow MS ( BTLoc ) ; CMS = & MS ; buildOrderingMF ( BaseOrd ) ; buildOrderingBT ( BaseOrd , CellOrd ) ; if ( isDebug ( ) ) { dbgs ( ) << <STR_LIT> ; for ( RegisterOrdering :: iterator I = CellOrd . begin ( ) , E = CellOrd . end ( ) ; I != E ; ++ I ) { unsigned VR = I -> first , Pos = I -> second ; dbgs ( ) << PrintReg ( VR , HRI ) << <STR_LIT> << Pos << <STR_LIT> ; } } MachineBasicBlock * RootB = MDT -> getRoot ( ) ; OrderedRegisterList AvailR ( CellOrd ) ; const char * const TGName = <STR_LIT> ; const char * const TGDesc = <STR_LIT> ; { NamedRegionTimer _T ( <STR_LIT> , <STR_LIT> , TGName , TGDesc , TimingDetail ) ; collectInBlock ( RootB , AvailR ) ; computeRemovableRegisters ( ) ; } if ( isDebug ( ) ) { dbgs ( ) << <STR_LIT> ; dump_map ( ) ; } if ( IFMap . empty ( ) ) return Changed ; { NamedRegionTimer _T ( <STR_LIT> , <STR_LIT> , TGName , TGDesc , TimingDetail ) ;


<s> MachineInstr * MI = & * I ; InsDefs . clear ( ) ; getInstrDefs ( MI , InsDefs ) ; bool Skip = MI -> isCopy ( ) || MI -> isRegSequence ( ) ; if ( ! Skip ) { for ( unsigned VR = InsDefs . find_first ( ) ; VR ; VR = InsDefs . find_next ( VR ) ) { if ( ! DoConst && isConstant ( VR ) ) continue ; if ( findSelfReference ( VR ) || isSmallConstant ( VR ) ) continue ; findRecordInsertForms ( VR , AVs ) ; if ( IFMap . size ( ) > MaxIFMSize ) return ; } } for ( unsigned VR = InsDefs . find_first ( ) ; VR ; VR = InsDefs . find_next ( VR ) ) AVs . insert ( VR ) ; BlockDefs . insert ( InsDefs ) ; } for ( auto * DTN : children < MachineDomTreeNode * > ( MDT -> getNode ( B ) ) ) { MachineBasicBlock * SB = DTN -> getBlock ( ) ;


<s> bool DoConst = OptConst ; RegisterSet BlockDefs , InsDefs ; for ( MachineBasicBlock :: iterator I = B -> begin ( ) , E = B -> end ( ) ; I != E ; ++ I ) { MachineInstr * MI = & * I ; InsDefs . clear ( ) ; getInstrDefs ( MI , InsDefs ) ; bool Skip = MI -> isCopy ( ) || MI -> isRegSequence ( ) ; if ( ! Skip ) { for ( unsigned VR = InsDefs . find_first ( ) ; VR ; VR = InsDefs . find_next ( VR ) ) { if ( ! DoConst && isConstant ( VR ) ) continue ; if ( findSelfReference ( VR ) || isSmallConstant ( VR ) ) continue ; findRecordInsertForms ( VR , AVs ) ; if ( IFMap . size ( ) > MaxIFMSize ) return ; } } for ( unsigned VR = InsDefs . find_first ( ) ; VR ; VR = InsDefs . find_next ( VR ) ) AVs . insert ( VR ) ; BlockDefs . insert ( InsDefs ) ; } for ( auto * DTN : children < MachineDomTreeNode * > ( MDT -> getNode ( B ) ) ) { MachineBasicBlock * SB = DTN -> getBlock ( ) ; collectInBlock ( SB , AVs ) ; }

for ( unsigned VR = BlockDefs . find_first ( ) ; VR ; VR = BlockDefs . find_next ( VR ) ) AVs . remove ( VR ) ;


<s> else Seq . insert ( L , VR ) ; unsigned S = Seq . size ( ) ;

if ( S > MaxSize ) Seq . resize ( MaxSize ) ;


<s> else Seq . insert ( L , VR ) ; unsigned S = Seq . size ( ) ; if ( S > MaxSize ) Seq . resize ( MaxSize ) ; assert ( Seq . size ( ) <= MaxSize ) ;


<s> void OrderedRegisterList :: remove ( unsigned VR ) { iterator L = std :: lower_bound ( Seq . begin ( ) , Seq . end ( ) , VR , Ord ) ;

if ( L != Seq . end ( ) ) Seq . erase ( L ) ;


<s> if ( L != Seq . end ( ) ) Seq . erase ( L ) ;


<s> collectInBlock ( RootB , AvailR ) ; computeRemovableRegisters ( ) ; } if ( isDebug ( ) ) { dbgs ( ) << <STR_LIT> ; dump_map ( ) ; } if ( IFMap . empty ( ) ) return Changed ; { NamedRegionTimer _T ( <STR_LIT> , <STR_LIT> , TGName , TGDesc , TimingDetail ) ; pruneCandidates ( ) ; } if ( isDebug ( ) ) { dbgs ( ) << <STR_LIT> ; dump_map ( ) ; } if ( IFMap . empty ( ) ) return Changed ; { NamedRegionTimer _T ( <STR_LIT> , <STR_LIT> , TGName , TGDesc , TimingDetail ) ; selectCandidates ( ) ; } if ( isDebug ( ) ) { dbgs ( ) << <STR_LIT> ; dump_map ( ) ; } if ( VRegIndexCutoff . getPosition ( ) ) { unsigned Cutoff = VRegIndexCutoff ; using IterListType = SmallVector < IFMapType :: iterator , <NUM_LIT> > ; IterListType Out ; for ( IFMapType :: iterator I = IFMap . begin ( ) , E = IFMap . end ( ) ; I != E ; ++ I ) { unsigned Idx = TargetRegisterInfo :: virtReg2Index ( I -> first ) ; if ( Idx >= Cutoff ) Out . push_back ( I ) ; } for ( unsigned i = <NUM_LIT> , n = Out . size ( ) ; i < n ; ++ i ) IFMap . erase ( Out [ i ] ) ; }


<s> bool <ISA_LIT>GenInsert :: runOnMachineFunction ( MachineFunction & MF ) { if ( skipFunction ( MF . getFunction ( ) ) ) return false ; bool Timing = OptTiming , TimingDetail = Timing && OptTimingDetail ; bool Changed = false ; assert ( ! OptSelectAll0 || ! OptSelectHas0 ) ; IFMap . clear ( ) ; BaseOrd . clear ( ) ; CellOrd . clear ( ) ; const auto & ST = MF . getSubtarget < <ISA_LIT>Subtarget > ( ) ; HII = ST . getInstrInfo ( ) ; HRI = ST . getRegisterInfo ( ) ; MFN = & MF ; MRI = & MF . getRegInfo ( ) ; MDT = & getAnalysis < MachineDominatorTree > ( ) ; Changed = removeDeadCode ( MDT -> getRootNode ( ) ) ; const <ISA_LIT>Evaluator HE ( * HRI , * MRI , * HII , MF ) ; BitTracker BTLoc ( HE , MF ) ; BTLoc . trace ( isDebug ( ) ) ; BTLoc . run ( ) ; CellMapShadow MS ( BTLoc ) ; CMS = & MS ; buildOrderingMF ( BaseOrd ) ; buildOrderingBT ( BaseOrd , CellOrd ) ; if ( isDebug ( ) ) { dbgs ( ) << <STR_LIT> ; for ( RegisterOrdering :: iterator I = CellOrd . begin ( ) , E = CellOrd . end ( ) ; I != E ; ++ I ) { unsigned VR = I -> first , Pos = I -> second ; dbgs ( ) << printReg ( VR , HRI ) << <STR_LIT> << Pos << <STR_LIT> ; } } MachineBasicBlock * RootB = MDT -> getRoot ( ) ; OrderedRegisterList AvailR ( CellOrd ) ; const char * const TGName = <STR_LIT> ; const char * const TGDesc = <STR_LIT> ; { NamedRegionTimer _T ( <STR_LIT> , <STR_LIT> , TGName , TGDesc , TimingDetail ) ; collectInBlock ( RootB , AvailR ) ; computeRemovableRegisters ( ) ; } if ( isDebug ( ) ) {


<s> for ( unsigned i = <NUM_LIT> , n = MI -> getNumOperands ( ) ; i < n ; ++ i ) { const MachineOperand & MO = MI -> getOperand ( i ) ;


<s> Register R = MO . getReg ( ) ; if ( ! Register :: isVirtualRegister ( R ) || ! MRI -> use_nodbg_empty ( R ) ) { AllDead = false ; break ; } Regs . push_back ( R ) ; } if ( ! AllDead ) continue ; B -> erase ( MI ) ; for ( unsigned I = <NUM_LIT> , N = Regs . size ( ) ; I != N ; ++ I ) MRI -> markUsesInDebugValueAsUndef ( Regs [ I ] ) ; Changed = true ; } return Changed ;


<s> for ( auto I = B -> rbegin ( ) , E = B -> rend ( ) ; I != E ; ++ I ) Instrs . push_back ( & * I ) ; for ( auto I = Instrs . begin ( ) , E = Instrs . end ( ) ; I != E ; ++ I ) { MachineInstr * MI = * I ; unsigned Opc = MI -> getOpcode ( ) ; if ( Opc == TargetOpcode :: LIFETIME_START || Opc == TargetOpcode :: LIFETIME_END ) continue ; bool Store = false ; if ( MI -> isInlineAsm ( ) || ! MI -> isSafeToMove ( nullptr , Store ) ) continue ; bool AllDead = true ; SmallVector < unsigned , <NUM_LIT> > Regs ; for ( const MachineOperand & MO : MI -> operands ( ) ) { if ( ! MO . isReg ( ) || ! MO . isDef ( ) ) continue ; Register R = MO . getReg ( ) ; if ( ! Register :: isVirtualRegister ( R ) || ! MRI -> use_nodbg_empty ( R ) ) { AllDead = false ; break ; } Regs . push_back ( R ) ;


<s> } bool Recorded = false ; for ( iterator I = AVs . begin ( ) , E = AVs . end ( ) ; I != E ; ++ I ) { unsigned SrcR = * I ; int FDi = - <NUM_LIT> , LDi = - <NUM_LIT> ; const BitTracker :: RegisterCell & AC = CMS -> lookup ( SrcR ) ; uint16_t AW = AC . width ( ) ; for ( uint16_t i = <NUM_LIT> , w = std :: min ( W , AW ) ; i < w ; ++ i ) { if ( RC [ i ] == AC [ i ] ) continue ; if ( FDi == - <NUM_LIT> ) FDi = i ; LDi = i ; } if ( FDi == - <NUM_LIT> ) continue ; uint16_t FD = FDi , LD = LDi ; uint16_t MinL = LD - FD + <NUM_LIT> ; for ( uint16_t L = MinL ; L < W ; ++ L ) { LRSMapType :: iterator F = LM . find ( L ) ; if ( F == LM . end ( ) ) continue ; RSListType & LL = F -> second ; for ( unsigned i = <NUM_LIT> , n = LL . size ( ) ; i < n ; ++ i ) { uint16_t S = LL [ i ] . second ; if ( S > FD ) continue ; uint16_t EL = L - MinL ; uint16_t LowS = ( EL < FD ) ? FD - EL : <NUM_LIT> ; if ( S < LowS ) continue ; unsigned InsR = LL [ i ] . first ; if ( ! isValidInsertForm ( VR , SrcR , InsR , L , S ) ) continue ; if ( isDebug ( ) ) {

dbgs ( ) << PrintReg ( VR , HRI ) << <STR_LIT> << PrintReg ( SrcR , HRI ) << ',' << PrintReg ( InsR , HRI ) << <STR_LIT> << L << <STR_LIT> << S << <STR_LIT> ;


<s> initialize<ISA_LIT>GenInsertPass ( * PassRegistry :: getPassRegistry ( ) ) ;


<s> if ( I -> second . empty ( ) ) Prune . push_back ( I ) ; } for ( unsigned i = <NUM_LIT> , n = Prune . size ( ) ; i < n ; ++ i ) IFMap . erase ( Prune [ i ] ) ;


<s> for ( IFMapType :: iterator I = IFMap . begin ( ) , E = IFMap . end ( ) ; I != E ; ++ I ) { if ( I -> second . empty ( ) ) Prune . push_back ( I ) ;


<s> for ( auto I = Instrs . begin ( ) , E = Instrs . end ( ) ; I != E ; ++ I ) { MachineInstr * MI = * I ; unsigned Opc = MI -> getOpcode ( ) ; if ( Opc == TargetOpcode :: LIFETIME_START || Opc == TargetOpcode :: LIFETIME_END ) continue ; bool Store = false ; if ( MI -> isInlineAsm ( ) || ! MI -> isSafeToMove ( nullptr , Store ) ) continue ; bool AllDead = true ; SmallVector < unsigned , <NUM_LIT> > Regs ; for ( const MachineOperand & MO : MI -> operands ( ) ) { if ( ! MO . isReg ( ) || ! MO . isDef ( ) ) continue ; unsigned R = MO . getReg ( ) ; if ( ! TargetRegisterInfo :: isVirtualRegister ( R ) || ! MRI -> use_nodbg_empty ( R ) ) { AllDead = false ; break ; } Regs . push_back ( R ) ; } if ( ! AllDead ) continue ; B -> erase ( MI ) ;


<s> BTLoc . trace ( isDebug ( ) ) ; BTLoc . run ( ) ; CellMapShadow MS ( BTLoc ) ; CMS = & MS ; buildOrderingMF ( BaseOrd ) ; buildOrderingBT ( BaseOrd , CellOrd ) ; if ( isDebug ( ) ) { dbgs ( ) << <STR_LIT> ; for ( RegisterOrdering :: iterator I = CellOrd . begin ( ) , E = CellOrd . end ( ) ; I != E ; ++ I ) { unsigned VR = I -> first , Pos = I -> second ; dbgs ( ) << PrintReg ( VR , HRI ) << <STR_LIT> << Pos << <STR_LIT> ; } } MachineBasicBlock * RootB = MDT -> getRoot ( ) ; OrderedRegisterList AvailR ( CellOrd ) ; const char * const TGName = <STR_LIT> ; const char * const TGDesc = <STR_LIT> ; { NamedRegionTimer _T ( <STR_LIT> , <STR_LIT> , TGName , TGDesc , TimingDetail ) ; collectInBlock ( RootB , AvailR ) ; computeRemovableRegisters ( ) ; } if ( isDebug ( ) ) { dbgs ( ) << <STR_LIT> ; dump_map ( ) ; } if ( IFMap . empty ( ) ) return Changed ; { NamedRegionTimer _T ( <STR_LIT> , <STR_LIT> , TGName , TGDesc , TimingDetail ) ; pruneCandidates ( ) ; } if ( isDebug ( ) ) { dbgs ( ) << <STR_LIT> ; dump_map ( ) ; } if ( IFMap . empty ( ) ) return Changed ; { NamedRegionTimer _T ( <STR_LIT> , <STR_LIT> , TGName , TGDesc , TimingDetail ) ; selectCandidates ( ) ; } if ( isDebug ( ) ) { dbgs ( ) << <STR_LIT> ; dump_map ( ) ; } if ( VRegIndexCutoff . getPosition ( ) ) { unsigned Cutoff = VRegIndexCutoff ; typedef SmallVector < IFMapType :: iterator , <NUM_LIT> > IterListType ; IterListType Out ; for ( IFMapType :: iterator I = IFMap . begin ( ) , E = IFMap . end ( ) ; I != E ; ++ I ) { unsigned Idx = TargetRegisterInfo :: virtReg2Index ( I -> first ) ; if ( Idx >= Cutoff ) Out . push_back ( I ) ; } for ( unsigned i = <NUM_LIT> , n = Out . size ( ) ; i < n ; ++ i ) IFMap . erase ( Out [ i ] ) ; }


<s> assert ( MinI != LL . end ( ) ) ; IFRecordWithRegSet M = * MinI ; LL . clear ( ) ; RegisterSet Us ; const MachineInstr * DefI = MRI -> getVRegDef ( I -> first ) ; getInstrUses ( DefI , Us ) ; bool Accept = false ; if ( SelectAll0 ) { bool All0 = true ; for ( unsigned R = Us . find_first ( ) ; R ; R = Us . find_next ( R ) ) { if ( UseC [ R ] == <NUM_LIT> ) continue ; All0 = false ; break ; } Accept = All0 ; } else if ( SelectHas0 ) { bool Has0 = false ; for ( unsigned R = Us . find_first ( ) ; R ; R = Us . find_next ( R ) ) { if ( UseC [ R ] != <NUM_LIT> ) continue ; Has0 = true ; break ; } Accept = Has0 ; } if ( Accept ) LL . push_back ( M ) ; } AllRMs . clear ( ) ; for ( IFMapType :: iterator I = IFMap . begin ( ) ; I != End ; ++ I ) { const IFListType & LL = I -> second ; if ( ! LL . empty ( ) ) AllRMs . insert ( LL [ <NUM_LIT> ] . second ) ; } for ( IFMapType :: iterator I = IFMap . begin ( ) ; I != End ; ++ I ) { IFListType & LL = I -> second ; if ( LL . empty ( ) ) continue ; unsigned SR = LL [ <NUM_LIT> ] . first . SrcR , IR = LL [ <NUM_LIT> ] . first . InsR ; if ( AllRMs [ SR ] || AllRMs [ IR ] ) LL . clear ( ) ; } pruneEmptyLists ( ) ;


<s> void <ISA_LIT>GenInsert :: buildOrderingBT ( RegisterOrdering & RB , RegisterOrdering & RO ) const { BitValueOrdering BVO ( RB ) ; RegisterCellLexCompare LexCmp ( BVO , * CMS ) ; using SortableVectorType = std :: vector < unsigned > ; SortableVectorType VRs ; for ( auto & I : RB ) VRs . push_back ( I . first ) ;


<s> for ( auto & J : LL ) findRemovableRegisters ( I . first , J . first , J . second ) ; }


<s> for ( const auto & I : IFMap ) { dbgs ( ) << <STR_LIT> << printReg ( I . first , HRI ) << <STR_LIT> ; const IFListType & LL = I . second ; for ( const auto & J : LL ) dbgs ( ) << <STR_LIT> << PrintIFR ( J . first , HRI ) << <STR_LIT> << PrintRegSet ( J . second , HRI ) << '\n' ;


<s> for ( const auto & I : IFMap ) { dbgs ( ) << <STR_LIT> << printReg ( I . first , HRI ) << <STR_LIT> ; const IFListType & LL = I . second ;

for ( const auto & J : LL ) dbgs ( ) << <STR_LIT> << PrintIFR ( J . first , HRI ) << <STR_LIT> << PrintRegSet ( J . second , HRI ) << '\n' ;


<s> unsigned NewR = RegMap [ I . first ] ; bool R32 = MRI -> getRegClass ( NewR ) == & <STR_LIT> ; const MCInstrDesc & D = R32 ? HII -> get ( <STR_LIT> ) : HII -> get ( <STR_LIT> ) ; IFRecord IF = I . second [ <NUM_LIT> ] . first ; unsigned Wdh = IF . Wdh , Off = IF . Off ; unsigned InsS = <NUM_LIT> ; if ( R32 && MRI -> getRegClass ( IF . InsR ) == & <STR_LIT> ) { InsS = <STR_LIT> ; if ( Off >= <NUM_LIT> ) { InsS = <STR_LIT> ; Off -= <NUM_LIT> ; } } MachineBasicBlock :: iterator At = MI ; if ( MI -> isPHI ( ) ) At = B . getFirstNonPHI ( ) ; BuildMI ( B , At , DL , D , NewR ) . addReg ( IF . SrcR ) . addReg ( IF . InsR , <NUM_LIT> , InsS ) . addImm ( Wdh ) . addImm ( Off ) ; MRI -> clearKillFlags ( IF . SrcR ) ; MRI -> clearKillFlags ( IF . InsR ) ; } for ( const auto & I : IFMap ) {

MachineInstr * DefI = MRI -> getVRegDef ( I . first ) ;


<s> PairMapType Memo ; for ( const auto & I : IFMap ) pruneUsesTooFar ( I . first , RPO , Memo ) ; pruneEmptyLists ( ) ; for ( const auto & I : IFMap ) pruneRegCopies ( I . first ) ;


<s> if ( I . second . empty ( ) ) continue ; HasNE = true ; break ; } if ( ! DefEx || HasNE ) { auto IsEmpty = [ ] ( const IFRecordWithRegSet & IR ) -> bool { return IR . second . empty ( ) ; } ; llvm :: erase_if ( LL , IsEmpty ) ; } else { IFRecord MaxIF = LL [ <NUM_LIT> ] . first ; for ( unsigned i = <NUM_LIT> , n = LL . size ( ) ; i < n ; ++ i ) { const IFRecord & IF = LL [ i ] . first ; unsigned M0 = BaseOrd [ MaxIF . SrcR ] , M1 = BaseOrd [ MaxIF . InsR ] ; unsigned R0 = BaseOrd [ IF . SrcR ] , R1 = BaseOrd [ IF . InsR ] ;


<s> for ( MachineInstr * MI : Instrs ) { unsigned Opc = MI -> getOpcode ( ) ; if ( Opc == TargetOpcode :: LIFETIME_START || Opc == TargetOpcode :: LIFETIME_END ) continue ; bool Store = false ; if ( MI -> isInlineAsm ( ) || ! MI -> isSafeToMove ( nullptr , Store ) ) continue ; bool AllDead = true ; SmallVector < unsigned , <NUM_LIT> > Regs ; for ( const MachineOperand & MO : MI -> operands ( ) ) { if ( ! MO . isReg ( ) || ! MO . isDef ( ) ) continue ; Register R = MO . getReg ( ) ; if ( ! R . isVirtual ( ) || ! MRI -> use_nodbg_empty ( R ) ) { AllDead = false ; break ; }


<s> for ( MachineInstr * MI : Instrs ) { unsigned Opc = MI -> getOpcode ( ) ; if ( Opc == TargetOpcode :: LIFETIME_START || Opc == TargetOpcode :: LIFETIME_END ) continue ; bool Store = false ; if ( MI -> isInlineAsm ( ) || ! MI -> isSafeToMove ( nullptr , Store ) ) continue ; bool AllDead = true ; SmallVector < unsigned , <NUM_LIT> > Regs ; for ( const MachineOperand & MO : MI -> operands ( ) ) { if ( ! MO . isReg ( ) || ! MO . isDef ( ) ) continue ;


<s> RegisterSet TT ; for ( const auto & J : LL ) TT . insert ( J . second ) ; for ( unsigned R = TT . find_first ( ) ; R ; R = TT . find_next ( R ) ) RemC [ R ] ++ ; AllRMs . insert ( TT ) ; } for ( unsigned R = AllRMs . find_first ( ) ; R ; R = AllRMs . find_next ( R ) ) { using use_iterator = MachineRegisterInfo :: use_nodbg_iterator ; using InstrSet = SmallSet < const MachineInstr * , <NUM_LIT> > ; InstrSet UIs ; use_iterator E = MRI -> use_nodbg_end ( ) ; for ( use_iterator I = MRI -> use_nodbg_begin ( R ) ; I != E ; ++ I ) UIs . insert ( I -> getParent ( ) ) ; unsigned C = UIs . size ( ) ; unsigned D = RemC [ R ] ; UseC [ R ] = ( C > D ) ? C - D : <NUM_LIT> ; } bool SelectAll0 = OptSelectAll0 , SelectHas0 = OptSelectHas0 ; if ( ! SelectAll0 && ! SelectHas0 ) SelectAll0 = true ; IFOrdering IFO ( UseC , BaseOrd ) ; for ( IFMapType :: iterator I = IFMap . begin ( ) ; I != End ; ++ I ) { IFListType & LL = I -> second ; if ( LL . empty ( ) ) continue ; IFListType :: iterator MinI = std :: min_element ( LL . begin ( ) , LL . end ( ) , IFO ) ; assert ( MinI != LL . end ( ) ) ; IFRecordWithRegSet M = * MinI ; LL . clear ( ) ; RegisterSet Us ; const MachineInstr * DefI = MRI -> getVRegDef ( I -> first ) ; getInstrUses ( DefI , Us ) ; bool Accept = false ; if ( SelectAll0 ) { bool All0 = true ; for ( unsigned R = Us . find_first ( ) ; R ; R = Us . find_next ( R ) ) { if ( UseC [ R ] == <NUM_LIT> ) continue ; All0 = false ; break ; } Accept = All0 ; } else if ( SelectHas0 ) { bool Has0 = false ; for ( unsigned R = Us . find_first ( ) ; R ; R = Us . find_next ( R ) ) { if ( UseC [ R ] != <NUM_LIT> ) continue ; Has0 = true ; break ; } Accept = Has0 ; } if ( Accept ) LL . push_back ( M ) ;


<s> using use_iterator = MachineRegisterInfo :: use_nodbg_iterator ; using InstrSet = SmallSet < const MachineInstr * , <NUM_LIT> > ; InstrSet UIs ; use_iterator E = MRI -> use_nodbg_end ( ) ; for ( use_iterator I = MRI -> use_nodbg_begin ( R ) ; I != E ; ++ I ) UIs . insert ( I -> getParent ( ) ) ; unsigned C = UIs . size ( ) ; unsigned D = RemC [ R ] ; UseC [ R ] = ( C > D ) ? C - D : <NUM_LIT> ; } bool SelectAll0 = OptSelectAll0 , SelectHas0 = OptSelectHas0 ; if ( ! SelectAll0 && ! SelectHas0 ) SelectAll0 = true ; IFOrdering IFO ( UseC , BaseOrd ) ; for ( IFMapType :: iterator I = IFMap . begin ( ) ; I != End ; ++ I ) { IFListType & LL = I -> second ; if ( LL . empty ( ) ) continue ; IFListType :: iterator MinI = std :: min_element ( LL . begin ( ) , LL . end ( ) , IFO ) ; assert ( MinI != LL . end ( ) ) ; IFRecordWithRegSet M = * MinI ; LL . clear ( ) ; RegisterSet Us ; const MachineInstr * DefI = MRI -> getVRegDef ( I -> first ) ; getInstrUses ( DefI , Us ) ; bool Accept = false ; if ( SelectAll0 ) { bool All0 = true ; for ( unsigned R = Us . find_first ( ) ; R ; R = Us . find_next ( R ) ) { if ( UseC [ R ] == <NUM_LIT> ) continue ; All0 = false ; break ; } Accept = All0 ;


<s> void <ISA_LIT>GenInsert :: buildOrderingMF ( RegisterOrdering & RO ) const { unsigned Index = <NUM_LIT> ; using mf_iterator = MachineFunction :: const_iterator ; for ( mf_iterator A = MFN -> begin ( ) , Z = MFN -> end ( ) ; A != Z ; ++ A ) { const MachineBasicBlock & B = * A ; if ( ! CMS -> BT . reached ( & B ) ) continue ; using mb_iterator = MachineBasicBlock :: const_iterator ; for ( mb_iterator I = B . begin ( ) , E = B . end ( ) ; I != E ; ++ I ) { const MachineInstr * MI = & * I ; for ( unsigned i = <NUM_LIT> , n = MI -> getNumOperands ( ) ; i < n ; ++ i ) { const MachineOperand & MO = MI -> getOperand ( i ) ;

if ( MO . isReg ( ) && MO . isDef ( ) ) {


<s> for ( unsigned i = <NUM_LIT> , n = MI -> getNumOperands ( ) ; i < n ; ++ i ) { const MachineOperand & MO = MI -> getOperand ( i ) ; if ( MO . isReg ( ) && MO . isDef ( ) ) { Register R = MO . getReg ( ) ; assert ( MO . getSubReg ( ) == <NUM_LIT> && <STR_LIT> ) ; if ( R . isVirtual ( ) ) RO . insert ( std :: make_pair ( R , Index ++ ) ) ; }


<s> void <ISA_LIT>GenInsert :: getInstrDefs ( const MachineInstr * MI , RegisterSet & Defs ) const { for ( unsigned i = <NUM_LIT> , n = MI -> getNumOperands ( ) ; i < n ; ++ i ) { const MachineOperand & MO = MI -> getOperand ( i ) ; if ( ! MO . isReg ( ) || ! MO . isDef ( ) ) continue ; Register R = MO . getReg ( ) ; if ( ! R . isVirtual ( ) ) continue ;


<s> const MachineOperand & MO = MI -> getOperand ( i ) ; if ( ! MO . isReg ( ) || ! MO . isUse ( ) ) continue ;


<s> std :: vector < MachineInstr * > Instrs ; for ( auto I = B -> rbegin ( ) , E = B -> rend ( ) ; I != E ; ++ I ) Instrs . push_back ( & * I ) ; for ( auto I = Instrs . begin ( ) , E = Instrs . end ( ) ; I != E ; ++ I ) { MachineInstr * MI = * I ; unsigned Opc = MI -> getOpcode ( ) ; if ( Opc == TargetOpcode :: LIFETIME_START || Opc == TargetOpcode :: LIFETIME_END ) continue ; bool Store = false ; if ( MI -> isInlineAsm ( ) || ! MI -> isSafeToMove ( nullptr , Store ) ) continue ; bool AllDead = true ; SmallVector < unsigned , <NUM_LIT> > Regs ; for ( const MachineOperand & MO : MI -> operands ( ) ) { if ( ! MO . isReg ( ) || ! MO . isDef ( ) ) continue ; Register R = MO . getReg ( ) ; if ( ! R . isVirtual ( ) || ! MRI -> use_nodbg_empty ( R ) ) { AllDead = false ; break ; } Regs . push_back ( R ) ; }


<s> bool Changed = false ; for ( auto * DTN : children < MachineDomTreeNode * > ( N ) ) Changed |= removeDeadCode ( DTN ) ; MachineBasicBlock * B = N -> getBlock ( ) ; std :: vector < MachineInstr * > Instrs ; for ( auto I = B -> rbegin ( ) , E = B -> rend ( ) ; I != E ; ++ I ) Instrs . push_back ( & * I ) ; for ( auto I = Instrs . begin ( ) , E = Instrs . end ( ) ; I != E ; ++ I ) { MachineInstr * MI = * I ; unsigned Opc = MI -> getOpcode ( ) ; if ( Opc == TargetOpcode :: LIFETIME_START || Opc == TargetOpcode :: LIFETIME_END ) continue ; bool Store = false ; if ( MI -> isInlineAsm ( ) || ! MI -> isSafeToMove ( nullptr , Store ) ) continue ; bool AllDead = true ; SmallVector < unsigned , <NUM_LIT> > Regs ; for ( const MachineOperand & MO : MI -> operands ( ) ) { if ( ! MO . isReg ( ) || ! MO . isDef ( ) ) continue ; Register R = MO . getReg ( ) ; if ( ! R . isVirtual ( ) || ! MRI -> use_nodbg_empty ( R ) ) { AllDead = false ; break ; }


<s> CellMapShadow MS ( BTLoc ) ; CMS = & MS ; buildOrderingMF ( BaseOrd ) ; buildOrderingBT ( BaseOrd , CellOrd ) ; if ( isDebug ( ) ) { dbgs ( ) << <STR_LIT> ; for ( RegisterOrdering :: iterator I = CellOrd . begin ( ) , E = CellOrd . end ( ) ; I != E ; ++ I ) { unsigned VR = I -> first , Pos = I -> second ; dbgs ( ) << PrintReg ( VR , HRI ) << <STR_LIT> << Pos << <STR_LIT> ; } } MachineBasicBlock * RootB = MDT -> getRoot ( ) ; OrderedRegisterList AvailR ( CellOrd ) ; { NamedRegionTimer _T ( <STR_LIT> , <STR_LIT> , TimingDetail ) ; collectInBlock ( RootB , AvailR ) ; computeRemovableRegisters ( ) ; } if ( isDebug ( ) ) { dbgs ( ) << <STR_LIT> ; dump_map ( ) ; } if ( IFMap . empty ( ) ) return false ; { NamedRegionTimer _T ( <STR_LIT> , <STR_LIT> , TimingDetail ) ; pruneCandidates ( ) ; } if ( isDebug ( ) ) { dbgs ( ) << <STR_LIT> ; dump_map ( ) ; } if ( IFMap . empty ( ) ) return false ; { NamedRegionTimer _T ( <STR_LIT> , <STR_LIT> , TimingDetail ) ; selectCandidates ( ) ; } if ( isDebug ( ) ) { dbgs ( ) << <STR_LIT> ; dump_map ( ) ; } if ( VRegIndexCutoff . getPosition ( ) ) { unsigned Cutoff = VRegIndexCutoff ; typedef SmallVector < IFMapType :: iterator , <NUM_LIT> > IterListType ; IterListType Out ; for ( IFMapType :: iterator I = IFMap . begin ( ) , E = IFMap . end ( ) ; I != E ; ++ I ) { unsigned Idx = TargetRegisterInfo :: virtReg2Index ( I -> first ) ; if ( Idx >= Cutoff ) Out . push_back ( I ) ; } for ( unsigned i = <NUM_LIT> , n = Out . size ( ) ; i < n ; ++ i ) IFMap . erase ( Out [ i ] ) ; } { NamedRegionTimer _T ( <STR_LIT> , <STR_LIT> , TimingDetail ) ; Changed = generateInserts ( ) ; }


<s> HRI = ST . getRegisterInfo ( ) ; MFN = & MF ; MRI = & MF . getRegInfo ( ) ; MDT = & getAnalysis < MachineDominatorTree > ( ) ; Changed |= removeDeadCode ( MDT -> getRootNode ( ) ) ; const <ISA_LIT>Evaluator HE ( * HRI , * MRI , * HII , MF ) ; BitTracker BTLoc ( HE , MF ) ; BTLoc . trace ( isDebug ( ) ) ; BTLoc . run ( ) ; CellMapShadow MS ( BTLoc ) ; CMS = & MS ; buildOrderingMF ( BaseOrd ) ; buildOrderingBT ( BaseOrd , CellOrd ) ; if ( isDebug ( ) ) { dbgs ( ) << <STR_LIT> ; for ( RegisterOrdering :: iterator I = CellOrd . begin ( ) , E = CellOrd . end ( ) ; I != E ; ++ I ) { unsigned VR = I -> first , Pos = I -> second ; dbgs ( ) << PrintReg ( VR , HRI ) << <STR_LIT> << Pos << <STR_LIT> ; } } MachineBasicBlock * RootB = MDT -> getRoot ( ) ; OrderedRegisterList AvailR ( CellOrd ) ; { NamedRegionTimer _T ( <STR_LIT> , <STR_LIT> , TimingDetail ) ; collectInBlock ( RootB , AvailR ) ; computeRemovableRegisters ( ) ; } if ( isDebug ( ) ) { dbgs ( ) << <STR_LIT> ; dump_map ( ) ; } if ( IFMap . empty ( ) ) return false ; { NamedRegionTimer _T ( <STR_LIT> , <STR_LIT> , TimingDetail ) ; pruneCandidates ( ) ;


<s> assert ( F != IFMap . end ( ) ) ; IFListType & LL = F -> second ; MachineInstr * DefVR = MRI -> getVRegDef ( VR ) ; bool DefEx = HII -> isConstExtended ( * DefVR ) ; bool HasNE = false ; for ( unsigned i = <NUM_LIT> , n = LL . size ( ) ; i < n ; ++ i ) { if ( LL [ i ] . second . empty ( ) ) continue ; HasNE = true ; break ; } if ( ! DefEx || HasNE ) { auto IsEmpty = [ ] ( const IFRecordWithRegSet & IR ) -> bool { return IR . second . empty ( ) ; } ; auto End = remove_if ( LL , IsEmpty ) ; if ( End != LL . end ( ) ) LL . erase ( End , LL . end ( ) ) ; } else { IFRecord MaxIF = LL [ <NUM_LIT> ] . first ; for ( unsigned i = <NUM_LIT> , n = LL . size ( ) ; i < n ; ++ i ) { const IFRecord & IF = LL [ i ] . first ; unsigned M0 = BaseOrd [ MaxIF . SrcR ] , M1 = BaseOrd [ MaxIF . InsR ] ; unsigned R0 = BaseOrd [ IF . SrcR ] , R1 = BaseOrd [ IF . InsR ] ; if ( M0 > R0 ) continue ; if ( M0 == R0 ) {


<s> if ( LL [ i ] . second . empty ( ) ) continue ; HasNE = true ; break ; } if ( ! DefEx || HasNE ) { auto IsEmpty = [ ] ( const IFRecordWithRegSet & IR ) -> bool { return IR . second . empty ( ) ; } ; auto End = remove_if ( LL , IsEmpty ) ; if ( End != LL . end ( ) ) LL . erase ( End , LL . end ( ) ) ; } else { IFRecord MaxIF = LL [ <NUM_LIT> ] . first ; for ( unsigned i = <NUM_LIT> , n = LL . size ( ) ; i < n ; ++ i ) { const IFRecord & IF = LL [ i ] . first ; unsigned M0 = BaseOrd [ MaxIF . SrcR ] , M1 = BaseOrd [ MaxIF . InsR ] ; unsigned R0 = BaseOrd [ IF . SrcR ] , R1 = BaseOrd [ IF . InsR ] ; if ( M0 > R0 ) continue ; if ( M0 == R0 ) { if ( M1 > R1 ) continue ; if ( M1 == R1 ) { if ( MaxIF . Wdh > IF . Wdh ) continue ; if ( MaxIF . Wdh == IF . Wdh && MaxIF . Off >= IF . Off ) continue ; } } MaxIF = IF ; } LL . clear ( ) ; LL . push_back ( std :: make_pair ( MaxIF , RegisterSet ( ) ) ) ; } for ( unsigned i = <NUM_LIT> , n = LL . size ( ) ; i < n ; ) { const RegisterSet & RMi = LL [ i ] . second ; unsigned j = <NUM_LIT> ; while ( j < n ) { if ( j != i && LL [ j ] . second . includes ( RMi ) ) break ; j ++ ; } if ( j == n ) { i ++ ;


<s> IFMapType :: iterator F = IFMap . find ( VR ) ; assert ( F != IFMap . end ( ) ) ; IFListType & LL = F -> second ; auto IsCopy = [ ] ( const IFRecordWithRegSet & IR ) -> bool { return IR . first . Wdh == <NUM_LIT> && ( IR . first . Off == <NUM_LIT> || IR . first . Off == <NUM_LIT> ) ; } ; auto End = remove_if ( LL , IsCopy ) ; if ( End != LL . end ( ) ) LL . erase ( End , LL . end ( ) ) ;


<s> return IR . first . Wdh == <NUM_LIT> && ( IR . first . Off == <NUM_LIT> || IR . first . Off == <NUM_LIT> ) ; } ; auto End = remove_if ( LL , IsCopy ) ;


<s> llvm :: sort ( VRs . begin ( ) , VRs . end ( ) , LexCmp ) ; for ( unsigned i = <NUM_LIT> , n = VRs . size ( ) ; i < n ; ++ i ) RO . insert ( std :: make_pair ( VRs [ i ] , i ) ) ;


<s> SortableVectorType VRs ; for ( RegisterOrdering :: iterator I = RB . begin ( ) , E = RB . end ( ) ; I != E ; ++ I ) VRs . push_back ( I -> first ) ;

llvm :: sort ( VRs . begin ( ) , VRs . end ( ) , LexCmp ) ;


<s> getInstrDefs ( MI , InsDefs ) ; bool Skip = MI -> isCopy ( ) || MI -> isRegSequence ( ) ; if ( ! Skip ) { for ( unsigned VR = InsDefs . find_first ( ) ; VR ; VR = InsDefs . find_next ( VR ) ) { if ( ! DoConst && isConstant ( VR ) ) continue ; if ( findSelfReference ( VR ) || isSmallConstant ( VR ) ) continue ; findRecordInsertForms ( VR , AVs ) ; } } for ( unsigned VR = InsDefs . find_first ( ) ; VR ; VR = InsDefs . find_next ( VR ) ) AVs . insert ( VR ) ; BlockDefs . insert ( InsDefs ) ; }

for ( auto * DTN : children < MachineDomTreeNode * > ( MDT -> getNode ( B ) ) ) {


<s> void <ISA_LIT>GenInsert :: collectInBlock ( MachineBasicBlock * B , OrderedRegisterList & AVs ) { if ( isDebug ( ) ) dbgs ( ) << <STR_LIT> << printMBBReference ( * B ) << <STR_LIT> ; if ( ! CMS -> BT . reached ( B ) ) return ; bool DoConst = OptConst ; RegisterSet BlockDefs , InsDefs ; for ( MachineBasicBlock :: iterator I = B -> begin ( ) , E = B -> end ( ) ; I != E ; ++ I ) { MachineInstr * MI = & * I ; InsDefs . clear ( ) ; getInstrDefs ( MI , InsDefs ) ; bool Skip = MI -> isCopy ( ) || MI -> isRegSequence ( ) ; if ( ! Skip ) { for ( unsigned VR = InsDefs . find_first ( ) ; VR ; VR = InsDefs . find_next ( VR ) ) { if ( ! DoConst && isConstant ( VR ) ) continue ; if ( findSelfReference ( VR ) || isSmallConstant ( VR ) ) continue ; findRecordInsertForms ( VR , AVs ) ;


<s> } else { IFRecord MaxIF = LL [ <NUM_LIT> ] . first ; for ( unsigned i = <NUM_LIT> , n = LL . size ( ) ; i < n ; ++ i ) { const IFRecord & IF = LL [ i ] . first ; unsigned M0 = BaseOrd [ MaxIF . SrcR ] , M1 = BaseOrd [ MaxIF . InsR ] ; unsigned R0 = BaseOrd [ IF . SrcR ] , R1 = BaseOrd [ IF . InsR ] ; if ( M0 > R0 ) continue ; if ( M0 == R0 ) { if ( M1 > R1 ) continue ; if ( M1 == R1 ) { if ( MaxIF . Wdh > IF . Wdh ) continue ; if ( MaxIF . Wdh == IF . Wdh && MaxIF . Off >= IF . Off ) continue ; } } MaxIF = IF ; } LL . clear ( ) ; LL . push_back ( std :: make_pair ( MaxIF , RegisterSet ( ) ) ) ; } for ( unsigned i = <NUM_LIT> , n = LL . size ( ) ; i < n ; ) { const RegisterSet & RMi = LL [ i ] . second ;


<s> for ( auto I = GTN :: child_begin ( N ) , E = GTN :: child_end ( N ) ; I != E ; ++ I ) Changed |= removeDeadCode ( * I ) ; MachineBasicBlock * B = N -> getBlock ( ) ; std :: vector < MachineInstr * > Instrs ; for ( auto I = B -> rbegin ( ) , E = B -> rend ( ) ; I != E ; ++ I ) Instrs . push_back ( & * I ) ; for ( auto I = Instrs . begin ( ) , E = Instrs . end ( ) ; I != E ; ++ I ) { MachineInstr * MI = * I ; unsigned Opc = MI -> getOpcode ( ) ; if ( Opc == TargetOpcode :: LIFETIME_START || Opc == TargetOpcode :: LIFETIME_END ) continue ; bool Store = false ; if ( MI -> isInlineAsm ( ) || ! MI -> isSafeToMove ( nullptr , Store ) ) continue ; bool AllDead = true ; SmallVector < unsigned , <NUM_LIT> > Regs ; for ( ConstMIOperands Op ( * MI ) ; Op . isValid ( ) ; ++ Op ) { if ( ! Op -> isReg ( ) || ! Op -> isDef ( ) ) continue ; unsigned R = Op -> getReg ( ) ; if ( ! TargetRegisterInfo :: isVirtualRegister ( R ) || ! MRI -> use_nodbg_empty ( R ) ) { AllDead = false ; break ; } Regs . push_back ( R ) ; } if ( ! AllDead ) continue ; B -> erase ( MI ) ; for ( unsigned I = <NUM_LIT> , N = Regs . size ( ) ; I != N ; ++ I ) MRI -> markUsesInDebugValueAsUndef ( Regs [ I ] ) ;


<s> for ( auto I = B -> rbegin ( ) , E = B -> rend ( ) ; I != E ; ++ I ) Instrs . push_back ( & * I ) ; for ( auto I = Instrs . begin ( ) , E = Instrs . end ( ) ; I != E ; ++ I ) { MachineInstr * MI = * I ; unsigned Opc = MI -> getOpcode ( ) ; if ( Opc == TargetOpcode :: LIFETIME_START || Opc == TargetOpcode :: LIFETIME_END ) continue ; bool Store = false ; if ( MI -> isInlineAsm ( ) || ! MI -> isSafeToMove ( nullptr , Store ) ) continue ;


<s> bool Timing = OptTiming , TimingDetail = Timing && OptTimingDetail ; bool Changed = false ; TimerGroup __G ( <STR_LIT> ) ; NamedRegionTimer __T ( <STR_LIT> , Timing && ! TimingDetail ) ; assert ( ! OptSelectAll0 || ! OptSelectHas0 ) ; IFMap . clear ( ) ; BaseOrd . clear ( ) ; CellOrd . clear ( ) ; const auto & ST = MF . getSubtarget < <ISA_LIT>Subtarget > ( ) ; HII = ST . getInstrInfo ( ) ; HRI = ST . getRegisterInfo ( ) ; MFN = & MF ; MRI = & MF . getRegInfo ( ) ; MDT = & getAnalysis < MachineDominatorTree > ( ) ; Changed = removeDeadCode ( MDT -> getRootNode ( ) ) ; const <ISA_LIT>Evaluator HE ( * HRI , * MRI , * HII , MF ) ; BitTracker BTLoc ( HE , MF ) ; BTLoc . trace ( isDebug ( ) ) ; BTLoc . run ( ) ; CellMapShadow MS ( BTLoc ) ; CMS = & MS ; buildOrderingMF ( BaseOrd ) ;


<s> for ( MachineBasicBlock :: iterator I = B . begin ( ) , E = B . end ( ) ; I != E ; ++ I ) { MachineInstr * MI = & * I ; I2X . insert ( std :: make_pair ( MI , Index ) ) ; Defs . reset ( ) ; Uses . reset ( ) ; getDefsUses ( MI , Defs , Uses ) ; DUM . insert ( std :: make_pair ( Index , DefUseInfo ( Defs , Uses ) ) ) ;


<s> I2X . insert ( std :: make_pair ( MI , Index ) ) ; Defs . reset ( ) ; Uses . reset ( ) ; getDefsUses ( MI , Defs , Uses ) ;

DUM . insert ( std :: make_pair ( Index , DefUseInfo ( Defs , Uses ) ) ) ;


<s> CondsetInfo ( ) : PredR ( <NUM_LIT> ) , TrueX ( UINT_MAX ) , FalseX ( UINT_MAX ) {


<s> DefUseInfo ( const BitVector & D , const BitVector & U ) : Defs ( D ) , Uses ( U ) {


<s> if ( isRegPair ( Reg ) ) getSubRegs ( Reg , Set ) ; else Set [ Reg ] = true ;


<s> break ; } if ( CanDown && DU . Defs [ SR1 ] ) CanDown = false ; if ( CanUp && DU . Defs [ SR2 ] ) CanUp = false ; } if ( Failure || ( ! CanUp && ! CanDown ) ) continue ; MachineOperand * SrcT = ( MinX == CI . TrueX ) ? Src1 : Src2 ; MachineOperand * SrcF = ( MinX == CI . FalseX ) ? Src1 : Src2 ; MachineBasicBlock :: iterator At = CanDown ? Def2 : Def1 ; ML . push_back ( MuxInfo ( At , DR , PR , SrcT , SrcF , Def1 , Def2 ) ) ; } for ( unsigned I = <NUM_LIT> , N = ML . size ( ) ; I < N ; ++ I ) { MuxInfo & MX = ML [ I ] ; MachineBasicBlock & B = * MX . At -> getParent ( ) ; DebugLoc DL = MX . At -> getDebugLoc ( ) ; unsigned MxOpc = getMuxOpcode ( * MX . SrcT , * MX . SrcF ) ; if ( ! MxOpc ) continue ; BuildMI ( B , MX . At , DL , HII -> get ( MxOpc ) , MX . DefR ) . addReg ( MX . PredR ) . addOperand ( * MX . SrcT ) . addOperand ( * MX . SrcF ) ; B . erase ( MX . Def1 ) ; B . erase ( MX . Def2 ) ; Changed = true ; } return Changed ;


<s> for ( unsigned X = MinX + <NUM_LIT> ; X < MaxX ; X ++ ) { const DefUseInfo & DU = DUM . lookup ( X ) ; if ( DU . Defs [ PR ] || DU . Defs [ DR ] || DU . Uses [ DR ] ) { Failure = true ; break ; } if ( CanDown && DU . Defs [ SR1 ] ) CanDown = false ; if ( CanUp && DU . Defs [ SR2 ] ) CanUp = false ; } if ( Failure || ( ! CanUp && ! CanDown ) ) continue ; MachineOperand * SrcT = ( MinX == CI . TrueX ) ? Src1 : Src2 ; MachineOperand * SrcF = ( MinX == CI . FalseX ) ? Src1 : Src2 ; MachineBasicBlock :: iterator At = CanDown ? Def2 : Def1 ; ML . push_back ( MuxInfo ( At , DR , PR , SrcT , SrcF , Def1 , Def2 ) ) ; } for ( unsigned I = <NUM_LIT> , N = ML . size ( ) ; I < N ; ++ I ) { MuxInfo & MX = ML [ I ] ; MachineBasicBlock & B = * MX . At -> getParent ( ) ; DebugLoc DL = MX . At -> getDebugLoc ( ) ; unsigned MxOpc = getMuxOpcode ( * MX . SrcT , * MX . SrcF ) ; if ( ! MxOpc ) continue ; BuildMI ( B , MX . At , DL , HII -> get ( MxOpc ) , MX . DefR ) . addReg ( MX . PredR ) . addOperand ( * MX . SrcT ) . addOperand ( * MX . SrcF ) ; B . erase ( MX . Def1 ) ; B . erase ( MX . Def2 ) ;


<s> if ( ! Mo -> isReg ( ) || Mo -> isImplicit ( ) ) continue ; unsigned R = Mo -> getReg ( ) ; BitVector & Set = Mo -> isDef ( ) ? Defs : Uses ; expandReg ( R , Set ) ; }


<s> unsigned Opc = MI -> getOpcode ( ) ; const MCInstrDesc & D = HII -> get ( Opc ) ; if ( const MCPhysReg * R = D . ImplicitDefs ) while ( * R ) expandReg ( * R ++ , Defs ) ; if ( const MCPhysReg * R = D . ImplicitUses ) while ( * R ) expandReg ( * R ++ , Uses ) ; for ( ConstMIOperands Mo ( MI ) ; Mo . isValid ( ) ; ++ Mo ) { if ( ! Mo -> isReg ( ) || Mo -> isImplicit ( ) ) continue ; unsigned R = Mo -> getReg ( ) ;

BitVector & Set = Mo -> isDef ( ) ? Defs : Uses ;


<s> if ( IsReg1 ) return IsReg2 ? <STR_LIT> : <STR_LIT> ; if ( IsReg2 ) return <STR_LIT> ; if ( Src2 . isImm ( ) && isInt < <NUM_LIT> > ( Src2 . getImm ( ) ) ) return <STR_LIT> ;


<s> if ( Src2 . isImm ( ) && isInt < <NUM_LIT> > ( Src2 . getImm ( ) ) ) return <STR_LIT> ; return <NUM_LIT> ;


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


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


<s> return <STR_LIT> . contains ( Reg ) ;


<s> bool isRegPair ( unsigned Reg ) const { return <STR_LIT> . contains ( Reg ) ;


<s> MuxInfo ( MachineBasicBlock :: iterator It , unsigned DR , unsigned PR , MachineOperand * TOp , MachineOperand * FOp , MachineInstr * D1 , MachineInstr * D2 ) : At ( It ) , DefR ( DR ) , PredR ( PR ) , SrcT ( TOp ) , SrcF ( FOp ) , Def1 ( D1 ) , Def2 ( D2 ) {


<s> bool <ISA_LIT>GenMux :: runOnMachineFunction ( MachineFunction & MF ) { HII = MF . getSubtarget < <ISA_LIT>Subtarget > ( ) . getInstrInfo ( ) ;

HRI = MF . getSubtarget < <ISA_LIT>Subtarget > ( ) . getRegisterInfo ( ) ;


<s> void <ISA_LIT>GenMux :: getDefsUses ( const MachineInstr * MI , BitVector & Defs , BitVector & Uses ) const { unsigned Opc = MI -> getOpcode ( ) ; const MCInstrDesc & D = HII -> get ( Opc ) ; if ( const MCPhysReg * R = D . ImplicitDefs ) while ( * R ) expandReg ( * R ++ , Defs ) ; if ( const MCPhysReg * R = D . ImplicitUses ) while ( * R ) expandReg ( * R ++ , Uses ) ; for ( const MachineOperand & MO : MI -> operands ( ) ) { if ( ! MO . isReg ( ) || MO . isImplicit ( ) ) continue ; Register R = MO . getReg ( ) ; BitVector & Set = MO . isDef ( ) ? Defs : Uses ; expandReg ( R , Set ) ;


<s> MachineOperand & PredOp = MI -> getOperand ( <NUM_LIT> ) ; if ( PredOp . isUndef ( ) ) continue ; unsigned PR = PredOp . getReg ( ) ; unsigned Idx = I2X . lookup ( MI ) ; CondsetMap :: iterator F = CM . find ( DR ) ; bool IfTrue = HII -> isPredicatedTrue ( Opc ) ; if ( F != CM . end ( ) && F -> second . PredR != PR ) { CM . erase ( F ) ; F = CM . end ( ) ; } if ( F == CM . end ( ) ) { auto It = CM . insert ( std :: make_pair ( DR , CondsetInfo ( ) ) ) ; F = It . first ; F -> second . PredR = PR ; } CondsetInfo & CI = F -> second ; if ( IfTrue ) CI . TrueX = Idx ; else CI . FalseX = Idx ; if ( CI . TrueX == std :: numeric_limits < unsigned > :: max ( ) || CI . FalseX == std :: numeric_limits < unsigned > :: max ( ) ) continue ; unsigned MinX = std :: min ( CI . TrueX , CI . FalseX ) ; unsigned MaxX = std :: max ( CI . TrueX , CI . FalseX ) ; unsigned SearchX = ( MaxX > <NUM_LIT> ) ? MaxX - <NUM_LIT> : <NUM_LIT> ; bool NearDef = false ; for ( unsigned X = SearchX ; X < MaxX ; ++ X ) { const DefUseInfo & DU = DUM . lookup ( X ) ; if ( ! DU . Defs [ PR ] ) continue ; NearDef = true ; break ; } if ( NearDef ) continue ;

MachineBasicBlock :: iterator It1 = B . begin ( ) , It2 = B . begin ( ) ;


<s> unsigned SR1 = Src1 -> isReg ( ) ? Src1 -> getReg ( ) : <NUM_LIT> ; unsigned SR2 = Src2 -> isReg ( ) ? Src2 -> getReg ( ) : <NUM_LIT> ; bool Failure = false , CanUp = true , CanDown = true ; for ( unsigned X = MinX + <NUM_LIT> ; X < MaxX ; X ++ ) { const DefUseInfo & DU = DUM . lookup ( X ) ; if ( DU . Defs [ PR ] || DU . Defs [ DR ] || DU . Uses [ DR ] ) { Failure = true ; break ; } if ( CanDown && DU . Defs [ SR1 ] ) CanDown = false ; if ( CanUp && DU . Defs [ SR2 ] ) CanUp = false ; } if ( Failure || ( ! CanUp && ! CanDown ) ) continue ; MachineOperand * SrcT = ( MinX == CI . TrueX ) ? Src1 : Src2 ; MachineOperand * SrcF = ( MinX == CI . FalseX ) ? Src1 : Src2 ; MachineBasicBlock :: iterator At = CanDown ? Def2 : Def1 ; ML . push_back ( MuxInfo ( At , DR , PR , SrcT , SrcF , Def1 , Def2 ) ) ; } for ( MuxInfo & MX : ML ) { unsigned MxOpc = getMuxOpcode ( * MX . SrcT , * MX . SrcF ) ; if ( ! MxOpc ) continue ; MachineBasicBlock & B = * MX . At -> getParent ( ) ; const DebugLoc & DL = B . findDebugLoc ( MX . At ) ; auto NewMux = BuildMI ( B , MX . At , DL , HII -> get ( MxOpc ) , MX . DefR ) . addReg ( MX . PredR ) . add ( * MX . SrcT ) . add ( * MX . SrcF ) ; NewMux -> clearKillInfo ( ) ; B . erase ( MX . Def1 ) ; B . erase ( MX . Def2 ) ; Changed = true ; } LivePhysRegs LPR ( * HRI ) ; LPR . addLiveOuts ( B ) ; auto IsLive = [ & LPR , this ] ( unsigned Reg ) -> bool {

for ( MCSubRegIterator S ( Reg , HRI , true ) ; S . isValid ( ) ; ++ S ) if ( LPR . contains ( * S ) ) return true ;


<s> HII = MF . getSubtarget < <ISA_LIT>Subtarget > ( ) . getInstrInfo ( ) ;


<s> if ( const uint16_t * R = D . ImplicitDefs ) while ( * R ) expandReg ( * R ++ , Defs ) ; if ( const uint16_t * R = D . ImplicitUses ) while ( * R ) expandReg ( * R ++ , Uses ) ; for ( ConstMIOperands Mo ( MI ) ; Mo . isValid ( ) ; ++ Mo ) { if ( ! Mo -> isReg ( ) || Mo -> isImplicit ( ) ) continue ; unsigned R = Mo -> getReg ( ) ;


<s> unsigned Opc = MI -> getOpcode ( ) ; const MCInstrDesc & D = HII -> get ( Opc ) ; if ( const MCPhysReg * R = D . ImplicitDefs ) while ( * R ) expandReg ( * R ++ , Defs ) ; if ( const MCPhysReg * R = D . ImplicitUses ) while ( * R ) expandReg ( * R ++ , Uses ) ; for ( ConstMIOperands Mo ( * MI ) ; Mo . isValid ( ) ; ++ Mo ) { if ( ! Mo -> isReg ( ) || Mo -> isImplicit ( ) ) continue ;


<s> if ( const MCPhysReg * R = D . ImplicitUses ) while ( * R ) expandReg ( * R ++ , Uses ) ; for ( ConstMIOperands Mo ( * MI ) ; Mo . isValid ( ) ; ++ Mo ) {

if ( ! Mo -> isReg ( ) || Mo -> isImplicit ( ) ) continue ;


<s> F -> second . PredR = PR ; } CondsetInfo & CI = F -> second ; if ( IfTrue ) CI . TrueX = Idx ; else CI . FalseX = Idx ; if ( CI . TrueX == std :: numeric_limits < unsigned > :: max ( ) || CI . FalseX == std :: numeric_limits < unsigned > :: max ( ) ) continue ; unsigned MinX = std :: min ( CI . TrueX , CI . FalseX ) ; unsigned MaxX = std :: max ( CI . TrueX , CI . FalseX ) ; unsigned SearchX = ( MaxX > <NUM_LIT> ) ? MaxX - <NUM_LIT> : <NUM_LIT> ; bool NearDef = false ; for ( unsigned X = SearchX ; X < MaxX ; ++ X ) { const DefUseInfo & DU = DUM . lookup ( X ) ; if ( ! DU . Defs [ PR ] ) continue ; NearDef = true ; break ; } if ( NearDef ) continue ; MachineBasicBlock :: iterator It1 = B . begin ( ) , It2 = B . begin ( ) ; std :: advance ( It1 , MinX ) ; std :: advance ( It2 , MaxX ) ; MachineInstr & Def1 = * It1 , & Def2 = * It2 ; MachineOperand * Src1 = & Def1 . getOperand ( <NUM_LIT> ) , * Src2 = & Def2 . getOperand ( <NUM_LIT> ) ; unsigned SR1 = Src1 -> isReg ( ) ? Src1 -> getReg ( ) : <NUM_LIT> ; unsigned SR2 = Src2 -> isReg ( ) ? Src2 -> getReg ( ) : <NUM_LIT> ; bool Failure = false , CanUp = true , CanDown = true ; for ( unsigned X = MinX + <NUM_LIT> ; X < MaxX ; X ++ ) { const DefUseInfo & DU = DUM . lookup ( X ) ; if ( DU . Defs [ PR ] || DU . Defs [ DR ] || DU . Uses [ DR ] ) { Failure = true ; break ; } if ( CanDown && DU . Defs [ SR1 ] ) CanDown = false ; if ( CanUp && DU . Defs [ SR2 ] ) CanUp = false ; } if ( Failure || ( ! CanUp && ! CanDown ) ) continue ; MachineOperand * SrcT = ( MinX == CI . TrueX ) ? Src1 : Src2 ; MachineOperand * SrcF = ( MinX == CI . FalseX ) ? Src1 : Src2 ; MachineBasicBlock :: iterator At = CanDown ? Def2 : Def1 ;

ML . push_back ( MuxInfo ( At , DR , PR , SrcT , SrcF , Def1 , Def2 ) ) ;


<s> } if ( CanDown && DU . Defs [ SR1 ] ) CanDown = false ; if ( CanUp && DU . Defs [ SR2 ] ) CanUp = false ; } if ( Failure || ( ! CanUp && ! CanDown ) ) continue ; MachineOperand * SrcT = ( MinX == CI . TrueX ) ? Src1 : Src2 ; MachineOperand * SrcF = ( MinX == CI . FalseX ) ? Src1 : Src2 ; MachineBasicBlock :: iterator At = CanDown ? Def2 : Def1 ; ML . push_back ( MuxInfo ( At , DR , PR , SrcT , SrcF , Def1 , Def2 ) ) ; } for ( unsigned I = <NUM_LIT> , N = ML . size ( ) ; I < N ; ++ I ) { MuxInfo & MX = ML [ I ] ; MachineBasicBlock & B = * MX . At -> getParent ( ) ; DebugLoc DL = MX . At -> getDebugLoc ( ) ; unsigned MxOpc = getMuxOpcode ( * MX . SrcT , * MX . SrcF ) ; if ( ! MxOpc ) continue ; BuildMI ( B , MX . At , DL , HII -> get ( MxOpc ) , MX . DefR ) . addReg ( MX . PredR ) . addOperand ( * MX . SrcT ) . addOperand ( * MX . SrcF ) ; B . erase ( MX . Def1 ) ; B . erase ( MX . Def2 ) ; Changed = true ; }


<s> } if ( Failure || ( ! CanUp && ! CanDown ) ) continue ; MachineOperand * SrcT = ( MinX == CI . TrueX ) ? Src1 : Src2 ; MachineOperand * SrcF = ( MinX == CI . FalseX ) ? Src1 : Src2 ; MachineBasicBlock :: iterator At = CanDown ? Def2 : Def1 ; ML . push_back ( MuxInfo ( At , DR , PR , SrcT , SrcF , Def1 , Def2 ) ) ; } for ( MuxInfo & MX : ML ) { unsigned MxOpc = getMuxOpcode ( * MX . SrcT , * MX . SrcF ) ; if ( ! MxOpc ) continue ; MachineBasicBlock & B = * MX . At -> getParent ( ) ; const DebugLoc & DL = B . findDebugLoc ( MX . At ) ; auto NewMux = BuildMI ( B , MX . At , DL , HII -> get ( MxOpc ) , MX . DefR ) . addReg ( MX . PredR ) . add ( * MX . SrcT ) . add ( * MX . SrcF ) ; NewMux -> clearKillInfo ( ) ; B . erase ( MX . Def1 ) ; B . erase ( MX . Def2 ) ; Changed = true ; } LivePhysRegs LPR ( * HRI ) ; LPR . addLiveOuts ( B ) ; auto IsLive = [ & LPR , this ] ( unsigned Reg ) -> bool { for ( MCSubRegIterator S ( Reg , HRI , true ) ; S . isValid ( ) ; ++ S ) if ( LPR . contains ( * S ) ) return true ; return false ; } ; for ( auto I = B . rbegin ( ) , E = B . rend ( ) ; I != E ; ++ I ) { if ( I -> isDebugValue ( ) ) continue ; for ( MachineOperand & Op : I -> operands ( ) ) { if ( ! Op . isReg ( ) || ! Op . isUse ( ) ) continue ;

assert ( Op . getSubReg ( ) == <NUM_LIT> && <STR_LIT> ) ;


<s> unsigned MaxX = std :: max ( CI . TrueX , CI . FalseX ) ; unsigned SearchX = ( MaxX >= MinPredDist ) ? MaxX - MinPredDist : <NUM_LIT> ; bool NearDef = false ; for ( unsigned X = SearchX ; X < MaxX ; ++ X ) { const DefUseInfo & DU = DUM . lookup ( X ) ; if ( ! DU . Defs [ PR ] ) continue ; NearDef = true ; break ; } if ( NearDef ) continue ; MachineBasicBlock :: iterator It1 = B . begin ( ) , It2 = B . begin ( ) ; std :: advance ( It1 , MinX ) ; std :: advance ( It2 , MaxX ) ; MachineInstr & Def1 = * It1 , & Def2 = * It2 ; MachineOperand * Src1 = & Def1 . getOperand ( <NUM_LIT> ) , * Src2 = & Def2 . getOperand ( <NUM_LIT> ) ; Register SR1 = Src1 -> isReg ( ) ? Src1 -> getReg ( ) : Register ( ) ; Register SR2 = Src2 -> isReg ( ) ? Src2 -> getReg ( ) : Register ( ) ; bool Failure = false , CanUp = true , CanDown = true ; for ( unsigned X = MinX + <NUM_LIT> ; X < MaxX ; X ++ ) { const DefUseInfo & DU = DUM . lookup ( X ) ; if ( DU . Defs [ PR ] || DU . Defs [ DR ] || DU . Uses [ DR ] ) { Failure = true ; break ; } if ( CanDown && DU . Defs [ SR1 ] ) CanDown = false ; if ( CanUp && DU . Defs [ SR2 ] ) CanUp = false ; } if ( Failure || ( ! CanUp && ! CanDown ) ) continue ;

MachineOperand * SrcT = ( MinX == CI . TrueX ) ? Src1 : Src2 ;


<s> if ( CanDown && DU . Defs [ SR1 ] ) CanDown = false ; if ( CanUp && DU . Defs [ SR2 ] ) CanUp = false ; } if ( Failure || ( ! CanUp && ! CanDown ) ) continue ; MachineOperand * SrcT = ( MinX == CI . TrueX ) ? Src1 : Src2 ; MachineOperand * SrcF = ( MinX == CI . FalseX ) ? Src1 : Src2 ; MachineBasicBlock :: iterator At = CanDown ? Def2 : Def1 ; ML . push_back ( MuxInfo ( At , DR , PR , SrcT , SrcF , Def1 , Def2 ) ) ; } for ( MuxInfo & MX : ML ) { unsigned MxOpc = getMuxOpcode ( * MX . SrcT , * MX . SrcF ) ; if ( ! MxOpc ) continue ; MachineBasicBlock & B = * MX . At -> getParent ( ) ; const DebugLoc & DL = B . findDebugLoc ( MX . At ) ; auto NewMux = BuildMI ( B , MX . At , DL , HII -> get ( MxOpc ) , MX . DefR ) . addReg ( MX . PredR ) . add ( * MX . SrcT ) . add ( * MX . SrcF ) ; NewMux -> clearKillInfo ( ) ; B . erase ( MX . Def1 ) ; B . erase ( MX . Def2 ) ; Changed = true ; } LivePhysRegs LPR ( * HRI ) ; LPR . addLiveOuts ( B ) ; auto IsLive = [ & LPR , this ] ( unsigned Reg ) -> bool { for ( MCSubRegIterator S ( Reg , HRI , true ) ; S . isValid ( ) ; ++ S ) if ( LPR . contains ( * S ) ) return true ; return false ; } ; for ( auto I = B . rbegin ( ) , E = B . rend ( ) ; I != E ; ++ I ) { if ( I -> isDebugInstr ( ) ) continue ; for ( MachineOperand & Op : I -> operands ( ) ) { if ( ! Op . isReg ( ) || ! Op . isUse ( ) ) continue ; assert ( Op . getSubReg ( ) == <NUM_LIT> && <STR_LIT> ) ;

bool Live = IsLive ( Op . getReg ( ) ) ;


<s> void <ISA_LIT>GenMux :: buildMaps ( MachineBasicBlock & B , InstrIndexMap & I2X , DefUseInfoMap & DUM ) { unsigned Index = <NUM_LIT> ; unsigned NR = HRI -> getNumRegs ( ) ; BitVector Defs ( NR ) , Uses ( NR ) ; for ( MachineInstr & MI : B ) { I2X . insert ( std :: make_pair ( & MI , Index ) ) ;


<s> } if ( NearDef ) continue ; MachineBasicBlock :: iterator It1 = B . begin ( ) , It2 = B . begin ( ) ; std :: advance ( It1 , MinX ) ; std :: advance ( It2 , MaxX ) ; MachineInstr & Def1 = * It1 , & Def2 = * It2 ; MachineOperand * Src1 = & Def1 . getOperand ( <NUM_LIT> ) , * Src2 = & Def2 . getOperand ( <NUM_LIT> ) ; unsigned SR1 = Src1 -> isReg ( ) ? Src1 -> getReg ( ) : <NUM_LIT> ; unsigned SR2 = Src2 -> isReg ( ) ? Src2 -> getReg ( ) : <NUM_LIT> ; bool Failure = false , CanUp = true , CanDown = true ; for ( unsigned X = MinX + <NUM_LIT> ; X < MaxX ; X ++ ) { const DefUseInfo & DU = DUM . lookup ( X ) ; if ( DU . Defs [ PR ] || DU . Defs [ DR ] || DU . Uses [ DR ] ) { Failure = true ; break ; } if ( CanDown && DU . Defs [ SR1 ] ) CanDown = false ; if ( CanUp && DU . Defs [ SR2 ] ) CanUp = false ; } if ( Failure || ( ! CanUp && ! CanDown ) ) continue ; MachineOperand * SrcT = ( MinX == CI . TrueX ) ? Src1 : Src2 ; MachineOperand * SrcF = ( MinX == CI . FalseX ) ? Src1 : Src2 ; MachineBasicBlock :: iterator At = CanDown ? Def2 : Def1 ; ML . push_back ( MuxInfo ( At , DR , PR , SrcT , SrcF , Def1 , Def2 ) ) ; } for ( MuxInfo & MX : ML ) {

unsigned MxOpc = getMuxOpcode ( * MX . SrcT , * MX . SrcF ) ;


<s> for ( MachineBasicBlock :: iterator I = B . begin ( ) ; I != End ; I = NextI ) { MachineInstr * MI = & * I ; NextI = std :: next ( I ) ; unsigned Opc = MI -> getOpcode ( ) ; if ( ! isCondTransfer ( Opc ) ) continue ; unsigned DR = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; if ( isRegPair ( DR ) ) continue ; MachineOperand & PredOp = MI -> getOperand ( <NUM_LIT> ) ; if ( PredOp . isUndef ( ) ) continue ; unsigned PR = PredOp . getReg ( ) ; unsigned Idx = I2X . lookup ( MI ) ; CondsetMap :: iterator F = CM . find ( DR ) ; bool IfTrue = HII -> isPredicatedTrue ( Opc ) ; if ( F != CM . end ( ) && F -> second . PredR != PR ) { CM . erase ( F ) ; F = CM . end ( ) ; } if ( F == CM . end ( ) ) { auto It = CM . insert ( std :: make_pair ( DR , CondsetInfo ( ) ) ) ; F = It . first ; F -> second . PredR = PR ; } CondsetInfo & CI = F -> second ; if ( IfTrue ) CI . TrueX = Idx ; else CI . FalseX = Idx ; if ( CI . TrueX == std :: numeric_limits < unsigned > :: max ( ) || CI . FalseX == std :: numeric_limits < unsigned > :: max ( ) ) continue ; unsigned MinX = std :: min ( CI . TrueX , CI . FalseX ) ; unsigned MaxX = std :: max ( CI . TrueX , CI . FalseX ) ; unsigned SearchX = ( MaxX >= MinPredDist ) ? MaxX - MinPredDist : <NUM_LIT> ; bool NearDef = false ; for ( unsigned X = SearchX ; X < MaxX ; ++ X ) { const DefUseInfo & DU = DUM . lookup ( X ) ; if ( ! DU . Defs [ PR ] ) continue ; NearDef = true ; break ; } if ( NearDef ) continue ; MachineBasicBlock :: iterator It1 = B . begin ( ) , It2 = B . begin ( ) ;


<s> StringRef getPassName ( ) const override { return <STR_LIT> ;


<s> <ISA_LIT>GenMux ( ) : MachineFunctionPass ( ID ) {


<s> MuxInfo ( MachineBasicBlock :: iterator It , unsigned DR , unsigned PR , MachineOperand * TOp , MachineOperand * FOp , MachineInstr & D1 , MachineInstr & D2 ) : At ( It ) , DefR ( DR ) , PredR ( PR ) , SrcT ( TOp ) , SrcF ( FOp ) , Def1 ( & D1 ) , Def2 ( & D2 ) {


<s> HII = MF . getSubtarget < <ISA_LIT>Subtarget > ( ) . getInstrInfo ( ) ; HRI = MF . getSubtarget < <ISA_LIT>Subtarget > ( ) . getRegisterInfo ( ) ;


<s> void <ISA_LIT>GenPredicate :: collectPredicateGPR ( MachineFunction & MF ) { for ( MachineFunction :: iterator A = MF . begin ( ) , Z = MF . end ( ) ; A != Z ; ++ A ) { MachineBasicBlock & B = * A ; for ( MachineBasicBlock :: iterator I = B . begin ( ) , E = B . end ( ) ; I != E ; ++ I ) { MachineInstr * MI = & * I ; unsigned Opc = MI -> getOpcode ( ) ; switch ( Opc ) { case <STR_LIT> : case TargetOpcode :: COPY : if ( isPredReg ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ) { Register RD = MI -> getOperand ( <NUM_LIT> ) ; if ( TargetRegisterInfo :: isVirtualRegister ( RD . R ) ) PredGPRs . insert ( RD ) ;


<s> FunctionPass * llvm :: create<ISA_LIT>GenPredicate ( ) { return new <ISA_LIT>GenPredicate ( ) ;


<s> bool Changed = false ; VectOfInst Erase ; for ( MachineFunction :: iterator A = MF . begin ( ) , Z = MF . end ( ) ; A != Z ; ++ A ) { MachineBasicBlock & B = * A ; for ( MachineBasicBlock :: iterator I = B . begin ( ) , E = B . end ( ) ; I != E ; ++ I ) { if ( I -> getOpcode ( ) != TargetOpcode :: COPY ) continue ; Register DR = I -> getOperand ( <NUM_LIT> ) ; Register SR = I -> getOperand ( <NUM_LIT> ) ; if ( ! TargetRegisterInfo :: isVirtualRegister ( DR . R ) ) continue ; if ( ! TargetRegisterInfo :: isVirtualRegister ( SR . R ) ) continue ; if ( MRI -> getRegClass ( DR . R ) != PredRC ) continue ; if ( MRI -> getRegClass ( SR . R ) != PredRC ) continue ; assert ( ! DR . S && ! SR . S && <STR_LIT> ) ; MRI -> replaceRegWith ( DR . R , SR . R ) ; Erase . insert ( I ) ; Changed = true ; } }

for ( VectOfInst :: iterator I = Erase . begin ( ) , E = Erase . end ( ) ; I != E ; ++ I ) ( * I ) -> eraseFromParent ( ) ;


<s> bool Changed = false ; VectOfInst Erase ; for ( MachineFunction :: iterator A = MF . begin ( ) , Z = MF . end ( ) ; A != Z ; ++ A ) { MachineBasicBlock & B = * A ; for ( MachineBasicBlock :: iterator I = B . begin ( ) , E = B . end ( ) ; I != E ; ++ I ) { if ( I -> getOpcode ( ) != TargetOpcode :: COPY ) continue ; Register DR = I -> getOperand ( <NUM_LIT> ) ; Register SR = I -> getOperand ( <NUM_LIT> ) ; if ( ! TargetRegisterInfo :: isVirtualRegister ( DR . R ) ) continue ; if ( ! TargetRegisterInfo :: isVirtualRegister ( SR . R ) ) continue ; if ( MRI -> getRegClass ( DR . R ) != PredRC ) continue ; if ( MRI -> getRegClass ( SR . R ) != PredRC ) continue ;

assert ( ! DR . S && ! SR . S && <STR_LIT> ) ;


<s> unsigned Opc = MI -> getOpcode ( ) ; if ( getPredForm ( Opc ) != <NUM_LIT> ) return true ; switch ( Opc ) { case <STR_LIT> : case <STR_LIT> : if ( MI -> getOperand ( <NUM_LIT> ) . isImm ( ) && MI -> getOperand ( <NUM_LIT> ) . getImm ( ) == <NUM_LIT> ) return true ; break ;


<s> bool <ISA_LIT>GenPredicate :: isPredReg ( unsigned R ) { if ( ! TargetRegisterInfo :: isVirtualRegister ( R ) ) return false ; const TargetRegisterClass * RC = MRI -> getRegClass ( R ) ;


<s> if ( ! TargetRegisterInfo :: isVirtualRegister ( R ) ) return false ; const TargetRegisterClass * RC = MRI -> getRegClass ( R ) ; return RC == & <STR_LIT> ;


<s> case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> :


<s> case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : for ( ConstMIOperands Mo ( DefI ) ; Mo . isValid ( ) ; ++ Mo ) if ( Mo -> isReg ( ) && Mo -> isUse ( ) ) WorkQ . push ( Register ( Mo -> getReg ( ) ) ) ; break ; default :


<s> PrintRegister ( Register R , const TargetRegisterInfo & I ) : Reg ( R ) , TRI ( I ) {


<s> MachineInstr * DefI = MRI -> getVRegDef ( Reg . R ) ; DefI -> eraseFromParent ( ) ; return ; } for ( ; I != E ; ++ I ) { MachineInstr * UseI = I -> getParent ( ) ;

if ( isConvertibleToPredForm ( UseI ) ) PUsers . insert ( UseI ) ;


<s> Register ( const MachineOperand & MO ) : R ( MO . getReg ( ) ) , S ( MO . getSubReg ( ) ) {


<s> MRI = & MF . getRegInfo ( ) ; PredGPRs . clear ( ) ; PUsers . clear ( ) ; G2P . clear ( ) ; bool Changed = false ; collectPredicateGPR ( MF ) ; for ( SetOfReg :: iterator I = PredGPRs . begin ( ) , E = PredGPRs . end ( ) ; I != E ; ++ I ) processPredicateGPR ( * I ) ; bool Again ; do { Again = false ; VectOfInst Processed , Copy ; typedef VectOfInst :: iterator iterator ; Copy = PUsers ; for ( iterator I = Copy . begin ( ) , E = Copy . end ( ) ; I != E ; ++ I ) { MachineInstr * MI = * I ; bool Done = convertToPredForm ( MI ) ; if ( Done ) { Processed . insert ( MI ) ;


<s> G2P . clear ( ) ; bool Changed = false ; collectPredicateGPR ( MF ) ; for ( SetOfReg :: iterator I = PredGPRs . begin ( ) , E = PredGPRs . end ( ) ; I != E ; ++ I ) processPredicateGPR ( * I ) ; bool Again ; do { Again = false ; VectOfInst Processed , Copy ; typedef VectOfInst :: iterator iterator ; Copy = PUsers ; for ( iterator I = Copy . begin ( ) , E = Copy . end ( ) ; I != E ; ++ I ) { MachineInstr * MI = * I ; bool Done = convertToPredForm ( MI ) ; if ( Done ) { Processed . insert ( MI ) ; Again = true ; } } Changed |= Again ; auto Done = [ Processed ] ( MachineInstr * MI ) -> bool { return Processed . count ( MI ) ; } ; PUsers . remove_if ( Done ) ; } while ( Again ) ; Changed |= eliminatePredCopies ( MF ) ; return Changed ;


<s> MachineBasicBlock & B = * DefI -> getParent ( ) ; DebugLoc DL = DefI -> getDebugLoc ( ) ; const TargetRegisterClass * PredRC = & <STR_LIT> ; unsigned NewPR = MRI -> createVirtualRegister ( PredRC ) ; if ( isConvertibleToPredForm ( DefI ) ) { MachineBasicBlock :: iterator DefIt = DefI ; BuildMI ( B , std :: next ( DefIt ) , DL , TII -> get ( TargetOpcode :: COPY ) , NewPR ) . addReg ( Reg . R , <NUM_LIT> , Reg . S ) ; G2P . insert ( std :: make_pair ( Reg , Register ( NewPR ) ) ) ; DEBUG ( dbgs ( ) << <STR_LIT> << PrintRegister ( Register ( NewPR ) , * TRI ) << '\n' ) ; return Register ( NewPR ) ; }


<s> if ( F != G2P . end ( ) ) return F -> second ; DEBUG ( dbgs ( ) << __func__ << <STR_LIT> << PrintRegister ( Reg , * TRI ) ) ; MachineInstr * DefI = MRI -> getVRegDef ( Reg . R ) ; assert ( DefI ) ; unsigned Opc = DefI -> getOpcode ( ) ; if ( Opc == <STR_LIT> || Opc == TargetOpcode :: COPY ) { assert ( DefI -> getOperand ( <NUM_LIT> ) . isDef ( ) && DefI -> getOperand ( <NUM_LIT> ) . isUse ( ) ) ; Register PR = DefI -> getOperand ( <NUM_LIT> ) ; G2P . insert ( std :: make_pair ( Reg , PR ) ) ; DEBUG ( dbgs ( ) << <STR_LIT> << PrintRegister ( PR , * TRI ) << '\n' ) ; return PR ; } MachineBasicBlock & B = * DefI -> getParent ( ) ; DebugLoc DL = DefI -> getDebugLoc ( ) ; const TargetRegisterClass * PredRC = & <STR_LIT> ; unsigned NewPR = MRI -> createVirtualRegister ( PredRC ) ; if ( isConvertibleToPredForm ( DefI ) ) { MachineBasicBlock :: iterator DefIt = DefI ; BuildMI ( B , std :: next ( DefIt ) , DL , TII -> get ( TargetOpcode :: COPY ) , NewPR ) . addReg ( Reg . R , <NUM_LIT> , Reg . S ) ; G2P . insert ( std :: make_pair ( Reg , Register ( NewPR ) ) ) ; DEBUG ( dbgs ( ) << <STR_LIT> << PrintRegister ( Register ( NewPR ) , * TRI ) << '\n' ) ; return Register ( NewPR ) ;


<s> case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : for ( const MachineOperand & MO : DefI -> operands ( ) ) if ( MO . isReg ( ) && MO . isUse ( ) ) WorkQ . push ( Register ( MO . getReg ( ) ) ) ; break ; default : return isScalarCmp ( DefOpc ) ; } } return true ;