<s> return Mode == <STR_LIT> ? <STR_LIT> : <STR_LIT> ; case <STR_LIT> : return Mode == <STR_LIT> ? <STR_LIT> : <STR_LIT> ; case <STR_LIT> : return Mode == <STR_LIT> ? <STR_LIT> : <STR_LIT> ; case <STR_LIT> : return Mode == <STR_LIT> ? <STR_LIT> : <STR_LIT> ; case <STR_LIT> : case <STR_LIT> : return <STR_LIT> ; case <STR_LIT> : case <STR_LIT> : return <STR_LIT> ; default : llvm_unreachable ( <STR_LIT> ) ; } return


<s> 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 , AddSub ) ; 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 ( Opcode , AddSub ) ; if ( NextMBBI == I ) { Advance = true ; ++ I ; } MBB . erase ( NextMBBI ) ; } } if ( ! DoMerge ) return false ; unsigned Offset = <NUM_LIT> ; if ( isAM2 ) Offset = <STR_LIT> ( AddSub , Bytes , <STR_LIT> ) ; else if ( ! isAM5 ) Offset = AddSub == <STR_LIT> ? - Bytes : Bytes ; if ( isAM5 ) { MachineOperand & MO = MI -> getOperand ( <NUM_LIT>


<s> 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 ( NextMBBI ) ; } } if ( ! DoMerge ) return false ; 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 . addOperand ( MI -> getOperand ( OpNum ) ) ; ( * MIB ) . setMemRefs ( MI -> memoperands_begin ( ) , MI -> memoperands_end (


<s> 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 : get<ISA_LIT>RegisterNumbering ( PReg ) ; unsigned Count = <NUM_LIT> ; 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


<s> bool <ISA_LIT>LoadStoreOpt :: MergeOps ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator MBBI , int Offset , unsigned Base , bool BaseKill , int Opcode , <STR_LIT> Pred , unsigned PredReg , unsigned Scratch , DebugLoc dl , SmallVector < std :: pair < unsigned , bool > , <NUM_LIT> > & Regs ) { unsigned NumRegs = Regs . size ( ) ; if ( NumRegs <= <NUM_LIT> ) return false ; <STR_LIT> Mode = <STR_LIT> ; bool isNotVFP = isi32Load ( Opcode ) || isi32Store ( Opcode ) ; bool haveIBAndDA = isNotVFP && ! isThumb2 ; if ( Offset == <NUM_LIT> && haveIBAndDA ) Mode = <STR_LIT> ; else if ( Offset == - <NUM_LIT> * ( int ) NumRegs + <NUM_LIT> && haveIBAndDA ) Mode = <STR_LIT> ; else if ( Offset == - <NUM_LIT> * ( int ) NumRegs && isNotVFP ) Mode = <STR_LIT> ; else if ( Offset != <NUM_LIT> ) { if ( NumRegs <= <NUM_LIT> ) return false ; unsigned NewBase ; if ( isi32Load ( Opcode ) ) NewBase = Regs [ NumRegs - <NUM_LIT> ] . first ; else { NewBase = Scratch ; if ( NewBase == <NUM_LIT> ) return false ; } int BaseOpc = ! isThumb2 ? <STR_LIT> : ( ( Base == <STR_LIT> ) ? <STR_LIT> : <STR_LIT> ) ; if ( Offset < <NUM_LIT> ) { BaseOpc = ! isThumb2 ? <STR_LIT> : ( ( Base == <STR_LIT> ) ? <STR_LIT> : <STR_LIT> ) ; Offset = - Offset ; } int ImmedOffset = isThumb2 ? <STR_LIT> ( Offset ) : <STR_LIT> ( Offset ) ; if ( ImmedOffset == - <NUM_LIT> ) return false ; BuildMI ( MBB , MBBI , dl , TII -> get ( BaseOpc ) , NewBase ) . addReg ( Base , getKillRegState ( BaseKill ) ) . addImm ( Offset ) . addImm ( Pred ) . addReg ( PredReg ) . addReg ( <NUM_LIT> ) ; Base =


<s> unsigned NewOpc = ( Opcode == <STR_LIT> ) ? <STR_LIT> : <STR_LIT> ; if ( isLd ) { BuildMI ( MBB , MBBI , MBBI -> getDebugLoc ( ) , TII -> get ( NewOpc ) ) . addReg ( BaseReg , getKillRegState ( BaseKill ) ) . addImm ( <STR_LIT> ( <STR_LIT> ) ) . 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 ( <STR_LIT> ( <STR_LIT> ) ) . addImm ( Pred ) . addReg ( PredReg ) . addReg ( EvenReg , getKillRegState ( EvenDeadKill ) ) . addReg ( OddReg , getKillRegState ( OddDeadKill ) ) ; ++ NumSTRD2STM ; } } else { unsigned NewOpc = ( Opcode == <STR_LIT> ) ? <STR_LIT> : <STR_LIT> ; DebugLoc dl = MBBI -> getDebugLoc ( ) ; if ( isLd && ( BaseKill || OffKill ) && ( TRI -> regsOverlap ( EvenReg , BaseReg ) || ( OffReg && TRI -> regsOverlap ( EvenReg , OffReg ) ) ) ) { assert ( ! TRI -> regsOverlap ( OddReg , BaseReg ) && ( ! OffReg || ! TRI -> regsOverlap ( OddReg , OffReg ) ) ) ; InsertLDR_STR ( MBB , MBBI , OffImm + <NUM_LIT> , isLd , dl , NewOpc , OddReg , OddDeadKill , BaseReg , false , OffReg , false , Pred , PredReg , TII ) ; InsertLDR_STR ( MBB , MBBI , OffImm , isLd , dl , NewOpc , EvenReg , EvenDeadKill , BaseReg , BaseKill , OffReg , OffKill , Pred , PredReg , TII ) ; } else { InsertLDR_STR ( MBB , MBBI , OffImm , isLd , dl , NewOpc , EvenReg , EvenDeadKill , BaseReg , false , OffReg , false , Pred , PredReg , TII ) ; InsertLDR_STR ( MBB , MBBI , OffImm + <NUM_LIT> , isLd , dl , NewOpc , OddReg , OddDeadKill , BaseReg , BaseKill , OffReg , OffKill , Pred , PredReg , TII ) ; } if ( isLd ) ++ NumLDRD2LDR ; else ++ NumSTRD2STR ; } MBBI = prior


<s> } } else { unsigned NewOpc = ( Opcode == <STR_LIT> ) ? <STR_LIT> : <STR_LIT> ; DebugLoc dl = MBBI -> getDebugLoc ( ) ; if ( isLd && ( BaseKill || OffKill ) && ( TRI -> regsOverlap ( EvenReg , BaseReg ) || ( OffReg && TRI -> regsOverlap ( EvenReg , OffReg ) ) ) ) { assert ( ! TRI -> regsOverlap ( OddReg , BaseReg ) && ( ! OffReg || ! TRI -> regsOverlap ( OddReg , OffReg ) ) ) ; InsertLDR_STR ( MBB , MBBI , OffImm + <NUM_LIT> , isLd , dl , NewOpc , OddReg , OddDeadKill , BaseReg , false , OffReg , false , Pred , PredReg , TII ) ; InsertLDR_STR ( MBB , MBBI , OffImm , isLd , dl , NewOpc , EvenReg , EvenDeadKill , BaseReg , BaseKill , OffReg , OffKill , Pred , PredReg , TII ) ; } else { InsertLDR_STR ( MBB , MBBI , OffImm , isLd , dl , NewOpc , EvenReg , EvenDeadKill , BaseReg , false , OffReg , false , Pred , PredReg , TII ) ; InsertLDR_STR ( MBB , MBBI , OffImm + <NUM_LIT> , isLd , dl , NewOpc , OddReg , OddDeadKill , BaseReg , BaseKill , OffReg , OffKill , Pred , PredReg , TII ) ; } if ( isLd ) ++ NumLDRD2LDR ; else ++ NumSTRD2STR ; } MBBI = prior ( MBBI ) ; MBB . erase


<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> : case <STR_LIT> : NumSTMGened ++ ; return <STR_LIT> ; case <STR_LIT> : NumFLDMGened ++ ; return <STR_LIT> ; case <STR_LIT> : NumFSTMGened ++ ; return <STR_LIT> ; case <STR_LIT> : NumFLDMGened ++ ; return <STR_LIT> ; case <STR_LIT> : NumFSTMGened ++ ; return


<s> static unsigned getPostIndexedLoadStoreOpcode ( 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 <STR_LIT> ; case <STR_LIT> : case <STR_LIT> : return <STR_LIT> ; default : llvm_unreachable


<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 <STR_LIT> ; case <STR_LIT> : case <STR_LIT> : return


<s> else Offset = <STR_LIT> ( <STR_LIT> , OffImm , <STR_LIT> ) ; if ( isDef ) BuildMI ( MBB , MBBI , MBBI -> getDebugLoc ( ) , TII -> get ( NewOpc ) ) . addReg ( Reg , getDefRegState ( true ) | getDeadRegState ( RegDeadKill ) ) . addReg (

BaseReg , getKillRegState ( BaseKill ) ) . addReg ( OffReg , getKillRegState ( OffKill ) ) . addImm ( Offset ) . addImm ( Pred ) . addReg ( PredReg ) ;


<s> if ( isDef ) BuildMI ( MBB , MBBI , MBBI -> getDebugLoc ( ) , TII -> get ( NewOpc ) ) . addReg ( Reg , getDefRegState ( true ) | getDeadRegState ( RegDeadKill ) ) . addReg ( BaseReg , getKillRegState ( BaseKill ) ) . addReg ( OffReg , getKillRegState ( OffKill ) ) . addImm ( Offset ) . addImm ( Pred ) . addReg ( PredReg ) ; else BuildMI ( MBB , MBBI , MBBI -> getDebugLoc ( ) , TII -> get ( NewOpc ) ) . addReg ( Reg , getKillRegState ( RegDeadKill ) ) . addReg ( BaseReg ,


<s> 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> I != E ; ++ I ) { if ( Offset < I -> Offset ) { MemOps . insert ( I , MemOpQueueEntry ( Offset , Position , MBBI ) ) ; NumMemOps ++ ; Advance = true ; 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> ) ; RS -> forward ( prior ( 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 ( prior ( MBBI ) ) ; } else if ( NumMemOps == <NUM_LIT> ) { if ( MergeBaseUpdateLoadStore ( MBB , MemOps [ <NUM_LIT> ] . MBBI , TII , Advance , MBBI ) ) { ++ NumMerges ; RS -> forward ( prior ( MBBI ) ) ; } } CurrBase = <NUM_LIT> ; CurrOpc = -


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

( MO . getReg ( ) , getKillRegState ( MO . isKill ( ) ) ) ;


<s> unsigned Reg = MemOps [ i ] . MBBI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; unsigned RegNum = <ISA_LIT>RegisterInfo :: getRegisterNumbering ( Reg ) ; isKill = MemOps [ i ] . MBBI -> getOperand ( <NUM_LIT> ) . isKill ( ) ; if ( NewOffset == Offset + ( int ) Size && ( ( isAM4 && RegNum > PRegNum ) || RegNum == PRegNum + <NUM_LIT> ) ) { Offset += Size ; Regs . push_back ( std :: make_pair ( Reg , isKill ) ) ; PRegNum = RegNum ; } else { if ( MergeOps ( MBB , ++ Loc , SOffset , Base , false , Opcode , Pred , PredReg , Scratch , dl , Regs ) ) { Merges . push_back ( prior ( Loc ) ) ; for ( unsigned j = SIndex ; j < i ; ++ j ) { MBB . erase ( MemOps [ j ] . MBBI ) ; MemOps [ j ] . Merged = true ; } } MergeLDR_STR ( MBB , i , Base , Opcode , Size , Pred , PredReg , Scratch , MemOps , Merges ) ; return ; } if ( MemOps [ i ] . Position > Pos ) { Pos = MemOps [ i ] . Position ; Loc = MemOps [ i ] . MBBI ; } } bool BaseKill = Loc -> findRegisterUseOperandIdx ( Base , true ) != - <NUM_LIT> ; if ( MergeOps ( MBB , ++ Loc , SOffset , Base , BaseKill , Opcode , Pred , PredReg , Scratch , dl , Regs ) ) { Merges . push_back ( prior


<s> DebugLoc dl = Loc -> getDebugLoc ( ) ; unsigned PReg = Loc -> getOperand ( <NUM_LIT> ) . getReg ( ) ; unsigned PRegNum = <ISA_LIT>RegisterInfo :: getRegisterNumbering ( PReg ) ; bool isKill = Loc -> getOperand ( <NUM_LIT> ) . isKill ( ) ; SmallVector < std :: pair < unsigned , bool > , <NUM_LIT> > Regs ; Regs . push_back ( std :: make_pair ( PReg , isKill ) ) ; for ( unsigned i = SIndex + <NUM_LIT> , e = MemOps . size ( ) ; i != e ; ++ i ) { int NewOffset = MemOps [ i ] . Offset ; unsigned Reg = MemOps [ i ] . MBBI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; unsigned RegNum = <ISA_LIT>RegisterInfo :: getRegisterNumbering ( Reg ) ; isKill = MemOps [ i ] . MBBI -> getOperand ( <NUM_LIT> ) . isKill ( ) ; if ( NewOffset == Offset + ( int ) Size && ( ( isAM4 && RegNum > PRegNum ) || RegNum == PRegNum + <NUM_LIT> ) ) { Offset += Size ; Regs . push_back ( std :: make_pair ( Reg , isKill ) ) ; PRegNum = RegNum ; } else { if ( MergeOps ( MBB , ++ Loc , SOffset , Base , false , Opcode , Pred , PredReg , Scratch , dl , Regs ) ) { Merges . push_back ( prior ( Loc ) ) ; for ( unsigned j = SIndex ; j < i ; ++ j ) { MBB . erase ( MemOps [ j ] . MBBI ) ; MemOps [ j ] . Merged = true ; } } MergeLDR_STR ( MBB , i , Base , Opcode , Size , Pred , PredReg , Scratch , MemOps , Merges ) ; return ; } if ( MemOps [ i ] . Position > Pos ) { Pos = MemOps [ i ] . Position ; Loc = MemOps [ i ] . MBBI ; } } bool BaseKill = Loc -> findRegisterUseOperandIdx ( Base , true ) != - <NUM_LIT> ; if ( MergeOps ( MBB , ++ Loc , SOffset , Base , BaseKill , Opcode , Pred , PredReg , Scratch , dl , Regs ) ) { Merges . push_back ( prior ( Loc ) ) ; for ( unsigned i = SIndex , e = MemOps . size ( ) ; i != e ; ++ i ) { MBB . erase ( MemOps [ i ] . MBBI


<s> if ( MBB . empty ( ) ) return false ; MachineBasicBlock :: iterator MBBI = prior ( MBB . end ( ) ) ; if ( MBBI != MBB . begin ( ) && ( MBBI -> getOpcode ( ) == <STR_LIT> || MBBI -> getOpcode ( ) == <STR_LIT> ) ) { MachineInstr * PrevMI = prior ( MBBI ) ; 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 ( NewOpc ) ) ; MO . setReg ( <STR_LIT> ) ; MBB . erase ( MBBI ) ; return true ; } } return false


<s> break ; } MI2LocMap [ MI ] = Loc ++ ; if ( ! isMemoryOp ( MI ) ) continue ; unsigned PredReg = <NUM_LIT> ; if ( llvm :: getInstrPredicate ( MI , PredReg ) != <STR_LIT> ) continue ; int Opcode = MI -> getOpcode ( ) ; bool isLd = Opcode == <STR_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> ; 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 { SmallVector < MachineInstr * , <NUM_LIT> > MIs ; MIs . push_back ( MI ) ; Base2LdsMap [ Base ] = MIs ; 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


<s> LastOpcode = Opcode ; if ( ++ NumMove == <NUM_LIT> ) break ; } 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 ; 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> ; unsigned NewOpc = <NUM_LIT> ; unsigned Offset = <NUM_LIT> ; DebugLoc dl ; if ( NumMove == <NUM_LIT> && CanFormLdStDWord ( Op0 , Op1 , dl , NewOpc , EvenReg , OddReg , BaseReg , OffReg , Offset , PredReg , Pred ) ) { Ops . pop_back ( ) ; Ops . pop_back ( ) ; if ( isLd ) { BuildMI ( * MBB , InsertPos , dl , TII -> get ( NewOpc ) ) . addReg ( EvenReg , RegState :: Define ) . addReg ( OddReg , RegState :: Define ) . addReg ( BaseReg ) . addReg ( <NUM_LIT> ) . addImm ( Offset ) . addImm ( Pred ) . addReg ( PredReg ) ; ++ NumLDRDFormed


<s> bool <ISA_LIT>PreAllocLoadStoreOpt :: runOnMachineFunction ( MachineFunction & Fn ) { TD = Fn . getTarget ( ) . getTargetData ( ) ; TII = Fn . getTarget ( ) . getInstrInfo ( ) ; TRI = Fn . getTarget ( ) . getRegisterInfo


<s> 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> ( OffField ) *


<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 ] . Position ) insertAfter = i ;


<s> if ( ! TL -> isLegalAddImmediate ( Offset ) ) return false ; if ( isThumb1 ) { if ( Base != NewBase ) { BuildMI ( MBB , MBBI , dl , TII -> get ( <STR_LIT> ) , NewBase ) . addReg ( Base , getKillRegState ( BaseKill ) ) . addImm ( Pred ) . addReg ( PredReg ) ; } AddDefaultT1CC ( BuildMI ( MBB , MBBI , dl , TII -> get ( BaseOpc ) , NewBase ) ) . addReg ( NewBase , getKillRegState ( true ) ) . addImm ( Offset ) . addImm ( Pred ) . addReg ( PredReg ) ; } else { BuildMI ( MBB , MBBI , dl , TII -> get ( BaseOpc ) , NewBase ) . addReg ( Base , getKillRegState ( BaseKill ) ) . addImm ( Offset ) . addImm ( Pred ) . addReg ( PredReg ) . addReg ( <NUM_LIT> ) ; } Base = NewBase ; BaseKill = true ; } bool isDef = ( isi32Load ( Opcode ) || Opcode == <STR_LIT> || Opcode == <STR_LIT> ) ; Opcode = getLoadStoreMultipleOpcode ( Opcode , Mode ) ; if ( ! Opcode ) return false ; bool Writeback = isThumb1 ; if ( Opcode == <STR_LIT> && isThumb1 ) for ( unsigned I = <NUM_LIT> ; I < NumRegs ; ++ I ) if ( Base == Regs [ I ] . first ) { Writeback = false ; break ; } MachineInstrBuilder MIB ; if ( Writeback ) { if ( Opcode == <STR_LIT> ) Opcode = <STR_LIT> ; MIB = BuildMI ( MBB , MBBI , dl , TII -> get ( Opcode ) ) ; MIB . addReg ( Base , getDefRegState ( true ) ) . addReg ( Base , getKillRegState ( BaseKill ) ) ; if ( ! BaseKill ) UpdateBaseRegUses ( MBB , MBBI , dl , Base , NumRegs , Pred , PredReg ) ; } else { MIB = BuildMI ( MBB , MBBI , dl , TII -> get ( Opcode ) ) ; MIB . addReg ( Base , getKillRegState ( BaseKill ) ) ; } MIB . addImm ( Pred ) . addReg ( PredReg


<s> AFI = Fn . getInfo < <ISA_LIT>FunctionInfo > ( ) ; TII = TM . getInstrInfo ( ) ; TRI = TM . getRegisterInfo ( ) ; STI = & TM . getSubtarget < <ISA_LIT>Subtarget > ( ) ; RS = new RegScavenger ( ) ; isThumb2 = AFI -> isThumb2Function ( ) ; isThumb1 = AFI -> isThumbFunction ( ) && ! isThumb2 ; if ( isThumb1 ) { delete RS ; return false ; } bool Modified = false ; for ( MachineFunction :: iterator MFI = Fn . begin ( ) , E = Fn . end ( ) ; MFI != E ; ++ MFI ) { MachineBasicBlock & MBB = * MFI ; Modified |= LoadStoreMultipleOpti ( MBB ) ; if ( TM . getSubtarget < <ISA_LIT>Subtarget > ( ) . hasV5TOps ( ) ) Modified |= MergeReturnIntoLDM ( MBB ) ; } delete


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


<s> InsertSub = true ; } if ( InsertSub ) { AddDefaultT1CC ( BuildMI ( MBB , MBBI , dl , TII -> get ( <STR_LIT> ) , Base ) ) . addReg ( Base , getKillRegState ( true ) ) . addImm ( WordOffset * <NUM_LIT> ) . addImm ( Pred ) . addReg ( PredReg ) ; return ; } } if ( MBBI -> killsRegister ( Base ) ) return ; } if ( MBB . succ_size ( ) > <NUM_LIT> ) AddDefaultT1CC ( BuildMI ( MBB , -- MBBI , dl , TII -> get ( <STR_LIT> ) , Base ) ) . addReg ( Base , getKillRegState ( true )


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


<s> bool <ISA_LIT>PreAllocLoadStoreOpt :: runOnMachineFunction ( MachineFunction & Fn ) { TD = Fn . getSubtarget ( ) . getDataLayout ( ) ; TII = Fn . getSubtarget ( ) . getInstrInfo ( ) ; TRI = Fn . getSubtarget ( ) . getRegisterInfo ( ) ; STI = & static_cast < const <ISA_LIT>Subtarget & > ( Fn . getSubtarget ( ) ) ; MRI = & Fn . getRegInfo ( ) ; MF = & Fn ; bool Modified = false ; for ( MachineFunction :: iterator MFI = Fn . begin ( ) , E = Fn . end ( ) ; MFI != E ; ++ MFI ) Modified |=


<s> if ( isLegalAddressImm ( Opcode , Imm , TII ) ) return true ; const MCInstrDesc & Desc = TII -> get ( Opcode ) ; unsigned AddrMode = ( Desc . TSFlags & <STR_LIT> ) ; switch (


<s> for ( MachineInstr * Op : llvm :: reverse ( Ops ) ) { unsigned LSMOpcode = getLoadStoreMultipleOpcode ( Op -> getOpcode ( ) , <STR_LIT> ) ; if ( LastOpcode && LSMOpcode != LastOpcode ) break ; int Offset = getMemoryOpOffset ( * Op ) ; unsigned Bytes = getLSMultipleTransferSize ( Op ) ; if ( LastBytes ) { if ( Bytes != LastBytes || Offset != ( LastOffset + ( int ) Bytes ) ) break ; } if ( NumMove == InstReorderLimit ) break ; ++ NumMove ; LastOffset = Offset ; LastBytes = Bytes ; 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 , <NUM_LIT> , TRI , * MF ) ; MRI -> constrainRegClass ( FirstReg , TRC ) ; MRI -> constrainRegClass ( SecondReg , TRC ) ; if ( isLd


<s> 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 ( ) && ! AFI -> shouldSignReturnAddress ( ) ) Modified |= MergeReturnIntoLDM ( MBB ) ; if ( isThumb1 ) Modified |= CombineMovBx ( MBB ) ; } Allocator . DestroyAll (


<s> 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> } IncrementOffset = getAddSubImmediate ( * Increment ) ; unsigned NewPostIncOpcode = getPostIndexedLoadStoreOpcode ( BaseAccess -> getOpcode ( ) , IncrementOffset > <NUM_LIT> ? <STR_LIT> : <STR_LIT> ) ; if ( ! isLegalAddressImm ( NewPostIncOpcode , IncrementOffset , TII ) ) { LLVM_DEBUG ( dbgs ( ) << <STR_LIT> ) ; return false ; } } else if ( PrePostInc ) { if ( Increment ) return false ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << <STR_LIT> << Base . virtRegIndex ( ) << <STR_LIT> ) ; int BaseOp = getBaseOperandIndex ( * PrePostInc ) ; IncrementOffset = PrePostInc -> getOperand ( BaseOp + <NUM_LIT> ) . getImm ( ) ; BaseAccess = PrePostInc ; NewBaseReg = PrePostInc -> getOperand ( <NUM_LIT> ) . getReg ( ) ; } else return false ; SmallPtrSet < MachineInstr * , <NUM_LIT> > SuccessorAccesses ; int CodesizeEstimate = - <NUM_LIT> ; for ( auto * Use : OtherAccesses ) { if ( DT -> dominates ( BaseAccess , Use ) ) { SuccessorAccesses . insert ( Use ) ; unsigned BaseOp = getBaseOperandIndex ( * Use ) ; if ( ! isLegalOrConvertableAddressImm ( Use -> getOpcode ( ) , Use -> getOperand ( BaseOp + <NUM_LIT> ) . getImm ( ) - IncrementOffset , TII , CodesizeEstimate ) ) { LLVM_DEBUG ( dbgs ( ) << <STR_LIT> ) ; return false ; } } else if ( ! DT -> dominates ( Use , BaseAccess ) ) { LLVM_DEBUG ( dbgs ( ) << <STR_LIT> ) ; return false ; } } if ( STI -> hasMinSize ( ) && CodesizeEstimate > <NUM_LIT> ) { LLVM_DEBUG ( dbgs ( ) << <STR_LIT> ) ; return false ; } if ( ! PrePostInc ) { LLVM_DEBUG ( dbgs ( ) << <STR_LIT> ; BaseAccess -> dump ( ) ) ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> ; Increment -> dump (


<s> <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 ; } NewBBI = llvm :: prior ( MBBI ) ; } else { unsigned NewOpc = ( isLd ) ? ( isT2 ? ( OffImm < <NUM_LIT> ? <STR_LIT> : <STR_LIT> ) : <STR_LIT> ) : ( isT2 ? ( OffImm < <NUM_LIT> ? <STR_LIT> : <STR_LIT> ) : <STR_LIT> ) ; DebugLoc dl = MBBI -> getDebugLoc ( ) ; if ( isLd && ( BaseKill || OffKill ) && ( TRI -> regsOverlap ( EvenReg , BaseReg ) ) ) { assert ( ! TRI -> regsOverlap ( OddReg , BaseReg ) ) ; InsertLDR_STR ( MBB , MBBI , OffImm + <NUM_LIT> , isLd , dl , NewOpc , OddReg , OddDeadKill , false , BaseReg , false , BaseUndef , false , OffUndef , Pred , PredReg , TII , isT2 ) ; NewBBI = llvm :: prior ( MBBI ) ; InsertLDR_STR ( MBB , MBBI , OffImm , isLd , dl , NewOpc , EvenReg , EvenDeadKill , false , BaseReg , BaseKill , BaseUndef , OffKill , OffUndef , Pred , PredReg , TII , isT2 ) ; } else { if ( OddReg == EvenReg && EvenDeadKill ) { EvenDeadKill = false ; OddDeadKill = true ; } if ( EvenReg == BaseReg ) EvenDeadKill = false ; InsertLDR_STR ( MBB , MBBI , OffImm , isLd , dl , NewOpc , EvenReg , EvenDeadKill , EvenUndef , BaseReg , false , BaseUndef


<s> for ( auto Use : Prev -> uses ( ) ) if ( Use . isKill ( ) ) { BuildMI ( MBB , MBBI , MBBI -> getDebugLoc ( ) , TII -> get ( <STR_LIT> ) ) . addReg ( Use . getReg ( ) , RegState :: Kill ) . add ( predOps ( <STR_LIT> ) ) . copyImplicitOps ( * MBBI ) ; MBB . erase ( MBBI ) ; MBB . erase ( Prev )


<s> -- Prev ; if ( Prev -> getOpcode ( ) != <STR_LIT> || ! Prev -> definesRegister ( <STR_LIT> ) ) return false ; for ( auto Use : Prev -> uses ( ) ) if ( Use . isKill ( ) ) { BuildMI ( MBB , MBBI , MBBI -> getDebugLoc ( ) , TII -> get ( <STR_LIT> ) ) . addReg ( Use . getReg ( ) , RegState :: Kill ) . add ( predOps ( <STR_LIT> ) ) . copyImplicitOps ( * MBBI ) ; MBB . erase ( MBBI


<s> unsigned NumRegs = Regs . size ( ) ; assert ( NumRegs > <NUM_LIT> ) ; bool SafeToClobberCPSR = ! isThumb1 || ( MBB . computeRegisterLiveness ( TRI , <STR_LIT> , InsertBefore , <NUM_LIT> ) == MachineBasicBlock :: LQR_Dead ) ; bool Writeback = isThumb1 ; if ( isThumb1 && isi32Load ( Opcode ) && ContainsReg ( Regs , Base ) ) { assert ( Base != <STR_LIT> && <STR_LIT> ) ; if ( Opcode == <STR_LIT> ) { Writeback = false ; } else if ( Opcode == <STR_LIT> ) { return nullptr ; } } <STR_LIT> Mode = <STR_LIT> ; bool isNotVFP = isi32Load ( Opcode ) || isi32Store ( Opcode ) ; bool haveIBAndDA = isNotVFP && ! isThumb2 && ! isThumb1 ; if ( Offset == <NUM_LIT> && haveIBAndDA ) { Mode = <STR_LIT> ; } else if ( Offset == - <NUM_LIT> * ( int ) NumRegs + <NUM_LIT> && haveIBAndDA ) { Mode = <STR_LIT> ; } else if ( Offset == - <NUM_LIT> * ( int ) NumRegs && isNotVFP && ! isThumb1 ) { Mode = <STR_LIT> ; } else if ( Offset != <NUM_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> ) { if ( ! getLoadStoreMultipleOpcode ( Opcode , Mode ) ) return nullptr ; if ( NumRegs <= <NUM_LIT> ) return nullptr ; if ( ! SafeToClobberCPSR ) return nullptr ; unsigned NewBase ; if ( isi32Load ( Opcode ) ) { NewBase = Regs [ NumRegs - <NUM_LIT> ] . first ; Writeback = false ; } else { moveLiveRegsBefore ( MBB , InsertBefore ) ; if ( ! isLoadSingle ( Opcode ) ) for ( const std :: pair < unsigned , bool > & R : Regs ) LiveRegs . addReg ( R . first ) ; NewBase = findFreeReg ( isThumb1 ? <STR_LIT> : <STR_LIT> ) ; if ( NewBase == <NUM_LIT> ) return nullptr ; } int BaseOpc = isThumb2 ? <STR_LIT> : ( isThumb1 && Base == <STR_LIT> ) ? <STR_LIT> : ( isThumb1 && Offset < <NUM_LIT> ) ? <STR_LIT> : isThumb1 ? <STR_LIT> : <STR_LIT> ; if ( Offset < <NUM_LIT> ) { Offset = - Offset ; BaseOpc = isThumb2 ? <STR_LIT> : ( isThumb1 && Offset < <NUM_LIT> && Base != <STR_LIT> ) ? <STR_LIT> : isThumb1 ? <STR_LIT> : <STR_LIT> ; } if ( ! TL -> isLegalAddImmediate ( Offset ) ) return nullptr ; bool KillOldBase = BaseKill && ( ! isi32Store ( Opcode ) || ! ContainsReg ( Regs , Base ) ) ; if ( isThumb1 ) { if ( Base != NewBase && ( BaseOpc == <STR_LIT> || BaseOpc == <STR_LIT> ) ) { if ( is<ISA_LIT>LowRegister ( NewBase ) && is<ISA_LIT>LowRegister ( Base ) && ! STI -> hasV6Ops ( ) ) { if ( Pred != <STR_LIT> ) return nullptr ; BuildMI ( MBB , InsertBefore , DL , TII -> get ( <STR_LIT> ) , NewBase ) . addReg ( Base ,


<s> const TargetMachine & TM = Fn . getTarget ( ) ; TL = TM . getTargetLowering ( ) ; AFI = Fn . getInfo < <ISA_LIT>FunctionInfo > ( ) ; TII = TM . getInstrInfo ( ) ; TRI = TM . getRegisterInfo ( ) ; STI = & TM . getSubtarget < <ISA_LIT>Subtarget > ( ) ; 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> if ( MBB . empty ( ) ) return false ; MachineBasicBlock :: iterator MBBI = MBB . getLastNonDebugInstr ( ) ; 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> ) return false ; unsigned NewOpc = ( isThumb2 ? <STR_LIT> : <STR_LIT> ) ; assert ( ( ( isThumb2 && Opcode == <STR_LIT> ) || Opcode ==


<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 ( ) ) continue ; unsigned Reg = MO . getReg ( ) ; if ( MO . isDef ( ) && TRI -> regsOverlap ( Reg , Base ) )


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


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


<s> SmallPtrSet < MachineInstr * , <NUM_LIT> > SuccessorAccesses ; int CodesizeEstimate = - <NUM_LIT> ; for ( auto * Use : OtherAccesses ) { if ( DT -> dominates ( BaseAccess , Use ) ) { SuccessorAccesses . insert ( Use ) ; unsigned BaseOp = getBaseOperandIndex ( * Use ) ; if ( ! isLegalOrConvertableAddressImm ( Use -> getOpcode ( ) , Use -> getOperand ( BaseOp + <NUM_LIT> ) . getImm ( ) - IncrementOffset , TII , CodesizeEstimate ) ) { LLVM_DEBUG ( dbgs ( ) << <STR_LIT> ) ; return false ; } } else if ( ! DT -> dominates ( Use , BaseAccess ) ) { LLVM_DEBUG ( dbgs ( ) << <STR_LIT> ) ; return false ; } } if ( STI -> hasMinSize ( ) && CodesizeEstimate > <NUM_LIT> ) { LLVM_DEBUG ( dbgs ( ) << <STR_LIT> ) ; return false ; } LLVM_DEBUG ( dbgs ( ) << <STR_LIT> ; BaseAccess -> dump ( ) ) ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> ; Increment -> dump ( ) ) ; Register NewBaseReg = Increment -> getOperand ( <NUM_LIT> ) . getReg ( ) ; MachineInstr * BaseAccessPost = createPostIncLoadStore ( BaseAccess , IncrementOffset , NewBaseReg , TII , TRI ) ; BaseAccess -> eraseFromParent ( ) ; Increment -> eraseFromParent ( ) ; ( void ) BaseAccessPost ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> ; BaseAccessPost -> dump (


<s> static MachineInstr * createPostIncLoadStore ( MachineInstr * MI , int Offset , Register NewReg , const TargetInstrInfo * TII , const TargetRegisterInfo * TRI ) { MachineFunction * MF = MI -> getMF ( ) ; MachineRegisterInfo & MRI = MF -> getRegInfo ( ) ; unsigned NewOpcode = getPostIndexedLoadStoreOpcode ( MI -> getOpcode ( ) , Offset > <NUM_LIT> ? <STR_LIT> : <STR_LIT> ) ; const MCInstrDesc & MCID = TII -> get ( NewOpcode ) ; const TargetRegisterClass * TRC = TII -> getRegClass ( MCID , <NUM_LIT> , TRI , * MF ) ; MRI . constrainRegClass ( NewReg , TRC ) ; TRC = TII -> getRegClass ( MCID , <NUM_LIT> ,


<s> unsigned NewPostIncOpcode = getPostIndexedLoadStoreOpcode ( BaseAccess -> getOpcode ( ) , IncrementOffset > <NUM_LIT> ? <STR_LIT> : <STR_LIT> ) ; if ( ! isLegalAddressImm ( NewPostIncOpcode , IncrementOffset , TII ) ) { LLVM_DEBUG ( dbgs ( ) << <STR_LIT> ) ; return false ; } SmallPtrSet < MachineInstr * , <NUM_LIT> > SuccessorAccesses ; for ( auto * Use : OtherAccesses ) { if ( DT -> dominates ( BaseAccess , Use ) ) { SuccessorAccesses . insert ( Use ) ; unsigned BaseOp = getBaseOperandIndex ( * Use ) ; if ( ! isLegalAddressImm ( Use -> getOpcode ( ) , Use -> getOperand ( BaseOp + <NUM_LIT> ) . getImm ( ) - IncrementOffset , TII ) ) { LLVM_DEBUG ( dbgs ( ) << <STR_LIT> ) ; return false ; } } else if ( ! DT -> dominates ( Use , BaseAccess ) ) { LLVM_DEBUG ( dbgs ( ) << <STR_LIT> ) ; return false ; } } LLVM_DEBUG ( dbgs ( ) << <STR_LIT> ; BaseAccess -> dump ( ) ) ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> ; Increment -> dump ( ) ) ; Register NewBaseReg = Increment -> getOperand ( <NUM_LIT> ) . getReg ( ) ; MachineInstr * BaseAccessPost = createPostIncLoadStore ( BaseAccess , IncrementOffset , NewBaseReg , TII , TRI ) ; BaseAccess -> eraseFromParent ( ) ; Increment -> eraseFromParent ( ) ; ( void ) BaseAccessPost ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> ; BaseAccessPost -> dump ( ) ) ; for ( auto * Use : SuccessorAccesses ) { LLVM_DEBUG ( dbgs ( ) << <STR_LIT> ; Use -> dump ( ) ) ; unsigned BaseOp = getBaseOperandIndex ( * Use ) ; Use -> getOperand ( BaseOp ) . setReg ( NewBaseReg ) ; int OldOffset = Use -> getOperand ( BaseOp + <NUM_LIT> ) . getImm ( ) ; Use -> getOperand ( BaseOp + <NUM_LIT> ) . setImm ( OldOffset - IncrementOffset ) ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> ; Use -> dump ( ) ) ; } for ( MachineOperand & Op : MRI -> use_nodbg_operands ( NewBaseReg ) ) Op . setIsKill ( false ) ; return true


<s> 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 ( ) ; 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


<s> 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> : return ( MI -> getNumOperands ( ) - <NUM_LIT> ) * <NUM_LIT> ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : return <STR_LIT> ( MI -> getOperand ( <NUM_LIT> ) . getImm (


<s> 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> : return ( MI -> getNumOperands ( ) - <NUM_LIT> ) * <NUM_LIT> ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT>


<s> if ( MMO -> getAlignment ( ) < <NUM_LIT> ) return false ; } if ( MI -> getNumOperands ( ) > <NUM_LIT> && MI -> getOperand ( <NUM_LIT> ) . isReg ( ) && MI -> getOperand ( <NUM_LIT> ) . isUndef ( ) ) return false ; if ( MI -> getNumOperands ( ) > <NUM_LIT> && MI -> getOperand ( <NUM_LIT> ) . isReg ( ) && MI -> getOperand ( <NUM_LIT> ) . isUndef ( ) ) return false ; int Opcode = MI -> getOpcode ( ) ; switch ( Opcode ) { default : break ; case <STR_LIT> : case <STR_LIT> : return MI -> getOperand ( <NUM_LIT> ) . isReg ( ) && MI -> getOperand ( <NUM_LIT> ) . getReg ( ) == <NUM_LIT> ; case <STR_LIT> : case <STR_LIT> : return MI -> getOperand ( <NUM_LIT> )


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


<s> const MachineOperand & PMO = Loc -> getOperand ( <NUM_LIT> ) ; unsigned PReg = PMO . getReg ( ) ; unsigned PRegNum = PMO . isUndef ( ) ? UINT_MAX : <ISA_LIT>RegisterInfo :: getRegisterNumbering ( PReg ) ; 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 : <ISA_LIT>RegisterInfo :: getRegisterNumbering ( Reg ) ; if ( Reg != <STR_LIT> && NewOffset == Offset + ( int ) Size && ( ( isAM4 && RegNum > PRegNum ) || RegNum == PRegNum + <NUM_LIT> ) ) { Offset += Size ; PRegNum = RegNum ; } 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> Mode = <STR_LIT> ; } else if ( isAM4 && Offset == - <NUM_LIT> * ( int ) NumRegs + <NUM_LIT> ) { if ( isThumb2 ) return false ; Mode = <STR_LIT> ; } else if ( isAM4 && Offset == - <NUM_LIT> * ( int ) NumRegs ) { Mode = <STR_LIT> ; } else if ( Offset != <NUM_LIT> ) { if ( NumRegs <= <NUM_LIT> ) return false ; unsigned NewBase ; if ( isi32Load ( Opcode ) ) NewBase = Regs [ NumRegs - <NUM_LIT> ] . first ; else { NewBase = Scratch ; if ( NewBase == <NUM_LIT> ) return false ; } int BaseOpc = ! isThumb2 ? <STR_LIT> : ( ( Base == <STR_LIT> ) ? <STR_LIT> : <STR_LIT> ) ; if ( Offset < <NUM_LIT> ) { BaseOpc = ! isThumb2 ? <STR_LIT> : ( ( Base == <STR_LIT> ) ? <STR_LIT> : <STR_LIT> ) ; Offset = - Offset ; } int ImmedOffset = isThumb2 ? <STR_LIT> ( Offset ) : <STR_LIT> ( Offset ) ; if ( ImmedOffset == - <NUM_LIT> ) return false ; BuildMI ( MBB , MBBI , dl , TII -> get ( BaseOpc ) , NewBase ) . addReg ( Base , getKillRegState ( BaseKill ) ) . addImm ( Offset ) . addImm ( Pred ) . addReg ( PredReg ) . addReg ( <NUM_LIT> ) ; Base = NewBase ; BaseKill = true ; } bool isDPR = Opcode == <STR_LIT> || Opcode == <STR_LIT> ; bool isDef = isi32Load ( Opcode ) || Opcode == <STR_LIT> || Opcode == <STR_LIT> ; Opcode = getLoadStoreMultipleOpcode ( Opcode ) ; MachineInstrBuilder MIB = ( isAM4 ) ? BuildMI ( MBB , MBBI , dl , TII -> get ( Opcode ) ) . addReg ( Base , getKillRegState ( BaseKill ) ) . addImm ( <STR_LIT> ( Mode ) ) . addImm ( Pred ) . addReg ( PredReg ) : BuildMI ( MBB , MBBI , dl , TII -> get ( Opcode ) ) . addReg ( Base , getKillRegState ( BaseKill ) ) . addImm ( <STR_LIT> ( Mode , false , isDPR ? NumRegs << <NUM_LIT> : NumRegs ) )

. addImm ( Pred ) . addReg ( PredReg ) ;


<s> AU . addRequired < AAResultsWrapperPass >


<s> 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 ( ) ; return


<s> if ( ! Errata602117 && ! NonConsecutiveRegs ) return false ; bool isT2 = Opcode == <STR_LIT> || Opcode == <STR_LIT> ; bool isLd = Opcode == <STR_LIT> || Opcode == <STR_LIT> ; bool EvenDeadKill = isLd ? MI -> getOperand ( <NUM_LIT> ) . isDead ( ) : MI -> getOperand ( <NUM_LIT> ) . isKill ( ) ; bool EvenUndef = MI -> getOperand ( <NUM_LIT> ) . isUndef ( ) ; 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 ; } } else { unsigned NewOpc = ( isLd ) ? ( isT2 ? ( OffImm < <NUM_LIT> ? <STR_LIT> : <STR_LIT> ) : <STR_LIT> ) : ( isT2 ? ( OffImm < <NUM_LIT> ? <STR_LIT> : <STR_LIT> ) : <STR_LIT> ) ; unsigned NewOpc2 = ( isLd ) ? ( isT2 ? ( OffImm + <NUM_LIT> < <NUM_LIT> ? <STR_LIT> : <STR_LIT> ) : <STR_LIT> ) : ( isT2 ? ( OffImm + <NUM_LIT> < <NUM_LIT> ? <STR_LIT> : <STR_LIT> ) : <STR_LIT> ) ; DebugLoc dl = MBBI -> getDebugLoc ( ) ; if ( isLd && ( BaseKill || OffKill ) && ( TRI -> regsOverlap ( EvenReg , BaseReg ) ) ) { assert ( ! TRI -> regsOverlap ( OddReg , BaseReg


<s> if ( STI -> isCortexM3 ( ) && isi32Load ( Opcode ) && PReg == getLoadStoreBaseOp ( * MI ) . getReg ( ) ) CanMergeToLSDouble = false ; bool CanMergeToLSMulti = true ; if ( STI -> isSwift ( ) && ! 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 ; 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 == <STR_LIT> ) break ; unsigned RegNum = MO . isUndef ( ) ? UINT_MAX : TRI -> getEncodingValue ( Reg ) ; bool PartOfLSMulti = CanMergeToLSMulti ; if ( PartOfLSMulti ) { if ( RegNum <= PRegNum ) PartOfLSMulti = false ; else if ( ! isNotVFP && RegNum != PRegNum + <NUM_LIT> ) PartOfLSMulti = false ; } bool PartOfLSDouble = CanMergeToLSDouble && Count <= <NUM_LIT> ; if ( ! PartOfLSMulti && ! PartOfLSDouble ) break ; CanMergeToLSMulti &= PartOfLSMulti ; CanMergeToLSDouble &= PartOfLSDouble ; unsigned Position = MemOps [ I ] . Position ; if ( Position < MemOps [ Latest ] . Position ) Latest = I ; else if ( Position > MemOps [ Earliest ] . Position ) Earliest = I ; Offset += Size ; PRegNum = RegNum ; } MergeCandidate * Candidate = new ( Allocator . Allocate ( ) ) MergeCandidate ; for ( unsigned C = SIndex , CE = SIndex + Count ; C < CE ; ++ C ) Candidate -> Instrs . push_back ( MemOps [ C ] . MI ) ; Candidate -> LatestMIIdx = Latest - SIndex ; Candidate -> EarliestMIIdx = Earliest - SIndex ; Candidate -> InsertPos = MemOps [ Latest ] . Position ; if ( Count == <NUM_LIT> ) CanMergeToLSMulti


<s> MemOpQueue MemOps ; unsigned CurrBase = <NUM_LIT> ; unsigned CurrOpc = ~ <NUM_LIT> ; <STR_LIT> CurrPred = <STR_LIT> ; unsigned Position = <NUM_LIT> ; assert ( Candidates . size ( ) == <NUM_LIT> ) ; assert ( MergeBaseCandidates . size ( ) == <NUM_LIT> ) ; LiveRegsValid = false ; for ( MachineBasicBlock :: iterator I = MBB . end ( ) , MBBI ; I != MBB . begin ( ) ; I = MBBI ) { MBBI = std :: prev ( I ) ; if ( FixInvalidRegPairOp ( MBB , MBBI ) ) continue ; ++ Position ; 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 , 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 -> isDebugValue ( ) ) { 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 =


<s> } 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 ) ) return false ; } 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 . addOperand ( MI -> getOperand ( OpNum ) ) ; MIB -> setMemRefs ( MI -> memoperands_begin ( ) , MI ->


<s> else if ( isAM4 && Offset == - <NUM_LIT> * ( int ) NumRegs ) Mode = <STR_LIT> ; else if ( Offset != <NUM_LIT> ) { if ( NumRegs <= <NUM_LIT> ) return false ; unsigned NewBase ; 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 , false , false , 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 ) ; MachineInstrBuilder MIB = ( isAM4 ) ? BuildMI ( MBB , MBBI , dl , TII -> get ( Opcode ) ) . addReg ( Base , false , false , BaseKill ) . addImm ( <STR_LIT> ( Mode ) ) . addImm ( Pred ) . addReg ( PredReg ) : BuildMI ( MBB , MBBI , dl , TII -> get ( Opcode ) ) . addReg ( Base , false , false , BaseKill ) . addImm ( <STR_LIT> ( Mode , false , isDPR ? NumRegs << <NUM_LIT> : NumRegs ) ) . addImm ( Pred ) . addReg ( PredReg ) ; for ( unsigned i = <NUM_LIT> ; i != NumRegs ; ++ i ) MIB = MIB . addReg ( Regs [ i ] . first , isDef , false , Regs [ i ] . second ) ; return true


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

. isKill ( ) ) ) . addReg ( Base ) . addReg ( <NUM_LIT> ) . addImm ( Offset ) . addImm ( Pred ) . addReg ( PredReg ) ;


<s> MI -> getOperand ( <NUM_LIT> ) . setImm ( <STR_LIT> ( <STR_LIT> , true ) ) ; MBB . erase ( PrevMBBI ) ; return true ; } } if ( MBBI != MBB . end ( ) ) { MachineBasicBlock :: iterator NextMBBI = llvm :: next ( MBBI ) ; if ( ( Mode == <STR_LIT> || Mode == <STR_LIT> ) && isMatchingIncrement ( NextMBBI , Base , Bytes , <NUM_LIT> , 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 , <NUM_LIT> , 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 ( <NUM_LIT> ) . getImm ( ) ) ; if ( MBBI != MBB . begin ( ) ) { MachineBasicBlock :: iterator PrevMBBI = prior ( MBBI ) ; if ( Mode == <STR_LIT> && isMatchingDecrement ( PrevMBBI , Base , Bytes , <NUM_LIT> , Pred , PredReg ) ) { MI -> getOperand ( <NUM_LIT> ) . setImm ( <STR_LIT> ( <STR_LIT> , true , Offset ) ) ; MBB . erase ( PrevMBBI ) ; return true ; } } if ( MBBI != MBB . end ( )


<s> 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 ; } MBB . erase ( NextMBBI ) ; } } 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> ? -


<s> bool BaseKill = MI -> getOperand ( <NUM_LIT> ) . 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 :: 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 =


<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 ( const MachineOperand & MO : memOps [ i ] . MBBI -> operands ( ) ) { 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 ] . second ) { unsigned Reg = Regs [ i - memOpsBegin ] . first ; if ( KilledRegs . count ( Reg ) ) { unsigned j = Killer [ Reg ] ; int Idx = memOps [ j ] .

MBBI -> findRegisterUseOperandIdx ( Reg , true ) ;


<s> 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 -> isBranch ( ) ) { InsertSub = true ; } if ( InsertSub


<s> 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 ; } NewBBI = llvm :: prior ( MBBI ) ; } else { unsigned NewOpc = ( isLd ) ? ( isT2 ? ( OffImm < <NUM_LIT> ? <STR_LIT> : <STR_LIT> ) : <STR_LIT> ) : ( isT2 ? ( OffImm < <NUM_LIT> ? <STR_LIT> : <STR_LIT> ) : <STR_LIT> ) ; DebugLoc dl = MBBI -> getDebugLoc ( ) ; if ( isLd && ( BaseKill || OffKill ) && ( TRI -> regsOverlap ( EvenReg , BaseReg ) ) ) { assert ( ! TRI -> regsOverlap ( OddReg , BaseReg ) ) ; InsertLDR_STR ( MBB , MBBI , OffImm + <NUM_LIT> , isLd , dl , NewOpc , OddReg , OddDeadKill , false , BaseReg , false , BaseUndef , false , OffUndef , Pred , PredReg , TII , isT2 ) ; NewBBI = llvm :: prior ( MBBI ) ; if ( isT2 && NewOpc == <STR_LIT> && OffImm + <NUM_LIT> >= <NUM_LIT>


<s> ( isThumb1 && Offset < <NUM_LIT> ) ? <STR_LIT> : isThumb1 ? <STR_LIT> : <STR_LIT> ; if ( Offset < <NUM_LIT> ) { Offset = - Offset ; BaseOpc = isThumb2 ? <STR_LIT> : ( isThumb1 && Offset < <NUM_LIT> && Base != <STR_LIT> ) ? <STR_LIT> : isThumb1 ? <STR_LIT> : <STR_LIT> ; } if ( ! TL -> isLegalAddImmediate ( Offset ) ) return nullptr ; bool KillOldBase = BaseKill && ( ! isi32Store ( Opcode ) || ! ContainsReg ( Regs , Base ) ) ; if ( isThumb1 ) { if ( Base != NewBase && ( BaseOpc == <STR_LIT> || BaseOpc == <STR_LIT> ) ) { if ( is<ISA_LIT>LowRegister ( NewBase ) && is<ISA_LIT>LowRegister ( Base ) && ! STI -> hasV6Ops ( ) ) { if ( Pred != <STR_LIT> ) return nullptr ; BuildMI ( MBB , InsertBefore , DL , TII -> get ( <STR_LIT> ) , NewBase ) . addReg ( Base , getKillRegState ( KillOldBase ) ) ; } else BuildMI ( MBB , InsertBefore , DL , TII -> get ( <STR_LIT> ) , NewBase ) . addReg ( Base , getKillRegState ( KillOldBase ) ) . add ( predOps ( Pred , PredReg ) ) ; Base = NewBase ; KillOldBase = true ; } if ( BaseOpc == <STR_LIT> ) { assert ( Offset % <NUM_LIT> == <NUM_LIT> && <STR_LIT> ) ; BuildMI ( MBB , InsertBefore , DL , TII -> get ( BaseOpc ) , NewBase ) . addReg ( Base , getKillRegState ( KillOldBase ) ) . addImm ( Offset / <NUM_LIT> ) . add ( predOps ( Pred , PredReg ) ) ; } else BuildMI ( MBB , InsertBefore , DL , TII -> get ( BaseOpc ) , NewBase ) . add ( t1CondCodeOp ( true ) ) . addReg ( Base , getKillRegState ( KillOldBase ) ) . addImm ( Offset ) . add ( predOps ( Pred , PredReg ) ) ; } else { BuildMI ( MBB , InsertBefore , DL , TII -> get ( BaseOpc ) , NewBase ) . addReg ( Base , getKillRegState ( KillOldBase ) ) . addImm ( Offset ) . add ( predOps ( Pred , PredReg ) ) . add ( condCodeOp ( ) ) ; } Base = NewBase ; BaseKill = true ; } bool isDef = isLoadSingle ( Opcode ) ; Opcode = getLoadStoreMultipleOpcode ( Opcode , Mode ) ; if ( ! Opcode ) return nullptr ; if ( isThumb1 && ! SafeToClobberCPSR && Writeback && ! BaseKill ) return nullptr ; MachineInstrBuilder MIB ; if ( Writeback ) { assert ( isThumb1 && <STR_LIT> ) ; if ( Opcode == <STR_LIT> ) { assert ( ! ( ContainsReg ( Regs , Base ) ) && <STR_LIT> ) ; Opcode = <STR_LIT> ; } MIB = BuildMI ( MBB , InsertBefore , DL


<s> MachineBasicBlock & MBB = * MI -> getParent ( ) ; MachineBasicBlock :: iterator MBBI ( MI ) ; int Offset ; MachineBasicBlock :: iterator MergeInstr = findIncDecBefore ( MBBI , Base , Pred , PredReg , Offset ) ; unsigned NewOpc ; 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> 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 ) ; if ( Offset == <NUM_LIT> || Offset == - <NUM_LIT> ) { 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 ( Pred ) . addReg ( PredReg ) ; assert ( TII -> get ( Opcode ) . getNumOperands ( ) == <NUM_LIT> && TII -> get

( NewOpc ) . getNumOperands ( ) == <NUM_LIT> && <STR_LIT> ) ;


<s> if ( isThumb1 ) return false ; const MachineOperand & BaseOP = MI -> getOperand ( <NUM_LIT> ) ; unsigned Base = BaseOP . getReg ( ) ; bool BaseKill = BaseOP . isKill ( ) ; 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 ; 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 ( )


<s> <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 ) ; 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


<s> 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 ) ; unsigned 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> if ( ! SafeToClobberCPSR ) return false ; unsigned NewBase ; if ( isi32Load ( Opcode ) ) { NewBase = Regs [ NumRegs - <NUM_LIT> ] . first ; } else { NewBase = Scratch ; if ( NewBase == <NUM_LIT> ) return false ; } int BaseOpc = isThumb2 ? <STR_LIT> : ( isThumb1 && Offset < <NUM_LIT> ) ? <STR_LIT> : isThumb1 ? <STR_LIT> : <STR_LIT> ; if ( Offset < <NUM_LIT> ) { Offset = - Offset ; BaseOpc = isThumb2 ? <STR_LIT> : ( isThumb1 && Offset < <NUM_LIT> ) ? <STR_LIT> : isThumb1 ? <STR_LIT> : <STR_LIT> ; } if ( ! TL -> isLegalAddImmediate ( Offset ) ) return false ; if ( isThumb1 ) { if ( Base != NewBase && Offset >= <NUM_LIT> ) { BuildMI ( MBB , MBBI , dl , TII -> get ( <STR_LIT> ) , NewBase ) . addReg ( Base , getKillRegState ( BaseKill ) ) . addImm ( Pred ) . addReg ( PredReg ) ; Base = NewBase ; BaseKill = false ; } AddDefaultT1CC ( BuildMI ( MBB , MBBI , dl , TII -> get ( BaseOpc ) , NewBase ) , true ) . addReg ( Base , getKillRegState ( BaseKill ) ) . addImm ( Offset ) . addImm ( Pred ) . addReg ( PredReg ) ; } else { BuildMI ( MBB , MBBI , dl , TII -> get ( BaseOpc ) , NewBase ) . addReg ( Base , getKillRegState ( BaseKill ) ) . addImm ( Offset ) . addImm ( Pred ) . addReg ( PredReg ) . addReg ( <NUM_LIT> ) ; } Base = NewBase ; BaseKill = true ; } bool isDef = ( isi32Load ( Opcode ) || Opcode == <STR_LIT> || Opcode == <STR_LIT> ) ; Opcode = getLoadStoreMultipleOpcode ( Opcode , Mode ) ; if ( ! Opcode ) return false ; bool Writeback = isThumb1 ; if ( Opcode == <STR_LIT> && isThumb1 ) for ( unsigned I = <NUM_LIT> ; I < NumRegs ; ++ I ) if ( Base == Regs [ I ] . first ) { Writeback = false ; break ; } if ( isThumb1 && Writeback && ! BaseKill ) return false ; MachineInstrBuilder MIB ; if ( Writeback ) { if ( Opcode == <STR_LIT> ) Opcode = <STR_LIT> ; MIB = BuildMI ( MBB , MBBI , dl , TII -> get ( Opcode ) ) ; MIB . addReg ( Base , getDefRegState ( true ) ) . addReg ( Base , getKillRegState ( BaseKill


<s> TII = Fn . getSubtarget ( ) . getInstrInfo ( ) ; TRI = Fn . getSubtarget ( ) . getRegisterInfo ( ) ; STI = & Fn . getTarget ( ) . getSubtarget < <ISA_LIT>Subtarget > ( ) ; MRI = & Fn . getRegInfo ( ) ; MF = & Fn ; bool Modified = false ; for ( MachineFunction :: iterator MFI = Fn . begin ( ) , E = Fn . end ( ) ; MFI != E ; ++ MFI ) Modified |= RescheduleLoadStoreInstrs (


<s> 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 ( prior ( 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 ] . second ) { unsigned Reg = Regs [ i - memOpsBegin ] . first ; if ( KilledRegs . count ( Reg ) ) { unsigned j = Killer [ Reg ] ; int Idx = memOps [ j ] . MBBI -> findRegisterUseOperandIdx ( Reg , true ) ; assert ( Idx >= <NUM_LIT> && <STR_LIT> ) ; memOps [ j ] . MBBI -> getOperand ( Idx ) . setIsKill ( false ) ; memOps [ j ] . isKill = false ; } memOps [ i ] . isKill


<s> if ( DoMerge ) MBB . erase ( PrevMBBI ) ; } if ( ! DoMerge && MBBI != MBB . end ( ) ) { MachineBasicBlock :: iterator NextMBBI = llvm :: next ( MBBI ) ; if ( isAM4 ) { 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 ; } } else { if ( Mode == <STR_LIT> && isMatchingIncrement ( NextMBBI , Base , Bytes , <NUM_LIT> , Pred , PredReg ) ) { DoMerge = true ; } } if ( DoMerge ) { if ( NextMBBI == I ) { Advance = true ; ++ I ; } MBB . erase ( NextMBBI ) ; } } if ( ! DoMerge ) return false ; unsigned NewOpc = getUpdatingLSMultipleOpcode ( Opcode ) ; MachineInstrBuilder MIB = BuildMI ( MBB , MBBI , dl , TII -> get ( NewOpc ) ) . addReg ( Base , getDefRegState ( true ) ) . addReg ( Base , getKillRegState ( BaseKill ) ) ; if ( isAM4 ) { MIB . addImm ( <STR_LIT> ( Mode ) ) . addImm ( Pred ) . addReg ( PredReg ) ; } else { MIB . addImm ( <STR_LIT> ( Mode , Offset ) ) . addImm ( Pred ) . addReg ( PredReg ) ; } for ( unsigned OpNum = <NUM_LIT> , e = MI -> getNumOperands ( ) ; OpNum != e ; ++ OpNum ) MIB . addOperand ( MI -> getOperand ( OpNum ) ) ; ( * MIB ) . setMemRefs ( MI -> memoperands_begin ( ) , MI -> memoperands_end ( ) ) ; MBB . erase ( MBBI ) ; return true


<s> if ( NumRegs <= <NUM_LIT> ) return false ; unsigned NewBase ; if ( isi32Load ( Opcode ) ) NewBase = Regs [ NumRegs - <NUM_LIT> ] . first ; else { NewBase = Scratch ; if ( NewBase == <NUM_LIT> ) return false ; } int BaseOpc = ! isThumb2 ? <STR_LIT> : ( ( Base == <STR_LIT> ) ? <STR_LIT> : <STR_LIT> ) ; if ( Offset < <NUM_LIT> ) { BaseOpc = ! isThumb2 ? <STR_LIT> : ( ( Base == <STR_LIT> ) ? <STR_LIT> : <STR_LIT> ) ; Offset = - Offset ; } int ImmedOffset = isThumb2 ? <STR_LIT> ( Offset ) : <STR_LIT> ( Offset ) ; if ( ImmedOffset == - <NUM_LIT> ) return false ; BuildMI ( MBB , MBBI , dl , TII -> get ( BaseOpc ) , NewBase ) . addReg ( Base , getKillRegState ( BaseKill ) ) . addImm ( Offset ) . addImm ( Pred ) . addReg ( PredReg ) . addReg ( <NUM_LIT> ) ; Base =


<s> MachineBasicBlock :: iterator MBBI = MBB . getLastNonDebugInstr ( ) ; if ( MBBI != MBB . begin ( ) && ( MBBI -> getOpcode ( ) == <STR_LIT> || MBBI -> getOpcode ( ) == <STR_LIT> || MBBI -> getOpcode ( ) == <STR_LIT> ) ) { 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 ( ) , &


<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


<s> if ( ! DoMerge && MBBI != MBB . end ( ) ) { MachineBasicBlock :: iterator NextMBBI = llvm :: next ( MBBI ) ; 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 ) ; if ( NextMBBI == I ) { Advance = true ; ++ I ; } MBB . erase ( NextMBBI ) ; } } if ( ! DoMerge ) return false ; bool isDPR = NewOpc == <STR_LIT> || NewOpc == <STR_LIT> ; unsigned Offset = <NUM_LIT> ; if ( isAM5 ) Offset = <STR_LIT> ( AddSub == <STR_LIT> ? <STR_LIT> : <STR_LIT> , true , ( isDPR ? <NUM_LIT> : <NUM_LIT> ) ) ; else if ( isAM2 ) Offset = <STR_LIT> ( AddSub , Bytes , <STR_LIT> ) ; else Offset = AddSub == <STR_LIT> ? - Bytes : Bytes ; 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 ( Offset ) . addImm ( Pred ) . addReg ( PredReg ) . addReg ( MO . getReg ( ) , ( isLd ? getDefRegState ( true ) : getKillRegState ( MO . isKill ( ) ) ) ) ; } else if ( isLd ) { if ( isAM2 ) 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 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


<s> bool <ISA_LIT>LoadStoreOpt :: MergeBaseUpdateLoadStore ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator MBBI , const TargetInstrInfo * TII , bool & Advance , MachineBasicBlock :: iterator & I ) { MachineInstr * MI = MBBI ; unsigned Base = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; 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 ( 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> ) ; if ( MBBI != MBB . begin ( ) ) { MachineBasicBlock :: iterator PrevMBBI = prior ( MBBI ) ; 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 ) ; } } if ( ! DoMerge && MBBI != MBB . end ( ) ) { MachineBasicBlock :: iterator NextMBBI = llvm :: next ( MBBI ) ; 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


<s> MachineInstr * MI = MBBI ; unsigned Base = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; bool BaseKill = MI -> getOperand ( <NUM_LIT> ) . isKill ( ) ; unsigned Bytes = getLSMultipleTransferSize ( MI ) ; unsigned PredReg = <NUM_LIT> ; <STR_LIT> Pred = llvm :: getInstrPredicate ( MI , PredReg ) ; int Opcode = MI -> getOpcode ( ) ; DebugLoc dl = MI -> getDebugLoc ( ) ; bool isAM4 = ( Opcode == <STR_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> || Opcode == <STR_LIT> ) ; bool DoMerge = false ; <STR_LIT> Mode = <STR_LIT> ; unsigned Offset = <NUM_LIT> ; if ( isAM4 ) { for ( unsigned i = <NUM_LIT> , e = MI -> getNumOperands ( ) ; i != e ; ++ i ) { if ( MI -> getOperand ( i ) . getReg ( ) == Base ) return false ; } assert ( ! <STR_LIT> ( MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ) ) ; Mode = <STR_LIT> ( MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ) ; } else { assert ( ! <STR_LIT> ( MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ) ) ; Mode = <STR_LIT> ( MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ) ; Offset = <STR_LIT> ( MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ) ; } if ( MBBI != MBB . begin ( ) ) { MachineBasicBlock :: iterator PrevMBBI = prior ( MBBI ) ; if ( isAM4 ) { if ( Mode == <STR_LIT> && isMatchingDecrement ( PrevMBBI , Base , Bytes , <NUM_LIT> , Pred , PredReg ) ) { DoMerge = true ; Mode = <STR_LIT> ; } else if ( isAM4 && Mode == <STR_LIT> && isMatchingDecrement ( PrevMBBI , Base , Bytes , <NUM_LIT> , Pred , PredReg ) ) { DoMerge = true ; Mode = <STR_LIT> ; } } else { if ( Mode == <STR_LIT> && isMatchingDecrement ( PrevMBBI , Base , Bytes , <NUM_LIT> , Pred , PredReg ) ) { Mode = <STR_LIT> ; DoMerge = true ; } } if ( DoMerge ) MBB . erase ( PrevMBBI ) ; } if ( ! DoMerge && MBBI != MBB . end ( ) ) { MachineBasicBlock :: iterator NextMBBI = llvm :: next ( MBBI ) ; if ( isAM4 ) { 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 =


<s> 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 -> optForMinSize ( ) || ! BaseKill ) return false ; bool HighRegsUsed =


<s> NewOpc = Opcode == <STR_LIT> ? <STR_LIT> : <STR_LIT> ; } else { MergeInstr = findIncDecAfter ( MBBI , Base , Pred , PredReg , Offset ) ; if ( Offset == <NUM_LIT> || Offset == - <NUM_LIT> ) { NewOpc = Opcode == <STR_LIT> ? <STR_LIT> : <STR_LIT> ; } else 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 ) .


<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 ) ; 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


<s> 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 ) ; 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 ( ) ) { LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << * MergeInstr ) ; MBB . erase ( MergeInstr )


<s> if ( Base != NewBase && Offset >= <NUM_LIT> ) { BuildMI ( MBB , MBBI , dl , TII -> get ( <STR_LIT> ) , NewBase ) . addReg ( Base , getKillRegState ( BaseKill ) ) . addImm ( Pred ) . addReg ( PredReg ) ; Base = NewBase ; BaseKill = false ; } AddDefaultT1CC ( BuildMI ( MBB , MBBI , dl , TII -> get ( BaseOpc ) , NewBase ) ) . addReg ( Base , getKillRegState ( BaseKill ) ) . addImm ( Offset ) . addImm ( Pred ) . addReg ( PredReg ) ; } else { BuildMI ( MBB , MBBI , dl , TII -> get ( BaseOpc ) , NewBase ) . addReg ( Base , getKillRegState ( BaseKill ) ) . addImm ( Offset ) . addImm ( Pred ) . addReg ( PredReg ) . addReg ( <NUM_LIT> ) ; } Base = NewBase ; BaseKill = true ; } bool isDef = ( isi32Load ( Opcode ) || Opcode == <STR_LIT> || Opcode == <STR_LIT> ) ; Opcode = getLoadStoreMultipleOpcode ( Opcode , Mode ) ; if ( ! Opcode ) return false ; bool Writeback = isThumb1 ; if ( Opcode == <STR_LIT> && isThumb1 ) for ( unsigned I = <NUM_LIT> ; I < NumRegs ; ++ I ) if ( Base == Regs [ I ] . first ) { Writeback = false ; break ; } if ( isThumb1 && Writeback && ! BaseKill ) return false ; MachineInstrBuilder MIB ; if ( Writeback ) { if ( Opcode == <STR_LIT> ) Opcode = <STR_LIT> ; MIB = BuildMI ( MBB , MBBI , dl , TII -> get ( Opcode ) ) ; MIB . addReg ( Base , getDefRegState ( true ) ) . addReg ( Base , getKillRegState ( BaseKill ) ) ; } else { MIB = BuildMI ( MBB , MBBI , dl , TII -> get ( Opcode ) ) ; MIB . addReg ( Base , getKillRegState ( BaseKill ) ) ; } MIB . addImm ( Pred ) . addReg ( PredReg ) ; for ( unsigned i = <NUM_LIT> ; i != NumRegs ; ++ i ) MIB = MIB . addReg ( Regs [ i ] . first , getDefRegState ( isDef ) | getKillRegState ( Regs [ i ] . second ) ) ; for ( unsigned i = <NUM_LIT> , e = ImpDefs . size ( ) ; i != e ; ++ i ) MIB . addReg ( ImpDefs [ i ] , RegState :: ImplicitDefine ) ; return true


<s> if ( ! ( 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 ) ) return false ; return CheckCPSRDef ? ! definesCPSR ( MI


<s> default : return false ; case <STR_LIT> : case <STR_LIT> : CheckCPSRDef = true ; case <STR_LIT> : break ; } if ( Bytes == <NUM_LIT> || ( Limit && Bytes >= Limit ) ) return false ; unsigned Scale = ( 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 && llvm :: getInstrPredicate ( MI , MyPredReg ) == Pred && MyPredReg == PredReg ) ) return false ; return CheckCPSRDef ? ! definesCPSR ( MI


<s> STI = & static_cast < const <ISA_LIT>Subtarget & > ( Fn . getSubtarget ( ) ) ; TII = STI -> getInstrInfo ( ) ; TRI = STI -> getRegisterInfo ( ) ; MRI = & Fn . getRegInfo ( ) ; MF = & Fn ; bool Modified = false ; for ( MachineBasicBlock & MFI : Fn ) Modified |= RescheduleLoadStoreInstrs ( & MFI ) ; return