<s> uint64_t F = D . TSFlags ; unsigned AM = ( F >> <STR_LIT> ) & <STR_LIT> ; switch ( AM ) { case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : switch ( ExtOpc ) { case PS_loadrubabs : case L4_loadrub_ap : case L4_loadrub_ur : return L2_loadrub_io ; case PS_loadrbabs : case L4_loadrb_ap : case L4_loadrb_ur : return L2_loadrb_io ; case PS_loadruhabs : case L4_loadruh_ap : case L4_loadruh_ur : return L2_loadruh_io ; case PS_loadrhabs : case L4_loadrh_ap : case L4_loadrh_ur : return L2_loadrh_io ; case PS_loadriabs : case L4_loadri_ap : case L4_loadri_ur : return L2_loadri_io ; case PS_loadrdabs : case L4_loadrd_ap : case L4_loadrd_ur : return L2_loadrd_io ; case L4_loadbzw2_ap : case L4_loadbzw2_ur : return L2_loadbzw2_io ; case L4_loadbzw4_ap : case L4_loadbzw4_ur : return L2_loadbzw4_io ; case L4_loadbsw2_ap : case L4_loadbsw2_ur : return L2_loadbsw2_io ; case L4_loadbsw4_ap : case L4_loadbsw4_ur : return L2_loadbsw4_io ; case L4_loadalignh_ap : case L4_loadalignh_ur : return L2_loadalignh_io ; case L4_loadalignb_ap : case L4_loadalignb_ur : return L2_loadalignb_io ; case L4_ploadrubt_abs : return L2_ploadrubt_io ; case L4_ploadrubf_abs : return L2_ploadrubf_io ; case L4_ploadrbt_abs : return L2_ploadrbt_io ; case L4_ploadrbf_abs : return L2_ploadrbf_io ; case L4_ploadruht_abs : return L2_ploadruht_io ; case L4_ploadruhf_abs : return L2_ploadruhf_io ; case L4_ploadrht_abs : return L2_ploadrht_io ; case L4_ploadrhf_abs : return L2_ploadrhf_io ; case L4_ploadrit_abs : return L2_ploadrit_io ; case L4_ploadrif_abs : return L2_ploadrif_io ; case L4_ploadrdt_abs : return L2_ploadrdt_io ; case L4_ploadrdf_abs : return L2_ploadrdf_io ; case PS_storerbabs : case S4_storerb_ap : case S4_storerb_ur : return S2_storerb_io ; case PS_storerhabs : case S4_storerh_ap : case S4_storerh_ur : return S2_storerh_io ; case PS_storerfabs : case S4_storerf_ap : case S4_storerf_ur : return S2_storerf_io ; case PS_storeriabs : case S4_storeri_ap : case S4_storeri_ur : return S2_storeri_io ; case PS_storerdabs : case S4_storerd_ap : case S4_storerd_ur : return S2_storerd_io ; case S4_pstorerbt_abs : return S2_pstorerbt_io ; case S4_pstorerbf_abs : return S2_pstorerbf_io ; case S4_pstorerht_abs : return S2_pstorerht_io ; case S4_pstorerhf_abs : return S2_pstorerhf_io ; case S4_pstorerft_abs : return S2_pstorerft_io ; case S4_pstorerff_abs : return S2_pstorerff_io ; case S4_pstorerit_abs : return S2_pstorerit_io ; case S4_pstorerif_abs : return S2_pstorerif_io ; case S4_pstorerdt_abs : return S2_pstorerdt_io ; case S4_pstorerdf_abs : return S2_pstorerdf_io ; default : break ; } break ; case <STR_LIT> : if ( ! isStoreImmediate ( ExtOpc ) ) return ExtOpc ; break ; default : break ; } } return <NUM_LIT> ;


<s> const MachineOperand & HCE :: getStoredValueOp ( const MachineInstr & MI ) const { assert ( MI . mayStore ( ) ) ;

return MI . getOperand ( MI . getNumExplicitOperands ( ) - <NUM_LIT> ) ;


return N != nullptr ? N -> Height : <NUM_LIT> ;


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


<s> assert ( Ex . S == <NUM_LIT> && <STR_LIT> ) ; assert ( ! Ex . Neg && <STR_LIT> ) ; InitI = BuildMI ( MBB , At , dl , HII -> get ( <STR_LIT> ) , DefR ) . add ( MachineOperand ( Ex . Rs ) ) . add ( ExtOp ) ; } else { assert ( ( Ex . Rs . Reg == <NUM_LIT> || Ex . Rs . isVReg ( ) ) && <STR_LIT> ) ; if ( Ex . trivial ( ) ) { InitI = BuildMI ( MBB , At , dl , HII -> get ( <STR_LIT> ) , DefR ) . add ( ExtOp ) ; } else if ( Ex . S == <NUM_LIT> ) { if ( Ex . Neg ) { InitI = BuildMI ( MBB , At , dl , HII -> get ( <STR_LIT> ) , DefR ) . add ( ExtOp ) . add ( MachineOperand ( Ex . Rs ) ) ; } else { InitI = BuildMI ( MBB , At , dl , HII -> get ( <STR_LIT> ) , DefR ) . add ( MachineOperand ( Ex . Rs ) ) . add ( ExtOp ) ; } } else { unsigned NewOpc = Ex . Neg ? <STR_LIT> : <STR_LIT> ; InitI = BuildMI ( MBB , At , dl , HII -> get ( NewOpc ) , DefR ) . add ( ExtOp ) . add ( MachineOperand ( Ex . Rs ) ) . addImm ( Ex . S ) ; } } assert ( InitI ) ; ( void ) InitI ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << MBB . getNumber ( ) << <STR_LIT> << PrintInit ( ExtI , * HRI ) << <STR_LIT> << * InitI ) ; return { DefR , <NUM_LIT> } ;


<s> } else { Min = <NUM_LIT> ; Max = - <NUM_LIT> ; } if ( Min > Max ) std :: tie ( Min , Max , Align ) = std :: make_tuple ( <NUM_LIT> , - <NUM_LIT> , <NUM_LIT> ) ; return * this ;


<s> OffsetRange & intersect ( OffsetRange A ) { if ( Align < A . Align ) std :: swap ( * this , A ) ; if ( Offset >= A . Offset && ( Offset - A . Offset ) % A . Align == <NUM_LIT> ) { Min = adjustUp ( std :: max ( Min , A . Min ) , Align , Offset ) ;

Max = adjustDown ( std :: min ( Max , A . Max ) , Align , Offset ) ;


return Reg != <NUM_LIT> && TargetRegisterInfo :: isStackSlot ( Reg ) ;


<s> bool isSlot ( ) const { return Reg != <NUM_LIT> && TargetRegisterInfo :: isStackSlot ( Reg ) ;


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


return Reg != <NUM_LIT> && ! TargetRegisterInfo :: isStackSlot ( Reg ) && TargetRegisterInfo :: isVirtualRegister ( Reg ) ;


<s> Loc ( MachineBasicBlock * B , MachineBasicBlock :: iterator It ) : Block ( B ) , At ( It ) { if ( B -> end ( ) == It ) { Pos = - <NUM_LIT> ;


<s> Pos = - <NUM_LIT> ; } else { assert ( It -> getParent ( ) == B ) ; Pos = std :: distance ( B -> begin ( ) , It ) ; }


<s> Node ( const OffsetRange & R ) : MaxEnd ( R . Max ) , Range ( R ) {


<s> if ( N -> Range . Min <= P ) { if ( ( CheckA && N -> Range . contains ( P ) ) || ( ! CheckA && P <= N -> Range . Max ) ) Seq . push_back ( N ) ;

nodesWith ( N -> Right , P , CheckA , Seq ) ;


<s> OffsetRange ( int32_t L , int32_t H , uint8_t A , uint8_t O = <NUM_LIT> ) : Min ( L ) , Max ( H ) , Align ( A ) , Offset ( O ) {


<s> Seq . push_back ( N ) ; order ( N -> Right , Seq ) ;


<s> PrintExpr ( const HCE :: ExtExpr & E , const <ISA_LIT>RegisterInfo & I ) : Ex ( E ) , HRI ( I ) {


<s> PrintIMap ( const HCE :: AssignmentMap & M , const <ISA_LIT>RegisterInfo & I ) : IMap ( M ) , HRI ( I ) {


<s> PrintInit ( const HCE :: ExtenderInit & EI , const <ISA_LIT>RegisterInfo & I ) : ExtI ( EI ) , HRI ( I ) {


<s> PrintRegister ( HCE :: Register R , const <ISA_LIT>RegisterInfo & I ) : Rs ( R ) , HRI ( I ) {


<s> if ( Balance < - <NUM_LIT> ) return rotateRight ( N -> Left , N ) ; if ( Balance > <NUM_LIT> ) return rotateLeft ( N -> Right , N ) ; return N ;


<s> ED . OpNum = OpNum ; bool IsLoad = MI . mayLoad ( ) ; bool IsStore = MI . mayStore ( ) ; for ( MachineOperand & Op : MI . operands ( ) ) if ( Op . isFI ( ) && Op . getIndex ( ) < <NUM_LIT> ) return ; if ( IsLoad || IsStore ) { unsigned AM = HII -> getAddrMode ( MI ) ; switch ( AM ) { case <STR_LIT> : break ; case <STR_LIT> : ED . Rd = MI . getOperand ( OpNum - <NUM_LIT> ) ; ED . IsDef = true ; break ; case <STR_LIT> : if ( ! isStoreImmediate ( Opc ) ) ED . Expr . Rs = MI . getOperand ( OpNum - <NUM_LIT> ) ; break ; case <STR_LIT> : ED . Expr . Rs = MI . getOperand ( OpNum - <NUM_LIT> ) ; ED . Expr . S = MI . getOperand ( OpNum - <NUM_LIT> ) . getImm ( ) ; break ; default : llvm_unreachable ( <STR_LIT> ) ; } } else { switch ( Opc ) { case <STR_LIT> : ED . Rd = MI . getOperand ( <NUM_LIT> ) ; ED . IsDef = true ; break ; case <STR_LIT> : case <STR_LIT> : ED . Rd = { MI . getOperand ( <NUM_LIT> ) . getReg ( ) , <STR_LIT> } ; ED . IsDef = true ; break ; case <STR_LIT> : ED . Rd = { MI . getOperand ( <NUM_LIT> ) . getReg ( ) , <STR_LIT> } ; ED . IsDef = true ; break ;


<s> Register ( const MachineOperand & Op ) : Reg ( Op . getReg ( ) ) , Sub ( Op . getSubReg ( ) ) {


<s> assert ( N -> Range != D -> Range && <STR_LIT> ) ; if ( D -> Range < N -> Range ) N -> Left = remove ( N -> Left , D ) ; else N -> Right = remove ( N -> Right , D ) ;


<s> Register DefR = insertInitializer ( Q . first , P . first ) ; NewRegs . push_back ( DefR . Reg ) ; for ( unsigned I : Q . second ) Changed |= replaceInstr ( I , DefR , P . first ) ;


<s> assert ( ExtRoot ( ExtValue ( ED ) ) == ExtRoot ( DefV ) && <STR_LIT> ) ; const ExtExpr & DefEx = ExtI . second ; ExtValue EV ( ED ) ; int32_t Diff = EV . Offset - DefV . Offset ; const MachineInstr & MI = * ED . UseMI ; LLVM_DEBUG ( dbgs ( ) << __func__ << <STR_LIT> << Idx << <STR_LIT> << PrintRegister ( ExtR , * HRI ) << <STR_LIT> << Diff << '\n' ) ; bool IsAbs = false , IsAbsSet = false ; if ( MI . mayLoad ( ) || MI . mayStore ( ) ) { unsigned AM = HII -> getAddrMode ( MI ) ; IsAbs = AM == <STR_LIT> ; IsAbsSet = AM == <STR_LIT> ; } std :: vector < std :: pair < MachineInstr * , unsigned >> RegOps ; if ( ED . IsDef && Diff != <NUM_LIT> ) { for ( MachineOperand & Op : MRI -> use_operands ( ED . Rd . Reg ) ) { MachineInstr & UI = * Op . getParent ( ) ; RegOps . push_back ( { & UI , getOperandIndex ( UI , Op ) } ) ; } } bool Replaced = false ;

if ( Diff == <NUM_LIT> && DefEx . trivial ( ) && ! IsAbs && ! IsAbsSet ) Replaced = replaceInstrExact ( ED , ExtR ) ;


<s> D &= ~ ( A - <NUM_LIT> ) ; } BuildMI ( MBB , At , dl , HII -> get ( IdxOpc ) ) . add ( MI . getOperand ( <NUM_LIT> ) ) . add ( MachineOperand ( ExtR ) ) . addImm ( D ) ; Diff -= D ; OffsetRange Uses = getOffsetRange ( MI . getOperand ( <NUM_LIT> ) ) ; if ( ! Uses . contains ( - Diff ) ) dbgs ( ) << <STR_LIT> << - Diff << <STR_LIT> << Uses << <STR_LIT> << MI ; assert ( Uses . contains ( - Diff ) ) ; MBB . erase ( MI ) ; return true ; } const ExtValue & EV = ExtI . first ; ( void ) EV ; const ExtExpr & Ex = ExtI . second ; ( void ) Ex ; if ( ExtOpc == <STR_LIT> || ExtOpc == <STR_LIT> ) { bool IsAddi = ExtOpc == <STR_LIT> ; const MachineOperand & RegOp = MI . getOperand ( IsAddi ? <NUM_LIT> : <NUM_LIT> ) ; const MachineOperand & ImmOp = MI . getOperand ( IsAddi ? <NUM_LIT> : <NUM_LIT> ) ; assert ( Ex . Rs == RegOp && EV == ImmOp && Ex . Neg != IsAddi && <STR_LIT> ) ; BuildMI ( MBB , At , dl , HII -> get ( TargetOpcode :: COPY ) ) . add ( MI . getOperand ( <NUM_LIT> ) ) . add ( MachineOperand ( ExtR ) ) ; Diff = <NUM_LIT> ; MBB . erase ( MI ) ; return true ; } if ( ExtOpc == <STR_LIT> || ExtOpc == <STR_LIT> || ExtOpc == <STR_LIT> || ExtOpc == <STR_LIT> ) { bool IsSub = ExtOpc == <STR_LIT> ; Register Rs = MI . getOperand ( IsSub ? <NUM_LIT> : <NUM_LIT> ) ; ExtValue V = MI . getOperand ( IsSub ? <NUM_LIT> : <NUM_LIT> ) ; assert ( EV == V && Rs == Ex . Rs && IsSub == Ex . Neg && <STR_LIT> ) ; unsigned NewOpc = ExtOpc == <STR_LIT> ? <STR_LIT> : <STR_LIT> ; BuildMI ( MBB , At , dl , HII -> get ( NewOpc ) ) . add ( MI . getOperand ( <NUM_LIT> ) ) . add ( MI . getOperand ( <NUM_LIT> ) ) . add ( MachineOperand ( ExtR ) ) ; MBB . erase ( MI ) ; return true ; } if ( MI . mayLoad ( ) || MI . mayStore ( ) ) { unsigned IdxOpc = getRegOffOpcode ( ExtOpc ) ; assert ( IdxOpc && <STR_LIT> ) ; MachineInstrBuilder MIB = BuildMI ( MBB , At , dl , HII -> get ( IdxOpc ) ) ;

if ( MI . mayLoad ( ) ) MIB . add ( getLoadResultOp ( MI ) ) ;


<s> assert ( Higher -> Right == Lower ) ; if ( height ( Lower -> Left ) > height ( Lower -> Right ) ) Lower = rotateRight ( Lower -> Left , Lower ) ; assert ( height ( Lower -> Left ) <= height ( Lower -> Right ) ) ; Higher -> Right = Lower -> Left ; update ( Higher ) ; Lower -> Left = Higher ; update ( Lower ) ; return Lower ;


<s> if ( height ( Lower -> Left ) > height ( Lower -> Right ) ) Lower = rotateRight ( Lower -> Left , Lower ) ; assert ( height ( Lower -> Left ) <= height ( Lower -> Right ) ) ;


<s> ExtValue VA ( A ) , VB ( B ) ; if ( VA != VB ) return VA < VB ; const MachineInstr * MA = A . UseMI ; const MachineInstr * MB = B . UseMI ; if ( MA == MB ) { return A . OpNum < B . OpNum ; } const MachineBasicBlock * BA = MA -> getParent ( ) ; const MachineBasicBlock * BB = MB -> getParent ( ) ; assert ( BA -> getNumber ( ) != - <NUM_LIT> && BB -> getNumber ( ) != - <NUM_LIT> ) ; if ( BA != BB ) return BA -> getNumber ( ) < BB -> getNumber ( ) ; return MDT -> dominates ( MA , MB ) ; } ) ; bool Changed = false ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << Extenders . size ( ) << <STR_LIT> ) ; for ( unsigned I = <NUM_LIT> , E = Extenders . size ( ) ; I != E ; ) { unsigned B = I ; const ExtRoot & T = Extenders [ B ] . getOp ( ) ;

while ( I != E && ExtRoot ( Extenders [ I ] . getOp ( ) ) == T ) ++ I ;


<s> OffsetRange & shift ( int32_t S ) { Min += S ; Max += S ;


<s> Min += S ; Max += S ; Offset = ( Offset + S ) % Align ; return * this ;


<s> bool trivial ( ) const { return Rs . Reg == <NUM_LIT> ;


<s> assert ( N != nullptr ) ; N -> Height = <NUM_LIT> + std :: max ( height ( N -> Left ) , height ( N -> Right ) ) ;

if ( N -> Left ) N -> MaxEnd = std :: max ( N -> MaxEnd , N -> Left -> MaxEnd ) ;


<s> if ( N -> Right ) N -> MaxEnd = std :: max ( N -> MaxEnd , N -> Right -> MaxEnd ) ; return N ;


<s> static OffsetRange zero ( ) { return { <NUM_LIT> , <NUM_LIT> , <NUM_LIT> ;


<s> return { <NUM_LIT> , <NUM_LIT> , <NUM_LIT> ;


<s> SmallVector < Node * , <NUM_LIT> > Nodes ; order ( Nodes ) ; for ( Node * N : Nodes ) delete N ;


<s> ~ RangeTree ( ) { SmallVector < Node * , <NUM_LIT> > Nodes ; order ( Nodes ) ;


<s> MachineBasicBlock & MBB = * DefL . Block ; MachineBasicBlock :: iterator At = DefL . At ; DebugLoc dl = DefL . Block -> findDebugLoc ( DefL . At ) ; const ExtValue & EV = ExtI . first ; MachineOperand ExtOp ( EV ) ; const ExtExpr & Ex = ExtI . second ; const MachineInstr * InitI = nullptr ; if ( Ex . Rs . isSlot ( ) ) { assert ( Ex . S == <NUM_LIT> && <STR_LIT> ) ; assert ( ! Ex . Neg && <STR_LIT> ) ; InitI = BuildMI ( MBB , At , dl , HII -> get ( <STR_LIT> ) , DefR ) . add ( MachineOperand ( Ex . Rs ) ) . add ( ExtOp ) ; } else { assert ( ( Ex . Rs . Reg == <NUM_LIT> || Ex . Rs . isVReg ( ) ) && <STR_LIT> ) ; if ( Ex . trivial ( ) ) { InitI = BuildMI ( MBB , At , dl , HII -> get ( <STR_LIT> ) , DefR ) . add ( ExtOp ) ; } else if ( Ex . S == <NUM_LIT> ) { if ( Ex . Neg ) { InitI = BuildMI ( MBB , At , dl , HII -> get ( <STR_LIT> ) , DefR ) . add ( ExtOp ) . add ( MachineOperand ( Ex . Rs ) ) ;


<s> return Reg != <NUM_LIT> && llvm :: Register :: isStackSlot ( Reg ) ;


<s> return Reg != <NUM_LIT> && ! llvm :: Register :: isStackSlot ( Reg ) && llvm :: Register :: isVirtualRegister ( Reg ) ;


<s> calculatePlacement ( P . first , Idxs , Defs ) ; for ( const std :: pair < Loc , IndexList > & Q : Defs ) { Register DefR = insertInitializer ( Q . first , P . first ) ; NewRegs . push_back ( DefR . Reg ) ; for ( unsigned I : Q . second ) Changed |= replaceInstr ( I , DefR , P . first ) ;


<s> const IndexList & Idxs = P . second ; if ( Idxs . size ( ) < CountThreshold ) continue ; Defs . clear ( ) ; calculatePlacement ( P . first , Idxs , Defs ) ; for ( const std :: pair < Loc , IndexList > & Q : Defs ) { Register DefR = insertInitializer ( Q . first , P . first ) ; NewRegs . push_back ( DefR . Reg ) ; for ( unsigned I : Q . second ) Changed |= replaceInstr ( I , DefR , P . first ) ; } } return Changed ;


<s> const ExtDesc & ED = Extenders [ Idx ] ; assert ( ( ! ED . IsDef || ED . Rd . Reg != <NUM_LIT> ) && <STR_LIT> ) ; const ExtValue & DefV = ExtI . first ; assert ( ExtRoot ( ExtValue ( ED ) ) == ExtRoot ( DefV ) && <STR_LIT> ) ; const ExtExpr & DefEx = ExtI . second ; ExtValue EV ( ED ) ; int32_t Diff = EV . Offset - DefV . Offset ; const MachineInstr & MI = * ED . UseMI ; LLVM_DEBUG ( dbgs ( ) << __func__ << <STR_LIT> << Idx << <STR_LIT> << PrintRegister ( ExtR , * HRI ) << <STR_LIT> << Diff << '\n' ) ; bool IsAbs = false , IsAbsSet = false ; if ( MI . mayLoadOrStore ( ) ) { unsigned AM = HII -> getAddrMode ( MI ) ; IsAbs = AM == <STR_LIT> ; IsAbsSet = AM == <STR_LIT> ; } std :: vector < std :: pair < MachineInstr * , unsigned >> RegOps ; if ( ED . IsDef && Diff != <NUM_LIT> ) { for ( MachineOperand & Op : MRI -> use_operands ( ED . Rd . Reg ) ) { MachineInstr & UI = * Op . getParent ( ) ; RegOps . push_back ( { & UI , getOperandIndex ( UI , Op ) } ) ; } } bool Replaced = false ; if ( Diff == <NUM_LIT> && DefEx . trivial ( ) && ! IsAbs && ! IsAbsSet ) Replaced = replaceInstrExact ( ED , ExtR ) ; else Replaced = replaceInstrExpr ( ED , ExtI , ExtR , Diff ) ; if ( Diff != <NUM_LIT> && Replaced && ED . IsDef ) { for ( std :: pair < MachineInstr * , unsigned > P : RegOps ) { unsigned J = P . second ; assert ( P . first -> getNumOperands ( ) > J + <NUM_LIT> && P . first -> getOperand ( J + <NUM_LIT> ) . isImm ( ) ) ; MachineOperand & ImmOp = P . first -> getOperand ( J + <NUM_LIT> ) ; ImmOp . setImm ( ImmOp . getImm ( ) + Diff ) ;


<s> return true ; } if ( MI . mayLoadOrStore ( ) && ! isStoreImmediate ( ExtOpc ) ) { unsigned RegOpc , Shift ; unsigned AM = HII -> getAddrMode ( MI ) ; if ( AM == <STR_LIT> ) { RegOpc = HII -> changeAddrMode_io_rr ( ExtOpc ) ; Shift = <NUM_LIT> ; } else if ( AM == <STR_LIT> ) { RegOpc = HII -> changeAddrMode_ur_rr ( ExtOpc ) ; Shift = MI . getOperand ( MI . mayLoad ( ) ? <NUM_LIT> : <NUM_LIT> ) . getImm ( ) ; } else { llvm_unreachable ( <STR_LIT> ) ; } if ( RegOpc == - <NUM_LIT> ) { dbgs ( ) << <STR_LIT> << HII -> getName ( ExtOpc ) << <STR_LIT> ; llvm_unreachable ( <STR_LIT> ) ; } unsigned BaseP , OffP ; HII -> getBaseAndOffsetPosition ( MI , BaseP , OffP ) ; MachineInstrBuilder MIB = BuildMI ( MBB , At , dl , HII -> get ( RegOpc ) ) ; if ( MI . mayLoad ( ) ) MIB . add ( getLoadResultOp ( MI ) ) ; if ( HII -> isPredicated ( MI ) ) MIB . add ( getPredicateOp ( MI ) ) ;


<s> const ExtValue & EV = ExtI . first ; ( void ) EV ; const ExtExpr & Ex = ExtI . second ; ( void ) Ex ; if ( ExtOpc == <STR_LIT> || ExtOpc == <STR_LIT> ) { bool IsAddi = ExtOpc == <STR_LIT> ; const MachineOperand & RegOp = MI . getOperand ( IsAddi ? <NUM_LIT> : <NUM_LIT> ) ; const MachineOperand & ImmOp = MI . getOperand ( IsAddi ? <NUM_LIT> : <NUM_LIT> ) ; assert ( Ex . Rs == RegOp && EV == ImmOp && Ex . Neg != IsAddi && <STR_LIT> ) ; BuildMI ( MBB , At , dl , HII -> get ( TargetOpcode :: COPY ) ) . add ( MI . getOperand ( <NUM_LIT> ) ) . add ( MachineOperand ( ExtR ) ) ; Diff = <NUM_LIT> ; MBB . erase ( MI ) ; return true ; } if ( ExtOpc == <STR_LIT> || ExtOpc == <STR_LIT> || ExtOpc == <STR_LIT> || ExtOpc == <STR_LIT> ) { bool IsSub = ExtOpc == <STR_LIT> ; Register Rs = MI . getOperand ( IsSub ? <NUM_LIT> : <NUM_LIT> ) ; ExtValue V = MI . getOperand ( IsSub ? <NUM_LIT> : <NUM_LIT> ) ; assert ( EV == V && Rs == Ex . Rs && IsSub == Ex . Neg && <STR_LIT> ) ; unsigned NewOpc = ExtOpc == <STR_LIT> ? <STR_LIT> : <STR_LIT> ; BuildMI ( MBB , At , dl , HII -> get ( NewOpc ) ) . add ( MI . getOperand ( <NUM_LIT> ) ) . add ( MI . getOperand ( <NUM_LIT> ) ) . add ( MachineOperand ( ExtR ) ) ; MBB . erase ( MI ) ; return true ;


<s> if ( skipFunction ( MF . getFunction ( ) ) ) return false ; if ( MF . getFunction ( ) . hasPersonalityFn ( ) ) { LLVM_DEBUG ( dbgs ( ) << getPassName ( ) << <STR_LIT> << MF . getName ( ) << <STR_LIT> ) ; return false ; } LLVM_DEBUG ( MF . print ( dbgs ( ) << <STR_LIT> << getPassName ( ) << '\n' , nullptr ) ) ; HST = & MF . getSubtarget < <ISA_LIT>Subtarget > ( ) ; HII = HST -> getInstrInfo ( ) ; HRI = HST -> getRegisterInfo ( ) ; MDT = & getAnalysis < MachineDominatorTree > ( ) ; MRI = & MF . getRegInfo ( ) ; AssignmentMap IMap ; collect ( MF ) ; llvm :: sort ( Extenders , [ this ] ( const ExtDesc & A , const ExtDesc & B ) { ExtValue VA ( A ) , VB ( B ) ; if ( VA != VB ) return VA < VB ; const MachineInstr * MA = A . UseMI ;


<s> HRI = HST -> getRegisterInfo ( ) ; MDT = & getAnalysis < MachineDominatorTree > ( ) ; MRI = & MF . getRegInfo ( ) ; AssignmentMap IMap ; collect ( MF ) ; llvm :: sort ( Extenders , [ this ] ( const ExtDesc & A , const ExtDesc & B ) { ExtValue VA ( A ) , VB ( B ) ; if ( VA != VB ) return VA < VB ; const MachineInstr * MA = A . UseMI ; const MachineInstr * MB = B . UseMI ; if ( MA == MB ) { return A . OpNum < B . OpNum ; } const MachineBasicBlock * BA = MA -> getParent ( ) ; const MachineBasicBlock * BB = MB -> getParent ( ) ;

assert ( BA -> getNumber ( ) != - <NUM_LIT> && BB -> getNumber ( ) != - <NUM_LIT> ) ;


<s> InitI = BuildMI ( MBB , At , dl , HII -> get ( <STR_LIT> ) , DefR ) . add ( ExtOp ) ; } else if ( Ex . S == <NUM_LIT> ) { if ( Ex . Neg ) { InitI = BuildMI ( MBB , At , dl , HII -> get ( <STR_LIT> ) , DefR ) . add ( ExtOp ) . add ( MachineOperand ( Ex . Rs ) ) ; } else { InitI = BuildMI ( MBB , At , dl , HII -> get ( <STR_LIT> ) , DefR ) . add ( MachineOperand ( Ex . Rs ) ) . add ( ExtOp ) ; } } else { unsigned NewOpc = Ex . Neg ? <STR_LIT> : <STR_LIT> ; InitI = BuildMI ( MBB , At , dl , HII -> get ( NewOpc ) , DefR ) . add ( ExtOp ) . add ( MachineOperand ( Ex . Rs ) ) . addImm ( Ex . S ) ; } } assert ( InitI ) ; ( void ) InitI ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << MBB . getNumber ( ) << <STR_LIT> << PrintInit ( ExtI , * HRI ) << <STR_LIT> << * InitI ) ; return { DefR , <NUM_LIT> } ;


<s> for ( unsigned I = Begin ; I != End ; ++ I ) assert ( ER == ExtRoot ( Extenders [ I ] . getOp ( ) ) ) ; std :: vector < OffsetRange > Ranges ( End - Begin ) ; for ( unsigned I = Begin ; I != End ; ++ I ) { const ExtDesc & ED = Extenders [ I ] ; if ( ! ED . IsDef ) continue ; ExtValue EV ( ED ) ; DEBUG ( dbgs ( ) << <STR_LIT> << I << <STR_LIT> << EV << <STR_LIT> << ED << '\n' ) ; assert ( ED . Rd . Reg != <NUM_LIT> ) ; Ranges [ I - Begin ] = getOffsetRange ( ED . Rd ) . shift ( EV . Offset ) ; if ( ED . UseMI -> getOpcode ( ) == <STR_LIT> ) { int32_t D = alignDown ( <NUM_LIT> , Ranges [ I - Begin ] . Align ) ; Ranges [ I - Begin ] . extendBy ( - D ) . extendBy ( D ) ; } } for ( unsigned I = Begin ; I != End ; ++ I ) { const ExtDesc & ED = Extenders [ I ] ; if ( ED . IsDef ) continue ; ExtValue EV ( ED ) ; DEBUG ( dbgs ( ) << <STR_LIT> << I << <STR_LIT> << EV << <STR_LIT> << ED << '\n' ) ; OffsetRange Dev = getOffsetRange ( ED ) ; Ranges [ I - Begin ] . intersect ( Dev . shift ( EV . Offset ) ) ; }

std :: map < OffsetRange , IndexList > RangeMap ;


<s>
for
(
unsigned
I
=
Begin
;
I
!=
End
;
++
I
)
{
const
ExtDesc
&
ED
=
Extenders
[
I
]
;
if
(
ED
.
IsDef
)
continue
;
ExtValue
EV
(
ED
)
;
DEBUG
(
dbgs
(
)
<<
<STR_LIT>
<<
I
<<
<STR_LIT>
<<
EV
<<
<STR_LIT>
<<
ED
<<
'\n'
)
;
OffsetRange
Dev
=
getOffsetRange
(
ED
)
;
Ranges
[
I
Begin
]
.
intersect
(
Dev
.
shift
(
EV
.
Offset
)
)
;
}
std
::
map
<
OffsetRange
,
IndexList
>
RangeMap
;
for
(
unsigned
I
=
Begin
;
I
!=
End
;
++
I
)
RangeMap
[
Ranges
[
I
Begin
]
]
.
insert
(
I
)
;
DEBUG
(
{
dbgs
(
)
<<
<STR_LIT>
;
for
(
unsigned
I
=
Begin
;
I
!=
End
;
++
I
)
dbgs
(
)
<<
<STR_LIT>
<<
I
<<
<STR_LIT>
<<
Ranges
[
I
Begin
]
<<
'\n'
;
dbgs
(
)
<<
<STR_LIT>
;
for
(
auto
&
P
:
RangeMap
)
{
dbgs
(
)
<<
<STR_LIT>
<<
P
.
first
<<
<STR_LIT>
;
for
(
unsigned
I
:
P
.
second
)
dbgs
(
)
<<
' '
<<
I
;


<s> return Min <= V && V <= Max && ( V % Align ) == <NUM_LIT> ;


<s> if ( D < <NUM_LIT> ) Min = ( INT_MIN - D < Min ) ? Min + D : INT_MIN ;

else Max = ( INT_MAX - D > Max ) ? Max + D : INT_MAX ;


<s> else Max = ( INT_MAX - D > Max ) ? Max + D : INT_MAX ;


<s> MachineBasicBlock :: iterator At = DefL . At ; DebugLoc dl = DefL . Block -> findDebugLoc ( DefL . At ) ; const ExtValue & EV = ExtI . first ; MachineOperand ExtOp ( EV ) ; const ExtExpr & Ex = ExtI . second ; const MachineInstr * InitI = nullptr ; if ( Ex . Rs . isSlot ( ) ) { assert ( Ex . S == <NUM_LIT> && <STR_LIT> ) ; assert ( ! Ex . Neg && <STR_LIT> ) ; InitI = BuildMI ( MBB , At , dl , HII -> get ( <STR_LIT> ) , DefR ) . add ( MachineOperand ( Ex . Rs ) ) . add ( ExtOp ) ; } else { assert ( ( Ex . Rs . Reg == <NUM_LIT> || Ex . Rs . isVReg ( ) ) && <STR_LIT> ) ; if ( Ex . trivial ( ) ) { InitI = BuildMI ( MBB , At , dl , HII -> get ( <STR_LIT> ) , DefR ) . add ( ExtOp ) ; } else if ( Ex . S == <NUM_LIT> ) { if ( Ex . Neg ) { InitI = BuildMI ( MBB , At , dl , HII -> get ( <STR_LIT> ) , DefR ) . add ( ExtOp ) . add ( MachineOperand ( Ex . Rs ) ) ; } else { InitI = BuildMI ( MBB , At , dl , HII -> get ( <STR_LIT> ) , DefR ) . add ( MachineOperand ( Ex . Rs ) ) . add ( ExtOp ) ; } } else { unsigned NewOpc = Ex . Neg ? <STR_LIT> : <STR_LIT> ; InitI = BuildMI ( MBB , At , dl , HII -> get ( NewOpc ) , DefR ) . add ( ExtOp ) . add ( MachineOperand ( Ex . Rs ) ) . addImm ( Ex . S ) ; } } assert ( InitI ) ; ( void ) InitI ; DEBUG ( dbgs ( ) << <STR_LIT> << MBB . getNumber ( ) << <STR_LIT> << PrintInit ( ExtI , * HRI ) << <STR_LIT> << * InitI ) ; return { DefR , <NUM_LIT> } ;


<s> InitI = BuildMI ( MBB , At , dl , HII -> get ( <STR_LIT> ) , DefR ) . add ( ExtOp ) . add ( MachineOperand ( Ex . Rs ) ) ; } else { InitI = BuildMI ( MBB , At , dl , HII -> get ( <STR_LIT> ) , DefR ) . add ( MachineOperand ( Ex . Rs ) ) . add ( ExtOp ) ; } } else { unsigned NewOpc = Ex . Neg ? <STR_LIT> : <STR_LIT> ; InitI = BuildMI ( MBB , At , dl , HII -> get ( NewOpc ) , DefR ) . add ( ExtOp ) . add ( MachineOperand ( Ex . Rs ) ) . addImm ( Ex . S ) ; } } assert ( InitI ) ; ( void ) InitI ;

DEBUG ( dbgs ( ) << <STR_LIT> << MBB . getNumber ( ) << <STR_LIT> << PrintInit ( ExtI , * HRI ) << <STR_LIT> << * InitI ) ;


<s> Align = std :: max ( Align , A . Align ) ; Min = std :: max ( Min , A . Min ) ; Max = std :: min ( Max , A . Max ) ; if ( Min > Max ) std :: tie ( Min , Max , Align ) = std :: make_tuple ( <NUM_LIT> , - <NUM_LIT> , <NUM_LIT> ) ; return * this ;


<s> OffsetRange ( int32_t L , int32_t H , uint8_t A ) : Min ( L ) , Max ( H ) , Align ( A ) {


<s> ED . IsDef = true ; break ; case <STR_LIT> : if ( ! isStoreImmediate ( Opc ) ) ED . Expr . Rs = MI . getOperand ( OpNum - <NUM_LIT> ) ; break ; case <STR_LIT> : ED . Expr . Rs = MI . getOperand ( OpNum - <NUM_LIT> ) ; ED . Expr . S = MI . getOperand ( OpNum - <NUM_LIT> ) . getImm ( ) ; break ; default : llvm_unreachable ( <STR_LIT> ) ; } } else { switch ( Opc ) { case <STR_LIT> : ED . Rd = MI . getOperand ( <NUM_LIT> ) ; ED . IsDef = true ; break ; case <STR_LIT> : case <STR_LIT> : ED . Rd = { MI . getOperand ( <NUM_LIT> ) . getReg ( ) , <STR_LIT> } ; ED . IsDef = true ; break ; case <STR_LIT> : ED . Rd = { MI . getOperand ( <NUM_LIT> ) . getReg ( ) , <STR_LIT> } ; ED . IsDef = true ; break ; case <STR_LIT> : ED . Rd = MI . getOperand ( <NUM_LIT> ) ; ED . Expr . Rs = MI . getOperand ( OpNum - <NUM_LIT> ) ; break ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : ED . Expr . Rs = MI . getOperand ( OpNum - <NUM_LIT> ) ; break ; case <STR_LIT> : ED . Rd = MI . getOperand ( <NUM_LIT> ) ; ED . Expr . Rs = MI . getOperand ( OpNum + <NUM_LIT> ) ; ED . Expr . Neg = true ; break ; case <STR_LIT> : ED . Expr . Rs = MI . getOperand ( OpNum + <NUM_LIT> ) ; ED . Expr . Neg = true ; default : break ;


<s> } } bool Replaced = false ; if ( Diff == <NUM_LIT> && DefEx . trivial ( ) && ! IsAbs && ! IsAbsSet ) Replaced = replaceInstrExact ( ED , ExtR ) ; else Replaced = replaceInstrExpr ( ED , ExtI , ExtR , Diff ) ; if ( Diff != <NUM_LIT> && Replaced && ED . IsDef ) { for ( std :: pair < MachineInstr * , unsigned > P : RegOps ) { unsigned J = P . second ; assert ( P . first -> getNumOperands ( ) > J + <NUM_LIT> && P . first -> getOperand ( J + <NUM_LIT> ) . isImm ( ) ) ; MachineOperand & ImmOp = P . first -> getOperand ( J + <NUM_LIT> ) ; ImmOp . setImm ( ImmOp . getImm ( ) + Diff ) ; }


<s> unsigned IdxOpc = getRegOffOpcode ( ExtOpc ) ; assert ( IdxOpc == <STR_LIT> ) ; int32_t D = isInt < <NUM_LIT> > ( Diff ) ? Diff : ( Diff > <NUM_LIT> ? <NUM_LIT> : - <NUM_LIT> ) ; BuildMI ( MBB , At , dl , HII -> get ( IdxOpc ) ) . add ( MI . getOperand ( <NUM_LIT> ) ) . add ( MachineOperand ( ExtR ) ) . addImm ( D ) ; Diff -= D ; OffsetRange Uses = getOffsetRange ( MI . getOperand ( <NUM_LIT> ) ) ; if ( ! Uses . contains ( Diff ) ) dbgs ( ) << <STR_LIT> << Diff << <STR_LIT> << Uses << <STR_LIT> << MI ; assert ( Uses . contains ( Diff ) ) ; MBB . erase ( MI ) ; return true ; } const ExtValue & EV = ExtI . first ; ( void ) EV ; const ExtExpr & Ex = ExtI . second ; ( void ) Ex ; if ( ExtOpc == <STR_LIT> || ExtOpc == <STR_LIT> ) { bool IsAddi = ExtOpc == <STR_LIT> ; const MachineOperand & RegOp = MI . getOperand ( IsAddi ? <NUM_LIT> : <NUM_LIT> ) ; const MachineOperand & ImmOp = MI . getOperand ( IsAddi ? <NUM_LIT> : <NUM_LIT> ) ; assert ( Ex . Rs == RegOp && EV == ImmOp && Ex . Neg != IsAddi && <STR_LIT> ) ; BuildMI ( MBB , At , dl , HII -> get ( TargetOpcode :: COPY ) ) . add ( MI . getOperand ( <NUM_LIT> ) ) . add ( MachineOperand ( ExtR ) ) ; Diff = <NUM_LIT> ; MBB . erase ( MI ) ; return true ; } if ( ExtOpc == <STR_LIT> || ExtOpc == <STR_LIT> || ExtOpc == <STR_LIT> || ExtOpc == <STR_LIT> ) { bool IsSub = ExtOpc == <STR_LIT> ; Register Rs = MI . getOperand ( IsSub ? <NUM_LIT> : <NUM_LIT> ) ; ExtValue V = MI . getOperand ( IsSub ? <NUM_LIT> : <NUM_LIT> ) ; assert ( EV == V && Rs == Ex . Rs && IsSub == Ex . Neg && <STR_LIT> ) ; unsigned NewOpc = ExtOpc == <STR_LIT> ? <STR_LIT> : <STR_LIT> ; BuildMI ( MBB , At , dl , HII -> get ( NewOpc ) ) . add ( MI . getOperand ( <NUM_LIT> ) ) . add ( MI . getOperand ( <NUM_LIT> ) ) . add ( MachineOperand ( ExtR ) ) ; MBB . erase ( MI ) ; return true ; }

if ( MI . mayLoad ( ) || MI . mayStore ( ) ) {


<s> for ( unsigned I = <NUM_LIT> , E = Extenders . size ( ) ; I != E ; ) { unsigned B = I ; const ExtRoot & T = Extenders [ B ] . getOp ( ) ; while ( I != E && ExtRoot ( Extenders [ I ] . getOp ( ) ) == T ) ++ I ; IMap . clear ( ) ; assignInits ( T , B , I , IMap ) ; Changed |= replaceExtenders ( IMap ) ; } DEBUG ( { if ( Changed ) MF . print ( dbgs ( ) << <STR_LIT> << getPassName ( ) << '\n' , nullptr ) ;


<s> assert ( alignTo ( std :: abs ( S ) , Align ) == uint64_t ( std :: abs ( S ) ) ) ; Min += S ; Max += S ; return * this ;


<s> AssignmentMap IMap ; collect ( MF ) ; std :: sort ( Extenders . begin ( ) , Extenders . end ( ) , [ ] ( const ExtDesc & A , const ExtDesc & B ) { return ExtValue ( A ) < ExtValue ( B ) ; } ) ; bool Changed = false ; DEBUG ( dbgs ( ) << <STR_LIT> << Extenders . size ( ) << <STR_LIT> ) ; for ( unsigned I = <NUM_LIT> , E = Extenders . size ( ) ; I != E ; ) { unsigned B = I ; const ExtRoot & T = Extenders [ B ] . getOp ( ) ; while ( I != E && ExtRoot ( Extenders [ I ] . getOp ( ) ) == T ) ++ I ;


<s> bool Changed = false ; DEBUG ( dbgs ( ) << <STR_LIT> << Extenders . size ( ) << <STR_LIT> ) ; for ( unsigned I = <NUM_LIT> , E = Extenders . size ( ) ; I != E ; ) { unsigned B = I ; const ExtRoot & T = Extenders [ B ] . getOp ( ) ; while ( I != E && ExtRoot ( Extenders [ I ] . getOp ( ) ) == T ) ++ I ; IMap . clear ( ) ; assignInits ( T , B , I , IMap ) ; Changed |= replaceExtenders ( IMap ) ; } DEBUG ( { if ( Changed ) MF . print ( dbgs ( ) << <STR_LIT> << getPassName ( ) << '\n' , nullptr ) ; else dbgs ( ) << <STR_LIT> ; } ) ; return Changed ;


<s> MDT = & getAnalysis < MachineDominatorTree > ( ) ; MRI = & MF . getRegInfo ( ) ; AssignmentMap IMap ; collect ( MF ) ; llvm :: sort ( Extenders . begin ( ) , Extenders . end ( ) , [ ] ( const ExtDesc & A , const ExtDesc & B ) { return ExtValue ( A ) < ExtValue ( B ) ; } ) ; bool Changed = false ; DEBUG ( dbgs ( ) << <STR_LIT> << Extenders . size ( ) << <STR_LIT> ) ; for ( unsigned I = <NUM_LIT> , E = Extenders . size ( ) ; I != E ; ) { unsigned B = I ; const ExtRoot & T = Extenders [ B ] . getOp ( ) ;


<s> for ( unsigned I = <NUM_LIT> , E = Extenders . size ( ) ; I != E ; ) { unsigned B = I ; const ExtRoot & T = Extenders [ B ] . getOp ( ) ; while ( I != E && ExtRoot ( Extenders [ I ] . getOp ( ) ) == T ) ++ I ; IMap . clear ( ) ; assignInits ( T , B , I , IMap ) ; Changed |= replaceExtenders ( IMap ) ; } DEBUG ( {

if ( Changed ) MF . print ( dbgs ( ) << <STR_LIT> << getPassName ( ) << '\n' , nullptr ) ;


<s> assert ( Ex . S == <NUM_LIT> && <STR_LIT> ) ; assert ( ! Ex . Neg && <STR_LIT> ) ; InitI = BuildMI ( MBB , At , dl , HII -> get ( <STR_LIT> ) , DefR ) . add ( MachineOperand ( Ex . Rs ) ) . add ( ExtOp ) ; } else { assert ( ( Ex . Rs . Reg == <NUM_LIT> || Ex . Rs . isVReg ( ) ) && <STR_LIT> ) ; if ( Ex . trivial ( ) ) { InitI = BuildMI ( MBB , At , dl , HII -> get ( <STR_LIT> ) , DefR ) . add ( ExtOp ) ; } else if ( Ex . S == <NUM_LIT> ) { if ( Ex . Neg ) { InitI = BuildMI ( MBB , At , dl , HII -> get ( <STR_LIT> ) , DefR ) . add ( ExtOp ) . add ( MachineOperand ( Ex . Rs ) ) ; } else { InitI = BuildMI ( MBB , At , dl , HII -> get ( <STR_LIT> ) , DefR ) . add ( MachineOperand ( Ex . Rs ) ) . add ( ExtOp ) ; }


return Reg != <NUM_LIT> && Reg . isStack ( ) ;


<s> return Reg != <NUM_LIT> && Reg . isStack ( ) ;


<s> return Reg != <NUM_LIT> && ! Reg . isStack ( ) && Reg . isVirtual ( ) ;


<s> Register ( llvm :: Register R , unsigned S ) : Reg ( R ) , Sub ( S ) {


<s> ED . Expr . Rs = MI . getOperand ( OpNum - <NUM_LIT> ) ; break ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : ED . Expr . Rs = MI . getOperand ( OpNum - <NUM_LIT> ) ; break ; case <STR_LIT> : ED . Rd = MI . getOperand ( <NUM_LIT> ) ; ED . Expr . Rs = MI . getOperand ( OpNum + <NUM_LIT> ) ; ED . Expr . Neg = true ; break ; case <STR_LIT> : ED . Expr . Rs = MI . getOperand ( OpNum + <NUM_LIT> ) ; ED . Expr . Neg = true ; default : break ; } } ED . UseMI = & MI ; ExtRoot ER ( ED . getOp ( ) ) ; if ( ER . Kind == MachineOperand :: MO_GlobalAddress ) if ( ER . V . GV -> getName ( ) . empty ( ) ) return ; Extenders . push_back ( ED ) ;


<s> break ; default : llvm_unreachable ( <STR_LIT> ) ; } } else { switch ( Opc ) { case <STR_LIT> : ED . Rd = MI . getOperand ( <NUM_LIT> ) ; ED . IsDef = true ; break ; case <STR_LIT> : case <STR_LIT> : ED . Rd = { MI . getOperand ( <NUM_LIT> ) . getReg ( ) , <STR_LIT> } ; ED . IsDef = true ; break ; case <STR_LIT> : ED . Rd = { MI . getOperand ( <NUM_LIT> ) . getReg ( ) , <STR_LIT> } ; ED . IsDef = true ; break ; case <STR_LIT> : ED . Rd = MI . getOperand ( <NUM_LIT> ) ; ED . Expr . Rs = MI . getOperand ( OpNum - <NUM_LIT> ) ; break ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : ED . Expr . Rs = MI . getOperand ( OpNum - <NUM_LIT> ) ;


<s> const ExtExpr & Ex = ExtI . second ; ( void ) Ex ; if ( ExtOpc == <STR_LIT> || ExtOpc == <STR_LIT> ) { bool IsAddi = ExtOpc == <STR_LIT> ; const MachineOperand & RegOp = MI . getOperand ( IsAddi ? <NUM_LIT> : <NUM_LIT> ) ; const MachineOperand & ImmOp = MI . getOperand ( IsAddi ? <NUM_LIT> : <NUM_LIT> ) ; assert ( Ex . Rs == RegOp && EV == ImmOp && Ex . Neg != IsAddi && <STR_LIT> ) ; BuildMI ( MBB , At , dl , HII -> get ( TargetOpcode :: COPY ) ) . add ( MI . getOperand ( <NUM_LIT> ) ) . add ( MachineOperand ( ExtR ) ) ; Diff = <NUM_LIT> ; MBB . erase ( MI ) ; return true ; } if ( ExtOpc == <STR_LIT> || ExtOpc == <STR_LIT> || ExtOpc == <STR_LIT> || ExtOpc == <STR_LIT> ) { bool IsSub = ExtOpc == <STR_LIT> ; Register Rs = MI . getOperand ( IsSub ? <NUM_LIT> : <NUM_LIT> ) ; ExtValue V = MI . getOperand ( IsSub ? <NUM_LIT> : <NUM_LIT> ) ; assert ( EV == V && Rs == Ex . Rs && IsSub == Ex . Neg && <STR_LIT> ) ; unsigned NewOpc = ExtOpc == <STR_LIT> ? <STR_LIT> : <STR_LIT> ; BuildMI ( MBB , At , dl , HII -> get ( NewOpc ) ) . add ( MI . getOperand ( <NUM_LIT> ) ) . add ( MI . getOperand ( <NUM_LIT> ) ) . add ( MachineOperand ( ExtR ) ) ; MBB . erase ( MI ) ; return true ; } if ( MI . mayLoad ( ) || MI . mayStore ( ) ) { unsigned IdxOpc = getRegOffOpcode ( ExtOpc ) ; assert ( IdxOpc && <STR_LIT> ) ; MachineInstrBuilder MIB = BuildMI ( MBB , At , dl , HII -> get ( IdxOpc ) ) ; if ( MI . mayLoad ( ) ) MIB . add ( getLoadResultOp ( MI ) ) ; if ( HII -> isPredicated ( MI ) ) MIB . add ( getPredicateOp ( MI ) ) ; MIB . add ( MachineOperand ( ExtR ) ) ; MIB . addImm ( Diff ) ; if ( MI . mayStore ( ) ) MIB . add ( getStoredValueOp ( MI ) ) ; MIB . cloneMemRefs ( MI ) ; MBB . erase ( MI ) ; return true ; } dbgs ( ) << '\n' << PrintInit ( ExtI , * HRI ) << <STR_LIT> << MI ; llvm_unreachable ( <STR_LIT> ) ; return false ;


<s> LLVM_DEBUG ( dbgs ( ) << getPassName ( ) << <STR_LIT> << MF . getName ( ) << <STR_LIT> ) ; return false ; } LLVM_DEBUG ( MF . print ( dbgs ( ) << <STR_LIT> << getPassName ( ) << '\n' , nullptr ) ) ; HII = MF . getSubtarget < <ISA_LIT>Subtarget > ( ) . getInstrInfo ( ) ; HRI = MF . getSubtarget < <ISA_LIT>Subtarget > ( ) . getRegisterInfo ( ) ; MDT = & getAnalysis < MachineDominatorTree > ( ) ; MRI = & MF . getRegInfo ( ) ; AssignmentMap IMap ; collect ( MF ) ; llvm :: sort ( Extenders , [ ] ( const ExtDesc & A , const ExtDesc & B ) { return ExtValue ( A ) < ExtValue ( B ) ; } ) ; bool Changed = false ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << Extenders . size ( ) << <STR_LIT> ) ; for ( unsigned I = <NUM_LIT> , E = Extenders . size ( ) ; I != E ; ) { unsigned B = I ; const ExtRoot & T = Extenders [ B ] . getOp ( ) ; while ( I != E && ExtRoot ( Extenders [ I ] . getOp ( ) ) == T ) ++ I ; IMap . clear ( ) ; assignInits ( T , B , I , IMap ) ; Changed |= replaceExtenders ( IMap ) ;


<s> RefMIs . insert ( ED . UseMI ) ; DomB = MDT -> findNearestCommonDominator ( DomB , MBB ) ; Blocks . insert ( MBB ) ; } Register Rs = ExtI . second . Rs ; const MachineInstr * DefI = Rs . isVReg ( ) ? MRI -> getVRegDef ( Rs . Reg ) : nullptr ; assert ( ! DefI || MDT -> dominates ( DefI -> getParent ( ) , DomB ) ) ; MachineBasicBlock :: iterator It ; if ( Blocks . count ( DomB ) ) { MachineBasicBlock :: iterator End = DomB -> end ( ) ; for ( It = DomB -> begin ( ) ; It != End ; ++ It ) if ( RefMIs . count ( & * It ) ) break ; assert ( It != End && <STR_LIT> ) ; } else { It = DomB -> getFirstTerminator ( ) ; } Loc DefLoc ( DomB , It ) ; Defs . emplace ( DefLoc , Refs ) ;


<s> Extenders . clear ( ) ; for ( MachineBasicBlock & MBB : MF ) for ( MachineInstr & MI : MBB ) collectInstr ( MI ) ;


<s> void HCE :: collect ( MachineFunction & MF ) {


<s> ED . OpNum = OpNum ; bool IsLoad = MI . mayLoad ( ) ; bool IsStore = MI . mayStore ( ) ; for ( MachineOperand & Op : MI . operands ( ) ) if ( Op . isFI ( ) && Op . getIndex ( ) < <NUM_LIT> ) return ; if ( IsLoad || IsStore ) { unsigned AM = HII -> getAddrMode ( MI ) ; switch ( AM ) { case <STR_LIT> : break ; case <STR_LIT> : ED . Rd = MI . getOperand ( OpNum - <NUM_LIT> ) ; ED . IsDef = true ; break ; case <STR_LIT> : if ( ! isStoreImmediate ( Opc ) ) ED . Expr . Rs = MI . getOperand ( OpNum - <NUM_LIT> ) ; break ; case <STR_LIT> : ED . Expr . Rs = MI . getOperand ( OpNum - <NUM_LIT> ) ; ED . Expr . S = MI . getOperand ( OpNum - <NUM_LIT> ) . getImm ( ) ; break ; default : llvm_unreachable ( <STR_LIT> ) ; } } else { switch ( Opc ) { case <STR_LIT> : ED . Rd = MI . getOperand ( <NUM_LIT> ) ; ED . IsDef = true ; break ; case <STR_LIT> : case <STR_LIT> : ED . Rd = { MI . getOperand ( <NUM_LIT> ) . getReg ( ) , <STR_LIT> } ; ED . IsDef = true ; break ; case <STR_LIT> : ED . Rd = { MI . getOperand ( <NUM_LIT> ) . getReg ( ) , <STR_LIT> } ; ED . IsDef = true ; break ; case <STR_LIT> : ED . Rd = MI . getOperand ( <NUM_LIT> ) ; ED . Expr . Rs = MI . getOperand ( OpNum - <NUM_LIT> ) ; break ; case <STR_LIT> :


<s> bool Changed = false ; for ( const std :: pair < ExtenderInit , IndexList > & P : IMap ) { const IndexList & Idxs = P . second ;

if ( Idxs . size ( ) < CountThreshold ) continue ;


<s> BuildMI ( MBB , At , dl , HII -> get ( TargetOpcode :: COPY ) ) . add ( MI . getOperand ( <NUM_LIT> ) ) . add ( MachineOperand ( ExtR ) ) ; Diff = <NUM_LIT> ; MBB . erase ( MI ) ; return true ; } if ( ExtOpc == <STR_LIT> || ExtOpc == <STR_LIT> || ExtOpc == <STR_LIT> || ExtOpc == <STR_LIT> ) { bool IsSub = ExtOpc == <STR_LIT> ; Register Rs = MI . getOperand ( IsSub ? <NUM_LIT> : <NUM_LIT> ) ; ExtValue V = MI . getOperand ( IsSub ? <NUM_LIT> : <NUM_LIT> ) ; assert ( EV == V && Rs == Ex . Rs && IsSub == Ex . Neg && <STR_LIT> ) ; unsigned NewOpc = ExtOpc == <STR_LIT> ? <STR_LIT> : <STR_LIT> ; BuildMI ( MBB , At , dl , HII -> get ( NewOpc ) ) . add ( MI . getOperand ( <NUM_LIT> ) ) . add ( MI . getOperand ( <NUM_LIT> ) ) . add ( MachineOperand ( ExtR ) ) ; MBB . erase ( MI ) ; return true ; } if ( MI . mayLoad ( ) || MI . mayStore ( ) ) { unsigned IdxOpc = getRegOffOpcode ( ExtOpc ) ; assert ( IdxOpc && <STR_LIT> ) ; MachineInstrBuilder MIB = BuildMI ( MBB , At , dl , HII -> get ( IdxOpc ) ) ; if ( MI . mayLoad ( ) ) MIB . add ( getLoadResultOp ( MI ) ) ; if ( HII -> isPredicated ( MI ) ) MIB . add ( getPredicateOp ( MI ) ) ; MIB . add ( MachineOperand ( ExtR ) ) ; MIB . addImm ( Diff ) ; if ( MI . mayStore ( ) ) MIB . add ( getStoredValueOp ( MI ) ) ; MIB . setMemRefs ( MI . memoperands_begin ( ) , MI . memoperands_end ( ) ) ; MBB . erase ( MI ) ; return true ; } dbgs ( ) << '\n' << PrintInit ( ExtI , * HRI ) << <STR_LIT> << MI ; llvm_unreachable ( <STR_LIT> ) ; return false ;


<s> } if ( ExtOpc == <STR_LIT> || ExtOpc == <STR_LIT> || ExtOpc == <STR_LIT> || ExtOpc == <STR_LIT> ) { bool IsSub = ExtOpc == <STR_LIT> ; Register Rs = MI . getOperand ( IsSub ? <NUM_LIT> : <NUM_LIT> ) ; ExtValue V = MI . getOperand ( IsSub ? <NUM_LIT> : <NUM_LIT> ) ; assert ( EV == V && Rs == Ex . Rs && IsSub == Ex . Neg && <STR_LIT> ) ; unsigned NewOpc = ExtOpc == <STR_LIT> ? <STR_LIT> : <STR_LIT> ; BuildMI ( MBB , At , dl , HII -> get ( NewOpc ) ) . add ( MI . getOperand ( <NUM_LIT> ) ) . add ( MI . getOperand ( <NUM_LIT> ) ) . add ( MachineOperand ( ExtR ) ) ; MBB . erase ( MI ) ; return true ; } if ( MI . mayLoad ( ) || MI . mayStore ( ) ) { unsigned IdxOpc = getRegOffOpcode ( ExtOpc ) ; assert ( IdxOpc && <STR_LIT> ) ; MachineInstrBuilder MIB = BuildMI ( MBB , At , dl , HII -> get ( IdxOpc ) ) ; if ( MI . mayLoad ( ) ) MIB . add ( getLoadResultOp ( MI ) ) ;

if ( HII -> isPredicated ( MI ) ) MIB . add ( getPredicateOp ( MI ) ) ;


<s> HII = MF . getSubtarget < <ISA_LIT>Subtarget > ( ) . getInstrInfo ( ) ; HRI = MF . getSubtarget < <ISA_LIT>Subtarget > ( ) . getRegisterInfo ( ) ; MDT = & getAnalysis < MachineDominatorTree > ( ) ; MRI = & MF . getRegInfo ( ) ; AssignmentMap IMap ; collect ( MF ) ; llvm :: sort ( Extenders . begin ( ) , Extenders . end ( ) , [ ] ( const ExtDesc & A , const ExtDesc & B ) { return ExtValue ( A ) < ExtValue ( B ) ; } ) ; bool Changed = false ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << Extenders . size ( ) << <STR_LIT> ) ;

for ( unsigned I = <NUM_LIT> , E = Extenders . size ( ) ; I != E ; ) {


<s> MachineFunction :: const_iterator BI = MB -> getIterator ( ) ; MachineFunction :: const_iterator NextI = std :: next ( BI ) ; if ( NextI != MB -> getParent ( ) -> end ( ) ) Targets . insert ( & * NextI ) ; } for ( const MachineBasicBlock * SB : MB -> successors ( ) ) if ( SB -> isEHPad ( ) ) Targets . insert ( SB ) ;


<s> assert ( Inputs . has ( PR . Reg ) ) ; const LatticeCell & PredC = Inputs . get ( PR . Reg ) ; if ( PredC . isBottom ( ) ) goto Undetermined ; uint32_t Props = PredC . properties ( ) ; bool CTrue = false , CFalse = false ; if ( Props & ConstantProperties :: Zero ) CFalse = true ; else if ( Props & ConstantProperties :: NonZero ) CTrue = true ; if ( ! CTrue && ! CFalse ) goto Undetermined ; const MachineBasicBlock * BranchTarget = BrI . getOperand ( <NUM_LIT> ) . getMBB ( ) ;


<s> if ( ! Src2 . isImm ( ) ) return false ; APInt A ( <NUM_LIT> , Src2 . getImm ( ) , true ) ; Eval = evaluateANDri ( R1 , A , Inputs , RC ) ; break ; } case <STR_LIT> : case <STR_LIT> : Eval = evaluateORrr ( R1 , Register ( Src2 ) , Inputs , RC ) ; break ; case <STR_LIT> : { if ( ! Src2 . isImm ( ) ) return false ; APInt A ( <NUM_LIT> , Src2 . getImm ( ) , true ) ; Eval = evaluateORri ( R1 , A , Inputs , RC ) ; break ; } case <STR_LIT> : case <STR_LIT> :

Eval = evaluateXORrr ( R1 , Register ( Src2 ) , Inputs , RC ) ;


<s> const MachineOperand & Src2 = MI . getOperand ( <NUM_LIT> ) ; Register R1 ( Src1 ) ; bool Eval = false ; LatticeCell RC ; switch ( Opc ) { default : return false ; case <STR_LIT> : case <STR_LIT> : Eval = evaluateANDrr ( R1 , Register ( Src2 ) , Inputs , RC ) ; break ; case <STR_LIT> : { if ( ! Src2 . isImm ( ) ) return false ; APInt A ( <NUM_LIT> , Src2 . getImm ( ) , true ) ; Eval = evaluateANDri ( R1 , A , Inputs , RC ) ; break ; } case <STR_LIT> : case <STR_LIT> : Eval = evaluateORrr ( R1 , Register ( Src2 ) , Inputs , RC ) ;


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


<s> MachineConstEvaluator ( MachineFunction & Fn ) : TRI ( * Fn . getSubtarget ( ) . getRegisterInfo ( ) ) , MF ( Fn ) , CX ( Fn . getFunction ( ) . getContext ( ) ) {


<s> if ( ! It -> isDebugInstr ( ) ) { InstrExec . insert ( & * It ) ; visitNonBranch ( * It ) ; } ++ It ; } if ( It != End ) { visitBranchesFrom ( * It ) ; } else { unsigned SBN = SB -> getNumber ( ) ; for ( const MachineBasicBlock * SSB : SB -> successors ( ) ) FlowQ . push ( CFGEdge ( SBN , SSB -> getNumber ( ) ) ) ; } } LLVM_DEBUG ( { dbgs ( ) << <STR_LIT> ; Cells . print ( dbgs ( ) , MCE . TRI ) ; dbgs ( ) << <STR_LIT> ; for ( const MachineBasicBlock & B : MF ) { unsigned BN = B . getNumber ( ) ; for ( const MachineBasicBlock * SB : B . successors ( ) ) { unsigned SN = SB -> getNumber ( ) ;

if ( ! EdgeExec . count ( CFGEdge ( BN , SN ) ) ) dbgs ( ) << <STR_LIT> << printMBBReference ( B ) << <STR_LIT> << printMBBReference ( * SB ) << '\n' ;


<s> EdgeExec . clear ( ) ; InstrExec . clear ( ) ; assert ( FlowQ . empty ( ) ) ; propagate ( MF ) ; bool Changed = rewrite ( MF ) ; LLVM_DEBUG ( { dbgs ( ) << <STR_LIT> << Changed << <STR_LIT> ; if ( Changed ) MF . print ( dbgs ( ) , nullptr ) ;


<s> bool runOnMachineFunction ( MachineFunction & MF ) override { const Function & F = MF . getFunction ( ) ;

if ( skipFunction ( F ) ) return false ;


<s> <ISA_LIT>ConstEvaluator HCE ( MF ) ;

return MachineConstPropagator ( HCE ) . run ( MF ) ;


<s> while ( It != End ) { const MachineInstr & MI = * It ; InstrExec . insert ( & MI ) ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << ( EvalOk ? <STR_LIT> : <STR_LIT> ) << <STR_LIT> << printMBBReference ( B ) << <STR_LIT> << MI ) ; EvalOk = EvalOk && MCE . evaluate ( MI , Cells , Targets , FallsThru ) ; if ( ! EvalOk ) FallsThru = true ; if ( ! FallsThru ) break ; ++ It ; } if ( EvalOk ) {

for ( const MachineBasicBlock * SB : B . successors ( ) ) {


<s> bool Changed = false ; if ( ! Eval ) { const LatticeCell & T = Cells . get ( DefR . Reg ) ; Changed = ! T . isBottom ( ) ; Cells . update ( DefR . Reg , Bottom ) ; } else { if ( ! Outputs . has ( DefR . Reg ) ) continue ; LatticeCell RC = Cells . get ( DefR . Reg ) ;

Changed = RC . meet ( Outputs . get ( DefR . Reg ) ) ;


<s> bool Changed = false ; if ( DefR . SubReg ) { Bottomize : const LatticeCell & T = Cells . get ( DefR . Reg ) ; Changed = ! T . isBottom ( ) ; Cells . update ( DefR . Reg , Bottom ) ; if ( Changed ) visitUsesOf ( DefR . Reg ) ; return ; } LatticeCell DefC = Cells . get ( DefR . Reg ) ; for ( unsigned i = <NUM_LIT> , n = PN . getNumOperands ( ) ; i < n ; i += <NUM_LIT> ) { const MachineBasicBlock * PB = PN . getOperand ( i + <NUM_LIT> ) . getMBB ( ) ; unsigned PBN = PB -> getNumber ( ) ; if ( ! EdgeExec . count ( CFGEdge ( PBN , MBN ) ) ) { LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << printMBBReference ( * PB ) << <STR_LIT> << printMBBReference ( * MB ) << <STR_LIT> ) ; continue ; } const MachineOperand & SO = PN . getOperand ( i ) ; Register UseR ( SO ) ; if ( ! TargetRegisterInfo :: isVirtualRegister ( UseR . Reg ) ) goto Bottomize ;

if ( ! Cells . has ( UseR . Reg ) ) continue ;


<s> LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << printReg ( Reg , & MCE . TRI ) << Cells . get ( Reg ) << '\n' ) ;

for ( MachineInstr & MI : MRI -> use_nodbg_instructions ( Reg ) ) {


<s> } if ( SimpleBranch ) { const MachineOperand & MD = BrI . getOperand ( <NUM_LIT> ) ; RegisterSubReg PR ( MD ) ; if ( PR . SubReg ) goto Undetermined ; assert ( Inputs . has ( PR . Reg ) ) ; const LatticeCell & PredC = Inputs . get ( PR . Reg ) ; if ( PredC . isBottom ( ) ) goto Undetermined ; uint32_t Props = PredC . properties ( ) ; bool CTrue = false , CFalse = false ; if ( Props & ConstantProperties :: Zero ) CFalse = true ; else if ( Props & ConstantProperties :: NonZero ) CTrue = true ; if ( ! CTrue && ! CFalse ) goto Undetermined ; const MachineBasicBlock * BranchTarget = BrI . getOperand ( <NUM_LIT> ) . getMBB ( ) ; FallsThru = false ; if ( ( ! Negated && CTrue ) || ( Negated && CFalse ) ) Targets . insert ( BranchTarget ) ;

else if ( ( ! Negated && CFalse ) || ( Negated && CTrue ) ) FallsThru = true ;


<s> case <STR_LIT> : Negated = true ; LLVM_FALLTHROUGH ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : SimpleBranch = true ; break ; case <STR_LIT> : Targets . insert ( BrI . getOperand ( <NUM_LIT> ) . getMBB ( ) ) ; FallsThru = false ; return true ; default : Undetermined : FallsThru = ! BrI . isUnconditionalBranch ( ) ; return false ; } if ( SimpleBranch ) { const MachineOperand & MD = BrI . getOperand ( <NUM_LIT> ) ; RegisterSubReg PR ( MD ) ; if ( PR . SubReg ) goto Undetermined ; assert ( Inputs . has ( PR . Reg ) ) ; const LatticeCell & PredC = Inputs . get ( PR . Reg ) ; if ( PredC . isBottom ( ) ) goto Undetermined ; uint32_t Props = PredC . properties ( ) ; bool CTrue = false , CFalse = false ; if ( Props & ConstantProperties :: Zero ) CFalse = true ; else if ( Props & ConstantProperties :: NonZero ) CTrue = true ; if ( ! CTrue && ! CFalse ) goto Undetermined ; const MachineBasicBlock * BranchTarget = BrI . getOperand ( <NUM_LIT> ) . getMBB ( ) ; FallsThru = false ; if ( ( ! Negated && CTrue ) || ( Negated && CFalse ) ) Targets . insert ( BranchTarget ) ; else if ( ( ! Negated && CFalse ) || ( Negated && CTrue ) ) FallsThru = true ; else goto Undetermined ;


<s> for ( unsigned i = <NUM_LIT> ; i < LS1 . size ( ) ; ++ i ) { bool Eval = constToInt ( LS1 . Values [ i ] , A ) && evaluateANDii ( A , A2 , ResA ) ; if ( ! Eval ) return false ; const Constant * C = intToConst ( ResA ) ; Result . add ( C ) ;


<s> RC . add ( intToConst ( A2 ) ) ; Result = RC ; return true ; } LatticeCell LS1 ; if ( ! getCell ( R1 , Inputs , LS1 ) ) return false ; if ( LS1 . isBottom ( ) || LS1 . isProperty ( ) ) return false ; APInt A , ResA ; for ( unsigned i = <NUM_LIT> ; i < LS1 . size ( ) ; ++ i ) {

bool Eval = constToInt ( LS1 . Values [ i ] , A ) && evaluateANDii ( A , A2 , ResA ) ;


<s> APInt A ; for ( unsigned i = <NUM_LIT> ; i < LS2 . size ( ) ; ++ i ) { LatticeCell RC ; bool Eval = constToInt ( LS2 . Values [ i ] , A ) && evaluateANDri ( R1 , A , Inputs , RC ) ; if ( ! Eval ) return false ; Result . meet ( RC ) ; }


<s> bool MachineConstEvaluator :: evaluateCLBr ( const RegisterSubReg & R1 , bool Zeros , bool Ones , const CellMap & Inputs , LatticeCell & Result ) { assert ( Inputs . has ( R1 . Reg ) ) ; LatticeCell LS1 ; if ( ! getCell ( R1 , Inputs , LS1 ) ) return false ; if ( LS1 . isBottom ( ) || LS1 . isProperty ( ) ) return false ; APInt A , CA ; for ( unsigned i = <NUM_LIT> ; i < LS1 . size ( ) ; ++ i ) { bool Eval = constToInt ( LS1 . Values [ i ] , A ) && evaluateCLBi ( A , Zeros , Ones , CA ) ; if ( ! Eval ) return false ; const Constant * C = intToConst ( CA ) ; Result . add ( C ) ;


<s> Result = ! APInt :: isSameValue ( A1 , A2 ) ; return true ; } if ( Cmp == Comparison :: EQ ) { Result = APInt :: isSameValue ( A1 , A2 ) ; return true ; } if ( Cmp & Comparison :: EQ ) { if ( APInt :: isSameValue ( A1 , A2 ) ) return ( Result = true ) ; } assert ( ( Cmp & ( Comparison :: L | Comparison :: G ) ) && <STR_LIT> ) ; Result = false ; unsigned W1 = A1 . getBitWidth ( ) ; unsigned W2 = A2 . getBitWidth ( ) ; unsigned MaxW = ( W1 >= W2 ) ? W1 : W2 ; if ( Cmp & Comparison :: U ) { APInt Zx1 = A1 . zext ( MaxW ) ; APInt Zx2 = A2 . zext ( MaxW ) ;

if ( Cmp & Comparison :: L ) Result = Zx1 . ult ( Zx2 ) ;


<s> if ( APInt :: isSameValue ( A1 , A2 ) ) return ( Result = true ) ; } assert ( ( Cmp & ( Comparison :: L | Comparison :: G ) ) && <STR_LIT> ) ; Result = false ; unsigned W1 = A1 . getBitWidth ( ) ; unsigned W2 = A2 . getBitWidth ( ) ; unsigned MaxW = ( W1 >= W2 ) ? W1 : W2 ; if ( Cmp & Comparison :: U ) { APInt Zx1 = A1 . zext ( MaxW ) ; APInt Zx2 = A2 . zext ( MaxW ) ;


<s> bool IsTrue = true , IsFalse = true ; for ( unsigned i = <NUM_LIT> ; i < LS . size ( ) ; ++ i ) { bool Res ; bool Computed = constToInt ( LS . Values [ i ] , A ) && evaluateCMPii ( Cmp , A , A2 , Res ) ; if ( ! Computed ) return false ; IsTrue &= Res ; IsFalse &= ! Res ;


<s> bool IsTrue = true , IsFalse = true ; for ( unsigned i = <NUM_LIT> ; i < LS . size ( ) ; ++ i ) { bool Res ; bool Computed = constToInt ( LS . Values [ i ] , A ) && evaluateCMPpi ( NegCmp , Props2 , A , Res ) ; if ( ! Computed ) return false ; IsTrue &= Res ; IsFalse &= ! Res ; }


<s> uint32_t Prop2 = LS2 . properties ( ) ; return evaluateCMPrp ( Cmp , R1 , Prop2 , Inputs , Result ) ; } APInt A ; bool IsTrue = true , IsFalse = true ; for ( unsigned i = <NUM_LIT> ; i < LS2 . size ( ) ; ++ i ) { bool Res ;

bool Computed = constToInt ( LS2 . Values [ i ] , A ) && evaluateCMPri ( Cmp , R1 , A , Inputs , Res ) ;


<s> uint32_t Prop1 = LS1 . properties ( ) ; if ( IsProp2 ) return evaluateCMPpp ( Cmp , Prop1 , LS2 . properties ( ) , Result ) ; uint32_t NegCmp = Comparison :: negate ( Cmp ) ; return evaluateCMPrp ( NegCmp , R2 , Prop1 , Inputs , Result ) ; } if ( IsProp2 ) { uint32_t Prop2 = LS2 . properties ( ) ; return evaluateCMPrp ( Cmp , R1 , Prop2 , Inputs , Result ) ; } APInt A ; bool IsTrue = true , IsFalse = true ; for ( unsigned i = <NUM_LIT> ; i < LS2 . size ( ) ; ++ i ) { bool Res ; bool Computed = constToInt ( LS2 . Values [ i ] , A ) && evaluateCMPri ( Cmp , R1 , A , Inputs , Res ) ; if ( ! Computed ) return false ; IsTrue &= Res ; IsFalse &= ! Res ; } assert ( ! IsTrue || ! IsFalse ) ; Result = IsTrue ;


<s> bool MachineConstEvaluator :: evaluateCOPY ( const RegisterSubReg & R1 , const CellMap & Inputs , LatticeCell & Result ) {

return getCell ( R1 , Inputs , Result ) ;


<s> if ( LS1 . isBottom ( ) || LS1 . isProperty ( ) ) return false ; APInt A , CA ; for ( unsigned i = <NUM_LIT> ; i < LS1 . size ( ) ; ++ i ) {

bool Eval = constToInt ( LS1 . Values [ i ] , A ) && evaluateCTBi ( A , Zeros , Ones , CA ) ;


<s> if ( LS1 . isProperty ( ) ) { uint32_t Ps = LS1 . properties ( ) ; if ( Ps & ConstantProperties :: Zero ) { const Constant * C = intToConst ( APInt ( Width , <NUM_LIT> , false ) ) ; Result . add ( C ) ; return true ; } return false ; } APInt A , CA ; for ( unsigned i = <NUM_LIT> ; i < LS1 . size ( ) ; ++ i ) { bool Eval = constToInt ( LS1 . Values [ i ] , A ) && evaluateEXTRACTi ( A , Bits , Offset , Signed , CA ) ; if ( ! Eval ) return false ; const Constant * C = intToConst ( CA ) ; Result . add ( C ) ; } return true ;


<s> const MachineOperand & Src2 = MI . getOperand ( <NUM_LIT> ) ; bool Result ; unsigned Opc = MI . getOpcode ( ) ; bool Computed = evaluateHexCompare2 ( Opc , Src1 , Src2 , Inputs , Result ) ; if ( Computed ) { RegisterSubReg DefR ( MI . getOperand ( <NUM_LIT> ) ) ; LatticeCell L = Outputs . get ( DefR . Reg ) ; uint32_t P = Result ? ConstantProperties :: NonZero : ConstantProperties :: Zero ; L . add ( P ) ;


<s> bool Imm1 = Src1 . isImm ( ) , Imm2 = Src2 . isImm ( ) ; if ( Reg1 ) { RegisterSubReg R1 ( Src1 ) ; if ( Reg2 ) { RegisterSubReg R2 ( Src2 ) ; return evaluateCMPrr ( Cmp , R1 , R2 , Inputs , Result ) ; } else if ( Imm2 ) { APInt A2 = getCmpImm ( Opc , <NUM_LIT> , Src2 ) ; return evaluateCMPri ( Cmp , R1 , A2 , Inputs , Result ) ; } } else if ( Imm1 ) { APInt A1 = getCmpImm ( Opc , <NUM_LIT> , Src1 ) ; if ( Reg2 ) { RegisterSubReg R2 ( Src2 ) ; uint32_t NegCmp = Comparison :: negate ( Cmp ) ; return evaluateCMPri ( NegCmp , R2 , A1 , Inputs , Result ) ; } else if ( Imm2 ) { APInt A2 = getCmpImm ( Opc , <NUM_LIT> , Src2 ) ; return evaluateCMPii ( Cmp , A1 , A2 , Result ) ; }


<s> RegisterSubReg R1 ( MI . getOperand ( <NUM_LIT> ) ) ; assert ( Inputs . has ( R1 . Reg ) ) ; unsigned Opc = MI . getOpcode ( ) ; unsigned Bits ; switch ( Opc ) { case <STR_LIT> : case <STR_LIT> : Bits = <NUM_LIT> ; break ; case <STR_LIT> : case <STR_LIT> : Bits = <NUM_LIT> ; break ; case <STR_LIT> : Bits = <NUM_LIT> ; break ; default :


<s> unsigned Opc = MI . getOpcode ( ) ; unsigned Bits ; switch ( Opc ) { case <STR_LIT> : case <STR_LIT> : Bits = <NUM_LIT> ; break ; case <STR_LIT> : case <STR_LIT> : Bits = <NUM_LIT> ; break ; case <STR_LIT> : Bits = <NUM_LIT> ; break ; default : llvm_unreachable ( <STR_LIT> ) ; } bool Signed = false ; switch ( Opc ) { case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : Signed = true ; break ;


<s> const MachineOperand & Src2 = MI . getOperand ( <NUM_LIT> ) ; RegisterSubReg R1 ( Src1 ) ; bool Eval = false ; LatticeCell RC ; switch ( Opc ) { default : return false ; case <STR_LIT> : case <STR_LIT> : Eval = evaluateANDrr ( R1 , RegisterSubReg ( Src2 ) , Inputs , RC ) ; break ; case <STR_LIT> : { if ( ! Src2 . isImm ( ) ) return false ; APInt A ( <NUM_LIT> , Src2 . getImm ( ) , true ) ; Eval = evaluateANDri ( R1 , A , Inputs , RC ) ; break ; } case <STR_LIT> : case <STR_LIT> : Eval = evaluateORrr ( R1 , RegisterSubReg ( Src2 ) , Inputs , RC ) ; break ; case <STR_LIT> : { if ( ! Src2 . isImm ( ) ) return false ; APInt A ( <NUM_LIT> , Src2 . getImm ( ) , true ) ; Eval = evaluateORri ( R1 , A , Inputs , RC ) ; break ; } case <STR_LIT> : case <STR_LIT> :

Eval = evaluateXORrr ( R1 , RegisterSubReg ( Src2 ) , Inputs , RC ) ;


<s> LatticeCell LSL , LSH ; if ( ! getCell ( RL , Inputs , LSL ) || ! getCell ( RH , Inputs , LSH ) ) return false ; if ( LSL . isProperty ( ) || LSH . isProperty ( ) ) return false ; unsigned LN = LSL . size ( ) , HN = LSH . size ( ) ; SmallVector < APInt , <NUM_LIT> > LoVs ( LN ) , HiVs ( HN ) ; for ( unsigned i = <NUM_LIT> ; i < LN ; ++ i ) { bool Eval = constToInt ( LSL . Values [ i ] , LoVs [ i ] ) ; if ( ! Eval ) return false ; assert ( LoVs [ i ] . getBitWidth ( ) == <NUM_LIT> ) ; } for ( unsigned i = <NUM_LIT> ; i < HN ; ++ i ) { bool Eval = constToInt ( LSH . Values [ i ] , HiVs [ i ] ) ;


<s> bool Eval = constToInt ( LSL . Values [ i ] , LoVs [ i ] ) ; if ( ! Eval ) return false ; assert ( LoVs [ i ] . getBitWidth ( ) == <NUM_LIT> ) ; } for ( unsigned i = <NUM_LIT> ; i < HN ; ++ i ) { bool Eval = constToInt ( LSH . Values [ i ] , HiVs [ i ] ) ; if ( ! Eval ) return false ; assert ( HiVs [ i ] . getBitWidth ( ) == <NUM_LIT> ) ; } for ( unsigned i = <NUM_LIT> ; i < HiVs . size ( ) ; ++ i ) { APInt HV = HiVs [ i ] . zext ( <NUM_LIT> ) << <NUM_LIT> ; for ( unsigned j = <NUM_LIT> ; j < LoVs . size ( ) ; ++ j ) {

APInt LV = LoVs [ j ] . zext ( <NUM_LIT> ) ;


<s> RegisterSubReg DefR ( MI . getOperand ( <NUM_LIT> ) ) ; RegisterSubReg R1 ( MI . getOperand ( <NUM_LIT> ) ) ; assert ( Inputs . has ( R1 . Reg ) ) ; LatticeCell RC = Outputs . get ( DefR . Reg ) ; bool Eval ; unsigned Opc = MI . getOpcode ( ) ; switch ( Opc ) { case <STR_LIT> : Eval = evaluateSplatr ( R1 , <NUM_LIT> , <NUM_LIT> , Inputs , RC ) ; break ; case <STR_LIT> : Eval = evaluateSplatr ( R1 , <NUM_LIT> , <NUM_LIT> , Inputs , RC ) ; break ; default : return false ; } if ( ! Eval ) return false ; Outputs . update ( DefR . Reg , RC ) ;


<s> RegisterSubReg DefR ( MI . getOperand ( <NUM_LIT> ) ) ; RegisterSubReg R1 ( MI . getOperand ( <NUM_LIT> ) ) ; assert ( Inputs . has ( R1 . Reg ) ) ; LatticeCell RC = Outputs . get ( DefR . Reg ) ; bool Eval ; unsigned Opc = MI . getOpcode ( ) ; switch ( Opc ) { case <STR_LIT> : Eval = evaluateSplatr ( R1 , <NUM_LIT> , <NUM_LIT> , Inputs , RC ) ; break ; case <STR_LIT> : Eval = evaluateSplatr ( R1 , <NUM_LIT> , <NUM_LIT> , Inputs , RC ) ; break ; default : return false ; } if ( ! Eval ) return false ;


<s> if ( ! getCell ( R1 , Inputs , LS1 ) ) return false ; if ( LS1 . isBottom ( ) || LS1 . isProperty ( ) ) return false ; APInt A , ResA ; for ( unsigned i = <NUM_LIT> ; i < LS1 . size ( ) ; ++ i ) { bool Eval = constToInt ( LS1 . Values [ i ] , A ) && evaluateORii ( A , A2 , ResA ) ; if ( ! Eval ) return false ; const Constant * C = intToConst ( ResA ) ; Result . add ( C ) ; }


<s> LatticeCell LS2 ; if ( ! evaluate ( R2 , L2 , LS2 ) ) return false ; if ( LS2 . isBottom ( ) || LS2 . isProperty ( ) ) return false ; APInt A ; for ( unsigned i = <NUM_LIT> ; i < LS2 . size ( ) ; ++ i ) { LatticeCell RC ; bool Eval = constToInt ( LS2 . Values [ i ] , A ) && evaluateORri ( R1 , A , Inputs , RC ) ; if ( ! Eval ) return false ; Result . meet ( RC ) ; }


<s> bool MachineConstEvaluator :: evaluateORrr ( const RegisterSubReg & R1 , const RegisterSubReg & R2 , const CellMap & Inputs , LatticeCell & Result ) { assert ( Inputs . has ( R1 . Reg ) && Inputs . has ( R2 . Reg ) ) ; const LatticeCell & L1 = Inputs . get ( R2 . Reg ) ; const LatticeCell & L2 = Inputs . get ( R2 . Reg ) ; if ( L2 . isBottom ( ) ) { if ( L1 . isBottom ( ) ) return false ;

return evaluateORrr ( R2 , R1 , Inputs , Result ) ;


<s> if ( LS1 . isBottom ( ) || LS1 . isProperty ( ) ) return false ; APInt A , XA ; for ( unsigned i = <NUM_LIT> ; i < LS1 . size ( ) ; ++ i ) { bool Eval = constToInt ( LS1 . Values [ i ] , A ) && evaluateSEXTi ( A , Width , Bits , XA ) ; if ( ! Eval ) return false ; const Constant * C = intToConst ( XA ) ; Result . add ( C ) ;


<s> LatticeCell LS1 ; if ( ! getCell ( R1 , Inputs , LS1 ) ) return false ; if ( LS1 . isBottom ( ) || LS1 . isProperty ( ) ) return false ; APInt A , XA ; for ( unsigned i = <NUM_LIT> ; i < LS1 . size ( ) ; ++ i ) { bool Eval = constToInt ( LS1 . Values [ i ] , A ) && evaluateSEXTi ( A , Width , Bits , XA ) ; if ( ! Eval ) return false ; const Constant * C = intToConst ( XA ) ; Result . add ( C ) ; }


<s> APInt LoBits = ( Bits < BW ) ? A1 . trunc ( Bits ) : A1 . zext ( Bits ) ; if ( Count > <NUM_LIT> ) LoBits = LoBits . zext ( SW ) ; APInt Res ( SW , <NUM_LIT> , false ) ; for ( unsigned i = <NUM_LIT> ; i < Count ; ++ i ) { Res <<= Bits ; Res |= LoBits ; } Result = Res ;


<s> if ( ! getCell ( R1 , Inputs , LS1 ) ) return false ; if ( LS1 . isBottom ( ) || LS1 . isProperty ( ) ) return false ; APInt A , SA ; for ( unsigned i = <NUM_LIT> ; i < LS1 . size ( ) ; ++ i ) { bool Eval = constToInt ( LS1 . Values [ i ] , A ) && evaluateSplati ( A , Bits , Count , SA ) ; if ( ! Eval ) return false ;

const Constant * C = intToConst ( SA ) ;


<s> if ( LS1 . isProperty ( ) ) { if ( LS1 . properties ( ) & ConstantProperties :: Zero ) { const Constant * C = intToConst ( A2 ) ; Result . add ( C ) ; return ! Result . isBottom ( ) ; } return false ; } APInt A , XA ; for ( unsigned i = <NUM_LIT> ; i < LS1 . size ( ) ; ++ i ) { bool Eval = constToInt ( LS1 . Values [ i ] , A ) && evaluateXORii ( A , A2 , XA ) ; if ( ! Eval ) return false ; const Constant * C = intToConst ( XA ) ; Result . add ( C ) ; } return ! Result . isBottom ( ) ;


<s> if ( ! getCell ( R1 , Inputs , LS1 ) || ! getCell ( R2 , Inputs , LS2 ) ) return false ; if ( LS1 . isProperty ( ) ) { if ( LS1 . properties ( ) & ConstantProperties :: Zero ) return ! ( Result = LS2 ) . isBottom ( ) ; return false ; } if ( LS2 . isProperty ( ) ) { if ( LS2 . properties ( ) & ConstantProperties :: Zero ) return ! ( Result = LS1 ) . isBottom ( ) ;


<s> if ( LS1 . isProperty ( ) ) return false ; APInt A , XA ; for ( unsigned i = <NUM_LIT> ; i < LS1 . size ( ) ; ++ i ) { bool Eval = constToInt ( LS1 . Values [ i ] , A ) && evaluateZEXTi ( A , Width , Bits , XA ) ; if ( ! Eval ) return false ;

const Constant * C = intToConst ( XA ) ;


<s> MapType :: const_iterator F = Map . find ( R ) ; if ( F != Map . end ( ) ) return F -> second ; return Top ;


<s> RC = L ; return ! RC . isBottom ( ) ; } bool Eval = evaluate ( R , L , RC ) ;


<s> break ; case <STR_LIT> : case <STR_LIT> : Signed = true ; break ; case <STR_LIT> : break ; case <STR_LIT> : case <STR_LIT> : break ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : Signed = true ; break ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : break ; default : llvm_unreachable ( <STR_LIT> ) ; break ;


<s> APInt <ISA_LIT>ConstEvaluator :: getCmpImm ( unsigned Opc , unsigned OpX , const MachineOperand & MO ) { bool Signed = false ; switch ( Opc ) { case <STR_LIT> : case <STR_LIT> : break ; case <STR_LIT> : case <STR_LIT> : Signed = true ; break ; case <STR_LIT> : break ; case <STR_LIT> : case <STR_LIT> : break ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : Signed = true ; break ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> :


<s> bool has ( Register R ) const { if ( ! R . isVirtual ( ) ) return true ;

MapType :: const_iterator F = Map . find ( R ) ;


<s> uint32_t N = L . IsSpecial ? sizeof L . Properties : L . Size * sizeof ( const Constant * ) ; memcpy ( Values , L . Values , N ) ;


<s> explicit RegisterSubReg ( const MachineOperand & MO ) : Reg ( MO . getReg ( ) ) , SubReg ( MO . getSubReg ( ) ) {


<s> From -> removeSuccessor ( To ) ; for ( MachineInstr & PN : To -> phis ( ) ) { int N = PN . getNumOperands ( ) - <NUM_LIT> ; while ( N > <NUM_LIT> ) { if ( PN . getOperand ( N + <NUM_LIT> ) . getMBB ( ) == From ) {


<s> void MachineConstPropagator :: removeCFGEdge ( MachineBasicBlock * From , MachineBasicBlock * To ) { From -> removeSuccessor ( To ) ; for ( MachineInstr & PN : To -> phis ( ) ) { int N = PN . getNumOperands ( ) - <NUM_LIT> ; while ( N > <NUM_LIT> ) { if ( PN . getOperand ( N + <NUM_LIT> ) . getMBB ( ) == From ) {


<s> while ( MI . getNumOperands ( ) > <NUM_LIT> ) MI . removeOperand ( <NUM_LIT> ) ;


<s> void <ISA_LIT>ConstEvaluator :: replaceWithNop ( MachineInstr & MI ) { MI . setDesc ( HII . get ( <STR_LIT> ) ) ;

while ( MI . getNumOperands ( ) > <NUM_LIT> ) MI . removeOperand ( <NUM_LIT> ) ;


<s> for ( MachineInstr & MI : llvm :: reverse ( * B ) ) { if ( InstrExec . count ( & MI ) ) { if ( MI . isBranch ( ) && ! HaveTargets ) continue ; Changed |= MCE . rewrite ( MI , Cells ) ; } } for ( auto I = B -> begin ( ) , E = B -> end ( ) ; I != E ; ++ I ) { if ( I -> isPHI ( ) ) continue ; auto P = I ; while ( ++ P != E ) if ( P -> isPHI ( ) ) break ; if ( P == E ) break ; B -> splice ( I , B , P ) ; -- I ; } if ( HaveTargets ) { SmallVector < MachineBasicBlock * , <NUM_LIT> > ToRemove ; for ( MachineBasicBlock * SB : B -> successors ( ) ) { if ( ! Targets . count ( SB ) ) ToRemove . push_back ( const_cast < MachineBasicBlock * > ( SB ) ) ; Targets . remove ( SB ) ; } for ( MachineBasicBlock * MBB : ToRemove ) removeCFGEdge ( B , MBB ) ;


<s> if ( InstrExec . count ( & MI ) ) { if ( MI . isBranch ( ) && ! HaveTargets ) continue ; Changed |= MCE . rewrite ( MI , Cells ) ; } } for ( auto I = B -> begin ( ) , E = B -> end ( ) ; I != E ; ++ I ) { if ( I -> isPHI ( ) ) continue ; auto P = I ; while ( ++ P != E ) if ( P -> isPHI ( ) ) break ; if ( P == E ) break ; B -> splice ( I , B , P ) ; -- I ; } if ( HaveTargets ) { SmallVector < MachineBasicBlock * , <NUM_LIT> > ToRemove ; for ( MachineBasicBlock * SB : B -> successors ( ) ) {

if ( ! Targets . count ( SB ) ) ToRemove . push_back ( const_cast < MachineBasicBlock * > ( SB ) ) ;


<s> while ( It != End ) { const MachineInstr & MI = * It ; InstrExec . insert ( & MI ) ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << ( EvalOk ? <STR_LIT> : <STR_LIT> ) << <STR_LIT> << printMBBReference ( B ) << <STR_LIT> << MI ) ; EvalOk = EvalOk && MCE . evaluate ( MI , Cells , Targets , FallsThru ) ; if ( ! EvalOk ) FallsThru = true ; if ( ! FallsThru ) break ; ++ It ; } if ( B . mayHaveInlineAsmBr ( ) ) EvalOk = false ; if ( EvalOk ) { for ( const MachineBasicBlock * SB : B . successors ( ) ) { if ( SB -> isEHPad ( ) ) Targets . insert ( SB ) ; } if ( FallsThru ) { const MachineFunction & MF = * B . getParent ( ) ; MachineFunction :: const_iterator BI = B . getIterator ( ) ; MachineFunction :: const_iterator Next = std :: next ( BI ) ; if ( Next != MF . end ( ) ) Targets . insert ( & * Next ) ; } } else { Targets . clear ( ) ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> <STR_LIT> ) ; for ( const MachineBasicBlock * SB : B . successors ( ) ) Targets . insert ( SB ) ; } for ( const MachineBasicBlock * TB : Targets ) { unsigned TBN = TB -> getNumber ( ) ;

LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << printMBBReference ( B ) << <STR_LIT> << printMBBReference ( * TB ) << <STR_LIT> ) ;


<s> } } ) ; for ( const MachineOperand & MO : MI . operands ( ) ) { if ( ! MO . isReg ( ) || ! MO . isDef ( ) ) continue ; RegisterSubReg DefR ( MO ) ; if ( ! DefR . Reg . isVirtual ( ) ) continue ; bool Changed = false ; if ( ! Eval ) { const LatticeCell & T = Cells . get ( DefR . Reg ) ; Changed = ! T . isBottom ( ) ; Cells . update ( DefR . Reg , Bottom ) ; } else { if ( ! Outputs . has ( DefR . Reg ) ) continue ; LatticeCell RC = Cells . get ( DefR . Reg ) ; Changed = RC . meet ( Outputs . get ( DefR . Reg ) ) ; Cells . update ( DefR . Reg , RC ) ; } if ( Changed ) visitUsesOf ( DefR . Reg ) ; }


<s>
dbgs
(
)
<<
<STR_LIT>
;
for
(
auto
&
I
:
Outputs
)
dbgs
(
)
<<
' '
<<
I
.
second
;
dbgs
(
)
<<
'\n'
;
}
}
)
;
for
(
const
MachineOperand
&
MO
:
MI
.
operands
(
)
)
{
if
(
!
MO
.
isReg
(
)
||
!
MO
.
isDef
(
)
)
continue
;
RegisterSubReg
DefR
(
MO
)
;
if
(
!
DefR
.
Reg
.
isVirtual
(
)
)
continue
;
bool
Changed
=
false
;
if
(
!
Eval
)
{
const
LatticeCell
&
T
=
Cells
.
get
(
DefR
.
Reg
)
;
Changed
=
!
T
.
isBottom
(
)
;
Cells
.
update
(
DefR
.
Reg
,
Bottom
)
;


<s> return ; } LatticeCell DefC = Cells . get ( DefR . Reg ) ; for ( unsigned i = <NUM_LIT> , n = PN . getNumOperands ( ) ; i < n ; i += <NUM_LIT> ) { const MachineBasicBlock * PB = PN . getOperand ( i + <NUM_LIT> ) . getMBB ( ) ; unsigned PBN = PB -> getNumber ( ) ; if ( ! EdgeExec . count ( CFGEdge ( PBN , MBN ) ) ) { LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << printMBBReference ( * PB ) << <STR_LIT> << printMBBReference ( * MB ) << <STR_LIT> ) ; continue ; } const MachineOperand & SO = PN . getOperand ( i ) ; RegisterSubReg UseR ( SO ) ; if ( ! UseR . Reg . isVirtual ( ) ) goto Bottomize ; if ( ! Cells . has ( UseR . Reg ) ) continue ; LatticeCell SrcC ; bool Eval = MCE . evaluate ( UseR , Cells . get ( UseR . Reg ) , SrcC ) ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << printMBBReference ( * PB ) << <STR_LIT> << printReg ( UseR . Reg , & MCE . TRI , UseR . SubReg ) << SrcC << '\n' ) ; Changed |= Eval ? DefC . meet ( SrcC ) : DefC . setBottom ( ) ;


<s> SmallVector < APInt , <NUM_LIT> > LoVs ( LN ) , HiVs ( HN ) ; for ( unsigned i = <NUM_LIT> ; i < LN ; ++ i ) { bool Eval = constToInt ( LSL . Values [ i ] , LoVs [ i ] ) ; if ( ! Eval ) return false ; assert ( LoVs [ i ] . getBitWidth ( ) == <NUM_LIT> ) ; } for ( unsigned i = <NUM_LIT> ; i < HN ; ++ i ) { bool Eval = constToInt ( LSH . Values [ i ] , HiVs [ i ] ) ; if ( ! Eval ) return false ; assert ( HiVs [ i ] . getBitWidth ( ) == <NUM_LIT> ) ; } for ( unsigned i = <NUM_LIT> ; i < HiVs . size ( ) ; ++ i ) {

APInt HV = HiVs [ i ] . zextOrSelf ( <NUM_LIT> ) << <NUM_LIT> ;


<s> if ( F != Map . end ( ) ) return F -> second ;


<s> const LatticeCell & get ( unsigned R ) const {

if ( ! Register :: isVirtualRegister ( R ) ) return Bottom ;


<s> bool MachineConstEvaluator :: getCell ( const RegisterSubReg & R , const CellMap & Inputs , LatticeCell & RC ) { if ( ! Register :: isVirtualRegister ( R . Reg ) ) return false ;

const LatticeCell & L = Inputs . get ( R . Reg ) ;


<s> bool has ( unsigned R ) const { if ( ! Register :: isVirtualRegister ( R ) ) return true ; MapType :: const_iterator F = Map . find ( R ) ; return F != Map . end ( ) ;


<s> if ( ! Register :: isVirtualRegister ( R ) ) return true ;


<s> dbgs ( ) << '\n' ; } } ) ; for ( const MachineOperand & MO : MI . operands ( ) ) { if ( ! MO . isReg ( ) || ! MO . isDef ( ) ) continue ; RegisterSubReg DefR ( MO ) ; if ( ! Register :: isVirtualRegister ( DefR . Reg ) ) continue ; bool Changed = false ; if ( ! Eval ) { const LatticeCell & T = Cells . get ( DefR . Reg ) ; Changed = ! T . isBottom ( ) ; Cells . update ( DefR . Reg , Bottom ) ; } else { if ( ! Outputs . has ( DefR . Reg ) ) continue ; LatticeCell RC = Cells . get ( DefR . Reg ) ;

Changed = RC . meet ( Outputs . get ( DefR . Reg ) ) ;


<s> bool Changed = false ; if ( DefR . SubReg ) { Bottomize : const LatticeCell & T = Cells . get ( DefR . Reg ) ; Changed = ! T . isBottom ( ) ; Cells . update ( DefR . Reg , Bottom ) ; if ( Changed ) visitUsesOf ( DefR . Reg ) ; return ; } LatticeCell DefC = Cells . get ( DefR . Reg ) ; for ( unsigned i = <NUM_LIT> , n = PN . getNumOperands ( ) ; i < n ; i += <NUM_LIT> ) { const MachineBasicBlock * PB = PN . getOperand ( i + <NUM_LIT> ) . getMBB ( ) ; unsigned PBN = PB -> getNumber ( ) ; if ( ! EdgeExec . count ( CFGEdge ( PBN , MBN ) ) ) { LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << printMBBReference ( * PB ) << <STR_LIT> << printMBBReference ( * MB ) << <STR_LIT> ) ; continue ; } const MachineOperand & SO = PN . getOperand ( i ) ; RegisterSubReg UseR ( SO ) ; if ( ! Register :: isVirtualRegister ( UseR . Reg ) ) goto Bottomize ; if ( ! Cells . has ( UseR . Reg ) ) continue ; LatticeCell SrcC ; bool Eval = MCE . evaluate ( UseR , Cells . get ( UseR . Reg ) , SrcC ) ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << printMBBReference ( * PB ) << <STR_LIT> << printReg ( UseR . Reg , & MCE . TRI , UseR . SubReg ) << SrcC << '\n' ) ; Changed |= Eval ? DefC . meet ( SrcC ) : DefC . setBottom ( ) ;


<s> LatticeCell DefC = Cells . get ( DefR . Reg ) ; for ( unsigned i = <NUM_LIT> , n = PN . getNumOperands ( ) ; i < n ; i += <NUM_LIT> ) { const MachineBasicBlock * PB = PN . getOperand ( i + <NUM_LIT> ) . getMBB ( ) ; unsigned PBN = PB -> getNumber ( ) ; if ( ! EdgeExec . count ( CFGEdge ( PBN , MBN ) ) ) { LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << printMBBReference ( * PB ) << <STR_LIT> << printMBBReference ( * MB ) << <STR_LIT> ) ; continue ; } const MachineOperand & SO = PN . getOperand ( i ) ; RegisterSubReg UseR ( SO ) ; if ( ! Register :: isVirtualRegister ( UseR . Reg ) ) goto Bottomize ;

if ( ! Cells . has ( UseR . Reg ) ) continue ;


<s> bool MachineConstPropagator :: run ( MachineFunction & MF ) { DEBUG ( MF . print ( dbgs ( ) << <STR_LIT> , nullptr ) ) ; MRI = & MF . getRegInfo ( ) ; Cells . clear ( ) ; EdgeExec . clear ( ) ; InstrExec . clear ( ) ; assert ( FlowQ . empty ( ) ) ; propagate ( MF ) ; bool Changed = rewrite ( MF ) ;


<s> InstrExec . clear ( ) ; assert ( FlowQ . empty ( ) ) ; propagate ( MF ) ; bool Changed = rewrite ( MF ) ; DEBUG ( { dbgs ( ) << <STR_LIT> << Changed << <STR_LIT> ; if ( Changed ) MF . print ( dbgs ( ) , nullptr ) ; } ) ; return Changed ;


<s> if ( It != End && InstrExec . count ( & * It ) ) continue ; while ( It != End && ! It -> isBranch ( ) ) { if ( ! It -> isDebugValue ( ) ) { InstrExec . insert ( & * It ) ; visitNonBranch ( * It ) ; } ++ It ; } if ( It != End ) { visitBranchesFrom ( * It ) ; } else { unsigned SBN = SB -> getNumber ( ) ; for ( const MachineBasicBlock * SSB : SB -> successors ( ) ) FlowQ . push ( CFGEdge ( SBN , SSB -> getNumber ( ) ) ) ; } } DEBUG ( { dbgs ( ) << <STR_LIT> ; Cells . print ( dbgs ( ) , MCE . TRI ) ; dbgs ( ) << <STR_LIT> ; for ( const MachineBasicBlock & B : MF ) { unsigned BN = B . getNumber ( ) ; for ( const MachineBasicBlock * SB : B . successors ( ) ) { unsigned SN = SB -> getNumber ( ) ; if ( ! EdgeExec . count ( CFGEdge ( BN , SN ) ) ) dbgs ( ) << <STR_LIT> << printMBBReference ( B ) << <STR_LIT> << printMBBReference ( * SB ) << '\n' ; } } } ) ;


<s> MachineBasicBlock :: const_iterator It = SB -> begin ( ) , End = SB -> end ( ) ; while ( It != End && It -> isPHI ( ) ) { InstrExec . insert ( & * It ) ; visitPHI ( * It ) ; ++ It ; } while ( It != End && It -> isDebugValue ( ) ) ++ It ; assert ( It == End || ! It -> isPHI ( ) ) ; if ( It != End && InstrExec . count ( & * It ) ) continue ; while ( It != End && ! It -> isBranch ( ) ) { if ( ! It -> isDebugValue ( ) ) { InstrExec . insert ( & * It ) ; visitNonBranch ( * It ) ; } ++ It ; }


<s> bool EvalOk = true , FallsThru = true ; while ( It != End ) { const MachineInstr & MI = * It ; InstrExec . insert ( & MI ) ; DEBUG ( dbgs ( ) << <STR_LIT> << ( EvalOk ? <STR_LIT> : <STR_LIT> ) << <STR_LIT> << printMBBReference ( B ) << <STR_LIT> << MI ) ; EvalOk = EvalOk && MCE . evaluate ( MI , Cells , Targets , FallsThru ) ; if ( ! EvalOk ) FallsThru = true ; if ( ! FallsThru ) break ; ++ It ; } if ( EvalOk ) { for ( const MachineBasicBlock * SB : B . successors ( ) ) { if ( SB -> isEHPad ( ) ) Targets . insert ( SB ) ; } if ( FallsThru ) { const MachineFunction & MF = * B . getParent ( ) ; MachineFunction :: const_iterator BI = B . getIterator ( ) ; MachineFunction :: const_iterator Next = std :: next ( BI ) ; if ( Next != MF . end ( ) ) Targets . insert ( & * Next ) ; } } else { Targets . clear ( ) ; DEBUG ( dbgs ( ) << <STR_LIT> <STR_LIT> ) ; for ( const MachineBasicBlock * SB : B . successors ( ) ) Targets . insert ( SB ) ;


<s> if ( DefR . SubReg ) { Bottomize : const LatticeCell & T = Cells . get ( DefR . Reg ) ; Changed = ! T . isBottom ( ) ; Cells . update ( DefR . Reg , Bottom ) ; if ( Changed ) visitUsesOf ( DefR . Reg ) ; return ; } LatticeCell DefC = Cells . get ( DefR . Reg ) ; for ( unsigned i = <NUM_LIT> , n = PN . getNumOperands ( ) ; i < n ; i += <NUM_LIT> ) { const MachineBasicBlock * PB = PN . getOperand ( i + <NUM_LIT> ) . getMBB ( ) ; unsigned PBN = PB -> getNumber ( ) ;

if ( ! EdgeExec . count ( CFGEdge ( PBN , MBN ) ) ) {


<s> void MachineConstPropagator :: visitUsesOf ( unsigned Reg ) { DEBUG ( dbgs ( ) << <STR_LIT> << printReg ( Reg , & MCE . TRI ) << Cells . get ( Reg ) << '\n' ) ; for ( MachineInstr & MI : MRI -> use_nodbg_instructions ( Reg ) ) { if ( ! InstrExec . count ( & MI ) ) continue ; if ( MI . isPHI ( ) ) visitPHI ( MI ) ;

else if ( ! MI . isBranch ( ) ) visitNonBranch ( MI ) ;


<s> if ( ! InstrExec . count ( & MI ) ) continue ; if ( MI . isPHI ( ) ) visitPHI ( MI ) ;


<s> FallsThru = ! BrI . isUnconditionalBranch ( ) ; return false ; } if ( SimpleBranch ) { const MachineOperand & MD = BrI . getOperand ( <NUM_LIT> ) ; Register PR ( MD ) ; if ( PR . SubReg ) goto Undetermined ; assert ( Inputs . has ( PR . Reg ) ) ; const LatticeCell & PredC = Inputs . get ( PR . Reg ) ; if ( PredC . isBottom ( ) ) goto Undetermined ; uint32_t Props = PredC . properties ( ) ; bool CTrue = false , CFalse = false ; if ( Props & ConstantProperties :: Zero ) CFalse = true ; else if ( Props & ConstantProperties :: NonZero ) CTrue = true ;

if ( ! CTrue && ! CFalse ) goto Undetermined ;


<s> StringRef getPassName ( ) const override {


<s> for ( unsigned i = <NUM_LIT> ; i < MaxCellSize ; ++ i ) Values [ i ] = nullptr ;


<s> dbgs ( ) << PrintReg ( Reg , TRI , SubReg ) ;


<s> unsigned Opc = MI . getOpcode ( ) ; switch ( Opc ) { default : break ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : return false ; } unsigned NumOp = MI . getNumOperands ( ) ; if ( NumOp == <NUM_LIT> ) return false ; bool AllDefs , Changed ; Changed = rewriteHexConstDefs ( MI , Inputs , AllDefs ) ;

if ( ! AllDefs ) Changed |= rewriteHexConstUses ( MI , Inputs ) ;


<s> int N = PN . getNumOperands ( ) - <NUM_LIT> ; while ( N > <NUM_LIT> ) { if ( PN . getOperand ( N + <NUM_LIT> ) . getMBB ( ) == From ) { PN . RemoveOperand ( N + <NUM_LIT> ) ; PN . RemoveOperand ( N ) ;


<s> case <STR_LIT> : case <STR_LIT> : Signed = true ; break ; } Register DefR ( MI . getOperand ( <NUM_LIT> ) ) ; unsigned BW = getRegBitWidth ( DefR . Reg ) ; LatticeCell RC = Outputs . get ( DefR . Reg ) ; bool Eval = Signed ? evaluateSEXTr ( R1 , BW , Bits , Inputs , RC ) : evaluateZEXTr ( R1 , BW , Bits , Inputs , RC ) ; if ( ! Eval ) return false ;


<s> unsigned Opc = MI . getOpcode ( ) ; unsigned Bits ; switch ( Opc ) { case <STR_LIT> : case <STR_LIT> : Bits = <NUM_LIT> ; break ; case <STR_LIT> : case <STR_LIT> : Bits = <NUM_LIT> ; break ; case <STR_LIT> : Bits = <NUM_LIT> ; break ; default : llvm_unreachable ( <STR_LIT> ) ; } bool Signed = false ; switch ( Opc ) { case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : Signed = true ; break ; } Register DefR ( MI . getOperand ( <NUM_LIT> ) ) ; unsigned BW = getRegBitWidth ( DefR . Reg ) ; LatticeCell RC = Outputs . get ( DefR . Reg ) ;

bool Eval = Signed ? evaluateSEXTr ( R1 , BW , Bits , Inputs , RC ) : evaluateZEXTr ( R1 , BW , Bits , Inputs , RC ) ;


<s> bool MachineConstEvaluator :: getCell ( const RegisterSubReg & R , const CellMap & Inputs , LatticeCell & RC ) { if ( ! TargetRegisterInfo :: isVirtualRegister ( R . Reg ) ) return false ; const LatticeCell & L = Inputs . get ( R . Reg ) ;


<s> bool MachineConstEvaluator :: getCell ( const RegisterSubReg & R , const CellMap & Inputs , LatticeCell & RC ) { if ( ! TargetRegisterInfo :: isVirtualRegister ( R . Reg ) ) return false ; const LatticeCell & L = Inputs . get ( R . Reg ) ; if ( ! R . SubReg ) { RC = L ;


<s>
CellMap
Outputs
;
bool
Eval
=
MCE
.
evaluate
(
MI
,
Cells
,
Outputs
)
;
LLVM_DEBUG
(
{
if
(
Eval
)
{
dbgs
(
)
<<
<STR_LIT>
;
for
(
auto
&
I
:
Outputs
)
dbgs
(
)
<<
' '
<<
I
.
second
;
dbgs
(
)
<<
'\n'
;
}
}
)
;
for
(
const
MachineOperand
&
MO
:
MI
.
operands
(
)
)
{
if
(
!
MO
.
isReg
(
)
||
!
MO
.
isDef
(
)
)
continue
;


<s> const MachineBasicBlock * MB = PN . getParent ( ) ; unsigned MBN = MB -> getNumber ( ) ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << printMBBReference ( * MB ) << <STR_LIT> << PN ) ; const MachineOperand & MD = PN . getOperand ( <NUM_LIT> ) ; RegisterSubReg DefR ( MD ) ; assert ( TargetRegisterInfo :: isVirtualRegister ( DefR . Reg ) ) ; bool Changed = false ; if ( DefR . SubReg ) { Bottomize : const LatticeCell & T = Cells . get ( DefR . Reg ) ; Changed = ! T . isBottom ( ) ; Cells . update ( DefR . Reg , Bottom ) ; if ( Changed ) visitUsesOf ( DefR . Reg ) ; return ; } LatticeCell DefC = Cells . get ( DefR . Reg ) ; for ( unsigned i = <NUM_LIT> , n = PN . getNumOperands ( ) ; i < n ; i += <NUM_LIT> ) { const MachineBasicBlock * PB = PN . getOperand ( i + <NUM_LIT> ) . getMBB ( ) ; unsigned PBN = PB -> getNumber ( ) ; if ( ! EdgeExec . count ( CFGEdge ( PBN , MBN ) ) ) { LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << printMBBReference ( * PB ) << <STR_LIT> << printMBBReference ( * MB ) << <STR_LIT> ) ; continue ; } const MachineOperand & SO = PN . getOperand ( i ) ; RegisterSubReg UseR ( SO ) ; if ( ! TargetRegisterInfo :: isVirtualRegister ( UseR . Reg ) ) goto Bottomize ; if ( ! Cells . has ( UseR . Reg ) ) continue ;


<s> for ( MachineBasicBlock * B : POT ) { SetVector < const MachineBasicBlock * > Targets ; bool HaveTargets = computeBlockSuccessors ( B , Targets ) ; for ( MachineInstr & MI : llvm :: reverse ( * B ) ) { if ( InstrExec . count ( & MI ) ) { if ( MI . isBranch ( ) && ! HaveTargets ) continue ; Changed |= MCE . rewrite ( MI , Cells ) ; } } for ( auto I = B -> begin ( ) , E = B -> end ( ) ; I != E ; ++ I ) {


<s> -- I ; } if ( HaveTargets ) { SmallVector < MachineBasicBlock * , <NUM_LIT> > ToRemove ; for ( MachineBasicBlock * SB : B -> successors ( ) ) { if ( ! Targets . count ( SB ) ) ToRemove . push_back ( const_cast < MachineBasicBlock * > ( SB ) ) ; Targets . remove ( SB ) ; } for ( unsigned i = <NUM_LIT> , n = ToRemove . size ( ) ; i < n ; ++ i ) removeCFGEdge ( B , ToRemove [ i ] ) ; } } for ( MachineBasicBlock & B : MF ) { for ( MachineInstr & MI : llvm :: make_early_inc_range ( B ) ) if ( MI . isBranch ( ) && ! InstrExec . count ( & MI ) ) B . erase ( & MI ) ; } return Changed ;


<s> bool Changed = convertToProperty ( ) ; uint32_t Ps = properties ( ) ;

if ( Ps == ( Ps & Property ) ) return Changed ;


<s> const_iterator begin ( ) const { return Map . begin ( ) ;


<s> CellMap ( ) { assert ( Top . isTop ( ) ) ; Bottom . setBottom ( ) ;


<s> bool MachineConstPropagator :: computeBlockSuccessors ( const MachineBasicBlock * MB , SetVector < const MachineBasicBlock * > & Targets ) { MachineBasicBlock :: const_iterator FirstBr = MB -> end ( ) ; for ( const MachineInstr & MI : * MB ) { if ( MI . isDebugValue ( ) ) continue ; if ( MI . isBranch ( ) ) { FirstBr = MI . getIterator ( ) ; break ; } } Targets . clear ( ) ; MachineBasicBlock :: const_iterator End = MB -> end ( ) ; bool DoNext = true ; for ( MachineBasicBlock :: const_iterator I = FirstBr ; I != End ; ++ I ) { const MachineInstr & MI = * I ; if ( MI . isDebugValue ( ) ) continue ; if ( ! InstrExec . count ( & MI ) ) continue ; bool Eval = MCE . evaluate ( MI , Cells , Targets , DoNext ) ; if ( ! Eval ) return false ;


<s> } Targets . clear ( ) ; MachineBasicBlock :: const_iterator End = MB -> end ( ) ; bool DoNext = true ; for ( MachineBasicBlock :: const_iterator I = FirstBr ; I != End ; ++ I ) { const MachineInstr & MI = * I ; if ( MI . isDebugValue ( ) ) continue ; if ( ! InstrExec . count ( & MI ) ) continue ; bool Eval = MCE . evaluate ( MI , Cells , Targets , DoNext ) ; if ( ! Eval ) return false ; if ( ! DoNext ) break ;


<s> if ( ! CI ) return false ; Val = CI -> getValue ( ) ; return true ;


<s> bool LatticeCell :: convertToProperty ( ) { if ( isProperty ( ) ) return false ; uint32_t Everything = ConstantProperties :: Everything ;

uint32_t Ps = ! isTop ( ) ? properties ( ) : Everything ;


<s> bool LatticeCell :: convertToProperty ( ) { if ( isProperty ( ) ) return false ; uint32_t Everything = ConstantProperties :: Everything ; uint32_t Ps = ! isTop ( ) ? properties ( ) : Everything ; if ( Ps != ConstantProperties :: Unknown ) {


<s> if ( CI -> isNegative ( ) ) return Props | NegOrZero ; return Props | PosOrZero ; } if ( isa < ConstantFP > ( C ) ) { const ConstantFP * CF = cast < ConstantFP > ( C ) ; uint32_t Props = CF -> isNegative ( ) ? ( NegOrZero | NonZero ) : PosOrZero ; if ( CF -> isZero ( ) ) return ( Props & ~ NumericProperties ) | ( Zero | Finite ) ; Props = ( Props & ~ NumericProperties ) | NonZero ; if ( CF -> isNaN ( ) ) return ( Props & ~ NumericProperties ) | NaN ; const APFloat & Val = CF -> getValueAPF ( ) ; if ( Val . isInfinity ( ) ) return ( Props & ~ NumericProperties ) | Infinity ; Props |= Finite ;


<s> const ConstantInt * CI = cast < ConstantInt > ( C ) ; if ( CI -> isZero ( ) ) return Zero | PosOrZero | NegOrZero | Finite ; uint32_t Props = ( NonZero | Finite ) ; if ( CI -> isNegative ( ) ) return Props | NegOrZero ; return Props | PosOrZero ; } if ( isa < ConstantFP > ( C ) ) { const ConstantFP * CF = cast < ConstantFP > ( C ) ; uint32_t Props = CF -> isNegative ( ) ? ( NegOrZero | NonZero ) : PosOrZero ; if ( CF -> isZero ( ) ) return ( Props & ~ NumericProperties ) | ( Zero | Finite ) ; Props = ( Props & ~ NumericProperties ) | NonZero ; if ( CF -> isNaN ( ) ) return ( Props & ~ NumericProperties ) | NaN ; const APFloat & Val = CF -> getValueAPF ( ) ; if ( Val . isInfinity ( ) ) return ( Props & ~ NumericProperties ) | Infinity ; Props |= Finite ; return Props ; }


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


<s> Targets . insert ( BrI . getOperand ( <NUM_LIT> ) . getMBB ( ) ) ; FallsThru = false ; return true ; default : Undetermined : FallsThru = ! BrI . isUnconditionalBranch ( ) ; return false ; } if ( SimpleBranch ) { const MachineOperand & MD = BrI . getOperand ( <NUM_LIT> ) ; Register PR ( MD ) ; if ( PR . SubReg ) goto Undetermined ; assert ( Inputs . has ( PR . Reg ) ) ; const LatticeCell & PredC = Inputs . get ( PR . Reg ) ; if ( PredC . isBottom ( ) ) goto Undetermined ; uint32_t Props = PredC . properties ( ) ; bool CTrue = false , CFalse = false ; ;

if ( Props & ConstantProperties :: Zero ) CFalse = true ;


<s> bool MachineConstEvaluator :: evaluateANDii ( const APInt & A1 , const APInt & A2 , APInt & Result ) {


<s> bool MachineConstEvaluator :: evaluateANDii ( const APInt & A1 , const APInt & A2 , APInt & Result ) { Result = A1 & A2 ;


<s> bool MachineConstEvaluator :: evaluateANDri ( const Register & R1 , const APInt & A2 , const CellMap & Inputs , LatticeCell & Result ) { assert ( Inputs . has ( R1 . Reg ) ) ; if ( A2 == - <NUM_LIT> ) return getCell ( R1 , Inputs , Result ) ;


<s> if ( LS2 . isBottom ( ) || LS2 . isProperty ( ) ) return false ; APInt A ; for ( unsigned i = <NUM_LIT> ; i < LS2 . size ( ) ; ++ i ) { LatticeCell RC ; bool Eval = constToInt ( LS2 . Values [ i ] , A ) && evaluateANDri ( R1 , A , Inputs , RC ) ;


<s> bool MachineConstEvaluator :: evaluateCLBi ( const APInt & A1 , bool Zeros , bool Ones , APInt & Result ) { unsigned BW = A1 . getBitWidth ( ) ; if ( ! Zeros && ! Ones ) return false ; unsigned Count = <NUM_LIT> ; if ( Zeros && ( Count == <NUM_LIT> ) ) Count = A1 . countLeadingZeros ( ) ; if ( Ones && ( Count == <NUM_LIT> ) ) Count = A1 . countLeadingOnes ( ) ; Result = APInt ( BW , static_cast < uint64_t > ( Count ) , false ) ; return true ;


<s> bool MachineConstEvaluator :: evaluateCLBi ( const APInt & A1 , bool Zeros , bool Ones , APInt & Result ) { unsigned BW = A1 . getBitWidth ( ) ; if ( ! Zeros && ! Ones ) return false ; unsigned Count = <NUM_LIT> ; if ( Zeros && ( Count == <NUM_LIT> ) ) Count = A1 . countLeadingZeros ( ) ;

if ( Ones && ( Count == <NUM_LIT> ) ) Count = A1 . countLeadingOnes ( ) ;


<s> if ( LS1 . isBottom ( ) || LS1 . isProperty ( ) ) return false ; APInt A , CA ; for ( unsigned i = <NUM_LIT> ; i < LS1 . size ( ) ; ++ i ) { bool Eval = constToInt ( LS1 . Values [ i ] , A ) && evaluateCLBi ( A , Zeros , Ones , CA ) ; if ( ! Eval ) return false ; const Constant * C = intToConst ( CA ) ; Result . add ( C ) ;


<s> Result = false ; unsigned W1 = A1 . getBitWidth ( ) ; unsigned W2 = A2 . getBitWidth ( ) ; unsigned MaxW = ( W1 >= W2 ) ? W1 : W2 ; if ( Cmp & Comparison :: U ) { const APInt Zx1 = A1 . zextOrSelf ( MaxW ) ; const APInt Zx2 = A2 . zextOrSelf ( MaxW ) ; if ( Cmp & Comparison :: L ) Result = Zx1 . ult ( Zx2 ) ;

else if ( Cmp & Comparison :: G ) Result = Zx2 . ult ( Zx1 ) ;


<s> if ( Cmp & Comparison :: EQ ) { if ( APInt :: isSameValue ( A1 , A2 ) ) return ( Result = true ) ; } assert ( ( Cmp & ( Comparison :: L | Comparison :: G ) ) && <STR_LIT> ) ; Result = false ; unsigned W1 = A1 . getBitWidth ( ) ; unsigned W2 = A2 . getBitWidth ( ) ; unsigned MaxW = ( W1 >= W2 ) ? W1 : W2 ;


<s> if ( Props & ConstantProperties :: Zero ) Result = ( Cmp & Comparison :: EQ ) ; else if ( Props & ConstantProperties :: NonZero ) Result = ( Cmp & Comparison :: G ) || ( Cmp == Comparison :: NE ) ; else return false ; return true ; } if ( Props & ConstantProperties :: Zero ) { Result = ( Cmp & Comparison :: L ) || ( Cmp == Comparison :: NE ) ; return true ; } return false ; } if ( Props & ConstantProperties :: Zero ) { if ( A2 == <NUM_LIT> ) Result = ( Cmp & Comparison :: EQ ) ; else Result = ( Cmp == Comparison :: NE ) || ( ( Cmp & Comparison :: L ) && ! A2 . isNegative ( ) ) || ( ( Cmp & Comparison :: G ) && A2 . isNegative ( ) ) ; return true ; } if ( Props & ConstantProperties :: PosOrZero ) { if ( ! A2 . isNegative ( ) ) return false ; Result = ( Cmp & Comparison :: G ) || ( Cmp == Comparison :: NE ) ;


<s> } return false ; } bool Poz1 = ( Props1 & P :: PosOrZero ) , Poz2 = ( Props2 & P :: PosOrZero ) ; bool Nez1 = ( Props1 & P :: NegOrZero ) , Nez2 = ( Props2 & P :: NegOrZero ) ; if ( Nez1 && Poz2 ) { if ( NonZero1 || NonZero2 ) { Result = ( Cmp & Comparison :: L ) ; return true ; } if ( ( Cmp & Comparison :: EQ ) && ( Cmp & Comparison :: L ) ) return ( Result = true ) ; } if ( Poz1 && Nez2 ) { if ( NonZero1 || NonZero2 ) { Result = ( Cmp & Comparison :: G ) ;


<s> return true ; } if ( NonZero1 && Zero2 ) { Result = ( Cmp & Comparison :: G ) ; return true ; } return false ; } bool Poz1 = ( Props1 & P :: PosOrZero ) , Poz2 = ( Props2 & P :: PosOrZero ) ; bool Nez1 = ( Props1 & P :: NegOrZero ) , Nez2 = ( Props2 & P :: NegOrZero ) ; if ( Nez1 && Poz2 ) { if ( NonZero1 || NonZero2 ) { Result = ( Cmp & Comparison :: L ) ; return true ; } if ( ( Cmp & Comparison :: EQ ) && ( Cmp & Comparison :: L ) ) return ( Result = true ) ;


<s> bool IsTrue = true , IsFalse = true ; for ( unsigned i = <NUM_LIT> ; i < LS . size ( ) ; ++ i ) { bool Res ; bool Computed = constToInt ( LS . Values [ i ] , A ) && evaluateCMPpi ( NegCmp , Props2 , A , Res ) ; if ( ! Computed ) return false ; IsTrue &= Res ; IsFalse &= ! Res ; }


<s> if ( ! getCell ( R1 , Inputs , LS1 ) || ! getCell ( R2 , Inputs , LS2 ) ) return false ; bool IsProp1 = LS1 . isProperty ( ) ; bool IsProp2 = LS2 . isProperty ( ) ; if ( IsProp1 ) { uint32_t Prop1 = LS1 . properties ( ) ; if ( IsProp2 ) return evaluateCMPpp ( Cmp , Prop1 , LS2 . properties ( ) , Result ) ; uint32_t NegCmp = Comparison :: negate ( Cmp ) ;

return evaluateCMPrp ( NegCmp , R2 , Prop1 , Inputs , Result ) ;


<s> bool MachineConstEvaluator :: evaluateCOPY ( const Register & R1 , const CellMap & Inputs , LatticeCell & Result ) { return getCell ( R1 , Inputs , Result ) ;


<s> unsigned BW = A1 . getBitWidth ( ) ; if ( ! Zeros && ! Ones ) return false ; unsigned Count = <NUM_LIT> ; if ( Zeros && ( Count == <NUM_LIT> ) ) Count = A1 . countTrailingZeros ( ) ; if ( Ones && ( Count == <NUM_LIT> ) ) Count = A1 . countTrailingOnes ( ) ; Result = APInt ( BW , static_cast < uint64_t > ( Count ) , false ) ;


<s> if ( BW <= <NUM_LIT> ) { int64_t V = A1 . getZExtValue ( ) ; V <<= ( <NUM_LIT> - Bits - Offset ) ; if ( Signed ) V >>= ( <NUM_LIT> - Bits ) ; else V = static_cast < uint64_t > ( V ) >> ( <NUM_LIT> - Bits ) ; Result = APInt ( BW , V , Signed ) ; return true ; } if ( Signed ) Result = A1 . shl ( BW - Bits - Offset ) . ashr ( BW - Bits ) ; else Result = A1 . shl ( BW - Bits - Offset ) . lshr ( BW - Bits ) ; return true ;


<s> return true ; } return false ; } APInt A , CA ; for ( unsigned i = <NUM_LIT> ; i < LS1 . size ( ) ; ++ i ) { bool Eval = constToInt ( LS1 . Values [ i ] , A ) && evaluateEXTRACTi ( A , Bits , Offset , Signed , CA ) ; if ( ! Eval ) return false ; const Constant * C = intToConst ( CA ) ;


<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> : Classic = true ; break ; default : return false ; } if ( Classic ) { const MachineOperand & Src1 = MI . getOperand ( <NUM_LIT> ) ; const MachineOperand & Src2 = MI . getOperand ( <NUM_LIT> ) ;


<s> } else if ( Imm1 ) { APInt A1 = getCmpImm ( Opc , <NUM_LIT> , Src1 ) ; if ( Reg2 ) { Register R2 ( Src2 ) ; uint32_t NegCmp = Comparison :: negate ( Cmp ) ; return evaluateCMPri ( NegCmp , R2 , A1 , Inputs , Result ) ; } else if ( Imm2 ) { APInt A2 = getCmpImm ( Opc , <NUM_LIT> , Src2 ) ; return evaluateCMPii ( Cmp , A1 , A2 , Result ) ; }


<s> } else if ( Imm2 ) { APInt A2 = getCmpImm ( Opc , <NUM_LIT> , Src2 ) ; return evaluateCMPri ( Cmp , R1 , A2 , Inputs , Result ) ; } } else if ( Imm1 ) { APInt A1 = getCmpImm ( Opc , <NUM_LIT> , Src1 ) ; if ( Reg2 ) { Register R2 ( Src2 ) ; uint32_t NegCmp = Comparison :: negate ( Cmp ) ; return evaluateCMPri ( NegCmp , R2 , A1 , Inputs , Result ) ; } else if ( Imm2 ) { APInt A2 = getCmpImm ( Opc , <NUM_LIT> , Src2 ) ; return evaluateCMPii ( Cmp , A1 , A2 , Result ) ;


<s> assert ( Inputs . has ( CR . Reg ) ) ; LatticeCell LS ; if ( ! getCell ( CR , Inputs , LS ) ) return false ; uint32_t Ps = LS . properties ( ) ; unsigned TakeOp ; if ( Ps & ConstantProperties :: Zero ) TakeOp = <NUM_LIT> ; else if ( Ps & ConstantProperties :: NonZero ) TakeOp = <NUM_LIT> ; else return false ; const MachineOperand & ValOp = MI . getOperand ( TakeOp ) ; Register DefR ( MI . getOperand ( <NUM_LIT> ) ) ; LatticeCell RC = Outputs . get ( DefR . Reg ) ; if ( ValOp . isImm ( ) ) { int64_t V = ValOp . getImm ( ) ; unsigned W = getRegBitWidth ( DefR . Reg ) ; APInt A ( W , V , true ) ; const Constant * C = intToConst ( A ) ; RC . add ( C ) ; Outputs . update ( DefR . Reg , RC ) ; return true ; } if ( ValOp . isReg ( ) ) { Register R ( ValOp ) ;

const LatticeCell & LR = Inputs . get ( R . Reg ) ;


<s> APInt A ( <NUM_LIT> , Src2 . getImm ( ) , true ) ; Eval = evaluateANDri ( R1 , A , Inputs , RC ) ; break ; } case <STR_LIT> : case <STR_LIT> : Eval = evaluateORrr ( R1 , Register ( Src2 ) , Inputs , RC ) ; break ; case <STR_LIT> : { APInt A ( <NUM_LIT> , Src2 . getImm ( ) , true ) ; Eval = evaluateORri ( R1 , A , Inputs , RC ) ; break ; } case <STR_LIT> :


<s> case <STR_LIT> : case <STR_LIT> : Eval = evaluateORrr ( R1 , Register ( Src2 ) , Inputs , RC ) ; break ; case <STR_LIT> : { APInt A ( <NUM_LIT> , Src2 . getImm ( ) , true ) ; Eval = evaluateORri ( R1 , A , Inputs , RC ) ; break ; } case <STR_LIT> : case <STR_LIT> : Eval = evaluateXORrr ( R1 , Register ( Src2 ) , Inputs , RC ) ; break ; } if ( Eval ) { Register DefR ( MI . getOperand ( <NUM_LIT> ) ) ; Outputs . update ( DefR . Reg , RC ) ;


<s> for ( unsigned i = <NUM_LIT> ; i < LN ; ++ i ) { bool Eval = constToInt ( LSL . Values [ i ] , LoVs [ i ] ) ; if ( ! Eval ) return false ; assert ( LoVs [ i ] . getBitWidth ( ) == <NUM_LIT> ) ; } for ( unsigned i = <NUM_LIT> ; i < HN ; ++ i ) { bool Eval = constToInt ( LSH . Values [ i ] , HiVs [ i ] ) ; if ( ! Eval ) return false ; assert ( HiVs [ i ] . getBitWidth ( ) == <NUM_LIT> ) ; } for ( unsigned i = <NUM_LIT> ; i < HiVs . size ( ) ; ++ i ) { APInt HV = HiVs [ i ] . zextOrSelf ( <NUM_LIT> ) << <NUM_LIT> ; for ( unsigned j = <NUM_LIT> ; j < LoVs . size ( ) ; ++ j ) { APInt LV = LoVs [ j ] . zextOrSelf ( <NUM_LIT> ) ; const Constant * C = intToConst ( HV | LV ) ; Result . add ( C ) ; if ( Result . isBottom ( ) ) return false ; } } return ! Result . isBottom ( ) ;


<s> Register DefR ( MI . getOperand ( <NUM_LIT> ) ) ; Register R1 ( MI . getOperand ( <NUM_LIT> ) ) ; assert ( Inputs . has ( R1 . Reg ) ) ; LatticeCell RC = Outputs . get ( DefR . Reg ) ; bool Eval ; unsigned Opc = MI . getOpcode ( ) ; switch ( Opc ) { case <STR_LIT> : Eval = evaluateSplatr ( R1 , <NUM_LIT> , <NUM_LIT> , Inputs , RC ) ; break ; case <STR_LIT> : Eval = evaluateSplatr ( R1 , <NUM_LIT> , <NUM_LIT> , Inputs , RC ) ; break ; default : return false ; } if ( ! Eval ) return false ; Outputs . update ( DefR . Reg , RC ) ; return true ;


<s> for ( unsigned i = <NUM_LIT> ; i < LS1 . size ( ) ; ++ i ) { bool Eval = constToInt ( LS1 . Values [ i ] , A ) && evaluateORii ( A , A2 , ResA ) ; if ( ! Eval ) return false ; const Constant * C = intToConst ( ResA ) ;


<s> assert ( Inputs . has ( R1 . Reg ) && Inputs . has ( R2 . Reg ) ) ; const LatticeCell & L1 = Inputs . get ( R2 . Reg ) ; const LatticeCell & L2 = Inputs . get ( R2 . Reg ) ; if ( L2 . isBottom ( ) ) { if ( L1 . isBottom ( ) ) return false ; return evaluateORrr ( R2 , R1 , Inputs , Result ) ; } LatticeCell LS2 ; if ( ! evaluate ( R2 , L2 , LS2 ) ) return false ; if ( LS2 . isBottom ( ) || LS2 . isProperty ( ) ) return false ; APInt A ; for ( unsigned i = <NUM_LIT> ; i < LS2 . size ( ) ; ++ i ) { LatticeCell RC ; bool Eval = constToInt ( LS2 . Values [ i ] , A ) && evaluateORri ( R1 , A , Inputs , RC ) ; if ( ! Eval ) return false ; Result . meet ( RC ) ;


<s> for ( unsigned i = <NUM_LIT> ; i < LS2 . size ( ) ; ++ i ) { LatticeCell RC ; bool Eval = constToInt ( LS2 . Values [ i ] , A ) && evaluateORri ( R1 , A , Inputs , RC ) ; if ( ! Eval ) return false ; Result . meet ( RC ) ; }


<s> break ; default : V = ( V << ( <NUM_LIT> - Bits ) ) >> ( <NUM_LIT> - Bits ) ; break ; } Result = APInt ( Width , V , true ) ; return true ; } if ( Bits < BW ) Result = A1 . trunc ( Bits ) . sext ( Width ) ;


<s> if ( ! getCell ( R1 , Inputs , LS1 ) ) return false ; if ( LS1 . isBottom ( ) || LS1 . isProperty ( ) ) return false ; APInt A , XA ; for ( unsigned i = <NUM_LIT> ; i < LS1 . size ( ) ; ++ i ) { bool Eval = constToInt ( LS1 . Values [ i ] , A ) && evaluateSEXTi ( A , Width , Bits , XA ) ; if ( ! Eval ) return false ; const Constant * C = intToConst ( XA ) ;


<s> APInt A , XA ; for ( unsigned i = <NUM_LIT> ; i < LS1 . size ( ) ; ++ i ) { bool Eval = constToInt ( LS1 . Values [ i ] , A ) && evaluateSEXTi ( A , Width , Bits , XA ) ;


<s> APInt LoBits = ( Bits < BW ) ? A1 . trunc ( Bits ) : A1 . zextOrSelf ( Bits ) ; if ( Count > <NUM_LIT> ) LoBits = LoBits . zext ( SW ) ; APInt Res ( SW , <NUM_LIT> , false ) ; for ( unsigned i = <NUM_LIT> ; i < Count ; ++ i ) { Res <<= Bits ; Res |= LoBits ;


<s> bool MachineConstEvaluator :: evaluateXORii ( const APInt & A1 , const APInt & A2 , APInt & Result ) { Result = A1 ^ A2 ; return true ;


<s> bool MachineConstEvaluator :: evaluateXORii ( const APInt & A1 , const APInt & A2 , APInt & Result ) {