<s> BT . run ( ) ; BTP = & BT ; std :: vector < LoopCand > Cand ; for ( auto & B : MF ) { if ( B . pred_size ( ) != <NUM_LIT> || B . succ_size ( ) != <NUM_LIT> ) continue ; MachineBasicBlock * PB = nullptr ; bool IsLoop = false ; for ( MachineBasicBlock * Pred : B . predecessors ( ) ) { if ( Pred != & B ) PB = Pred ; else IsLoop = true ; } if ( ! IsLoop ) continue ; MachineBasicBlock * EB = nullptr ; for ( MachineBasicBlock * Succ : B . successors ( ) ) { if ( Succ == & B ) continue ; if ( Succ -> pred_size ( ) == <NUM_LIT> ) EB = Succ ; break ; } Cand . push_back ( LoopCand ( & B , PB , EB ) ) ; } bool Changed = false ; for ( auto & C : Cand ) Changed |= processLoop ( C ) ;


<s> for ( MachineInstr & MI : llvm :: reverse ( * B ) ) Instrs . push_back ( & MI ) ; for ( auto MI : Instrs ) { unsigned Opc = MI -> getOpcode ( ) ; if ( Opc == TargetOpcode :: LIFETIME_START || Opc == TargetOpcode :: LIFETIME_END ) continue ; bool Store = false ; if ( MI -> isInlineAsm ( ) ) continue ; if ( ! MI -> isPHI ( ) && ! MI -> isSafeToMove ( nullptr , Store ) ) continue ; bool AllDead = true ; SmallVector < unsigned , <NUM_LIT> > Regs ; for ( auto & Op : MI -> operands ( ) ) { if ( ! Op . isReg ( ) || ! Op . isDef ( ) ) continue ; Register R = Op . getReg ( ) ; if ( ! R . isVirtual ( ) || ! isDead ( R ) ) { AllDead = false ; break ;


<s> bool AllDead = true ; SmallVector < unsigned , <NUM_LIT> > Regs ; for ( auto & Op : MI -> operands ( ) ) { if ( ! Op . isReg ( ) || ! Op . isDef ( ) ) continue ; Register R = Op . getReg ( ) ; if ( ! R . isVirtual ( ) || ! isDead ( 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> bool BitSimplification :: genCombineHalf ( MachineInstr * MI , BitTracker :: RegisterRef RD , const BitTracker :: RegisterCell & RC ) { RegHalf L , H ; if ( ! matchHalf ( RD . Reg , RC , <NUM_LIT> , L ) || ! matchHalf ( RD . Reg , RC , <NUM_LIT> , H ) ) return false ; if ( L . Reg == H . Reg && L . Sub == H . Sub && ! H . Low && L . Low ) return false ; unsigned Opc = MI -> getOpcode ( ) ; unsigned COpc = getCombineOpcode ( H . Low , L . Low ) ; if ( COpc == Opc ) return false ; MachineBasicBlock & B = * MI -> getParent ( ) ; DebugLoc DL = MI -> getDebugLoc ( ) ; unsigned NewR = MRI . createVirtualRegister ( & <STR_LIT> ) ;

auto At = MI -> isPHI ( ) ? B . getFirstNonPHI ( ) : MachineBasicBlock :: iterator ( MI ) ;


<s> RegHalf L , H ; if ( ! matchHalf ( RD . Reg , RC , <NUM_LIT> , L ) || ! matchHalf ( RD . Reg , RC , <NUM_LIT> , H ) ) return false ; if ( L . Reg == H . Reg && L . Sub == H . Sub && ! H . Low && L . Low ) return false ; unsigned Opc = MI -> getOpcode ( ) ; unsigned COpc = getCombineOpcode ( H . Low , L . Low ) ; if ( COpc == Opc ) return false ; MachineBasicBlock & B = * MI -> getParent ( ) ; DebugLoc DL = MI -> getDebugLoc ( ) ; unsigned NewR = MRI . createVirtualRegister ( & <STR_LIT> ) ; auto At = MI -> isPHI ( ) ? B . getFirstNonPHI ( ) : MachineBasicBlock :: iterator ( MI ) ; BuildMI ( B , At , DL , HII . get ( COpc ) , NewR ) . addReg ( H . Reg , <NUM_LIT> , H . Sub ) . addReg ( L . Reg , <NUM_LIT> , L . Sub ) ; HBS :: replaceSubWithSub ( RD . Reg , RD . Sub , NewR , <NUM_LIT> , MRI ) ;

BT . put ( BitTracker :: RegisterRef ( NewR ) , RC ) ;


<s> NewR = MRI . createVirtualRegister ( & <STR_LIT> ) ; BuildMI ( B , At , DL , HII . get ( <STR_LIT> ) , NewR ) . addReg ( L . Reg , <NUM_LIT> , L . Sub ) ; } else if ( ! L . Low && Opc != <STR_LIT> ) { NewR = MRI . createVirtualRegister ( & <STR_LIT> ) ; BuildMI ( B , MI , DL , HII . get ( <STR_LIT> ) , NewR ) . addReg ( L . Reg , <NUM_LIT> , L . Sub ) . addImm ( <NUM_LIT> ) ; } if ( NewR == <NUM_LIT> ) return false ; HBS :: replaceSubWithSub ( RD . Reg , RD . Sub , NewR , <NUM_LIT> , MRI ) ; BT . put ( BitTracker :: RegisterRef ( NewR ) , RC ) ;


<s> NewR = MRI . createVirtualRegister ( & <STR_LIT> ) ; BuildMI ( B , At , DL , HII . get ( <STR_LIT> ) , NewR ) . addReg ( L . Reg , <NUM_LIT> , L . Sub ) ; } else if ( ! L . Low && Opc != <STR_LIT> ) { NewR = MRI . createVirtualRegister ( & <STR_LIT> ) ; BuildMI ( B , MI , DL , HII . get ( <STR_LIT> ) , NewR ) . addReg ( L . Reg , <NUM_LIT> , L . Sub ) . addImm ( <NUM_LIT> ) ; }


<s> while ( W > <NUM_LIT> && RC [ W - <NUM_LIT> ] . is ( <NUM_LIT> ) ) W -- ; if ( W == <NUM_LIT> || W == RC . width ( ) ) return false ; unsigned NewOpc = ( W == <NUM_LIT> ) ? <STR_LIT> : ( W == <NUM_LIT> ) ? <STR_LIT> : ( W < <NUM_LIT> ) ? <STR_LIT> : <STR_LIT> ; MachineBasicBlock & B = * MI -> getParent ( ) ; DebugLoc DL = MI -> getDebugLoc ( ) ; for ( auto & Op : MI -> uses ( ) ) { if ( ! Op . isReg ( ) ) continue ; BitTracker :: RegisterRef RS = Op ; if ( ! BT . has ( RS . Reg ) ) continue ; const BitTracker :: RegisterCell & SC = BT . lookup ( RS . Reg ) ; unsigned BN , BW ; if ( ! HBS :: getSubregMask ( RS , BN , BW , MRI ) ) continue ; if ( BW < W || ! HBS :: isEqual ( RC , <NUM_LIT> , SC , BN , W ) ) continue ; unsigned NewR = MRI . createVirtualRegister ( & <STR_LIT> ) ; auto At = MI -> isPHI ( ) ? B . getFirstNonPHI ( ) : MachineBasicBlock :: iterator ( MI ) ; auto MIB = BuildMI ( B , At , DL , HII . get ( NewOpc ) , NewR ) . addReg ( RS . Reg , <NUM_LIT> , RS . Sub ) ; if ( NewOpc == <STR_LIT> ) MIB . addImm ( ( <NUM_LIT> << W ) - <NUM_LIT> ) ; else if ( NewOpc == <STR_LIT> ) MIB . addImm ( W ) . addImm ( <NUM_LIT> ) ;

HBS :: replaceSubWithSub ( RD . Reg , RD . Sub , NewR , <NUM_LIT> , MRI ) ;


<s> BitTracker :: RegisterRef RS = Op ; if ( ! BT . has ( RS . Reg ) ) continue ; const BitTracker :: RegisterCell & SC = BT . lookup ( RS . Reg ) ; unsigned BN , BW ; if ( ! HBS :: getSubregMask ( RS , BN , BW , MRI ) ) continue ; if ( BW < W || ! HBS :: isEqual ( RC , <NUM_LIT> , SC , BN , W ) ) continue ; unsigned NewR = MRI . createVirtualRegister ( & <STR_LIT> ) ; auto At = MI -> isPHI ( ) ? B . getFirstNonPHI ( ) : MachineBasicBlock :: iterator ( MI ) ; auto MIB = BuildMI ( B , At , DL , HII . get ( NewOpc ) , NewR ) . addReg ( RS . Reg , <NUM_LIT> , RS . Sub ) ; if ( NewOpc == <STR_LIT> ) MIB . addImm ( ( <NUM_LIT> << W ) - <NUM_LIT> ) ; else if ( NewOpc == <STR_LIT> ) MIB . addImm ( W ) . addImm ( <NUM_LIT> ) ;


<s> BuildMI ( B , At , DL , HII . get ( <STR_LIT> ) , NewR ) . addReg ( Rs . Reg , <NUM_LIT> , Rs . Sub ) . addReg ( Rt . Reg , <NUM_LIT> , Rt . Sub ) ; HBS :: replaceSubWithSub ( RD . Reg , RD . Sub , NewR , <NUM_LIT> , MRI ) ; BT . put ( BitTracker :: RegisterRef ( NewR ) , RC ) ; return true ;


<s> if ( ! TargetRegisterInfo :: isVirtualRegister ( RR . Reg ) ) return nullptr ; auto * RC = MRI . getRegClass ( RR . Reg ) ; if ( RR . Sub == <NUM_LIT> ) return RC ;

auto VerifySR = [ ] ( unsigned Sub ) -> void {


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


<s> switch ( Opc ) { case TargetOpcode :: COPY : case TargetOpcode :: REG_SEQUENCE : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : return true ; default : break ;


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


<s> for ( auto I = B . begin ( ) , E = B . end ( ) ; I != E ; ++ I , AVB . insert ( Defs ) ) { MachineInstr * MI = & * I ; Defs . clear ( ) ; HBS :: getInstrDefs ( * MI , Defs ) ; unsigned Opc = MI -> getOpcode ( ) ; if ( Opc == TargetOpcode :: COPY || Opc == TargetOpcode :: REG_SEQUENCE ) continue ; if ( MI -> mayStore ( ) ) { bool T = genStoreUpperHalf ( MI ) ; T = T || genStoreImmediate ( MI ) ; Changed |= T ; continue ; } if ( Defs . count ( ) != <NUM_LIT> ) continue ; const MachineOperand & Op0 = MI -> getOperand ( <NUM_LIT> ) ; if ( ! Op0 . isReg ( ) || ! Op0 . isDef ( ) ) continue ; BitTracker :: RegisterRef RD = Op0 ; if ( ! BT . has ( RD . Reg ) ) continue ; const TargetRegisterClass * FRC = HBS :: getFinalVRegClass ( RD , MRI ) ; const BitTracker :: RegisterCell & RC = BT . lookup ( RD . Reg ) ;


<s> RegisterSet Defs ; for ( auto I = B . begin ( ) , E = B . end ( ) ; I != E ; ++ I , AVB . insert ( Defs ) ) { MachineInstr * MI = & * I ; Defs . clear ( ) ; HBS :: getInstrDefs ( * MI , Defs ) ; unsigned Opc = MI -> getOpcode ( ) ; if ( Opc == TargetOpcode :: COPY || Opc == TargetOpcode :: REG_SEQUENCE ) continue ; if ( MI -> mayStore ( ) ) { bool T = genStoreUpperHalf ( MI ) ; T = T || genStoreImmediate ( MI ) ; Changed |= T ; continue ; } if ( Defs . count ( ) != <NUM_LIT> ) continue ; const MachineOperand & Op0 = MI -> getOperand ( <NUM_LIT> ) ; if ( ! Op0 . isReg ( ) || ! Op0 . isDef ( ) ) continue ; BitTracker :: RegisterRef RD = Op0 ; if ( ! BT . has ( RD . Reg ) ) continue ; const TargetRegisterClass * FRC = HBS :: getFinalVRegClass ( RD , MRI ) ; const BitTracker :: RegisterCell & RC = BT . lookup ( RD . Reg ) ; if ( FRC -> getID ( ) == <STR_LIT> ) { bool T = genPackhl ( MI , RD , RC ) ; Changed |= T ; continue ; } if ( FRC -> getID ( ) == <STR_LIT> ) { bool T = genExtractHalf ( MI , RD , RC ) ; T = T || genCombineHalf ( MI , RD , RC ) ; T = T || genExtractLow ( MI , RD , RC ) ; Changed |= T ; continue ; } if ( FRC -> getID ( ) == <STR_LIT> ) { bool T = simplifyTstbit ( MI , RD , RC ) ; Changed |= T ; continue ; } } return Changed ;


<s> auto & HII = * HST . getInstrInfo ( ) ; MDT = & getAnalysis < MachineDominatorTree > ( ) ; MachineRegisterInfo & MRI = MF . getRegInfo ( ) ; bool Changed ; Changed = DeadCodeElimination ( MF , * MDT ) . run ( ) ; const <ISA_LIT>Evaluator HE ( HRI , MRI , HII , MF ) ; BitTracker BT ( HE , MF ) ; DEBUG ( BT . trace ( true ) ) ; BT . run ( ) ; MachineBasicBlock & Entry = MF . front ( ) ; RegisterSet AIG ; ConstGeneration ImmG ( BT , HII , MRI ) ; Changed |= visitBlock ( Entry , ImmG , AIG ) ; RegisterSet ARE ; RedundantInstrElimination RIE ( BT , HII , MRI ) ; bool Ried = visitBlock ( Entry , RIE , ARE ) ; if ( Ried ) { Changed = true ; BT . run ( ) ; } RegisterSet ACG ; CopyGeneration CopyG ( BT , HII , MRI ) ; Changed |= visitBlock ( Entry , CopyG , ACG ) ; RegisterSet ACP ; CopyPropagation CopyP ( HRI , MRI ) ; Changed |= visitBlock ( Entry , CopyP , ACP ) ; Changed = DeadCodeElimination ( MF , * MDT ) . run ( ) || Changed ; BT . run ( ) ;


<s> if ( Opc != <STR_LIT> ) return false ; unsigned BN = MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ; BitTracker :: RegisterRef RS = MI -> getOperand ( <NUM_LIT> ) ; unsigned F , W ; DebugLoc DL = MI -> getDebugLoc ( ) ; if ( ! BT . has ( RS . Reg ) || ! HBS :: getSubregMask ( RS , F , W , MRI ) ) return false ; MachineBasicBlock & B = * MI -> getParent ( ) ; auto At = MI -> isPHI ( ) ? B . getFirstNonPHI ( ) : MachineBasicBlock :: iterator ( MI ) ; const BitTracker :: RegisterCell & SC = BT . lookup ( RS . Reg ) ; const BitTracker :: BitValue & V = SC [ F + BN ] ; if ( V . Type == BitTracker :: BitValue :: Ref && V . RefI . Reg != RS . Reg ) { const TargetRegisterClass * TC = MRI . getRegClass ( V . RefI . Reg ) ; unsigned P = UINT_MAX ; BitTracker :: RegisterRef RR ( V . RefI . Reg , <NUM_LIT> ) ; if ( TC == & <STR_LIT> ) { P = V . RefI . Pos ; RR . Sub = <STR_LIT> ; if ( P >= <NUM_LIT> ) { P -= <NUM_LIT> ; RR . Sub = <STR_LIT> ; } } else if ( TC == & <STR_LIT> ) { P = V . RefI . Pos ; } if ( P != UINT_MAX ) { unsigned NewR = MRI . createVirtualRegister ( & <STR_LIT> ) ; BuildMI ( B , At , DL , HII . get ( <STR_LIT> ) , NewR ) . addReg ( RR . Reg , <NUM_LIT> , RR . Sub ) . addImm ( P ) ; HBS :: replaceReg ( RD . Reg , NewR , MRI ) ;


<s> Bits . clear ( ) ; LRU . clear ( ) ;


<s> if ( Bits . size ( ) <= Idx ) Bits . resize ( std :: max ( Idx + <NUM_LIT> , <NUM_LIT> ) ) ;


<s> unsigned find_first ( ) const { int First = Bits . find_first ( ) ; if ( First < <NUM_LIT> ) return <NUM_LIT> ;


<s> if ( First < <NUM_LIT> ) return <NUM_LIT> ; return x2v ( First ) ;


<s> unsigned Idx = v2x ( R ) ; if ( Idx >= Bits . size ( ) ) return false ; return Bits . test ( Idx ) ;


<s> bool has ( unsigned R ) const { unsigned Idx = v2x ( R ) ; if ( Idx >= Bits . size ( ) ) return false ;


<s> bool includes ( const RegisterSet & Rs ) const { return ! Rs . Bits . test ( Bits ) ;


<s> for ( unsigned R = Rs . find_first ( ) ; R ; R = Rs . find_next ( R ) ) insert ( R ) ;


<s> return Bits . anyCommon ( Rs . Bits ) ;


<s> bool intersects ( const RegisterSet & Rs ) const {


<s> explicit RegisterSet ( unsigned s , bool t = false ) : Bits ( s , t ) {


<s> BitTracker :: RegisterRef UR = * I ; unsigned B , W ; if ( ! HBS :: getSubregMask ( UR , B , W , MRI ) ) return false ; MachineInstr & UseI = * I -> getParent ( ) ; if ( UseI . isPHI ( ) || UseI . isCopy ( ) ) { Register DefR = UseI . getOperand ( <NUM_LIT> ) . getReg ( ) ;

if ( ! Register :: isVirtualRegister ( DefR ) ) return false ;


<s> const TargetRegisterClass * <ISA_LIT>BitSimplify :: getFinalVRegClass ( const BitTracker :: RegisterRef & RR , MachineRegisterInfo & MRI ) { if ( ! Register :: isVirtualRegister ( RR . Reg ) ) return nullptr ; auto * RC = MRI . getRegClass ( RR . Reg ) ; if ( RR . Sub == <NUM_LIT> ) return RC ; auto & HRI = static_cast < const <ISA_LIT>RegisterInfo & > ( * MRI . getTargetRegisterInfo ( ) ) ; auto VerifySR = [ & HRI ] ( const TargetRegisterClass * RC , unsigned Sub ) -> void { ( void ) HRI ; assert ( Sub == HRI . get<ISA_LIT>SubRegIndex ( * RC , <STR_LIT> ) || Sub == HRI . get<ISA_LIT>SubRegIndex ( * RC , <STR_LIT> ) ) ; } ;


<s> if ( ! Op . isReg ( ) || ! Op . isDef ( ) ) continue ; Register R = Op . getReg ( ) ;

if ( ! Register :: isVirtualRegister ( R ) ) continue ;


<s> void <ISA_LIT>BitSimplify :: getInstrDefs ( const MachineInstr & MI , RegisterSet & Defs ) {


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

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


<s> const BitTracker :: RegisterCell & SC = BT . lookup ( Reg ) ; if ( Pos + <NUM_LIT> > SC . width ( ) ) return false ; for ( unsigned i = <NUM_LIT> ; i < <NUM_LIT> ; ++ i ) { const BitTracker :: BitValue & RV = RC [ i + B ] ; if ( RV . Type == BitTracker :: BitValue :: Ref ) { if ( RV . RefI . Reg != Reg ) return false ; if ( RV . RefI . Pos != i + Pos ) return false ; continue ; } if ( RC [ i + B ] != SC [ i + Pos ] ) return false ; } unsigned Sub = <NUM_LIT> ; switch ( Pos ) { case <NUM_LIT> : Sub = <STR_LIT> ; Low = true ; break ; case <NUM_LIT> : Sub = <STR_LIT> ; Low = false ; break ; case <NUM_LIT> : Sub = <STR_LIT> ; Low = true ; break ; case <NUM_LIT> : Sub = <STR_LIT> ; Low = false ; break ; default : return false ; }


<s> if ( P < I - B ) return false ; unsigned Pos = P - ( I - B ) ; if ( Reg == <NUM_LIT> || Reg == SelfR ) return false ; if ( ! Register :: isVirtualRegister ( Reg ) ) return false ; if ( ! BT . has ( Reg ) ) return false ; const BitTracker :: RegisterCell & SC = BT . lookup ( Reg ) ; if ( Pos + <NUM_LIT> > SC . width ( ) ) return false ; for ( unsigned i = <NUM_LIT> ; i < <NUM_LIT> ; ++ i ) { const BitTracker :: BitValue & RV = RC [ i + B ] ; if ( RV . Type == BitTracker :: BitValue :: Ref ) { if ( RV . RefI . Reg != Reg ) return false ; if ( RV . RefI . Pos != i + Pos ) return false ; continue ; } if ( RC [ i + B ] != SC [ i + Pos ] ) return false ; } unsigned Sub = <NUM_LIT> ; switch ( Pos ) { case <NUM_LIT> : Sub = <STR_LIT> ; Low = true ; break ; case <NUM_LIT> : Sub = <STR_LIT> ; Low = false ; break ; case <NUM_LIT> : Sub = <STR_LIT> ;


<s> Forbidden . insert ( R ) ; continue ; } if ( FRC == & <STR_LIT> || FRC == & <STR_LIT> ) { unsigned SubLo = HRI . get<ISA_LIT>SubRegIndex ( * FRC , <STR_LIT> ) ; unsigned SubHi = HRI . get<ISA_LIT>SubRegIndex ( * FRC , <STR_LIT> ) ; BitTracker :: RegisterRef TL = { R , SubLo } ; BitTracker :: RegisterRef TH = { R , SubHi } ; BitTracker :: RegisterRef ML , MH ; if ( findMatch ( TL , ML , AVB ) && findMatch ( TH , MH , AVB ) ) { auto * FRC = HBS :: getFinalVRegClass ( R , MRI ) ; Register NewR = MRI . createVirtualRegister ( FRC ) ; BuildMI ( B , At , DL , HII . get ( TargetOpcode :: REG_SEQUENCE ) , NewR ) . addReg ( ML . Reg , <NUM_LIT> , ML . Sub ) . addImm ( SubLo ) . addReg ( MH . Reg , <NUM_LIT> , MH . Sub ) . addImm ( SubHi ) ; BT . put ( BitTracker :: RegisterRef ( NewR ) , BT . get ( R ) ) ; HBS :: replaceReg ( R , NewR , MRI ) ; Forbidden . insert ( R ) ; } } } } return Changed ;


<s> BitTracker :: RegisterRef MR ; auto * FRC = HBS :: getFinalVRegClass ( R , MRI ) ; if ( findMatch ( R , MR , AVB ) ) { Register NewR = MRI . createVirtualRegister ( FRC ) ; BuildMI ( B , At , DL , HII . get ( TargetOpcode :: COPY ) , NewR ) . addReg ( MR . Reg , <NUM_LIT> , MR . Sub ) ; BT . put ( BitTracker :: RegisterRef ( NewR ) , BT . get ( MR ) ) ; HBS :: replaceReg ( R , NewR , MRI ) ; Forbidden . insert ( R ) ; continue ; } if ( FRC == & <STR_LIT> || FRC == & <STR_LIT> ) { unsigned SubLo = HRI . get<ISA_LIT>SubRegIndex ( * FRC , <STR_LIT> ) ; unsigned SubHi = HRI . get<ISA_LIT>SubRegIndex ( * FRC , <STR_LIT> ) ; BitTracker :: RegisterRef TL = { R , SubLo } ; BitTracker :: RegisterRef TH = { R , SubHi } ; BitTracker :: RegisterRef ML , MH ; if ( findMatch ( TL , ML , AVB ) && findMatch ( TH , MH , AVB ) ) { auto * FRC = HBS :: getFinalVRegClass ( R , MRI ) ; Register NewR = MRI . createVirtualRegister ( FRC ) ;

BuildMI ( B , At , DL , HII . get ( TargetOpcode :: REG_SEQUENCE ) , NewR ) . addReg ( ML . Reg , <NUM_LIT> , ML . Sub ) . addImm ( SubLo ) . addReg ( MH . Reg , <NUM_LIT> , MH . Sub ) . addImm ( SubHi ) ;


<s> decltype ( End ) NextI ; for ( auto I = Begin ; I != End ; I = NextI ) { NextI = std :: next ( I ) ; I -> setReg ( NewR ) ;


<s> bool <ISA_LIT>BitSimplify :: replaceRegWithSub ( unsigned OldR , unsigned NewR , unsigned NewSR , MachineRegisterInfo & MRI ) { if ( ! Register :: isVirtualRegister ( OldR ) || ! Register :: isVirtualRegister ( NewR ) ) return false ; if ( hasTiedUse ( OldR , MRI , NewSR ) ) return false ;

auto Begin = MRI . use_begin ( OldR ) , End = MRI . use_end ( ) ;


<s> bool <ISA_LIT>BitSimplify :: replaceSubWithSub ( unsigned OldR , unsigned OldSR , unsigned NewR , unsigned NewSR , MachineRegisterInfo & MRI ) { if ( ! Register :: isVirtualRegister ( OldR ) || ! Register :: isVirtualRegister ( NewR ) ) return false ; if ( OldSR != NewSR && hasTiedUse ( OldR , MRI , NewSR ) ) return false ; auto Begin = MRI . use_begin ( OldR ) , End = MRI . use_end ( ) ; decltype ( End ) NextI ; for ( auto I = Begin ; I != End ; I = NextI ) { NextI = std :: next ( I ) ; if ( I -> getSubReg ( ) != OldSR ) continue ; I -> setReg ( NewR ) ; I -> setSubReg ( NewSR ) ; } return Begin != End ;


<s> unsigned Opc = MI -> getOpcode ( ) ; if ( Opc == TargetOpcode :: LIFETIME_START || Opc == TargetOpcode :: LIFETIME_END ) continue ; bool Store = false ; if ( MI -> isInlineAsm ( ) ) continue ; if ( ! MI -> isPHI ( ) && ! MI -> isSafeToMove ( nullptr , Store ) ) continue ; bool AllDead = true ; SmallVector < unsigned , <NUM_LIT> > Regs ; for ( auto & Op : MI -> operands ( ) ) { if ( ! Op . isReg ( ) || ! Op . isDef ( ) ) continue ; Register R = Op . getReg ( ) ; if ( ! Register :: isVirtualRegister ( R ) || ! isDead ( R ) ) {


<s> unsigned BN = MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ; BitTracker :: RegisterRef RS = MI -> getOperand ( <NUM_LIT> ) ; unsigned F , W ; DebugLoc DL = MI -> getDebugLoc ( ) ; if ( ! BT . has ( RS . Reg ) || ! HBS :: getSubregMask ( RS , F , W , MRI ) ) return false ; MachineBasicBlock & B = * MI -> getParent ( ) ; auto At = MI -> isPHI ( ) ? B . getFirstNonPHI ( ) : MachineBasicBlock :: iterator ( MI ) ; const BitTracker :: RegisterCell & SC = BT . lookup ( RS . Reg ) ; const BitTracker :: BitValue & V = SC [ F + BN ] ; if ( V . Type == BitTracker :: BitValue :: Ref && V . RefI . Reg != RS . Reg ) { const TargetRegisterClass * TC = MRI . getRegClass ( V . RefI . Reg ) ; unsigned P = std :: numeric_limits < unsigned > :: max ( ) ; BitTracker :: RegisterRef RR ( V . RefI . Reg , <NUM_LIT> ) ; if ( TC == & <STR_LIT> ) { P = V . RefI . Pos ; RR . Sub = <STR_LIT> ; if ( P >= <NUM_LIT> ) { P -= <NUM_LIT> ; RR . Sub = <STR_LIT> ; } } else if ( TC == & <STR_LIT> ) { P = V . RefI . Pos ; } if ( P != std :: numeric_limits < unsigned > :: max ( ) ) { unsigned NewR = MRI . createVirtualRegister ( & <STR_LIT> ) ; BuildMI ( B , At , DL , HII . get ( <STR_LIT> ) , NewR ) . addReg ( RR . Reg , <NUM_LIT> , RR . Sub ) . addImm ( P ) ;

HBS :: replaceReg ( RD . Reg , NewR , MRI ) ;


<s> unsigned Opc = MI -> getOpcode ( ) ; if ( Opc != <STR_LIT> ) return false ; unsigned BN = MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ; BitTracker :: RegisterRef RS = MI -> getOperand ( <NUM_LIT> ) ; unsigned F , W ; DebugLoc DL = MI -> getDebugLoc ( ) ; if ( ! BT . has ( RS . Reg ) || ! HBS :: getSubregMask ( RS , F , W , MRI ) ) return false ; MachineBasicBlock & B = * MI -> getParent ( ) ; auto At = MI -> isPHI ( ) ? B . getFirstNonPHI ( ) : MachineBasicBlock :: iterator ( MI ) ; const BitTracker :: RegisterCell & SC = BT . lookup ( RS . Reg ) ; const BitTracker :: BitValue & V = SC [ F + BN ] ; if ( V . Type == BitTracker :: BitValue :: Ref && V . RefI . Reg != RS . Reg ) { const TargetRegisterClass * TC = MRI . getRegClass ( V . RefI . Reg ) ; unsigned P = std :: numeric_limits < unsigned > :: max ( ) ; BitTracker :: RegisterRef RR ( V . RefI . Reg , <NUM_LIT> ) ; if ( TC == & <STR_LIT> ) { P = V . RefI . Pos ; RR . Sub = <STR_LIT> ; if ( P >= <NUM_LIT> ) { P -= <NUM_LIT> ; RR . Sub = <STR_LIT> ; } } else if ( TC == & <STR_LIT> ) { P = V . RefI . Pos ; } if ( P != std :: numeric_limits < unsigned > :: max ( ) ) { unsigned NewR = MRI . createVirtualRegister ( & <STR_LIT> ) ; BuildMI ( B , At , DL , HII . get ( <STR_LIT> ) , NewR ) . addReg ( RR . Reg , <NUM_LIT> , RR . Sub ) . addImm ( P ) ; HBS :: replaceReg ( RD . Reg , NewR , MRI ) ;


<s> if ( RC == & <STR_LIT> ) { if ( isInt < <NUM_LIT> > ( C ) ) { BuildMI ( B , At , DL , HII . get ( <STR_LIT> ) , Reg ) . addImm ( C ) ; return Reg ; } unsigned Lo = Lo_32 ( C ) , Hi = Hi_32 ( C ) ; if ( isInt < <NUM_LIT> > ( Lo ) || isInt < <NUM_LIT> > ( Hi ) ) { unsigned Opc = isInt < <NUM_LIT> > ( Lo ) ? <STR_LIT> : <STR_LIT> ; BuildMI ( B , At , DL , HII . get ( Opc ) , Reg ) . addImm ( int32_t ( Hi ) ) . addImm ( int32_t ( Lo ) ) ; return Reg ; } BuildMI ( B , At , DL , HII . get ( <STR_LIT> ) , Reg ) . addImm ( C ) ; return Reg ; } if ( RC == & <STR_LIT> ) { unsigned Opc ; if ( C == <NUM_LIT> ) Opc = <STR_LIT> ; else if ( ( C & <NUM_LIT> ) == <NUM_LIT> ) Opc = <STR_LIT> ; else return <NUM_LIT> ; BuildMI ( B , At , DL , HII . get ( Opc ) , Reg ) ; return Reg ; } return <NUM_LIT> ;


<s> } unsigned Lo = Lo_32 ( C ) , Hi = Hi_32 ( C ) ; if ( isInt < <NUM_LIT> > ( Lo ) || isInt < <NUM_LIT> > ( Hi ) ) { unsigned Opc = isInt < <NUM_LIT> > ( Lo ) ? <STR_LIT> : <STR_LIT> ; BuildMI ( B , At , DL , HII . get ( Opc ) , Reg ) . addImm ( int32_t ( Hi ) ) . addImm ( int32_t ( Lo ) ) ; return Reg ; } BuildMI ( B , At , DL , HII . get ( <STR_LIT> ) , Reg ) . addImm ( C ) ; return Reg ; } if ( RC == & <STR_LIT> ) {


<s> return true ; } assert ( RR . Sub == <STR_LIT> || RR . Sub == <STR_LIT> ) ; if ( RR . Sub == <STR_LIT> ) Begin = <NUM_LIT> ; switch ( RC -> getID ( ) ) { case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : Width = RC -> getSize ( ) * <NUM_LIT> / <NUM_LIT> ;

if ( RR . Sub == <STR_LIT> ) Begin = Width ;


<s> if ( findMatch ( R , MR , AVB ) ) { unsigned NewR = MRI . createVirtualRegister ( FRC ) ; BuildMI ( B , At , DL , HII . get ( TargetOpcode :: COPY ) , NewR ) . addReg ( MR . Reg , <NUM_LIT> , MR . Sub ) ; BT . put ( BitTracker :: RegisterRef ( NewR ) , BT . get ( MR ) ) ; HBS :: replaceReg ( R , NewR , MRI ) ; Forbidden . insert ( R ) ; continue ; } if ( FRC == & <STR_LIT> || FRC == & <STR_LIT> || FRC == & <STR_LIT> ) { BitTracker :: RegisterRef TL = { R , <STR_LIT> } ; BitTracker :: RegisterRef TH = { R , <STR_LIT> } ; BitTracker :: RegisterRef ML , MH ; if ( findMatch ( TL , ML , AVB ) && findMatch ( TH , MH , AVB ) ) { auto * FRC = HBS :: getFinalVRegClass ( R , MRI ) ; unsigned NewR = MRI . createVirtualRegister ( FRC ) ; BuildMI ( B , At , DL , HII . get ( TargetOpcode :: REG_SEQUENCE ) , NewR ) . addReg ( ML . Reg , <NUM_LIT> , ML . Sub ) . addImm ( <STR_LIT> ) . addReg ( MH . Reg , <NUM_LIT> , MH . Sub ) . addImm ( <STR_LIT> ) ; BT . put ( BitTracker :: RegisterRef ( NewR ) , BT . get ( R ) ) ;


<s> auto & HRI = * HST . getRegisterInfo ( ) ; auto & HII = * HST . getInstrInfo ( ) ; MDT = & getAnalysis < MachineDominatorTree > ( ) ; MachineRegisterInfo & MRI = MF . getRegInfo ( ) ; bool Changed ; Changed = DeadCodeElimination ( MF , * MDT ) . run ( ) ; const <ISA_LIT>Evaluator HE ( HRI , MRI , HII , MF ) ; BitTracker BT ( HE , MF ) ; DEBUG ( BT . trace ( true ) ) ; BT . run ( ) ; MachineBasicBlock & Entry = MF . front ( ) ; RegisterSet AIG ; ConstGeneration ImmG ( BT , HII , MRI ) ; Changed |= visitBlock ( Entry , ImmG , AIG ) ; RegisterSet ARE ;

RedundantInstrElimination RIE ( BT , HII , MRI ) ;


<s> MachineBasicBlock & Entry = MF . front ( ) ; RegisterSet AIG ; ConstGeneration ImmG ( BT , HII , MRI ) ; Changed |= visitBlock ( Entry , ImmG , AIG ) ; RegisterSet ARE ; RedundantInstrElimination RIE ( BT , HII , MRI ) ; bool Ried = visitBlock ( Entry , RIE , ARE ) ; if ( Ried ) { Changed = true ; BT . run ( ) ; } RegisterSet ACG ; CopyGeneration CopyG ( BT , HII , HRI , MRI ) ; Changed |= visitBlock ( Entry , CopyG , ACG ) ; RegisterSet ACP ; CopyPropagation CopyP ( HRI , MRI ) ; Changed |= visitBlock ( Entry , CopyP , ACP ) ; Changed = DeadCodeElimination ( MF , * MDT ) . run ( ) || Changed ; BT . run ( ) ; RegisterSet ABS ;

BitSimplification BitS ( BT , * MDT , HII , HRI , MRI , MF ) ;


<s> BitTracker :: RegisterRef RS = MI -> getOperand ( <NUM_LIT> ) ; unsigned F , W ; DebugLoc DL = MI -> getDebugLoc ( ) ; if ( ! BT . has ( RS . Reg ) || ! HBS :: getSubregMask ( RS , F , W , MRI ) ) return false ; MachineBasicBlock & B = * MI -> getParent ( ) ; auto At = MI -> isPHI ( ) ? B . getFirstNonPHI ( ) : MachineBasicBlock :: iterator ( MI ) ; const BitTracker :: RegisterCell & SC = BT . lookup ( RS . Reg ) ; const BitTracker :: BitValue & V = SC [ F + BN ] ; if ( V . Type == BitTracker :: BitValue :: Ref && V . RefI . Reg != RS . Reg ) { const TargetRegisterClass * TC = MRI . getRegClass ( V . RefI . Reg ) ; unsigned P = UINT_MAX ; BitTracker :: RegisterRef RR ( V . RefI . Reg , <NUM_LIT> ) ; if ( TC == & <STR_LIT> ) { P = V . RefI . Pos ; RR . Sub = <STR_LIT> ; if ( P >= <NUM_LIT> ) { P -= <NUM_LIT> ; RR . Sub = <STR_LIT> ; } } else if ( TC == & <STR_LIT> ) { P = V . RefI . Pos ; } if ( P != UINT_MAX ) { unsigned NewR = MRI . createVirtualRegister ( & <STR_LIT> ) ; BuildMI ( B , At , DL , HII . get ( <STR_LIT> ) , NewR ) . addReg ( RR . Reg , <NUM_LIT> , RR . Sub ) . addImm ( P ) ; HBS :: replaceReg ( RD . Reg , NewR , MRI ) ; BT . put ( NewR , RC ) ; return true ; } } else if ( V . is ( <NUM_LIT> ) || V . is ( <NUM_LIT> ) ) { unsigned NewR = MRI . createVirtualRegister ( & <STR_LIT> ) ;

unsigned NewOpc = V . is ( <NUM_LIT> ) ? <STR_LIT> : <STR_LIT> ;


<s> if ( L . Low && Opc != <STR_LIT> ) { NewR = MRI . createVirtualRegister ( & <STR_LIT> ) ; BuildMI ( B , At , DL , HII . get ( <STR_LIT> ) , NewR ) . addReg ( L . Reg , <NUM_LIT> , L . Sub ) ; } else if ( ! L . Low && Opc != <STR_LIT> ) { NewR = MRI . createVirtualRegister ( & <STR_LIT> ) ;

BuildMI ( B , MI , DL , HII . get ( <STR_LIT> ) , NewR ) . addReg ( L . Reg , <NUM_LIT> , L . Sub ) . addImm ( <NUM_LIT> ) . addImm ( <NUM_LIT> ) ;


<s> NextI = std :: next ( I ) ; MachineInstr * MI = & * I ; if ( MI -> getOpcode ( ) == TargetOpcode :: COPY ) continue ; if ( MI -> hasUnmodeledSideEffects ( ) || MI -> isInlineAsm ( ) ) continue ; unsigned NumD = MI -> getDesc ( ) . getNumDefs ( ) ; if ( NumD != <NUM_LIT> ) continue ; BitTracker :: RegisterRef RD = MI -> getOperand ( <NUM_LIT> ) ; if ( ! BT . has ( RD . Reg ) ) continue ; const BitTracker :: RegisterCell & DC = BT . lookup ( RD . Reg ) ; auto At = MI -> isPHI ( ) ? B . getFirstNonPHI ( ) : MachineBasicBlock :: iterator ( MI ) ; for ( auto & Op : MI -> uses ( ) ) { if ( ! Op . isReg ( ) ) continue ; BitTracker :: RegisterRef RS = Op ; if ( ! BT . has ( RS . Reg ) ) continue ; if ( ! HBS :: isTransparentCopy ( RD , RS , MRI ) ) continue ; unsigned BN , BW ; if ( ! HBS :: getSubregMask ( RS , BN , BW , MRI ) ) continue ; const BitTracker :: RegisterCell & SC = BT . lookup ( RS . Reg ) ; if ( ! usedBitsEqual ( RD , RS ) && ! HBS :: isEqual ( DC , <NUM_LIT> , SC , BN , BW ) ) continue ; const DebugLoc & DL = MI -> getDebugLoc ( ) ; const TargetRegisterClass * FRC = HBS :: getFinalVRegClass ( RD , MRI ) ; unsigned NewR = MRI . createVirtualRegister ( FRC ) ;

BuildMI ( B , At , DL , HII . get ( TargetOpcode :: COPY ) , NewR ) . addReg ( RS . Reg , <NUM_LIT> , RS . Sub ) ;


<s> for ( auto I = B . begin ( ) , E = B . end ( ) , NextI = I ; I != E ; ++ I ) { NextI = std :: next ( I ) ; MachineInstr * MI = & * I ; if ( MI -> getOpcode ( ) == TargetOpcode :: COPY ) continue ; if ( MI -> hasUnmodeledSideEffects ( ) || MI -> isInlineAsm ( ) ) continue ; unsigned NumD = MI -> getDesc ( ) . getNumDefs ( ) ; if ( NumD != <NUM_LIT> ) continue ; BitTracker :: RegisterRef RD = MI -> getOperand ( <NUM_LIT> ) ; if ( ! BT . has ( RD . Reg ) ) continue ; const BitTracker :: RegisterCell & DC = BT . lookup ( RD . Reg ) ; auto At = MI -> isPHI ( ) ? B . getFirstNonPHI ( ) : MachineBasicBlock :: iterator ( MI ) ; for ( auto & Op : MI -> uses ( ) ) { if ( ! Op . isReg ( ) ) continue ; BitTracker :: RegisterRef RS = Op ; if ( ! BT . has ( RS . Reg ) ) continue ; if ( ! HBS :: isTransparentCopy ( RD , RS , MRI ) ) continue ; unsigned BN , BW ; if ( ! HBS :: getSubregMask ( RS , BN , BW , MRI ) ) continue ; const BitTracker :: RegisterCell & SC = BT . lookup ( RS . Reg ) ; if ( ! usedBitsEqual ( RD , RS ) && ! HBS :: isEqual ( DC , <NUM_LIT> , SC , BN , BW ) ) continue ; const DebugLoc & DL = MI -> getDebugLoc ( ) ; const TargetRegisterClass * FRC = HBS :: getFinalVRegClass ( RD , MRI ) ; unsigned NewR = MRI . createVirtualRegister ( FRC ) ;


<s> bool ConstGeneration :: isTfrConst ( const MachineInstr & MI ) const { unsigned Opc = MI . getOpcode ( ) ; switch ( Opc ) { 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> : return true ;


<s> if ( isConst ( DR , C ) ) { DebugLoc DL = I -> getDebugLoc ( ) ; auto At = I -> isPHI ( ) ? B . getFirstNonPHI ( ) : I ; unsigned ImmReg = genTfrConst ( MRI . getRegClass ( DR ) , C , B , At , DL ) ; if ( ImmReg ) { HBS :: replaceReg ( DR , ImmReg , MRI ) ; BT . put ( ImmReg , BT . lookup ( DR ) ) ;


<s> RegisterSet Visited ; std :: vector < unsigned > Pending ; Pending . push_back ( Reg ) ; for ( unsigned i = <NUM_LIT> ; i < Pending . size ( ) ; ++ i ) { unsigned R = Pending [ i ] ; if ( Visited . has ( R ) ) continue ; Visited . insert ( R ) ; for ( auto I = MRI . use_begin ( R ) , E = MRI . use_end ( ) ; I != E ; ++ I ) { BitTracker :: RegisterRef UR = * I ; unsigned B , W ; if ( ! HBS :: getSubregMask ( UR , B , W , MRI ) ) return false ; MachineInstr & UseI = * I -> getParent ( ) ; if ( UseI . isPHI ( ) || UseI . isCopy ( ) ) { Register DefR = UseI . getOperand ( <NUM_LIT> ) . getReg ( ) ; if ( ! DefR . isVirtual ( ) ) return false ; Pending . push_back ( DefR ) ; } else { if ( ! computeUsedBits ( UseI , I . getOperandNo ( ) , Used , B ) ) return false ; } }


<s> MachineInstr & UseI = * I -> getParent ( ) ; if ( UseI . isPHI ( ) || UseI . isCopy ( ) ) { Register DefR = UseI . getOperand ( <NUM_LIT> ) . getReg ( ) ; if ( ! DefR . isVirtual ( ) ) return false ; Pending . push_back ( DefR ) ; } else { if ( ! computeUsedBits ( UseI , I . getOperandNo ( ) , Used , B ) ) return false ; } } } Bits |= Used ; return true ;


<s> if ( ! HBS :: getSubregMask ( Inp , B , W , MRI ) ) return false ; for ( Register R = AVs . find_first ( ) ; R ; R = AVs . find_next ( R ) ) { if ( ! BT . has ( R ) || Forbidden [ R ] ) continue ; const BitTracker :: RegisterCell & RC = BT . lookup ( R ) ; unsigned RW = RC . width ( ) ; if ( W == RW ) { if ( FRC != MRI . getRegClass ( R ) ) continue ; if ( ! HBS :: isTransparentCopy ( R , Inp , MRI ) ) continue ; if ( ! HBS :: isEqual ( InpRC , B , RC , <NUM_LIT> , W ) ) continue ; Out . Reg = R ; Out . Sub = <NUM_LIT> ; return true ; } if ( W * <NUM_LIT> != RW ) continue ; if ( MRI . getRegClass ( R ) != & <STR_LIT> ) continue ; if ( HBS :: isEqual ( InpRC , B , RC , <NUM_LIT> , W ) ) Out . Sub = <STR_LIT> ;

else if ( HBS :: isEqual ( InpRC , B , RC , W , W ) ) Out . Sub = <STR_LIT> ;


<s> if ( ! HBS :: isTransparentCopy ( R , Inp , MRI ) ) continue ; if ( ! HBS :: isEqual ( InpRC , B , RC , <NUM_LIT> , W ) ) continue ; Out . Reg = R ; Out . Sub = <NUM_LIT> ; return true ; } if ( W * <NUM_LIT> != RW ) continue ; if ( MRI . getRegClass ( R ) != & <STR_LIT> ) continue ; if ( HBS :: isEqual ( InpRC , B , RC , <NUM_LIT> , W ) ) Out . Sub = <STR_LIT> ; else if ( HBS :: isEqual ( InpRC , B , RC , W , W ) ) Out . Sub = <STR_LIT> ; else continue ;


<s> if ( ! BT . has ( S ) ) continue ; const BitTracker :: RegisterCell & SC = BT . lookup ( S ) ; if ( SC . width ( ) != W || ctlz ( SC ) != W - Z ) continue ; const BitTracker :: BitValue & S0 = SC [ <NUM_LIT> ] ; if ( S0 . Type != BitTracker :: BitValue :: Ref || S0 . RefI . Reg != SrcR ) continue ; unsigned P = S0 . RefI . Pos ; if ( Pos <= P && ( Pos + W - Z ) != P ) continue ; if ( P < Pos && ( P + Z ) != Pos ) continue ; if ( std :: min ( P , Pos ) != <NUM_LIT> && std :: min ( P , Pos ) != <NUM_LIT> ) continue ; unsigned I ; for ( I = <NUM_LIT> ; I < Z ; ++ I ) { const BitTracker :: BitValue & V = SC [ I ] ; if ( V . Type != BitTracker :: BitValue :: Ref ) break ; if ( V . RefI . Reg != SrcR || V . RefI . Pos != P + I ) break ; } if ( I != Z ) continue ; if ( MaxBitSplit . getNumOccurrences ( ) ) CountBitSplit ++ ; MachineInstr * DefS = MRI . getVRegDef ( S ) ; assert ( DefS != nullptr ) ; DebugLoc DL = DefS -> getDebugLoc ( ) ; MachineBasicBlock & B = * DefS -> getParent ( ) ; auto At = DefS -> isPHI ( ) ? B . getFirstNonPHI ( ) : MachineBasicBlock :: iterator ( DefS ) ; if ( MRI . getRegClass ( SrcR ) -> getID ( ) == <STR_LIT> ) SrcSR = ( std :: min ( Pos , P ) == <NUM_LIT> ) ? <STR_LIT> : <STR_LIT> ; if ( ! validateReg ( { SrcR , SrcSR } , <STR_LIT> , <NUM_LIT> ) ) continue ; unsigned ImmOp = Pos <= P ? W - Z : Z ; unsigned NewR = <NUM_LIT> ; for ( MachineInstr * In : NewMIs ) { if ( In -> getOpcode ( ) != <STR_LIT> ) continue ; MachineOperand & Op1 = In -> getOperand ( <NUM_LIT> ) ; if ( Op1 . getReg ( ) != SrcR || Op1 . getSubReg ( ) != SrcSR ) continue ; if ( In -> getOperand ( <NUM_LIT> ) . getImm ( ) != ImmOp ) continue ; MachineOperand & Op0 = In -> getOperand ( <NUM_LIT> ) ; MachineInstr * DefI = MRI . getVRegDef ( Op0 . getReg ( ) ) ; assert ( DefI != nullptr ) ; if ( ! MDT . dominates ( DefI , & * At ) ) continue ; assert ( Op0 . getSubReg ( ) == <NUM_LIT> ) ;


<s> unsigned Opc = MI -> getOpcode ( ) ; unsigned COpc = getCombineOpcode ( H . Low , L . Low ) ; if ( COpc == Opc ) return false ; if ( ! validateReg ( H , COpc , <NUM_LIT> ) || ! validateReg ( L , COpc , <NUM_LIT> ) ) return false ; MachineBasicBlock & B = * MI -> getParent ( ) ; DebugLoc DL = MI -> getDebugLoc ( ) ; Register NewR = MRI . createVirtualRegister ( & <STR_LIT> ) ; auto At = MI -> isPHI ( ) ? B . getFirstNonPHI ( ) : MachineBasicBlock :: iterator ( MI ) ; BuildMI ( B , At , DL , HII . get ( COpc ) , NewR ) . addReg ( H . Reg , <NUM_LIT> , H . Sub ) . addReg ( L . Reg , <NUM_LIT> , L . Sub ) ;


<s> if ( ! HBS :: getSubregMask ( RS , BN , BW , MRI ) ) continue ; if ( BW < W || ! HBS :: isEqual ( RC , <NUM_LIT> , SC , BN , W ) ) continue ; if ( ! validateReg ( RS , NewOpc , <NUM_LIT> ) ) continue ; Register NewR = MRI . createVirtualRegister ( & <STR_LIT> ) ; auto At = MI -> isPHI ( ) ? B . getFirstNonPHI ( ) : MachineBasicBlock :: iterator ( MI ) ; auto MIB = BuildMI ( B , At , DL , HII . get ( NewOpc ) , NewR ) . addReg ( RS . Reg , <NUM_LIT> , RS . Sub ) ; if ( NewOpc == <STR_LIT> ) MIB . addImm ( ( <NUM_LIT> << W ) - <NUM_LIT> ) ; else if ( NewOpc == <STR_LIT> ) MIB . addImm ( W ) . addImm ( <NUM_LIT> ) ; HBS :: replaceSubWithSub ( RD . Reg , RD . Sub , NewR , <NUM_LIT> , MRI ) ;


<s> if ( ! validateReg ( Rs , <STR_LIT> , <NUM_LIT> ) || ! validateReg ( Rt , <STR_LIT> , <NUM_LIT> ) ) return false ; MachineBasicBlock & B = * MI -> getParent ( ) ; Register NewR = MRI . createVirtualRegister ( & <STR_LIT> ) ; DebugLoc DL = MI -> getDebugLoc ( ) ; auto At = MI -> isPHI ( ) ? B . getFirstNonPHI ( ) : MachineBasicBlock :: iterator ( MI ) ; BuildMI ( B , At , DL , HII . get ( <STR_LIT> ) , NewR ) . addReg ( Rs . Reg , <NUM_LIT> , Rs . Sub ) . addReg ( Rt . Reg , <NUM_LIT> , Rt . Sub ) ; HBS :: replaceSubWithSub ( RD . Reg , RD . Sub , NewR , <NUM_LIT> , MRI ) ; BT . put ( BitTracker :: RegisterRef ( NewR ) , RC ) ;


<s> case <STR_LIT> : Align ++ ; LLVM_FALLTHROUGH ; case <STR_LIT> : break ; default : return false ; } if ( ! MI -> getOperand ( <NUM_LIT> ) . isReg ( ) ) return false ; MachineOperand & OffOp = MI -> getOperand ( <NUM_LIT> ) ; if ( ! OffOp . isImm ( ) ) return false ; int64_t Off = OffOp . getImm ( ) ; if ( ! isUIntN ( <NUM_LIT> + Align , Off ) || ( Off & ( ( <NUM_LIT> << Align ) - <NUM_LIT> ) ) ) return false ; BitTracker :: RegisterRef RS = MI -> getOperand ( <NUM_LIT> ) ; if ( ! BT . has ( RS . Reg ) ) return false ; const BitTracker :: RegisterCell & RC = BT . lookup ( RS . Reg ) ; uint64_t U ; if ( ! HBS :: getConst ( RC , <NUM_LIT> , RC . width ( ) , U ) ) return false ; int V ; switch ( Opc ) { case <STR_LIT> : V = int8_t ( U ) ; break ; case <STR_LIT> : V = int16_t ( U ) ; break ; case <STR_LIT> : V = int32_t ( U ) ; break ; default : llvm_unreachable ( <STR_LIT> ) ; }

if ( ! isInt < <NUM_LIT> > ( V ) ) return false ;


<s> BitTracker :: RegisterRef RS = MI -> getOperand ( <NUM_LIT> ) ; if ( ! BT . has ( RS . Reg ) ) return false ; const BitTracker :: RegisterCell & RC = BT . lookup ( RS . Reg ) ; uint64_t U ; if ( ! HBS :: getConst ( RC , <NUM_LIT> , RC . width ( ) , U ) ) return false ; int V ; switch ( Opc ) { case <STR_LIT> : V = int8_t ( U ) ; break ; case <STR_LIT> : V = int16_t ( U ) ; break ; case <STR_LIT> : V = int32_t ( U ) ; break ; default : llvm_unreachable ( <STR_LIT> ) ; } if ( ! isInt < <NUM_LIT> > ( V ) ) return false ;


<s> BuildMI ( B , At , DL , HII . get ( Opc ) , Reg ) . addImm ( int32_t ( Hi ) ) . addImm ( int32_t ( Lo ) ) ; return Reg ; } MachineFunction * MF = B . getParent ( ) ; auto & HST = MF -> getSubtarget < <ISA_LIT>Subtarget > ( ) ; if ( ! HST . isTinyCore ( ) || MF -> getFunction ( ) . hasOptSize ( ) ) { BuildMI ( B , At , DL , HII . get ( <STR_LIT> ) , Reg ) . addImm ( C ) ; return Reg ; } } if ( RC == & <STR_LIT> ) { unsigned Opc ; if ( C == <NUM_LIT> ) Opc = <STR_LIT> ; else if ( ( C & <NUM_LIT> ) == <NUM_LIT> ) Opc = <STR_LIT> ; else return <NUM_LIT> ; BuildMI ( B , At , DL , HII . get ( Opc ) , Reg ) ; return Reg ; } return <NUM_LIT> ;


<s> Register R = Op . getReg ( ) ; if ( ! R . isVirtual ( ) ) continue ; Defs . insert ( R ) ; }


<s> Register R = Op . getReg ( ) ; if ( ! R . isVirtual ( ) ) continue ; Defs . insert ( R ) ;


<s> if ( ! Op . isReg ( ) || ! Op . isUse ( ) ) continue ;


<s> Register R = Op . getReg ( ) ; if ( ! R . isVirtual ( ) ) continue ; Uses . insert ( R ) ;


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


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


<s> case TargetOpcode :: COPY : case TargetOpcode :: REG_SEQUENCE : case <STR_LIT> : case <STR_LIT> : return true ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : return NoConv ; default :


<s> case TargetOpcode :: REG_SEQUENCE : case <STR_LIT> : case <STR_LIT> : return true ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : return NoConv ; default : break ; } return false ;


<s> if ( UseI -> isDebugValue ( ) ) continue ; if ( UseI -> isPHI ( ) ) { assert ( ! UseI -> getOperand ( <NUM_LIT> ) . getSubReg ( ) ) ; Register DR = UseI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; if ( DR == R ) continue ;


<s> bool DeadCodeElimination :: isDead ( unsigned R ) const { for ( auto I = MRI . use_begin ( R ) , E = MRI . use_end ( ) ; I != E ; ++ I ) {

MachineInstr * UseI = I -> getParent ( ) ;


<s> auto * DRC = getFinalVRegClass ( RD , MRI ) ; if ( ! DRC ) return false ;

return DRC == getFinalVRegClass ( RS , MRI ) ;


<s> if ( I == B + <NUM_LIT> ) return false ; Register Reg = RC [ I ] . RefI . Reg ; unsigned P = RC [ I ] . RefI . Pos ; if ( P < I - B ) return false ; unsigned Pos = P - ( I - B ) ; if ( Reg == <NUM_LIT> || Reg == SelfR ) return false ; if ( ! Reg . isVirtual ( ) ) return false ; if ( ! BT . has ( Reg ) ) return false ; const BitTracker :: RegisterCell & SC = BT . lookup ( Reg ) ; if ( Pos + <NUM_LIT> > SC . width ( ) ) return false ; for ( unsigned i = <NUM_LIT> ; i < <NUM_LIT> ; ++ i ) { const BitTracker :: BitValue & RV = RC [ i + B ] ; if ( RV . Type == BitTracker :: BitValue :: Ref ) { if ( RV . RefI . Reg != Reg ) return false ; if ( RV . RefI . Pos != i + Pos ) return false ; continue ; }

if ( RC [ i + B ] != SC [ i + Pos ] ) return false ;


<s> bool Low = false ; unsigned I = B ; while ( I < B + <NUM_LIT> && RC [ I ] . num ( ) ) I ++ ; if ( I == B + <NUM_LIT> ) return false ; Register Reg = RC [ I ] . RefI . Reg ; unsigned P = RC [ I ] . RefI . Pos ; if ( P < I - B ) return false ; unsigned Pos = P - ( I - B ) ; if ( Reg == <NUM_LIT> || Reg == SelfR ) return false ; if ( ! Reg . isVirtual ( ) ) return false ; if ( ! BT . has ( Reg ) ) return false ; const BitTracker :: RegisterCell & SC = BT . lookup ( Reg ) ; if ( Pos + <NUM_LIT> > SC . width ( ) ) return false ; for ( unsigned i = <NUM_LIT> ; i < <NUM_LIT> ; ++ i ) { const BitTracker :: BitValue & RV = RC [ i + B ] ; if ( RV . Type == BitTracker :: BitValue :: Ref ) { if ( RV . RefI . Reg != Reg ) return false ; if ( RV . RefI . Pos != i + Pos ) return false ; continue ; } if ( RC [ i + B ] != SC [ i + Pos ] ) return false ; } unsigned Sub = <NUM_LIT> ; switch ( Pos ) { case <NUM_LIT> : Sub = <STR_LIT> ; Low = true ; break ; case <NUM_LIT> : Sub = <STR_LIT> ; Low = false ; break ; case <NUM_LIT> : Sub = <STR_LIT> ; Low = true ; break ; case <NUM_LIT> : Sub = <STR_LIT> ; Low = false ; break ; default : return false ; } RH . Reg = Reg ; RH . Sub = Sub ; RH . Low = Low ;

if ( ! HBS :: getFinalVRegClass ( RH , MRI ) ) RH . Sub = <NUM_LIT> ;


<s> BuildMI ( LB , At , At -> getDebugLoc ( ) , HII -> get ( TargetOpcode :: PHI ) , PhiR ) . addReg ( NewPredR ) . addMBB ( & PB ) . addReg ( G . Inp . Reg ) . addMBB ( & LB ) ; RegMap . insert ( std :: make_pair ( G . Inp . Reg , PhiR ) ) ; for ( unsigned i = G . Ins . size ( ) ; i > <NUM_LIT> ; -- i ) { const MachineInstr * SI = G . Ins [ i - <NUM_LIT> ] ; unsigned DR = getDefReg ( SI ) ; const TargetRegisterClass * RC = MRI -> getRegClass ( DR ) ; Register NewDR = MRI -> createVirtualRegister ( RC ) ; DebugLoc DL = SI -> getDebugLoc ( ) ; auto MIB = BuildMI ( LB , At , DL , HII -> get ( SI -> getOpcode ( ) ) , NewDR ) ; for ( unsigned j = <NUM_LIT> , m = SI -> getNumOperands ( ) ; j < m ; ++ j ) { const MachineOperand & Op = SI -> getOperand ( j ) ; if ( ! Op . isReg ( ) ) { MIB . add ( Op ) ; continue ;


<s> void <ISA_LIT>LoopRescheduling :: moveGroup ( InstrGroup & G , MachineBasicBlock & LB , MachineBasicBlock & PB , MachineBasicBlock :: iterator At , unsigned OldPhiR , unsigned NewPredR ) { DenseMap < unsigned , unsigned > RegMap ; const TargetRegisterClass * PhiRC = MRI -> getRegClass ( NewPredR ) ; Register PhiR = MRI -> createVirtualRegister ( PhiRC ) ; BuildMI ( LB , At , At -> getDebugLoc ( ) , HII -> get ( TargetOpcode :: PHI ) , PhiR ) . addReg ( NewPredR ) . addMBB ( & PB ) . addReg ( G . Inp . Reg ) . addMBB ( & LB ) ; RegMap . insert ( std :: make_pair ( G . Inp . Reg , PhiR ) ) ; for ( unsigned i = G . Ins . size ( ) ; i > <NUM_LIT> ; -- i ) { const MachineInstr * SI = G . Ins [ i - <NUM_LIT> ] ; unsigned DR = getDefReg ( SI ) ; const TargetRegisterClass * RC = MRI -> getRegClass ( DR ) ; Register NewDR = MRI -> createVirtualRegister ( RC ) ; DebugLoc DL = SI -> getDebugLoc ( ) ; auto MIB = BuildMI ( LB , At , DL , HII -> get ( SI -> getOpcode ( ) ) , NewDR ) ; for ( unsigned j = <NUM_LIT> , m = SI -> getNumOperands ( ) ; j < m ; ++ j ) { const MachineOperand & Op = SI -> getOperand ( j ) ;


<s> unsigned SubLo = HRI . get<ISA_LIT>SubRegIndex ( DstRC , <STR_LIT> ) ; unsigned SubHi = HRI . get<ISA_LIT>SubRegIndex ( DstRC , <STR_LIT> ) ; assert ( ( Sub1 == SubLo && Sub2 == SubHi ) || ( Sub1 == SubHi && Sub2 == SubLo ) ) ; if ( Sub1 == SubLo && Sub2 == SubHi ) { SL = I . getOperand ( <NUM_LIT> ) ; SH = I . getOperand ( <NUM_LIT> ) ; return true ; } if ( Sub1 == SubHi && Sub2 == SubLo ) { SH = I . getOperand ( <NUM_LIT> ) ; SL = I . getOperand ( <NUM_LIT> ) ;


<s> if ( ! Op0 . isReg ( ) || ! Op0 . isDef ( ) ) continue ; BitTracker :: RegisterRef RD = Op0 ; if ( ! BT . has ( RD . Reg ) ) continue ; const TargetRegisterClass * FRC = HBS :: getFinalVRegClass ( RD , MRI ) ; const BitTracker :: RegisterCell & RC = BT . lookup ( RD . Reg ) ; if ( FRC -> getID ( ) == <STR_LIT> ) { bool T = genPackhl ( MI , RD , RC ) ; T = T || simplifyExtractLow ( MI , RD , RC , AVB ) ; Changed |= T ; continue ; } if ( FRC -> getID ( ) == <STR_LIT> ) { bool T = genBitSplit ( MI , RD , RC , AVB ) ; T = T || simplifyExtractLow ( MI , RD , RC , AVB ) ; T = T || genExtractHalf ( MI , RD , RC ) ; T = T || genCombineHalf ( MI , RD , RC ) ; T = T || genExtractLow ( MI , RD , RC ) ;


<s> bool <ISA_LIT>BitSimplify :: replaceReg ( Register OldR , Register NewR , MachineRegisterInfo & MRI ) { if ( ! OldR . isVirtual ( ) || ! NewR . isVirtual ( ) ) return false ; auto Begin = MRI . use_begin ( OldR ) , End = MRI . use_end ( ) ; decltype ( End ) NextI ;

for ( auto I = Begin ; I != End ; I = NextI ) {


<s> bool <ISA_LIT>BitSimplify :: replaceReg ( Register OldR , Register NewR , MachineRegisterInfo & MRI ) { if ( ! OldR . isVirtual ( ) || ! NewR . isVirtual ( ) ) return false ; auto Begin = MRI . use_begin ( OldR ) , End = MRI . use_end ( ) ; decltype ( End ) NextI ; for ( auto I = Begin ; I != End ; I = NextI ) { NextI = std :: next ( I ) ; I -> setReg ( NewR ) ; } return Begin != End ;


<s> if ( hasTiedUse ( OldR , MRI , NewSR ) ) return false ; auto Begin = MRI . use_begin ( OldR ) , End = MRI . use_end ( ) ; decltype ( End ) NextI ; for ( auto I = Begin ; I != End ; I = NextI ) {


<s> bool <ISA_LIT>BitSimplify :: replaceSubWithSub ( Register OldR , unsigned OldSR , Register NewR , unsigned NewSR , MachineRegisterInfo & MRI ) { if ( ! OldR . isVirtual ( ) || ! NewR . isVirtual ( ) ) return false ; if ( OldSR != NewSR && hasTiedUse ( OldR , MRI , NewSR ) ) return false ; auto Begin = MRI . use_begin ( OldR ) , End = MRI . use_end ( ) ; decltype ( End ) NextI ; for ( auto I = Begin ; I != End ; I = NextI ) { NextI = std :: next ( I ) ; if ( I -> getSubReg ( ) != OldSR ) continue ;


<s> for ( auto I = Begin ; I != End ; I = NextI ) { NextI = std :: next ( I ) ; if ( I -> getSubReg ( ) != OldSR ) continue ; I -> setReg ( NewR ) ; I -> setSubReg ( NewSR ) ; } return Begin != End ;


<s> auto & HRI = * HST . getRegisterInfo ( ) ; auto & HII = * HST . getInstrInfo ( ) ; MDT = & getAnalysis < MachineDominatorTree > ( ) ; MachineRegisterInfo & MRI = MF . getRegInfo ( ) ; bool Changed ; Changed = DeadCodeElimination ( MF , * MDT ) . run ( ) ; const <ISA_LIT>Evaluator HE ( HRI , MRI , HII , MF ) ; BitTracker BT ( HE , MF ) ; LLVM_DEBUG ( BT . trace ( true ) ) ; BT . run ( ) ; MachineBasicBlock & Entry = MF . front ( ) ; RegisterSet AIG ;

ConstGeneration ImmG ( BT , HII , MRI ) ;


<s> bool DeadCodeElimination :: runOnNode ( MachineDomTreeNode * N ) { bool Changed = false ; for ( auto * DTN : children < MachineDomTreeNode * > ( N ) ) Changed |= runOnNode ( 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 MI : Instrs ) { unsigned Opc = MI -> getOpcode ( ) ; if ( Opc == TargetOpcode :: LIFETIME_START || Opc == TargetOpcode :: LIFETIME_END ) continue ; bool Store = false ; if ( MI -> isInlineAsm ( ) ) continue ;

if ( ! MI -> isPHI ( ) && ! MI -> isSafeToMove ( nullptr , Store ) ) continue ;


<s> BitTracker :: RegisterCell NewRC ( W ) ; for ( uint16_t I = <NUM_LIT> ; I != W ; ++ I ) { NewRC [ I ] = BitTracker :: BitValue ( C & <NUM_LIT> ) ; C = unsigned ( C ) >> <NUM_LIT> ; } BT . put ( BitTracker :: RegisterRef ( NewR ) , NewRC ) ; return true ; } ; auto IsNonZero = [ ] ( const MachineOperand & Op ) { if ( Op . isGlobal ( ) || Op . isBlockAddress ( ) ) return true ; if ( Op . isImm ( ) ) return Op . getImm ( ) != <NUM_LIT> ; if ( Op . isCImm ( ) ) return ! Op . getCImm ( ) -> isZero ( ) ; if ( Op . isFPImm ( ) ) return ! Op . getFPImm ( ) -> isZero ( ) ; return false ; } ; auto IsZero = [ ] ( const MachineOperand & Op ) { if ( Op . isGlobal ( ) || Op . isBlockAddress ( ) ) return false ; if ( Op . isImm ( ) ) return Op . getImm ( ) == <NUM_LIT> ; if ( Op . isCImm ( ) ) return Op . getCImm ( ) -> isZero ( ) ; if ( Op . isFPImm ( ) ) return Op . getFPImm ( ) -> isZero ( ) ; return false ; } ; if ( KnownZ || KnownNZ ) { assert ( KnownZ != KnownNZ && <STR_LIT> ) ; return ReplaceWithConst ( KnownZ == ( Opc == <STR_LIT> ) ) ; } MachineInstr * InpDef = MRI . getVRegDef ( SR . Reg ) ; if ( ! InpDef ) return false ; if ( SR . Sub == <NUM_LIT> && InpDef -> getOpcode ( ) == <STR_LIT> ) { MachineOperand & Src1 = InpDef -> getOperand ( <NUM_LIT> ) ; MachineOperand & Src2 = InpDef -> getOperand ( <NUM_LIT> ) ; bool KnownNZ1 = IsNonZero ( Src1 ) , KnownNZ2 = IsNonZero ( Src2 ) ; if ( KnownNZ1 && KnownNZ2 ) return ReplaceWithConst ( Opc == <STR_LIT> ) ; bool KnownZ1 = IsZero ( Src1 ) , KnownZ2 = IsZero ( Src2 ) ; if ( KnownZ1 && KnownZ2 ) return ReplaceWithConst ( Opc == <STR_LIT> ) ;

if ( ( KnownZ1 || KnownNZ1 ) && ( KnownZ2 || KnownNZ2 ) ) {


<s> NewRC [ I ] = BitTracker :: BitValue ( C & <NUM_LIT> ) ; C = unsigned ( C ) >> <NUM_LIT> ; } BT . put ( BitTracker :: RegisterRef ( NewR ) , NewRC ) ; return true ; } ; auto IsNonZero = [ ] ( const MachineOperand & Op ) { if ( Op . isGlobal ( ) || Op . isBlockAddress ( ) ) return true ; if ( Op . isImm ( ) ) return Op . getImm ( ) != <NUM_LIT> ; if ( Op . isCImm ( ) ) return ! Op . getCImm ( ) -> isZero ( ) ; if ( Op . isFPImm ( ) ) return ! Op . getFPImm ( ) -> isZero ( ) ; return false ; } ; auto IsZero = [ ] ( const MachineOperand & Op ) { if ( Op . isGlobal ( ) || Op . isBlockAddress ( ) ) return false ; if ( Op . isImm ( ) ) return Op . getImm ( ) == <NUM_LIT> ; if ( Op . isCImm ( ) ) return Op . getCImm ( ) -> isZero ( ) ; if ( Op . isFPImm ( ) ) return Op . getFPImm ( ) -> isZero ( ) ; return false ; } ; if ( KnownZ || KnownNZ ) { assert ( KnownZ != KnownNZ && <STR_LIT> ) ; return ReplaceWithConst ( KnownZ == ( Opc == <STR_LIT> ) ) ; } MachineInstr * InpDef = MRI . getVRegDef ( SR . Reg ) ; if ( ! InpDef ) return false ; if ( SR . Sub == <NUM_LIT> && InpDef -> getOpcode ( ) == <STR_LIT> ) { MachineOperand & Src1 = InpDef -> getOperand ( <NUM_LIT> ) ; MachineOperand & Src2 = InpDef -> getOperand ( <NUM_LIT> ) ; bool KnownNZ1 = IsNonZero ( Src1 ) , KnownNZ2 = IsNonZero ( Src2 ) ; if ( KnownNZ1 && KnownNZ2 ) return ReplaceWithConst ( Opc == <STR_LIT> ) ; bool KnownZ1 = IsZero ( Src1 ) , KnownZ2 = IsZero ( Src2 ) ; if ( KnownZ1 && KnownZ2 ) return ReplaceWithConst ( Opc == <STR_LIT> ) ; if ( ( KnownZ1 || KnownNZ1 ) && ( KnownZ2 || KnownNZ2 ) ) { Register NewR = MRI . createVirtualRegister ( FRC ) ; BuildMI ( B , At , DL , HII . get ( <STR_LIT> ) , NewR ) . addReg ( InpDef -> getOperand ( <NUM_LIT> ) . getReg ( ) ) . addImm ( KnownZ1 == ( Opc == <STR_LIT> ) ) . addImm ( KnownZ2 == ( Opc == <STR_LIT> ) ) ;

HBS :: replaceReg ( RD . Reg , NewR , MRI ) ;


<s> static inline unsigned v2x ( unsigned v ) {

return Register :: virtReg2Index ( v ) ;


<s> static inline unsigned x2v ( unsigned x ) { return Register :: index2VirtReg ( x ) ;


<s> bool <ISA_LIT>Evaluator :: evaluate ( const MachineInstr * BI , const CellMapType & Inputs , BranchTargetList & Targets , bool & FallsThru ) const { unsigned Opc = BI -> getOpcode ( ) ; bool SimpleBranch = false ; bool Negated = false ; switch ( Opc ) { case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : Negated = true ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : SimpleBranch = true ; break ; case <STR_LIT> : Targets . insert ( BI -> getOperand ( <NUM_LIT> ) . getMBB ( ) ) ; FallsThru = false ;


<s> assert ( MI -> isCopy ( ) ) ; RegisterRef RD = MI -> getOperand ( <NUM_LIT> ) ; RegisterRef RS = MI -> getOperand ( <NUM_LIT> ) ; assert ( RD . Sub == <NUM_LIT> ) ; if ( ! TargetRegisterInfo :: isPhysicalRegister ( RS . Reg ) ) return false ; RegExtMap :: const_iterator F = VRX . find ( RD . Reg ) ; if ( F == VRX . end ( ) ) return false ; uint16_t EW = F -> second . Width ; putCell ( RD , getCell ( RS , Inputs ) , Outputs ) ; RegisterCell Res ; if ( F -> second . Type == ExtType :: SExt ) Res = eSXT ( getCell ( RD , Outputs ) , EW ) ; else if ( F -> second . Type == ExtType :: ZExt ) Res = eZXT ( getCell ( RD , Outputs ) , EW ) ; putCell ( RD , Res , Outputs ) ; return true ;


<s> RegisterRef RS = MI -> getOperand ( <NUM_LIT> ) ; assert ( RD . Sub == <NUM_LIT> ) ; if ( ! TargetRegisterInfo :: isPhysicalRegister ( RS . Reg ) ) return false ; RegExtMap :: const_iterator F = VRX . find ( RD . Reg ) ;

if ( F == VRX . end ( ) ) return false ;


<s> case L2_loadrub_io : case L2_loadrub_pbr : case L2_loadrub_pci : case L2_loadrub_pcr : case L2_loadrub_pi : case L4_loadrub_abs : case L4_loadrub_ap : case L4_loadrub_rr : case L4_loadrub_ur : BitNum = <NUM_LIT> ; SignEx = false ; break ; case L2_loadrhgp : case L2_loadrh_io : case L2_loadrh_pbr : case L2_loadrh_pci : case L2_loadrh_pcr : case L2_loadrh_pi : case L4_loadrh_abs : case L4_loadrh_ap : case L4_loadrh_rr : case L4_loadrh_ur : BitNum = <NUM_LIT> ; SignEx = true ; break ; case L2_loadruhgp : case L2_loadruh_io : case L2_loadruh_pbr : case L2_loadruh_pci : case L2_loadruh_pcr : case L2_loadruh_pi : case L4_loadruh_rr : case L4_loadruh_abs : case L4_loadruh_ap : case L4_loadruh_ur : BitNum = <NUM_LIT> ; SignEx = false ; break ; case L2_loadrigp : case L2_loadri_io : case L2_loadri_pbr : case L2_loadri_pci : case L2_loadri_pcr : case L2_loadri_pi : case L2_loadw_locked : case L4_loadri_abs : case L4_loadri_ap : case L4_loadri_rr : case L4_loadri_ur : case LDriw_pred : BitNum = <NUM_LIT> ; SignEx = true ; break ; case L2_loadrdgp : case L2_loadrd_io : case L2_loadrd_pbr : case L2_loadrd_pci : case L2_loadrd_pcr : case L2_loadrd_pi : case L4_loadd_locked : case L4_loadrd_abs :


<s> const unsigned Num64 = sizeof ( Phys64 ) / sizeof ( unsigned ) ; if ( PReg == <NUM_LIT> ) return ( Width <= <NUM_LIT> ) ? Phys32 [ <NUM_LIT> ] : Phys64 [ <NUM_LIT> ] ; unsigned Idx32 = <NUM_LIT> , Idx64 = <NUM_LIT> ; if ( ! Is64 ) { while ( Idx32 < Num32 ) { if ( Phys32 [ Idx32 ] == PReg ) break ; Idx32 ++ ; } Idx64 = Idx32 / <NUM_LIT> ; } else { while ( Idx64 < Num64 ) { if ( Phys64 [ Idx64 ] == PReg ) break ; Idx64 ++ ; } Idx32 = Idx64 * <NUM_LIT> + <NUM_LIT> ; }


<s> unsigned Width = <NUM_LIT> ; if ( ATy -> isIntegerTy ( ) ) Width = ATy -> getIntegerBitWidth ( ) ; else if ( ATy -> isPointerTy ( ) ) Width = <NUM_LIT> ; if ( Width == <NUM_LIT> || Width > <NUM_LIT> ) break ; InPhysReg = getNextPhysReg ( InPhysReg , Width ) ; if ( ! InPhysReg ) break ; InVirtReg = getVirtRegFor ( InPhysReg ) ; if ( ! InVirtReg ) continue ; AttributeSet Attrs = F . getAttributes ( ) ; if ( Attrs . hasAttribute ( AttrIdx , Attribute :: SExt ) ) VRX . insert ( std :: make_pair ( InVirtReg , ExtType ( ExtType :: SExt , Width ) ) ) ; else if ( Attrs . hasAttribute ( AttrIdx , Attribute :: ZExt ) ) VRX . insert ( std :: make_pair ( InVirtReg , ExtType ( ExtType :: ZExt , Width ) ) ) ; }


<s> using namespace <ISA_LIT> ; const TargetRegisterClass * RC = MRI . getRegClass ( Reg ) ; unsigned ID = RC -> getID ( ) ; uint16_t RW = getRegBitWidth ( RegisterRef ( Reg , Sub ) ) ; switch ( ID ) { case DoubleRegsRegClassID : case VecDblRegsRegClassID : case VecDblRegs128BRegClassID :

return ( Sub == subreg_loreg ) ? BT :: BitMask ( <NUM_LIT> , RW - <NUM_LIT> ) : BT :: BitMask ( RW , <NUM_LIT> * RW - <NUM_LIT> ) ;


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

if ( MO . isReg ( ) ) Vector [ i ] = BT :: RegisterRef ( MO ) ;


<s> default : return false ; } if ( ! SimpleBranch ) return false ; RegisterRef PR = BI . getOperand ( <NUM_LIT> ) ; RegisterCell PC = getCell ( PR , Inputs ) ; const BT :: BitValue & Test = PC [ <NUM_LIT> ] ; if ( ! Test . is ( <NUM_LIT> ) && ! Test . is ( <NUM_LIT> ) ) return false ; if ( ! Test . is ( ! Negated ) ) { FallsThru = true ; return true ; } Targets . insert ( BI . getOperand ( <NUM_LIT> ) . getMBB ( ) ) ; FallsThru = false ; return true ;


<s> case L2_loadbzw4_pcr : case L2_loadbzw4_pi : case L2_loadrbgp : case L2_loadrb_io : case L2_loadrb_pbr : case L2_loadrb_pci : case L2_loadrb_pcr : case L2_loadrb_pi : case PS_loadrbabs : case L4_loadrb_ap : case L4_loadrb_rr : case L4_loadrb_ur : BitNum = <NUM_LIT> ; SignEx = true ; break ; case L2_loadrubgp : case L2_loadrub_io : case L2_loadrub_pbr : case L2_loadrub_pci : case L2_loadrub_pcr : case L2_loadrub_pi : case PS_loadrubabs : case L4_loadrub_ap : case L4_loadrub_rr : case L4_loadrub_ur : BitNum = <NUM_LIT> ; SignEx = false ; break ; case L2_loadrhgp : case L2_loadrh_io : case L2_loadrh_pbr : case L2_loadrh_pci : case L2_loadrh_pcr : case L2_loadrh_pi : case PS_loadrhabs : case L4_loadrh_ap : case L4_loadrh_rr : case L4_loadrh_ur : BitNum = <NUM_LIT> ; SignEx = true ; break ; case L2_loadruhgp : case L2_loadruh_io : case L2_loadruh_pbr : case L2_loadruh_pci : case L2_loadruh_pcr : case L2_loadruh_pi : case L4_loadruh_rr : case PS_loadruhabs : case L4_loadruh_ap : case L4_loadruh_ur : BitNum = <NUM_LIT> ; SignEx = false ; break ; case L2_loadrigp : case L2_loadri_io : case L2_loadri_pbr : case L2_loadri_pci : case L2_loadri_pcr : case L2_loadri_pi : case L2_loadw_locked : case PS_loadriabs : case L4_loadri_ap : case L4_loadri_rr : case L4_loadri_ur : case LDriw_pred : BitNum = <NUM_LIT> ; SignEx = true ; break ; case L2_loadrdgp : case L2_loadrd_io : case L2_loadrd_pbr : case L2_loadrd_pci : case L2_loadrd_pcr : case L2_loadrd_pi : case L4_loadd_locked : case PS_loadrdabs : case L4_loadrd_ap : case L4_loadrd_rr : case L4_loadrd_ur : BitNum = <NUM_LIT> ; SignEx = true ; break ; } const MachineOperand & MD = MI . getOperand ( <NUM_LIT> ) ; assert ( MD . isReg ( ) && MD . isDef ( ) ) ; RegisterRef RD = MD ; uint16_t W = getRegBitWidth ( RD ) ; assert ( W >= BitNum && BitNum > <NUM_LIT> ) ; RegisterCell Res ( W ) ; for ( uint16_t i = <NUM_LIT> ; i < BitNum ; ++ i ) Res [ i ] = BT :: BitValue :: self ( BT :: BitRef ( RD . Reg , i ) ) ; if ( SignEx ) { const BT :: BitValue & Sign = Res [ BitNum - <NUM_LIT> ] ; for ( uint16_t i = BitNum ; i < W ; ++ i ) Res [ i ] = BT :: BitValue :: ref ( Sign ) ;


<s> typedef Function :: const_arg_iterator arg_iterator ; for ( arg_iterator I = F . arg_begin ( ) , E = F . arg_end ( ) ; I != E ; ++ I ) { const Argument & Arg = * I ; Type * ATy = Arg . getType ( ) ; unsigned Width = <NUM_LIT> ; if ( ATy -> isIntegerTy ( ) ) Width = ATy -> getIntegerBitWidth ( ) ; else if ( ATy -> isPointerTy ( ) ) Width = <NUM_LIT> ; if ( Width == <NUM_LIT> || Width > <NUM_LIT> ) break ; if ( Arg . hasAttribute ( Attribute :: ByVal ) ) continue ; InPhysReg = getNextPhysReg ( InPhysReg , Width ) ; if ( ! InPhysReg ) break ;

InVirtReg = getVirtRegFor ( InPhysReg ) ;


<s> Type * ATy = Arg . getType ( ) ; unsigned Width = <NUM_LIT> ; if ( ATy -> isIntegerTy ( ) ) Width = ATy -> getIntegerBitWidth ( ) ; else if ( ATy -> isPointerTy ( ) ) Width = <NUM_LIT> ; if ( Width == <NUM_LIT> || Width > <NUM_LIT> ) break ; if ( Arg . hasAttribute ( Attribute :: ByVal ) ) continue ; InPhysReg = getNextPhysReg ( InPhysReg , Width ) ; if ( ! InPhysReg ) break ; InVirtReg = getVirtRegFor ( InPhysReg ) ; if ( ! InVirtReg ) continue ; if ( Arg . hasAttribute ( Attribute :: SExt ) ) VRX . insert ( std :: make_pair ( InVirtReg , ExtType ( ExtType :: SExt , Width ) ) ) ; else if ( Arg . hasAttribute ( Attribute :: ZExt ) ) VRX . insert ( std :: make_pair ( InVirtReg , ExtType ( ExtType :: ZExt , Width ) ) ) ;


<s> const TargetRegisterClass * RC = MRI . getRegClass ( Reg ) ; unsigned ID = RC -> getID ( ) ; uint16_t RW = getRegBitWidth ( RegisterRef ( Reg , Sub ) ) ; auto & HRI = static_cast < const <ISA_LIT>RegisterInfo & > ( TRI ) ; bool IsSubLo = ( Sub == HRI . get<ISA_LIT>SubRegIndex ( RC , <STR_LIT> ) ) ; switch ( ID ) { case DoubleRegsRegClassID : case VecDblRegsRegClassID : case VecDblRegs128BRegClassID : return IsSubLo ? BT :: BitMask ( <NUM_LIT> , RW - <NUM_LIT> ) : BT :: BitMask ( RW , <NUM_LIT> * RW - <NUM_LIT> ) ;


<s> case <STR_LIT> : case <STR_LIT> : Negated = true ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : SimpleBranch = true ; break ; case <STR_LIT> : Targets . insert ( BI . getOperand ( <NUM_LIT> ) . getMBB ( ) ) ; FallsThru = false ; return true ; default : return false ; } if ( ! SimpleBranch ) return false ; RegisterRef PR = BI . getOperand ( <NUM_LIT> ) ; RegisterCell PC = getCell ( PR , Inputs ) ; const BT :: BitValue & Test = PC [ <NUM_LIT> ] ; if ( ! Test . is ( <NUM_LIT> ) && ! Test . is ( <NUM_LIT> ) ) return false ; if ( ! Test . is ( ! Negated ) ) { FallsThru = true ; return true ; } Targets . insert ( BI . getOperand ( <NUM_LIT> ) . getMBB ( ) ) ; FallsThru = false ;


<s> FallsThru = false ; return true ; default : return false ; } if ( ! SimpleBranch ) return false ; RegisterRef PR = BI . getOperand ( <NUM_LIT> ) ; RegisterCell PC = getCell ( PR , Inputs ) ; const BT :: BitValue & Test = PC [ <NUM_LIT> ] ; if ( ! Test . is ( <NUM_LIT> ) && ! Test . is ( <NUM_LIT> ) ) return false ;


<s> if ( Width == <NUM_LIT> || Width > <NUM_LIT> ) break ; AttributeSet Attrs = F . getAttributes ( ) ; if ( Attrs . hasAttribute ( AttrIdx , Attribute :: ByVal ) ) continue ; InPhysReg = getNextPhysReg ( InPhysReg , Width ) ; if ( ! InPhysReg ) break ; InVirtReg = getVirtRegFor ( InPhysReg ) ; if ( ! InVirtReg ) continue ;

if ( Attrs . hasAttribute ( AttrIdx , Attribute :: SExt ) ) VRX . insert ( std :: make_pair ( InVirtReg , ExtType ( ExtType :: SExt , Width ) ) ) ;


<s> assert ( MI . isCopy ( ) ) ; RegisterRef RD = MI . getOperand ( <NUM_LIT> ) ; RegisterRef RS = MI . getOperand ( <NUM_LIT> ) ; assert ( RD . Sub == <NUM_LIT> ) ; if ( ! Register :: isPhysicalRegister ( RS . Reg ) ) return false ; RegExtMap :: const_iterator F = VRX . find ( RD . Reg ) ; if ( F == VRX . end ( ) ) return false ; uint16_t EW = F -> second . Width ; putCell ( RD , getCell ( RS , Inputs ) , Outputs ) ; RegisterCell Res ; if ( F -> second . Type == ExtType :: SExt ) Res = eSXT ( getCell ( RD , Outputs ) , EW ) ; else if ( F -> second . Type == ExtType :: ZExt ) Res = eZXT ( getCell ( RD , Outputs ) , EW ) ; putCell ( RD , Res , Outputs ) ; return true ;


<s> if ( F -> second . Type == ExtType :: SExt ) Res = eSXT ( getCell ( RD , Outputs ) , EW ) ; else if ( F -> second . Type == ExtType :: ZExt ) Res = eZXT ( getCell ( RD , Outputs ) , EW ) ; putCell ( RD , Res , Outputs ) ; return true ;


for ( auto & RC : { HvxVRRegClass , HvxWRRegClass , HvxQRRegClass , HvxVQRRegClass } ) if ( RC . contains ( Reg ) ) return TRI . getRegSizeInBits ( RC ) ;


<s> const auto & HST = MF . getSubtarget < <ISA_LIT>Subtarget > ( ) ; if ( HST . useHVXOps ( ) ) { for ( auto & RC : { HvxVRRegClass , HvxWRRegClass , HvxQRRegClass , HvxVQRRegClass } ) if ( RC . contains ( Reg ) ) return TRI . getRegSizeInBits ( RC ) ; } if ( const TargetRegisterClass * RC = TRI . getMinimalPhysRegClass ( Reg ) ) return TRI . getRegSizeInBits ( * RC ) ; llvm_unreachable ( ( Twine ( <STR_LIT> ) + TRI . getName ( Reg ) ) . str ( ) . c_str ( ) ) ;


<s> Register R = Op . getReg ( ) ; if ( ! R . isVirtual ( ) ) continue ;

if ( DefReg != <NUM_LIT> ) return <NUM_LIT> ;


<s> unsigned <ISA_LIT>Evaluator :: getVirtRegFor ( unsigned PReg ) const { for ( std :: pair < unsigned , unsigned > P : MRI . liveins ( ) ) if ( P . first == PReg ) return P . second ; return <NUM_LIT> ;


<s> <ISA_LIT>Evaluator :: <ISA_LIT>Evaluator ( const <ISA_LIT>RegisterInfo & tri , MachineRegisterInfo & mri , const <ISA_LIT>InstrInfo & tii , MachineFunction & mf ) : MachineEvaluator ( tri , mri ) , MF ( mf ) , MFI ( mf . getFrameInfo ( ) ) , TII ( tii ) { unsigned InVirtReg , InPhysReg = <NUM_LIT> ;

for ( const Argument & Arg : MF . getFunction ( ) . args ( ) ) {


<s> if ( ! InVirtReg ) continue ; if ( Arg . hasAttribute ( Attribute :: SExt ) ) VRX . insert ( std :: make_pair ( InVirtReg , ExtType ( ExtType :: SExt , Width ) ) ) ; else if ( Arg . hasAttribute ( Attribute :: ZExt ) ) VRX . insert ( std :: make_pair ( InVirtReg , ExtType ( ExtType :: ZExt , Width ) ) ) ; }


<s> return IsSubLo ? BT :: BitMask ( <NUM_LIT> , RW - <NUM_LIT> ) : BT :: BitMask ( RW , <NUM_LIT> * RW - <NUM_LIT> ) ; default : break ; }

dbgs ( ) << printReg ( Reg , & TRI , Sub ) << <STR_LIT> << TRI . getRegClassName ( & RC ) << '\n' ;


<s> for ( auto & RC : { HvxVRRegClass , HvxWRRegClass , HvxQRRegClass , HvxVQRRegClass } ) if ( RC . contains ( Reg ) ) return TRI . getRegSizeInBits ( RC ) ; } if ( const TargetRegisterClass * RC = TRI . getMinimalPhysRegClass ( Reg ) ) return TRI . getRegSizeInBits ( * RC ) ; llvm_unreachable ( ( Twine ( <STR_LIT> ) + TRI . getName ( Reg ) ) . str ( ) . c_str ( ) ) ;


<s> if ( ! Register :: isVirtualRegister ( R ) ) continue ; if ( DefReg != <NUM_LIT> ) return <NUM_LIT> ; DefReg = R ; }


<s> if ( Sub == <NUM_LIT> ) return MachineEvaluator :: mask ( Reg , <NUM_LIT> ) ; const TargetRegisterClass & RC = * MRI . getRegClass ( Reg ) ; unsigned ID = RC . getID ( ) ; uint16_t RW = getRegBitWidth ( RegisterRef ( Reg , Sub ) ) ; const auto & HRI = static_cast < const <ISA_LIT>RegisterInfo & > ( TRI ) ; bool IsSubLo = ( Sub == HRI . get<ISA_LIT>SubRegIndex ( RC , <STR_LIT> ) ) ; switch ( ID ) { case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : return IsSubLo ? BT :: BitMask ( <NUM_LIT> , RW - <NUM_LIT> ) : BT :: BitMask ( RW , <NUM_LIT> * RW - <NUM_LIT> ) ; default : break ;


<s> const auto & HRI = static_cast < const <ISA_LIT>RegisterInfo & > ( TRI ) ; bool IsSubLo = ( Idx == HRI . get<ISA_LIT>SubRegIndex ( RC , <STR_LIT> ) ) ; bool IsSubHi = ( Idx == HRI . get<ISA_LIT>SubRegIndex ( RC , <STR_LIT> ) ) ; assert ( IsSubLo != IsSubHi && <STR_LIT> ) ;


<s> using namespace <ISA_LIT> ; for ( auto & RC : { HvxVRRegClass , HvxWRRegClass , HvxQRRegClass } ) if ( RC . contains ( Reg ) ) return TRI . getRegSizeInBits ( RC ) ;

if ( const TargetRegisterClass * RC = TRI . getMinimalPhysRegClass ( Reg ) ) return TRI . getRegSizeInBits ( * RC ) ;


<s> unsigned InVirtReg , InPhysReg = <NUM_LIT> ; for ( const Argument & Arg : MF . getFunction ( ) -> args ( ) ) { Type * ATy = Arg . getType ( ) ; unsigned Width = <NUM_LIT> ; if ( ATy -> isIntegerTy ( ) ) Width = ATy -> getIntegerBitWidth ( ) ; else if ( ATy -> isPointerTy ( ) ) Width = <NUM_LIT> ; if ( Width == <NUM_LIT> || Width > <NUM_LIT> ) break ; if ( Arg . hasAttribute ( Attribute :: ByVal ) ) continue ; InPhysReg = getNextPhysReg ( InPhysReg , Width ) ; if ( ! InPhysReg ) break ; InVirtReg = getVirtRegFor ( InPhysReg ) ;


<s> BT :: BitMask <ISA_LIT>Evaluator :: mask ( unsigned Reg , unsigned Sub ) const { if ( Sub == <NUM_LIT> ) return MachineEvaluator :: mask ( Reg , <NUM_LIT> ) ; const TargetRegisterClass & RC = * MRI . getRegClass ( Reg ) ; unsigned ID = RC . getID ( ) ; uint16_t RW = getRegBitWidth ( RegisterRef ( Reg , Sub ) ) ; auto & HRI = static_cast < const <ISA_LIT>RegisterInfo & > ( TRI ) ; bool IsSubLo = ( Sub == HRI . get<ISA_LIT>SubRegIndex ( RC , <STR_LIT> ) ) ;


<s> unsigned ID = RC . getID ( ) ; uint16_t RW = getRegBitWidth ( RegisterRef ( Reg , Sub ) ) ; auto & HRI = static_cast < const <ISA_LIT>RegisterInfo & > ( TRI ) ; bool IsSubLo = ( Sub == HRI . get<ISA_LIT>SubRegIndex ( RC , <STR_LIT> ) ) ; switch ( ID ) { case <STR_LIT> : case <STR_LIT> :

return IsSubLo ? BT :: BitMask ( <NUM_LIT> , RW - <NUM_LIT> ) : BT :: BitMask ( RW , <NUM_LIT> * RW - <NUM_LIT> ) ;


<s> uint16_t RW = getRegBitWidth ( RegisterRef ( Reg , Sub ) ) ; switch ( ID ) { case DoubleRegsRegClassID : return ( Sub == subreg_loreg ) ? BT :: BitMask ( <NUM_LIT> , RW - <NUM_LIT> ) : BT :: BitMask ( RW , <NUM_LIT> * RW - <NUM_LIT> ) ;


<s> RegisterRefs :: RegisterRefs ( const MachineInstr * MI ) : Base ( MI -> getNumOperands ( ) ) { for ( unsigned i = <NUM_LIT> , n = size ( ) ; i < n ; ++ i ) { const MachineOperand & MO = MI -> getOperand ( i ) ;

if ( MO . isReg ( ) ) at ( i ) = BT :: RegisterRef ( MO ) ;


<s> const TargetRegisterClass & RC = * MRI . getRegClass ( Reg ) ; unsigned ID = RC . getID ( ) ; uint16_t RW = getRegBitWidth ( RegisterRef ( Reg , Sub ) ) ; auto & HRI = static_cast < const <ISA_LIT>RegisterInfo & > ( TRI ) ; bool IsSubLo = ( Sub == HRI . get<ISA_LIT>SubRegIndex ( RC , <STR_LIT> ) ) ;


<s> BT :: BitMask <ISA_LIT>Evaluator :: mask ( unsigned Reg , unsigned Sub ) const { if ( Sub == <NUM_LIT> ) return MachineEvaluator :: mask ( Reg , <NUM_LIT> ) ; const TargetRegisterClass & RC = * MRI . getRegClass ( Reg ) ; unsigned ID = RC . getID ( ) ; uint16_t RW = getRegBitWidth ( RegisterRef ( Reg , Sub ) ) ; auto & HRI = static_cast < const <ISA_LIT>RegisterInfo & > ( TRI ) ;

bool IsSubLo = ( Sub == HRI . get<ISA_LIT>SubRegIndex ( RC , <STR_LIT> ) ) ;


<s> unsigned InVirtReg , InPhysReg = <NUM_LIT> ; const Function & F = * MF . getFunction ( ) ; typedef Function :: const_arg_iterator arg_iterator ; for ( arg_iterator I = F . arg_begin ( ) , E = F . arg_end ( ) ; I != E ; ++ I ) { AttrIdx ++ ; const Argument & Arg = * I ; Type * ATy = Arg . getType ( ) ; unsigned Width = <NUM_LIT> ; if ( ATy -> isIntegerTy ( ) ) Width = ATy -> getIntegerBitWidth ( ) ; else if ( ATy -> isPointerTy ( ) ) Width = <NUM_LIT> ; if ( Width == <NUM_LIT> || Width > <NUM_LIT> ) break ; AttributeList Attrs = F . getAttributes ( ) ; if ( Attrs . hasAttribute ( AttrIdx , Attribute :: ByVal ) ) continue ; InPhysReg = getNextPhysReg ( InPhysReg , Width ) ; if ( ! InPhysReg ) break ; InVirtReg = getVirtRegFor ( InPhysReg ) ; if ( ! InVirtReg ) continue ; if ( Attrs . hasAttribute ( AttrIdx , Attribute :: SExt ) ) VRX . insert ( std :: make_pair ( InVirtReg , ExtType ( ExtType :: SExt , Width ) ) ) ;

else if ( Attrs . hasAttribute ( AttrIdx , Attribute :: ZExt ) ) VRX . insert ( std :: make_pair ( InVirtReg , ExtType ( ExtType :: ZExt , Width ) ) ) ;


<s> AttributeList Attrs = F . getAttributes ( ) ; if ( Attrs . hasAttribute ( AttrIdx , Attribute :: ByVal ) ) continue ; InPhysReg = getNextPhysReg ( InPhysReg , Width ) ; if ( ! InPhysReg ) break ; InVirtReg = getVirtRegFor ( InPhysReg ) ; if ( ! InVirtReg ) continue ; if ( Attrs . hasAttribute ( AttrIdx , Attribute :: SExt ) ) VRX . insert ( std :: make_pair ( InVirtReg , ExtType ( ExtType :: SExt , Width ) ) ) ; else if ( Attrs . hasAttribute ( AttrIdx , Attribute :: ZExt ) ) VRX . insert ( std :: make_pair ( InVirtReg , ExtType ( ExtType :: ZExt , Width ) ) ) ; }


<s> for ( const MachineOperand & Op : MI . operands ( ) ) { if ( ! Op . isReg ( ) || ! Op . isDef ( ) ) continue ; unsigned R = Op . getReg ( ) ;

if ( ! TargetRegisterInfo :: isVirtualRegister ( R ) ) continue ;


<s> for ( const MachineOperand & Op : MI . operands ( ) ) {

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


<s> assert ( TargetRegisterInfo :: isPhysicalRegister ( Reg ) ) ; using namespace <ISA_LIT> ; const auto & HST = MF . getSubtarget < <ISA_LIT>Subtarget > ( ) ; if ( HST . useHVXOps ( ) ) { for ( auto & RC : { HvxVRRegClass , HvxWRRegClass , HvxQRRegClass , HvxVQRRegClass } ) if ( RC . contains ( Reg ) ) return TRI . getRegSizeInBits ( RC ) ; }


<s> if ( HST . useHVXOps ( ) ) { for ( auto & RC : { HvxVRRegClass , HvxWRRegClass , HvxQRRegClass , HvxVQRRegClass } ) if ( RC . contains ( Reg ) ) return TRI . getRegSizeInBits ( RC ) ;


<s> case L2_loadbsw4_pi : case L2_loadbzw2_pbr : case L2_loadbzw2_pci : case L2_loadbzw2_pcr : case L2_loadbzw2_pi : case L2_loadbzw4_pbr : case L2_loadbzw4_pci : case L2_loadbzw4_pcr : case L2_loadbzw4_pi : case L2_loadrbgp : case L2_loadrb_io : case L2_loadrb_pbr : case L2_loadrb_pci : case L2_loadrb_pcr : case L2_loadrb_pi : case L4_loadrb_abs : case L4_loadrb_ap : case L4_loadrb_rr : case L4_loadrb_ur : BitNum = <NUM_LIT> ; SignEx = true ; break ; case L2_loadrubgp : case L2_loadrub_io : case L2_loadrub_pbr : case L2_loadrub_pci : case L2_loadrub_pcr : case L2_loadrub_pi : case L4_loadrub_abs : case L4_loadrub_ap : case L4_loadrub_rr : case L4_loadrub_ur : BitNum = <NUM_LIT> ; SignEx = false ; break ; case L2_loadrhgp : case L2_loadrh_io : case L2_loadrh_pbr : case L2_loadrh_pci : case L2_loadrh_pcr : case L2_loadrh_pi : case L4_loadrh_abs : case L4_loadrh_ap : case L4_loadrh_rr : case L4_loadrh_ur : BitNum = <NUM_LIT> ; SignEx = true ; break ; case L2_loadruhgp : case L2_loadruh_io : case L2_loadruh_pbr : case L2_loadruh_pci : case L2_loadruh_pcr : case L2_loadruh_pi : case L4_loadruh_rr : case L4_loadruh_abs : case L4_loadruh_ap : case L4_loadruh_ur : BitNum = <NUM_LIT> ; SignEx = false ; break ; case L2_loadrigp : case L2_loadri_io : case L2_loadri_pbr : case L2_loadri_pci : case L2_loadri_pcr : case L2_loadri_pi : case L2_loadw_locked : case L4_loadri_abs : case L4_loadri_ap : case L4_loadri_rr : case L4_loadri_ur : case LDriw_pred : BitNum = <NUM_LIT> ; SignEx = true ; break ; case L2_loadrdgp : case L2_loadrd_io : case L2_loadrd_pbr : case L2_loadrd_pci :


<s> using iterator = MachineRegisterInfo :: livein_iterator ; for ( iterator I = MRI . livein_begin ( ) , E = MRI . livein_end ( ) ; I != E ; ++ I ) { if ( I -> first == PReg ) return I -> second ; }


<s> unsigned <ISA_LIT>Evaluator :: getVirtRegFor ( unsigned PReg ) const { using iterator = MachineRegisterInfo :: livein_iterator ; for ( iterator I = MRI . livein_begin ( ) , E = MRI . livein_end ( ) ; I != E ; ++ I ) { if ( I -> first == PReg ) return I -> second ; } return <NUM_LIT> ;


<s> Type * ATy = Arg . getType ( ) ; unsigned Width = <NUM_LIT> ; if ( ATy -> isIntegerTy ( ) ) Width = ATy -> getIntegerBitWidth ( ) ; else if ( ATy -> isPointerTy ( ) ) Width = <NUM_LIT> ; if ( Width == <NUM_LIT> || Width > <NUM_LIT> ) break ; if ( Arg . hasAttribute ( Attribute :: ByVal ) ) continue ; InPhysReg = getNextPhysReg ( InPhysReg , Width ) ; if ( ! InPhysReg ) break ; InVirtReg = getVirtRegFor ( InPhysReg ) ; if ( ! InVirtReg ) continue ; if ( Arg . hasAttribute ( Attribute :: SExt ) ) VRX . insert ( std :: make_pair ( InVirtReg , ExtType ( ExtType :: SExt , Width ) ) ) ; else if ( Arg . hasAttribute ( Attribute :: ZExt ) ) VRX . insert ( std :: make_pair ( InVirtReg , ExtType ( ExtType :: ZExt , Width ) ) ) ; }


<s> assert ( RD . Sub == <NUM_LIT> ) ; if ( ! TargetRegisterInfo :: isPhysicalRegister ( RS . Reg ) ) return false ; RegExtMap :: const_iterator F = VRX . find ( RD . Reg ) ; if ( F == VRX . end ( ) ) return false ; uint16_t EW = F -> second . Width ; putCell ( RD , getCell ( RS , Inputs ) , Outputs ) ; RegisterCell Res ; if ( F -> second . Type == ExtType :: SExt ) Res = eSXT ( getCell ( RD , Outputs ) , EW ) ; else if ( F -> second . Type == ExtType :: ZExt ) Res = eZXT ( getCell ( RD , Outputs ) , EW ) ; putCell ( RD , Res , Outputs ) ;


<s> if ( F -> second . Type == ExtType :: SExt ) Res = eSXT ( getCell ( RD , Outputs ) , EW ) ; else if ( F -> second . Type == ExtType :: ZExt ) Res = eZXT ( getCell ( RD , Outputs ) , EW ) ; putCell ( RD , Res , Outputs ) ; return true ;


<s> break ; case L2_loadrubgp : case L2_loadrub_io : case L2_loadrub_pbr : case L2_loadrub_pci : case L2_loadrub_pcr : case L2_loadrub_pi : case L4_loadrub_abs : case L4_loadrub_ap : case L4_loadrub_rr : case L4_loadrub_ur : BitNum = <NUM_LIT> ; SignEx = false ; break ; case L2_loadrhgp : case L2_loadrh_io : case L2_loadrh_pbr : case L2_loadrh_pci : case L2_loadrh_pcr : case L2_loadrh_pi : case L4_loadrh_abs : case L4_loadrh_ap : case L4_loadrh_rr : case L4_loadrh_ur : BitNum = <NUM_LIT> ; SignEx = true ; break ; case L2_loadruhgp : case L2_loadruh_io : case L2_loadruh_pbr : case L2_loadruh_pci : case L2_loadruh_pcr : case L2_loadruh_pi : case L4_loadruh_rr : case L4_loadruh_abs : case L4_loadruh_ap : case L4_loadruh_ur : BitNum = <NUM_LIT> ; SignEx = false ; break ; case L2_loadrigp : case L2_loadri_io : case L2_loadri_pbr : case L2_loadri_pci : case L2_loadri_pcr : case L2_loadri_pi : case L2_loadw_locked : case L4_loadri_abs : case L4_loadri_ap : case L4_loadri_rr : case L4_loadri_ur : case LDriw_pred : BitNum = <NUM_LIT> ; SignEx = true ; break ; case L2_loadrdgp : case L2_loadrd_io : case L2_loadrd_pbr : case L2_loadrd_pci : case L2_loadrd_pcr : case L2_loadrd_pi :


<s> case L2_loadrd_pci : case L2_loadrd_pcr : case L2_loadrd_pi : case L4_loadd_locked : case L4_loadrd_abs : case L4_loadrd_ap : case L4_loadrd_rr : case L4_loadrd_ur : BitNum = <NUM_LIT> ; SignEx = true ; break ; } const MachineOperand & MD = MI . getOperand ( <NUM_LIT> ) ; assert ( MD . isReg ( ) && MD . isDef ( ) ) ; RegisterRef RD = MD ; uint16_t W = getRegBitWidth ( RD ) ; assert ( W >= BitNum && BitNum > <NUM_LIT> ) ; RegisterCell Res ( W ) ; for ( uint16_t i = <NUM_LIT> ; i < BitNum ; ++ i ) Res [ i ] = BT :: BitValue :: self ( BT :: BitRef ( RD . Reg , i ) ) ; if ( SignEx ) { const BT :: BitValue & Sign = Res [ BitNum - <NUM_LIT> ] ; for ( uint16_t i = BitNum ; i < W ; ++ i ) Res [ i ] = BT :: BitValue :: ref ( Sign ) ; } else { for ( uint16_t i = BitNum ; i < W ; ++ i ) Res [ i ] = BT :: BitValue :: Zero ;


<s> ExtType ( char t , uint16_t w ) : Type ( t ) , Width ( w ) {


<s> InPhysReg = getNextPhysReg ( InPhysReg , Width ) ; if ( ! InPhysReg ) break ; InVirtReg = getVirtRegFor ( InPhysReg ) ; if ( ! InVirtReg ) continue ; AttributeSet Attrs = F . getAttributes ( ) ; if ( Attrs . hasAttribute ( AttrIdx , Attribute :: SExt ) ) VRX . insert ( std :: make_pair ( InVirtReg , ExtType ( ExtType :: SExt , Width ) ) ) ; else if ( Attrs . hasAttribute ( AttrIdx , Attribute :: ZExt ) ) VRX . insert ( std :: make_pair ( InVirtReg , ExtType ( ExtType :: ZExt , Width ) ) ) ;


<s> for ( unsigned i = <NUM_LIT> , n = Vector . size ( ) ; i < n ; ++ i ) { const MachineOperand & MO = MI . getOperand ( i ) ; if ( MO . isReg ( ) ) Vector [ i ] = BT :: RegisterRef ( MO ) ; }


<s> IndexType Index = IndexMap . getIndex ( & In ) ; for ( auto & Op : In . operands ( ) ) { if ( ! Op . isReg ( ) || ! Op . isUse ( ) || Op . isUndef ( ) ) continue ; RegisterRef R = { Op . getReg ( ) , Op . getSubReg ( ) } ; if ( TargetRegisterInfo :: isPhysicalRegister ( R . Reg ) && Reserved [ R . Reg ] ) continue ; bool IsKill = Op . isKill ( ) ; for ( auto S : expandToSubRegs ( R , MRI , TRI ) ) { LastUse [ S ] = Index ; if ( IsKill ) closeRange ( S ) ; } } for ( auto & Op : In . operands ( ) ) { if ( ! Op . isReg ( ) || ! Op . isDef ( ) || Op . isUndef ( ) ) continue ; RegisterRef R = { Op . getReg ( ) , Op . getSubReg ( ) } ; if ( TargetRegisterInfo :: isPhysicalRegister ( R . Reg ) && Reserved [ R . Reg ] ) continue ; for ( auto S : expandToSubRegs ( R , MRI , TRI ) ) { if ( LastDef [ S ] != IndexType :: None || LastUse [ S ] != IndexType :: None ) closeRange ( S ) ; LastDef [ S ] = Index ; } } } RegisterSet LiveOnExit ; for ( auto * SB : B . successors ( ) ) for ( auto R : getLiveIns ( * SB ) ) for ( auto S : expandToSubRegs ( R , MRI , TRI ) ) LiveOnExit . insert ( S ) ; for ( auto R : LiveOnExit ) LastUse [ R ] = IndexType :: Exit ; RegisterSet Left ; for ( auto & I : LastUse ) if ( I . second != IndexType :: None ) Left . insert ( I . first ) ;

for ( auto & I : LastDef ) if ( I . second != IndexType :: None ) Left . insert ( I . first ) ;


<s> if ( In . isDebugValue ( ) ) continue ; IndexType Index = IndexMap . getIndex ( & In ) ; for ( auto & Op : In . operands ( ) ) { if ( ! Op . isReg ( ) || ! Op . isUse ( ) || Op . isUndef ( ) ) continue ; RegisterRef R = { Op . getReg ( ) , Op . getSubReg ( ) } ; if ( TargetRegisterInfo :: isPhysicalRegister ( R . Reg ) && Reserved [ R . Reg ] ) continue ; bool IsKill = Op . isKill ( ) ; for ( auto S : expandToSubRegs ( R , MRI , TRI ) ) { LastUse [ S ] = Index ; if ( IsKill ) closeRange ( S ) ; } } for ( auto & Op : In . operands ( ) ) { if ( ! Op . isReg ( ) || ! Op . isDef ( ) || Op . isUndef ( ) ) continue ; RegisterRef R = { Op . getReg ( ) , Op . getSubReg ( ) } ; if ( TargetRegisterInfo :: isPhysicalRegister ( R . Reg ) && Reserved [ R . Reg ] ) continue ; for ( auto S : expandToSubRegs ( R , MRI , TRI ) ) { if ( LastDef [ S ] != IndexType :: None || LastUse [ S ] != IndexType :: None ) closeRange ( S ) ; LastDef [ S ] = Index ; } } } RegisterSet LiveOnExit ;

for ( auto * SB : B . successors ( ) ) for ( auto R : getLiveIns ( * SB , MRI , TRI ) ) LiveOnExit . insert ( R ) ;


<s> for ( auto I : B . liveins ( ) ) { if ( I . LaneMask . all ( ) ) { Tmp . insert ( { I . PhysReg , <NUM_LIT> } ) ; continue ; } for ( MCSubRegIndexIterator S ( I . PhysReg , & TRI ) ; S . isValid ( ) ; ++ S ) { LaneBitmask M = TRI . getSubRegIndexLaneMask ( S . getSubRegIndex ( ) ) ; if ( ( M & I . LaneMask ) . any ( ) ) Tmp . insert ( { S . getSubReg ( ) , <NUM_LIT> } ) ; } } for ( auto R : Tmp ) { if ( ! Reserved [ R . Reg ] ) LiveIns . insert ( R ) ; for ( auto S : expandToSubRegs ( R , MRI , TRI ) ) if ( ! Reserved [ S . Reg ] ) LiveIns . insert ( S ) ; } return LiveIns ;


<s> DeadMap [ R ] . add ( IndexType :: Entry , IndexType :: Exit , false , false ) ; return ; } RangeList & RL = F -> second ; RangeList :: iterator A = RL . begin ( ) , Z = RL . end ( ) - <NUM_LIT> ; if ( A -> start ( ) != IndexType :: Entry ) { IndexType DE = IndexMap . getPrevIndex ( A -> start ( ) ) ; if ( DE != IndexType :: Entry ) DeadMap [ R ] . add ( IndexType :: Entry , DE , false , false ) ; } while ( A != Z ) { IndexType AE = ( A -> end ( ) == IndexType :: None ) ? A -> start ( ) : A -> end ( ) ; IndexType DS = IndexMap . getNextIndex ( AE ) ; ++ A ;


<s> IndexType Index = IndexMap . getIndex ( & In ) ; for ( auto & Op : In . operands ( ) ) { if ( ! Op . isReg ( ) || ! Op . isUse ( ) || Op . isUndef ( ) ) continue ; RegisterRef R = { Op . getReg ( ) , Op . getSubReg ( ) } ; if ( TargetRegisterInfo :: isPhysicalRegister ( R . Reg ) && Reserved [ R . Reg ] ) continue ; bool IsKill = Op . isKill ( ) ; for ( auto S : expandToSubRegs ( R , MRI , TRI ) ) { LastUse [ S ] = Index ; if ( IsKill ) closeRange ( S ) ; } } Defs . clear ( ) ; Clobbers . clear ( ) ; for ( auto & Op : In . operands ( ) ) { if ( ! Op . isReg ( ) || ! Op . isDef ( ) || Op . isUndef ( ) ) continue ; RegisterRef R = { Op . getReg ( ) , Op . getSubReg ( ) } ; for ( auto S : expandToSubRegs ( R , MRI , TRI ) ) { if ( TargetRegisterInfo :: isPhysicalRegister ( S . Reg ) && Reserved [ S . Reg ] ) continue ; if ( Op . isDead ( ) ) Clobbers . insert ( S ) ; else Defs . insert ( S ) ; } } for ( auto & Op : In . operands ( ) ) { if ( ! Op . isRegMask ( ) ) continue ;

const uint32_t * BM = Op . getRegMask ( ) ;


<s> LLVM_DEBUG ( dbgs ( ) << __func__ << <STR_LIT> << IndexMap << '\n' ) ; computeInitialLiveRanges ( IndexMap , LiveMap ) ; LLVM_DEBUG ( dbgs ( ) << __func__ << <STR_LIT> << PrintRangeMap ( LiveMap , TRI ) << '\n' ) ; return LiveMap ;


<s> IndexType ZE = ( Z -> end ( ) == IndexType :: None ) ? Z -> start ( ) : Z -> end ( ) ; IndexType DS = IndexMap . getNextIndex ( ZE ) ; if ( DS < IndexType :: Exit ) DeadMap [ R ] . add ( DS , IndexType :: Exit , false , false ) ; } } ; MachineFunction & MF = * IndexMap . getBlock ( ) . getParent ( ) ; auto & MRI = MF . getRegInfo ( ) ; unsigned NumRegs = TRI . getNumRegs ( ) ; BitVector Visited ( NumRegs ) ; for ( unsigned R = <NUM_LIT> ; R < NumRegs ; ++ R ) { for ( auto S : expandToSubRegs ( { R , <NUM_LIT> } , MRI , TRI ) ) { if ( Reserved [ S . Reg ] || Visited [ S . Reg ] ) continue ; addDeadRanges ( S ) ; Visited [ S . Reg ] = true ; } }

for ( auto & P : LiveMap ) if ( Register :: isVirtualRegister ( P . first . Reg ) ) addDeadRanges ( P . first ) ;


<s> Clobbers . clear ( ) ; for ( auto & Op : In . operands ( ) ) { if ( ! Op . isReg ( ) || ! Op . isDef ( ) || Op . isUndef ( ) ) continue ; RegisterRef R = { Op . getReg ( ) , Op . getSubReg ( ) } ; for ( auto S : expandToSubRegs ( R , MRI , TRI ) ) { if ( Register :: isPhysicalRegister ( S . Reg ) && Reserved [ S . Reg ] ) continue ; if ( Op . isDead ( ) ) Clobbers . insert ( S ) ; else Defs . insert ( S ) ; } } for ( auto & Op : In . operands ( ) ) { if ( ! Op . isRegMask ( ) ) continue ; const uint32_t * BM = Op . getRegMask ( ) ; for ( unsigned PR = <NUM_LIT> , N = TRI . getNumRegs ( ) ; PR != N ; ++ PR ) { if ( MCSubRegIterator ( PR , & TRI , false ) . isValid ( ) ) continue ; if ( Reserved [ PR ] ) continue ; if ( BM [ PR / <NUM_LIT> ] & ( <NUM_LIT> << ( PR % <NUM_LIT> ) ) ) continue ; RegisterRef R = { PR , <NUM_LIT> } ; if ( ! Defs . count ( R ) ) Clobbers . insert ( R ) ; } } for ( RegisterRef R : Defs ) Clobbers . erase ( R ) ; for ( RegisterRef S : Defs ) { assert ( ! Register :: isPhysicalRegister ( S . Reg ) || ! MCSubRegIterator ( S . Reg , & TRI , false ) . isValid ( ) ) ; if ( LastDef [ S ] != IndexType :: None || LastUse [ S ] != IndexType :: None ) closeRange ( S ) ;


<s> unsigned PReg = * RC . begin ( ) ; MCSubRegIndexIterator I ( PReg , & TRI ) ; if ( ! I . isValid ( ) ) SRs . insert ( { R . Reg , <NUM_LIT> } ) ;

for ( ; I . isValid ( ) ; ++ I ) SRs . insert ( { R . Reg , I . getSubRegIndex ( ) } ) ;


<s> if ( DS < DE ) DeadMap [ R ] . add ( DS , DE , false , false ) ; } if ( Z -> end ( ) != IndexType :: Exit ) { IndexType ZE = ( Z -> end ( ) == IndexType :: None ) ? Z -> start ( ) : Z -> end ( ) ; IndexType DS = IndexMap . getNextIndex ( ZE ) ; if ( DS < IndexType :: Exit ) DeadMap [ R ] . add ( DS , IndexType :: Exit , false , false ) ; } } ; MachineFunction & MF = * IndexMap . getBlock ( ) . getParent ( ) ; auto & MRI = MF . getRegInfo ( ) ; unsigned NumRegs = TRI . getNumRegs ( ) ; BitVector Visited ( NumRegs ) ; for ( unsigned R = <NUM_LIT> ; R < NumRegs ; ++ R ) { for ( auto S : expandToSubRegs ( { R , <NUM_LIT> } , MRI , TRI ) ) { if ( Reserved [ S . Reg ] || Visited [ S . Reg ] ) continue ;


<s> computeInitialLiveRanges ( IndexMap , LiveMap ) ; DEBUG ( dbgs ( ) << __func__ << <STR_LIT> << PrintRangeMap ( LiveMap , TRI ) << '\n' ) ;


<s> if ( I . LaneMask . all ( ) || ( I . LaneMask . any ( ) && ! S . isValid ( ) ) ) { Tmp . insert ( { I . PhysReg , <NUM_LIT> } ) ; continue ; } for ( ; S . isValid ( ) ; ++ S ) { unsigned SI = S . getSubRegIndex ( ) ; if ( ( I . LaneMask & TRI . getSubRegIndexLaneMask ( SI ) ) . any ( ) ) Tmp . insert ( { S . getSubReg ( ) , <NUM_LIT> } ) ; } } for ( auto R : Tmp ) { if ( ! Reserved [ R . Reg ] ) LiveIns . insert ( R ) ;

for ( auto S : expandToSubRegs ( R , MRI , TRI ) ) if ( ! Reserved [ S . Reg ] ) LiveIns . insert ( S ) ;


<s> IndexRange ( ) : Fixed ( false ) , TiedEnd ( false ) {


<s> auto & RC = * MRI . getRegClass ( R . Reg ) ; unsigned PReg = * RC . begin ( ) ; MCSubRegIndexIterator I ( PReg , & TRI ) ; if ( ! I . isValid ( ) ) SRs . insert ( { R . Reg , <NUM_LIT> } ) ; for ( ; I . isValid ( ) ; ++ I ) SRs . insert ( { R . Reg , I . getSubRegIndex ( ) } ) ; }


<s> RegisterSet SRs ; if ( R . Sub != <NUM_LIT> ) { SRs . insert ( R ) ; return SRs ; } if ( Register :: isPhysicalRegister ( R . Reg ) ) { MCSubRegIterator I ( R . Reg , & TRI ) ; if ( ! I . isValid ( ) ) SRs . insert ( { R . Reg , <NUM_LIT> } ) ; for ( ; I . isValid ( ) ; ++ I ) SRs . insert ( { * I , <NUM_LIT> } ) ; } else { assert ( R . Reg . isVirtual ( ) ) ; auto & RC = * MRI . getRegClass ( R . Reg ) ; unsigned PReg = * RC . begin ( ) ;

MCSubRegIndexIterator I ( PReg , & TRI ) ;


<s> void add ( const IndexRange & Range ) { push_back ( Range ) ;


<s> if ( Z -> end ( ) != IndexType :: Exit ) { IndexType ZE = ( Z -> end ( ) == IndexType :: None ) ? Z -> start ( ) : Z -> end ( ) ; IndexType DS = IndexMap . getNextIndex ( ZE ) ; if ( DS < IndexType :: Exit ) DeadMap [ R ] . add ( DS , IndexType :: Exit , false , false ) ; } } ; MachineFunction & MF = * IndexMap . getBlock ( ) . getParent ( ) ; auto & MRI = MF . getRegInfo ( ) ; unsigned NumRegs = TRI . getNumRegs ( ) ; BitVector Visited ( NumRegs ) ; for ( unsigned R = <NUM_LIT> ; R < NumRegs ; ++ R ) { for ( auto S : expandToSubRegs ( { R , <NUM_LIT> } , MRI , TRI ) ) {

if ( Reserved [ S . Reg ] || Visited [ S . Reg ] ) continue ;


<s> ++ A ; IndexType DE = IndexMap . getPrevIndex ( A -> start ( ) ) ; if ( DS < DE ) DeadMap [ R ] . add ( DS , DE , false , false ) ; } if ( Z -> end ( ) != IndexType :: Exit ) { IndexType ZE = ( Z -> end ( ) == IndexType :: None ) ? Z -> start ( ) : Z -> end ( ) ; IndexType DS = IndexMap . getNextIndex ( ZE ) ; if ( DS < IndexType :: Exit ) DeadMap [ R ] . add ( DS , IndexType :: Exit , false , false ) ; } } ; MachineFunction & MF = * IndexMap . getBlock ( ) . getParent ( ) ; auto & MRI = MF . getRegInfo ( ) ; unsigned NumRegs = TRI . getNumRegs ( ) ; BitVector Visited ( NumRegs ) ; for ( unsigned R = <NUM_LIT> ; R < NumRegs ; ++ R ) { for ( auto S : expandToSubRegs ( { R , <NUM_LIT> } , MRI , TRI ) ) {


<s> } } for ( auto & Op : In . operands ( ) ) { if ( ! Op . isReg ( ) || ! Op . isDef ( ) || Op . isUndef ( ) ) continue ; RegisterRef R = { Op . getReg ( ) , Op . getSubReg ( ) } ; if ( TargetRegisterInfo :: isPhysicalRegister ( R . Reg ) && Reserved [ R . Reg ] ) continue ; for ( auto S : expandToSubRegs ( R , MRI , TRI ) ) { if ( LastDef [ S ] != IndexType :: None ) closeRange ( S ) ; LastDef [ S ] = Index ; } } } RegisterSet LiveOnExit ; for ( auto * SB : B . successors ( ) ) for ( auto R : getLiveIns ( * SB ) ) for ( auto S : expandToSubRegs ( R , MRI , TRI ) ) LiveOnExit . insert ( S ) ; for ( auto R : LiveOnExit ) LastUse [ R ] = IndexType :: Exit ; RegisterSet Left ; for ( auto & I : LastUse ) if ( I . second != IndexType :: None ) Left . insert ( I . first ) ; for ( auto & I : LastDef ) if ( I . second != IndexType :: None ) Left . insert ( I . first ) ;

for ( auto R : Left ) closeRange ( R ) ;


<s> std :: map < RegisterRef , IndexType > LastDef , LastUse ; RegisterSet LiveOnEntry ; MachineBasicBlock & B = IndexMap . getBlock ( ) ; MachineRegisterInfo & MRI = B . getParent ( ) -> getRegInfo ( ) ; for ( auto R : getLiveIns ( B ) ) for ( auto S : expandToSubRegs ( R , MRI , TRI ) ) LiveOnEntry . insert ( S ) ; for ( auto R : LiveOnEntry ) LastDef [ R ] = IndexType :: Entry ; auto closeRange = [ & LastUse , & LastDef , & LiveMap ] ( RegisterRef R ) -> void { auto LD = LastDef [ R ] , LU = LastUse [ R ] ; if ( LD == IndexType :: None ) LD = IndexType :: Entry ; if ( LU == IndexType :: None ) LU = IndexType :: Exit ; LiveMap [ R ] . add ( LD , LU , false , false ) ; LastUse [ R ] = LastDef [ R ] = IndexType :: None ; } ; for ( auto & In : B ) { if ( In . isDebugValue ( ) ) continue ; IndexType Index = IndexMap . getIndex ( & In ) ; for ( auto & Op : In . operands ( ) ) { if ( ! Op . isReg ( ) || ! Op . isUse ( ) || Op . isUndef ( ) ) continue ; RegisterRef R = { Op . getReg ( ) , Op . getSubReg ( ) } ; if ( TargetRegisterInfo :: isPhysicalRegister ( R . Reg ) && Reserved [ R . Reg ] ) continue ; bool IsKill = Op . isKill ( ) ; for ( auto S : expandToSubRegs ( R , MRI , TRI ) ) {


<s> DEBUG ( dbgs ( ) << LLVM_FUNCTION_NAME << <STR_LIT> << IndexMap << '\n' ) ; computeInitialLiveRanges ( IndexMap , LiveMap ) ; DEBUG ( dbgs ( ) << LLVM_FUNCTION_NAME << <STR_LIT> << PrintRangeMap ( LiveMap , TRI ) << '\n' ) ; return LiveMap ;


<s> IndexType end ( ) const { return second ;


<s> if ( R . Sub != <NUM_LIT> ) { SRs . insert ( R ) ; return SRs ; } if ( TargetRegisterInfo :: isPhysicalRegister ( R . Reg ) ) { MCSubRegIterator I ( R . Reg , & TRI ) ; if ( ! I . isValid ( ) ) SRs . insert ( { R . Reg , <NUM_LIT> } ) ; for ( ; I . isValid ( ) ; ++ I ) SRs . insert ( { * I , <NUM_LIT> } ) ; } else { assert ( TargetRegisterInfo :: isVirtualRegister ( R . Reg ) ) ; auto & RC = * MRI . getRegClass ( R . Reg ) ; unsigned PReg = * RC . begin ( ) ; MCSubRegIndexIterator I ( PReg , & TRI ) ;


<s> for ( auto I : B . liveins ( ) ) if ( ! Reserved [ I . PhysReg ] ) LiveIns . insert ( { I . PhysReg , <NUM_LIT> } ) ;


for ( auto I : B . liveins ( ) ) if ( ! Reserved [ I . PhysReg ] ) LiveIns . insert ( { I . PhysReg , <NUM_LIT> } ) ;


<s> <ISA_LIT>BlockRanges :: <ISA_LIT>BlockRanges ( MachineFunction & mf ) : MF ( mf ) , HST ( mf . getSubtarget < <ISA_LIT>Subtarget > ( ) ) , TII ( * HST . getInstrInfo ( ) ) , TRI ( * HST . getRegisterInfo ( ) ) , Reserved ( TRI . getReservedRegs ( mf ) ) { for ( auto I = TRI . regclass_begin ( ) , E = TRI . regclass_end ( ) ; I != E ; ++ I ) { auto * RC = * I ; if ( RC -> isAllocatable ( ) ) continue ;

for ( unsigned R : * RC ) Reserved [ R ] = true ;


<s> IndexRange ( IndexType Start , IndexType End , bool F = false , bool T = false ) : std :: pair < IndexType , IndexType > ( Start , End ) , Fixed ( F ) , TiedEnd ( T ) {


<s> IndexType ( unsigned Idx ) : Index ( Idx ) {


<s> PrintRangeMap ( const RegToRangeMap & M , const TargetRegisterInfo & I ) : Map ( M ) , TRI ( I ) {


<s> void setStart ( const IndexType & S ) { first = S ;


<s> inline <ISA_LIT>BlockRanges :: IndexType :: operator unsigned ( ) const {


<s> assert ( Index >= First ) ; return Index ;


<s> } OffsetMap [ & B ] = InstOffset ; for ( auto & MI : B . instrs ( ) ) { InstOffset += HII -> getSize ( MI ) ; if ( MI . isBranch ( ) && HII -> isExtendable ( MI ) ) InstOffset += HEXAGON_INSTR_SIZE ; }


<s> for ( auto & B : MF ) { for ( auto & MI : B ) { if ( ! MI . isBranch ( ) || ! isJumpOutOfRange ( MI , BlockToInstOffset ) ) continue ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << HII -> isExtendable ( MI ) << <STR_LIT> << HII -> isConstExtended ( MI ) << <STR_LIT> << MI ) ; if ( ! HII -> isExtendable ( MI ) && ! HII -> isExtended ( MI ) ) {


<s> LLVM_DEBUG ( dbgs ( ) << <STR_LIT> ) ; auto & HST = MF . getSubtarget < <ISA_LIT>Subtarget > ( ) ; HII = HST . getInstrInfo ( ) ; HRI = HST . getRegisterInfo ( ) ; bool Changed = false ; Changed = relaxBranches ( MF ) ; return Changed ;


<s> LLVM_DEBUG ( dbgs ( ) << <STR_LIT> ) ; auto & HST = MF . getSubtarget < <ISA_LIT>Subtarget > ( ) ;


<s> for ( auto & MI : B . instrs ( ) ) { InstOffset += HII -> getSize ( MI ) ; if ( MI . isBranch ( ) && HII -> isExtendable ( MI ) ) InstOffset += HEXAGON_INSTR_SIZE ; }


<s> } OffsetMap [ & B ] = InstOffset ; for ( auto & MI : B . instrs ( ) ) InstOffset += HII -> getSize ( & MI ) ; }


<s> return ! HII -> isJumpWithinBranchRange ( & * FirstTerm , Distance ) ; } if ( FBB ) { auto SecondTerm = std :: next ( FirstTerm ) ; assert ( SecondTerm != B . instr_end ( ) && ( SecondTerm -> isBranch ( ) || SecondTerm -> isCall ( ) ) && <STR_LIT> ) ; if ( & MI != & * SecondTerm ) return false ; Distance = std :: abs ( ( long long ) InstOffset - BlockToInstOffset [ FBB ] ) + BranchRelaxSafetyBuffer ;

return ! HII -> isJumpWithinBranchRange ( & * SecondTerm , Distance ) ;


<s> InstOffset += HII -> nonDbgBBSize ( & B ) * HEXAGON_INSTR_SIZE ; MachineBasicBlock * TBB = NULL , * FBB = NULL ; SmallVector < MachineOperand , <NUM_LIT> > Cond ; if ( HII -> AnalyzeBranch ( B , TBB , FBB , Cond , false ) ) { if ( HII -> isNewValueJump ( & * FirstTerm ) ) TBB = FirstTerm -> getOperand ( HII -> getCExtOpNum ( & * FirstTerm ) ) . getMBB ( ) ; } if ( TBB && & MI == & * FirstTerm ) { Distance = std :: abs ( ( long long ) InstOffset - BlockToInstOffset [ TBB ] ) + BranchRelaxSafetyBuffer ; return ! HII -> isJumpWithinBranchRange ( & * FirstTerm , Distance ) ; }


<s> if ( ! HII -> isExtendable ( & MI ) && ! HII -> isExtended ( & MI ) ) { DEBUG ( dbgs ( ) << <STR_LIT> ) ; } else { int ExtOpNum = HII -> getCExtOpNum ( & MI ) ;

MachineOperand & MO = MI . getOperand ( ExtOpNum ) ;


<s> StringRef getPassName ( ) const override {


<s> if ( HII -> isNewValueJump ( * FirstTerm ) ) TBB = FirstTerm -> getOperand ( HII -> getCExtOpNum ( * FirstTerm ) ) . getMBB ( ) ; } if ( TBB && & MI == & * FirstTerm ) { Distance = std :: abs ( ( long long ) InstOffset - BlockToInstOffset [ TBB ] ) + BranchRelaxSafetyBuffer ; return ! HII -> isJumpWithinBranchRange ( * FirstTerm , Distance ) ; } if ( FBB ) {

auto SecondTerm = std :: next ( FirstTerm ) ;


<s> auto FirstTerm = B . getFirstInstrTerminator ( ) ; if ( FirstTerm == B . instr_end ( ) ) return false ; if ( HII -> isExtended ( MI ) ) return false ; unsigned InstOffset = BlockToInstOffset [ & B ] ; unsigned Distance = <NUM_LIT> ; InstOffset += HII -> nonDbgBBSize ( & B ) * HEXAGON_INSTR_SIZE ; MachineBasicBlock * TBB = nullptr , * FBB = nullptr ; SmallVector < MachineOperand , <NUM_LIT> > Cond ; if ( HII -> analyzeBranch ( B , TBB , FBB , Cond , false ) ) { if ( HII -> isNewValueJump ( * FirstTerm ) ) TBB = FirstTerm -> getOperand ( HII -> getCExtOpNum ( * FirstTerm ) ) . getMBB ( ) ; } if ( TBB && & MI == & * FirstTerm ) { Distance = std :: abs ( ( long long ) InstOffset - BlockToInstOffset [ TBB ] ) + BranchRelaxSafetyBuffer ; return ! HII -> isJumpWithinBranchRange ( * FirstTerm , Distance ) ; } if ( FBB ) { auto SecondTerm = std :: next ( FirstTerm ) ; assert ( SecondTerm != B . instr_end ( ) && ( SecondTerm -> isBranch ( ) || SecondTerm -> isCall ( ) ) && <STR_LIT> ) ; if ( & MI != & * SecondTerm ) return false ; Distance = std :: abs ( ( long long ) InstOffset - BlockToInstOffset [ FBB ] ) + BranchRelaxSafetyBuffer ; return ! HII -> isJumpWithinBranchRange ( * SecondTerm , Distance ) ;


<s> unsigned InstOffset = BlockToInstOffset [ & B ] ; unsigned Distance = <NUM_LIT> ; InstOffset += HII -> nonDbgBBSize ( & B ) * HEXAGON_INSTR_SIZE ; MachineBasicBlock * TBB = NULL , * FBB = NULL ; SmallVector < MachineOperand , <NUM_LIT> > Cond ; if ( HII -> analyzeBranch ( B , TBB , FBB , Cond , false ) ) { if ( HII -> isNewValueJump ( & * FirstTerm ) ) TBB = FirstTerm -> getOperand ( HII -> getCExtOpNum ( & * FirstTerm ) ) . getMBB ( ) ; } if ( TBB && & MI == & * FirstTerm ) {

Distance = std :: abs ( ( long long ) InstOffset - BlockToInstOffset [ TBB ] ) + BranchRelaxSafetyBuffer ;


<s> InstOffset = alignTo ( InstOffset , B . getAlignment ( ) ) ; } OffsetMap [ & B ] = InstOffset ; for ( auto & MI : B . instrs ( ) ) { InstOffset += HII -> getSize ( MI ) ;

if ( MI . isBranch ( ) && HII -> isExtendable ( MI ) ) InstOffset += HEXAGON_INSTR_SIZE ;