<s> unsigned Opcode = MI . getOpcode ( ) ; switch ( Opcode ) { case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : break ; default : return false ; } if ( ! MI . getOperand ( <NUM_LIT> ) . isReg ( ) ) return false ; if ( ! MI . hasOneMemOperand ( ) ) return false ; const MachineMemOperand & MMO = * * MI . memoperands_begin ( ) ; if ( MMO . isVolatile ( ) || MMO . isAtomic ( ) ) return false ; if ( MMO . getAlign ( ) < Align ( <NUM_LIT> ) ) return false ; if ( MI . getOperand ( <NUM_LIT> ) . isReg ( ) && MI . getOperand ( <NUM_LIT>


<s> if ( ! MO . isReg ( ) ) continue ; Register Reg = MO . getReg ( ) ; if ( MO . isDef ( ) && TRI -> regsOverlap ( Reg , Base ) ) return false ; if ( Reg != Base && ! MemRegs . count ( Reg ) ) AddedRegPressure . insert ( Reg ) ; } } if ( MemRegs . size ( ) <= <NUM_LIT> ) return true ; return AddedRegPressure . size ( ) <= MemRegs . size


<s> SmallSet < unsigned , <NUM_LIT> > AddedRegPressure ; while ( ++ I != E ) { if ( I -> isDebugInstr ( ) || MemOps . count ( & * I ) ) continue ; if ( I -> isCall ( ) || I -> isTerminator ( ) || I -> hasUnmodeledSideEffects ( ) ) return false ; if ( I -> mayStore ( ) || ( ! isLd && I -> mayLoad ( ) ) ) for ( MachineInstr * MemOp :

MemOps ) if ( I -> mayAlias ( AA , * MemOp , false ) ) return false ;


<s> if ( ! Overlap ) { for ( const MemOpQueueEntry & E : MemOps ) { if ( TRI -> regsOverlap ( Reg , E . MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ) { Overlap = true ; break ; } } } } if ( ! Overlap ) { if ( Offset > MemOps . back ( ) . Offset ) { MemOps . push_back ( MemOpQueueEntry ( * MBBI , Offset , Position ) ) ; continue ; } else { MemOpQueue :: iterator MI , ME ; for ( MI = MemOps . begin ( ) , ME = MemOps . end ( ) ; MI != ME ; ++ MI ) { if ( Offset < MI -> Offset ) { break ; } if ( Offset == MI -> Offset ) { MI = ME ; break ; } } if ( MI != MemOps . end ( ) ) { MemOps . insert ( MI , MemOpQueueEntry ( * MBBI , Offset , Position ) ) ; continue ; } } } } MBBI = I ; -- Position ; } else if ( MBBI -> isDebugInstr ( ) ) { continue ; } else if ( MBBI -> getOpcode ( ) == <STR_LIT> || MBBI -> getOpcode ( ) == <STR_LIT> ) { MergeBaseCandidates . push_back ( & * MBBI ) ; } if ( MemOps . size ( ) > <NUM_LIT> ) { FormCandidates ( MemOps ) ; CurrBase = <NUM_LIT> ; CurrOpc = ~ <NUM_LIT> ; CurrPred = <STR_LIT> ; MemOps . clear ( ) ; } } if ( MemOps . size ( ) > <NUM_LIT> ) FormCandidates ( MemOps ) ; auto LessThan = [ ] ( const MergeCandidate * M0 , const MergeCandidate * M1 ) { return M0 -> InsertPos < M1 -> InsertPos ; } ; llvm :: sort ( Candidates , LessThan ) ; bool Changed = false ; for ( const MergeCandidate * Candidate : Candidates ) { if ( Candidate -> CanMergeToLSMulti || Candidate -> CanMergeToLSDouble ) { MachineInstr * Merged = MergeOpsUpdate ( * Candidate ) ; if ( Merged ) { Changed = true ; unsigned Opcode = Merged -> getOpcode ( ) ; if ( Opcode == <STR_LIT> || Opcode == <STR_LIT> ) MergeBaseUpdateLSDouble ( * Merged ) ; else MergeBaseUpdateLSMultiple ( Merged ) ; } else { for ( MachineInstr * MI : Candidate -> Instrs ) { if ( MergeBaseUpdateLoadStore ( MI ) ) Changed = true ; } } } else { assert ( Candidate -> Instrs . size ( ) == <NUM_LIT> ) ; if ( MergeBaseUpdateLoadStore ( Candidate -> Instrs . front ( ) ) ) Changed = true ; } } Candidates . clear ( ) ; for ( MachineInstr * MI : MergeBaseCandidates ) MergeBaseUpdateLSDouble ( * MI ) ; MergeBaseCandidates . clear (


<s> } } if ( MI != MemOps . end ( ) ) { MemOps . insert ( MI , MemOpQueueEntry ( * MBBI , Offset , Position ) ) ; continue ; } } } } MBBI = I ; -- Position ; } else if ( MBBI -> isDebugInstr ( ) ) { continue ; } else if ( MBBI -> getOpcode ( ) == <STR_LIT> || MBBI -> getOpcode ( ) == <STR_LIT> ) { MergeBaseCandidates . push_back ( & * MBBI ) ; } if ( MemOps . size ( ) > <NUM_LIT> ) { FormCandidates ( MemOps ) ; CurrBase = <NUM_LIT> ; CurrOpc = ~ <NUM_LIT> ; CurrPred = <STR_LIT> ; MemOps . clear ( ) ; } } if ( MemOps . size ( ) > <NUM_LIT> ) FormCandidates ( MemOps ) ; auto LessThan = [ ] ( const MergeCandidate * M0 , const MergeCandidate * M1 ) { return M0 -> InsertPos < M1 -> InsertPos ; } ; llvm :: sort ( Candidates , LessThan ) ; bool Changed = false ; for ( const MergeCandidate * Candidate : Candidates ) { if ( Candidate -> CanMergeToLSMulti || Candidate -> CanMergeToLSDouble ) { MachineInstr * Merged = MergeOpsUpdate ( * Candidate ) ; if ( Merged ) { Changed = true ; unsigned Opcode = Merged -> getOpcode ( ) ; if ( Opcode == <STR_LIT> || Opcode == <STR_LIT> ) MergeBaseUpdateLSDouble ( * Merged ) ; else MergeBaseUpdateLSMultiple ( Merged )


<s> if ( getLoadStoreBaseOp ( MI ) . getReg ( ) == <STR_LIT> && STI . getFrameLowering ( ) -> getTransientStackAlign

( ) >= Align ( <NUM_LIT> ) ) return true ;


<s> static bool mayCombineMisaligned ( const TargetSubtargetInfo & STI , const MachineInstr & MI ) { unsigned Opcode = MI . getOpcode ( ) ; if ( ! isi32Load ( Opcode ) && ! isi32Store ( Opcode ) ) return true ; if ( getLoadStoreBaseOp ( MI ) . getReg ( ) == <STR_LIT> && STI . getFrameLowering ( ) -> getTransientStackAlign ( ) >= Align ( <NUM_LIT> ) ) return true ; return


<s> NewOpc = Opcode == <STR_LIT> ? <STR_LIT> : <STR_LIT> ; } else return false ; } MBB . erase ( MergeInstr ) ; DebugLoc DL = MI . getDebugLoc ( ) ; MachineInstrBuilder MIB = BuildMI ( MBB , MBBI , DL , TII -> get ( NewOpc ) ) ; if ( NewOpc == <STR_LIT> || NewOpc == <STR_LIT> ) { MIB . add ( Reg0Op ) . add ( Reg1Op ) . addReg ( BaseOp . getReg ( ) , RegState :: Define ) ; } else { assert ( NewOpc == <STR_LIT> || NewOpc == <STR_LIT> ) ; MIB . addReg ( BaseOp . getReg ( ) , RegState :: Define ) . add ( Reg0Op ) . add ( Reg1Op ) ; } MIB . addReg ( BaseOp . getReg ( ) , RegState :: Kill ) . addImm ( Offset ) . addImm (


<s> if ( Mode == <STR_LIT> && Offset == - Bytes ) { Mode = <STR_LIT> ; } else if ( Mode == <STR_LIT> && Offset == - Bytes ) { Mode = <STR_LIT> ; } else { MergeInstr = findIncDecAfter ( MBBI , Base , Pred , PredReg , Offset ) ; if ( ( ( Mode != <STR_LIT> && Mode != <STR_LIT> ) || Offset != Bytes ) && ( ( Mode != <STR_LIT> && Mode != <STR_LIT> ) || Offset != - Bytes ) ) { if ( ! STI -> hasMinSize ( ) || ! BaseKill ) return false ; bool HighRegsUsed = false ; for ( unsigned i = <NUM_LIT> , e = MI -> getNumOperands ( ) ; i != e ; ++ i ) if ( MI -> getOperand ( i ) . getReg ( ) >= <STR_LIT> ) { HighRegsUsed = true ; break ; } if ( ! HighRegsUsed ) MergeInstr = MBB . end ( ) ; else return false ; } } if ( MergeInstr != MBB . end ( ) ) MBB . erase ( MergeInstr ) ; unsigned NewOpc = getUpdatingLSMultipleOpcode ( Opcode , Mode ) ; MachineInstrBuilder MIB = BuildMI ( MBB , MBBI , DL , TII -> get ( NewOpc ) ) . addReg ( Base , getDefRegState ( true ) ) . addReg ( Base , getKillRegState ( BaseKill ) ) . addImm ( Pred ) . addReg ( PredReg ) ; for ( unsigned OpNum = <NUM_LIT> , e = MI -> getNumOperands ( ) ; OpNum != e ; ++ OpNum ) MIB . add ( MI -> getOperand ( OpNum ) ) ; MIB . setMemRefs ( MI -> memoperands ( ) ) ; MBB . erase (


<s> for ( unsigned i = <NUM_LIT> , e = MI -> getNumOperands ( ) ; i != e ; ++ i ) if ( MI -> getOperand ( i ) . getReg ( ) == Base ) return false ; int Bytes = getLSMultipleTransferSize ( MI ) ; MachineBasicBlock & MBB = * MI -> getParent ( ) ; MachineBasicBlock :: iterator MBBI ( MI ) ; int Offset ; MachineBasicBlock :: iterator MergeInstr = findIncDecBefore ( MBBI , Base , Pred , PredReg , Offset ) ; <STR_LIT> Mode = getLoadStoreMultipleSubMode ( Opcode ) ; if ( Mode == <STR_LIT> && Offset == - Bytes ) { Mode = <STR_LIT> ; } else if ( Mode == <STR_LIT> && Offset == - Bytes ) { Mode = <STR_LIT> ; } else { MergeInstr = findIncDecAfter ( MBBI , Base , Pred , PredReg , Offset ) ; if ( ( ( Mode != <STR_LIT> && Mode != <STR_LIT> ) || Offset != Bytes ) && ( ( Mode != <STR_LIT> && Mode != <STR_LIT> ) || Offset != - Bytes ) ) { if ( ! STI -> hasMinSize ( ) || ! BaseKill ) return false ; bool HighRegsUsed = false ; for ( unsigned i = <NUM_LIT> , e = MI -> getNumOperands ( ) ; i != e ; ++ i ) if ( MI -> getOperand ( i ) . getReg ( ) >= <STR_LIT> ) { HighRegsUsed = true ; break ; } if ( ! HighRegsUsed ) MergeInstr = MBB . end


<s> if ( IsLoad || IsStore ) { MachineOperand & MO = MBBI -> getOperand ( MBBI -> getDesc ( ) . getNumOperands ( ) - <NUM_LIT> ) ; Offset = MO . getImm ( ) - WordOffset * getImmScale ( Opc ) ; Register InstrSrcReg = getLoadStoreRegOp ( * MBBI ) . getReg ( ) ; if ( Offset >= <NUM_LIT> && ! ( IsStore && InstrSrcReg == Base ) ) MO . setImm ( Offset ) ; else InsertSub = true ; } else if ( ( Opc == <STR_LIT> || Opc == <STR_LIT> ) && ! definesCPSR ( * MBBI ) ) { MachineOperand & MO = MBBI -> getOperand ( MBBI -> getDesc ( ) . getNumOperands ( ) - <NUM_LIT> ) ; Offset = ( Opc == <STR_LIT> ) ? MO . getImm ( ) + WordOffset * <NUM_LIT> : MO . getImm ( ) - WordOffset * <NUM_LIT> ; if ( Offset >= <NUM_LIT> && TL -> isLegalAddImmediate ( Offset ) ) { MO . setImm ( Offset ) ; return ; } else { InsertSub = true ; } } else { InsertSub = true ; } } else if ( definesCPSR ( * MBBI ) || MBBI -> isCall ( ) || MBBI -> isBranch ( ) ) { InsertSub =


<s> Scale = <NUM_LIT> ; isT2 = true ; } else { return false ; } if ( ! Op0 -> hasOneMemOperand ( ) || ( * Op0 -> memoperands_begin ( ) ) -> isVolatile ( ) || ( * Op0 -> memoperands_begin ( ) ) -> isAtomic ( ) ) return false ; unsigned Align = ( * Op0 -> memoperands_begin ( ) ) -> getAlignment ( ) ; const Function & Func = MF -> getFunction ( ) ; unsigned ReqAlign = STI -> hasV6Ops ( ) ? TD -> getABITypeAlignment ( Type :: getInt64Ty ( Func . getContext ( ) ) ) : <NUM_LIT> ; if ( Align < ReqAlign ) return false ; int OffImm = getMemoryOpOffset ( * Op0 ) ; if ( isT2 ) { int Limit = ( <NUM_LIT> << <NUM_LIT> ) * Scale ; if ( OffImm >= Limit || ( OffImm <= - Limit ) || ( OffImm & ( Scale - <NUM_LIT> ) ) ) return false ; Offset = OffImm ; } else { <STR_LIT> AddSub = <STR_LIT> ; if ( OffImm < <NUM_LIT> ) { AddSub = <STR_LIT> ; OffImm = - OffImm ; } int Limit = ( <NUM_LIT> << <NUM_LIT> ) * Scale ; if ( OffImm >= Limit || ( OffImm & ( Scale - <NUM_LIT> ) ) ) return false ; Offset = <STR_LIT> ( AddSub , OffImm ) ; } FirstReg = Op0 -> getOperand ( <NUM_LIT> ) . getReg ( ) ; SecondReg = Op1 -> getOperand ( <NUM_LIT> ) . getReg ( ) ; if ( FirstReg == SecondReg ) return false ; BaseReg = Op0 -> getOperand ( <NUM_LIT> ) . getReg ( ) ; Pred = getInstrPredicate ( * Op0 , PredReg ) ; dl = Op0 -> getDebugLoc ( )


<s> MachineBasicBlock :: iterator EndMBBI = MBB . end ( ) ; MachineBasicBlock :: iterator NextMBBI = std :: next ( MBBI ) ; while ( NextMBBI != EndMBBI && NextMBBI -> isDebugInstr ( ) ) ++ NextMBBI ; if ( NextMBBI == EndMBBI ) return EndMBBI ; Offset = isIncrementOrDecrement ( * NextMBBI , Reg , Pred , PredReg ) ; return Offset == <NUM_LIT> ?


<s> if ( MBBI == BeginMBBI ) return EndMBBI ; MachineBasicBlock :: iterator PrevMBBI = std :: prev ( MBBI ) ; while ( PrevMBBI -> isDebugInstr ( ) && PrevMBBI != BeginMBBI ) -- PrevMBBI ; Offset = isIncrementOrDecrement ( * PrevMBBI , Reg , Pred


<s> bool BaseKill = BaseOp . isKill ( ) ; bool BaseUndef = BaseOp . isUndef ( ) ; assert ( ( isT2 || MI -> getOperand ( <NUM_LIT> ) . getReg ( ) == <STR_LIT> ) && <STR_LIT> ) ; int OffImm = getMemoryOpOffset ( * MI ) ; unsigned PredReg = <NUM_LIT> ; <STR_LIT> Pred = getInstrPredicate ( * MI , PredReg ) ; if ( OddRegNum > EvenRegNum && OffImm == <NUM_LIT> ) { unsigned NewOpc = ( isLd ) ? ( isT2 ? <STR_LIT> : <STR_LIT> ) : ( isT2 ? <STR_LIT> : <STR_LIT> ) ; if ( isLd ) { BuildMI ( MBB , MBBI , MBBI -> getDebugLoc ( ) , TII -> get ( NewOpc ) ) . addReg ( BaseReg , getKillRegState ( BaseKill ) ) . addImm ( Pred ) . addReg ( PredReg ) . addReg ( EvenReg , getDefRegState ( isLd ) | getDeadRegState ( EvenDeadKill ) ) . addReg ( OddReg , getDefRegState ( isLd ) | getDeadRegState ( OddDeadKill ) ) . cloneMemRefs ( * MI ) ; ++ NumLDRD2LDM ; } else { BuildMI ( MBB , MBBI , MBBI -> getDebugLoc ( ) , TII -> get ( NewOpc ) ) . addReg ( BaseReg , getKillRegState ( BaseKill ) ) . addImm ( Pred ) . addReg ( PredReg ) . addReg ( EvenReg , getKillRegState ( EvenDeadKill ) | getUndefRegState ( EvenUndef ) ) . addReg ( OddReg , getKillRegState ( OddDeadKill ) | getUndefRegState ( OddUndef ) ) . cloneMemRefs ( * MI ) ; ++ NumSTRD2STM ; } } else { unsigned NewOpc = ( isLd ) ? ( isT2 ? ( OffImm < <NUM_LIT> ? <STR_LIT> : <STR_LIT> ) : <STR_LIT> ) : ( isT2 ? ( OffImm < <NUM_LIT> ? <STR_LIT> : <STR_LIT>


<s> case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : break ; default : return false ; } if ( ! MI . getOperand ( <NUM_LIT> ) . isReg ( ) ) return false ; if ( ! MI . hasOneMemOperand ( ) ) return false ; const MachineMemOperand & MMO = * * MI . memoperands_begin ( ) ; if ( MMO . isVolatile ( ) ||


<s> for ( const MemOpQueueEntry & E : MemOps ) { if ( TRI -> regsOverlap ( Reg , E . MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ) { Overlap = true ; break ; } } } } if ( ! Overlap ) { if ( Offset > MemOps . back ( ) . Offset ) { MemOps . push_back ( MemOpQueueEntry ( * MBBI , Offset , Position ) ) ; continue ; } else { MemOpQueue :: iterator MI , ME ; for ( MI = MemOps . begin ( ) , ME = MemOps . end ( ) ; MI != ME ; ++ MI ) { if ( Offset < MI -> Offset ) { break ; } if ( Offset == MI -> Offset ) { MI = ME ; break ; } } if ( MI != MemOps . end ( ) ) { MemOps . insert ( MI , MemOpQueueEntry ( * MBBI , Offset , Position ) ) ; continue ; } } } } MBBI = I ; -- Position ; } else if ( MBBI -> isDebugInstr ( ) ) { continue ; } else if ( MBBI -> getOpcode ( ) == <STR_LIT> || MBBI -> getOpcode ( ) == <STR_LIT> ) { MergeBaseCandidates . push_back ( & * MBBI ) ; } if ( MemOps . size ( ) > <NUM_LIT> ) { FormCandidates ( MemOps ) ; CurrBase = <NUM_LIT> ; CurrOpc = ~ <NUM_LIT> ; CurrPred = <STR_LIT> ; MemOps . clear ( ) ; } } if ( MemOps . size ( ) > <NUM_LIT> ) FormCandidates ( MemOps ) ; auto LessThan = [ ] ( const MergeCandidate * M0 , const MergeCandidate * M1 ) { return M0 -> InsertPos < M1 -> InsertPos ; } ; llvm :: sort ( Candidates , LessThan ) ; bool Changed = false ; for ( const MergeCandidate * Candidate : Candidates ) { if ( Candidate -> CanMergeToLSMulti || Candidate -> CanMergeToLSDouble ) { MachineInstr * Merged = MergeOpsUpdate ( * Candidate ) ; if ( Merged ) { Changed = true ; unsigned Opcode = Merged -> getOpcode ( ) ; if ( Opcode == <STR_LIT> || Opcode == <STR_LIT> ) MergeBaseUpdateLSDouble ( * Merged ) ; else MergeBaseUpdateLSMultiple ( Merged ) ; } else { for ( MachineInstr * MI : Candidate -> Instrs ) { if ( MergeBaseUpdateLoadStore ( MI ) ) Changed = true ; } } } else { assert ( Candidate -> Instrs . size ( ) == <NUM_LIT> ) ; if ( MergeBaseUpdateLoadStore ( Candidate -> Instrs . front ( ) ) ) Changed = true ; } } Candidates . clear ( ) ; for ( MachineInstr * MI : MergeBaseCandidates )


<s> if ( ! isAM5 && Offset == Bytes ) { NewOpc = getPreIndexedLoadStoreOpcode ( Opcode , <STR_LIT> ) ; } else if ( Offset == - Bytes ) { NewOpc = getPreIndexedLoadStoreOpcode ( Opcode , <STR_LIT> ) ; } else { MergeInstr = findIncDecAfter ( MBBI , Base , Pred , PredReg , Offset ) ; if ( Offset == Bytes ) { NewOpc = getPostIndexedLoadStoreOpcode ( Opcode , <STR_LIT> ) ; } else if ( ! isAM5 && Offset == - Bytes ) { NewOpc = getPostIndexedLoadStoreOpcode ( Opcode , <STR_LIT> ) ; } else return false ; } MBB . erase ( MergeInstr ) ; <STR_LIT> AddSub = Offset < <NUM_LIT> ? <STR_LIT> : <STR_LIT> ; bool isLd = isLoadSingle ( Opcode ) ; if ( isAM5 ) { MachineOperand & MO = MI -> getOperand ( <NUM_LIT> ) ; BuildMI ( MBB , MBBI , DL , TII -> get ( NewOpc ) ) . addReg ( Base , getDefRegState ( true ) ) . addReg ( Base , getKillRegState ( isLd ? BaseKill : false ) ) . addImm ( Pred ) . addReg ( PredReg ) . addReg ( MO . getReg ( ) , ( isLd ? getDefRegState ( true ) : getKillRegState ( MO . isKill ( ) ) ) ) . cloneMemRefs ( * MI ) ; } else if ( isLd ) { if ( isAM2 ) { if ( NewOpc == <STR_LIT> || NewOpc == <STR_LIT> ) { BuildMI ( MBB , MBBI , DL , TII -> get ( NewOpc ) , MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) . addReg ( Base , RegState :: Define ) . addReg ( Base ) . addImm ( Offset ) . addImm ( Pred ) . addReg ( PredReg ) . cloneMemRefs ( * MI ) ; } else { int Imm = <STR_LIT> ( AddSub , Bytes , <STR_LIT> ) ; BuildMI ( MBB , MBBI , DL , TII -> get ( NewOpc ) , MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) . addReg ( Base , RegState :: Define ) . addReg ( Base ) . addReg ( <NUM_LIT> ) . addImm ( Imm ) . add ( predOps ( Pred , PredReg ) ) . cloneMemRefs ( * MI ) ; } } else


<s> if ( ! isMemoryOp ( MI ) ) continue ; unsigned PredReg = <NUM_LIT> ; if ( getInstrPredicate ( MI , PredReg ) != <STR_LIT> ) continue ; int Opc = MI . getOpcode ( ) ; bool isLd = isLoadSingle ( Opc ) ; Register Base = MI . getOperand ( <NUM_LIT> ) . getReg ( ) ; int Offset = getMemoryOpOffset ( MI ) ; bool StopHere = false ; auto FindBases = [ & ] ( Base2InstMap & Base2Ops , BaseVec & Bases ) { MapIt BI = Base2Ops . find ( Base ) ; if ( BI == Base2Ops . end ( ) ) { Base2Ops [ Base ] . push_back ( & MI ) ; Bases . push_back ( Base ) ; return ; } for ( unsigned i = <NUM_LIT> , e = BI -> second . size ( ) ; i != e ; ++ i ) { if ( Offset == getMemoryOpOffset ( * BI -> second [ i ] ) ) { StopHere = true ; break ; } } if ( ! StopHere ) BI -> second . push_back ( & MI ) ; } ; if ( isLd ) FindBases ( Base2LdsMap , LdBases ) ; else FindBases ( Base2StsMap , StBases ) ; if ( StopHere ) { -- Loc ; break ; } } for ( unsigned i = <NUM_LIT> , e = LdBases . size ( ) ; i != e ; ++ i ) { unsigned Base = LdBases [ i ] ; SmallVectorImpl < MachineInstr * > & Lds = Base2LdsMap [ Base ] ; if ( Lds . size ( ) > <NUM_LIT> ) RetVal |= RescheduleOps ( MBB , Lds , Base , true , MI2LocMap ) ; } for ( unsigned i = <NUM_LIT> , e = StBases . size ( ) ; i != e ; ++ i ) { unsigned Base = StBases [ i ] ; SmallVectorImpl < MachineInstr * > & Sts = Base2StsMap [ Base ] ; if ( Sts . size ( ) > <NUM_LIT> ) RetVal |= RescheduleOps ( MBB , Sts , Base , false , MI2LocMap ) ; } if ( MBBI != E ) { Base2LdsMap . clear ( ) ; Base2StsMap . clear ( ) ; LdBases . clear ( ) ; StBases . clear (


<s> while ( MBBI != E ) { for ( ; MBBI != E ; ++ MBBI ) { MachineInstr & MI = * MBBI ; if ( MI . isCall ( ) || MI . isTerminator ( ) ) { ++ MBBI ; break ; } if ( ! MI . isDebugInstr ( ) ) MI2LocMap [ & MI ] = ++ Loc ; if ( ! isMemoryOp ( MI ) ) continue ; unsigned PredReg = <NUM_LIT> ; if ( getInstrPredicate ( MI , PredReg ) != <STR_LIT> ) continue ; int Opc = MI . getOpcode ( ) ; bool isLd = isLoadSingle ( Opc ) ; Register Base = MI . getOperand ( <NUM_LIT> ) . getReg ( ) ; int Offset = getMemoryOpOffset ( MI ) ; bool StopHere = false ; auto FindBases = [ & ] ( Base2InstMap & Base2Ops , BaseVec & Bases ) { MapIt BI = Base2Ops . find ( Base ) ; if ( BI == Base2Ops . end ( ) ) { Base2Ops [ Base ] . push_back ( & MI ) ; Bases . push_back ( Base ) ; return ; } for ( unsigned i = <NUM_LIT> , e = BI -> second . size ( ) ; i != e ; ++ i ) { if ( Offset == getMemoryOpOffset ( * BI -> second [ i ] ) ) { StopHere = true ; break ; } } if ( ! StopHere ) BI -> second . push_back ( & MI ) ; } ; if ( isLd ) FindBases ( Base2LdsMap , LdBases ) ; else FindBases ( Base2StsMap , StBases ) ; if ( StopHere ) { -- Loc ; break ; } } for ( unsigned i = <NUM_LIT> , e = LdBases . size ( ) ; i != e ; ++ i ) { unsigned Base = LdBases [ i ] ; SmallVectorImpl < MachineInstr * > & Lds = Base2LdsMap [ Base ] ; if ( Lds . size ( ) > <NUM_LIT> ) RetVal |= RescheduleOps ( MBB , Lds , Base , true , MI2LocMap ) ; } for ( unsigned i = <NUM_LIT> , e = StBases . size ( ) ; i != e ; ++ i ) { unsigned Base = StBases [ i ] ; SmallVectorImpl < MachineInstr * > & Sts = Base2StsMap [ Base ] ; if ( Sts . size ( ) > <NUM_LIT> ) RetVal |= RescheduleOps ( MBB , Sts , Base , false , MI2LocMap ) ; } if ( MBBI != E ) { Base2LdsMap . clear ( ) ; Base2StsMap . clear


<s> else if ( Opcode == <STR_LIT> ) NewOpc = <STR_LIT> ; else if ( Opcode == <STR_LIT> || Opcode == <STR_LIT> ) { NewOpc = <STR_LIT> ; Scale = <NUM_LIT> ; isT2 = true ; } else if ( Opcode == <STR_LIT> || Opcode == <STR_LIT> ) { NewOpc = <STR_LIT> ; Scale = <NUM_LIT> ; isT2 = true ; } else return false ; if ( ! Op0 -> hasOneMemOperand ( ) || ( * Op0 -> memoperands_begin ( ) ) -> isVolatile ( ) ) return false ; unsigned Align = ( * Op0 -> memoperands_begin ( ) ) -> getAlignment ( ) ; const Function * Func = MF -> getFunction ( ) ; unsigned ReqAlign = STI -> hasV6Ops ( ) ? TD -> getABITypeAlignment ( Type :: getInt64Ty ( Func -> getContext ( ) ) ) : <NUM_LIT> ; if ( Align < ReqAlign ) return false ; int OffImm = getMemoryOpOffset ( Op0 ) ; if ( isT2 ) { int Limit = ( <NUM_LIT> << <NUM_LIT> ) * Scale ; if ( OffImm >= Limit || ( OffImm <= - Limit ) || ( OffImm & ( Scale - <NUM_LIT> ) ) ) return false ; Offset = OffImm ; } else { <STR_LIT> AddSub = <STR_LIT> ; if ( OffImm < <NUM_LIT> ) { AddSub = <STR_LIT> ; OffImm = - OffImm ; } int Limit = ( <NUM_LIT> << <NUM_LIT> ) * Scale ; if ( OffImm >= Limit || ( OffImm & ( Scale - <NUM_LIT> ) ) ) return false ; Offset = <STR_LIT> ( AddSub , OffImm ) ; } EvenReg = Op0 -> getOperand ( <NUM_LIT>


<s> bool OddDeadKill = isLd ? MI -> getOperand ( <NUM_LIT> ) . isDead ( ) : MI -> getOperand ( <NUM_LIT> ) . isKill ( ) ; bool OddUndef = MI -> getOperand ( <NUM_LIT> ) . isUndef ( ) ; bool BaseKill = BaseOp . isKill ( ) ; bool BaseUndef = BaseOp . isUndef ( ) ; bool OffKill = isT2 ? false : MI -> getOperand ( <NUM_LIT> ) . isKill ( ) ; bool OffUndef = isT2 ? false : MI -> getOperand ( <NUM_LIT> ) . isUndef ( ) ; int OffImm = getMemoryOpOffset ( MI ) ; unsigned PredReg = <NUM_LIT> ; <STR_LIT> Pred = getInstrPredicate ( MI , PredReg ) ; if ( OddRegNum > EvenRegNum && OffImm == <NUM_LIT> ) { unsigned NewOpc = ( isLd ) ? ( isT2 ? <STR_LIT> : <STR_LIT> ) : ( isT2 ? <STR_LIT> : <STR_LIT> ) ; if ( isLd ) { BuildMI ( MBB , MBBI , MBBI -> getDebugLoc ( ) , TII -> get ( NewOpc ) ) . addReg ( BaseReg , getKillRegState ( BaseKill ) ) . addImm ( Pred ) . addReg ( PredReg ) . addReg ( EvenReg , getDefRegState ( isLd ) | getDeadRegState ( EvenDeadKill ) ) . addReg ( OddReg , getDefRegState ( isLd ) | getDeadRegState ( OddDeadKill ) ) ; ++ NumLDRD2LDM ; } else { BuildMI ( MBB , MBBI , MBBI -> getDebugLoc ( ) , TII -> get ( NewOpc ) ) . addReg ( BaseReg , getKillRegState ( BaseKill ) ) . addImm ( Pred ) . addReg ( PredReg ) . addReg ( EvenReg , getKillRegState ( EvenDeadKill ) | getUndefRegState ( EvenUndef ) ) . addReg ( OddReg , getKillRegState ( OddDeadKill ) | getUndefRegState ( OddUndef ) ) ; ++ NumSTRD2STM


<s> if ( ! DoMerge ) return false ; if ( isAM5 ) { MachineOperand & MO = MI -> getOperand ( <NUM_LIT> ) ; BuildMI ( MBB , MBBI , dl , TII -> get ( NewOpc ) ) . addReg ( Base , getDefRegState ( true ) ) . addReg ( Base , getKillRegState ( isLd ? BaseKill : false ) ) . addImm ( Pred ) . addReg ( PredReg ) . addReg ( MO . getReg ( ) , ( isLd ? getDefRegState ( true ) : getKillRegState ( MO . isKill ( ) ) ) ) ; } else if ( isLd ) { if ( isAM2 ) { if ( NewOpc == <STR_LIT> || NewOpc == <STR_LIT> ) { int Offset = AddSub == <STR_LIT> ? - Bytes : Bytes ; BuildMI ( MBB , MBBI , dl , TII -> get ( NewOpc ) , MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) . addReg ( Base , RegState :: Define ) . addReg ( Base ) . addImm ( Offset ) . addImm ( Pred ) . addReg ( PredReg ) ; } else { int Offset = <STR_LIT> ( AddSub , Bytes , <STR_LIT> ) ; BuildMI ( MBB , MBBI , dl , TII -> get ( NewOpc ) , MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) . addReg ( Base , RegState :: Define ) . addReg ( Base ) . addReg ( <NUM_LIT> ) . addImm ( Offset ) . addImm ( Pred ) . addReg ( PredReg ) ; } } else { int Offset = AddSub == <STR_LIT> ? - Bytes : Bytes ; BuildMI ( MBB , MBBI , dl , TII -> get ( NewOpc ) , MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) . addReg ( Base , RegState


<s> break ; } for ( unsigned i = SIndex + <NUM_LIT> , e = MemOps . size ( ) ; i != e ; ++ i ) { int NewOffset = MemOps [ i ] . Offset ; const MachineOperand & MO = MemOps [ i ] . MBBI -> getOperand ( <NUM_LIT> ) ; unsigned Reg = MO . getReg ( ) ; unsigned RegNum = MO . isUndef ( ) ? UINT_MAX : TRI -> getEncodingValue ( Reg ) ; if ( Reg != <STR_LIT> && NewOffset == Offset + ( int ) Size && ( ( isNotVFP && RegNum > PRegNum ) || ( ( Count < Limit ) && RegNum == PRegNum + <NUM_LIT> ) ) && ( ! STI -> isSwift ( ) || isNotVFP || Count != <NUM_LIT> || ! ( PRegNum & <NUM_LIT> ) ) ) { Offset += Size ; PRegNum = RegNum ; ++ Count ; } else { MergeOpsUpdate ( MBB , MemOps , SIndex , i , insertAfter , SOffset , Base , false , Opcode , Pred , PredReg , Scratch , dl , Merges ) ; MergeLDR_STR ( MBB , i , Base , Opcode , Size , Pred , PredReg , Scratch , MemOps , Merges ) ; return ; } if ( MemOps [ i ] . Position > MemOps [ insertAfter ]


<s> unsigned Count = <NUM_LIT> ; unsigned Limit = ~ <NUM_LIT> ; switch ( Opcode ) { default : break ; case <STR_LIT> : Limit = <NUM_LIT> ; break ; case <STR_LIT> : Limit = <NUM_LIT> ; break ; case <STR_LIT> : Limit = <NUM_LIT> ; break ; case <STR_LIT> : Limit = <NUM_LIT> ; break ; } for ( unsigned i = SIndex + <NUM_LIT> , e = MemOps . size ( ) ; i != e ; ++ i ) { int NewOffset = MemOps [ i ] . Offset ; const MachineOperand & MO = MemOps [ i ] . MBBI -> getOperand ( <NUM_LIT> ) ; unsigned Reg = MO . getReg ( ) ; unsigned RegNum = MO . isUndef ( ) ? UINT_MAX : TRI -> getEncodingValue ( Reg ) ; if ( Reg != <STR_LIT> && NewOffset == Offset + ( int ) Size && ( ( isNotVFP && RegNum > PRegNum ) || ( ( Count < Limit ) && RegNum == PRegNum + <NUM_LIT> ) ) && ( ! STI -> isSwift ( ) || isNotVFP || Count != <NUM_LIT> || ! ( PRegNum & <NUM_LIT> ) ) ) { Offset += Size ; PRegNum = RegNum ; ++ Count ; } else { MergeOpsUpdate ( MBB , MemOps , SIndex , i , insertAfter , SOffset , Base , false ,

Opcode , Pred , PredReg , Scratch , dl , Merges ) ;


<s> SmallVector < unsigned , <NUM_LIT> > ImpDefs ; for ( unsigned i = memOpsBegin ; i < memOpsEnd ; ++ i ) { unsigned Reg = memOps [ i ] . Reg ; bool isKill = memOps [ i ] . isKill || KilledRegs . count ( Reg ) ; Regs . push_back ( std :: make_pair ( Reg , isKill ) ) ; for ( MIOperands MO ( memOps [ i ] . MBBI ) ; MO . isValid ( ) ; ++ MO ) { if ( ! MO -> isReg ( ) || ! MO -> isDef ( ) || ! MO -> isImplicit ( ) || MO -> isDead ( ) ) continue ; unsigned DefReg = MO -> getReg ( ) ; if ( std :: find ( ImpDefs . begin ( ) , ImpDefs . end ( ) , DefReg ) == ImpDefs . end ( ) ) ImpDefs . push_back ( DefReg ) ; } } MachineBasicBlock :: iterator Loc = memOps [ insertAfter ]


<s> if ( MBBI != MBB . begin ( ) && ( MBBI -> getOpcode ( ) == <STR_LIT> || MBBI -> getOpcode ( ) == <STR_LIT> || MBBI -> getOpcode ( ) == <STR_LIT> ) ) { MachineInstr * PrevMI = prior ( MBBI ) ; unsigned Opcode = PrevMI -> getOpcode ( ) ; if ( Opcode == <STR_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> ) { MachineOperand & MO = PrevMI -> getOperand ( PrevMI -> getNumOperands ( ) - <NUM_LIT> ) ; if ( MO . getReg ( ) != <STR_LIT> )


<s> unsigned Base = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; int Offset = getMemoryOpOffset ( MI ) ; bool StopHere = false ; if ( isLd ) { DenseMap < unsigned , SmallVector < MachineInstr * , <NUM_LIT> > > :: iterator BI = Base2LdsMap . find ( Base ) ; if ( BI != Base2LdsMap . end ( ) ) { for ( unsigned i = <NUM_LIT> , e = BI -> second . size ( ) ; i != e ; ++ i ) { if ( Offset == getMemoryOpOffset ( BI -> second [ i ] ) ) { StopHere = true ; break ; } } if ( ! StopHere ) BI -> second . push_back ( MI ) ; } else { Base2LdsMap [ Base ] . push_back ( MI ) ; LdBases . push_back ( Base ) ; } } else { DenseMap < unsigned , SmallVector < MachineInstr * , <NUM_LIT> > > :: iterator BI = Base2StsMap . find ( Base ) ; if ( BI != Base2StsMap . end ( ) ) { for ( unsigned i = <NUM_LIT> , e = BI -> second . size ( ) ; i != e ; ++ i ) { if ( Offset == getMemoryOpOffset ( BI -> second [ i ] ) ) { StopHere = true ; break ; } } if ( ! StopHere ) BI -> second . push_back ( MI ) ; } else { Base2StsMap [ Base ] . push_back ( MI ) ; StBases . push_back ( Base ) ; } } if ( StopHere ) { -- Loc ; break ; } } for ( unsigned i = <NUM_LIT> , e = LdBases . size ( ) ; i != e ; ++ i ) { unsigned Base = LdBases [ i ] ; SmallVectorImpl < MachineInstr * > & Lds = Base2LdsMap [ Base ] ; if ( Lds . size ( ) > <NUM_LIT> ) RetVal |= RescheduleOps ( MBB , Lds , Base , true , MI2LocMap ) ; } for ( unsigned i = <NUM_LIT> , e = StBases . size ( ) ; i != e ; ++ i ) { unsigned Base = StBases [ i ] ; SmallVectorImpl < MachineInstr * > & Sts = Base2StsMap [ Base ] ; if ( Sts . size ( ) > <NUM_LIT> ) RetVal |= RescheduleOps ( MBB , Sts , Base , false , MI2LocMap ) ; } if ( MBBI != E ) { Base2LdsMap . clear ( ) ; Base2StsMap . clear ( ) ; LdBases . clear (


<s> TRI = Fn . getTarget ( ) . getRegisterInfo ( ) ; STI = & Fn . getTarget ( ) . getSubtarget < <ISA_LIT>Subtarget > ( ) ; MRI = & Fn . getRegInfo ( ) ; MF = & Fn ; bool Modified


<s> Limit = <NUM_LIT> ; break ; case <STR_LIT> : Limit = <NUM_LIT> ; break ; case <STR_LIT> : Limit = <NUM_LIT> ; break ; } for ( unsigned i = SIndex + <NUM_LIT> , e = MemOps . size ( ) ; i != e ; ++ i ) { int NewOffset = MemOps [ i ] . Offset ; const MachineOperand & MO = MemOps [ i ] . MBBI -> getOperand ( <NUM_LIT> ) ; unsigned Reg = MO . getReg ( ) ; unsigned RegNum = MO . isUndef ( ) ? UINT_MAX : TRI -> getEncodingValue ( Reg ) ; if ( Reg != <STR_LIT> && NewOffset == Offset + ( int ) Size && ( ( isNotVFP && RegNum > PRegNum ) || ( ( Count < Limit ) && RegNum == PRegNum + <NUM_LIT> ) ) ) { Offset += Size ; PRegNum = RegNum ; ++ Count ; } else { MergeOpsUpdate ( MBB , MemOps , SIndex , i , insertAfter , SOffset , Base , false , Opcode , Pred , PredReg , Scratch , dl , Merges ) ; MergeLDR_STR ( MBB , i , Base , Opcode , Size , Pred , PredReg , Scratch , MemOps ,


<s> MachineBasicBlock :: iterator InsertPos = isLd ? FirstOp : LastOp ; while ( InsertPos != MBB -> end ( ) && ( MemOps . count ( InsertPos ) || InsertPos -> isDebugValue ( ) ) ) ++ InsertPos ; MachineInstr * Op0 = Ops . back ( ) ; MachineInstr * Op1 = Ops [ Ops . size ( ) - <NUM_LIT> ] ; unsigned EvenReg = <NUM_LIT> , OddReg = <NUM_LIT> ; unsigned BaseReg = <NUM_LIT> , PredReg = <NUM_LIT> ; <STR_LIT> Pred = <STR_LIT> ; bool isT2 = false ; unsigned NewOpc = <NUM_LIT> ; int Offset = <NUM_LIT> ; DebugLoc dl ; if ( NumMove == <NUM_LIT> && CanFormLdStDWord ( Op0 , Op1 , dl , NewOpc , EvenReg , OddReg , BaseReg , Offset , PredReg , Pred , isT2 ) ) { Ops . pop_back ( ) ; Ops . pop_back ( ) ; const MCInstrDesc & MCID = TII -> get ( NewOpc ) ; const TargetRegisterClass * TRC = TII -> getRegClass ( MCID , <NUM_LIT> , TRI , * MF ) ; MRI -> constrainRegClass ( EvenReg , TRC ) ; MRI -> constrainRegClass ( OddReg , TRC ) ; if ( isLd ) { MachineInstrBuilder MIB = BuildMI ( * MBB , InsertPos , dl , MCID ) . addReg ( EvenReg , RegState :: Define ) . addReg ( OddReg , RegState :: Define ) . addReg ( BaseReg ) ; if ( ! isT2 ) MIB . addReg ( <NUM_LIT> ) ; MIB . addImm ( Offset ) . addImm ( Pred ) . addReg ( PredReg ) ; concatenateMemOperands ( MIB , Op0 , Op1 ) ; DEBUG ( dbgs ( ) << <STR_LIT> << * MIB << <STR_LIT> ) ; ++ NumLDRDFormed ; } else { MachineInstrBuilder MIB = BuildMI ( * MBB , InsertPos , dl , MCID ) . addReg ( EvenReg ) . addReg ( OddReg ) . addReg ( BaseReg ) ; if ( ! isT2 ) MIB . addReg ( <NUM_LIT> ) ; MIB . addImm ( Offset ) . addImm ( Pred ) . addReg ( PredReg ) ; concatenateMemOperands ( MIB , Op0 , Op1 ) ; DEBUG ( dbgs ( ) << <STR_LIT> << * MIB << <STR_LIT> ) ; ++ NumSTRDFormed ; } MBB -> erase ( Op0 ) ; MBB -> erase ( Op1 ) ; MRI -> setRegAllocationHint ( EvenReg , <STR_LIT> , OddReg ) ; MRI -> setRegAllocationHint ( OddReg , <STR_LIT> , EvenReg ) ; } else { for ( unsigned i = <NUM_LIT> ; i != NumMove


<s> case <STR_LIT> : ConvOpcode = <STR_LIT> ; break ; default : llvm_unreachable ( <STR_LIT> ) ; } assert ( isLegalAddressImm ( ConvOpcode , OldOffset - Offset , TII ) && <STR_LIT> ) ; const MCInstrDesc & MCID = TII -> get ( ConvOpcode ) ; BuildMI ( * MI -> getParent ( ) , MI , MI -> getDebugLoc ( ) , MCID ) . add ( MI -> getOperand ( <NUM_LIT> ) ) . add ( MI -> getOperand ( <NUM_LIT> ) ) . addImm ( OldOffset - Offset ) . add ( MI -> getOperand ( <NUM_LIT> ) ) . add ( MI -> getOperand ( <NUM_LIT> ) ) . cloneMemRefs ( * MI ) ; MI -> eraseFromParent


<s> for ( unsigned Reg : RegClassInfo . getOrder ( & RegClass ) ) if ( LiveRegs . available ( MF -> getRegInfo ( ) , Reg ) ) return Reg ; return <NUM_LIT>


<s> MachineBasicBlock :: iterator EndMBBI = MBB . end ( ) ; MachineBasicBlock :: iterator NextMBBI = std :: next ( MBBI ) ; while ( NextMBBI != EndMBBI ) { while ( NextMBBI != EndMBBI && NextMBBI -> isDebugInstr ( ) ) ++ NextMBBI ; if ( NextMBBI == EndMBBI ) return EndMBBI ; unsigned Off = isIncrementOrDecrement ( * NextMBBI , Reg , Pred , PredReg ) ; if ( Off


<s> AU . addRequired < AAResultsWrapperPass > ( ) ; AU . addRequired < MachineDominatorTree >


<s> switch ( AddrMode ) { case <STR_LIT> : CodesizeEstimate += <NUM_LIT> ; return std :: abs ( Imm ) < ( ( ( <NUM_LIT> << <NUM_LIT> ) * <NUM_LIT> ) - <NUM_LIT> ) ; } return false


<s> LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << MI ) ; const MachineOperand & BaseOp = MI . getOperand ( <NUM_LIT> ) ; Register Base = BaseOp . getReg ( ) ; const MachineOperand & Reg0Op = MI . getOperand ( <NUM_LIT> ) ; const MachineOperand & Reg1Op = MI . getOperand ( <NUM_LIT> ) ; if ( Reg0Op . getReg ( ) == Base || Reg1Op . getReg ( ) == Base ) return false ; Register PredReg ; <STR_LIT> Pred = getInstrPredicate ( MI , PredReg ) ; MachineBasicBlock :: iterator MBBI ( MI ) ; MachineBasicBlock & MBB = * MI . getParent ( ) ; int Offset ; MachineBasicBlock :: iterator MergeInstr = findIncDecBefore ( MBBI , Base , Pred , PredReg , Offset ) ; unsigned NewOpc ; if ( Offset == <NUM_LIT> || Offset == - <NUM_LIT> ) { NewOpc = Opcode == <STR_LIT> ? <STR_LIT> : <STR_LIT> ; } else { MergeInstr = findIncDecAfter ( MBBI , Base , Pred , PredReg , Offset , TRI ) ; if ( MergeInstr == MBB . end ( ) ) return false ; NewOpc = Opcode == <STR_LIT> ? <STR_LIT> : <STR_LIT> ; if ( ! isLegalAddressImm ( NewOpc , Offset , TII ) ) return false ; } LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << * MergeInstr ) ; MBB . erase ( MergeInstr ) ; DebugLoc DL = MI . getDebugLoc ( ) ; MachineInstrBuilder MIB = BuildMI ( MBB , MBBI , DL , TII -> get ( NewOpc ) ) ; if ( NewOpc == <STR_LIT> || NewOpc == <STR_LIT> ) { MIB . add ( Reg0Op ) . add ( Reg1Op ) . addReg ( BaseOp . getReg ( ) , RegState :: Define ) ; } else { assert ( NewOpc == <STR_LIT> || NewOpc == <STR_LIT> ) ; MIB . addReg ( BaseOp . getReg ( ) , RegState :: Define ) . add ( Reg0Op ) . add ( Reg1Op ) ; } MIB . addReg ( BaseOp . getReg ( ) , RegState :: Kill ) . addImm ( Offset ) . addImm ( Pred ) . addReg ( PredReg ) ; assert ( TII -> get ( Opcode ) . getNumOperands ( ) == <NUM_LIT> && TII -> get ( NewOpc ) . getNumOperands ( ) == <NUM_LIT> && <STR_LIT> ) ; for ( const MachineOperand & MO : MI . implicit_operands ( ) ) MIB . add ( MO ) ; MIB . cloneMemRefs (


<s> bool <ISA_LIT>LoadStoreOpt :: MergeBaseUpdateLSDouble ( MachineInstr & MI ) const { unsigned Opcode = MI . getOpcode ( ) ; assert ( ( Opcode == <STR_LIT> || Opcode == <STR_LIT> ) && <STR_LIT> ) ; if ( MI . getOperand ( <NUM_LIT> ) . getImm ( ) != <NUM_LIT> ) return false ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << MI ) ; const MachineOperand & BaseOp = MI . getOperand ( <NUM_LIT> ) ; Register Base = BaseOp . getReg ( ) ; const MachineOperand & Reg0Op = MI . getOperand ( <NUM_LIT> ) ; const MachineOperand & Reg1Op = MI . getOperand ( <NUM_LIT> ) ; if ( Reg0Op . getReg ( ) == Base || Reg1Op . getReg ( ) == Base ) return false ; Register PredReg ; <STR_LIT> Pred = getInstrPredicate ( MI , PredReg ) ; MachineBasicBlock :: iterator MBBI ( MI ) ; MachineBasicBlock & MBB = * MI . getParent ( ) ; int Offset ; MachineBasicBlock :: iterator MergeInstr = findIncDecBefore ( MBBI , Base , Pred , PredReg , Offset ) ; unsigned NewOpc ; if ( Offset == <NUM_LIT> || Offset == - <NUM_LIT> ) { NewOpc = Opcode == <STR_LIT> ? <STR_LIT> : <STR_LIT> ; } else { MergeInstr = findIncDecAfter ( MBBI , Base , Pred , PredReg , Offset , TRI ) ; if ( MergeInstr == MBB . end ( ) ) return false ; NewOpc = Opcode == <STR_LIT> ? <STR_LIT> : <STR_LIT> ; if ( ! isLegalAddressImm ( NewOpc , Offset , TII ) ) return false ; } LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << * MergeInstr ) ; MBB . erase ( MergeInstr ) ; DebugLoc DL = MI


<s> bool <ISA_LIT>LoadStoreOpt :: MergeBaseUpdateLSMultiple ( MachineInstr * MI ) { if ( isThumb1 ) return false ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << * MI ) ; const MachineOperand & BaseOP = MI -> getOperand ( <NUM_LIT> ) ; Register Base = BaseOP . getReg ( ) ; bool BaseKill = BaseOP . isKill ( ) ; Register PredReg ; <STR_LIT> Pred = getInstrPredicate ( * MI , PredReg ) ; unsigned Opcode = MI -> getOpcode ( ) ; DebugLoc DL = MI -> getDebugLoc ( ) ; for ( unsigned i = <NUM_LIT> , e = MI -> getNumOperands ( ) ; i != e ; ++ i ) if ( MI -> getOperand ( i ) . getReg ( ) == Base ) return false ; int Bytes = getLSMultipleTransferSize ( MI ) ; MachineBasicBlock & MBB = * MI -> getParent ( ) ; MachineBasicBlock :: iterator MBBI ( MI ) ; int Offset ; MachineBasicBlock :: iterator MergeInstr = findIncDecBefore ( MBBI , Base , Pred , PredReg , Offset ) ; <STR_LIT> Mode = getLoadStoreMultipleSubMode ( Opcode ) ; if ( Mode == <STR_LIT> && Offset == - Bytes ) { Mode = <STR_LIT> ; } else if ( Mode == <STR_LIT> && Offset == - Bytes ) { Mode = <STR_LIT> ; } else { MergeInstr = findIncDecAfter ( MBBI , Base , Pred , PredReg , Offset , TRI ) ; if ( ( ( Mode != <STR_LIT> && Mode != <STR_LIT> ) || Offset != Bytes ) && ( ( Mode != <STR_LIT> && Mode != <STR_LIT> ) || Offset != - Bytes ) ) { if ( ! STI -> hasMinSize ( ) || ! BaseKill ) return false ; bool HighRegsUsed = false ; for ( unsigned i = <NUM_LIT> , e = MI -> getNumOperands ( ) ; i != e ; ++ i ) if ( MI -> getOperand ( i ) . getReg ( ) >= <STR_LIT> ) { HighRegsUsed = true ; break ; } if ( ! HighRegsUsed ) MergeInstr = MBB . end ( ) ; else return false ; } } if ( MergeInstr != MBB . end


<s> LastOpcode = LSMOpcode ; unsigned Loc = MI2LocMap [ Op ] ; if ( Loc <= FirstLoc ) { FirstLoc = Loc ; FirstOp = Op ; } if ( Loc >= LastLoc ) { LastLoc = Loc ; LastOp = Op ; } } if ( NumMove <= <NUM_LIT> ) Ops . pop_back ( ) ; else { SmallPtrSet < MachineInstr * , <NUM_LIT> > MemOps ; SmallSet < unsigned , <NUM_LIT> > MemRegs ; for ( size_t i = Ops . size ( ) - NumMove , e = Ops . size ( ) ; i != e ; ++ i ) { MemOps . insert ( Ops [ i ] ) ; MemRegs . insert ( Ops [ i ] -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ; } bool DoMove = ( LastLoc - FirstLoc ) <= NumMove * <NUM_LIT> ; if ( DoMove ) DoMove = IsSafeAndProfitableToMove ( isLd , Base , FirstOp , LastOp , MemOps , MemRegs , TRI , AA ) ; if ( ! DoMove ) { for ( unsigned i = <NUM_LIT> ; i != NumMove ; ++ i ) Ops . pop_back ( ) ; } else { MachineBasicBlock :: iterator InsertPos = isLd ? FirstOp : LastOp ; while ( InsertPos != MBB -> end ( ) && ( MemOps . count ( & * InsertPos ) || InsertPos -> isDebugInstr ( ) ) ) ++ InsertPos ; MachineInstr * Op0 = Ops . back ( ) ; MachineInstr * Op1 = Ops [ Ops . size ( ) - <NUM_LIT> ] ; Register FirstReg , SecondReg ; Register BaseReg , PredReg ; <STR_LIT> Pred = <STR_LIT> ; bool isT2 = false ; unsigned NewOpc = <NUM_LIT> ; int Offset = <NUM_LIT> ; DebugLoc dl ; if ( NumMove == <NUM_LIT> && CanFormLdStDWord ( Op0 , Op1 , dl , NewOpc , FirstReg , SecondReg , BaseReg , Offset , PredReg , Pred , isT2 ) ) { Ops . pop_back ( ) ; Ops . pop_back ( ) ; const MCInstrDesc & MCID = TII -> get ( NewOpc ) ; const TargetRegisterClass * TRC = TII -> getRegClass ( MCID


<s> if ( AssumeMisalignedLoadStores || skipFunction ( Fn . getFunction ( ) ) ) return false ; TD = & Fn . getDataLayout ( ) ; STI = & static_cast < const <ISA_LIT>Subtarget & > ( Fn . getSubtarget ( ) ) ; TII = STI -> getInstrInfo ( ) ; TRI = STI -> getRegisterInfo ( ) ; MRI = & Fn . getRegInfo ( ) ; DT = & getAnalysis < MachineDominatorTree > ( ) ; MF = & Fn ; AA = & getAnalysis < AAResultsWrapperPass > ( ) . getAAResults ( ) ; bool Modified = DistributeIncrements ( ) ; for ( MachineBasicBlock & MFI : Fn ) Modified |= RescheduleLoadStoreInstrs


<s> MRI = & Fn . getRegInfo ( ) ; DT = & getAnalysis < MachineDominatorTree > ( ) ; MF = & Fn ; AA = & getAnalysis < AAResultsWrapperPass > ( ) . getAAResults ( ) ; bool Modified = DistributeIncrements ( )


<s> unsigned EIndex = MemOps . size ( ) ; do { const MachineInstr * MI = MemOps [ SIndex ] . MI ; int Offset = MemOps [ SIndex ] . Offset ; const MachineOperand & PMO = getLoadStoreRegOp ( * MI ) ; unsigned PReg = PMO . getReg ( ) ; unsigned PRegNum = PMO . isUndef ( ) ? std :: numeric_limits < unsigned > :: max ( ) : TRI -> getEncodingValue ( PReg ) ; unsigned Latest = SIndex ; unsigned Earliest = SIndex ; unsigned Count = <NUM_LIT> ; bool CanMergeToLSDouble = STI -> isThumb2 ( ) && isNotVFP && isValidLSDoubleOffset ( Offset ) ; if ( STI -> isCortexM3 ( ) && isi32Load ( Opcode ) && PReg == getLoadStoreBaseOp ( * MI ) . getReg ( ) ) CanMergeToLSDouble = false ; bool CanMergeToLSMulti = true ; if ( STI -> hasSlowOddRegister ( ) && ! isNotVFP && ( PRegNum % <NUM_LIT> ) == <NUM_LIT> ) CanMergeToLSMulti = false ; if ( PReg == <STR_LIT> || PReg == <STR_LIT> ) CanMergeToLSMulti = CanMergeToLSDouble = false ; if ( AssumeMisalignedLoadStores && ! mayCombineMisaligned ( * STI , * MI ) ) CanMergeToLSMulti = CanMergeToLSDouble = false ; unsigned Limit ; switch ( Opcode ) { default : Limit = UINT_MAX ; break ; case <STR_LIT> : case <STR_LIT> : Limit = <NUM_LIT> ; break ; } for ( unsigned I = SIndex + <NUM_LIT> ; I < EIndex ; ++ I , ++ Count ) { int NewOffset = MemOps [ I ] . Offset ; if ( NewOffset != Offset + ( int ) Size ) break ; const MachineOperand & MO = getLoadStoreRegOp ( * MemOps [ I ] . MI ) ; unsigned Reg = MO . getReg ( ) ; if ( Reg == <STR_LIT> || Reg


<s> if ( I -> isDebugInstr ( ) || MemOps . count ( & * I ) ) continue ; if ( I -> isCall ( ) || I -> isTerminator ( ) || I -> hasUnmodeledSideEffects ( ) ) return false ; if ( I -> mayStore ( ) || ( ! isLd && I -> mayLoad ( ) ) ) for ( MachineInstr * MemOp : MemOps ) if ( I -> mayAlias ( AA , * MemOp , false ) ) return false ; for ( unsigned j = <NUM_LIT> , NumOps = I -> getNumOperands ( ) ; j != NumOps ; ++ j ) { MachineOperand & MO = I -> getOperand ( j ) ; if ( ! MO . isReg ( ) ) continue ; unsigned Reg = MO . getReg ( ) ; if ( MO . isDef ( ) && TRI -> regsOverlap ( Reg , Base ) ) return false ; if ( Reg != Base && ! MemRegs . count ( Reg ) ) AddedRegPressure . insert ( Reg ) ; } } if ( MemRegs . size ( )


<s> if ( isMemoryOp ( * MBBI ) ) { unsigned Opcode = MBBI -> getOpcode ( ) ; const MachineOperand & MO = MBBI -> getOperand ( <NUM_LIT> ) ; unsigned Reg = MO . getReg ( ) ; unsigned Base = getLoadStoreBaseOp ( * MBBI ) . getReg ( ) ; unsigned PredReg = <NUM_LIT> ; <STR_LIT> Pred = getInstrPredicate ( * MBBI , PredReg ) ; int Offset = getMemoryOpOffset ( * MBBI ) ; if ( CurrBase == <NUM_LIT> ) { CurrBase = Base ; CurrOpc = Opcode ; CurrPred = Pred ; MemOps . push_back ( MemOpQueueEntry ( * MBBI , Offset , Position ) ) ; continue ; } if ( CurrOpc == Opcode && CurrBase == Base && CurrPred == Pred ) { bool Overlap = false ; if ( isLoadSingle ( Opcode ) ) { Overlap = ( Base == Reg ) ; if ( ! Overlap ) { for ( const MemOpQueueEntry & E : MemOps ) { if ( TRI -> regsOverlap ( Reg , E . MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ) { Overlap = true ; break ; } } } } if ( ! Overlap ) { if ( Offset > MemOps . back ( ) . Offset ) { MemOps . push_back ( MemOpQueueEntry ( * MBBI , Offset , Position ) ) ; continue ; } else { MemOpQueue :: iterator MI


<s> MachineBasicBlock :: iterator MergeInstr = findIncDecBefore ( MBBI , Base , Pred , PredReg , Offset ) ; <STR_LIT> Mode = getLoadStoreMultipleSubMode ( Opcode ) ; if ( Mode == <STR_LIT> && Offset == - Bytes ) { Mode = <STR_LIT> ; } else if ( Mode == <STR_LIT> && Offset == - Bytes ) { Mode = <STR_LIT> ; } else { MergeInstr = findIncDecAfter ( MBBI , Base , Pred , PredReg , Offset ) ; if ( ( ( Mode != <STR_LIT> && Mode != <STR_LIT> ) || Offset != Bytes ) && ( ( Mode != <STR_LIT> && Mode != <STR_LIT> ) || Offset != - Bytes ) ) { if ( ! MBB . getParent ( ) -> getFunction ( ) . optForMinSize ( ) || ! BaseKill ) return false ; bool HighRegsUsed = false ; for ( unsigned i = <NUM_LIT> , e = MI -> getNumOperands ( ) ; i != e ; ++ i ) if ( MI -> getOperand ( i ) . getReg ( ) >= <STR_LIT> ) { HighRegsUsed = true ; break ; } if ( ! HighRegsUsed ) MergeInstr = MBB . end ( ) ; else return false ; } } if ( MergeInstr != MBB . end ( ) ) MBB . erase ( MergeInstr ) ; unsigned NewOpc = getUpdatingLSMultipleOpcode ( Opcode , Mode ) ; MachineInstrBuilder MIB = BuildMI ( MBB , MBBI , DL , TII -> get ( NewOpc ) ) . addReg ( Base , getDefRegState ( true ) ) . addReg ( Base , getKillRegState ( BaseKill ) ) . addImm ( Pred ) . addReg ( PredReg ) ; for ( unsigned OpNum = <NUM_LIT> , e = MI -> getNumOperands ( ) ; OpNum != e ; ++ OpNum ) MIB . add ( MI ->


<s> DenseSet < unsigned > KilledRegs ; DenseSet < unsigned > UsedRegs ; for ( const MachineInstr * MI : Cand . Instrs ) { const MachineOperand & MO = getLoadStoreRegOp ( * MI ) ; unsigned Reg = MO . getReg ( ) ; bool IsKill = MO . isKill ( ) ; if ( IsKill ) KilledRegs . insert ( Reg ) ; Regs . push_back ( std :: make_pair ( Reg , IsKill ) ) ; UsedRegs . insert ( Reg ) ; if ( IsLoad ) { for ( const MachineOperand & MO : MI -> implicit_operands ( ) ) { if ( ! MO . isReg ( ) || ! MO . isDef ( ) || MO . isDead ( ) ) continue ; assert ( MO . isImplicit ( ) ) ; unsigned DefReg = MO . getReg ( ) ; if ( is_contained ( ImpDefs , DefReg ) ) continue ; if ( MI -> readsRegister ( DefReg ) ) continue ; ImpDefs . push_back ( DefReg ) ; } } } typedef MachineBasicBlock :: iterator iterator ; MachineInstr * LatestMI = Cand . Instrs [ Cand . LatestMIIdx ] ; iterator InsertBefore = std :: next ( iterator ( LatestMI ) ) ; MachineBasicBlock & MBB = * LatestMI -> getParent ( ) ; unsigned Offset = getMemoryOpOffset ( * First ) ; unsigned Base = getLoadStoreBaseOp ( * First ) . getReg ( ) ; bool BaseKill = LatestMI -> killsRegister ( Base ) ; unsigned PredReg = <NUM_LIT> ; <STR_LIT> Pred = getInstrPredicate ( * First , PredReg ) ; DebugLoc DL = First -> getDebugLoc ( ) ; MachineInstr * Merged = nullptr ; if ( Cand . CanMergeToLSDouble ) Merged = CreateLoadStoreDouble ( MBB , InsertBefore , Offset , Base , BaseKill , Opcode , Pred , PredReg , DL , Regs ) ; if ( ! Merged && Cand . CanMergeToLSMulti ) Merged = CreateLoadStoreMulti ( MBB , InsertBefore , Offset , Base , BaseKill , Opcode , Pred , PredReg , DL , Regs ) ; if ( ! Merged ) return nullptr ; iterator EarliestI ( Cand . Instrs [ Cand . EarliestMIIdx ] ) ; bool EarliestAtBegin = false ; if ( EarliestI == MBB . begin ( ) ) { EarliestAtBegin = true ; }


<s> int Offset ; MachineBasicBlock :: iterator MergeInstr = findIncDecBefore ( MBBI , Base , Pred , PredReg , Offset ) ; <STR_LIT> Mode = getLoadStoreMultipleSubMode ( Opcode ) ; if ( Mode == <STR_LIT> && Offset == - Bytes ) { Mode = <STR_LIT> ; } else if ( Mode == <STR_LIT> && Offset == - Bytes ) { Mode = <STR_LIT> ; } else { MergeInstr = findIncDecAfter ( MBBI , Base , Pred , PredReg , Offset , TRI ) ; if ( ( ( Mode != <STR_LIT> && Mode != <STR_LIT> ) || Offset != Bytes ) && ( ( Mode != <STR_LIT> && Mode != <STR_LIT> ) || Offset != - Bytes ) ) { if ( ! STI -> hasMinSize ( ) || ! BaseKill ) return false ; bool HighRegsUsed = false ; for ( const MachineOperand & MO : llvm :: drop_begin ( MI -> operands ( ) , <NUM_LIT> ) ) if ( MO . getReg ( ) >= <STR_LIT> ) { HighRegsUsed = true ; break ; } if ( ! HighRegsUsed ) MergeInstr = MBB . end ( ) ; else return false ; } } if ( MergeInstr != MBB . end ( ) ) { LLVM_DEBUG ( dbgs ( ) <<


<s> MF = & Fn ; STI = & static_cast < const <ISA_LIT>Subtarget & > ( Fn . getSubtarget ( ) ) ; TL = STI -> getTargetLowering ( ) ; AFI = Fn . getInfo < <ISA_LIT>FunctionInfo > ( ) ; TII = STI -> getInstrInfo ( ) ; TRI = STI -> getRegisterInfo ( ) ; RegClassInfoValid = false ; isThumb2 = AFI -> isThumb2Function ( ) ; isThumb1 = AFI -> isThumbFunction ( ) && ! isThumb2 ; bool Modified = false ; for ( MachineBasicBlock & MBB : Fn ) { Modified |= LoadStoreMultipleOpti ( MBB ) ; if ( STI -> hasV5TOps ( ) ) Modified


<s> bool <ISA_LIT>PreAllocLoadStoreOpt :: runOnMachineFunction ( MachineFunction & Fn ) { if ( AssumeMisalignedLoadStores || skipFunction ( * Fn . getFunction ( ) ) ) return false ; TD = & Fn . getDataLayout ( ) ; STI = & static_cast < const <ISA_LIT>Subtarget & > ( Fn . getSubtarget ( ) ) ; TII = STI -> getInstrInfo ( ) ; TRI = STI -> getRegisterInfo ( ) ; MRI = & Fn


<s> } else if ( Opcode == <STR_LIT> || Opcode == <STR_LIT> ) { NewOpc = <STR_LIT> ; Scale = <NUM_LIT> ; isT2 = true ; } else return false ; if ( ! isT2 && ( Op0 -> getOperand ( <NUM_LIT> ) . getReg ( ) != Op1 -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ) return false ; if ( ! Op0 -> hasOneMemOperand ( ) || ! ( * Op0 -> memoperands_begin ( ) ) -> getValue ( ) || ( * Op0 -> memoperands_begin ( ) ) -> isVolatile ( ) ) return false ; unsigned Align = ( * Op0 -> memoperands_begin ( ) ) -> getAlignment ( ) ; const Function * Func = MF -> getFunction ( ) ; unsigned ReqAlign = STI -> hasV6Ops ( ) ? TD -> getPrefTypeAlignment ( Type :: getInt64Ty ( Func -> getContext ( ) ) ) : <NUM_LIT> ; if ( Align < ReqAlign ) return false ; int OffImm = getMemoryOpOffset ( Op0 ) ; if ( isT2 ) { if ( OffImm < <NUM_LIT> ) { if ( OffImm < - <NUM_LIT> ) return false ; } else { int Limit = ( <NUM_LIT> << <NUM_LIT> ) * Scale ; if ( OffImm >= Limit || ( OffImm & ( Scale - <NUM_LIT> ) ) ) return false ; } Offset = OffImm ; } else { <STR_LIT> AddSub = <STR_LIT>


<s> } else { int Limit = ( <NUM_LIT> << <NUM_LIT> ) * Scale ; if ( OffImm >= Limit || ( OffImm & ( Scale - <NUM_LIT> ) ) ) return false ; } Offset = OffImm ; } else { <STR_LIT> AddSub = <STR_LIT> ; if ( OffImm < <NUM_LIT> ) { AddSub = <STR_LIT> ; OffImm = - OffImm ; } int Limit = ( <NUM_LIT> << <NUM_LIT> ) * Scale ; if ( OffImm >= Limit || ( OffImm & ( Scale - <NUM_LIT> ) ) ) return false ; Offset = <STR_LIT> ( AddSub , OffImm ) ; } EvenReg = Op0 -> getOperand ( <NUM_LIT> ) . getReg ( ) ; OddReg = Op1 -> getOperand ( <NUM_LIT> ) . getReg ( ) ; if ( EvenReg == OddReg ) return false ; BaseReg = Op0 -> getOperand ( <NUM_LIT> ) . getReg ( ) ; if ( ! isT2 ) OffReg = Op0 -> getOperand ( <NUM_LIT> ) . getReg ( ) ; Pred = llvm :: getInstrPredicate ( Op0 , PredReg ) ; dl = Op0 -> getDebugLoc ( ) ; return


<s> static int getLoadStoreMultipleOpcode ( int Opcode ) { switch ( Opcode ) { case <STR_LIT> : ++ NumLDMGened ; return <STR_LIT> ; case <STR_LIT> : ++ NumSTMGened ; return <STR_LIT> ; case <STR_LIT> : case <STR_LIT> : ++ NumLDMGened ; return <STR_LIT> ; case <STR_LIT>


<s> case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : case <STR_LIT>


<s> case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : case <STR_LIT> : return <STR_LIT> ; case


<s> static unsigned getPreIndexedLoadStoreOpcode ( unsigned Opc ) { switch ( Opc ) { case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : case <STR_LIT> : return


<s> static void InsertLDR_STR ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator & MBBI , int OffImm , bool isDef , DebugLoc dl , unsigned NewOpc , unsigned Reg , bool RegDeadKill , bool RegUndef , unsigned BaseReg , bool BaseKill , bool BaseUndef , unsigned OffReg , bool OffKill , bool OffUndef , <STR_LIT> Pred , unsigned PredReg , const TargetInstrInfo * TII , bool isT2 ) { int Offset = OffImm ; if ( ! isT2 ) { if ( OffImm < <NUM_LIT> ) Offset = <STR_LIT> ( <STR_LIT> , -


<s> return Opc == <STR_LIT> || isT2i32Load ( Opc


<s> return Opc == <STR_LIT> || isT2i32Store


<s> if ( MI -> getOpcode ( ) != <STR_LIT> && MI -> getOpcode ( ) != <STR_LIT> && MI -> getOpcode ( ) != <STR_LIT> && MI -> getOpcode ( ) != <STR_LIT> && MI -> getOpcode ( ) != <STR_LIT> ) return false ; if ( Bytes == <NUM_LIT> || ( Limit && Bytes >= Limit ) ) return false ; unsigned Scale = ( MI -> getOpcode ( ) == <STR_LIT> ) ? <NUM_LIT> : <NUM_LIT> ; return ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) == Base && MI -> getOperand ( <NUM_LIT> ) . getReg ( ) == Base && ( MI -> getOperand ( <NUM_LIT> ) . getImm ( ) * Scale ) == Bytes

&& llvm :: getInstrPredicate ( MI , MyPredReg ) == Pred && MyPredReg == PredReg ) ;


<s> unsigned MyPredReg = <NUM_LIT> ; if ( ! MI ) return false ; if ( MI -> getOpcode ( ) != <STR_LIT> && MI -> getOpcode ( ) != <STR_LIT> && MI -> getOpcode ( ) != <STR_LIT> && MI -> getOpcode ( ) != <STR_LIT> && MI -> getOpcode ( ) != <STR_LIT> ) return false ; if ( Bytes == <NUM_LIT> || ( Limit && Bytes >= Limit ) ) return false ; unsigned Scale = ( MI -> getOpcode ( ) == <STR_LIT> ) ? <NUM_LIT> : <NUM_LIT> ; return ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) == Base && MI -> getOperand ( <NUM_LIT> ) . getReg ( ) == Base && ( MI -> getOperand ( <NUM_LIT> ) . getImm

( ) * Scale ) == Bytes && llvm :: getInstrPredicate ( MI , MyPredReg ) == Pred && MyPredReg == PredReg ) ;


<s> if ( TID . isCall ( ) || TID . isTerminator ( ) || TID . hasUnmodeledSideEffects ( ) ) return false ; if ( isLd && TID . mayStore ( ) ) return false ; if ( ! isLd ) { if ( TID . mayLoad ( ) ) return false ; if ( TID . mayStore ( ) ) return false ; } for ( unsigned j = <NUM_LIT> , NumOps = I -> getNumOperands ( ) ; j != NumOps ; ++ j ) { MachineOperand & MO = I -> getOperand ( j ) ; if ( ! MO . isReg ( ) ) continue ; unsigned Reg = MO .


<s> if ( isLd && TID . mayStore ( ) ) return false ; if ( ! isLd ) { if ( TID . mayLoad ( ) ) return false ; if ( TID . mayStore ( ) ) return false ; } for ( unsigned j = <NUM_LIT> , NumOps = I -> getNumOperands ( ) ; j != NumOps ; ++ j ) { MachineOperand & MO = I -> getOperand ( j ) ; if ( ! MO . isReg ( )


<s> if ( isAM2 && <STR_LIT> ( MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ) != <NUM_LIT> ) return false ; if ( isAM5 && <STR_LIT> ( MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ) != <NUM_LIT> ) return false ; if ( isT2i32Load ( Opcode ) || isT2i32Store ( Opcode ) ) if ( MI -> getOperand ( <NUM_LIT> ) . getImm ( ) != <NUM_LIT> ) return false ; bool isLd = isi32Load ( Opcode ) || Opcode == <STR_LIT> || Opcode == <STR_LIT> ; if ( isLd && MI -> getOperand ( <NUM_LIT> ) . getReg ( ) == Base ) return false ; unsigned PredReg = <NUM_LIT> ; <STR_LIT> Pred = llvm :: getInstrPredicate ( MI , PredReg ) ; bool DoMerge = false ; <STR_LIT> AddSub = <STR_LIT> ; unsigned NewOpc = <NUM_LIT> ; unsigned Limit = isAM5 ? <NUM_LIT> : ( isAM2 ? <NUM_LIT> : <NUM_LIT> ) ; MachineBasicBlock :: iterator BeginMBBI = MBB . begin ( ) ; if ( MBBI != BeginMBBI ) { MachineBasicBlock :: iterator PrevMBBI = prior ( MBBI ) ; while ( PrevMBBI != BeginMBBI && PrevMBBI -> isDebugValue ( ) ) -- PrevMBBI ; if ( isMatchingDecrement ( PrevMBBI , Base , Bytes , Limit , Pred , PredReg ) ) { DoMerge = true ; AddSub = <STR_LIT> ; } else if ( ! isAM5 && isMatchingIncrement ( PrevMBBI , Base , Bytes , Limit , Pred , PredReg ) ) { DoMerge = true ; } if ( DoMerge ) { NewOpc = getPreIndexedLoadStoreOpcode ( Opcode ) ; MBB . erase ( PrevMBBI ) ; } } MachineBasicBlock :: iterator EndMBBI = MBB . end ( ) ; if ( ! DoMerge && MBBI != EndMBBI ) { MachineBasicBlock :: iterator NextMBBI = llvm :: next ( MBBI ) ; while ( NextMBBI != EndMBBI && NextMBBI -> isDebugValue ( ) ) ++ NextMBBI ; if ( ! isAM5 && isMatchingDecrement ( NextMBBI , Base , Bytes , Limit , Pred , PredReg ) ) { DoMerge = true ; AddSub = <STR_LIT> ; } else if ( isMatchingIncrement ( NextMBBI , Base , Bytes , Limit , Pred , PredReg ) ) { DoMerge = true ; } if ( DoMerge ) { NewOpc = getPostIndexedLoadStoreOpcode (


<s> bool DoMerge = false ; <STR_LIT> Mode = <STR_LIT> ; for ( unsigned i = <NUM_LIT> , e = MI -> getNumOperands ( ) ; i != e ; ++ i ) { if ( MI -> getOperand ( i ) . getReg ( ) == Base ) return false ; } Mode = <STR_LIT> ( MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ) ; MachineBasicBlock :: iterator BeginMBBI = MBB . begin ( ) ; if ( MBBI != BeginMBBI ) { MachineBasicBlock :: iterator PrevMBBI = prior ( MBBI ) ; while ( PrevMBBI != BeginMBBI && PrevMBBI -> isDebugValue ( ) ) -- PrevMBBI ; if ( Mode == <STR_LIT> && isMatchingDecrement ( PrevMBBI , Base , Bytes , <NUM_LIT> , Pred , PredReg ) ) { Mode = <STR_LIT> ; DoMerge = true ; } else if ( Mode == <STR_LIT> && isMatchingDecrement ( PrevMBBI , Base , Bytes , <NUM_LIT> , Pred , PredReg ) ) { Mode = <STR_LIT> ; DoMerge = true ; } if ( DoMerge ) MBB . erase ( PrevMBBI ) ; } MachineBasicBlock :: iterator EndMBBI = MBB . end ( ) ; if ( ! DoMerge && MBBI != EndMBBI ) { MachineBasicBlock :: iterator NextMBBI = llvm :: next ( MBBI ) ; while ( NextMBBI != EndMBBI && NextMBBI -> isDebugValue ( ) ) ++ NextMBBI ; if ( ( Mode == <STR_LIT> || Mode == <STR_LIT> ) && isMatchingIncrement ( NextMBBI , Base , Bytes , <NUM_LIT> , Pred , PredReg ) ) { DoMerge = true ; } else if ( ( Mode == <STR_LIT> || Mode == <STR_LIT> ) && isMatchingDecrement ( NextMBBI , Base , Bytes , <NUM_LIT> , Pred , PredReg ) ) { DoMerge = true ; } if ( DoMerge ) { if ( NextMBBI ==


<s> unsigned Reg = MO . getReg ( ) ; unsigned RegNum = MO . isUndef ( ) ? UINT_MAX : <ISA_LIT>RegisterInfo :: getRegisterNumbering ( Reg ) ; if ( Reg != <STR_LIT> && NewOffset == Offset + ( int ) Size && ( ( isNotVFP && RegNum > PRegNum ) || ( ( Size < <NUM_LIT> || Count < <NUM_LIT> ) && RegNum == PRegNum + <NUM_LIT> ) ) ) { Offset += Size ; PRegNum = RegNum ; ++ Count ; } else { MergeOpsUpdate ( MBB , MemOps , SIndex , i , insertAfter , SOffset , Base , false , Opcode , Pred , PredReg , Scratch , dl , Merges ) ; MergeLDR_STR ( MBB , i , Base , Opcode , Size , Pred , PredReg , Scratch ,


<s> for ( unsigned i = memOpsEnd , e = memOps . size ( ) ; i != e ; ++ i ) { if ( memOps [ i ] . Position < insertPos && memOps [ i ] . isKill ) { unsigned Reg = memOps [ i ] . Reg ; KilledRegs . insert ( Reg ) ; Killer [ Reg ] = i ; } } SmallVector < std :: pair < unsigned , bool > , <NUM_LIT> > Regs ; for ( unsigned i = memOpsBegin ; i < memOpsEnd ; ++ i ) { unsigned Reg = memOps [ i ] . Reg ; if ( UnavailRegs . count ( Reg ) ) return ; bool isKill = memOps [ i ] . isKill || KilledRegs . count ( Reg ) ; Regs . push_back ( std :: make_pair ( Reg , isKill ) ) ; } MachineBasicBlock :: iterator Loc = memOps [ insertAfter ] . MBBI ; ++ Loc ; if ( ! MergeOps ( MBB , Loc , Offset , Base , BaseKill , Opcode , Pred , PredReg , Scratch , dl , Regs ) ) return ; Merges . push_back ( prior ( Loc ) ) ; for ( unsigned i = memOpsBegin ; i < memOpsEnd ; ++ i ) { if ( Regs [ i - memOpsBegin ] . second ) { unsigned Reg = Regs [ i - memOpsBegin ] . first ; if ( KilledRegs . count ( Reg ) ) { unsigned j = Killer [ Reg ] ; memOps [ j ] . MBBI -> getOperand ( <NUM_LIT> ) . setIsKill ( false ) ; memOps [ j ] . isKill = false ; } } MBB . erase ( memOps [ i ] .


<s> if ( PrevMI -> getOpcode ( ) == <STR_LIT> || PrevMI -> getOpcode ( ) == <STR_LIT> ) { MachineOperand & MO = PrevMI -> getOperand ( PrevMI -> getNumOperands ( ) - <NUM_LIT> ) ; if ( MO . getReg ( ) != <STR_LIT> ) return false ; unsigned NewOpc = isThumb2 ? <STR_LIT> : <STR_LIT> ; PrevMI -> setDesc ( TII -> get


<s> if ( DoMove ) DoMove = IsSafeAndProfitableToMove ( isLd , Base , FirstOp , LastOp , MemOps , MemRegs , TRI ) ; if ( ! DoMove ) { for ( unsigned i = <NUM_LIT> ; i != NumMove ; ++ i ) Ops . pop_back ( ) ; } else { MachineBasicBlock :: iterator InsertPos = isLd ? FirstOp : LastOp ; while ( InsertPos != MBB -> end ( ) && ( MemOps . count ( InsertPos ) || InsertPos -> isDebugValue ( ) ) ) ++ InsertPos ; MachineInstr * Op0 = Ops . back ( ) ; MachineInstr * Op1 = Ops [ Ops . size ( ) - <NUM_LIT> ] ; unsigned EvenReg = <NUM_LIT> , OddReg = <NUM_LIT> ; unsigned BaseReg = <NUM_LIT> , OffReg = <NUM_LIT> , PredReg = <NUM_LIT> ; <STR_LIT> Pred = <STR_LIT> ; bool isT2 = false ; unsigned NewOpc = <NUM_LIT> ; int Offset = <NUM_LIT> ; DebugLoc dl ; if ( NumMove == <NUM_LIT> && CanFormLdStDWord ( Op0 , Op1 , dl , NewOpc , EvenReg , OddReg , BaseReg , OffReg , Offset , PredReg , Pred , isT2 ) ) { Ops . pop_back ( ) ; Ops . pop_back ( ) ; if ( isLd ) { MachineInstrBuilder MIB = BuildMI ( * MBB , InsertPos , dl , TII -> get ( NewOpc ) ) . addReg ( EvenReg , RegState :: Define ) . addReg ( OddReg , RegState :: Define ) . addReg ( BaseReg ) ; if ( ! isT2 ) MIB . addReg ( OffReg ) ; MIB . addImm ( Offset ) . addImm ( Pred ) . addReg ( PredReg ) ; ++ NumLDRDFormed ; } else { MachineInstrBuilder MIB = BuildMI ( * MBB , InsertPos , dl , TII -> get ( NewOpc ) ) . addReg ( EvenReg ) . addReg ( OddReg ) . addReg ( BaseReg ) ; if ( ! isT2 ) MIB . addReg ( OffReg ) ; MIB . addImm ( Offset ) . addImm ( Pred ) . addReg ( PredReg ) ; ++ NumSTRDFormed ; } MBB -> erase ( Op0 ) ; MBB -> erase ( Op1 ) ; MRI -> setRegAllocationHint ( EvenReg , <STR_LIT> , OddReg ) ; MRI -> setRegAllocationHint ( OddReg ,


<s> isThumb2 = AFI -> isThumb2Function ( ) ; bool Modified = false ; for ( MachineFunction :: iterator MFI = Fn . begin ( ) , E = Fn . end ( ) ; MFI != E ; ++ MFI ) { MachineBasicBlock & MBB =


<s> CurrBase = Base ; CurrOpc = Opcode ; CurrPred = Pred ; MemOps . push_back ( MemOpQueueEntry ( * MBBI , Offset , Position ) ) ; continue ; } if ( CurrOpc == Opcode && CurrBase == Base && CurrPred == Pred ) { bool Overlap = false ; if ( isLoadSingle ( Opcode ) ) { Overlap = ( Base == Reg ) ; if ( ! Overlap ) { for ( const MemOpQueueEntry & E : MemOps ) { if ( TRI -> regsOverlap ( Reg , E . MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ) { Overlap = true ; break ; } } } } if ( ! Overlap ) { if ( Offset > MemOps . back ( ) . Offset ) { MemOps . push_back ( MemOpQueueEntry ( * MBBI , Offset , Position ) ) ; continue ; } else { MemOpQueue :: iterator MI , ME ; for ( MI = MemOps . begin ( ) , ME = MemOps . end ( ) ; MI != ME ; ++ MI ) { if ( Offset < MI -> Offset ) { break ; } if ( Offset == MI -> Offset ) { MI = ME ; break ; } } if ( MI != MemOps . end ( ) ) { MemOps . insert ( MI , MemOpQueueEntry ( * MBBI , Offset , Position ) ) ; continue ; } } } } MBBI = I ; -- Position ; } else if ( MBBI -> isDebugInstr ( ) ) { continue ; } else if ( MBBI -> getOpcode ( ) == <STR_LIT> || MBBI -> getOpcode ( ) == <STR_LIT> ) { MergeBaseCandidates . push_back ( & * MBBI ) ; } if ( MemOps . size ( ) > <NUM_LIT> ) { FormCandidates ( MemOps ) ; CurrBase = <NUM_LIT> ; CurrOpc = ~ <NUM_LIT> ; CurrPred = <STR_LIT> ; MemOps . clear ( ) ; } } if ( MemOps . size ( ) > <NUM_LIT> ) FormCandidates (


<s> if ( TRI -> regsOverlap ( Reg , E . MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ) { Overlap = true ; break ; } } } } if ( ! Overlap ) { if ( Offset > MemOps . back ( ) . Offset ) { MemOps . push_back ( MemOpQueueEntry ( * MBBI , Offset , Position ) ) ; continue ; } else { MemOpQueue :: iterator MI , ME ; for ( MI = MemOps . begin ( ) , ME = MemOps . end ( ) ; MI != ME ; ++ MI ) { if ( Offset < MI -> Offset ) { break ; } if ( Offset == MI -> Offset ) { MI = ME ; break ; } } if ( MI != MemOps . end ( ) ) { MemOps . insert ( MI , MemOpQueueEntry ( * MBBI , Offset , Position ) ) ; continue ; } } } } MBBI = I ; -- Position ; } else if ( MBBI -> isDebugInstr ( ) ) { continue ; } else if ( MBBI -> getOpcode ( ) == <STR_LIT> || MBBI -> getOpcode ( ) == <STR_LIT> ) { MergeBaseCandidates . push_back ( & * MBBI ) ; } if ( MemOps . size ( ) > <NUM_LIT> ) { FormCandidates ( MemOps ) ; CurrBase = <NUM_LIT> ; CurrOpc = ~ <NUM_LIT> ; CurrPred = <STR_LIT> ; MemOps . clear ( ) ; } } if ( MemOps . size ( ) > <NUM_LIT> ) FormCandidates ( MemOps ) ; auto LessThan = [ ] ( const MergeCandidate * M0 , const MergeCandidate * M1 ) { return M0 -> InsertPos < M1 -> InsertPos ; } ; llvm :: sort ( Candidates . begin ( ) , Candidates . end ( ) , LessThan ) ; bool Changed = false ; for ( const MergeCandidate * Candidate : Candidates ) { if ( Candidate -> CanMergeToLSMulti || Candidate -> CanMergeToLSDouble ) { MachineInstr * Merged = MergeOpsUpdate ( * Candidate ) ; if ( Merged ) { Changed = true ; unsigned Opcode = Merged -> getOpcode ( ) ; if ( Opcode == <STR_LIT> || Opcode == <STR_LIT> ) MergeBaseUpdateLSDouble ( * Merged ) ; else MergeBaseUpdateLSMultiple ( Merged ) ; } else { for ( MachineInstr * MI : Candidate -> Instrs ) { if ( MergeBaseUpdateLoadStore ( MI ) ) Changed = true ; } } } else { assert ( Candidate -> Instrs . size ( ) == <NUM_LIT> ) ; if ( MergeBaseUpdateLoadStore ( Candidate -> Instrs . front ( ) ) ) Changed = true ; } } Candidates . clear ( )


<s> int PIdx = MI -> findFirstPredOperandIdx ( ) ; if ( PIdx == - <NUM_LIT> ) { PredReg = <NUM_LIT> ; return <STR_LIT> ; } PredReg = MI -> getOperand ( PIdx + <NUM_LIT> ) .


<s> static int getLoadStoreMultipleOpcode ( int Opcode ) { switch ( Opcode ) { case <STR_LIT> : NumLDMGened ++ ; return <STR_LIT> ; case <STR_LIT> : NumSTMGened ++ ; return <STR_LIT> ; case <STR_LIT> : NumFLDMGened ++ ; return <STR_LIT> ; case <STR_LIT> : NumFSTMGened ++ ; return <STR_LIT> ; case


<s> case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; default : abort ( ) ; } return <NUM_LIT>


<s> static inline bool isMatchingDecrement ( MachineInstr * MI , unsigned Base , unsigned Bytes , <STR_LIT> Pred , unsigned PredReg ) { unsigned MyPredReg = <NUM_LIT> ; return ( MI && MI -> getOpcode ( ) == <STR_LIT> && MI -> getOperand ( <NUM_LIT> ) . getReg ( ) == Base && MI -> getOperand ( <NUM_LIT> ) . getReg ( ) == Base && <STR_LIT> ( MI -> getOperand ( <NUM_LIT> ) . getImm

( ) ) == Bytes && getInstrPredicate ( MI , MyPredReg ) == Pred && MyPredReg == PredReg ) ;


<s> return ( MI && MI -> getOpcode ( ) == <STR_LIT> && MI -> getOperand ( <NUM_LIT> ) . getReg ( ) == Base && MI -> getOperand ( <NUM_LIT> ) . getReg ( ) == Base && <STR_LIT> ( MI

-> getOperand ( <NUM_LIT> ) . getImm ( ) ) == Bytes && getInstrPredicate ( MI , MyPredReg ) == Pred && MyPredReg == PredReg ) ;


<s> return ( MI && MI -> getOpcode ( ) == <STR_LIT> && MI -> getOperand ( <NUM_LIT> ) . getReg ( ) == Base && MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ==

Base && <STR_LIT> ( MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ) == Bytes && getInstrPredicate ( MI , MyPredReg ) == Pred && MyPredReg == PredReg ) ;


<s> break ; } else if ( Offset == I -> Offset ) { break ; } } } } } } if ( Advance ) { ++ Position ; ++ MBBI ; } else TryMerge = true ; if ( TryMerge ) { if ( NumMemOps > <NUM_LIT> ) { AdvanceRS ( MBB , MemOps ) ; unsigned Scratch = RS -> FindUnusedReg ( & <STR_LIT> , true ) ; if ( ! Scratch ) Scratch = RS -> FindUnusedReg ( & <STR_LIT> , AFI -> getSpilledCSRegisters ( ) ) ; RS -> forward ( prior ( MBBI ) ) ; SmallVector < MachineBasicBlock :: iterator , <NUM_LIT> > MBBII = MergeLDR_STR ( MBB , <NUM_LIT> , CurrBase , CurrOpc , CurrSize , CurrPred , CurrPredReg , Scratch , MemOps ) ; for ( unsigned i = <NUM_LIT> , e = MBBII . size ( ) ; i < e ; ++ i ) if ( mergeBaseUpdateLSMultiple ( MBB , MBBII [ i ] , Advance , MBBI ) ) NumMerges ++ ; NumMerges += MBBII . size ( ) ; for ( unsigned i = <NUM_LIT> ; i != NumMemOps ; ++ i ) if ( ! MemOps [ i ] . Merged ) if ( mergeBaseUpdateLoadStore ( MBB , MemOps [ i ] . MBBI , TII , Advance , MBBI ) ) NumMerges ++ ; RS -> skipTo ( prior ( MBBI ) ) ; } CurrBase = <NUM_LIT> ; CurrOpc = - <NUM_LIT> ; CurrSize = <NUM_LIT> ; CurrPred = <STR_LIT> ; CurrPredReg = <NUM_LIT> ; if ( NumMemOps ) { MemOps . clear ( ) ; NumMemOps = <NUM_LIT> ; } if ( ! Advance && ! isMemOp && MBBI != E ) { ++ Position ; ++ MBBI ; } } } return NumMerges


<s> MemOpQueueEntry ( int o , int p , MachineBasicBlock :: iterator i ) : Offset ( o )

, Position ( p ) , MBBI ( i ) , Merged ( false ) { }


<s> MemOpQueueEntry ( int o , int p , MachineBasicBlock :: iterator i ) : Offset ( o ) , Position ( p )


<s> MachineBasicBlock :: iterator PrevMBBI = prior ( MBBI ) ; if ( Mode == <STR_LIT> && isMatchingDecrement ( PrevMBBI , Base , Bytes , Pred , PredReg ) ) { MI -> getOperand ( <NUM_LIT> ) . setImm ( <STR_LIT> ( <STR_LIT> , true ) ) ; MBB . erase ( PrevMBBI ) ; return true ; } else if ( Mode == <STR_LIT> && isMatchingDecrement ( PrevMBBI , Base , Bytes , Pred , PredReg ) ) { MI -> getOperand ( <NUM_LIT> ) . setImm ( <STR_LIT> ( <STR_LIT> , true ) ) ; MBB . erase ( PrevMBBI ) ; return true ; } } if ( MBBI != MBB . end ( ) ) { MachineBasicBlock :: iterator NextMBBI = next ( MBBI ) ; if ( ( Mode == <STR_LIT> || Mode == <STR_LIT> ) && isMatchingIncrement ( NextMBBI , Base , Bytes , Pred , PredReg ) ) { MI -> getOperand ( <NUM_LIT> ) . setImm ( <STR_LIT> ( Mode , true ) ) ; if ( NextMBBI == I ) { Advance = true ; ++ I ; } MBB . erase ( NextMBBI ) ; return true ; } else if ( ( Mode == <STR_LIT> || Mode == <STR_LIT> ) && isMatchingDecrement ( NextMBBI , Base , Bytes , Pred , PredReg ) ) { MI -> getOperand ( <NUM_LIT> ) . setImm ( <STR_LIT> ( Mode , true ) ) ; if ( NextMBBI == I ) { Advance = true ; ++ I ; } MBB . erase ( NextMBBI ) ; return true ; } } } else { if ( <STR_LIT> ( MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ) ) return false ; <STR_LIT> Mode = <STR_LIT> ( MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ) ; unsigned Offset = <STR_LIT> ( MI -> getOperand (


<s> if ( Opcode == <STR_LIT> ) NewBase = Regs [ NumRegs - <NUM_LIT> ] . first ; else { NewBase = Scratch ; if ( NewBase == <NUM_LIT> ) return false ; } int BaseOpc = <STR_LIT> ; if ( Offset < <NUM_LIT> ) { BaseOpc = <STR_LIT> ; Offset = - Offset ; } int ImmedOffset = <STR_LIT> ( Offset ) ; if ( ImmedOffset == - <NUM_LIT> ) return false ; BuildMI ( MBB , MBBI , dl , TII -> get ( BaseOpc ) , NewBase ) . addReg ( Base , getKillRegState ( BaseKill ) ) . addImm ( ImmedOffset ) . addImm ( Pred ) . addReg ( PredReg ) . addReg ( <NUM_LIT> ) ; Base = NewBase ; BaseKill = true ; } bool isDPR = Opcode == <STR_LIT> || Opcode == <STR_LIT> ; bool isDef = Opcode == <STR_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> ; Opcode = getLoadStoreMultipleOpcode ( Opcode


<s> for ( MachineFunction :: iterator MFI = Fn . begin ( ) , E = Fn . end ( ) ; MFI != E ; ++ MFI ) { MachineBasicBlock & MBB = * MFI ; Modified |= LoadStoreMultipleOpti ( MBB ) ; Modified |= MergeReturnIntoLDM ( MBB ) ; } delete RS ; return


<s> if ( MemOps [ i ] . Position < Position ) { Position = MemOps [ i ] . Position ; Loc = MemOps [ i ] . MBBI ; } } if ( Loc != MBB . begin ( ) ) RS -> forward ( std :: prev (


<s> if ( MI . definesRegister ( DefReg ) ) LastLivePos = std :: min ( LastLivePos , MIPosition ) ; MachineOperand * UseOp = MI . findRegisterUseOperand ( DefReg ) ; if ( ! UseOp ) continue ; if ( UseOp -> isKill ( ) ) LastLivePos = std :: min ( LastLivePos , MIPosition ) ; Uses [ MIPosition ] = UseOp ; } for ( std :: map < unsigned , MachineOperand * > :: iterator I = Uses . begin ( ) , E = Uses . end ( ) ; I != E ; ++ I


<s> if ( MIPosition <= RangeBegin || MIPosition > RangeEnd ) continue ; if ( MI . definesRegister ( DefReg ) ) LastLivePos = std :: min ( LastLivePos , MIPosition ) ; MachineOperand * UseOp = MI . findRegisterUseOperand ( DefReg ) ; if ( ! UseOp ) continue ; if ( UseOp -> isKill ( ) ) LastLivePos = std :: min ( LastLivePos , MIPosition ) ; Uses [ MIPosition ] = UseOp ; } for ( std :: map < unsigned , MachineOperand * > :: iterator I = Uses . begin ( ) , E = Uses . end ( ) ; I != E ; ++ I ) { if ( I -> first > LastLivePos ) break ; UsesOfImpDefs . push_back ( I ->


<s> } else if ( ! Overlap ) { if ( Clobber ) { TryMerge = true ; Advance = true ; } if ( CurrOpc == Opcode && CurrBase == Base && CurrPred == Pred ) { if ( Offset > MemOps . back ( ) . Offset ) { MemOps . push_back ( MemOpQueueEntry ( Offset , Reg , isKill , Position , MBBI ) ) ; ++ NumMemOps ; Advance = true ; } else { for ( MemOpQueueIter I = MemOps . begin ( ) , E = MemOps . end ( ) ; I != E ; ++ I ) { if ( Offset < I -> Offset ) { MemOps . insert ( I , MemOpQueueEntry ( Offset , Reg , isKill , Position , MBBI ) ) ; ++ NumMemOps ; Advance = true ; break ; } else if ( Offset == I -> Offset ) { break ; } } } } } } if ( MBBI -> isDebugValue ( ) ) { ++ MBBI ; if ( MBBI == E ) TryMerge = true ; } else if ( Advance ) { ++ Position ; ++ MBBI ; if ( MBBI == E ) TryMerge = true ; } else TryMerge = true ; if ( TryMerge ) { if ( NumMemOps > <NUM_LIT> ) { AdvanceRS ( MBB , MemOps ) ; unsigned Scratch = RS -> FindUnusedReg ( & <STR_LIT> ) ; RS -> forward ( std :: prev ( MBBI ) ) ; Merges . clear ( ) ; MergeLDR_STR ( MBB , <NUM_LIT> , CurrBase , CurrOpc , CurrSize , CurrPred , CurrPredReg , Scratch , MemOps , Merges ) ; for ( unsigned i = <NUM_LIT> , e = Merges . size ( ) ; i < e ; ++ i ) if ( MergeBaseUpdateLSMultiple ( MBB , Merges [ i ] , Advance , MBBI ) ) ++ NumMerges ; NumMerges += Merges . size ( ) ; for ( unsigned i = <NUM_LIT> ; i != NumMemOps ; ++ i ) if ( ! MemOps [ i ] . Merged ) if ( MergeBaseUpdateLoadStore ( MBB , MemOps [ i ] . MBBI , TII , Advance , MBBI ) ) ++ NumMerges ; RS -> skipTo ( std :: prev ( MBBI ) ) ; } else if ( NumMemOps == <NUM_LIT> ) { if ( MergeBaseUpdateLoadStore ( MBB , MemOps [ <NUM_LIT> ] . MBBI , TII , Advance , MBBI ) ) { ++ NumMerges ; RS -> forward ( std :: prev ( MBBI ) ) ; } } CurrBase = <NUM_LIT> ; CurrOpc = - <NUM_LIT> ; CurrSize = <NUM_LIT> ; CurrPred = <STR_LIT> ; CurrPredReg = <NUM_LIT> ; if ( NumMemOps ) { MemOps . clear (


<s> DebugLoc dl = MI -> getDebugLoc ( ) ; for ( unsigned i = <NUM_LIT> , e = MI -> getNumOperands ( ) ; i != e ; ++ i ) if ( MI -> getOperand ( i ) . getReg ( ) == Base ) return false ; bool DoMerge = false ; <STR_LIT> Mode = <STR_LIT> ( Opcode ) ; MachineBasicBlock :: iterator BeginMBBI = MBB . begin ( ) ; if ( MBBI != BeginMBBI ) { MachineBasicBlock :: iterator PrevMBBI = std :: prev ( MBBI ) ; while ( PrevMBBI != BeginMBBI && PrevMBBI -> isDebugValue ( ) ) -- PrevMBBI ; if ( Mode == <STR_LIT> && isMatchingDecrement ( PrevMBBI , Base , Bytes , <NUM_LIT> , Pred , PredReg ) ) { Mode = <STR_LIT> ; DoMerge = true ; } else if ( Mode == <STR_LIT> && isMatchingDecrement ( PrevMBBI , Base , Bytes , <NUM_LIT> , Pred , PredReg ) ) { Mode = <STR_LIT> ; DoMerge = true ; } if ( DoMerge ) MBB . erase ( PrevMBBI ) ; } MachineBasicBlock :: iterator EndMBBI = MBB . end ( ) ; if ( ! DoMerge && MBBI != EndMBBI ) { MachineBasicBlock :: iterator NextMBBI = std :: next ( MBBI ) ; while ( NextMBBI != EndMBBI && NextMBBI -> isDebugValue ( ) ) ++ NextMBBI ; if ( ( Mode == <STR_LIT> || Mode == <STR_LIT> ) && isMatchingIncrement ( NextMBBI , Base , Bytes , <NUM_LIT> , Pred , PredReg ) ) { DoMerge = true ; } else if ( ( Mode == <STR_LIT> || Mode == <STR_LIT> ) && isMatchingDecrement ( NextMBBI , Base , Bytes , <NUM_LIT> , Pred , PredReg ) ) { DoMerge = true ; } if ( DoMerge ) { if ( NextMBBI == I ) { Advance = true ; ++ I ; } MBB . erase


<s> } } SmallVector < std :: pair < unsigned , bool > , <NUM_LIT> > Regs ; SmallVector < unsigned , <NUM_LIT> > ImpDefs ; SmallVector < MachineOperand * , <NUM_LIT> > UsesOfImpDefs ; for ( unsigned i = memOpsBegin ; i < memOpsEnd ; ++ i ) { unsigned Reg = memOps [ i ] . Reg ; bool isKill = memOps [ i ] . isKill || KilledRegs . count ( Reg ) ; Regs . push_back ( std :: make_pair ( Reg , isKill ) ) ; for ( MIOperands MO ( memOps [ i ] . MBBI ) ; MO . isValid ( ) ; ++ MO ) { if ( ! MO -> isReg ( ) || ! MO -> isDef ( ) || ! MO -> isImplicit ( ) || MO -> isDead ( ) ) continue ; unsigned DefReg = MO -> getReg ( ) ; if ( std :: find ( ImpDefs . begin ( ) , ImpDefs . end ( ) , DefReg ) == ImpDefs . end ( ) ) ImpDefs . push_back ( DefReg ) ; findUsesOfImpDef ( UsesOfImpDefs , memOps , DefReg , memOps [ i ] .


<s> SmallSet < unsigned , <NUM_LIT> > KilledRegs ; DenseMap < unsigned , unsigned > Killer ; for ( unsigned i = <NUM_LIT> , e = memOps . size ( ) ; i != e ; ++ i ) { if ( i == memOpsBegin ) { i = memOpsEnd ; if ( i == e ) break ; } if ( memOps [ i ] . Position < insertPos && memOps [ i ] . isKill ) { unsigned Reg = memOps [ i ] . Reg ; KilledRegs . insert ( Reg ) ; Killer [ Reg ] = i ; } } SmallVector < std :: pair < unsigned , bool > , <NUM_LIT> > Regs ; SmallVector < unsigned , <NUM_LIT> > ImpDefs ; SmallVector < MachineOperand * , <NUM_LIT> > UsesOfImpDefs ; for ( unsigned i = memOpsBegin ; i < memOpsEnd ; ++ i ) { unsigned Reg = memOps [ i ] . Reg ; bool isKill = memOps [ i ] . isKill || KilledRegs . count ( Reg ) ; Regs . push_back ( std :: make_pair ( Reg , isKill ) ) ; for ( MIOperands MO ( memOps [ i ] . MBBI ) ; MO . isValid ( ) ; ++ MO ) { if ( ! MO -> isReg ( ) || ! MO -> isDef ( ) || ! MO -> isImplicit ( ) || MO -> isDead ( ) ) continue ; unsigned DefReg = MO -> getReg ( ) ; if ( std :: find ( ImpDefs . begin ( ) , ImpDefs . end ( ) , DefReg ) == ImpDefs . end ( ) ) ImpDefs . push_back ( DefReg ) ; findUsesOfImpDef ( UsesOfImpDefs , memOps , DefReg , memOps [ i ] . Position , insertPos ) ; } } MachineBasicBlock :: iterator Loc = memOps [ insertAfter ] . MBBI ; ++ Loc ; if ( ! MergeOps ( MBB , Loc , Offset , Base , BaseKill , Opcode , Pred , PredReg , Scratch , dl , Regs , ImpDefs ) ) return ; Merges . push_back ( std :: prev ( Loc ) ) ; for ( SmallVectorImpl < MachineOperand * > :: iterator I = UsesOfImpDefs . begin ( ) , E = UsesOfImpDefs . end ( ) ; I != E ; ++ I ) ( * I ) -> setIsUndef ( ) ; for ( unsigned i = memOpsBegin ; i < memOpsEnd ; ++ i ) { if ( Regs [ i - memOpsBegin ] .


<s> MachineInstr * PrevMI = std :: prev ( MBBI ) ; unsigned Opcode = PrevMI -> getOpcode ( ) ; if ( Opcode == <STR_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> ) { MachineOperand & MO = PrevMI -> getOperand ( PrevMI -> getNumOperands ( ) - <NUM_LIT> ) ; if ( MO . getReg ( ) != <STR_LIT> ) return false ; unsigned NewOpc = ( isThumb2 ? <STR_LIT> : <STR_LIT> ) ; assert ( ( ( isThumb2 && Opcode == <STR_LIT> ) || Opcode == <STR_LIT> ) && <STR_LIT> ) ; PrevMI -> setDesc ( TII -> get ( NewOpc ) ) ; MO . setReg ( <STR_LIT> ) ; PrevMI -> copyImplicitOps ( * MBB . getParent ( ) , & * MBBI ) ; MBB . erase ( MBBI ) ; return true ; } } return


<s> bool BaseKill = BaseOP . isKill ( ) ; unsigned Bytes = getLSMultipleTransferSize ( MI ) ; unsigned PredReg = <NUM_LIT> ; <STR_LIT> Pred = getInstrPredicate ( MI , PredReg ) ; unsigned Opcode = MI -> getOpcode ( ) ; DebugLoc DL = MI -> getDebugLoc ( ) ; for ( unsigned i = <NUM_LIT> , e = MI -> getNumOperands ( ) ; i != e ; ++ i ) if ( MI -> getOperand ( i ) . getReg ( ) == Base ) return false ; bool DoMerge = false ; <STR_LIT> Mode = getLoadStoreMultipleSubMode ( Opcode ) ; MachineBasicBlock & MBB = * MI -> getParent ( ) ; MachineBasicBlock :: iterator BeginMBBI = MBB . begin ( ) ; MachineBasicBlock :: iterator MBBI ( MI ) ; if ( MBBI != BeginMBBI ) { MachineBasicBlock :: iterator PrevMBBI = std :: prev ( MBBI ) ; while ( PrevMBBI != BeginMBBI && PrevMBBI -> isDebugValue ( ) ) -- PrevMBBI ; if ( Mode == <STR_LIT> && isMatchingDecrement ( PrevMBBI , Base , Bytes , <NUM_LIT> , Pred , PredReg ) ) { Mode =


<s> <STR_LIT> Pred = getInstrPredicate ( First , PredReg ) ; DebugLoc DL = First -> getDebugLoc ( ) ; MachineInstr * Merged = nullptr ; if ( Cand . CanMergeToLSDouble ) Merged = CreateLoadStoreDouble ( MBB , InsertBefore , Offset , Base , BaseKill , Opcode , Pred , PredReg , DL , Regs ) ; if ( ! Merged && Cand . CanMergeToLSMulti ) Merged = CreateLoadStoreMulti ( MBB , InsertBefore , Offset , Base , BaseKill , Opcode , Pred , PredReg , DL , Regs ) ; if ( ! Merged ) return nullptr ; iterator EarliestI ( Cand . Instrs [ Cand . EarliestMIIdx ] ) ; bool EarliestAtBegin = false ; if ( EarliestI == MBB . begin ( ) ) { EarliestAtBegin = true ; } else { EarliestI = std :: prev ( EarliestI ) ; } for ( MachineInstr * MI : Cand . Instrs ) MBB . erase ( MI ) ; if ( EarliestAtBegin ) EarliestI = MBB . begin ( ) ; else EarliestI = std :: next ( EarliestI ) ; auto FixupRange = make_range ( EarliestI , iterator ( Merged ) ) ; if ( isLoadSingle ( Opcode ) ) { for ( MachineInstr & MI : FixupRange ) { for ( unsigned & ImpDefReg : ImpDefs ) { for ( MachineOperand & MO : MI . implicit_operands ( ) ) { if ( ! MO . isReg ( ) || MO . getReg ( ) != ImpDefReg ) continue ; if ( MO . readsReg ( ) ) MO . setIsUndef ( ) ; else if ( MO . isDef ( ) ) ImpDefReg = <NUM_LIT> ; } } } MachineInstrBuilder MIB ( * Merged -> getParent ( ) -> getParent ( ) , Merged ) ; for ( unsigned ImpDef : ImpDefs ) MIB . addReg ( ImpDef , RegState :: ImplicitDefine ) ; } else { assert ( isi32Store ( Opcode ) || Opcode == <STR_LIT> || Opcode == <STR_LIT> ) ; for ( MachineInstr & MI : FixupRange ) { for ( MachineOperand & MO : MI . uses ( ) ) { if ( ! MO . isReg ( ) || ! MO . isKill ( ) ) continue ; if ( KilledRegs . count ( MO . getReg ( ) ) ) MO . setIsKill ( false ) ; } } assert ( ImpDefs . empty ( ) ) ; } return


<s> MRI = & Fn . getRegInfo ( ) ; MF = & Fn ; bool Modified = false ; for ( MachineFunction :: iterator MFI = Fn . begin ( ) , E = Fn . end ( )


<s> case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT>


<s> case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : return <NUM_LIT> ; case <STR_LIT> : case <STR_LIT> : return <NUM_LIT> ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : return ( MI -> getNumOperands ( ) - MI -> getDesc ( ) . getNumOperands ( ) + <NUM_LIT> ) * <NUM_LIT> ; case <STR_LIT> : case <STR_LIT> : return ( MI -> getNumOperands ( ) - MI -> getDesc ( ) . getNumOperands (


<s> break ; } if ( Bytes == <NUM_LIT> || ( Limit && Bytes >= Limit ) ) return false ; unsigned Scale = ( MI -> getOpcode ( ) == <STR_LIT> || MI -> getOpcode ( ) == <STR_LIT> ) ? <NUM_LIT> : <NUM_LIT> ; if ( ! ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) == Base && MI -> getOperand ( <NUM_LIT> ) . getReg ( ) == Base && ( MI -> getOperand ( <NUM_LIT> ) . getImm ( ) * Scale

) == Bytes && getInstrPredicate ( MI , MyPredReg ) == Pred && MyPredReg == PredReg ) ) return false ;


<s> if ( ! ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) == Base && MI -> getOperand ( <NUM_LIT> ) . getReg ( ) == Base && ( MI -> getOperand ( <NUM_LIT> ) .

getImm ( ) * Scale ) == Bytes && getInstrPredicate ( MI , MyPredReg ) == Pred && MyPredReg == PredReg ) ) return false ;


<s> } else if ( Advance ) { ++ Position ; ++ MBBI ; if ( MBBI == E ) TryMerge = true ; } else { TryMerge = true ; } if ( TryMerge ) { if ( NumMemOps > <NUM_LIT> ) { AdvanceRS ( MBB , MemOps ) ; unsigned Scratch = RS -> FindUnusedReg ( isThumb1 ? & <STR_LIT> : & <STR_LIT> ) ; RS -> forward ( std :: prev ( MBBI ) ) ; Merges . clear ( ) ; MergeLDR_STR ( MBB , <NUM_LIT> , CurrBase , CurrOpc , CurrSize , CurrPred , CurrPredReg , Scratch , MemOps , Merges ) ; for ( unsigned i = <NUM_LIT> , e = Merges . size ( ) ; i < e ; ++ i ) if ( MergeBaseUpdateLSMultiple ( MBB , Merges [ i ] , Advance , MBBI ) ) ++ NumMerges ; NumMerges += Merges . size ( ) ; for ( unsigned i = <NUM_LIT> ; i != NumMemOps ; ++ i ) if ( ! MemOps [ i ] . Merged ) if ( MergeBaseUpdateLoadStore ( MBB , MemOps [ i ] . MBBI , TII , Advance , MBBI ) ) ++ NumMerges ; RS -> skipTo ( std :: prev ( MBBI ) ) ; } else if ( NumMemOps == <NUM_LIT> ) { if ( MergeBaseUpdateLoadStore ( MBB , MemOps [ <NUM_LIT> ] . MBBI , TII , Advance , MBBI ) ) { ++ NumMerges ; RS -> forward ( std :: prev ( MBBI ) ) ; } } CurrBase = <NUM_LIT> ; CurrOpc = - <NUM_LIT> ; CurrSize = <NUM_LIT> ; CurrPred = <STR_LIT> ; CurrPredReg = <NUM_LIT> ; if ( NumMemOps ) { MemOps . clear ( ) ; NumMemOps =


<s> bool BaseKill = MI -> getOperand ( <NUM_LIT> ) . isKill ( ) ; unsigned Bytes = getLSMultipleTransferSize ( MI ) ; int Opcode = MI -> getOpcode ( ) ; DebugLoc dl = MI -> getDebugLoc ( ) ; bool isAM5 = ( Opcode == <STR_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> ) ; bool isAM2 = ( Opcode == <STR_LIT> || Opcode == <STR_LIT> ) ; if ( isi32Load ( Opcode ) || isi32Store ( Opcode ) ) if ( MI -> getOperand ( <NUM_LIT> ) . getImm ( ) != <NUM_LIT> ) return false ; if ( isAM5 && <STR_LIT> ( MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ) != <NUM_LIT> ) return false ; bool isLd = isi32Load ( Opcode ) || Opcode == <STR_LIT> || Opcode == <STR_LIT> ; if ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) == Base ) return false ; unsigned PredReg = <NUM_LIT> ; <STR_LIT> Pred = getInstrPredicate ( MI , PredReg ) ; bool DoMerge = false ; <STR_LIT> AddSub = <STR_LIT> ; unsigned NewOpc = <NUM_LIT> ; unsigned Limit = isAM5 ? <NUM_LIT> : ( isAM2 ? <NUM_LIT> : <NUM_LIT> ) ; MachineBasicBlock :: iterator BeginMBBI = MBB . begin ( ) ; if ( MBBI != BeginMBBI ) { MachineBasicBlock :: iterator PrevMBBI = std :: prev ( MBBI ) ; while ( PrevMBBI != BeginMBBI && PrevMBBI -> isDebugValue ( ) ) -- PrevMBBI ; if ( isMatchingDecrement ( PrevMBBI , Base , Bytes , Limit , Pred , PredReg ) ) { DoMerge = true ; AddSub = <STR_LIT> ; } else if ( ! isAM5 && isMatchingIncrement ( PrevMBBI , Base , Bytes , Limit , Pred , PredReg ) ) { DoMerge = true ; } if ( DoMerge ) { NewOpc = getPreIndexedLoadStoreOpcode ( Opcode , AddSub ) ; MBB . erase ( PrevMBBI ) ; } } MachineBasicBlock :: iterator EndMBBI = MBB . end ( ) ; if ( ! DoMerge && MBBI != EndMBBI ) { MachineBasicBlock :: iterator NextMBBI = std :: next ( MBBI ) ; while ( NextMBBI != EndMBBI && NextMBBI -> isDebugValue ( ) ) ++ NextMBBI ; if ( ! isAM5 && isMatchingDecrement ( NextMBBI , Base , Bytes , Limit , Pred , PredReg ) ) { DoMerge = true ; AddSub = <STR_LIT> ; } else if ( isMatchingIncrement ( NextMBBI , Base , Bytes , Limit , Pred , PredReg ) ) { DoMerge = true ; } if ( DoMerge ) { NewOpc = getPostIndexedLoadStoreOpcode ( Opcode , AddSub ) ; if ( NextMBBI == I ) { Advance = true ; ++ I


<s> bool isNotVFP = isi32Load ( Opcode ) || isi32Store ( Opcode ) ; int Offset = MemOps [ SIndex ] . Offset ; int SOffset = Offset ; unsigned insertAfter = SIndex ; MachineBasicBlock :: iterator Loc = MemOps [ SIndex ] . MBBI ; DebugLoc dl = Loc -> getDebugLoc ( ) ; const MachineOperand & PMO = Loc -> getOperand ( <NUM_LIT> ) ; unsigned PReg = PMO . getReg ( ) ; unsigned PRegNum = PMO . isUndef ( ) ? UINT_MAX : TRI -> getEncodingValue ( PReg ) ; unsigned Count = <NUM_LIT> ; unsigned Limit = ~ <NUM_LIT> ; bool BaseKill = false ; switch ( Opcode ) { default : break ; case <STR_LIT> : Limit = <NUM_LIT> ; break ; case <STR_LIT> : Limit = <NUM_LIT> ; break ; case <STR_LIT> : Limit = <NUM_LIT> ; break ; case <STR_LIT> : Limit = <NUM_LIT> ; break ; } for ( unsigned i = SIndex + <NUM_LIT> , e = MemOps . size ( ) ; i != e ; ++ i ) { int NewOffset = MemOps [ i ] . Offset ; const MachineOperand & MO = MemOps [ i ] . MBBI -> getOperand ( <NUM_LIT> ) ; unsigned Reg = MO . getReg ( ) ; unsigned RegNum = MO . isUndef ( ) ? UINT_MAX : TRI -> getEncodingValue ( Reg ) ; if ( Reg != <STR_LIT> && NewOffset == Offset + ( int ) Size && ( ( isNotVFP && RegNum > PRegNum ) || ( ( Count < Limit ) && RegNum == PRegNum + <NUM_LIT> ) )

&& ( ! STI -> isSwift ( ) || isNotVFP || Count != <NUM_LIT> || ! ( PRegNum & <NUM_LIT> ) ) ) {


<s> const MachineOperand & MO = MemOps [ i ] . MBBI -> getOperand ( <NUM_LIT> ) ; unsigned Reg = MO . getReg ( ) ; unsigned RegNum = MO . isUndef ( ) ? UINT_MAX : TRI -> getEncodingValue ( Reg ) ; if ( Reg != <STR_LIT> && NewOffset == Offset + ( int ) Size && ( ( isNotVFP && RegNum > PRegNum ) || ( ( Count < Limit ) && RegNum == PRegNum + <NUM_LIT> ) ) && ( ! STI -> isSwift ( ) || isNotVFP || Count != <NUM_LIT> || ! ( PRegNum & <NUM_LIT> ) ) ) { Offset += Size ; PRegNum = RegNum ; ++ Count ; } else { BaseKill = Loc -> killsRegister ( Base ) ; MergeOpsUpdate ( MBB , MemOps , SIndex , i , insertAfter , SOffset , Base , BaseKill , Opcode , Pred , PredReg , Scratch , dl , Merges ) ; MergeLDR_STR ( MBB , i , Base , Opcode , Size , Pred , PredReg ,


<s> } if ( NumMove <= <NUM_LIT> ) Ops . pop_back ( ) ; else { SmallPtrSet < MachineInstr * , <NUM_LIT> > MemOps ; SmallSet < unsigned , <NUM_LIT> > MemRegs ; for ( int i = NumMove - <NUM_LIT> ; i >= <NUM_LIT> ; -- i ) { MemOps . insert ( Ops [ i ] ) ; MemRegs . insert ( Ops [ i ] -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ; } bool DoMove = ( LastLoc - FirstLoc ) <= NumMove * <NUM_LIT> ; if ( DoMove ) DoMove = IsSafeAndProfitableToMove ( isLd , Base , FirstOp , LastOp , MemOps , MemRegs , TRI ) ; if ( ! DoMove ) { for ( unsigned i = <NUM_LIT> ; i != NumMove ; ++ i ) Ops . pop_back ( ) ; } else { MachineBasicBlock :: iterator InsertPos = isLd ? FirstOp : LastOp ; while ( InsertPos != MBB -> end ( ) && ( MemOps . count ( InsertPos ) || InsertPos -> isDebugValue ( ) ) ) ++ InsertPos ; MachineInstr * Op0 = Ops . back ( ) ; MachineInstr * Op1 = Ops [ Ops . size ( ) - <NUM_LIT> ] ; unsigned EvenReg = <NUM_LIT> , OddReg = <NUM_LIT> ; unsigned BaseReg = <NUM_LIT> , PredReg = <NUM_LIT> ; <STR_LIT> Pred = <STR_LIT> ; bool isT2 = false ; unsigned NewOpc = <NUM_LIT> ; int Offset = <NUM_LIT> ; DebugLoc dl ; if ( NumMove == <NUM_LIT> && CanFormLdStDWord ( Op0 , Op1 , dl , NewOpc , EvenReg , OddReg , BaseReg , Offset , PredReg , Pred , isT2 ) ) { Ops . pop_back ( ) ; Ops . pop_back ( ) ; const MCInstrDesc & MCID = TII -> get ( NewOpc


<s> unsigned EvenReg = <NUM_LIT> , OddReg = <NUM_LIT> ; unsigned BaseReg = <NUM_LIT> , PredReg = <NUM_LIT> ; <STR_LIT> Pred = <STR_LIT> ; bool isT2 = false ; unsigned NewOpc = <NUM_LIT> ; int Offset = <NUM_LIT> ; DebugLoc dl ; if ( NumMove == <NUM_LIT> && CanFormLdStDWord ( Op0 , Op1 , dl , NewOpc , EvenReg , OddReg , BaseReg , Offset , PredReg , Pred , isT2 ) ) { Ops . pop_back ( ) ; Ops . pop_back ( ) ; const MCInstrDesc & MCID = TII -> get ( NewOpc ) ; const TargetRegisterClass * TRC = TII -> getRegClass ( MCID , <NUM_LIT> , TRI , * MF ) ; MRI -> constrainRegClass ( EvenReg , TRC ) ; MRI -> constrainRegClass ( OddReg , TRC ) ; if ( isLd ) { MachineInstrBuilder MIB = BuildMI ( * MBB , InsertPos , dl , MCID ) . addReg ( EvenReg , RegState :: Define ) . addReg ( OddReg , RegState :: Define ) . addReg ( BaseReg ) ; if ( ! isT2 ) MIB . addReg ( <NUM_LIT> ) ; MIB . addImm ( Offset ) . addImm ( Pred ) . addReg ( PredReg ) ; concatenateMemOperands ( MIB , Op0 , Op1 ) ; DEBUG ( dbgs ( ) << <STR_LIT> << * MIB << <STR_LIT> ) ; ++ NumLDRDFormed ; } else { MachineInstrBuilder MIB = BuildMI ( * MBB , InsertPos , dl , MCID ) . addReg ( EvenReg ) . addReg ( OddReg ) . addReg ( BaseReg ) ; if ( ! isT2 ) MIB . addReg ( <NUM_LIT> ) ; MIB . addImm ( Offset ) . addImm ( Pred ) . addReg ( PredReg ) ; concatenateMemOperands ( MIB , Op0 , Op1 ) ; DEBUG ( dbgs ( ) << <STR_LIT> << * MIB << <STR_LIT> ) ; ++ NumSTRDFormed ; } MBB -> erase ( Op0 ) ; MBB -> erase ( Op1 ) ; MRI -> setRegAllocationHint ( EvenReg , <STR_LIT> , OddReg ) ; MRI -> setRegAllocationHint ( OddReg , <STR_LIT> , EvenReg ) ; } else { for ( unsigned i = <NUM_LIT> ; i != NumMove ; ++ i ) { MachineInstr * Op = Ops . back ( ) ; Ops . pop_back ( ) ; MBB -> splice ( InsertPos , MBB , Op ) ; } } NumLdStMoved += NumMove


<s> isThumb2 = AFI -> isThumb2Function ( ) ; isThumb1 = AFI -> isThumbFunction ( ) && ! isThumb2 ; bool Modified = false ; for ( MachineFunction :: iterator MFI = Fn . begin ( ) , E = Fn . end ( ) ; MFI != E ; ++ MFI ) { MachineBasicBlock & MBB


<s> TRI = STI -> getRegisterInfo ( ) ; RS = new RegScavenger ( ) ; isThumb2 = AFI -> isThumb2Function ( ) ; isThumb1 = AFI -> isThumbFunction ( ) && ! isThumb2 ; bool Modified = false ; for ( MachineFunction :: iterator MFI = Fn . begin ( ) , E = Fn . end ( ) ; MFI != E ; ++ MFI


<s> unsigned Opc = MBBI -> getOpcode ( ) ; if ( MBBI -> readsRegister ( Base ) ) { int Offset ; bool IsLoad = Opc == <STR_LIT> || Opc == <STR_LIT> || Opc == <STR_LIT> ; bool IsStore = Opc == <STR_LIT> || Opc == <STR_LIT> || Opc == <STR_LIT> ; if ( IsLoad || IsStore ) { MachineOperand & MO = MBBI -> getOperand ( MBBI -> getDesc ( ) . getNumOperands ( ) - <NUM_LIT> ) ; Offset = MO . getImm ( ) - WordOffset * getImmScale ( Opc ) ; unsigned InstrSrcReg = MBBI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; if ( Offset >= <NUM_LIT> && ! ( IsStore && InstrSrcReg == Base ) ) MO . setImm ( Offset ) ; else InsertSub = true ; } else if ( ( Opc == <STR_LIT> || Opc == <STR_LIT> ) && ! definesCPSR ( MBBI ) ) { MachineOperand & MO = MBBI -> getOperand ( MBBI -> getDesc ( ) . getNumOperands ( ) - <NUM_LIT> ) ; Offset = ( Opc == <STR_LIT> ) ? MO . getImm ( ) + WordOffset * <NUM_LIT> : MO . getImm ( ) - WordOffset * <NUM_LIT> ; if ( Offset >= <NUM_LIT> && TL -> isLegalAddImmediate ( Offset ) ) { MO . setImm ( Offset ) ; return ; } else { InsertSub = true ; } } else { InsertSub = true ; } } else if ( definesCPSR ( MBBI ) || MBBI -> isCall ( ) || MBBI


<s> } case <STR_LIT> : ++ NumSTMGened ; switch ( Mode ) { default : llvm_unreachable ( <STR_LIT> ) ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; } case <STR_LIT> : ++ NumLDMGened ; switch ( Mode ) { default : llvm_unreachable ( <STR_LIT> ) ; case <STR_LIT> : return <STR_LIT> ; } case <STR_LIT> : ++ NumSTMGened ; switch ( Mode ) { default : llvm_unreachable ( <STR_LIT> ) ; case <STR_LIT> : return <STR_LIT> ; } case <STR_LIT> : case <STR_LIT> : ++ NumLDMGened ; switch ( Mode ) { default : llvm_unreachable ( <STR_LIT> ) ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; } case <STR_LIT> : case <STR_LIT> : ++ NumSTMGened ; switch ( Mode ) { default : llvm_unreachable ( <STR_LIT> ) ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; } case <STR_LIT> : ++ NumVLDMGened ; switch ( Mode ) { default : llvm_unreachable ( <STR_LIT> ) ; case <STR_LIT> :


<s> case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; } case <STR_LIT> : ++ NumSTMGened ; switch ( Mode ) { default : llvm_unreachable ( <STR_LIT> ) ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; } case <STR_LIT> : ++ NumLDMGened ; switch ( Mode ) { default : llvm_unreachable ( <STR_LIT> ) ; case <STR_LIT> : return <STR_LIT> ; } case <STR_LIT> : ++ NumSTMGened ; switch ( Mode ) { default : llvm_unreachable ( <STR_LIT> ) ; case <STR_LIT> : return <STR_LIT> ; } case <STR_LIT> : case <STR_LIT> : ++ NumLDMGened ; switch ( Mode ) { default : llvm_unreachable ( <STR_LIT> ) ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; } case <STR_LIT> : case <STR_LIT> : ++ NumSTMGened ; switch ( Mode ) { default : llvm_unreachable ( <STR_LIT> ) ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; } case <STR_LIT> : ++ NumVLDMGened ; switch ( Mode ) { default : llvm_unreachable ( <STR_LIT> ) ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <NUM_LIT> ; } case <STR_LIT> : ++ NumVSTMGened ; switch ( Mode ) { default : llvm_unreachable ( <STR_LIT> ) ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <NUM_LIT> ; } case <STR_LIT> : ++ NumVLDMGened ; switch ( Mode )


<s> case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : return ( MI -> getNumOperands ( ) - MI -> getDesc ( ) . getNumOperands ( ) + <NUM_LIT> ) * <NUM_LIT> ; case <STR_LIT> : case <STR_LIT> : return ( MI -> getNumOperands ( ) - MI -> getDesc ( ) . getNumOperands ( )


<s> bool isAM3 = Opcode == <STR_LIT> || Opcode == <STR_LIT> ; unsigned NumOperands = MI -> getDesc ( ) . getNumOperands ( ) ; unsigned OffField = MI -> getOperand ( NumOperands - <NUM_LIT> ) . getImm ( ) ; if ( Opcode == <STR_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> ) return OffField ; if ( Opcode == <STR_LIT> || Opcode == <STR_LIT> ) return OffField * <NUM_LIT> ; int Offset = isAM3 ? <STR_LIT> ( OffField ) : <STR_LIT> (


<s> if ( ! STI -> hasV5TEOps ( ) ) return false ; unsigned Scale = <NUM_LIT> ; unsigned Opcode = Op0 -> getOpcode ( ) ; if ( Opcode == <STR_LIT> ) NewOpc = <STR_LIT> ; else if ( Opcode == <STR_LIT> ) NewOpc = <STR_LIT> ; else if ( Opcode == <STR_LIT> || Opcode == <STR_LIT> ) { NewOpc = <STR_LIT> ; Scale = <NUM_LIT> ; isT2 = true ; } else if ( Opcode == <STR_LIT> || Opcode == <STR_LIT> ) { NewOpc = <STR_LIT> ; Scale = <NUM_LIT> ; isT2 = true ; } else return false ; if ( ! Op0 -> hasOneMemOperand ( ) || ! ( * Op0 -> memoperands_begin ( ) ) -> getValue ( ) || ( * Op0 -> memoperands_begin ( ) ) -> isVolatile ( ) ) return false ; unsigned Align = ( * Op0 -> memoperands_begin ( ) ) -> getAlignment ( ) ; const Function * Func = MF -> getFunction ( ) ; unsigned ReqAlign = STI -> hasV6Ops ( ) ? TD -> getABITypeAlignment ( Type :: getInt64Ty ( Func -> getContext ( ) ) ) : <NUM_LIT> ; if ( Align < ReqAlign ) return false ; int OffImm = getMemoryOpOffset ( Op0 ) ; if ( isT2 ) { if ( OffImm < <NUM_LIT> ) { if ( OffImm < - <NUM_LIT> ) return false ; }


<s> case <STR_LIT> : ++ NumSTMGened ; switch ( Mode ) { default : llvm_unreachable ( <STR_LIT> ) ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; } break ; case <STR_LIT> : case <STR_LIT> : ++ NumLDMGened ; switch ( Mode ) { default : llvm_unreachable ( <STR_LIT> ) ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; } break ; case <STR_LIT> : case <STR_LIT> : ++ NumSTMGened ; switch ( Mode ) { default : llvm_unreachable ( <STR_LIT> ) ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; } break ; case <STR_LIT> : ++ NumVLDMGened ; switch ( Mode ) { default : llvm_unreachable ( <STR_LIT> ) ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return <STR_LIT> ; } break ; case <STR_LIT> : ++ NumVSTMGened ; switch ( Mode ) { default : llvm_unreachable ( <STR_LIT> ) ; case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : return


<s> return <NUM_LIT> ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : return ( MI -> getNumOperands ( ) - MI -> getDesc ( ) . getNumOperands ( ) + <NUM_LIT> ) * <NUM_LIT> ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT>


<s> switch ( MI -> getOpcode ( ) ) { default : return <NUM_LIT> ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : return <NUM_LIT> ; case <STR_LIT> : case <STR_LIT> : return <NUM_LIT> ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT>