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


<s> if ( CoaCounter >= CoaLimit ) return false ; CoaCounter ++ ; } unsigned BW1 , BW2 ; if ( ! isIntReg ( R1 , BW1 ) || ! isIntReg ( R2 , BW2 ) || BW1 != BW2 ) return false ; if ( MRI -> isLiveIn ( R1 . Reg ) ) return false ; if ( MRI -> isLiveIn ( R2 . Reg ) ) return false ; LiveInterval & L1 = LIS -> getInterval ( R1 . Reg ) ; LiveInterval & L2 = LIS -> getInterval ( R2 . Reg ) ; if ( L2 . empty ( ) ) return false ; if ( L1 . hasSubRanges ( ) || L2 . hasSubRanges ( ) ) return false ; bool Overlap = L1 . overlaps ( L2 ) ;

LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << ( Overlap ? <STR_LIT> : <STR_LIT> ) << <STR_LIT> << printReg ( R1 . Reg , TRI , R1 . Sub ) << <STR_LIT> << L1 << <STR_LIT> << printReg ( R2 . Reg , TRI , R2 . Sub ) << <STR_LIT> << L2 << <STR_LIT> ) ;


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

else if ( CanDown ) predicateAt ( MD , DefI , TfrIt , MP , Cond , UpdRegs ) ;


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


<s> unsigned Opc = MI -> getOpcode ( ) ; unsigned PredOpc = HII -> getCondOpcode ( Opc , ! Cond ) ; MachineInstrBuilder MB = BuildMI ( B , Where , DL , HII -> get ( PredOpc ) ) ; unsigned Ox = <NUM_LIT> , NP = MI -> getNumOperands ( ) ; while ( Ox < NP ) { MachineOperand & MO = MI -> getOperand ( Ox ) ; if ( ! MO . isReg ( ) || ! MO . isDef ( ) ) break ; Ox ++ ; } MB . addReg ( DefOp . getReg ( ) , getRegState ( DefOp ) , DefOp . getSubReg ( ) ) ; MB . addReg ( PredOp . getReg ( ) , PredOp . isUndef ( ) ? RegState :: Undef : <NUM_LIT> , PredOp . getSubReg ( ) ) ; while ( Ox < NP ) { MachineOperand & MO = MI -> getOperand ( Ox ) ; if ( ! MO . isReg ( ) || ! MO . isImplicit ( ) ) MB . addOperand ( MO ) ; Ox ++ ; } MachineFunction & MF = * B . getParent ( ) ; MachineInstr :: mmo_iterator I = MI -> memoperands_begin ( ) ; unsigned NR = std :: distance ( I , MI -> memoperands_end ( ) ) ; MachineInstr :: mmo_iterator MemRefs = MF . allocateMemRefsArray ( NR ) ; for ( unsigned i = <NUM_LIT> ; i < NR ; ++ i ) MemRefs [ i ] = * I ++ ; MB . setMemRefs ( MemRefs , MemRefs + NR ) ; MachineInstr * NewI = MB ; NewI -> clearKillInfo ( ) ; LIS -> InsertMachineInstrInMaps ( * NewI ) ;

for ( auto & Op : NewI -> operands ( ) ) if ( Op . isReg ( ) ) UpdRegs . insert ( Op . getReg ( ) ) ;


<s> if ( ! Done ) { if ( RegisterRef ( I -> getOperand ( <NUM_LIT> ) ) == RegisterRef ( I -> getOperand ( <NUM_LIT> ) ) ) { for ( auto & Op : I -> operands ( ) ) if ( Op . isReg ( ) ) UpdRegs . insert ( Op . getReg ( ) ) ; removeInstr ( & * I ) ; }


<s> LIS -> RemoveMachineInstrFromMaps ( * MI ) ; MI -> eraseFromParent ( ) ;


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


<s> MachineBasicBlock :: iterator I , E , NextI ;

for ( I = B . begin ( ) , E = B . end ( ) ; I != E ; I = NextI ) {


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


<s> for ( MachineBasicBlock :: iterator I = std :: next ( StartI ) ; I != EndI ; ++ I ) { MachineInstr * MI = & * I ; if ( MI -> hasUnmodeledSideEffects ( ) ) return false ; bool L = MI -> mayLoad ( ) , S = MI -> mayStore ( ) ;


<s> bool IsLoad = TheI -> mayLoad ( ) , IsStore = TheI -> mayStore ( ) ; if ( ! IsLoad && ! IsStore ) return true ; if ( HII -> areMemAccessesTriviallyDisjoint ( * TheI , * ToI ) ) return true ; if ( TheI -> hasUnmodeledSideEffects ( ) ) return false ; MachineBasicBlock :: iterator StartI = IsDown ? TheI : ToI ; MachineBasicBlock :: iterator EndI = IsDown ? ToI : TheI ; bool Ordered = TheI -> hasOrderedMemoryRef ( ) ;

for ( MachineBasicBlock :: iterator I = std :: next ( StartI ) ; I != EndI ; ++ I ) {


<s> unsigned Mask = getMaskForSub ( RR . Sub ) | Exec ;

ReferenceMap :: iterator F = Map . find ( RR . Reg ) ;


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


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

VM . insert ( std :: make_pair ( OldVN , NewVN ) ) ;


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


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


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


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


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

AU . addPreserved < MachineDominatorTree > ( ) ;


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


<s> return IfTrue ? A2_tfrt : A2_tfrf ; case <NUM_LIT> : return IfTrue ? A2_tfrpt : A2_tfrpf ; } llvm_unreachable ( <STR_LIT> ) ; } switch ( SO . getType ( ) ) { case MachineOperand :: MO_Immediate : case MachineOperand :: MO_FPImmediate : case MachineOperand :: MO_ConstantPoolIndex : case MachineOperand :: MO_TargetIndex : case MachineOperand :: MO_JumpTableIndex : case MachineOperand :: MO_ExternalSymbol : case MachineOperand :: MO_GlobalAddress : case MachineOperand :: MO_BlockAddress :

return IfTrue ? C2_cmoveit : C2_cmoveif ;


<s> LaneBitmask <ISA_LIT>ExpandCondsets :: getLaneMask ( unsigned Reg , unsigned Sub ) { assert ( TargetRegisterInfo :: isVirtualRegister ( Reg ) ) ;

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


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


<s> switch ( Sub ) { case <STR_LIT> : case <STR_LIT> : return Sub_Low ;


<s> StringRef getPassName ( ) const override {


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

if ( RR . Sub == <NUM_LIT> || RD . Sub == <NUM_LIT> ) return nullptr ;


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


<s> <ISA_LIT>ExpandCondsets ( ) : MachineFunctionPass ( ID ) { if ( OptCoaLimit . getPosition ( ) ) CoaLimitActive = true , CoaLimit = OptCoaLimit ; if ( OptTfrLimit . getPosition ( ) ) TfrLimitActive = true , TfrLimit = OptTfrLimit ; initialize<ISA_LIT>ExpandCondsetsPass ( * PassRegistry :: getPassRegistry ( ) ) ;


<s> <ISA_LIT>ExpandCondsets ( ) : MachineFunctionPass ( ID ) { if ( OptCoaLimit . getPosition ( ) ) CoaLimitActive = true , CoaLimit = OptCoaLimit ;

if ( OptTfrLimit . getPosition ( ) ) TfrLimitActive = true , TfrLimit = OptTfrLimit ;


<s> switch ( Opc ) { case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> :


<s> for ( LiveInterval :: iterator I = LI . begin ( ) , E = LI . end ( ) ; I != E ; ++ I ) { LiveRange :: Segment & LR = * I ; if ( ! LR . start . isRegister ( ) ) return false ; if ( ! LR . end . isRegister ( ) && ! LR . end . isDead ( ) ) return false ; }


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


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


<s> bool <ISA_LIT>ExpandCondsets :: isRefInMap ( RegisterRef RR , ReferenceMap & Map , unsigned Exec ) { ReferenceMap :: iterator F = Map . find ( RR . Reg ) ;

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


<s> ReferenceMap :: iterator F = Map . find ( RR . Reg ) ; if ( F == Map . end ( ) ) return false ; unsigned Mask = getMaskForSub ( RR . Sub ) | Exec ; if ( Mask & F -> second ) return true ; return false ;


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


<s> while ( Ox < NP ) { MachineOperand & MO = MI . getOperand ( Ox ) ; if ( ! MO . isReg ( ) || ! MO . isImplicit ( ) ) MB . add ( MO ) ; Ox ++ ; } MachineFunction & MF = * B . getParent ( ) ; MachineInstr :: mmo_iterator I = MI . memoperands_begin ( ) ; unsigned NR = std :: distance ( I , MI . memoperands_end ( ) ) ; MachineInstr :: mmo_iterator MemRefs = MF . allocateMemRefsArray ( NR ) ; for ( unsigned i = <NUM_LIT> ; i < NR ; ++ i ) MemRefs [ i ] = * I ++ ; MB . setMemRefs ( MemRefs , MemRefs + NR ) ; MachineInstr * NewI = MB ; NewI -> clearKillInfo ( ) ; LIS -> InsertMachineInstrInMaps ( * NewI ) ; for ( auto & Op : NewI -> operands ( ) ) if ( Op . isReg ( ) ) UpdRegs . insert ( Op . getReg ( ) ) ;


<s> Ox ++ ; } MB . addReg ( DefOp . getReg ( ) , getRegState ( DefOp ) , DefOp . getSubReg ( ) ) ; MB . addReg ( PredOp . getReg ( ) , PredOp . isUndef ( ) ? RegState :: Undef : <NUM_LIT> , PredOp . getSubReg ( ) ) ; while ( Ox < NP ) { MachineOperand & MO = MI . getOperand ( Ox ) ; if ( ! MO . isReg ( ) || ! MO . isImplicit ( ) ) MB . add ( MO ) ; Ox ++ ; } MachineFunction & MF = * B . getParent ( ) ; MachineInstr :: mmo_iterator I = MI . memoperands_begin ( ) ; unsigned NR = std :: distance ( I , MI . memoperands_end ( ) ) ; MachineInstr :: mmo_iterator MemRefs = MF . allocateMemRefsArray ( NR ) ;

for ( unsigned i = <NUM_LIT> ; i < NR ; ++ i ) MemRefs [ i ] = * I ++ ;


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


<s> bool <ISA_LIT>ExpandCondsets :: predicateInBlock ( MachineBasicBlock & B , std :: set < unsigned > & UpdRegs ) { bool Changed = false ; MachineBasicBlock :: iterator I , E , NextI ; for ( I = B . begin ( ) , E = B . end ( ) ; I != E ; I = NextI ) {


<s> LIS -> createAndComputeVirtRegInterval ( Reg ) ;


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


<s> void <ISA_LIT>ExpandCondsets :: removeInstr ( MachineInstr & MI ) { LIS -> RemoveMachineInstrFromMaps ( MI ) ; MI . eraseFromParent ( ) ;


<s> LIS -> RemoveMachineInstrFromMaps ( MI ) ;


<s> for ( auto & Op : MI -> operands ( ) ) { if ( ! Op . isReg ( ) || RO != RegisterRef ( Op ) ) continue ; Op . setReg ( RN . Reg ) ; Op . setSubReg ( RN . Sub ) ; assert ( ! Op . isDef ( ) && <STR_LIT> ) ;


<s> void <ISA_LIT>ExpandCondsets :: renameInRange ( RegisterRef RO , RegisterRef RN , unsigned PredR , bool Cond , MachineBasicBlock :: iterator First , MachineBasicBlock :: iterator Last ) { MachineBasicBlock :: iterator End = std :: next ( Last ) ; for ( MachineBasicBlock :: iterator I = First ; I != End ; ++ I ) { MachineInstr * MI = & * I ; if ( ! HII -> isPredicated ( * MI ) ) continue ; if ( ! MI -> readsRegister ( PredR ) || ( Cond != HII -> isPredicatedTrue ( * MI ) ) ) continue ;

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


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

PredUpd . insert ( CoalUpd . begin ( ) , CoalUpd . end ( ) ) ;


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


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


<s> LiveInterval & LI = LIS -> getInterval ( Reg ) ; if ( LI . hasSubRanges ( ) ) { for ( LiveInterval :: SubRange & S : LI . subranges ( ) ) {

updateDeadsInRange ( Reg , S . LaneMask , S ) ;


<s> if ( LI . hasSubRanges ( ) ) { for ( LiveInterval :: SubRange & S : LI . subranges ( ) ) { updateDeadsInRange ( Reg , S . LaneMask , S ) ; LIS -> shrinkToUses ( S , Reg ) ; } LI . clear ( ) ; LIS -> constructMainRangeFromSubranges ( LI ) ;


<s> void <ISA_LIT>ExpandCondsets :: updateKillFlags ( unsigned Reg ) { auto KillAt = [ this , Reg ] ( SlotIndex K , LaneBitmask LM ) -> void { MachineInstr * MI = LIS -> getInstructionFromIndex ( K ) ; for ( auto & Op : MI -> operands ( ) ) { if ( ! Op . isReg ( ) || ! Op . isUse ( ) || Op . getReg ( ) != Reg ) continue ; LaneBitmask SLM = getLaneMask ( Reg , Op . getSubReg ( ) ) ; if ( ( SLM & LM ) == SLM ) { Op . setIsKill ( true ) ; break ; } } } ; LiveInterval & LI = LIS -> getInterval ( Reg ) ; for ( auto I = LI . begin ( ) , E = LI . end ( ) ; I != E ; ++ I ) { if ( ! I -> end . isRegister ( ) ) continue ; auto NextI = std :: next ( I ) ; if ( NextI != E && NextI -> start . isRegister ( ) ) { MachineInstr * DefI = LIS -> getInstructionFromIndex ( NextI -> start ) ; if ( HII -> isPredicated ( * DefI ) ) continue ; } bool WholeReg = true ; if ( LI . hasSubRanges ( ) ) { auto EndsAtI = [ I ] ( LiveInterval :: SubRange & S ) -> bool { LiveRange :: iterator F = S . find ( I -> end ) ; return F != S . end ( ) && I -> end == F -> end ; } ; for ( LiveInterval :: SubRange & S : LI . subranges ( ) ) { if ( EndsAtI ( S ) ) KillAt ( I -> end , S . LaneMask ) ; else WholeReg = false ; }


<s> void <ISA_LIT>ExpandCondsets :: updateLiveness ( std :: set < unsigned > & RegSet , bool Recalc , bool UpdateKills , bool UpdateDeads ) { UpdateKills |= UpdateDeads ; for ( auto R : RegSet ) { if ( Recalc ) recalculateLiveInterval ( R ) ; if ( UpdateKills ) MRI -> clearKillFlags ( R ) ; if ( UpdateDeads ) updateDeadFlags ( R ) ; if ( UpdateKills ) updateKillFlags ( R ) ; LIS -> getInterval ( R ) . verify ( ) ;


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

if ( UpdateKills ) updateKillFlags ( R ) ;


<s> FunctionPass * llvm :: create<ISA_LIT>ExpandPredSpillCode ( <ISA_LIT>TargetMachine & TM ) { return new <ISA_LIT>ExpandPredSpillCode ( TM ) ;


<s> MachineFunctionPass ( ID ) , QTM ( TM ) , QST ( * TM . getSubtargetImpl ( ) ) {


<s> <ISA_LIT>ExpandPredSpillCode ( <ISA_LIT>TargetMachine & TM ) : MachineFunctionPass ( ID ) , QTM ( TM ) , QST ( * TM . getSubtargetImpl ( ) ) {


PassInfo * PI = new PassInfo ( Name , <STR_LIT> , & <ISA_LIT>ExpandPredSpillCode :: ID , <NUM_LIT> , false , false ) ;


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


<s> BuildMI ( * MBB , MII , MI -> getDebugLoc ( ) , TII -> get ( <STR_LIT> ) ) . addReg ( FP ) . addImm ( Offset ) . addReg ( HEXAGON_RESERVED_REG_2 ) ; } MII = MBB -> erase ( MI ) ; -- MII ; } else if ( Opc == <STR_LIT> ) { int DstReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; assert ( <STR_LIT> . contains ( DstReg ) && <STR_LIT> ) ; unsigned FP = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; assert ( FP == QTM . getSubtargetImpl ( ) -> getRegisterInfo ( ) -> getFrameRegister ( ) && <STR_LIT> ) ; assert ( MI -> getOperand ( <NUM_LIT> ) . isImm ( ) && <STR_LIT> ) ; int Offset = MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ; if ( ! TII -> isValidOffset ( <STR_LIT> , Offset ) ) { if ( ! TII -> isValidOffset ( <STR_LIT> , Offset ) ) { BuildMI ( * MBB , MII , MI -> getDebugLoc ( ) , TII -> get ( <STR_LIT> ) , HEXAGON_RESERVED_REG_1 ) . addImm ( Offset ) ; BuildMI ( * MBB , MII , MI -> getDebugLoc ( ) , TII -> get ( <STR_LIT> ) , HEXAGON_RESERVED_REG_1 ) . addReg ( FP ) . addReg ( HEXAGON_RESERVED_REG_1 ) ; BuildMI ( * MBB , MII , MI -> getDebugLoc ( ) , TII -> get ( <STR_LIT> ) , HEXAGON_RESERVED_REG_2 ) . addReg ( HEXAGON_RESERVED_REG_1 ) . addImm ( <NUM_LIT> ) ; BuildMI ( * MBB , MII , MI -> getDebugLoc ( ) , TII -> get ( <STR_LIT> ) , DstReg ) . addReg ( HEXAGON_RESERVED_REG_2 ) ; } else { BuildMI ( * MBB , MII , MI -> getDebugLoc ( ) , TII -> get ( <STR_LIT> ) , HEXAGON_RESERVED_REG_1 ) . addReg ( FP ) . addImm ( Offset ) ;


<s> } MII = MBB -> erase ( MI ) ; -- MII ; } else if ( Opc == <STR_LIT> ) { int DstReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; assert ( <STR_LIT> . contains ( DstReg ) && <STR_LIT> ) ; unsigned FP = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; assert ( FP == QST . getRegisterInfo ( ) -> getFrameRegister ( ) && <STR_LIT> ) ; assert ( MI -> getOperand ( <NUM_LIT> ) . isImm ( ) && <STR_LIT> ) ; int Offset = MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ; if ( ! TII -> isValidOffset ( <STR_LIT> , Offset ) ) { if ( ! TII -> isValidOffset ( <STR_LIT> , Offset ) ) { BuildMI ( * MBB , MII , MI -> getDebugLoc ( ) , TII -> get ( <STR_LIT> ) , HEXAGON_RESERVED_REG_1 ) . addImm ( Offset ) ; BuildMI ( * MBB , MII , MI -> getDebugLoc ( ) , TII -> get ( <STR_LIT> ) , HEXAGON_RESERVED_REG_1 ) . addReg ( FP ) . addReg ( HEXAGON_RESERVED_REG_1 ) ; BuildMI ( * MBB , MII , MI -> getDebugLoc ( ) , TII -> get ( <STR_LIT> ) , HEXAGON_RESERVED_REG_2 ) . addReg ( HEXAGON_RESERVED_REG_1 ) . addImm ( <NUM_LIT> ) ; BuildMI ( * MBB , MII , MI -> getDebugLoc ( ) , TII -> get ( <STR_LIT> ) , DstReg ) . addReg ( HEXAGON_RESERVED_REG_2 ) ; } else { BuildMI ( * MBB , MII , MI -> getDebugLoc ( ) , TII -> get ( <STR_LIT> ) , HEXAGON_RESERVED_REG_1 ) . addReg ( FP ) . addImm ( Offset ) ; BuildMI ( * MBB , MII , MI -> getDebugLoc ( ) , TII -> get ( <STR_LIT> ) , HEXAGON_RESERVED_REG_2 ) . addReg ( HEXAGON_RESERVED_REG_1 ) . addImm ( <NUM_LIT> ) ; BuildMI ( * MBB , MII , MI -> getDebugLoc ( ) , TII -> get ( <STR_LIT> ) , DstReg ) . addReg ( HEXAGON_RESERVED_REG_2 ) ; } } else { BuildMI ( * MBB , MII , MI -> getDebugLoc ( ) , TII -> get ( <STR_LIT> ) , HEXAGON_RESERVED_REG_2 ) . addReg ( FP ) . addImm ( Offset ) ; BuildMI ( * MBB , MII , MI -> getDebugLoc ( ) , TII -> get ( <STR_LIT> ) , DstReg ) . addReg ( HEXAGON_RESERVED_REG_2 ) ;


<s> FunctionPass * llvm :: create<ISA_LIT>ExpandPredSpillCode ( const <ISA_LIT>TargetMachine & TM ) {

return new <ISA_LIT>ExpandPredSpillCode ( TM ) ;


<s> return new <ISA_LIT>ExpandPredSpillCode ( TM ) ;


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


<s> PassRegistry & Registry = * PassRegistry :: getPassRegistry ( ) ;


<s> <ISA_LIT>ExpandPredSpillCode ( const <ISA_LIT>TargetMachine & TM ) :

MachineFunctionPass ( ID ) , QTM ( TM ) , QST ( * TM . getSubtargetImpl ( ) ) {


<s> const char * Name = <STR_LIT> ; PassInfo * PI = new PassInfo ( Name , <STR_LIT> , & <ISA_LIT>ExpandPredSpillCode :: ID , nullptr , false , false ) ;

Registry . registerPass ( * PI , true ) ;


<s> static void initializePassOnce ( PassRegistry & Registry ) {


<s> if ( Opc == <STR_LIT> ) { unsigned FP = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; assert ( FP == QTM . getRegisterInfo ( ) -> getFrameRegister ( ) && <STR_LIT> ) ; assert ( MI -> getOperand ( <NUM_LIT> ) . isImm ( ) && <STR_LIT> ) ; int Offset = MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ; int SrcReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; assert ( <STR_LIT> . contains ( SrcReg ) && <STR_LIT> ) ; if ( ! TII -> isValidOffset ( <STR_LIT> , Offset ) ) { if ( ! TII -> isValidOffset ( <STR_LIT> , Offset ) ) { BuildMI ( * MBB , MII , MI -> getDebugLoc ( ) , TII -> get ( <STR_LIT> ) , HEXAGON_RESERVED_REG_1 ) . addImm ( Offset ) ; BuildMI ( * MBB , MII , MI -> getDebugLoc ( ) , TII -> get ( <STR_LIT> ) , HEXAGON_RESERVED_REG_1 ) . addReg ( FP ) . addReg ( HEXAGON_RESERVED_REG_1 ) ; BuildMI ( * MBB , MII , MI -> getDebugLoc ( ) , TII -> get ( <STR_LIT> ) , HEXAGON_RESERVED_REG_2 ) . addReg ( SrcReg ) ; BuildMI ( * MBB , MII , MI -> getDebugLoc ( ) , TII -> get ( <STR_LIT> ) ) . addReg ( HEXAGON_RESERVED_REG_1 ) . addImm ( <NUM_LIT> ) . addReg ( HEXAGON_RESERVED_REG_2 ) ; } else { BuildMI ( * MBB , MII , MI -> getDebugLoc ( ) , TII -> get ( <STR_LIT> ) , HEXAGON_RESERVED_REG_1 ) . addReg ( FP ) . addImm ( Offset ) ; BuildMI ( * MBB , MII , MI -> getDebugLoc ( ) , TII -> get ( <STR_LIT> ) , HEXAGON_RESERVED_REG_2 ) . addReg ( SrcReg ) ; BuildMI ( * MBB , MII , MI -> getDebugLoc ( ) , TII -> get ( <STR_LIT> ) ) . addReg ( HEXAGON_RESERVED_REG_1 ) . addImm ( <NUM_LIT> ) . addReg ( HEXAGON_RESERVED_REG_2 ) ; } } else { BuildMI ( * MBB , MII , MI -> getDebugLoc ( ) , TII -> get ( <STR_LIT> ) , HEXAGON_RESERVED_REG_2 ) . addReg ( SrcReg ) ; BuildMI ( * MBB , MII , MI -> getDebugLoc ( ) , TII -> get ( <STR_LIT> ) ) . addReg ( FP ) . addImm ( Offset ) . addReg ( HEXAGON_RESERVED_REG_2 ) ; } MII = MBB -> erase ( MI ) ; -- MII ; } else if ( Opc == <STR_LIT> ) { int DstReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; assert ( <STR_LIT> . contains ( DstReg ) && <STR_LIT> ) ; unsigned FP = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; assert ( FP == QTM . getRegisterInfo ( ) -> getFrameRegister ( ) && <STR_LIT> ) ; assert ( MI -> getOperand ( <NUM_LIT> ) . isImm ( ) && <STR_LIT> ) ;


<s> DebugLoc DL = MII -> getDebugLoc ( ) ; unsigned Scratch = RS . scavengeRegister ( & <STR_LIT> , MII , <NUM_LIT> ) ; if ( MII -> getOperand ( <NUM_LIT> ) . isReg ( ) ) { BuildMI ( * MBB , MII , DL , TII -> get ( <STR_LIT> ) , <STR_LIT> ) . addReg ( MII -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ; } else { BuildMI ( * MBB , MII , DL , TII -> get ( <STR_LIT> ) , Scratch ) . addImm ( MII -> getOperand ( <NUM_LIT> ) . getImm ( ) ) ; BuildMI ( * MBB , MII , DL , TII -> get ( <STR_LIT> ) , <STR_LIT> ) . addReg ( Scratch ) ; }

BuildMI ( * MBB , MII , DL , TII -> get ( <STR_LIT> ) , Scratch ) . addMBB ( MII -> getOperand ( <NUM_LIT> ) . getMBB ( ) ) ;


<s> const TargetInstrInfo * TII = MF . getSubtarget ( ) . getInstrInfo ( ) ; MachineBasicBlock * MBB = MII -> getParent ( ) ; DebugLoc DL = MII -> getDebugLoc ( ) ; unsigned Scratch = RS . scavengeRegister ( & <STR_LIT> , MII , <NUM_LIT> ) ; if ( MII -> getOperand ( <NUM_LIT> ) . isReg ( ) ) { BuildMI ( * MBB , MII , DL , TII -> get ( <STR_LIT> ) , <STR_LIT> ) . addReg ( MII -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ; } else {

BuildMI ( * MBB , MII , DL , TII -> get ( <STR_LIT> ) , Scratch ) . addImm ( MII -> getOperand ( <NUM_LIT> ) . getImm ( ) ) ;


<s> static bool isHardwareLoop ( const MachineInstr * MI ) { return MI -> getOpcode ( ) == <STR_LIT> || MI -> getOpcode ( ) == <STR_LIT> ;


<s> unsigned InstOffset = <NUM_LIT> ; DenseMap < const MachineBasicBlock * , unsigned > BlockToInstOffset ; const <ISA_LIT>InstrInfo * HII = static_cast < const <ISA_LIT>InstrInfo * > ( MF . getSubtarget ( ) . getInstrInfo ( ) ) ; for ( const MachineBasicBlock & MBB : MF ) { if ( MBB . getLogAlignment ( ) ) { int ByteAlign = ( <NUM_LIT> << MBB . getLogAlignment ( ) ) - <NUM_LIT> ; InstOffset = ( InstOffset + ByteAlign ) & ~ ( ByteAlign ) ; } BlockToInstOffset [ & MBB ] = InstOffset ; for ( const MachineInstr & MI : MBB ) InstOffset += HII -> getSize ( MI ) ; }


<s> unsigned InstOffset = <NUM_LIT> ; DenseMap < const MachineBasicBlock * , unsigned > BlockToInstOffset ; const <ISA_LIT>InstrInfo * HII = static_cast < const <ISA_LIT>InstrInfo * > ( MF . getSubtarget ( ) . getInstrInfo ( ) ) ; for ( const MachineBasicBlock & MBB : MF ) { if ( MBB . getLogAlignment ( ) ) { int ByteAlign = ( <NUM_LIT> << MBB . getLogAlignment ( ) ) - <NUM_LIT> ; InstOffset = ( InstOffset + ByteAlign ) & ~ ( ByteAlign ) ; }

BlockToInstOffset [ & MBB ] = InstOffset ;


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


<s> switch ( MII -> getOpcode ( ) ) { case <STR_LIT> : newOp = <STR_LIT> ; break ; case <STR_LIT> : newOp = <STR_LIT> ; break ; case <STR_LIT> : newOp = <STR_LIT> ; break ; case <STR_LIT> : newOp = <STR_LIT> ; break ; default : llvm_unreachable ( <STR_LIT> ) ; } MIB = BuildMI ( * MBB , MII , DL , TII -> get ( newOp ) ) ; for ( unsigned i = <NUM_LIT> ; i < MII -> getNumOperands ( ) ; ++ i ) MIB . add ( MII -> getOperand ( i ) ) ;


<s> const TargetInstrInfo * TII = MF . getSubtarget ( ) . getInstrInfo ( ) ; MachineBasicBlock * MBB = MII -> getParent ( ) ; DebugLoc DL = MII -> getDebugLoc ( ) ; MachineInstrBuilder MIB ; unsigned newOp ; switch ( MII -> getOpcode ( ) ) { case <STR_LIT> : newOp = <STR_LIT> ; break ; case <STR_LIT> : newOp = <STR_LIT> ; break ; case <STR_LIT> : newOp = <STR_LIT> ; break ; case <STR_LIT> : newOp = <STR_LIT> ; break ; default : llvm_unreachable ( <STR_LIT> ) ; }

MIB = BuildMI ( * MBB , MII , DL , TII -> get ( newOp ) ) ;


<s> } BlockToInstOffset [ & MBB ] = InstOffset ; for ( const MachineInstr & MI : MBB ) InstOffset += HII -> getSize ( MI ) ; } bool Changed = false ; for ( MachineBasicBlock & MBB : MF ) { InstOffset = BlockToInstOffset [ & MBB ] ; MachineBasicBlock :: iterator MII = MBB . begin ( ) ; MachineBasicBlock :: iterator MIE = MBB . end ( ) ; while ( MII != MIE ) { unsigned InstSize = HII -> getSize ( * MII ) ; if ( MII -> isMetaInstruction ( ) ) { ++ MII ;


<s> InstOffset = alignTo ( InstOffset , MBB . getAlignment ( ) ) ; } BlockToInstOffset [ & MBB ] = InstOffset ; for ( const MachineInstr & MI : MBB ) InstOffset += HII -> getSize ( MI ) ; } bool Changed = false ; for ( MachineBasicBlock & MBB : MF ) { InstOffset = BlockToInstOffset [ & MBB ] ; MachineBasicBlock :: iterator MII = MBB . begin ( ) ; MachineBasicBlock :: iterator MIE = MBB . end ( ) ; while ( MII != MIE ) { unsigned InstSize = HII -> getSize ( * MII ) ;


<s> InstOffset = BlockToInstOffset [ & MBB ] ; MachineBasicBlock :: iterator MII = MBB . begin ( ) ; MachineBasicBlock :: iterator MIE = MBB . end ( ) ; while ( MII != MIE ) { InstOffset += HII -> getSize ( & * MII ) ; if ( MII -> isDebugValue ( ) ) { ++ MII ; continue ; } if ( isHardwareLoop ( * MII ) ) { assert ( MII -> getOperand ( <NUM_LIT> ) . isMBB ( ) && <STR_LIT> ) ; int diff = InstOffset - BlockToInstOffset [ MII -> getOperand ( <NUM_LIT> ) . getMBB ( ) ] ; if ( ( unsigned ) abs ( diff ) > MaxLoopRange ) { useExtLoopInstr ( MF , MII ) ; MII = MBB . erase ( MII ) ; Changed = true ; } else { ++ MII ; } } else { ++ MII ; } }


<s> for ( const MachineInstr & MI : MBB ) InstOffset += HII -> getSize ( MI ) ; } bool Changed = false ; for ( MachineBasicBlock & MBB : MF ) { InstOffset = BlockToInstOffset [ & MBB ] ; MachineBasicBlock :: iterator MII = MBB . begin ( ) ; MachineBasicBlock :: iterator MIE = MBB . end ( ) ; while ( MII != MIE ) { unsigned InstSize = HII -> getSize ( * MII ) ; if ( MII -> isMetaInstruction ( ) ) { ++ MII ; continue ; } if ( isHardwareLoop ( * MII ) ) { assert ( MII -> getOperand ( <NUM_LIT> ) . isMBB ( ) && <STR_LIT> ) ; MachineBasicBlock * TargetBB = MII -> getOperand ( <NUM_LIT> ) . getMBB ( ) ; unsigned Diff = AbsoluteDifference ( InstOffset , BlockToInstOffset [ TargetBB ] ) ; if ( Diff > MaxLoopRange ) {


<s> unsigned InstSize = HII -> getSize ( * MII ) ; if ( MII -> isMetaInstruction ( ) ) { ++ MII ; continue ; } if ( isHardwareLoop ( * MII ) ) { assert ( MII -> getOperand ( <NUM_LIT> ) . isMBB ( ) && <STR_LIT> ) ; MachineBasicBlock * TargetBB = MII -> getOperand ( <NUM_LIT> ) . getMBB ( ) ; unsigned Diff = AbsoluteDifference ( InstOffset , BlockToInstOffset [ TargetBB ] ) ; if ( Diff > MaxLoopRange ) { useExtLoopInstr ( MF , MII ) ; MII = MBB . erase ( MII ) ; Changed = true ; } else {


<s> MachineBasicBlock :: iterator MIE = MBB . end ( ) ; while ( MII != MIE ) { InstOffset += HII -> getSize ( * MII ) ; if ( MII -> isMetaInstruction ( ) ) { ++ MII ; continue ; } if ( isHardwareLoop ( * MII ) ) { assert ( MII -> getOperand ( <NUM_LIT> ) . isMBB ( ) && <STR_LIT> ) ; int diff = InstOffset - BlockToInstOffset [ MII -> getOperand ( <NUM_LIT> ) . getMBB ( ) ] ; if ( ( unsigned ) abs ( diff ) > MaxLoopRange ) { useExtLoopInstr ( MF , MII ) ; MII = MBB . erase ( MII ) ; Changed = true ; } else { ++ MII ; } } else { ++ MII ;


<s> BlockToInstOffset [ & MBB ] = InstOffset ; for ( const MachineInstr & MI : MBB ) InstOffset += HII -> getSize ( MI ) ; } bool Changed = false ; for ( MachineBasicBlock & MBB : MF ) { InstOffset = BlockToInstOffset [ & MBB ] ; MachineBasicBlock :: iterator MII = MBB . begin ( ) ; MachineBasicBlock :: iterator MIE = MBB . end ( ) ; while ( MII != MIE ) { InstOffset += HII -> getSize ( * MII ) ; if ( MII -> isDebugValue ( ) ) { ++ MII ; continue ; } if ( isHardwareLoop ( * MII ) ) { assert ( MII -> getOperand ( <NUM_LIT> ) . isMBB ( ) && <STR_LIT> ) ; int diff = InstOffset - BlockToInstOffset [ MII -> getOperand ( <NUM_LIT> ) . getMBB ( ) ] ; if ( ( unsigned ) abs ( diff ) > MaxLoopRange ) { useExtLoopInstr ( MF , MII ) ; MII = MBB . erase ( MII ) ; Changed = true ; } else { ++ MII ; } } else { ++ MII ; } }


<s> static bool isHardwareLoop ( const MachineInstr & MI ) {

return MI . getOpcode ( ) == <STR_LIT> || MI . getOpcode ( ) == <STR_LIT> || MI . getOpcode ( ) == <STR_LIT> || MI . getOpcode ( ) == <STR_LIT> ;


<s> if ( skipFunction ( * MF . getFunction ( ) ) ) return false ; return fixupLoopInstrs ( MF ) ;


<s> if ( skipFunction ( * MF . getFunction ( ) ) ) return false ;


<s> newOp = <STR_LIT> ; break ; case <STR_LIT> : newOp = <STR_LIT> ; break ; case <STR_LIT> : newOp = <STR_LIT> ; break ; case <STR_LIT> : newOp = <STR_LIT> ; break ; default : llvm_unreachable ( <STR_LIT> ) ; } MIB = BuildMI ( * MBB , MII , DL , TII -> get ( newOp ) ) ; for ( unsigned i = <NUM_LIT> ; i < MII -> getNumOperands ( ) ; ++ i ) MIB . addOperand ( MII -> getOperand ( i ) ) ;


<s> static bool isHardwareLoop ( const MachineInstr * MI ) {

return MI -> getOpcode ( ) == <STR_LIT> || MI -> getOpcode ( ) == <STR_LIT> || MI -> getOpcode ( ) == <STR_LIT> || MI -> getOpcode ( ) == <STR_LIT> ;


<s> bool <ISA_LIT>FixupHwLoops :: fixupLoopInstrs ( MachineFunction & MF ) { unsigned InstOffset = <NUM_LIT> ; DenseMap < const MachineBasicBlock * , unsigned > BlockToInstOffset ; const <ISA_LIT>InstrInfo * HII = static_cast < const <ISA_LIT>InstrInfo * > ( MF . getSubtarget ( ) . getInstrInfo ( ) ) ; for ( const MachineBasicBlock & MBB : MF ) { if ( MBB . getAlignment ( ) ) { int ByteAlign = ( <NUM_LIT> << MBB . getAlignment ( ) ) - <NUM_LIT> ; InstOffset = ( InstOffset + ByteAlign ) & ~ ( ByteAlign ) ; } BlockToInstOffset [ & MBB ] = InstOffset ; for ( const MachineInstr & MI : MBB ) InstOffset += HII -> getSize ( MI ) ; } bool Changed = false ; for ( MachineBasicBlock & MBB : MF ) { InstOffset = BlockToInstOffset [ & MBB ] ; MachineBasicBlock :: iterator MII = MBB . begin ( ) ; MachineBasicBlock :: iterator MIE = MBB . end ( ) ; while ( MII != MIE ) { unsigned InstSize = HII -> getSize ( * MII ) ; if ( MII -> isMetaInstruction ( ) ) { ++ MII ; continue ; } if ( isHardwareLoop ( * MII ) ) { assert ( MII -> getOperand ( <NUM_LIT> ) . isMBB ( ) && <STR_LIT> ) ; MachineBasicBlock * TargetBB = MII -> getOperand ( <NUM_LIT> ) . getMBB ( ) ; unsigned Diff = AbsoluteDifference ( InstOffset , BlockToInstOffset [ TargetBB ] ) ; if ( Diff > MaxLoopRange ) { useExtLoopInstr ( MF , MII ) ; MII = MBB . erase ( MII ) ; Changed = true ; } else { ++ MII ; } } else { ++ MII ;


<s> const char * getPassName ( ) const {


<s> bool Changed = false ; for ( MachineBasicBlock & MBB : MF ) { InstOffset = BlockToInstOffset [ & MBB ] ; MachineBasicBlock :: iterator MII = MBB . begin ( ) ; MachineBasicBlock :: iterator MIE = MBB . end ( ) ; while ( MII != MIE ) { InstOffset += HII -> getSize ( & * MII ) ; if ( MII -> isDebugValue ( ) ) { ++ MII ; continue ; } if ( isHardwareLoop ( MII ) ) { assert ( MII -> getOperand ( <NUM_LIT> ) . isMBB ( ) && <STR_LIT> ) ; int diff = InstOffset - BlockToInstOffset [ MII -> getOperand ( <NUM_LIT> ) . getMBB ( ) ] ; if ( ( unsigned ) abs ( diff ) > MaxLoopRange ) { useExtLoopInstr ( MF , MII ) ; MII = MBB . erase ( MII ) ; Changed = true ;


<s> if ( MII -> getOperand ( <NUM_LIT> ) . isReg ( ) ) { BuildMI ( * MBB , MII , DL , TII -> get ( <STR_LIT> ) , <STR_LIT> ) . addReg ( MII -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ; } else { BuildMI ( * MBB , MII , DL , TII -> get ( <STR_LIT> ) , Scratch ) . addImm ( MII -> getOperand ( <NUM_LIT> ) . getImm ( ) ) ;

BuildMI ( * MBB , MII , DL , TII -> get ( <STR_LIT> ) , <STR_LIT> ) . addReg ( Scratch ) ;


<s> } else { BuildMI ( * MBB , MII , DL , TII -> get ( <STR_LIT> ) , Scratch ) . addImm ( MII -> getOperand ( <NUM_LIT> ) . getImm ( ) ) ; BuildMI ( * MBB , MII , DL , TII -> get ( <STR_LIT> ) , <STR_LIT> ) . addReg ( Scratch ) ; } BuildMI ( * MBB , MII , DL , TII -> get ( <STR_LIT> ) , Scratch ) . addMBB ( MII -> getOperand ( <NUM_LIT> ) . getMBB ( ) ) ;


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


<s> RS . forward ( MII ) ; assert ( MII -> getOperand ( <NUM_LIT> ) . isMBB ( ) && <STR_LIT> ) ; int Sub = InstOffset - BlockToInstOffset [ MII -> getOperand ( <NUM_LIT> ) . getMBB ( ) ] ; unsigned Dist = Sub > <NUM_LIT> ? Sub : - Sub ; if ( Dist > MAX_LOOP_DISTANCE ) { convertLoopInstr ( MF , MII , RS ) ; MII = MBB -> erase ( MII ) ; Changed = true ;


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


<s> <ISA_LIT>FixupHwLoops ( ) : MachineFunctionPass ( ID ) { initialize<ISA_LIT>FixupHwLoopsPass ( * PassRegistry :: getPassRegistry ( ) ) ;


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

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


return MI -> getOpcode ( ) == <STR_LIT> || MI -> getOpcode ( ) == <STR_LIT> ;


<s> return MI -> getOpcode ( ) == <STR_LIT> || MI -> getOpcode ( ) == <STR_LIT> ;


<s> bool <ISA_LIT>FixupHwLoops :: runOnMachineFunction ( MachineFunction & MF ) { bool Changed = fixupLoopInstrs ( MF ) ;


<s> bool <ISA_LIT>FixupHwLoops :: runOnMachineFunction ( MachineFunction & MF ) {


<s> MachineOperand ImpUse = MachineOperand :: CreateReg ( R , IsDef , true ) ; Inst -> addOperand ( ImpUse ) ; }


<s>
const
TargetRegisterClass
*
RC
=
TRI
->
getMinimalPhysRegClass
(
S
->
Reg
)
;
int
FI
=
MFI
->
CreateFixedSpillStackObject
(
RC
->
getSize
(
)
,
S
->
Offset
)
;
MinOffset
=
std
::
min
(
MinOffset
,
S
->
Offset
)
;
CSI
.
push_back
(
CalleeSavedInfo
(
S
->
Reg
,
FI
)
)
;
SRegs
[
S
->
Reg
]
=
false
;
}
for
(
int
x
=
SRegs
.
find_first
(
)
;
x
>=
<NUM_LIT>
;
x
=
SRegs
.
find_next
(
x
)
)
{
unsigned
R
=
x
;
const
TargetRegisterClass
*
RC
=
TRI
->
getMinimalPhysRegClass
(
R
)
;
int
Off
=
MinOffset
RC
->
getSize
(
)
;
unsigned
Align
=
std
::
min
(
RC
->
getAlignment
(
)
,
getStackAlignment
(
)
)
;
assert
(
isPowerOf2_32
(
Align
)
)
;
Off
&=
Align
;
int
FI
=
MFI
->
CreateFixedSpillStackObject
(
RC
->
getSize
(
)
,
Off
)
;
MinOffset
=
std
::
min
(
MinOffset
,
Off
)
;
CSI
.
push_back
(
CalleeSavedInfo
(
R
,
FI
)
)
;
SRegs
[
R
]
=
false
;
}
DEBUG
(
{
dbgs
(
)
<<
<STR_LIT>
;
for
(
unsigned
i
=
<NUM_LIT>
,
n
=
CSI
.
size
(
)
;
i
<
n
;
++
i
)
{
int
FI
=
CSI
[
i
]
.
getFrameIdx
(
)
;
int
Off
=
MFI
->
getObjectOffset
(
FI
)
;
dbgs
(
)
<<
' '
<<
PrintReg
(
CSI
[
i
]
.
getReg
(
)
,
TRI
)
<<
<STR_LIT>
<<
FI
<<
<STR_LIT>
;
if
(
Off
>=
<NUM_LIT>
)
dbgs
(
)
<<
'+'
;


<s> return new <ISA_LIT>CallFrameInformation ( ) ;


<s> bool HasReplacedPseudoInst = replacePredRegPseudoSpillCode ( MF ) ; if ( HasReplacedPseudoInst && needToReserveScavengingSpillSlots ( MF , HRI ) ) { MachineFrameInfo * MFI = MF . getFrameInfo ( ) ; for ( int i = <NUM_LIT> ; i < NumberScavengerSlots ; i ++ ) RS -> addScavengingFrameIndex ( MFI -> CreateSpillStackObject ( RC . getSize ( ) , RC . getAlignment ( ) ) ) ; }


<s>
dbgs
(
)
<<
'{'
;
for
(
int
x
=
Regs
.
find_first
(
)
;
x
>=
<NUM_LIT>
;
x
=
Regs
.
find_next
(
x
)
)
{
unsigned
R
=
x
;
dbgs
(
)
<<
' '
<<
PrintReg
(
R
,
&
TRI
)
;


<s> ( void ) Opc ; assert ( ( Opc == <STR_LIT> || Opc == <STR_LIT> ) && <STR_LIT> ) ;


<s> assert ( ( Opc == <STR_LIT> || Opc == <STR_LIT> ) && <STR_LIT> ) ;


<s> insertPrologueInBlock ( * PrologB ) ; if ( EpilogB ) { insertCSRRestoresInBlock ( * EpilogB , CSI , HRI ) ; insertEpilogueInBlock ( * EpilogB ) ; } else { for ( auto & B : MF ) if ( B . isReturnBlock ( ) ) insertCSRRestoresInBlock ( B , CSI , HRI ) ;

for ( auto & B : MF ) if ( B . isReturnBlock ( ) ) insertEpilogueInBlock ( B ) ;


<s> MachineOperand & RdOp = AI -> getOperand ( <NUM_LIT> ) ; MachineOperand & RsOp = AI -> getOperand ( <NUM_LIT> ) ; unsigned Rd = RdOp . getReg ( ) , Rs = RsOp . getReg ( ) ; BuildMI ( MB , AI , DL , HII . get ( <STR_LIT> ) , Rd ) . addReg ( SP ) . addReg ( Rs ) ; if ( Rs != Rd ) { BuildMI ( MB , AI , DL , HII . get ( <STR_LIT> ) , SP ) . addReg ( SP ) . addReg ( Rs ) ; } if ( A > <NUM_LIT> ) { BuildMI ( MB , AI , DL , HII . get ( <STR_LIT> ) , Rd ) . addReg ( Rd ) . addImm ( - int64_t ( A ) ) ; if ( Rs != Rd ) BuildMI ( MB , AI , DL , HII . get ( <STR_LIT> ) , SP ) . addReg ( SP ) . addImm ( - int64_t ( A ) ) ; } if ( Rs == Rd ) { BuildMI ( MB , AI , DL , HII . get ( TargetOpcode :: COPY ) , SP ) . addReg ( Rd ) ; } if ( CF > <NUM_LIT> ) { BuildMI ( MB , AI , DL , HII . get ( <STR_LIT> ) , Rd ) . addReg ( Rd ) . addImm ( CF ) ; }


<s> if ( A > <NUM_LIT> ) { BuildMI ( MB , AI , DL , HII . get ( <STR_LIT> ) , Rd ) . addReg ( Rd ) . addImm ( - int64_t ( A ) ) ; if ( Rs != Rd ) BuildMI ( MB , AI , DL , HII . get ( <STR_LIT> ) , SP ) . addReg ( SP ) . addImm ( - int64_t ( A ) ) ; } if ( Rs == Rd ) { BuildMI ( MB , AI , DL , HII . get ( TargetOpcode :: COPY ) , SP ) . addReg ( Rd ) ; } if ( CF > <NUM_LIT> ) { BuildMI ( MB , AI , DL , HII . get ( <STR_LIT> ) , Rd ) . addReg ( Rd ) . addImm ( CF ) ; }


<s> MachineBasicBlock :: iterator FindAllocFrame ( MachineBasicBlock & B ) {

for ( auto & I : B ) if ( IsAllocFrame ( I ) ) return I ;


<s> } SmallVector < MachineBasicBlock * , <NUM_LIT> > SFBlocks ; BitVector CSR ( <STR_LIT> ) ; for ( const MCPhysReg * P = HRI . getCalleeSavedRegs ( & MF ) ; * P ; ++ P ) CSR [ * P ] = true ; for ( auto & I : MF ) if ( needsStackFrame ( I , CSR ) ) SFBlocks . push_back ( & I ) ; DEBUG ( { dbgs ( ) << <STR_LIT> ; for ( auto & B : SFBlocks ) dbgs ( ) << <STR_LIT> << B -> getNumber ( ) ;


<s> for ( auto & B : MF ) for ( auto & I : B ) if ( I . getOpcode ( ) == <STR_LIT> ) return & I ;


<s> bool HasAlloca = MFI . hasVarSizedObjects ( ) ; bool HasExtraAlign = HRI . needsStackRealignment ( MF ) ; bool NoOpt = MF . getTarget ( ) . getOptLevel ( ) == CodeGenOpt :: None ; unsigned SP = HRI . getStackRegister ( ) , FP = HRI . getFrameRegister ( ) ; unsigned AP = <NUM_LIT> ; if ( const MachineInstr * AI = getAlignaInstr ( MF ) ) AP = AI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; unsigned FrameSize = MFI . getStackSize ( ) ; bool UseFP = false , UseAP = false ;

if ( NoOpt && ! HasExtraAlign ) UseFP = true ;


<s> unsigned getMaxCalleeSavedReg ( const std :: vector < CalleeSavedInfo > & CSI , const TargetRegisterInfo & TRI ) { assert ( <STR_LIT> > <NUM_LIT> && <STR_LIT> ) ; if ( CSI . empty ( ) ) return <NUM_LIT> ; unsigned Max = getMax32BitSubRegister ( CSI [ <NUM_LIT> ] . getReg ( ) , TRI ) ; for ( unsigned I = <NUM_LIT> , E = CSI . size ( ) ; I < E ; ++ I ) { unsigned Reg = getMax32BitSubRegister ( CSI [ I ] . getReg ( ) , TRI ) ; if ( Reg > Max ) Max = Reg ; } return Max ;


<s> bool HasAlloca = MFI . hasVarSizedObjects ( ) ; if ( MF . getTarget ( ) . getOptLevel ( ) == CodeGenOpt :: None ) return true ; if ( ( HasFixed || HasPrealloc ) && ( HasAlloca || HasExtraAlign ) ) return true ;

if ( MFI . getStackSize ( ) > <NUM_LIT> ) {


<s> bool hasReturn ( const MachineBasicBlock & MBB ) { for ( auto I = MBB . getFirstTerminator ( ) , E = MBB . end ( ) ; I != E ; ++ I ) if ( I -> isReturn ( ) ) return true ; return false ;


<s> MachineBasicBlock :: const_iterator I = MBB . getLastNonDebugInstr ( ) ; unsigned RetOpc = I -> getOpcode ( ) ; return RetOpc == <STR_LIT> || RetOpc == <STR_LIT> ;


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

PassRegistry & PR = * PassRegistry :: getPassRegistry ( ) ;


<s> auto AF = FindAllocFrame ( B ) ; if ( AF == B . end ( ) ) continue ; insertCFIInstructionsAt ( B , ++ AF ) ; }


<s> unsigned ROpc = <STR_LIT> ; DeallocCall = BuildMI ( MBB , MI , DL , HII . get ( ROpc ) ) . addExternalSymbol ( RestoreFn ) ; } else { MachineBasicBlock :: iterator It = MBB . getFirstTerminator ( ) ; assert ( It -> isReturn ( ) && std :: next ( It ) == MBB . end ( ) ) ; unsigned ROpc = <STR_LIT> ; DeallocCall = BuildMI ( MBB , It , DL , HII . get ( ROpc ) ) . addExternalSymbol ( RestoreFn ) ; DeallocCall -> copyImplicitOps ( MF , It ) ; } addCalleeSaveRegistersAsImpOperand ( DeallocCall , MaxR , true ) ; return true ; } for ( unsigned i = <NUM_LIT> ; i < CSI . size ( ) ; ++ i ) { unsigned Reg = CSI [ i ] . getReg ( ) ; const TargetRegisterClass * RC = HRI . getMinimalPhysRegClass ( Reg ) ; int FI = CSI [ i ] . getFrameIdx ( ) ; HII . loadRegFromStackSlot ( MBB , MI , Reg , FI , RC , & HRI ) ;


<s> bool HasTC = hasTailCall ( MBB ) || ! hasReturn ( MBB ) ; unsigned MaxR = getMaxCalleeSavedReg ( CSI , HRI ) ; SpillKind Kind = HasTC ? SK_FromMemTailcall : SK_FromMem ; const char * RestoreFn = getSpillFunctionFor ( MaxR , Kind ) ; DebugLoc DL = MI != MBB . end ( ) ? MI -> getDebugLoc ( ) : MBB . getLastNonDebugInstr ( ) -> getDebugLoc ( ) ; MachineInstr * DeallocCall = nullptr ; if ( HasTC ) { unsigned ROpc = <STR_LIT> ; DeallocCall = BuildMI ( MBB , MI , DL , HII . get ( ROpc ) ) . addExternalSymbol ( RestoreFn ) ; } else { MachineBasicBlock :: iterator It = MBB . getFirstTerminator ( ) ; assert ( It -> isReturn ( ) && std :: next ( It ) == MBB . end ( ) ) ; unsigned ROpc = <STR_LIT> ; DeallocCall = BuildMI ( MBB , It , DL , HII . get ( ROpc ) ) . addExternalSymbol ( RestoreFn ) ; DeallocCall -> copyImplicitOps ( MF , It ) ; } addCalleeSaveRegistersAsImpOperand ( DeallocCall , MaxR , true ) ; return true ; } for ( unsigned i = <NUM_LIT> ; i < CSI . size ( ) ; ++ i ) { unsigned Reg = CSI [ i ] . getReg ( ) ; const TargetRegisterClass * RC = HRI . getMinimalPhysRegClass ( Reg ) ; int FI = CSI [ i ] . getFrameIdx ( ) ; HII . loadRegFromStackSlot ( MBB , MI , Reg , FI , RC , & HRI ) ;


<s> } for ( unsigned i = <NUM_LIT> , n = CSI . size ( ) ; i < n ; ++ i ) { unsigned Reg = CSI [ i ] . getReg ( ) ; bool IsKill = ! HRI . isEHReturnCalleeSaveReg ( Reg ) ; int FI = CSI [ i ] . getFrameIdx ( ) ; const TargetRegisterClass * RC = HRI . getMinimalPhysRegClass ( Reg ) ; HII . storeRegToStackSlot ( MBB , MI , Reg , IsKill , FI , RC , & HRI ) ; if ( IsKill ) MBB . addLiveIn ( Reg ) ; }


<s> const char * SpillFun = getSpillFunctionFor ( MaxReg , SK_ToMem ) ; DebugLoc DL = MI != MBB . end ( ) ? MI -> getDebugLoc ( ) : DebugLoc ( ) ; MachineInstr * SaveRegsCall = BuildMI ( MBB , MI , DL , HII . get ( <STR_LIT> ) ) . addExternalSymbol ( SpillFun ) ; addCalleeSaveRegistersAsImpOperand ( SaveRegsCall , MaxReg , false ) ; for ( unsigned I = <NUM_LIT> ; I < CSI . size ( ) ; ++ I ) MBB . addLiveIn ( CSI [ I ] . getReg ( ) ) ; return true ; } for ( unsigned i = <NUM_LIT> , n = CSI . size ( ) ; i < n ; ++ i ) { unsigned Reg = CSI [ i ] . getReg ( ) ; bool IsKill = ! HRI . isEHReturnCalleeSaveReg ( Reg ) ;


<s> break ; } unsigned RetOpc = RetI ? RetI -> getOpcode ( ) : <NUM_LIT> ; MachineBasicBlock :: iterator InsertPt = MBB . getFirstTerminator ( ) ; DebugLoc DL ; if ( InsertPt != MBB . end ( ) ) DL = InsertPt -> getDebugLoc ( ) ; else if ( ! MBB . empty ( ) ) DL = std :: prev ( MBB . end ( ) ) -> getDebugLoc ( ) ; if ( RetOpc == <STR_LIT> ) { BuildMI ( MBB , InsertPt , DL , HII . get ( <STR_LIT> ) ) ; BuildMI ( MBB , InsertPt , DL , HII . get ( <STR_LIT> ) , SP ) . addReg ( SP ) . addReg ( <STR_LIT> ) ; return ; } if ( RetOpc == <STR_LIT> ) { MachineBasicBlock :: iterator It = RetI ; ++ It ;


<s> unsigned NumBytes = MFI -> getStackSize ( ) ; unsigned SP = HRI . getStackRegister ( ) ; unsigned MaxCF = MFI -> getMaxCallFrameSize ( ) ; MachineBasicBlock :: iterator InsertPt = MBB . begin ( ) ; auto * FuncInfo = MF . getInfo < <ISA_LIT>MachineFunctionInfo > ( ) ; auto & AdjustRegs = FuncInfo -> getAllocaAdjustInsts ( ) ; for ( auto MI : AdjustRegs ) { assert ( ( MI -> getOpcode ( ) == <STR_LIT> ) && <STR_LIT> ) ; expandAlloca ( MI , HII , SP , MaxCF ) ; MI -> eraseFromParent ( ) ; } if ( ! hasFP ( MF ) ) return ; const unsigned int ALLOCFRAME_MAX = <NUM_LIT> ; MachineMemOperand * MMO = MF . getMachineMemOperand ( MachinePointerInfo ( ) , MachineMemOperand :: MOStore , <NUM_LIT> , <NUM_LIT> ) ; if ( NumBytes >= ALLOCFRAME_MAX ) { BuildMI ( MBB , InsertPt , dl , HII . get ( <STR_LIT> ) ) . addImm ( <NUM_LIT> ) . addMemOperand ( MMO ) ; unsigned CallerSavedReg = HRI . getFirstCallerSavedNonParamReg ( ) ; BuildMI ( MBB , InsertPt , dl , HII . get ( <STR_LIT> ) , CallerSavedReg ) . addImm ( NumBytes ) ; BuildMI ( MBB , InsertPt , dl , HII . get ( <STR_LIT> ) , SP ) . addReg ( SP ) . addReg ( CallerSavedReg ) ; } else { BuildMI ( MBB , InsertPt , dl , HII . get ( <STR_LIT> ) ) . addImm ( NumBytes ) . addMemOperand ( MMO ) ; }


<s> auto End = It -> getParent ( ) -> instr_end ( ) ; MachineBasicBlock :: const_instr_iterator I = It . getInstrIterator ( ) ; while ( ++ I != End && I -> isBundled ( ) ) if ( I -> getOpcode ( ) == <STR_LIT> ) return true ;


<s> inline static bool isOptSize ( const MachineFunction & MF ) { AttributeSet AF = MF . getFunction ( ) -> getAttributes ( ) ; return AF . hasAttribute ( AttributeSet :: FunctionIndex , Attribute :: OptimizeForSize ) ;


<s> AttributeSet AF = MF . getFunction ( ) -> getAttributes ( ) ; return AF . hasAttribute ( AttributeSet :: FunctionIndex , Attribute :: OptimizeForSize ) ;


<s> const MachineFrameInfo * MFI = MF . getFrameInfo ( ) ;

if ( ! MFI -> hasVarSizedObjects ( ) ) return false ;


<s> bool <ISA_LIT>FrameLowering :: needsAligna ( const MachineFunction & MF ) const { const MachineFrameInfo * MFI = MF . getFrameInfo ( ) ; if ( ! MFI -> hasVarSizedObjects ( ) ) return false ; unsigned MaxA = MFI -> getMaxAlignment ( ) ; if ( MaxA <= getStackAlignment ( ) ) return false ; return true ;


<s> int Offset = - LFS ; for ( int i = <NUM_LIT> , e = MFI -> getObjectIndexEnd ( ) ; i != e ; ++ i ) { if ( ! MFI -> isSpillSlotObjectIndex ( i ) || MFI -> isDeadObjectIndex ( i ) ) continue ; int S = MFI -> getObjectSize ( i ) ; LFS += S ; Offset -= S ; MFI -> mapLocalFrameObject ( i , Offset ) ; } MFI -> setLocalFrameSize ( LFS ) ; unsigned A = MFI -> getLocalFrameMaxAlign ( ) ;

assert ( A <= <NUM_LIT> && <STR_LIT> ) ;


<s> Offset -= S ; MFI -> mapLocalFrameObject ( i , Offset ) ; } MFI -> setLocalFrameSize ( LFS ) ; unsigned A = MFI -> getLocalFrameMaxAlign ( ) ; assert ( A <= <NUM_LIT> && <STR_LIT> ) ; if ( A == <NUM_LIT> ) MFI -> setLocalFrameMaxAlign ( <NUM_LIT> ) ;

MFI -> setUseLocalStackAllocationBlock ( true ) ;


<s> if ( Opc == <STR_LIT> ) { HasReplacedPseudoInst = true ; unsigned VirtReg = MRI . createVirtualRegister ( & <STR_LIT> ) ; unsigned SrcReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; bool IsOrigSrcRegKilled = MI -> getOperand ( <NUM_LIT> ) . isKill ( ) ; assert ( MI -> getOperand ( <NUM_LIT> ) . isFI ( ) && <STR_LIT> ) ; assert ( <STR_LIT> . contains ( SrcReg ) && <STR_LIT> ) ; BuildMI ( * MBB , MII , MI -> getDebugLoc ( ) , HII . get ( <STR_LIT> ) , VirtReg ) . addReg ( SrcReg , getKillRegState ( IsOrigSrcRegKilled ) ) ; MI -> setDesc ( HII . get ( <STR_LIT> ) ) ; MI -> getOperand ( <NUM_LIT> ) . setReg ( VirtReg ) ; MI -> getOperand ( <NUM_LIT> ) . setIsKill ( ) ; } else if ( Opc == <STR_LIT> ) { MachineOperand & M0 = MI -> getOperand ( <NUM_LIT> ) ; if ( M0 . isDead ( ) ) { MBB -> erase ( MII ) ; continue ; } unsigned VirtReg = MRI . createVirtualRegister ( & <STR_LIT> ) ; unsigned DestReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; assert ( MI -> getOperand ( <NUM_LIT> ) . isFI ( ) && <STR_LIT> ) ; assert ( <STR_LIT> . contains ( DestReg ) && <STR_LIT> ) ; MI -> setDesc ( HII . get ( <STR_LIT> ) ) ; MI -> getOperand ( <NUM_LIT> ) . setReg ( VirtReg ) ; const MCInstrDesc & D = HII . get ( <STR_LIT> ) ; BuildMI ( * MBB , std :: next ( MII ) , MI -> getDebugLoc ( ) , D , DestReg ) . addReg ( VirtReg , getKillRegState ( true ) ) ; HasReplacedPseudoInst = true ;


<s> bool NeedCFI = MF . getMMI ( ) . hasDebugInfo ( ) || MF . getFunction ( ) -> needsUnwindTableEntry ( ) ;


<s> bool <ISA_LIT>FrameLowering :: shouldInlineCSR ( MachineFunction & MF , const CSIVect & CSI ) const { if ( MF . getInfo < <ISA_LIT>MachineFunctionInfo > ( ) -> hasEHReturn ( ) ) return true ; if ( ! isOptSize ( MF ) && ! isMinSize ( MF ) ) if ( MF . getTarget ( ) . getOptLevel ( ) > CodeGenOpt :: Default ) return true ; BitVector Regs ( <STR_LIT> ) ; for ( unsigned i = <NUM_LIT> , n = CSI . size ( ) ; i < n ; ++ i ) { unsigned R = CSI [ i ] . getReg ( ) ; if ( ! <STR_LIT> . contains ( R ) ) return true ; Regs [ R ] = true ; } int F = Regs . find_first ( ) ; if ( F != <STR_LIT> ) return true ;


<s> unsigned Threshold = isOptSize ( MF ) ? SpillFuncThresholdOs - <NUM_LIT> : SpillFuncThreshold ;


<s> unsigned NumCSI = CSI . size ( ) ; unsigned Threshold = isOptSize ( MF ) ? SpillFuncThresholdOs - <NUM_LIT> : SpillFuncThreshold ; return Threshold < NumCSI ;


<s> bool <ISA_LIT>FrameLowering :: useSpillFunction ( MachineFunction & MF , const CSIVect & CSI ) const { if ( shouldInlineCSR ( MF , CSI ) ) return false ; unsigned NumCSI = CSI . size ( ) ; if ( NumCSI <= <NUM_LIT> ) return false ;

unsigned Threshold = isOptSize ( MF ) ? SpillFuncThresholdOs : SpillFuncThreshold ;


<s> unsigned NumCSI = CSI . size ( ) ; if ( NumCSI <= <NUM_LIT> ) return false ; unsigned Threshold = isOptSize ( MF ) ? SpillFuncThresholdOs : SpillFuncThreshold ; return Threshold < NumCSI ;


<s> void emitEpilogue ( MachineFunction & MF , MachineBasicBlock & MBB ) const override {


<s> private : typedef std :: vector < CalleeSavedInfo > CSIVect ; void expandAlloca ( MachineInstr * AI , const <ISA_LIT>InstrInfo & TII , unsigned SP , unsigned CF ) const ; void insertPrologueInBlock ( MachineBasicBlock & MBB ) const ; void insertEpilogueInBlock ( MachineBasicBlock & MBB ) const ; bool insertCSRSpillsInBlock ( MachineBasicBlock & MBB , const CSIVect & CSI , const <ISA_LIT>RegisterInfo & HRI ) const ; bool insertCSRRestoresInBlock ( MachineBasicBlock & MBB , const CSIVect & CSI , const <ISA_LIT>RegisterInfo & HRI ) const ; void insertCFIInstructionsAt ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator At ) const ; void adjustForCalleeSavedRegsSpillCall ( MachineFunction & MF ) const ; bool replacePredRegPseudoSpillCode ( MachineFunction & MF ) const ; bool replaceVecPredRegPseudoSpillCode ( MachineFunction & MF ) const ; void findShrunkPrologEpilog ( MachineFunction & MF , MachineBasicBlock * & PrologB , MachineBasicBlock * & EpilogB ) const ;

bool shouldInlineCSR ( llvm :: MachineFunction & MF , const CSIVect & CSI ) const ;


<s> const SpillSlot * getCalleeSavedSpillSlots ( unsigned & NumEntries ) const override { static const SpillSlot Offsets [ ] = { { <STR_LIT> , - <NUM_LIT> } , { <STR_LIT> , - <NUM_LIT> } , { <STR_LIT> , - <NUM_LIT> } , { <STR_LIT> , - <NUM_LIT> } , { <STR_LIT> , - <NUM_LIT> } , { <STR_LIT> , - <NUM_LIT> } , { <STR_LIT> , - <NUM_LIT> } , { <STR_LIT> , - <NUM_LIT> } , { <STR_LIT> , - <NUM_LIT> } , { <STR_LIT> , - <NUM_LIT> } , { <STR_LIT> , - <NUM_LIT> } , { <STR_LIT> , - <NUM_LIT> } , { <STR_LIT> , - <NUM_LIT> } , { <STR_LIT> , - <NUM_LIT> } , { <STR_LIT> , - <NUM_LIT> } , { <STR_LIT> , - <NUM_LIT> , { <STR_LIT> , - <NUM_LIT> , { <STR_LIT> , - <NUM_LIT> } } ; NumEntries = array_lengthof ( Offsets ) ; return Offsets ; } bool assignCalleeSavedSpillSlots ( MachineFunction & MF , const TargetRegisterInfo * TRI , std :: vector < CalleeSavedInfo > & CSI ) const override ; bool needsAligna ( const MachineFunction & MF ) const ; const MachineInstr * getAlignaInstr ( const MachineFunction & MF ) const ; void insertCFIInstructions ( MachineFunction & MF ) const ;


<s> explicit <ISA_LIT>FrameLowering ( ) : TargetFrameLowering ( StackGrowsDown , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , true ) {


<s> bool restoreCalleeSavedRegisters ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator MI , const std :: vector < CalleeSavedInfo > & CSI , const TargetRegisterInfo * TRI ) const override {


<s> bool restoreCalleeSavedRegisters ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator MI , const std :: vector < CalleeSavedInfo > & CSI , const TargetRegisterInfo * TRI ) const override { return true ;


<s> bool spillCalleeSavedRegisters ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator MI , const std :: vector < CalleeSavedInfo > & CSI , const TargetRegisterInfo * TRI ) const override {


<s> void <ISA_LIT>FrameLowering :: addCalleeSaveRegistersAsImpOperand ( MachineInstr * MI , const CSIVect & CSI , bool IsDef , bool IsKill ) const { for ( auto & R : CSI ) MI -> addOperand ( MachineOperand :: CreateReg ( R . getReg ( ) , IsDef , true , IsKill ) ) ;


<s> } } LLVM_DEBUG ( dbgs ( ) << <STR_LIT> ; dump_registers ( TmpSup , * TRI ) ; dbgs ( ) << <STR_LIT> ) ; SRegs |= TmpSup ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> ; dump_registers ( SRegs , * TRI ) ; dbgs ( ) << <STR_LIT> ) ; for ( int x = SRegs . find_first ( ) ; x >= <NUM_LIT> ; x = SRegs . find_next ( x ) ) { unsigned R = x ; for ( MCSuperRegIterator SR ( R , TRI ) ; SR . isValid ( ) ; ++ SR ) { if ( ! SRegs [ * SR ] ) continue ; SRegs [ R ] = false ; break ; } } LLVM_DEBUG ( dbgs ( ) << <STR_LIT> ; dump_registers ( SRegs , * TRI ) ; dbgs ( ) << <STR_LIT> ) ; CSI . clear ( ) ; using SpillSlot = TargetFrameLowering :: SpillSlot ; unsigned NumFixed ; int MinOffset = <NUM_LIT> ; const SpillSlot * FixedSlots = getCalleeSavedSpillSlots ( NumFixed ) ; for ( const SpillSlot * S = FixedSlots ; S != FixedSlots + NumFixed ; ++ S ) { if ( ! SRegs [ S -> Reg ] ) continue ; const TargetRegisterClass * RC = TRI -> getMinimalPhysRegClass ( S -> Reg ) ; int FI = MFI . CreateFixedSpillStackObject ( TRI -> getSpillSize ( * RC ) , S -> Offset ) ; MinOffset = std :: min ( MinOffset , S -> Offset ) ; CSI . push_back ( CalleeSavedInfo ( S -> Reg , FI ) ) ; SRegs [ S -> Reg ] = false ; } for ( int x = SRegs . find_first ( ) ; x >= <NUM_LIT> ; x = SRegs . find_next ( x ) ) { unsigned R = x ;

const TargetRegisterClass * RC = TRI -> getMinimalPhysRegClass ( R ) ;


<s> for ( auto * RC : SpillRCs ) { if ( ! needToReserveScavengingSpillSlots ( MF , HRI , RC ) ) continue ; unsigned Num = <NUM_LIT> ; switch ( RC -> getID ( ) ) { case <STR_LIT> : Num = NumberScavengerSlots ; break ; case <STR_LIT> : Num = <NUM_LIT> ; break ; } unsigned S = HRI . getSpillSize ( * RC ) , A = HRI . getSpillAlignment ( * RC ) ; for ( unsigned i = <NUM_LIT> ; i < Num ; i ++ ) {

int NewFI = MFI . CreateSpillStackObject ( S , A ) ;


<s> for ( auto * RC : SpillRCs ) { if ( ! needToReserveScavengingSpillSlots ( MF , HRI , RC ) ) continue ; unsigned Num = <NUM_LIT> ; switch ( RC -> getID ( ) ) { case <STR_LIT> : Num = NumberScavengerSlots ; break ; case <STR_LIT> : Num = <NUM_LIT> ; break ; } unsigned S = HRI . getSpillSize ( * RC ) , A = HRI . getSpillAlignment ( * RC ) ; for ( unsigned i = <NUM_LIT> ; i < Num ; i ++ ) { int NewFI = MFI . CreateSpillStackObject ( S , A ) ;

RS -> addScavengingFrameIndex ( NewFI ) ;


<s> dbgs ( ) << '{' ; for ( int x = Regs . find_first ( ) ; x >= <NUM_LIT> ; x = Regs . find_next ( x ) ) { unsigned R = x ;

dbgs
(
)
<<
' '
<<
printReg
(
R
,
&
TRI
)
;


<s> unsigned Opc = MI . getOpcode ( ) ; ( void ) Opc ;

assert ( ( Opc == <STR_LIT> || Opc == <STR_LIT> ) && <STR_LIT> ) ;


<s> unsigned Opc = MI . getOpcode ( ) ; ( void ) Opc ; assert ( ( Opc == <STR_LIT> || Opc == <STR_LIT> ) && <STR_LIT> ) ; return MBB . erase ( I ) ;


<s> if ( EpilogB ) { insertCSRRestoresInBlock ( * EpilogB , CSI , HRI ) ; insertEpilogueInBlock ( * EpilogB ) ; } else { for ( auto & B : MF ) if ( B . isReturnBlock ( ) ) insertCSRRestoresInBlock ( B , CSI , HRI ) ; for ( auto & B : MF ) if ( B . isReturnBlock ( ) ) insertEpilogueInBlock ( B ) ; for ( auto & B : MF ) { if ( B . empty ( ) ) continue ; MachineInstr * RetI = getReturn ( B ) ; if ( ! RetI || isRestoreCall ( RetI -> getOpcode ( ) ) ) continue ; for ( auto & R : CSI ) RetI -> addOperand ( MachineOperand :: CreateReg ( R . getReg ( ) , false , true ) ) ; } } if ( EpilogB ) { unsigned MaxBN = MF . getNumBlockIDs ( ) ; BitVector DoneT ( MaxBN + <NUM_LIT> ) , DoneF ( MaxBN + <NUM_LIT> ) , Path ( MaxBN + <NUM_LIT> ) ; updateExitPaths ( * EpilogB , * EpilogB , DoneT , DoneF , Path ) ; }


<s> MachineInstr * RetI = getReturn ( B ) ; if ( ! RetI || isRestoreCall ( RetI -> getOpcode ( ) ) ) continue ; for ( auto & R : CSI ) RetI -> addOperand ( MachineOperand :: CreateReg ( R . getReg ( ) , false , true ) ) ; } } if ( EpilogB ) { unsigned MaxBN = MF . getNumBlockIDs ( ) ; BitVector DoneT ( MaxBN + <NUM_LIT> ) , DoneF ( MaxBN + <NUM_LIT> ) , Path ( MaxBN + <NUM_LIT> ) ; updateExitPaths ( * EpilogB , * EpilogB , DoneT , DoneF , Path ) ;


<s> assert ( ! MFI . hasVarSizedObjects ( ) && ! HST . getRegisterInfo ( ) -> needsStackRealignment ( MF ) ) ;

return F . hasFnAttribute ( Attribute :: NoReturn ) && F . hasFnAttribute ( Attribute :: NoUnwind ) && ! F . hasFnAttribute ( Attribute :: UWTable ) && HST . noreturnStackElim ( ) && MFI . getStackSize ( ) == <NUM_LIT> ;


<s> const auto & F = MF . getFunction ( ) ; const auto & MFI = MF . getFrameInfo ( ) ; const auto & HST = MF . getSubtarget < <ISA_LIT>Subtarget > ( ) ; assert ( ! MFI . hasVarSizedObjects ( ) && ! HST . getRegisterInfo ( ) -> needsStackRealignment ( MF ) ) ;


<s> const auto & F = MF . getFunction ( ) ;

assert ( F . hasFnAttribute ( Attribute :: NoReturn ) && F . getFunction ( ) . hasFnAttribute ( Attribute :: NoUnwind ) && ! F . getFunction ( ) . hasFnAttribute ( Attribute :: UWTable ) ) ;


<s> DebugLoc DL = MI -> getDebugLoc ( ) ; Register DstR = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; Register SrcR = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; if ( ! <STR_LIT> . contains ( DstR ) || ! <STR_LIT> . contains ( SrcR ) ) return false ; Register TmpR = MRI . createVirtualRegister ( & <STR_LIT> ) ; BuildMI ( B , It , DL , HII . get ( TargetOpcode :: COPY ) , TmpR ) . add ( MI -> getOperand ( <NUM_LIT> ) ) ;

BuildMI ( B , It , DL , HII . get ( TargetOpcode :: COPY ) , DstR ) . addReg ( TmpR , RegState :: Kill ) ;


<s> bool <ISA_LIT>FrameLowering :: expandCopy ( MachineBasicBlock & B , MachineBasicBlock :: iterator It , MachineRegisterInfo & MRI , const <ISA_LIT>InstrInfo & HII , SmallVectorImpl < unsigned > & NewRegs ) const { MachineInstr * MI = & * It ; DebugLoc DL = MI -> getDebugLoc ( ) ; Register DstR = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; Register SrcR = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; if ( ! <STR_LIT> . contains ( DstR ) || ! <STR_LIT> . contains ( SrcR ) ) return false ; Register TmpR = MRI . createVirtualRegister ( & <STR_LIT> ) ; BuildMI ( B , It , DL , HII . get ( TargetOpcode :: COPY ) , TmpR ) . add ( MI -> getOperand ( <NUM_LIT> ) ) ;


<s> int FI = MI -> getOperand ( <NUM_LIT> ) . getIndex ( ) ; Register TmpR = MRI . createVirtualRegister ( & <STR_LIT> ) ; BuildMI ( B , It , DL , HII . get ( <STR_LIT> ) , TmpR ) . addFrameIndex ( FI ) . addImm ( <NUM_LIT> ) . cloneMemRefs ( * MI ) ; unsigned TfrOpc = ( Opc == <STR_LIT> ) ? <STR_LIT> : <STR_LIT> ;

BuildMI ( B , It , DL , HII . get ( TfrOpc ) , DstR ) . addReg ( TmpR , RegState :: Kill ) ;


<s> if ( ! MI -> getOperand ( <NUM_LIT> ) . isFI ( ) ) return false ; bool NeedsAligna = needsAligna ( MF ) ; auto & HRI = * MF . getSubtarget < <ISA_LIT>Subtarget > ( ) . getRegisterInfo ( ) ; DebugLoc DL = MI -> getDebugLoc ( ) ; Register DstR = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; int FI = MI -> getOperand ( <NUM_LIT> ) . getIndex ( ) ;

unsigned NeedAlign = HRI . getSpillAlignment ( <STR_LIT> ) ;


<s> auto UseAligned = [ & ] ( unsigned NeedAlign , unsigned HasAlign ) { return ! NeedsAligna && ( NeedAlign <= HasAlign ) ; } ; LoadOpc = UseAligned ( NeedAlign , HasAlign ) ? <STR_LIT> : <STR_LIT> ; BuildMI ( B , It , DL , HII . get ( LoadOpc ) , DstLo ) . addFrameIndex ( FI ) . addImm ( <NUM_LIT> ) . cloneMemRefs ( * MI ) ; LoadOpc = UseAligned ( NeedAlign , HasAlign ) ? <STR_LIT> : <STR_LIT> ;

BuildMI ( B , It , DL , HII . get ( LoadOpc ) , DstHi ) . addFrameIndex ( FI ) . addImm ( Size ) . cloneMemRefs ( * MI ) ;


<s> bool NeedsAligna = needsAligna ( MF ) ; unsigned Size = HRI . getSpillSize ( <STR_LIT> ) ; unsigned NeedAlign = HRI . getSpillAlignment ( <STR_LIT> ) ; unsigned HasAlign = MFI . getObjectAlignment ( FI ) ; unsigned LoadOpc ; auto UseAligned = [ & ] ( unsigned NeedAlign , unsigned HasAlign ) { return ! NeedsAligna && ( NeedAlign <= HasAlign ) ; } ; LoadOpc = UseAligned ( NeedAlign , HasAlign ) ? <STR_LIT> : <STR_LIT> ; BuildMI ( B , It , DL , HII . get ( LoadOpc ) , DstLo ) . addFrameIndex ( FI ) . addImm ( <NUM_LIT> ) . cloneMemRefs ( * MI ) ;


<s> MachineFunction & MF = * B . getParent ( ) ; auto * HRI = MF . getSubtarget < <ISA_LIT>Subtarget > ( ) . getRegisterInfo ( ) ; HII . loadRegFromStackSlot ( B , It , TmpR1 , FI , RC , HRI ) ; expandLoadVec ( B , std :: prev ( It ) , MRI , HII , NewRegs ) ; BuildMI ( B , It , DL , HII . get ( <STR_LIT> ) , DstR ) . addReg ( TmpR1 , RegState :: Kill ) . addReg ( TmpR0 , RegState :: Kill ) ; NewRegs . push_back ( TmpR0 ) ; NewRegs . push_back ( TmpR1 ) ; B . erase ( It ) ;


<s> bool Changed = false ; for ( auto & B : MF ) { MachineBasicBlock :: iterator NextI ; for ( auto I = B . begin ( ) , E = B . end ( ) ; I != E ; I = NextI ) { MachineInstr * MI = & * I ; NextI = std :: next ( I ) ; unsigned Opc = MI -> getOpcode ( ) ; switch ( Opc ) { case TargetOpcode :: COPY : Changed |= expandCopy ( B , I , MRI , HII , NewRegs ) ; break ; case <STR_LIT> : case <STR_LIT> : Changed |= expandStoreInt ( B , I , MRI , HII , NewRegs ) ; break ; case <STR_LIT> : case <STR_LIT> : Changed |= expandLoadInt ( B , I , MRI , HII , NewRegs ) ; break ; case <STR_LIT> : Changed |= expandStoreVecPred ( B , I , MRI , HII , NewRegs ) ; break ; case <STR_LIT> : Changed |= expandLoadVecPred ( B , I , MRI , HII , NewRegs ) ; break ; case <STR_LIT> : Changed |= expandLoadVec2 ( B , I , MRI , HII , NewRegs ) ; break ; case <STR_LIT> : Changed |= expandStoreVec2 ( B , I , MRI , HII , NewRegs ) ; break ; } } }


<s> for ( auto I = B . begin ( ) , E = B . end ( ) ; I != E ; I = NextI ) { MachineInstr * MI = & * I ; NextI = std :: next ( I ) ; unsigned Opc = MI -> getOpcode ( ) ; switch ( Opc ) { case TargetOpcode :: COPY : Changed |= expandCopy ( B , I , MRI , HII , NewRegs ) ; break ; case <STR_LIT> : case <STR_LIT> : Changed |= expandStoreInt ( B , I , MRI , HII , NewRegs ) ; break ; case <STR_LIT> : case <STR_LIT> : Changed |= expandLoadInt ( B , I , MRI , HII , NewRegs ) ; break ; case <STR_LIT> : Changed |= expandStoreVecPred ( B , I , MRI , HII , NewRegs ) ; break ; case <STR_LIT> : Changed |= expandLoadVecPred ( B , I , MRI , HII , NewRegs ) ; break ; case <STR_LIT> :

Changed |= expandLoadVec2 ( B , I , MRI , HII , NewRegs ) ;


<s> unsigned Opc = MI -> getOpcode ( ) ; Register SrcR = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; bool IsKill = MI -> getOperand ( <NUM_LIT> ) . isKill ( ) ; int FI = MI -> getOperand ( <NUM_LIT> ) . getIndex ( ) ; Register TmpR = MRI . createVirtualRegister ( & <STR_LIT> ) ; unsigned TfrOpc = ( Opc == <STR_LIT> ) ? <STR_LIT> : <STR_LIT> ; BuildMI ( B , It , DL , HII . get ( TfrOpc ) , TmpR ) . addReg ( SrcR , getKillRegState ( IsKill ) ) ; BuildMI ( B , It , DL , HII . get ( <STR_LIT> ) ) . addFrameIndex ( FI ) . addImm ( <NUM_LIT> ) . addReg ( TmpR , RegState :: Kill ) . cloneMemRefs ( * MI ) ;


<s> bool <ISA_LIT>FrameLowering :: expandStoreInt ( MachineBasicBlock & B , MachineBasicBlock :: iterator It , MachineRegisterInfo & MRI , const <ISA_LIT>InstrInfo & HII , SmallVectorImpl < unsigned > & NewRegs ) const { MachineInstr * MI = & * It ; if ( ! MI -> getOperand ( <NUM_LIT> ) . isFI ( ) ) return false ; DebugLoc DL = MI -> getDebugLoc ( ) ; unsigned Opc = MI -> getOpcode ( ) ;

Register SrcR = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ;


<s> Register SrcR = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; bool IsKill = MI -> getOperand ( <NUM_LIT> ) . isKill ( ) ; int FI = MI -> getOperand ( <NUM_LIT> ) . getIndex ( ) ; unsigned NeedAlign = HRI . getSpillAlignment ( <STR_LIT> ) ; unsigned HasAlign = MFI . getObjectAlignment ( FI ) ; bool UseAligned = ! NeedsAligna && ( NeedAlign <= HasAlign ) ; unsigned StoreOpc = UseAligned ? <STR_LIT> : <STR_LIT> ; BuildMI ( B , It , DL , HII . get ( StoreOpc ) ) . addFrameIndex ( FI ) . addImm ( <NUM_LIT> ) . addReg ( SrcR , getKillRegState ( IsKill ) ) . cloneMemRefs ( * MI ) ;


<s> MachineInstr * MI = & * It ; if ( ! MI -> getOperand ( <NUM_LIT> ) . isFI ( ) ) return false ; bool NeedsAligna = needsAligna ( MF ) ; auto & HRI = * MF . getSubtarget < <ISA_LIT>Subtarget > ( ) . getRegisterInfo ( ) ; DebugLoc DL = MI -> getDebugLoc ( ) ; Register SrcR = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; bool IsKill = MI -> getOperand ( <NUM_LIT> ) . isKill ( ) ; int FI = MI -> getOperand ( <NUM_LIT> ) . getIndex ( ) ; unsigned NeedAlign = HRI . getSpillAlignment ( <STR_LIT> ) ; unsigned HasAlign = MFI . getObjectAlignment ( FI ) ; bool UseAligned = ! NeedsAligna && ( NeedAlign <= HasAlign ) ;

unsigned StoreOpc = UseAligned ? <STR_LIT> : <STR_LIT> ;


<s> bool <ISA_LIT>FrameLowering :: expandStoreVec2 ( MachineBasicBlock & B , MachineBasicBlock :: iterator It , MachineRegisterInfo & MRI , const <ISA_LIT>InstrInfo & HII , SmallVectorImpl < unsigned > & NewRegs ) const { MachineFunction & MF = * B . getParent ( ) ; auto & MFI = MF . getFrameInfo ( ) ; auto & HRI = * MF . getSubtarget < <ISA_LIT>Subtarget > ( ) . getRegisterInfo ( ) ; MachineInstr * MI = & * It ; if ( ! MI -> getOperand ( <NUM_LIT> ) . isFI ( ) ) return false ; LivePhysRegs LPR ( HRI ) ; LPR . addLiveIns ( B ) ; SmallVector < std :: pair < MCPhysReg , const MachineOperand * > , <NUM_LIT> > Clobbers ; for ( auto R = B . begin ( ) ; R != It ; ++ R ) { Clobbers . clear ( ) ; LPR . stepForward ( * R , Clobbers ) ; } DebugLoc DL = MI -> getDebugLoc ( ) ; Register SrcR = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; Register SrcLo = HRI . getSubReg ( SrcR , <STR_LIT> ) ; Register SrcHi = HRI . getSubReg ( SrcR , <STR_LIT> ) ; bool IsKill = MI -> getOperand ( <NUM_LIT> ) . isKill ( ) ; int FI = MI -> getOperand ( <NUM_LIT> ) . getIndex ( ) ; bool NeedsAligna = needsAligna ( MF ) ; unsigned Size = HRI . getSpillSize ( <STR_LIT> ) ; unsigned NeedAlign = HRI . getSpillAlignment ( <STR_LIT> ) ; unsigned HasAlign = MFI . getObjectAlignment ( FI ) ; unsigned StoreOpc ; auto UseAligned = [ & ] ( unsigned NeedAlign , unsigned HasAlign ) { return ! NeedsAligna && ( NeedAlign <= HasAlign ) ; } ; if ( LPR . contains ( SrcLo ) ) { StoreOpc = UseAligned ( NeedAlign , HasAlign ) ? <STR_LIT> : <STR_LIT> ; BuildMI ( B , It , DL , HII . get ( StoreOpc ) ) . addFrameIndex ( FI ) . addImm ( <NUM_LIT> ) . addReg ( SrcLo , getKillRegState ( IsKill ) ) . cloneMemRefs ( * MI ) ; } if ( LPR . contains ( SrcHi ) ) {


<s> while ( ++ T != End && T -> isBundled ( ) ) { if ( T -> getOpcode ( ) == <STR_LIT> ) HasAllocFrame = true ; else if ( T -> isCall ( ) ) HasCall = true ; } if ( HasAllocFrame ) return HasCall ? It : std :: next ( It ) ;


<s> bool HasCall = false , HasAllocFrame = false ; auto T = It . getInstrIterator ( ) ; while ( ++ T != End && T -> isBundled ( ) ) { if ( T -> getOpcode ( ) == <STR_LIT> ) HasAllocFrame = true ;

else if ( T -> isCall ( ) ) HasCall = true ;


<s> auto F = DeadMap . find ( { Reg , <NUM_LIT> } ) ; if ( F == DeadMap . end ( ) ) return false ; for ( auto & DR : F -> second ) if ( DR . contains ( FIR ) ) return true ; return false ; } ; for ( unsigned Reg : RC -> getRawAllocationOrder ( MF ) ) { bool Dead = true ; for ( auto R : <ISA_LIT>BlockRanges :: expandToSubRegs ( { Reg , <NUM_LIT> } , MRI , HRI ) ) { if ( isDead ( R . Reg ) ) continue ;


<s> return false ; } ; for ( unsigned Reg : RC -> getRawAllocationOrder ( MF ) ) { bool Dead = true ; for ( auto R : <ISA_LIT>BlockRanges :: expandToSubRegs ( { Reg , <NUM_LIT> } , MRI , HRI ) ) { if ( isDead ( R . Reg ) ) continue ; Dead = false ; break ; } if ( Dead ) return Reg ;


<s> unsigned RPON = <NUM_LIT> ; for ( RPOTType :: rpo_iterator I = RPOT . begin ( ) , E = RPOT . end ( ) ; I != E ; ++ I ) RPO [ ( * I ) -> getNumber ( ) ] = RPON ++ ; for ( auto & I : MF ) { unsigned BN = RPO [ I . getNumber ( ) ] ; for ( auto SI = I . succ_begin ( ) , SE = I . succ_end ( ) ; SI != SE ; ++ SI ) { if ( RPO [ ( * SI ) -> getNumber ( ) ] <= BN ) return ; } } SmallVector < MachineBasicBlock * , <NUM_LIT> > SFBlocks ; BitVector CSR ( <STR_LIT> ) ; for ( const MCPhysReg * P = HRI . getCalleeSavedRegs ( & MF ) ; * P ; ++ P ) for ( MCSubRegIterator S ( * P , & HRI , true ) ; S . isValid ( ) ; ++ S ) CSR [ * S ] = true ; for ( auto & I : MF ) if ( needsStackFrame ( I , CSR , HRI ) ) SFBlocks . push_back ( & I ) ; LLVM_DEBUG ( { dbgs ( ) << <STR_LIT> ;

for ( auto & B : SFBlocks ) dbgs ( ) << <STR_LIT> << printMBBReference ( * B ) ;


<s> using UnsignedMap = DenseMap < unsigned , unsigned > ; using RPOTType = ReversePostOrderTraversal < const MachineFunction * > ; UnsignedMap RPO ; RPOTType RPOT ( & MF ) ; unsigned RPON = <NUM_LIT> ; for ( RPOTType :: rpo_iterator I = RPOT . begin ( ) , E = RPOT . end ( ) ; I != E ; ++ I ) RPO [ ( * I ) -> getNumber ( ) ] = RPON ++ ; for ( auto & I : MF ) { unsigned BN = RPO [ I . getNumber ( ) ] ; for ( auto SI = I . succ_begin ( ) , SE = I . succ_end ( ) ; SI != SE ; ++ SI ) { if ( RPO [ ( * SI ) -> getNumber ( ) ] <= BN ) return ; } } SmallVector < MachineBasicBlock * , <NUM_LIT> > SFBlocks ; BitVector CSR ( <STR_LIT> ) ; for ( const MCPhysReg * P = HRI . getCalleeSavedRegs ( & MF ) ; * P ; ++ P ) for ( MCSubRegIterator S ( * P , & HRI , true ) ; S . isValid ( ) ; ++ S ) CSR [ * S ] = true ;

for ( auto & I : MF ) if ( needsStackFrame ( I , CSR , HRI ) ) SFBlocks . push_back ( & I ) ;


<s> const MachineInstr * <ISA_LIT>FrameLowering :: getAlignaInstr ( const MachineFunction & MF ) const {

for ( auto & B : MF ) for ( auto & I : B ) if ( I . getOpcode ( ) == <STR_LIT> ) return & I ;


<s> bool expandStoreInt ( MachineBasicBlock & B , MachineBasicBlock :: iterator It , MachineRegisterInfo & MRI , const <ISA_LIT>InstrInfo & HII , SmallVectorImpl < unsigned > & NewRegs ) const ; bool expandLoadInt ( MachineBasicBlock & B , MachineBasicBlock :: iterator It , MachineRegisterInfo & MRI , const <ISA_LIT>InstrInfo & HII , SmallVectorImpl < unsigned > & NewRegs ) const ; bool expandStoreVecPred ( MachineBasicBlock & B , MachineBasicBlock :: iterator It , MachineRegisterInfo & MRI , const <ISA_LIT>InstrInfo & HII , SmallVectorImpl < unsigned > & NewRegs ) const ; bool expandLoadVecPred ( MachineBasicBlock & B , MachineBasicBlock :: iterator It , MachineRegisterInfo & MRI , const <ISA_LIT>InstrInfo & HII , SmallVectorImpl < unsigned > & NewRegs ) const ; bool expandStoreVec2 ( MachineBasicBlock & B , MachineBasicBlock :: iterator It , MachineRegisterInfo & MRI , const <ISA_LIT>InstrInfo & HII , SmallVectorImpl < unsigned > & NewRegs ) const ; bool expandLoadVec2 ( MachineBasicBlock & B , MachineBasicBlock :: iterator It , MachineRegisterInfo & MRI , const <ISA_LIT>InstrInfo & HII , SmallVectorImpl < unsigned > & NewRegs ) const ; bool expandStoreVec ( MachineBasicBlock & B , MachineBasicBlock :: iterator It , MachineRegisterInfo & MRI , const <ISA_LIT>InstrInfo & HII , SmallVectorImpl < unsigned > & NewRegs ) const ; bool expandLoadVec ( MachineBasicBlock & B , MachineBasicBlock :: iterator It , MachineRegisterInfo & MRI , const <ISA_LIT>InstrInfo & HII , SmallVectorImpl < unsigned > & NewRegs ) const ; bool expandSpillMacros ( MachineFunction & MF , SmallVectorImpl < unsigned > & NewRegs ) const ;

unsigned findPhysReg ( MachineFunction & MF , <ISA_LIT>BlockRanges :: IndexRange & FIR , <ISA_LIT>BlockRanges :: InstrIndexMap & IndexMap , <ISA_LIT>BlockRanges :: RegToRangeMap & DeadMap , const TargetRegisterClass * RC ) const ;


<s> if ( * SubRegs > RegNo ) RegNo = * SubRegs ; } else { if ( ! RegNo || * SubRegs < RegNo ) RegNo = * SubRegs ; } }


<s> if ( Reg < <STR_LIT> || Reg > <STR_LIT> ) return Reg ; unsigned RegNo = <NUM_LIT> ; for ( MCSubRegIterator SubRegs ( Reg , & TRI ) ; SubRegs . isValid ( ) ; ++ SubRegs ) { if ( hireg ) {

if ( * SubRegs > RegNo ) RegNo = * SubRegs ;


<s> static unsigned getMaxCalleeSavedReg ( const std :: vector < CalleeSavedInfo > & CSI , const TargetRegisterInfo & TRI ) { static_assert ( <STR_LIT> > <NUM_LIT> , <STR_LIT> ) ; if ( CSI . empty ( ) ) return <NUM_LIT> ; unsigned Max = getMax32BitSubRegister ( CSI [ <NUM_LIT> ] . getReg ( ) , TRI ) ;

for ( unsigned I = <NUM_LIT> , E = CSI . size ( ) ; I < E ; ++ I ) {


<s> unsigned Max = getMax32BitSubRegister ( CSI [ <NUM_LIT> ] . getReg ( ) , TRI ) ; for ( unsigned I = <NUM_LIT> , E = CSI . size ( ) ; I < E ; ++ I ) { unsigned Reg = getMax32BitSubRegister ( CSI [ I ] . getReg ( ) , TRI ) ; if ( Reg > Max ) Max = Reg ; }


<s> static MachineInstr * getReturn ( MachineBasicBlock & MBB ) {

for ( auto & I : MBB ) if ( I . isReturn ( ) ) return & I ;


<s> } assert ( SpillFunc && <STR_LIT> ) ; switch ( MaxReg ) { case <STR_LIT> : return SpillFunc [ <NUM_LIT> ] ; case <STR_LIT> : return SpillFunc [ <NUM_LIT> ] ; case <STR_LIT> : return SpillFunc [ <NUM_LIT> ] ; case <STR_LIT> : return SpillFunc [ <NUM_LIT> ] ; case <STR_LIT> : return SpillFunc [ <NUM_LIT> ] ; case <STR_LIT> : return SpillFunc [ <NUM_LIT> ] ; default : llvm_unreachable ( <STR_LIT> ) ; } return nullptr ;


<s> auto & MFI = MF . getFrameInfo ( ) ; auto & HRI = * MF . getSubtarget < <ISA_LIT>Subtarget > ( ) . getRegisterInfo ( ) ; bool HasExtraAlign = HRI . needsStackRealignment ( MF ) ; bool HasAlloca = MFI . hasVarSizedObjects ( ) ; if ( MF . getTarget ( ) . getOptLevel ( ) == CodeGenOpt :: None ) return true ; if ( HasAlloca || HasExtraAlign ) return true ;

if ( MFI . getStackSize ( ) > <NUM_LIT> ) {


<s> if ( HasAlloca || HasExtraAlign ) return true ; if ( MFI . getStackSize ( ) > <NUM_LIT> ) { const TargetMachine & TM = MF . getTarget ( ) ; if ( TM . Options . DisableFramePointerElim ( MF ) || ! EliminateFramePointer ) return true ; if ( EnableStackOVFSanitizer ) return true ; }

const auto & HMFI = * MF . getInfo < <ISA_LIT>MachineFunctionInfo > ( ) ;


<s> static bool hasReturn ( const MachineBasicBlock & MBB ) {

for ( auto I = MBB . getFirstTerminator ( ) , E = MBB . end ( ) ; I != E ; ++ I ) if ( I -> isReturn ( ) ) return true ;


<s> MachineBasicBlock :: const_iterator I = MBB . getLastNonDebugInstr ( ) ;

if ( I == MBB . end ( ) ) return false ;


<s> unsigned SP = HRI . getStackRegister ( ) ; if ( NumBytes >= ALLOCFRAME_MAX ) { BuildMI ( MBB , InsertPt , dl , HII . get ( <STR_LIT> ) ) . addDef ( SP ) . addReg ( SP ) . addImm ( <NUM_LIT> ) . addMemOperand ( MMO ) ; unsigned SP = HRI . getStackRegister ( ) ; BuildMI ( MBB , InsertPt , dl , HII . get ( <STR_LIT> ) , SP ) . addReg ( SP ) . addImm ( - int ( NumBytes ) ) ;


<s> for ( auto & B : MF ) { auto At = findCFILocation ( B ) ; if ( At . hasValue ( ) ) insertCFIInstructionsAt ( B , At . getValue ( ) ) ;


<s> BuildMI ( MBB , At , DL , CFID ) . addCFIIndex ( MF . addFrameInst ( DefCfa ) ) ; auto OffR31 = MCCFIInstruction :: createOffset ( FrameLabel , DwRAReg , - <NUM_LIT> ) ; BuildMI ( MBB , At , DL , CFID ) . addCFIIndex ( MF . addFrameInst ( OffR31 ) ) ; auto OffR30 = MCCFIInstruction :: createOffset ( FrameLabel , DwFPReg , - <NUM_LIT> ) ; BuildMI ( MBB , At , DL , CFID ) . addCFIIndex ( MF . addFrameInst ( OffR30 ) ) ; } static unsigned int RegsToMove [ ] = { <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> } ; const std :: vector < CalleeSavedInfo > & CSI = MFI . getCalleeSavedInfo ( ) ; for ( unsigned i = <NUM_LIT> ; RegsToMove [ i ] != <STR_LIT> ; ++ i ) { unsigned Reg = RegsToMove [ i ] ; auto IfR = [ Reg ] ( const CalleeSavedInfo & C ) -> bool { return C . getReg ( ) == Reg ; } ; auto F = find_if ( CSI , IfR ) ; if ( F == CSI . end ( ) ) continue ; int64_t Offset ; if ( HasFP ) { Offset = MFI . getObjectOffset ( F -> getFrameIdx ( ) ) ; } else { unsigned FrameReg ; Offset = getFrameIndexReference ( MF , F -> getFrameIdx ( ) , FrameReg ) ; } Offset -= <NUM_LIT> ; if ( Reg < <STR_LIT> || Reg > <STR_LIT> ) { unsigned DwarfReg = HRI . getDwarfRegNum ( Reg , true ) ; auto OffReg = MCCFIInstruction :: createOffset ( FrameLabel , DwarfReg , Offset ) ; BuildMI ( MBB , At , DL , CFID ) . addCFIIndex ( MF . addFrameInst ( OffReg ) ) ; } else { Register HiReg = HRI . getSubReg ( Reg , <STR_LIT> ) ; Register LoReg = HRI . getSubReg ( Reg , <STR_LIT> ) ; unsigned HiDwarfReg = HRI . getDwarfRegNum ( HiReg , true ) ; unsigned LoDwarfReg = HRI . getDwarfRegNum ( LoReg , true ) ; auto OffHi = MCCFIInstruction :: createOffset ( FrameLabel , HiDwarfReg , Offset + <NUM_LIT> ) ; BuildMI ( MBB , At , DL , CFID ) . addCFIIndex ( MF . addFrameInst ( OffHi ) ) ; auto OffLo = MCCFIInstruction :: createOffset ( FrameLabel , LoDwarfReg , Offset ) ; BuildMI ( MBB , At , DL , CFID ) . addCFIIndex ( MF . addFrameInst ( OffLo ) ) ; } }


<s> MachineFrameInfo & MFI = MF . getFrameInfo ( ) ; MachineModuleInfo & MMI = MF . getMMI ( ) ; auto & HST = MF . getSubtarget < <ISA_LIT>Subtarget > ( ) ; auto & HII = * HST . getInstrInfo ( ) ; auto & HRI = * HST . getRegisterInfo ( ) ; DebugLoc DL ; const MCInstrDesc & CFID = HII . get ( TargetOpcode :: CFI_INSTRUCTION ) ; MCSymbol * FrameLabel = MMI . getContext ( ) . createTempSymbol ( ) ; bool HasFP = hasFP ( MF ) ; if ( HasFP ) { unsigned DwFPReg = HRI . getDwarfRegNum ( HRI . getFrameRegister ( ) , true ) ; unsigned DwRAReg = HRI . getDwarfRegNum ( HRI . getRARegister ( ) , true ) ; auto DefCfa = MCCFIInstruction :: createDefCfa ( FrameLabel , DwFPReg , - <NUM_LIT> ) ; BuildMI ( MBB , At , DL , CFID ) . addCFIIndex ( MF . addFrameInst ( DefCfa ) ) ; auto OffR31 = MCCFIInstruction :: createOffset ( FrameLabel , DwRAReg , - <NUM_LIT> ) ; BuildMI ( MBB , At , DL , CFID ) . addCFIIndex ( MF . addFrameInst ( OffR31 ) ) ; auto OffR30 = MCCFIInstruction :: createOffset ( FrameLabel , DwFPReg , - <NUM_LIT> ) ; BuildMI ( MBB , At , DL , CFID ) . addCFIIndex ( MF . addFrameInst ( OffR30 ) ) ; } static unsigned int RegsToMove [ ] = { <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> } ; const std :: vector < CalleeSavedInfo > & CSI = MFI . getCalleeSavedInfo ( ) ; for ( unsigned i = <NUM_LIT> ; RegsToMove [ i ] != <STR_LIT> ; ++ i ) { unsigned Reg = RegsToMove [ i ] ; auto IfR = [ Reg ] ( const CalleeSavedInfo & C ) -> bool { return C . getReg ( ) == Reg ; } ; auto F = find_if ( CSI , IfR ) ;


<s> assert ( It -> isReturn ( ) && std :: next ( It ) == MBB . end ( ) ) ; unsigned RetOpc ; if ( LongCalls ) RetOpc = IsPIC ? <STR_LIT> : <STR_LIT> ; else RetOpc = IsPIC ? <STR_LIT> : <STR_LIT> ; DeallocCall = BuildMI ( MBB , It , DL , HII . get ( RetOpc ) ) . addExternalSymbol ( RestoreFn ) ; DeallocCall -> copyImplicitOps ( MF , * It ) ; } addCalleeSaveRegistersAsImpOperand ( DeallocCall , CSI , true , false ) ; return true ; } for ( unsigned i = <NUM_LIT> ; i < CSI . size ( ) ; ++ i ) { unsigned Reg = CSI [ i ] . getReg ( ) ; const TargetRegisterClass * RC = HRI . getMinimalPhysRegClass ( Reg ) ; int FI = CSI [ i ] . getFrameIdx ( ) ; HII . loadRegFromStackSlot ( MBB , MI , Reg , FI , RC , & HRI ) ; }


<s> MachineBasicBlock :: iterator MI = MBB . begin ( ) ; PrologueStubs = false ; MachineFunction & MF = * MBB . getParent ( ) ; auto & HST = MF . getSubtarget < <ISA_LIT>Subtarget > ( ) ; auto & HII = * HST . getInstrInfo ( ) ; if ( useSpillFunction ( MF , CSI ) ) { PrologueStubs = true ; unsigned MaxReg = getMaxCalleeSavedReg ( CSI , HRI ) ; bool StkOvrFlowEnabled = EnableStackOVFSanitizer ; const char * SpillFun = getSpillFunctionFor ( MaxReg , SK_ToMem , StkOvrFlowEnabled ) ; auto & HTM = static_cast < const <ISA_LIT>TargetMachine & > ( MF . getTarget ( ) ) ; bool IsPIC = HTM . isPositionIndependent ( ) ; bool LongCalls = HST . useLongCalls ( ) || EnableSaveRestoreLong ; DebugLoc DL = MI != MBB . end ( ) ? MI -> getDebugLoc ( ) : DebugLoc ( ) ; unsigned SpillOpc ; if ( StkOvrFlowEnabled ) { if ( LongCalls ) SpillOpc = IsPIC ? <STR_LIT> : <STR_LIT> ; else SpillOpc = IsPIC ? <STR_LIT> : <STR_LIT> ; } else { if ( LongCalls ) SpillOpc = IsPIC ? <STR_LIT> : <STR_LIT> ; else SpillOpc = IsPIC ? <STR_LIT> : <STR_LIT> ; } MachineInstr * SaveRegsCall = BuildMI ( MBB , MI , DL , HII . get ( SpillOpc ) ) . addExternalSymbol ( SpillFun ) ; addCalleeSaveRegistersAsImpOperand ( SaveRegsCall , CSI , false , true ) ; for ( unsigned I = <NUM_LIT> ; I < CSI . size ( ) ; ++ I ) MBB . addLiveIn ( CSI [ I ] . getReg ( ) ) ; return true ; }

for ( unsigned i = <NUM_LIT> , n = CSI . size ( ) ; i < n ; ++ i ) {


<s> else SpillOpc = IsPIC ? <STR_LIT> : <STR_LIT> ; } MachineInstr * SaveRegsCall = BuildMI ( MBB , MI , DL , HII . get ( SpillOpc ) ) . addExternalSymbol ( SpillFun ) ; addCalleeSaveRegistersAsImpOperand ( SaveRegsCall , CSI , false , true ) ; for ( unsigned I = <NUM_LIT> ; I < CSI . size ( ) ; ++ I ) MBB . addLiveIn ( CSI [ I ] . getReg ( ) ) ; return true ; } for ( unsigned i = <NUM_LIT> , n = CSI . size ( ) ; i < n ; ++ i ) { unsigned Reg = CSI [ i ] . getReg ( ) ; bool IsKill = ! HRI . isEHReturnCalleeSaveReg ( Reg ) ;


<s> unsigned RetOpc = RetI ? RetI -> getOpcode ( ) : <NUM_LIT> ; if ( RetOpc == <STR_LIT> ) { BuildMI ( MBB , InsertPt , dl , HII . get ( <STR_LIT> ) ) . addDef ( <STR_LIT> ) . addReg ( <STR_LIT> ) ; BuildMI ( MBB , InsertPt , dl , HII . get ( <STR_LIT> ) , SP ) . addReg ( SP ) . addReg ( <STR_LIT> ) ; return ; } if ( RetOpc == <STR_LIT> || RetOpc == <STR_LIT> || RetOpc == <STR_LIT> || RetOpc == <STR_LIT> ) { MachineBasicBlock :: iterator It = RetI ; ++ It ; while ( It != MBB . end ( ) ) { if ( ! It -> isLabel ( ) ) It = MBB . erase ( It ) ; else ++ It ; } return ; } bool NeedsDeallocframe = true ; if ( ! MBB . empty ( ) && InsertPt != MBB . begin ( ) ) { MachineBasicBlock :: iterator PrevIt = std :: prev ( InsertPt ) ; unsigned COpc = PrevIt -> getOpcode ( ) ; if ( COpc == <STR_LIT> || COpc == <STR_LIT> || COpc == <STR_LIT> || COpc == <STR_LIT> || COpc == <STR_LIT> || COpc == <STR_LIT> ) NeedsDeallocframe = false ; } if ( ! MF . getSubtarget < <ISA_LIT>Subtarget > ( ) . isEnvironmentMusl ( ) || ! MF . getFunction ( ) . isVarArg ( ) ) { if ( ! NeedsDeallocframe ) return ; if ( RetOpc != <STR_LIT> || DisableDeallocRet ) { BuildMI ( MBB , InsertPt , dl , HII . get ( <STR_LIT> ) ) . addDef ( <STR_LIT> ) . addReg ( <STR_LIT> ) ; return ; } unsigned NewOpc = <STR_LIT> ; MachineInstr * NewI = BuildMI ( MBB , RetI , dl , HII . get ( NewOpc ) ) . addDef ( <STR_LIT> ) . addReg ( <STR_LIT> ) ; NewI -> copyImplicitOps ( MF , * RetI ) ; MBB . erase ( RetI ) ; } else { int NumVarArgRegs = <NUM_LIT> - FirstVarArgSavedReg ; int RegisterSavedAreaSizePlusPadding = ( NumVarArgRegs % <NUM_LIT> == <NUM_LIT> ) ? ( NumVarArgRegs * <NUM_LIT> ) : ( NumVarArgRegs * <NUM_LIT> + <NUM_LIT> ) ;

MachineBasicBlock :: iterator Term = MBB . getFirstTerminator ( ) ;


<s> unsigned MaxCF = MFI . getMaxCallFrameSize ( ) ; MachineBasicBlock :: iterator InsertPt = MBB . begin ( ) ; SmallVector < MachineInstr * , <NUM_LIT> > AdjustRegs ; for ( auto & MBB : MF ) for ( auto & MI : MBB ) if ( MI . getOpcode ( ) == <STR_LIT> ) AdjustRegs . push_back ( & MI ) ; for ( auto MI : AdjustRegs ) { assert ( ( MI -> getOpcode ( ) == <STR_LIT> ) && <STR_LIT> ) ; expandAlloca ( MI , HII , SP , MaxCF ) ; MI -> eraseFromParent ( ) ; } DebugLoc dl = MBB . findDebugLoc ( InsertPt ) ; if ( MF . getFunction ( ) . isVarArg ( ) && MF . getSubtarget < <ISA_LIT>Subtarget > ( ) . isEnvironmentMusl ( ) ) { int NumVarArgRegs = <NUM_LIT> - FirstVarArgSavedReg ; int RegisterSavedAreaSizePlusPadding = ( NumVarArgRegs % <NUM_LIT> == <NUM_LIT> ) ? NumVarArgRegs * <NUM_LIT> : NumVarArgRegs * <NUM_LIT> + <NUM_LIT> ; if ( RegisterSavedAreaSizePlusPadding > <NUM_LIT> ) { BuildMI ( MBB , InsertPt , dl , HII . get ( <STR_LIT> ) , SP ) . addReg ( SP ) . addImm ( - RegisterSavedAreaSizePlusPadding ) . setMIFlag ( MachineInstr :: FrameSetup ) ; int NumBytes = <NUM_LIT> ; auto & HMFI = * MF . getInfo < <ISA_LIT>MachineFunctionInfo > ( ) ; for ( int i = HMFI . getFirstNamedArgFrameIndex ( ) , e = HMFI . getLastNamedArgFrameIndex ( ) ; i >= e ; -- i ) { int ObjSize = MFI . getObjectSize ( i ) ; int ObjAlign = MFI . getObjectAlignment ( i ) ; unsigned LDOpc , STOpc ; int OpcodeChecker = ObjAlign ; if ( ObjSize < ObjAlign ) { if ( ObjSize <= <NUM_LIT> ) OpcodeChecker = <NUM_LIT> ; else if ( ObjSize <= <NUM_LIT> ) OpcodeChecker = <NUM_LIT> ; else if ( ObjSize <= <NUM_LIT> ) OpcodeChecker = <NUM_LIT> ; else if ( ObjSize > <NUM_LIT> ) OpcodeChecker = <NUM_LIT> ;


<s> static inline bool isOptNone ( const MachineFunction & MF ) { return MF . getFunction ( ) . hasOptNone ( ) || MF . getTarget ( ) . getOptLevel ( ) == CodeGenOpt :: None ;


<s> static inline bool isOptNone ( const MachineFunction & MF ) {

return MF . getFunction ( ) . hasOptNone ( ) || MF . getTarget ( ) . getOptLevel ( ) == CodeGenOpt :: None ;


<s> static inline bool isOptSize ( const MachineFunction & MF ) {

const Function & F = MF . getFunction ( ) ;


<s> switch ( MI . getOpcode ( ) ) { case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : ++ LS ; LLVM_FALLTHROUGH ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : ++ LS ; LLVM_FALLTHROUGH ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> :

if ( MI . getOperand ( <NUM_LIT> ) . isFI ( ) ) HasImmStack = true ;


<s> for ( auto & I : MBB ) { const MachineInstr * MI = & I ; if ( MI -> isCall ( ) ) return true ; unsigned Opc = MI -> getOpcode ( ) ; switch ( Opc ) { case <STR_LIT> : case <STR_LIT> : return true ; default : break ; } for ( const MachineOperand & MO : MI -> operands ( ) ) { if ( MO . isFI ( ) ) return true ; if ( MO . isReg ( ) ) { Register R = MO . getReg ( ) ; if ( Register :: isVirtualRegister ( R ) ) return true ; for ( MCSubRegIterator S ( R , & HRI , true ) ; S . isValid ( ) ; ++ S ) if ( CSR [ * S ] ) return true ; continue ; } if ( MO . isRegMask ( ) ) { const uint32_t * BM = MO . getRegMask ( ) ; for ( int x = CSR . find_first ( ) ; x >= <NUM_LIT> ; x = CSR . find_next ( x ) ) { unsigned R = x ; if ( ! ( BM [ R / <NUM_LIT> ] & ( <NUM_LIT> << ( R % <NUM_LIT> ) ) ) ) return true ; } } } } return false ;


<s> if ( MO . isReg ( ) ) { Register R = MO . getReg ( ) ; if ( Register :: isVirtualRegister ( R ) ) return true ; for ( MCSubRegIterator S ( R , & HRI , true ) ; S . isValid ( ) ; ++ S ) if ( CSR [ * S ] ) return true ; continue ; } if ( MO . isRegMask ( ) ) { const uint32_t * BM = MO . getRegMask ( ) ; for ( int x = CSR . find_first ( ) ; x >= <NUM_LIT> ; x = CSR . find_next ( x ) ) { unsigned R = x ; if ( ! ( BM [ R / <NUM_LIT> ] & ( <NUM_LIT> << ( R % <NUM_LIT> ) ) ) ) return true ; } } } } return false ;


<s> for ( MCRegAliasIterator AI ( Reg , & HRI , true ) ; AI . isValid ( ) ; ++ AI ) if ( MRI . isPhysRegUsed ( * AI ) ) return true ;


<s> if ( ! DealignSlots . empty ( ) ) { for ( MachineBasicBlock & BB : MF ) { for ( MachineInstr & MI : BB ) { bool KeepOld = true ; ArrayRef < MachineMemOperand * > memops = MI . memoperands ( ) ; SmallVector < MachineMemOperand * , <NUM_LIT> > new_memops ; for ( MachineMemOperand * MMO : memops ) { auto * PV = MMO -> getPseudoValue ( ) ; if ( auto * FS = dyn_cast_or_null < FixedStackPseudoSourceValue > ( PV ) ) { int FI = FS -> getFrameIndex ( ) ; if ( DealignSlots . count ( FI ) ) { unsigned A = MFI . getObjectAlignment ( FI ) ; auto * NewMMO = MF . getMachineMemOperand ( MMO -> getPointerInfo ( ) , MMO -> getFlags ( ) , MMO -> getSize ( ) , A , MMO -> getAAInfo ( ) , MMO -> getRanges ( ) , MMO -> getSyncScopeID ( ) , MMO -> getOrdering ( ) , MMO -> getFailureOrdering ( ) ) ; new_memops . push_back ( NewMMO ) ; KeepOld = false ; continue ; } } new_memops . push_back ( MMO ) ; } if ( ! KeepOld ) MI . setMemRefs ( MF , new_memops ) ; } } } unsigned AP = <NUM_LIT> ; if ( const MachineInstr * AI = getAlignaInstr ( MF ) ) AP = AI -> getOperand ( <NUM_LIT> ) . getReg ( ) ;

auto & HMFI = * MF . getInfo < <ISA_LIT>MachineFunctionInfo > ( ) ;


<s> bool restoreCalleeSavedRegisters ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator MI , std :: vector < CalleeSavedInfo > & CSI , const TargetRegisterInfo * TRI ) const override {


<s> bool NeedCFI = MF . needsFrameMoves ( ) ; if ( ! NeedCFI ) return false ; HFI . insertCFIInstructions ( MF ) ;