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

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


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


<s> void <ISA_LIT>BranchRelaxation :: computeOffset ( MachineFunction & MF , DenseMap < MachineBasicBlock * , unsigned > & OffsetMap ) { unsigned InstOffset = <NUM_LIT> ; for ( auto & B : MF ) { if ( B . getAlignment ( ) ) { int ByteAlign = ( <NUM_LIT> << B . getAlignment ( ) ) - <NUM_LIT> ; InstOffset = ( InstOffset + ByteAlign ) & ~ ( ByteAlign ) ; }


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


<s> MachineFunctionPass :: getAnalysisUsage ( AU ) ;


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


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

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


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

if ( & MI != & * SecondTerm ) return false ;


<s> bool <ISA_LIT>BranchRelaxation :: reGenerateBranch ( MachineFunction & MF , DenseMap < MachineBasicBlock * , unsigned > & BlockToInstOffset ) { bool Changed = false ; for ( auto & B : MF ) { for ( auto & MI : B ) { if ( ! MI . isBranch ( ) || ! isJumpOutOfRange ( MI , BlockToInstOffset ) ) continue ; DEBUG ( dbgs ( ) << <STR_LIT> << HII -> isExtendable ( MI ) << <STR_LIT> << HII -> isConstExtended ( MI ) << <STR_LIT> << MI ) ; if ( ! HII -> isExtendable ( MI ) && ! HII -> isExtended ( MI ) ) { DEBUG ( dbgs ( ) << <STR_LIT> ) ; } else { int ExtOpNum = HII -> getCExtOpNum ( MI ) ;

MachineOperand & MO = MI . getOperand ( ExtOpNum ) ;


<s> DenseMap < MachineBasicBlock * , unsigned > BlockToInstOffset ; computeOffset ( MF , BlockToInstOffset ) ; return reGenerateBranch ( MF , BlockToInstOffset ) ;


<s> bool <ISA_LIT>BranchRelaxation :: relaxBranches ( MachineFunction & MF ) { DenseMap < MachineBasicBlock * , unsigned > BlockToInstOffset ; computeOffset ( MF , BlockToInstOffset ) ; return reGenerateBranch ( MF , BlockToInstOffset ) ;


<s> bool <ISA_LIT>BranchRelaxation :: runOnMachineFunction ( MachineFunction & MF ) { DEBUG ( dbgs ( ) << <STR_LIT> ) ; auto & HST = MF . getSubtarget < <ISA_LIT>Subtarget > ( ) ;


<s> HII = HST . getInstrInfo ( ) ; HRI = HST . getRegisterInfo ( ) ; bool Changed = false ;


<s> <ISA_LIT>_CCState :: <ISA_LIT>_CCState ( CallingConv :: ID CC , bool isVarArg , const TargetMachine & tm , SmallVector < CCValAssign , <NUM_LIT> > & locs , LLVMContext & c ) : CallingConv ( CC ) , IsVarArg ( isVarArg ) , TM ( tm ) , TRI ( * TM . getRegisterInfo ( ) ) , Locs ( locs ) , Context ( c ) { StackOffset = <NUM_LIT> ; UsedRegs . resize ( ( TRI . getNumRegs ( ) + <NUM_LIT> ) / <NUM_LIT> ) ;


<s> void <ISA_LIT>_CCState :: MarkAllocated ( unsigned Reg ) {

UsedRegs [ Reg / <NUM_LIT> ] |= <NUM_LIT> << ( Reg & <NUM_LIT> ) ;


UsedRegs . resize ( ( TM . getRegisterInfo ( ) -> getNumRegs ( ) + <NUM_LIT> ) / <NUM_LIT> ) ;


for ( MCRegAliasIterator AI ( Reg , & TRI , true ) ; AI . isValid ( ) ; ++ AI ) UsedRegs [ * AI / <NUM_LIT> ] |= <NUM_LIT> << ( * AI & <NUM_LIT> ) ;


<s> for ( MCRegAliasIterator AI ( Reg , & TRI , true ) ; AI . isValid ( ) ; ++ AI ) UsedRegs [ * AI / <NUM_LIT> ] |= <NUM_LIT> << ( * AI & <NUM_LIT> ) ;


<s> StackOffset = <NUM_LIT> ; UsedRegs . resize ( ( TM . getSubtargetImpl ( ) -> getRegisterInfo ( ) -> getNumRegs ( ) + <NUM_LIT> ) / <NUM_LIT> ) ;


<s> UsedRegs [ Reg / <NUM_LIT> ] |= <NUM_LIT> << ( Reg & <NUM_LIT> ) ;

if ( const unsigned * RegAliases = TRI . getAliasSet ( Reg ) ) for ( ; ( Reg = * RegAliases ) ; ++ RegAliases ) UsedRegs [ Reg / <NUM_LIT> ] |= <NUM_LIT> << ( Reg & <NUM_LIT> ) ;


<s> void addLoc ( const CCValAssign & V ) { Locs . push_back ( V ) ;


<s> void addLoc ( const CCValAssign & V ) {


<s> unsigned Reg = Regs [ FirstUnalloc ] , ShadowReg = ShadowRegs [ FirstUnalloc ] ; MarkAllocated ( Reg ) ; MarkAllocated ( ShadowReg ) ; return Reg ;


<s> unsigned AllocateReg ( const unsigned * Regs , const unsigned * ShadowRegs , unsigned NumRegs ) { unsigned FirstUnalloc = getFirstUnallocated ( Regs , NumRegs ) ; if ( FirstUnalloc == NumRegs ) return <NUM_LIT> ; unsigned Reg = Regs [ FirstUnalloc ] , ShadowReg = ShadowRegs [ FirstUnalloc ] ; MarkAllocated ( Reg ) ;


<s> assert ( Align && ( ( Align - <NUM_LIT> ) & Align ) == <NUM_LIT> ) ; StackOffset = ( ( StackOffset + Align - <NUM_LIT> ) & ~ ( Align - <NUM_LIT> ) ) ; unsigned Result = StackOffset ;


<s> for ( unsigned i = <NUM_LIT> ; i != NumOps ; ++ i ) { EVT ArgVT = ArgVTs [ i ] ; <STR_LIT> ArgFlags = Flags [ i ] ; if ( Fn ( i , ArgVT , ArgVT , CCValAssign :: Full , ArgFlags , * this , - <NUM_LIT> , - <NUM_LIT> , false ) ) { dbgs ( ) << <STR_LIT> << i << <STR_LIT> << ArgVT . getEVTString ( ) << <STR_LIT> ; abort ( ) ; }


<s> void <ISA_LIT>_CCState :: AnalyzeCallResult ( EVT VT , <ISA_LIT>_CCAssignFn Fn ) {

if ( Fn ( <NUM_LIT> , VT , VT , CCValAssign :: Full , <STR_LIT> ( ) , * this , - <NUM_LIT> , - <NUM_LIT> , false ) ) {


<s> EVT ArgVT = Ins [ i ] . VT ; <STR_LIT> ArgFlags = Ins [ i ] . Flags ;

if ( Fn ( i , ArgVT , ArgVT , CCValAssign :: Full , ArgFlags , * this , <NUM_LIT> , <NUM_LIT> , false ) ) {


<s> if ( SretValueInRegs <= <NUM_LIT> ) { unsigned Reg = <STR_LIT> ; addLoc ( CCValAssign :: getReg ( <NUM_LIT> , <STR_LIT> , Reg , <STR_LIT> , CCValAssign :: Full ) ) ; return ; } if ( SretValueInRegs <= <NUM_LIT> ) { unsigned Reg = <STR_LIT> ;


<s> LLVMContext & getContext ( ) const {


<s> unsigned getFirstUnallocated ( const unsigned * Regs , unsigned NumRegs ) const { for ( unsigned i = <NUM_LIT> ; i != NumRegs ; ++ i ) if ( ! isAllocated ( Regs [ i ] ) ) return i ;


<s> unsigned getNextStackOffset ( ) const {


<s> const TargetMachine & getTarget ( ) const { return TM ;


<s> const TargetMachine & getTarget ( ) const {


<s> if ( MinAlign > ( int ) Align ) Align = MinAlign ; unsigned Offset = AllocateStack ( Size , Align ) ; addLoc ( CCValAssign :: getMem ( ValNo , ValVT . getSimpleVT ( ) , Offset , LocVT . getSimpleVT ( ) , LocInfo ) ) ;


<s> void <ISA_LIT>_CCState :: HandleByVal ( unsigned ValNo , EVT ValVT , EVT LocVT , CCValAssign :: LocInfo LocInfo , int MinSize , int MinAlign , <STR_LIT> ArgFlags ) {

unsigned Align = ArgFlags . getByValAlign ( ) ;


<s> <ISA_LIT>_CCState :: <ISA_LIT>_CCState ( CallingConv :: ID CC , bool isVarArg , const TargetMachine & tm , SmallVectorImpl < CCValAssign > & locs , LLVMContext & c ) : CallingConv ( CC ) , IsVarArg ( isVarArg ) , TM ( tm ) , Locs ( locs ) , Context ( c ) { StackOffset = <NUM_LIT> ;


<s> bool isAllocated ( unsigned Reg ) const {

return UsedRegs [ Reg / <NUM_LIT> ] & ( <NUM_LIT> << ( Reg & <NUM_LIT> ) ) ;


<s> bool isVarArg ( ) const { return IsVarArg ;


<s> const TargetRegisterInfo & TRI = * TM . getRegisterInfo ( ) ; for ( MCRegAliasIterator AI ( Reg , & TRI , true ) ; AI . isValid ( ) ; ++ AI ) UsedRegs [ * AI / <NUM_LIT> ] |= <NUM_LIT> << ( * AI & <NUM_LIT> ) ;


<s> void <ISA_LIT>_CCState :: MarkAllocated ( unsigned Reg ) { const TargetRegisterInfo & TRI = * TM . getRegisterInfo ( ) ;


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


<s> StringRef getPassName ( ) const override {


<s> return MachineFunctionProperties ( ) . set ( MachineFunctionProperties :: Property :: NoVRegs ) ;


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


<s> break ; case <STR_LIT> : NewOpcode = <STR_LIT> ; break ; case <STR_LIT> : NewOpcode = <STR_LIT> ; break ; case <STR_LIT> : NewOpcode = <STR_LIT> ; break ; default : llvm_unreachable ( <STR_LIT> ) ; } MI . setDesc ( TII -> get ( NewOpcode ) ) ; MI . getOperand ( <NUM_LIT> ) . setMBB ( NewTarget ) ;


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


<s> bool <ISA_LIT>CFGOptimizer :: isOnFallThroughPath ( MachineBasicBlock * MBB ) { if ( MBB -> canFallThrough ( ) ) return true ; for ( MachineBasicBlock * PB : MBB -> predecessors ( ) ) if ( PB -> isLayoutSuccessor ( MBB ) && PB -> canFallThrough ( ) ) return true ;


<s> if ( MBB -> canFallThrough ( ) ) return true ; for ( MachineBasicBlock * PB : MBB -> predecessors ( ) ) if ( PB -> isLayoutSuccessor ( MBB ) && PB -> canFallThrough ( ) ) return true ;


<s> static bool IsUnconditionalJump ( int Opc ) {


<s> MBBb != MBBe ; ++ MBBb ) { MachineBasicBlock * MBB = & * MBBb ; MachineBasicBlock :: iterator MII = MBB -> getFirstTerminator ( ) ; if ( MII != MBB -> end ( ) ) { MachineInstr & MI = * MII ; int Opc = MI . getOpcode ( ) ; if ( IsConditionalBranch ( Opc ) ) { unsigned NumSuccs = MBB -> succ_size ( ) ; MachineBasicBlock :: succ_iterator SI = MBB -> succ_begin ( ) ; MachineBasicBlock * FirstSucc = * SI ; MachineBasicBlock * SecondSucc = * ( ++ SI ) ; MachineBasicBlock * LayoutSucc = nullptr ; MachineBasicBlock * JumpAroundTarget = nullptr ; if ( MBB -> isLayoutSuccessor ( FirstSucc ) ) { LayoutSucc = FirstSucc ; JumpAroundTarget = SecondSucc ; } else if ( MBB -> isLayoutSuccessor ( SecondSucc ) ) { LayoutSucc = SecondSucc ; JumpAroundTarget = FirstSucc ; } else { } MachineBasicBlock * CondBranchTarget = nullptr ; if ( MI . getOpcode ( ) == <STR_LIT> || MI . getOpcode ( ) == <STR_LIT> ) { CondBranchTarget = MI . getOperand ( <NUM_LIT> ) . getMBB ( ) ; } if ( ! LayoutSucc || ( CondBranchTarget != JumpAroundTarget ) ) { continue ; } if ( ( NumSuccs == <NUM_LIT> ) && LayoutSucc && ( LayoutSucc -> pred_size ( ) == <NUM_LIT> ) ) { if ( ( LayoutSucc -> size ( ) == <NUM_LIT> ) && IsUnconditionalJump ( LayoutSucc -> front ( ) . getOpcode ( ) ) ) { assert ( JumpAroundTarget && <STR_LIT> ) ;

MachineBasicBlock * UncondTarget = LayoutSucc -> front ( ) . getOperand ( <NUM_LIT> ) . getMBB ( ) ;


<s> MachineBasicBlock :: iterator MII = MBB -> getFirstTerminator ( ) ; if ( MII != MBB -> end ( ) ) { MachineInstr * MI = MII ; int Opc = MI -> getOpcode ( ) ; if ( IsConditionalBranch ( Opc ) ) { unsigned NumSuccs = MBB -> succ_size ( ) ; MachineBasicBlock :: succ_iterator SI = MBB -> succ_begin ( ) ; MachineBasicBlock * FirstSucc = * SI ; MachineBasicBlock * SecondSucc = * ( ++ SI ) ; MachineBasicBlock * LayoutSucc = nullptr ; MachineBasicBlock * JumpAroundTarget = nullptr ; if ( MBB -> isLayoutSuccessor ( FirstSucc ) ) { LayoutSucc = FirstSucc ; JumpAroundTarget = SecondSucc ; } else if ( MBB -> isLayoutSuccessor ( SecondSucc ) ) { LayoutSucc = SecondSucc ; JumpAroundTarget = FirstSucc ; } else { } MachineBasicBlock * CondBranchTarget = nullptr ; if ( ( MI -> getOpcode ( ) == <STR_LIT> ) || ( MI -> getOpcode ( ) == <STR_LIT> ) ) { CondBranchTarget = MI -> getOperand ( <NUM_LIT> ) . getMBB ( ) ; } if ( ! LayoutSucc || ( CondBranchTarget != JumpAroundTarget ) ) { continue ; } if ( ( NumSuccs == <NUM_LIT> ) && LayoutSucc && ( LayoutSucc -> pred_size ( ) == <NUM_LIT> ) ) { if ( ( LayoutSucc -> size ( ) == <NUM_LIT> ) && IsUnconditionalJump ( LayoutSucc -> front ( ) . getOpcode ( ) ) ) { MachineBasicBlock * UncondTarget = LayoutSucc -> front ( ) . getOperand ( <NUM_LIT> ) . getMBB ( ) ; bool case1 = LayoutSucc -> isLayoutSuccessor ( JumpAroundTarget ) ; bool case2 = JumpAroundTarget -> isSuccessor ( UncondTarget ) && JumpAroundTarget -> size ( ) >= <NUM_LIT> && IsUnconditionalJump ( JumpAroundTarget -> back ( ) . getOpcode ( ) ) && JumpAroundTarget -> pred_size ( ) == <NUM_LIT> && JumpAroundTarget -> succ_size ( ) == <NUM_LIT> ; if ( case1 || case2 ) { InvertAndChangeJumpTarget ( MI , UncondTarget ) ; MBB -> removeSuccessor ( JumpAroundTarget ) ; MBB -> addSuccessor ( UncondTarget ) ; LayoutSucc -> erase ( LayoutSucc -> begin ( ) ) ; LayoutSucc -> removeSuccessor ( UncondTarget ) ; LayoutSucc -> addSuccessor ( JumpAroundTarget ) ; if ( case2 && ! case1 ) {

JumpAroundTarget -> moveAfter ( LayoutSucc ) ;


<s> } MachineBasicBlock * CondBranchTarget = nullptr ; if ( MI . getOpcode ( ) == <STR_LIT> || MI . getOpcode ( ) == <STR_LIT> ) { CondBranchTarget = MI . getOperand ( <NUM_LIT> ) . getMBB ( ) ; } if ( ! LayoutSucc || ( CondBranchTarget != JumpAroundTarget ) ) { continue ; } if ( ( NumSuccs == <NUM_LIT> ) && LayoutSucc && ( LayoutSucc -> pred_size ( ) == <NUM_LIT> ) ) { if ( ( LayoutSucc -> size ( ) == <NUM_LIT> ) && IsUnconditionalJump ( LayoutSucc -> front ( ) . getOpcode ( ) ) ) { assert ( JumpAroundTarget && <STR_LIT> ) ; MachineBasicBlock * UncondTarget = LayoutSucc -> front ( ) . getOperand ( <NUM_LIT> ) . getMBB ( ) ; bool case1 = LayoutSucc -> isLayoutSuccessor ( JumpAroundTarget ) ; bool case2 = JumpAroundTarget -> isSuccessor ( UncondTarget ) && ! JumpAroundTarget -> empty ( ) && IsUnconditionalJump ( JumpAroundTarget -> back ( ) . getOpcode ( ) ) && JumpAroundTarget -> pred_size ( ) == <NUM_LIT> && JumpAroundTarget -> succ_size ( ) == <NUM_LIT> ; if ( case1 || case2 ) { InvertAndChangeJumpTarget ( MI , UncondTarget ) ; MBB . replaceSuccessor ( JumpAroundTarget , UncondTarget ) ; LayoutSucc -> erase ( LayoutSucc -> begin ( ) ) ; LayoutSucc -> replaceSuccessor ( UncondTarget , JumpAroundTarget ) ; if ( case2 && ! case1 ) { JumpAroundTarget -> moveAfter ( LayoutSucc ) ; if ( ! isOnFallThroughPath ( UncondTarget ) ) UncondTarget -> moveAfter ( JumpAroundTarget ) ; } std :: vector < MachineBasicBlock :: RegisterMaskPair > OrigLiveIn ( LayoutSucc -> livein_begin ( ) , LayoutSucc -> livein_end ( ) ) ; std :: vector < MachineBasicBlock :: RegisterMaskPair > NewLiveIn ( JumpAroundTarget -> livein_begin ( ) , JumpAroundTarget -> livein_end ( ) ) ;

for ( const auto & OrigLI : OrigLiveIn ) LayoutSucc -> removeLiveIn ( OrigLI . PhysReg ) ;


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

return new <ISA_LIT>CFGOptimizer ( TM ) ;


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


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

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


<s> void <ISA_LIT>CFGOptimizer :: InvertAndChangeJumpTarget ( MachineInstr * MI , MachineBasicBlock * NewTarget ) { const <ISA_LIT>InstrInfo * QII = QTM . getInstrInfo ( ) ; int NewOpcode = <NUM_LIT> ; switch ( MI -> getOpcode ( ) ) { case <STR_LIT> : NewOpcode = <STR_LIT> ; break ; case <STR_LIT> : NewOpcode = <STR_LIT> ; break ; case <STR_LIT> : NewOpcode = <STR_LIT> ; break ; case <STR_LIT> :


<s> void <ISA_LIT>CFGOptimizer :: InvertAndChangeJumpTarget ( MachineInstr * MI , MachineBasicBlock * NewTarget ) { const <ISA_LIT>InstrInfo * QII = QTM . getInstrInfo ( ) ; int NewOpcode = <NUM_LIT> ; switch ( MI -> getOpcode ( ) ) { case <STR_LIT> : NewOpcode = <STR_LIT> ; break ; case <STR_LIT> : NewOpcode = <STR_LIT> ; break ; case <STR_LIT> : NewOpcode = <STR_LIT> ; break ; case <STR_LIT> : NewOpcode = <STR_LIT> ; break ; default : llvm_unreachable ( <STR_LIT> ) ; } MI -> setDesc ( QII -> get ( NewOpcode ) ) ;

MI -> getOperand ( <NUM_LIT> ) . setMBB ( NewTarget ) ;


<s> static bool IsConditionalBranch ( int Opc ) {

return ( Opc == <STR_LIT> ) || ( Opc == <STR_LIT> ) || ( Opc == <STR_LIT> ) || ( Opc == <STR_LIT> ) ;


<s> if ( IsConditionalBranch ( Opc ) ) { unsigned NumSuccs = MBB -> succ_size ( ) ; MachineBasicBlock :: succ_iterator SI = MBB -> succ_begin ( ) ; MachineBasicBlock * FirstSucc = * SI ; MachineBasicBlock * SecondSucc = * ( ++ SI ) ; MachineBasicBlock * LayoutSucc = nullptr ; MachineBasicBlock * JumpAroundTarget = nullptr ; if ( MBB -> isLayoutSuccessor ( FirstSucc ) ) { LayoutSucc = FirstSucc ; JumpAroundTarget = SecondSucc ; } else if ( MBB -> isLayoutSuccessor ( SecondSucc ) ) { LayoutSucc = SecondSucc ; JumpAroundTarget = FirstSucc ; } else { } MachineBasicBlock * CondBranchTarget = nullptr ; if ( ( MI -> getOpcode ( ) == <STR_LIT> ) || ( MI -> getOpcode ( ) == <STR_LIT> ) ) { CondBranchTarget = MI -> getOperand ( <NUM_LIT> ) . getMBB ( ) ; } if ( ! LayoutSucc || ( CondBranchTarget != JumpAroundTarget ) ) { continue ; } if ( ( NumSuccs == <NUM_LIT> ) && LayoutSucc && ( LayoutSucc -> pred_size ( ) == <NUM_LIT> ) ) { if ( ( LayoutSucc -> size ( ) == <NUM_LIT> ) && IsUnconditionalJump ( LayoutSucc -> front ( ) . getOpcode ( ) ) ) { MachineBasicBlock * UncondTarget = LayoutSucc -> front ( ) . getOperand ( <NUM_LIT> ) . getMBB ( ) ; bool case1 = LayoutSucc -> isLayoutSuccessor ( JumpAroundTarget ) ; bool case2 = JumpAroundTarget -> isSuccessor ( UncondTarget ) && JumpAroundTarget -> size ( ) >= <NUM_LIT> && IsUnconditionalJump ( JumpAroundTarget -> back ( ) . getOpcode ( ) ) && JumpAroundTarget -> pred_size ( ) == <NUM_LIT> && JumpAroundTarget -> succ_size ( ) == <NUM_LIT> ; if ( case1 || case2 ) { InvertAndChangeJumpTarget ( MI , UncondTarget ) ; MBB -> removeSuccessor ( JumpAroundTarget ) ; MBB -> addSuccessor ( UncondTarget ) ; LayoutSucc -> erase ( LayoutSucc -> begin ( ) ) ; LayoutSucc -> removeSuccessor ( UncondTarget ) ; LayoutSucc -> addSuccessor ( JumpAroundTarget ) ; if ( case2 && ! case1 ) { JumpAroundTarget -> moveAfter ( LayoutSucc ) ; if ( ! UncondTarget -> canFallThrough ( ) ) { UncondTarget -> moveAfter ( JumpAroundTarget ) ; } } std :: vector < unsigned > OrigLiveIn ( LayoutSucc -> livein_begin ( ) , LayoutSucc -> livein_end ( ) ) ; std :: vector < unsigned > NewLiveIn ( JumpAroundTarget -> livein_begin ( ) , JumpAroundTarget -> livein_end ( ) ) ; for ( unsigned i = <NUM_LIT> ; i < OrigLiveIn . size ( ) ; ++ i ) { LayoutSucc -> removeLiveIn ( OrigLiveIn [ i ] ) ; } for ( unsigned i = <NUM_LIT> ; i < NewLiveIn . size ( ) ; ++ i ) { LayoutSucc -> addLiveIn ( NewLiveIn [ i ] ) ; } }


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


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


<s> NewOpcode = <STR_LIT> ; break ; case <STR_LIT> : NewOpcode = <STR_LIT> ; break ; default : llvm_unreachable ( <STR_LIT> ) ; } MI -> setDesc ( QII -> get ( NewOpcode ) ) ; MI -> getOperand ( <NUM_LIT> ) . setMBB ( NewTarget ) ;


<s> return ( Opc == <STR_LIT> ) || ( Opc == <STR_LIT> ) || ( Opc == <STR_LIT> ) || ( Opc == <STR_LIT> ) ;


<s> InvertAndChangeJumpTarget ( MI , UncondTarget ) ; MBB -> removeSuccessor ( JumpAroundTarget ) ; MBB -> addSuccessor ( UncondTarget ) ; LayoutSucc -> erase ( LayoutSucc -> begin ( ) ) ; LayoutSucc -> removeSuccessor ( UncondTarget ) ; LayoutSucc -> addSuccessor ( JumpAroundTarget ) ; if ( case2 && ! case1 ) { JumpAroundTarget -> moveAfter ( LayoutSucc ) ; if ( ! UncondTarget -> canFallThrough ( ) ) { UncondTarget -> moveAfter ( JumpAroundTarget ) ; } } std :: vector < unsigned > OrigLiveIn ( LayoutSucc -> livein_begin ( ) , LayoutSucc -> livein_end ( ) ) ; std :: vector < unsigned > NewLiveIn ( JumpAroundTarget -> livein_begin ( ) , JumpAroundTarget -> livein_end ( ) ) ; for ( unsigned i = <NUM_LIT> ; i < OrigLiveIn . size ( ) ; ++ i ) { LayoutSucc -> removeLiveIn ( OrigLiveIn [ i ] ) ; } for ( unsigned i = <NUM_LIT> ; i < NewLiveIn . size ( ) ; ++ i ) { LayoutSucc -> addLiveIn ( NewLiveIn [ i ] ) ; } } } }


<s> if ( IsConditionalBranch ( Opc ) ) { unsigned NumSuccs = MBB -> succ_size ( ) ; MachineBasicBlock :: succ_iterator SI = MBB -> succ_begin ( ) ; MachineBasicBlock * FirstSucc = * SI ; MachineBasicBlock * SecondSucc = * ( ++ SI ) ; MachineBasicBlock * LayoutSucc = nullptr ; MachineBasicBlock * JumpAroundTarget = nullptr ; if ( MBB -> isLayoutSuccessor ( FirstSucc ) ) { LayoutSucc = FirstSucc ; JumpAroundTarget = SecondSucc ; } else if ( MBB -> isLayoutSuccessor ( SecondSucc ) ) { LayoutSucc = SecondSucc ; JumpAroundTarget = FirstSucc ; } else { } MachineBasicBlock * CondBranchTarget = nullptr ; if ( MI . getOpcode ( ) == <STR_LIT> || MI . getOpcode ( ) == <STR_LIT> ) { CondBranchTarget = MI . getOperand ( <NUM_LIT> ) . getMBB ( ) ; } if ( ! LayoutSucc || ( CondBranchTarget != JumpAroundTarget ) ) { continue ; } if ( ( NumSuccs == <NUM_LIT> ) && LayoutSucc && ( LayoutSucc -> pred_size ( ) == <NUM_LIT> ) ) { if ( ( LayoutSucc -> size ( ) == <NUM_LIT> ) && IsUnconditionalJump ( LayoutSucc -> front ( ) . getOpcode ( ) ) ) { assert ( JumpAroundTarget && <STR_LIT> ) ; MachineBasicBlock * UncondTarget = LayoutSucc -> front ( ) . getOperand ( <NUM_LIT> ) . getMBB ( ) ; bool case1 = LayoutSucc -> isLayoutSuccessor ( JumpAroundTarget ) ; bool case2 = JumpAroundTarget -> isSuccessor ( UncondTarget ) && ! JumpAroundTarget -> empty ( ) && IsUnconditionalJump ( JumpAroundTarget -> back ( ) . getOpcode ( ) ) && JumpAroundTarget -> pred_size ( ) == <NUM_LIT> && JumpAroundTarget -> succ_size ( ) == <NUM_LIT> ; if ( case1 || case2 ) { InvertAndChangeJumpTarget ( MI , UncondTarget ) ; MBB -> replaceSuccessor ( JumpAroundTarget , UncondTarget ) ; LayoutSucc -> erase ( LayoutSucc -> begin ( ) ) ; LayoutSucc -> replaceSuccessor ( UncondTarget , JumpAroundTarget ) ; if ( case2 && ! case1 ) {


<s> unsigned NumSuccs = MBB -> succ_size ( ) ; MachineBasicBlock :: succ_iterator SI = MBB -> succ_begin ( ) ; MachineBasicBlock * FirstSucc = * SI ; MachineBasicBlock * SecondSucc = * ( ++ SI ) ; MachineBasicBlock * LayoutSucc = nullptr ; MachineBasicBlock * JumpAroundTarget = nullptr ; if ( MBB -> isLayoutSuccessor ( FirstSucc ) ) { LayoutSucc = FirstSucc ; JumpAroundTarget = SecondSucc ; } else if ( MBB -> isLayoutSuccessor ( SecondSucc ) ) { LayoutSucc = SecondSucc ; JumpAroundTarget = FirstSucc ; } else { } MachineBasicBlock * CondBranchTarget = nullptr ; if ( ( MI -> getOpcode ( ) == <STR_LIT> ) || ( MI -> getOpcode ( ) == <STR_LIT> ) ) { CondBranchTarget = MI -> getOperand ( <NUM_LIT> ) . getMBB ( ) ; } if ( ! LayoutSucc || ( CondBranchTarget != JumpAroundTarget ) ) { continue ; } if ( ( NumSuccs == <NUM_LIT> ) && LayoutSucc && ( LayoutSucc -> pred_size ( ) == <NUM_LIT> ) ) { if ( ( LayoutSucc -> size ( ) == <NUM_LIT> ) && IsUnconditionalJump ( LayoutSucc -> front ( ) . getOpcode ( ) ) ) { MachineBasicBlock * UncondTarget = LayoutSucc -> front ( ) . getOperand ( <NUM_LIT> ) . getMBB ( ) ; bool case1 = LayoutSucc -> isLayoutSuccessor ( JumpAroundTarget ) ; bool case2 = JumpAroundTarget -> isSuccessor ( UncondTarget ) && JumpAroundTarget -> size ( ) >= <NUM_LIT> && IsUnconditionalJump ( JumpAroundTarget -> back ( ) . getOpcode ( ) ) && JumpAroundTarget -> pred_size ( ) == <NUM_LIT> && JumpAroundTarget -> succ_size ( ) == <NUM_LIT> ; if ( case1 || case2 ) { InvertAndChangeJumpTarget ( MI , UncondTarget ) ; MBB -> removeSuccessor ( JumpAroundTarget ) ; MBB -> addSuccessor ( UncondTarget ) ; LayoutSucc -> erase ( LayoutSucc -> begin ( ) ) ; LayoutSucc -> removeSuccessor ( UncondTarget ) ; LayoutSucc -> addSuccessor ( JumpAroundTarget ) ; if ( case2 && ! case1 ) { JumpAroundTarget -> moveAfter ( LayoutSucc ) ; if ( ! UncondTarget -> canFallThrough ( ) ) { UncondTarget -> moveAfter ( JumpAroundTarget ) ; } } std :: vector < MachineBasicBlock :: RegisterMaskPair > OrigLiveIn ( LayoutSucc -> livein_begin ( ) , LayoutSucc -> livein_end ( ) ) ; std :: vector < MachineBasicBlock :: RegisterMaskPair > NewLiveIn ( JumpAroundTarget -> livein_begin ( ) , JumpAroundTarget -> livein_end ( ) ) ; for ( const auto & OrigLI : OrigLiveIn ) LayoutSucc -> removeLiveIn ( OrigLI . PhysReg ) ; for ( const auto & NewLI : NewLiveIn ) LayoutSucc -> addLiveIn ( NewLI ) ; } } }


<s> if ( ( LayoutSucc -> size ( ) == <NUM_LIT> ) && IsUnconditionalJump ( LayoutSucc -> front ( ) . getOpcode ( ) ) ) { MachineBasicBlock * UncondTarget = LayoutSucc -> front ( ) . getOperand ( <NUM_LIT> ) . getMBB ( ) ; bool case1 = LayoutSucc -> isLayoutSuccessor ( JumpAroundTarget ) ; bool case2 = JumpAroundTarget -> isSuccessor ( UncondTarget ) && JumpAroundTarget -> size ( ) >= <NUM_LIT> && IsUnconditionalJump ( JumpAroundTarget -> back ( ) . getOpcode ( ) ) && JumpAroundTarget -> pred_size ( ) == <NUM_LIT> && JumpAroundTarget -> succ_size ( ) == <NUM_LIT> ; if ( case1 || case2 ) { InvertAndChangeJumpTarget ( MI , UncondTarget ) ; MBB -> replaceSuccessor ( JumpAroundTarget , UncondTarget ) ; LayoutSucc -> erase ( LayoutSucc -> begin ( ) ) ; LayoutSucc -> replaceSuccessor ( UncondTarget , JumpAroundTarget ) ; if ( case2 && ! case1 ) { JumpAroundTarget -> moveAfter ( LayoutSucc ) ; if ( ! UncondTarget -> canFallThrough ( ) ) { UncondTarget -> moveAfter ( JumpAroundTarget ) ; } } std :: vector < MachineBasicBlock :: RegisterMaskPair > OrigLiveIn ( LayoutSucc -> livein_begin ( ) , LayoutSucc -> livein_end ( ) ) ; std :: vector < MachineBasicBlock :: RegisterMaskPair > NewLiveIn ( JumpAroundTarget -> livein_begin ( ) , JumpAroundTarget -> livein_end ( ) ) ; for ( const auto & OrigLI : OrigLiveIn ) LayoutSucc -> removeLiveIn ( OrigLI . PhysReg ) ; for ( const auto & NewLI : NewLiveIn ) LayoutSucc -> addLiveIn ( NewLI ) ; } }


<s> } else { } MachineBasicBlock * CondBranchTarget = nullptr ; if ( MI . getOpcode ( ) == <STR_LIT> || MI . getOpcode ( ) == <STR_LIT> ) { CondBranchTarget = MI . getOperand ( <NUM_LIT> ) . getMBB ( ) ; } if ( ! LayoutSucc || ( CondBranchTarget != JumpAroundTarget ) ) { continue ; } if ( ( NumSuccs == <NUM_LIT> ) && LayoutSucc && ( LayoutSucc -> pred_size ( ) == <NUM_LIT> ) ) { if ( ( LayoutSucc -> size ( ) == <NUM_LIT> ) && IsUnconditionalJump ( LayoutSucc -> front ( ) . getOpcode ( ) ) ) { assert ( JumpAroundTarget && <STR_LIT> ) ; MachineBasicBlock * UncondTarget = LayoutSucc -> front ( ) . getOperand ( <NUM_LIT> ) . getMBB ( ) ; bool case1 = LayoutSucc -> isLayoutSuccessor ( JumpAroundTarget ) ; bool case2 = JumpAroundTarget -> isSuccessor ( UncondTarget ) && JumpAroundTarget -> size ( ) >= <NUM_LIT> && IsUnconditionalJump ( JumpAroundTarget -> back ( ) . getOpcode ( ) ) && JumpAroundTarget -> pred_size ( ) == <NUM_LIT> && JumpAroundTarget -> succ_size ( ) == <NUM_LIT> ; if ( case1 || case2 ) { InvertAndChangeJumpTarget ( MI , UncondTarget ) ; MBB -> replaceSuccessor ( JumpAroundTarget , UncondTarget ) ; LayoutSucc -> erase ( LayoutSucc -> begin ( ) ) ; LayoutSucc -> replaceSuccessor ( UncondTarget , JumpAroundTarget ) ; if ( case2 && ! case1 ) { JumpAroundTarget -> moveAfter ( LayoutSucc ) ; if ( ! isOnFallThroughPath ( UncondTarget ) ) UncondTarget -> moveAfter ( JumpAroundTarget ) ; } std :: vector < MachineBasicBlock :: RegisterMaskPair > OrigLiveIn ( LayoutSucc -> livein_begin ( ) , LayoutSucc -> livein_end ( ) ) ; std :: vector < MachineBasicBlock :: RegisterMaskPair > NewLiveIn ( JumpAroundTarget -> livein_begin ( ) , JumpAroundTarget -> livein_end ( ) ) ; for ( const auto & OrigLI : OrigLiveIn ) LayoutSucc -> removeLiveIn ( OrigLI . PhysReg ) ; for ( const auto & NewLI : NewLiveIn ) LayoutSucc -> addLiveIn ( NewLI ) ; } } } } } } return true ;


<s> if ( MI . getOpcode ( ) == <STR_LIT> || MI . getOpcode ( ) == <STR_LIT> ) { CondBranchTarget = MI . getOperand ( <NUM_LIT> ) . getMBB ( ) ; } if ( ! LayoutSucc || ( CondBranchTarget != JumpAroundTarget ) ) { continue ; } if ( ( NumSuccs == <NUM_LIT> ) && LayoutSucc && ( LayoutSucc -> pred_size ( ) == <NUM_LIT> ) ) { if ( ( LayoutSucc -> size ( ) == <NUM_LIT> ) && IsUnconditionalJump ( LayoutSucc -> front ( ) . getOpcode ( ) ) ) { assert ( JumpAroundTarget && <STR_LIT> ) ; MachineBasicBlock * UncondTarget = LayoutSucc -> front ( ) . getOperand ( <NUM_LIT> ) . getMBB ( ) ; bool case1 = LayoutSucc -> isLayoutSuccessor ( JumpAroundTarget ) ; bool case2 = JumpAroundTarget -> isSuccessor ( UncondTarget ) && JumpAroundTarget -> size ( ) >= <NUM_LIT> && IsUnconditionalJump ( JumpAroundTarget -> back ( ) . getOpcode ( ) ) && JumpAroundTarget -> pred_size ( ) == <NUM_LIT> && JumpAroundTarget -> succ_size ( ) == <NUM_LIT> ; if ( case1 || case2 ) { InvertAndChangeJumpTarget ( MI , UncondTarget ) ; MBB -> replaceSuccessor ( JumpAroundTarget , UncondTarget ) ; LayoutSucc -> erase ( LayoutSucc -> begin ( ) ) ; LayoutSucc -> replaceSuccessor ( UncondTarget , JumpAroundTarget ) ; if ( case2 && ! case1 ) { JumpAroundTarget -> moveAfter ( LayoutSucc ) ; if ( ! isOnFallThroughPath ( UncondTarget ) ) UncondTarget -> moveAfter ( JumpAroundTarget ) ; } std :: vector < MachineBasicBlock :: RegisterMaskPair > OrigLiveIn ( LayoutSucc -> livein_begin ( ) , LayoutSucc -> livein_end ( ) ) ;

std :: vector < MachineBasicBlock :: RegisterMaskPair > NewLiveIn ( JumpAroundTarget -> livein_begin ( ) , JumpAroundTarget -> livein_end ( ) ) ;


<s> return MachineFunctionProperties ( ) . set ( MachineFunctionProperties :: Property :: AllVRegsAllocated ) ;


<s> MachineFunctionProperties getRequiredProperties ( ) const override {

return MachineFunctionProperties ( ) . set ( MachineFunctionProperties :: Property :: AllVRegsAllocated ) ;


<s> bool case2 = JumpAroundTarget -> isSuccessor ( UncondTarget ) && JumpAroundTarget -> size ( ) >= <NUM_LIT> && IsUnconditionalJump ( JumpAroundTarget -> back ( ) . getOpcode ( ) ) && JumpAroundTarget -> pred_size ( ) == <NUM_LIT> && JumpAroundTarget -> succ_size ( ) == <NUM_LIT> ; if ( case1 || case2 ) { InvertAndChangeJumpTarget ( MI , UncondTarget ) ; MBB -> replaceSuccessor ( JumpAroundTarget , UncondTarget ) ; LayoutSucc -> erase ( LayoutSucc -> begin ( ) ) ; LayoutSucc -> replaceSuccessor ( UncondTarget , JumpAroundTarget ) ; if ( case2 && ! case1 ) { JumpAroundTarget -> moveAfter ( LayoutSucc ) ; if ( ! UncondTarget -> canFallThrough ( ) ) { UncondTarget -> moveAfter ( JumpAroundTarget ) ; } } std :: vector < MachineBasicBlock :: RegisterMaskPair > OrigLiveIn ( LayoutSucc -> livein_begin ( ) , LayoutSucc -> livein_end ( ) ) ; std :: vector < MachineBasicBlock :: RegisterMaskPair > NewLiveIn ( JumpAroundTarget -> livein_begin ( ) , JumpAroundTarget -> livein_end ( ) ) ;


<s> bool case1 = LayoutSucc -> isLayoutSuccessor ( JumpAroundTarget ) ; bool case2 = JumpAroundTarget -> isSuccessor ( UncondTarget ) && JumpAroundTarget -> size ( ) >= <NUM_LIT> && IsUnconditionalJump ( JumpAroundTarget -> back ( ) . getOpcode ( ) ) && JumpAroundTarget -> pred_size ( ) == <NUM_LIT> && JumpAroundTarget -> succ_size ( ) == <NUM_LIT> ; if ( case1 || case2 ) { InvertAndChangeJumpTarget ( MI , UncondTarget ) ; MBB -> removeSuccessor ( JumpAroundTarget ) ; MBB -> addSuccessor ( UncondTarget ) ; LayoutSucc -> erase ( LayoutSucc -> begin ( ) ) ; LayoutSucc -> removeSuccessor ( UncondTarget ) ; LayoutSucc -> addSuccessor ( JumpAroundTarget ) ; if ( case2 && ! case1 ) { JumpAroundTarget -> moveAfter ( LayoutSucc ) ; if ( ! UncondTarget -> canFallThrough ( ) ) { UncondTarget -> moveAfter ( JumpAroundTarget ) ; } } std :: vector < unsigned > OrigLiveIn ( LayoutSucc -> livein_begin ( ) , LayoutSucc -> livein_end ( ) ) ;

std :: vector < unsigned > NewLiveIn ( JumpAroundTarget -> livein_begin ( ) , JumpAroundTarget -> livein_end ( ) ) ;


<s> void <ISA_LIT>CFGOptimizer :: InvertAndChangeJumpTarget ( MachineInstr * MI , MachineBasicBlock * NewTarget ) { const <ISA_LIT>InstrInfo * QII = QTM . getSubtargetImpl ( ) -> getInstrInfo ( ) ; int NewOpcode = <NUM_LIT> ; switch ( MI -> getOpcode ( ) ) { case <STR_LIT> : NewOpcode = <STR_LIT> ; break ; case <STR_LIT> : NewOpcode = <STR_LIT> ; break ; case <STR_LIT> : NewOpcode = <STR_LIT> ; break ; case <STR_LIT> :


<s> case <STR_LIT> : NewOpcode = <STR_LIT> ; break ; case <STR_LIT> : NewOpcode = <STR_LIT> ; break ; case <STR_LIT> : NewOpcode = <STR_LIT> ; break ; case <STR_LIT> : NewOpcode = <STR_LIT> ; break ; default :


<s> switch ( MI -> getOpcode ( ) ) { case <STR_LIT> : NewOpcode = <STR_LIT> ; break ; case <STR_LIT> : NewOpcode = <STR_LIT> ; break ; case <STR_LIT> : NewOpcode = <STR_LIT> ; break ; case <STR_LIT> : NewOpcode = <STR_LIT> ;


<s> switch ( MI -> getOpcode ( ) ) { case <STR_LIT> : NewOpcode = <STR_LIT> ; break ; case <STR_LIT> : NewOpcode = <STR_LIT> ; break ; case <STR_LIT> : NewOpcode = <STR_LIT> ; break ; case <STR_LIT> : NewOpcode = <STR_LIT> ; break ; default :


<s> MachineInstr * MI = MII ; int Opc = MI -> getOpcode ( ) ; if ( IsConditionalBranch ( Opc ) ) { unsigned NumSuccs = MBB -> succ_size ( ) ; MachineBasicBlock :: succ_iterator SI = MBB -> succ_begin ( ) ; MachineBasicBlock * FirstSucc = * SI ; MachineBasicBlock * SecondSucc = * ( ++ SI ) ; MachineBasicBlock * LayoutSucc = nullptr ; MachineBasicBlock * JumpAroundTarget = nullptr ; if ( MBB -> isLayoutSuccessor ( FirstSucc ) ) { LayoutSucc = FirstSucc ; JumpAroundTarget = SecondSucc ; } else if ( MBB -> isLayoutSuccessor ( SecondSucc ) ) { LayoutSucc = SecondSucc ; JumpAroundTarget = FirstSucc ; } else { } MachineBasicBlock * CondBranchTarget = nullptr ; if ( ( MI -> getOpcode ( ) == <STR_LIT> ) || ( MI -> getOpcode ( ) == <STR_LIT> ) ) { CondBranchTarget = MI -> getOperand ( <NUM_LIT> ) . getMBB ( ) ; } if ( ! LayoutSucc || ( CondBranchTarget != JumpAroundTarget ) ) { continue ; } if ( ( NumSuccs == <NUM_LIT> ) && LayoutSucc && ( LayoutSucc -> pred_size ( ) == <NUM_LIT> ) ) { if ( ( LayoutSucc -> size ( ) == <NUM_LIT> ) && IsUnconditionalJump ( LayoutSucc -> front ( ) . getOpcode ( ) ) ) { MachineBasicBlock * UncondTarget = LayoutSucc -> front ( ) . getOperand ( <NUM_LIT> ) . getMBB ( ) ; bool case1 = LayoutSucc -> isLayoutSuccessor ( JumpAroundTarget ) ; bool case2 = JumpAroundTarget -> isSuccessor ( UncondTarget ) && JumpAroundTarget -> size ( ) >= <NUM_LIT> && IsUnconditionalJump ( JumpAroundTarget -> back ( ) . getOpcode ( ) ) && JumpAroundTarget -> pred_size ( ) == <NUM_LIT> && JumpAroundTarget -> succ_size ( ) == <NUM_LIT> ; if ( case1 || case2 ) { InvertAndChangeJumpTarget ( MI , UncondTarget ) ; MBB -> removeSuccessor ( JumpAroundTarget ) ; MBB -> addSuccessor ( UncondTarget ) ; LayoutSucc -> erase ( LayoutSucc -> begin ( ) ) ; LayoutSucc -> removeSuccessor ( UncondTarget ) ; LayoutSucc -> addSuccessor ( JumpAroundTarget ) ; if ( case2 && ! case1 ) { JumpAroundTarget -> moveAfter ( LayoutSucc ) ; if ( ! UncondTarget -> canFallThrough ( ) ) { UncondTarget -> moveAfter ( JumpAroundTarget ) ; }


<s> if ( MII != MBB -> end ( ) ) { MachineInstr * MI = MII ; int Opc = MI -> getOpcode ( ) ; if ( IsConditionalBranch ( Opc ) ) { unsigned NumSuccs = MBB -> succ_size ( ) ; MachineBasicBlock :: succ_iterator SI = MBB -> succ_begin ( ) ; MachineBasicBlock * FirstSucc = * SI ; MachineBasicBlock * SecondSucc = * ( ++ SI ) ; MachineBasicBlock * LayoutSucc = nullptr ; MachineBasicBlock * JumpAroundTarget = nullptr ; if ( MBB -> isLayoutSuccessor ( FirstSucc ) ) { LayoutSucc = FirstSucc ; JumpAroundTarget = SecondSucc ; } else if ( MBB -> isLayoutSuccessor ( SecondSucc ) ) { LayoutSucc = SecondSucc ; JumpAroundTarget = FirstSucc ; } else { } MachineBasicBlock * CondBranchTarget = nullptr ; if ( ( MI -> getOpcode ( ) == <STR_LIT> ) || ( MI -> getOpcode ( ) == <STR_LIT> ) ) { CondBranchTarget = MI -> getOperand ( <NUM_LIT> ) . getMBB ( ) ; } if ( ! LayoutSucc || ( CondBranchTarget != JumpAroundTarget ) ) { continue ; }

if ( ( NumSuccs == <NUM_LIT> ) && LayoutSucc && ( LayoutSucc -> pred_size ( ) == <NUM_LIT> ) ) {


<s> IdxList [ IdxC ++ ] = ConstantInt :: get ( Int32Ty , <NUM_LIT> ) ; } while ( ++ nax <= Num ) { GepNode * N = NA [ nax - <NUM_LIT> ] ; IdxList [ IdxC ++ ] = N -> Idx ; if ( nax < Num ) { Type * NextTy = next_type ( N -> PTy , N -> Idx ) ; if ( NextTy != NA [ nax ] -> PTy ) break ; } } ArrayRef < Value * > A ( IdxList , IdxC ) ; Type * InpTy = Input -> getType ( ) ; Type * ElTy = cast < PointerType > ( InpTy -> getScalarType ( ) ) -> getElementType ( ) ; NewInst = GetElementPtrInst :: Create ( ElTy , Input , A , <STR_LIT> , & * At ) ;

DEBUG ( dbgs ( ) << <STR_LIT> << * NewInst << '\n' ) ;


<s> static BasicBlock :: iterator first_use_of_in_block ( T & Values , BasicBlock * B ) { BasicBlock :: iterator FirstUse = B -> end ( ) , BEnd = B -> end ( ) ; typedef typename T :: iterator iterator ; for ( iterator I = Values . begin ( ) , E = Values . end ( ) ; I != E ; ++ I ) { Value * V = * I ; if ( isa < PHINode > ( V ) ) continue ; if ( ! isa < Instruction > ( V ) ) continue ; Instruction * In = cast < Instruction > ( V ) ;

if ( In -> getParent ( ) != B ) continue ;


<s> GepNode ( ) : Flags ( <NUM_LIT> ) , Parent ( nullptr ) , Idx ( nullptr ) , PTy ( nullptr ) {


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

FunctionPass :: getAnalysisUsage ( AU ) ;


<s> void getAnalysisUsage ( AnalysisUsage & AU ) const override { AU . addRequired < DominatorTreeWrapperPass > ( ) ; AU . addPreserved < DominatorTreeWrapperPass > ( ) ; AU . addRequired < PostDominatorTreeWrapperPass > ( ) ;

AU . addPreserved < PostDominatorTreeWrapperPass > ( ) ;


<s> StringRef getPassName ( ) const override {


<s> static void invert_find_roots ( const NodeVect & Nodes , NodeChildrenMap & NCM , NodeVect & Roots ) { typedef NodeVect :: const_iterator const_iterator ; for ( const_iterator I = Nodes . begin ( ) , E = Nodes . end ( ) ; I != E ; ++ I ) { GepNode * N = * I ; if ( N -> Flags & GepNode :: Root ) { Roots . push_back ( N ) ;


<s> return B -> empty ( ) || ( & * B -> begin ( ) == B -> getTerminator ( ) ) ;


<s> LastUsed = ( Last -> Flags & GepNode :: Used ) ; if ( LastUsed ) break ; NodeChildrenMap :: iterator CF = NCM . find ( Last ) ; LastCN = ( CF != NCM . end ( ) ) ? CF -> second . size ( ) : <NUM_LIT> ; if ( LastCN != <NUM_LIT> ) break ; GepNode * Child = CF -> second . front ( ) ; BasicBlock * ChildB = cast_or_null < BasicBlock > ( Loc [ Child ] ) ; if ( ChildB != nullptr && LastB != ChildB ) break ; Last = Child ; } while ( true ) ; BasicBlock :: iterator InsertAt = LastB -> getTerminator ( ) -> getIterator ( ) ; if ( LastUsed || LastCN > <NUM_LIT> ) { ValueVect Urs ; getAllUsersForNode ( Root , Urs , NCM ) ; BasicBlock :: iterator FirstUse = first_use_of_in_block ( Urs , LastB ) ; if ( FirstUse != LastB -> end ( ) ) InsertAt = FirstUse ; } Value * NewInst = fabricateGEP ( NA , InsertAt , LastB ) ; if ( LastCN > <NUM_LIT> ) { NodeVect & Cs = NCM [ Last ] ; for ( NodeVect :: iterator I = Cs . begin ( ) , E = Cs . end ( ) ; I != E ; ++ I ) { GepNode * CN = * I ;


<s> NodeChildrenMap NCM ; NodeVect Roots ; invert_find_roots ( Nodes , NCM , Roots ) ; while ( ! Roots . empty ( ) ) { NodeVect :: iterator First = Roots . begin ( ) ; GepNode * Root = * First , * Last = * First ; Roots . erase ( First ) ; NodeVect NA ; bool LastUsed = false ; unsigned LastCN = <NUM_LIT> ; Value * LocV = Loc [ Last ] ; if ( ! LocV ) continue ; BasicBlock * LastB = cast < BasicBlock > ( LocV ) ; do { NA . push_back ( Last ) ; LastUsed = ( Last -> Flags & GepNode :: Used ) ; if ( LastUsed ) break ; NodeChildrenMap :: iterator CF = NCM . find ( Last ) ; LastCN = ( CF != NCM . end ( ) ) ? CF -> second . size ( ) : <NUM_LIT> ; if ( LastCN != <NUM_LIT> ) break ; GepNode * Child = CF -> second . front ( ) ; BasicBlock * ChildB = cast_or_null < BasicBlock > ( Loc [ Child ] ) ; if ( ChildB != nullptr && LastB != ChildB ) break ; Last = Child ; } while ( true ) ; BasicBlock :: iterator InsertAt = LastB -> getTerminator ( ) -> getIterator ( ) ; if ( LastUsed || LastCN > <NUM_LIT> ) { ValueVect Urs ; getAllUsersForNode ( Root , Urs , NCM ) ; BasicBlock :: iterator FirstUse = first_use_of_in_block ( Urs , LastB ) ; if ( FirstUse != LastB -> end ( ) ) InsertAt = FirstUse ; } Value * NewInst = fabricateGEP ( NA , InsertAt , LastB ) ; if ( LastCN > <NUM_LIT> ) { NodeVect & Cs = NCM [ Last ] ; for ( NodeVect :: iterator I = Cs . begin ( ) , E = Cs . end ( ) ; I != E ; ++ I ) { GepNode * CN = * I ; CN -> Flags &= ~ GepNode :: Internal ; CN -> Flags |= GepNode :: Root ; CN -> BaseVal = NewInst ; Roots . push_back ( CN ) ;


<s>
static
BasicBlock
*
nearest_common_dominator
(
DominatorTree
*
DT
,
T
&
Blocks
)
{
DEBUG
(
{
dbgs
(
)
<<
<STR_LIT>
;
for
(
typename
T
::
iterator
I
=
Blocks
.
begin
(
)
,
E
=
Blocks
.
end
(
)
;
I
!=
E
;
++
I
)
{
if
(
!
*
I
)
continue
;
BasicBlock
*
B
=
cast
<
BasicBlock
>
(
*
I
)
;
dbgs
(
)
<<
' '
<<
B
->
getName
(
)
;
}
dbgs
(
)
<<
<STR_LIT>
;


<s> for ( typename T :: iterator I = Blocks . begin ( ) , E = Blocks . end ( ) ;


<s> assert ( CI && <STR_LIT> ) ; int64_t i = CI -> getValue ( ) . getSExtValue ( ) ; Type * NextTy = cast < StructType > ( Ty ) -> getElementType ( i ) ;


<s> Work . push_back ( Root ) ; Nodes . insert ( Root ) ; while ( ! Work . empty ( ) ) { NodeVect :: iterator First = Work . begin ( ) ; GepNode * N = * First ; Work . erase ( First ) ; NodeChildrenMap :: iterator CF = NCM . find ( N ) ; if ( CF != NCM . end ( ) ) { Work . insert ( Work . end ( ) , CF -> second . begin ( ) , CF -> second . end ( ) ) ; Nodes . insert ( CF -> second . begin ( ) , CF -> second . end ( ) ) ; }


<s> static void nodes_for_root ( GepNode * Root , NodeChildrenMap & NCM , NodeSet & Nodes ) { NodeVect Work ; Work . push_back ( Root ) ; Nodes . insert ( Root ) ; while ( ! Work . empty ( ) ) { NodeVect :: iterator First = Work . begin ( ) ; GepNode * N = * First ;


<s> static const NodeSet * node_class ( GepNode * N , NodeSymRel & Rel ) { for ( NodeSymRel :: iterator I = Rel . begin ( ) , E = Rel . end ( ) ; I != E ; ++ I ) if ( I -> count ( N ) ) return & * I ;


<s> if ( node_hash ( N1 ) != node_hash ( N2 ) ) return false ; NodePair NP = node_pair ( N1 , N2 ) ; NodePairSet :: iterator FEq = Eq . find ( NP ) ; if ( FEq != Eq . end ( ) ) return true ; NodePairSet :: iterator FNe = Ne . find ( NP ) ;

if ( FNe != Ne . end ( ) ) return false ;


<s> if ( FEq != Eq . end ( ) ) return true ; NodePairSet :: iterator FNe = Ne . find ( NP ) ; if ( FNe != Ne . end ( ) ) return false ; bool Root1 = N1 -> Flags & GepNode :: Root ; bool Root2 = N2 -> Flags & GepNode :: Root ;


<s> ID . AddPointer ( N -> PTy ) ; return ID . ComputeHash ( ) ;


<s> static NodePair node_pair ( GepNode * N1 , GepNode * N2 ) { uintptr_t P1 = uintptr_t ( N1 ) , P2 = uintptr_t ( N2 ) ; if ( P1 <= P2 ) return std :: make_pair ( N1 , N2 ) ;


<s> if ( BasicBlock * PH = L -> getLoopPreheader ( ) ) return PH ;


<s> NodeToUsesMap :: iterator UF = Uses . find ( Node ) ; assert ( UF != Uses . end ( ) && <STR_LIT> ) ; UseSet & Us = UF -> second ; for ( UseSet :: iterator I = Us . begin ( ) , E = Us . end ( ) ; I != E ; ++ I ) { Use * U = * I ; User * R = U -> getUser ( ) ; if ( ! isa < Instruction > ( R ) ) continue ; BasicBlock * PB = isa < PHINode > ( R ) ? cast < PHINode > ( R ) -> getIncomingBlock ( * U ) : cast < Instruction > ( R ) -> getParent ( ) ;


<s> GepNode * N = Node ; GepNode * C = nullptr , * NewNode = nullptr ; while ( is_constant ( N ) && ! ( N -> Flags & GepNode :: Root ) ) { GepNode * NewN = new ( * Mem ) GepNode ( N ) ; Nodes . push_back ( NewN ) ; Loc [ NewN ] = PB ; if ( N == Node ) NewNode = NewN ; NewN -> Flags &= ~ GepNode :: Used ; if ( C ) C -> Parent = NewN ; C = NewN ; N = N -> Parent ; } if ( ! NewNode ) return ; NodeToUsesMap :: iterator UF = Uses . find ( Node ) ; assert ( UF != Uses . end ( ) ) ; UseSet & Us = UF -> second ; UseSet NewUs ; for ( UseSet :: iterator I = Us . begin ( ) ; I != Us . end ( ) ; ) { User * S = ( * I ) -> getUser ( ) ; UseSet :: iterator Nx = std :: next ( I ) ; if ( S == R ) { NewUs . insert ( * I ) ;


<s> for ( ValueVect :: iterator I = BO . begin ( ) , E = BO . end ( ) ; I != E ; ++ I ) { BasicBlock * B = cast < BasicBlock > ( * I ) ; for ( BasicBlock :: iterator J = B -> begin ( ) , F = B -> end ( ) ; J != F ; ++ J ) { if ( ! isa < GetElementPtrInst > ( J ) ) continue ; GetElementPtrInst * GepI = cast < GetElementPtrInst > ( J ) ; if ( isHandledGepForm ( GepI ) ) processGepInst ( GepI , NM ) ; } }

LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << Nodes ) ;


<s> ValueVect BO ; getBlockTraversalOrder ( & Fn -> front ( ) , BO ) ; ValueToNodeMap NM ; for ( ValueVect :: iterator I = BO . begin ( ) , E = BO . end ( ) ; I != E ; ++ I ) { BasicBlock * B = cast < BasicBlock > ( * I ) ; for ( BasicBlock :: iterator J = B -> begin ( ) , F = B -> end ( ) ; J != F ; ++ J ) { if ( ! isa < GetElementPtrInst > ( J ) ) continue ; GetElementPtrInst * GepI = cast < GetElementPtrInst > ( J ) ; if ( isHandledGepForm ( GepI ) ) processGepInst ( GepI , NM ) ; }


<s> NodeSet & S = I -> second ; for ( NodeSet :: iterator NI = S . begin ( ) , NE = S . end ( ) ; NI != NE ; ++ NI ) { GepNode * N = * NI ; if ( node_class ( N , EqRel ) ) continue ; NodeSet C ; for ( NodeSet :: iterator NJ = std :: next ( NI ) ; NJ != NE ; ++ NJ ) if ( node_eq ( N , * NJ , Eq , Ne ) ) C . insert ( * NJ ) ; if ( ! C . empty ( ) ) { C . insert ( N ) ; std :: pair < NodeSymRel :: iterator , bool > Ins = EqRel . insert ( C ) ; ( void ) Ins ; assert ( Ins . second && <STR_LIT> ) ; } } } LLVM_DEBUG ( { dbgs ( ) << <STR_LIT> ;

for ( NodePairSet :: iterator I = Eq . begin ( ) , E = Eq . end ( ) ; I != E ; ++ I ) dbgs ( ) << <STR_LIT> << I -> first << <STR_LIT> << I -> second << <STR_LIT> ;


<s> invert_find_roots ( Nodes , NCM , Roots ) ; for ( NodeVect :: iterator I = Roots . begin ( ) , E = Roots . end ( ) ; I != E ; ++ I ) recalculatePlacementRec ( * I , NCM , Loc ) ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << LocationAsBlock ( Loc ) ) ;


<s>
for
(
const_iterator
I
=
S
.
begin
(
)
,
E
=
S
.
end
(
)
;
I
!=
E
;
++
I
)
OS
<<
*
I
<<
' '
<<
*
*
I
<<
'\n'
;


<s> if ( NextTy != NA [ nax ] -> PTy ) break ; } } ArrayRef < Value * > A ( IdxList , IdxC ) ; Type * InpTy = Input -> getType ( ) ; Type * ElTy = cast < PointerType > ( InpTy -> getScalarType ( ) ) -> getElementType ( ) ; NewInst = GetElementPtrInst :: Create ( ElTy , Input , A , <STR_LIT> , & * At ) ; NewInst -> setIsInBounds ( RN -> Flags & GepNode :: InBounds ) ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << * NewInst << '\n' ) ; Input = NewInst ; } while ( nax <= Num ) ; delete [ ] IdxList ;


<s> Instruction * In = cast < Instruction > ( V ) ; if ( In -> getParent ( ) != B ) continue ; BasicBlock :: iterator It = In -> getIterator ( ) ; if ( std :: distance ( FirstUse , BEnd ) < std :: distance ( It , BEnd ) ) FirstUse = It ;


<s> static BasicBlock :: iterator first_use_of_in_block ( T & Values , BasicBlock * B ) { BasicBlock :: iterator FirstUse = B -> end ( ) , BEnd = B -> end ( ) ; using iterator = typename T :: iterator ;

for ( iterator I = Values . begin ( ) , E = Values . end ( ) ; I != E ; ++ I ) {


<s> void <ISA_LIT>CommonGEP :: getBlockTraversalOrder ( BasicBlock * Root , ValueVect & Order ) {


<s> GepNode * N = * I ; if ( N -> Flags & GepNode :: Root ) { Roots . push_back ( N ) ; continue ; }


<s> BasicBlock :: iterator FirstUse = first_use_of_in_block ( Urs , LastB ) ; if ( FirstUse != LastB -> end ( ) ) InsertAt = FirstUse ; } Value * NewInst = fabricateGEP ( NA , InsertAt , LastB ) ; if ( LastCN > <NUM_LIT> ) { NodeVect & Cs = NCM [ Last ] ; for ( NodeVect :: iterator I = Cs . begin ( ) , E = Cs . end ( ) ; I != E ; ++ I ) { GepNode * CN = * I ; CN -> Flags &= ~ GepNode :: Internal ; CN -> Flags |= GepNode :: Root ; CN -> BaseVal = NewInst ; Roots . push_back ( CN ) ; } } if ( LastUsed ) { NodeToUsesMap :: iterator UF = Uses . find ( Last ) ; assert ( UF != Uses . end ( ) && <STR_LIT> ) ; UseSet & Us = UF -> second ;

for ( UseSet :: iterator I = Us . begin ( ) , E = Us . end ( ) ; I != E ; ++ I ) {


<s> unsigned LastCN = <NUM_LIT> ; Value * LocV = Loc [ Last ] ; if ( ! LocV ) continue ; BasicBlock * LastB = cast < BasicBlock > ( LocV ) ; do { NA . push_back ( Last ) ; LastUsed = ( Last -> Flags & GepNode :: Used ) ; if ( LastUsed ) break ; NodeChildrenMap :: iterator CF = NCM . find ( Last ) ; LastCN = ( CF != NCM . end ( ) ) ? CF -> second . size ( ) : <NUM_LIT> ; if ( LastCN != <NUM_LIT> ) break ; GepNode * Child = CF -> second . front ( ) ; BasicBlock * ChildB = cast_or_null < BasicBlock > ( Loc [ Child ] ) ; if ( ChildB != nullptr && LastB != ChildB ) break ; Last = Child ; } while ( true ) ; BasicBlock :: iterator InsertAt = LastB -> getTerminator ( ) -> getIterator ( ) ; if ( LastUsed || LastCN > <NUM_LIT> ) { ValueVect Urs ; getAllUsersForNode ( Root , Urs , NCM ) ; BasicBlock :: iterator FirstUse = first_use_of_in_block ( Urs , LastB ) ; if ( FirstUse != LastB -> end ( ) ) InsertAt = FirstUse ; } Value * NewInst = fabricateGEP ( NA , InsertAt , LastB ) ; if ( LastCN > <NUM_LIT> ) { NodeVect & Cs = NCM [ Last ] ; for ( NodeVect :: iterator I = Cs . begin ( ) , E = Cs . end ( ) ; I != E ; ++ I ) { GepNode * CN = * I ; CN -> Flags &= ~ GepNode :: Internal ; CN -> Flags |= GepNode :: Root ; CN -> BaseVal = NewInst ; Roots . push_back ( CN ) ; } } if ( LastUsed ) { NodeToUsesMap :: iterator UF = Uses . find ( Last ) ; assert ( UF != Uses . end ( ) && <STR_LIT> ) ;


<s>
++
I
)
{
if
(
!
*
I
)
continue
;
BasicBlock
*
B
=
cast
<
BasicBlock
>
(
*
I
)
;
dbgs
(
)
<<
' '
<<
B
->
getName
(
)
;
}


<s> Type * PtrTy = cast < PointerType > ( PtrOp -> getType ( ) ) -> getElementType ( ) ; for ( User :: op_iterator OI = GepI -> idx_begin ( ) + <NUM_LIT> , OE = GepI -> idx_end ( ) ; OI != OE ; ++ OI ) { Value * Op = * OI ; GepNode * Nx = new ( * Mem ) GepNode ; Nx -> Parent = PN ; Nx -> Flags |= GepNode :: Internal | InBounds ; Nx -> PTy = PtrTy ; Nx -> Idx = Op ; Nodes . push_back ( Nx ) ; NodeOrder . insert ( Nx ) ; PN = Nx ; PtrTy = next_type ( PtrTy , Op ) ; } if ( ! Us . empty ( ) ) { PN -> Flags |= GepNode :: Used ; Uses [ PN ] . insert ( Us . begin ( ) , Us . end ( ) ) ; } NM . insert ( std :: make_pair ( GepI , PN ) ) ;


<s> for ( NodeVect :: iterator I = Cs . begin ( ) , E = Cs . end ( ) ; I != E ; ++ I ) { GepNode * CN = * I ; NodeToValueMap :: iterator LF = Loc . find ( CN ) ; if ( LF == Loc . end ( ) ) continue ; Bs . push_back ( LF -> second ) ; } } BasicBlock * DomB = nearest_common_dominator ( DT , Bs ) ; if ( ! DomB ) return nullptr ; Instruction * IdxI = dyn_cast < Instruction > ( Node -> Idx ) ; if ( IdxI && ! DT -> dominates ( IdxI -> getParent ( ) , DomB ) ) return nullptr ;


<s> NodeVect & Cs = CF -> second ; for ( NodeVect :: iterator I = Cs . begin ( ) , E = Cs . end ( ) ; I != E ; ++ I ) recalculatePlacementRec ( * I , NCM , Loc ) ; } BasicBlock * LB = recalculatePlacement ( Node , NCM , Loc ) ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << Node << '\n' ) ; return LB ;


<s> ValueVect BO ; BO . push_back ( & Fn -> front ( ) ) ; for ( unsigned i = <NUM_LIT> ; i < BO . size ( ) ; ++ i ) { BasicBlock * B = cast < BasicBlock > ( BO [ i ] ) ; for ( auto DTN : children < DomTreeNode * > ( DT -> getNode ( B ) ) ) BO . push_back ( DTN -> getBlock ( ) ) ; } for ( unsigned i = BO . size ( ) ; i > <NUM_LIT> ; -- i ) { BasicBlock * B = cast < BasicBlock > ( BO [ i - <NUM_LIT> ] ) ; BasicBlock :: InstListType & IL = B -> getInstList ( ) ; using reverse_iterator = BasicBlock :: InstListType :: reverse_iterator ; ValueVect Ins ; for ( reverse_iterator I = IL . rbegin ( ) , E = IL . rend ( ) ; I != E ; ++ I ) Ins . push_back ( & * I ) ; for ( ValueVect :: iterator I = Ins . begin ( ) , E = Ins . end ( ) ; I != E ; ++ I ) {

Instruction * In = cast < Instruction > ( * I ) ;


<s> using reverse_iterator = BasicBlock :: InstListType :: reverse_iterator ; ValueVect Ins ; for ( reverse_iterator I = IL . rbegin ( ) , E = IL . rend ( ) ; I != E ; ++ I ) Ins . push_back ( & * I ) ; for ( ValueVect :: iterator I = Ins . begin ( ) , E = Ins . end ( ) ; I != E ; ++ I ) { Instruction * In = cast < Instruction > ( * I ) ;

if ( isInstructionTriviallyDead ( In ) ) In -> eraseFromParent ( ) ;


<s> } if ( ! NewNode ) return ; NodeToUsesMap :: iterator UF = Uses . find ( Node ) ; assert ( UF != Uses . end ( ) ) ; UseSet & Us = UF -> second ; UseSet NewUs ; for ( UseSet :: iterator I = Us . begin ( ) ; I != Us . end ( ) ; ) { User * S = ( * I ) -> getUser ( ) ; UseSet :: iterator Nx = std :: next ( I ) ; if ( S == R ) { NewUs . insert ( * I ) ; Us . erase ( I ) ; } I = Nx ; } if ( Us . empty ( ) ) { Node -> Flags &= ~ GepNode :: Used ; Uses . erase ( UF ) ; }


<s> NodeSet Ns ; nodes_for_root ( Node , NCM , Ns ) ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << Node << '\n' ) ; NodeToUsesMap FNs ; for ( NodeSet :: iterator I = Ns . begin ( ) , E = Ns . end ( ) ; I != E ; ++ I ) { GepNode * N = * I ; if ( ! ( N -> Flags & GepNode :: Used ) ) continue ; NodeToUsesMap :: iterator UF = Uses . find ( N ) ; assert ( UF != Uses . end ( ) ) ; UseSet & Us = UF -> second ; UseSet LSs ;

for ( UseSet :: iterator J = Us . begin ( ) , F = Us . end ( ) ; J != F ; ++ J ) {


<s> BasicBlock * <ISA_LIT>CommonGEP :: adjustForInvariance ( GepNode * Node , NodeChildrenMap & NCM , NodeToValueMap & Loc ) { ValueVect Bs ; if ( Node -> Flags & GepNode :: Root ) { if ( Instruction * PIn = dyn_cast < Instruction > ( Node -> BaseVal ) ) Bs . push_back ( PIn -> getParent ( ) ) ; } else { Bs . push_back ( Loc [ Node -> Parent ] ) ; } if ( Instruction * IIn = dyn_cast < Instruction > ( Node -> Idx ) ) Bs . push_back ( IIn -> getParent ( ) ) ; BasicBlock * TopB = nearest_common_dominatee ( DT , Bs ) ; BasicBlock * LocB = cast_or_null < BasicBlock > ( Loc [ Node ] ) ; if ( LocB ) { Loop * Lp = LI -> getLoopFor ( LocB ) ; while ( Lp ) { if ( ! isInvariantIn ( Node , Lp ) || ! isInMainPath ( LocB , Lp ) ) break ; BasicBlock * NewLoc = preheader ( DT , Lp ) ; if ( ! NewLoc || ! DT -> dominates ( TopB , NewLoc ) ) break ; Lp = Lp -> getParentLoop ( ) ; LocB = NewLoc ; } } Loc [ Node ] = LocB ; NodeChildrenMap :: iterator CF = NCM . find ( Node ) ; if ( CF != NCM . end ( ) ) { NodeVect & Cs = CF -> second ; for ( GepNode * C : Cs ) adjustForInvariance ( C , NCM , Loc ) ;


<s> } else { Bs . push_back ( Loc [ Node -> Parent ] ) ; } if ( Instruction * IIn = dyn_cast < Instruction > ( Node -> Idx ) ) Bs . push_back ( IIn -> getParent ( ) ) ; BasicBlock * TopB = nearest_common_dominatee ( DT , Bs ) ; BasicBlock * LocB = cast_or_null < BasicBlock > ( Loc [ Node ] ) ; if ( LocB ) { Loop * Lp = LI -> getLoopFor ( LocB ) ; while ( Lp ) { if ( ! isInvariantIn ( Node , Lp ) || ! isInMainPath ( LocB , Lp ) ) break ; BasicBlock * NewLoc = preheader ( DT , Lp ) ; if ( ! NewLoc || ! DT -> dominates ( TopB , NewLoc ) ) break ; Lp = Lp -> getParentLoop ( ) ; LocB = NewLoc ; } } Loc [ Node ] = LocB ; NodeChildrenMap :: iterator CF = NCM . find ( Node ) ; if ( CF != NCM . end ( ) ) { NodeVect & Cs = CF -> second ; for ( GepNode * C : Cs ) adjustForInvariance ( C , NCM , Loc ) ;


<s> getBlockTraversalOrder ( & Fn -> front ( ) , BO ) ; ValueToNodeMap NM ; for ( Value * I : BO ) { BasicBlock * B = cast < BasicBlock > ( I ) ; for ( Instruction & J : * B ) if ( auto * GepI = dyn_cast < GetElementPtrInst > ( & J ) ) if ( isHandledGepForm ( GepI ) ) processGepInst ( GepI , NM ) ; }


<s> void <ISA_LIT>CommonGEP :: collect ( ) { ValueVect BO ; getBlockTraversalOrder ( & Fn -> front ( ) , BO ) ; ValueToNodeMap NM ; for ( Value * I : BO ) {

BasicBlock * B = cast < BasicBlock > ( I ) ;


<s> GepNode * N = * NI ; if ( node_class ( N , EqRel ) ) continue ; NodeSet C ; for ( NodeSet :: iterator NJ = std :: next ( NI ) ; NJ != NE ; ++ NJ ) if ( node_eq ( N , * NJ , Eq , Ne ) ) C . insert ( * NJ ) ; if ( ! C . empty ( ) ) { C . insert ( N ) ; std :: pair < NodeSymRel :: iterator , bool > Ins = EqRel . insert ( C ) ; ( void ) Ins ; assert ( Ins . second && <STR_LIT> ) ; } } } LLVM_DEBUG ( { dbgs ( ) << <STR_LIT> ; for ( NodePairSet :: iterator I = Eq . begin ( ) , E = Eq . end ( ) ; I != E ; ++ I ) dbgs ( ) << <STR_LIT> << I -> first << <STR_LIT> << I -> second << <STR_LIT> ; dbgs ( ) << <STR_LIT> ; for ( const NodeSet & S : EqRel ) { dbgs ( ) << '{' ; for ( NodeSet :: const_iterator J = S . begin ( ) , F = S . end ( ) ; J != F ; ++ J ) { if ( J != S . begin ( ) ) dbgs ( ) << ',' ;


<s> for ( GepNode * Root : Roots ) recalculatePlacementRec ( Root , NCM , Loc ) ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << LocationAsBlock ( Loc ) ) ; if ( OptEnableInv ) { for ( GepNode * Root : Roots ) adjustForInvariance ( Root , NCM , Loc ) ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << LocationAsBlock ( Loc ) ) ; } if ( OptEnableConst ) { for ( GepNode * Root : Roots ) separateConstantChains ( Root , NCM , Loc ) ; }

LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << Uses ) ;


<s> unsigned Num = NA . size ( ) ; GepNode * RN = NA [ <NUM_LIT> ] ; assert ( ( RN -> Flags & GepNode :: Root ) && <STR_LIT> ) ; GetElementPtrInst * NewInst = nullptr ; Value * Input = RN -> BaseVal ; Type * InpTy = RN -> PTy ; unsigned Idx = <NUM_LIT> ; do { SmallVector < Value * , <NUM_LIT> > IdxList ; if ( ! ( NA [ Idx ] -> Flags & GepNode :: Pointer ) ) { Type * Int32Ty = Type :: getInt32Ty ( * Ctx ) ; IdxList . push_back ( ConstantInt :: get ( Int32Ty , <NUM_LIT> ) ) ; } while ( ++ Idx <= Num ) { GepNode * N = NA [ Idx - <NUM_LIT> ] ; IdxList . push_back ( N -> Idx ) ;


<s> assert ( UF != Uses . end ( ) && <STR_LIT> ) ; UseSet & Us = UF -> second ; for ( const auto & U : Us ) Values . push_back ( U -> getUser ( ) ) ; } NodeChildrenMap :: iterator CF = NCM . find ( N ) ; if ( CF != NCM . end ( ) ) { NodeVect & Cs = CF -> second ; llvm :: append_range ( Work , Cs ) ; }


<s> NodeToUsesMap :: iterator UF = Uses . find ( N ) ; assert ( UF != Uses . end ( ) && <STR_LIT> ) ; UseSet & Us = UF -> second ;

for ( const auto & U : Us ) Values . push_back ( U -> getUser ( ) ) ;


<s> if ( N -> Flags & GepNode :: Root ) { Roots . push_back ( N ) ; continue ; }


<s> GepNode * Child = CF -> second . front ( ) ; BasicBlock * ChildB = cast_or_null < BasicBlock > ( Loc [ Child ] ) ; if ( ChildB != nullptr && LastB != ChildB ) break ; Last = Child ; } while ( true ) ; BasicBlock :: iterator InsertAt = LastB -> getTerminator ( ) -> getIterator ( ) ; if ( LastUsed || LastCN > <NUM_LIT> ) { ValueVect Urs ; getAllUsersForNode ( Root , Urs , NCM ) ; BasicBlock :: iterator FirstUse = first_use_of_in_block ( Urs , LastB ) ; if ( FirstUse != LastB -> end ( ) ) InsertAt = FirstUse ; } Value * NewInst = fabricateGEP ( NA , InsertAt , LastB ) ; if ( LastCN > <NUM_LIT> ) { NodeVect & Cs = NCM [ Last ] ; for ( GepNode * CN : Cs ) { CN -> Flags &= ~ GepNode :: Internal ; CN -> Flags |= GepNode :: Root ; CN -> BaseVal = NewInst ; Roots . push_back ( CN ) ; } } if ( LastUsed ) { NodeToUsesMap :: iterator UF = Uses . find ( Last ) ; assert ( UF != Uses . end ( ) && <STR_LIT> ) ; UseSet & Us = UF -> second ; for ( Use * U : Us ) U -> set ( NewInst ) ; } }


<s> if ( ! LocV ) continue ; BasicBlock * LastB = cast < BasicBlock > ( LocV ) ; do { NA . push_back ( Last ) ; LastUsed = ( Last -> Flags & GepNode :: Used ) ; if ( LastUsed ) break ; NodeChildrenMap :: iterator CF = NCM . find ( Last ) ; LastCN = ( CF != NCM . end ( ) ) ? CF -> second . size ( ) : <NUM_LIT> ; if ( LastCN != <NUM_LIT> ) break ; GepNode * Child = CF -> second . front ( ) ; BasicBlock * ChildB = cast_or_null < BasicBlock > ( Loc [ Child ] ) ; if ( ChildB != nullptr && LastB != ChildB ) break ; Last = Child ; } while ( true ) ; BasicBlock :: iterator InsertAt = LastB -> getTerminator ( ) -> getIterator ( ) ; if ( LastUsed || LastCN > <NUM_LIT> ) { ValueVect Urs ; getAllUsersForNode ( Root , Urs , NCM ) ; BasicBlock :: iterator FirstUse = first_use_of_in_block ( Urs , LastB ) ; if ( FirstUse != LastB -> end ( ) ) InsertAt = FirstUse ;


<s> static void nodes_for_root ( GepNode * Root , NodeChildrenMap & NCM , NodeSet & Nodes ) { NodeVect Work ; Work . push_back ( Root ) ; Nodes . insert ( Root ) ; while ( ! Work . empty ( ) ) { NodeVect :: iterator First = Work . begin ( ) ; GepNode * N = * First ; Work . erase ( First ) ;

NodeChildrenMap :: iterator CF = NCM . find ( N ) ;


<s> for ( const NodeSet & S : Rel ) if ( S . count ( N ) ) return & S ; return nullptr ;


<s> bool Different = ( N1 -> Flags & CmpFlags ) != ( N2 -> Flags & CmpFlags ) ; NodePair P = node_pair ( N1 , N2 ) ; if ( Different || ( Root1 && N1 -> BaseVal != N2 -> BaseVal ) ) { Ne . insert ( P ) ; return false ; } if ( Root1 || node_eq ( N1 -> Parent , N2 -> Parent , Eq , Ne ) ) { Eq . insert ( P ) ; return true ;


<s> N -> BaseVal = PtrOp ; N -> Flags |= GepNode :: Root | InBounds ; } else { N -> Parent = F -> second ; } N -> PTy = GepI -> getSourceElementType ( ) ; N -> Flags |= GepNode :: Pointer ; N -> Idx = * GepI -> idx_begin ( ) ; UseSet Us ; for ( Value :: user_iterator UI = GepI -> user_begin ( ) , UE = GepI -> user_end ( ) ; UI != UE ; ++ UI ) { if ( isa < GetElementPtrInst > ( * UI ) ) { GetElementPtrInst * UserG = cast < GetElementPtrInst > ( * UI ) ;

if ( isHandledGepForm ( UserG ) ) continue ;


<s> NodeToUsesMap :: iterator UF = Uses . find ( Node ) ; assert ( UF != Uses . end ( ) && <STR_LIT> ) ; UseSet & Us = UF -> second ; for ( Use * U : Us ) { User * R = U -> getUser ( ) ; if ( ! isa < Instruction > ( R ) ) continue ; BasicBlock * PB = isa < PHINode > ( R ) ? cast < PHINode > ( R ) -> getIncomingBlock ( * U ) : cast < Instruction > ( R ) -> getParent ( ) ; Bs . push_back ( PB ) ; } } NodeChildrenMap :: iterator CF = NCM . find ( Node ) ; if ( CF != NCM . end ( ) ) { NodeVect & Cs = CF -> second ; for ( GepNode * CN : Cs ) { NodeToValueMap :: iterator LF = Loc . find ( CN ) ; if ( LF == Loc . end ( ) ) continue ; Bs . push_back ( LF -> second ) ; } } BasicBlock * DomB = nearest_common_dominator ( DT , Bs ) ; if ( ! DomB ) return nullptr ; Instruction * IdxI = dyn_cast < Instruction > ( Node -> Idx ) ; if ( IdxI && ! DT -> dominates ( IdxI -> getParent ( ) , DomB ) ) return nullptr ; while ( is_empty ( DomB ) ) { DomTreeNode * N = ( * DT ) [ DomB ] -> getIDom ( ) ; if ( ! N ) break ; DomB = N -> getBlock ( ) ;


<s> BasicBlock * <ISA_LIT>CommonGEP :: recalculatePlacementRec ( GepNode * Node , NodeChildrenMap & NCM , NodeToValueMap & Loc ) { LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << Node << '\n' ) ; NodeChildrenMap :: iterator CF = NCM . find ( Node ) ; if ( CF != NCM . end ( ) ) { NodeVect & Cs = CF -> second ; for ( GepNode * C : Cs ) recalculatePlacementRec ( C , NCM , Loc ) ; } BasicBlock * LB = recalculatePlacement ( Node , NCM , Loc ) ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << Node << '\n' ) ; return LB ;


<s> if ( CF != NCM . end ( ) ) { NodeVect & Cs = CF -> second ;

for ( GepNode * C : Cs ) recalculatePlacementRec ( C , NCM , Loc ) ;


<s> BasicBlock * B = cast < BasicBlock > ( BO [ i ] ) ; for ( auto DTN : children < DomTreeNode * > ( DT -> getNode ( B ) ) ) BO . push_back ( DTN -> getBlock ( ) ) ; } for ( Value * V : llvm :: reverse ( BO ) ) { BasicBlock * B = cast < BasicBlock > ( V ) ; ValueVect Ins ; for ( Instruction & I : llvm :: reverse ( * B ) ) Ins . push_back ( & I ) ;


<s> for ( const BasicBlock & BB : F ) for ( const Instruction & I : BB ) if ( isa < InvokeInst > ( I ) || isa < LandingPadInst > ( I ) ) return false ; Fn = & F ; DT = & getAnalysis < DominatorTreeWrapperPass > ( ) . getDomTree ( ) ; PDT = & getAnalysis < PostDominatorTreeWrapperPass > ( ) . getPostDomTree ( ) ; LI = & getAnalysis < LoopInfoWrapperPass > ( ) . getLoopInfo ( ) ; Ctx = & F . getContext ( ) ; Nodes . clear ( ) ; Uses . clear ( ) ; NodeOrder . clear ( ) ; SpecificBumpPtrAllocator < GepNode > Allocator ; Mem = & Allocator ; collect ( ) ; common ( ) ; NodeToValueMap Loc ; computeNodePlacement ( Loc ) ; materialize ( Loc ) ; removeDeadCode ( ) ; if ( verifyFunction ( F , & dbgs ( ) ) ) report_fatal_error ( <STR_LIT> ) ; return true ;


<s> GepNode * N = Node ; GepNode * C = nullptr , * NewNode = nullptr ; while ( is_constant ( N ) && ! ( N -> Flags & GepNode :: Root ) ) { GepNode * NewN = new ( * Mem ) GepNode ( N ) ; Nodes . push_back ( NewN ) ; Loc [ NewN ] = PB ; if ( N == Node ) NewNode = NewN ; NewN -> Flags &= ~ GepNode :: Used ; if ( C ) C -> Parent = NewN ; C = NewN ; N = N -> Parent ; } if ( ! NewNode ) return ; NodeToUsesMap :: iterator UF = Uses . find ( Node ) ; assert ( UF != Uses . end ( ) ) ; UseSet & Us = UF -> second ;


<s> void <ISA_LIT>CommonGEP :: separateConstantChains ( GepNode * Node , NodeChildrenMap & NCM , NodeToValueMap & Loc ) { NodeSet Ns ; nodes_for_root ( Node , NCM , Ns ) ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << Node << '\n' ) ; NodeToUsesMap FNs ; for ( GepNode * N : Ns ) { if ( ! ( N -> Flags & GepNode :: Used ) ) continue ; NodeToUsesMap :: iterator UF = Uses . find ( N ) ; assert ( UF != Uses . end ( ) ) ;


<s> UseSet & Us = UF -> second ; UseSet LSs ; for ( Use * U : Us ) { User * R = U -> getUser ( ) ; if ( LoadInst * Ld = dyn_cast < LoadInst > ( R ) ) { unsigned PtrX = LoadInst :: getPointerOperandIndex ( ) ; if ( & Ld -> getOperandUse ( PtrX ) == U ) LSs . insert ( U ) ;

} else if ( StoreInst * St = dyn_cast < StoreInst > ( R ) ) {


<s> NodeVect Work ; Work . push_back ( Node ) ; while ( ! Work . empty ( ) ) { NodeVect :: iterator First = Work . begin ( ) ; GepNode * N = * First ; Work . erase ( First ) ; if ( N -> Flags & GepNode :: Used ) { NodeToUsesMap :: iterator UF = Uses . find ( N ) ; assert ( UF != Uses . end ( ) && <STR_LIT> ) ; UseSet & Us = UF -> second ;

for ( UseSet :: iterator I = Us . begin ( ) , E = Us . end ( ) ; I != E ; ++ I ) Values . push_back ( ( * I ) -> getUser ( ) ) ;


<s> LI = & getAnalysis < LoopInfoWrapperPass > ( ) . getLoopInfo ( ) ; Ctx = & F . getContext ( ) ; Nodes . clear ( ) ; Uses . clear ( ) ; NodeOrder . clear ( ) ; SpecificBumpPtrAllocator < GepNode > Allocator ; Mem = & Allocator ; collect ( ) ; common ( ) ; NodeToValueMap Loc ; computeNodePlacement ( Loc ) ; materialize ( Loc ) ; removeDeadCode ( ) ;

if ( verifyFunction ( F , & dbgs ( ) ) ) report_fatal_error ( <STR_LIT> ) ;


<s> do { unsigned IdxC = <NUM_LIT> ; if ( ! NA [ nax ] -> PTy -> isPointerTy ( ) ) { Type * Int32Ty = Type :: getInt32Ty ( * Ctx ) ; IdxList [ IdxC ++ ] = ConstantInt :: get ( Int32Ty , <NUM_LIT> ) ; } while ( ++ nax <= Num ) { GepNode * N = NA [ nax - <NUM_LIT> ] ; IdxList [ IdxC ++ ] = N -> Idx ; if ( nax < Num ) { Type * NextTy = next_type ( N -> PTy , N -> Idx ) ; if ( NextTy != NA [ nax ] -> PTy ) break ; } } ArrayRef < Value * > A ( IdxList , IdxC ) ; Type * InpTy = Input -> getType ( ) ; Type * ElTy = cast < PointerType > ( InpTy -> getScalarType ( ) ) -> getElementType ( ) ; NewInst = GetElementPtrInst :: Create ( ElTy , Input , A , <STR_LIT> , & * At ) ; NewInst -> setIsInBounds ( RN -> Flags & GepNode :: InBounds ) ; DEBUG ( dbgs ( ) << <STR_LIT> << * NewInst << '\n' ) ;


<s> IdxList [ IdxC ++ ] = ConstantInt :: get ( Int32Ty , <NUM_LIT> ) ; } while ( ++ nax <= Num ) { GepNode * N = NA [ nax - <NUM_LIT> ] ; IdxList [ IdxC ++ ] = N -> Idx ; if ( nax < Num ) { Type * NextTy = next_type ( N -> PTy , N -> Idx ) ; if ( NextTy != NA [ nax ] -> PTy ) break ; } } ArrayRef < Value * > A ( IdxList , IdxC ) ;


<s> N -> Flags |= GepNode :: Root | InBounds ; } else { N -> Parent = F -> second ; } N -> PTy = PtrOp -> getType ( ) ; N -> Idx = * GepI -> idx_begin ( ) ; UseSet Us ; for ( Value :: user_iterator UI = GepI -> user_begin ( ) , UE = GepI -> user_end ( ) ; UI != UE ; ++ UI ) { if ( isa < GetElementPtrInst > ( * UI ) ) { GetElementPtrInst * UserG = cast < GetElementPtrInst > ( * UI ) ; if ( isHandledGepForm ( UserG ) ) continue ; } Us . insert ( & UI . getUse ( ) ) ; } Nodes . push_back ( N ) ; NodeOrder . insert ( N ) ; GepNode * PN = N ; Type * PtrTy = cast < PointerType > ( PtrOp -> getType ( ) ) -> getElementType ( ) ; for ( User :: op_iterator OI = GepI -> idx_begin ( ) + <NUM_LIT> , OE = GepI -> idx_end ( ) ; OI != OE ; ++ OI ) { Value * Op = * OI ; GepNode * Nx = new ( * Mem ) GepNode ; Nx -> Parent = PN ; Nx -> Flags |= GepNode :: Internal | InBounds ; Nx -> PTy = PtrTy ; Nx -> Idx = Op ; Nodes . push_back ( Nx ) ;


<s> uint32_t InBounds = GepI -> isInBounds ( ) ? GepNode :: InBounds : <NUM_LIT> ; ValueToNodeMap :: iterator F = NM . find ( PtrOp ) ; if ( F == NM . end ( ) ) { N -> BaseVal = PtrOp ; N -> Flags |= GepNode :: Root | InBounds ; } else { N -> Parent = F -> second ; } N -> PTy = PtrOp -> getType ( ) ; N -> Idx = * GepI -> idx_begin ( ) ; UseSet Us ; for ( Value :: user_iterator UI = GepI -> user_begin ( ) , UE = GepI -> user_end ( ) ; UI != UE ; ++ UI ) { if ( isa < GetElementPtrInst > ( * UI ) ) { GetElementPtrInst * UserG = cast < GetElementPtrInst > ( * UI ) ; if ( isHandledGepForm ( UserG ) ) continue ; } Us . insert ( & UI . getUse ( ) ) ; } Nodes . push_back ( N ) ; NodeOrder . insert ( N ) ; GepNode * PN = N ; Type * PtrTy = cast < PointerType > ( PtrOp -> getType ( ) ) -> getElementType ( ) ; for ( User :: op_iterator OI = GepI -> idx_begin ( ) + <NUM_LIT> , OE = GepI -> idx_end ( ) ; OI != OE ; ++ OI ) { Value * Op = * OI ; GepNode * Nx = new ( * Mem ) GepNode ;


<s> BO . push_back ( & Fn -> front ( ) ) ; for ( unsigned i = <NUM_LIT> ; i < BO . size ( ) ; ++ i ) { BasicBlock * B = cast < BasicBlock > ( BO [ i ] ) ; for ( auto DTN : children < DomTreeNode * > ( DT -> getNode ( B ) ) ) BO . push_back ( DTN -> getBlock ( ) ) ; } for ( unsigned i = BO . size ( ) ; i > <NUM_LIT> ; -- i ) { BasicBlock * B = cast < BasicBlock > ( BO [ i - <NUM_LIT> ] ) ; BasicBlock :: InstListType & IL = B -> getInstList ( ) ; typedef BasicBlock :: InstListType :: reverse_iterator reverse_iterator ; ValueVect Ins ; for ( reverse_iterator I = IL . rbegin ( ) , E = IL . rend ( ) ; I != E ; ++ I ) Ins . push_back ( & * I ) ;

for ( ValueVect :: iterator I = Ins . begin ( ) , E = Ins . end ( ) ; I != E ; ++ I ) {


<s> ValueToNodeMap NM ; for ( ValueVect :: iterator I = BO . begin ( ) , E = BO . end ( ) ; I != E ; ++ I ) {

BasicBlock * B = cast < BasicBlock > ( * I ) ;


<s> ValueToNodeMap NM ; for ( ValueVect :: iterator I = BO . begin ( ) , E = BO . end ( ) ; I != E ; ++ I ) { BasicBlock * B = cast < BasicBlock > ( * I ) ; for ( BasicBlock :: iterator J = B -> begin ( ) , F = B -> end ( ) ; J != F ; ++ J ) { if ( ! isa < GetElementPtrInst > ( J ) ) continue ; GetElementPtrInst * GepI = cast < GetElementPtrInst > ( J ) ; if ( isHandledGepForm ( GepI ) ) processGepInst ( GepI , NM ) ;


<s> unsigned IdxC = <NUM_LIT> ; if ( ! NA [ nax ] -> PTy -> isPointerTy ( ) ) { Type * Int32Ty = Type :: getInt32Ty ( * Ctx ) ; IdxList [ IdxC ++ ] = ConstantInt :: get ( Int32Ty , <NUM_LIT> ) ; } while ( ++ nax <= Num ) { GepNode * N = NA [ nax - <NUM_LIT> ] ; IdxList [ IdxC ++ ] = N -> Idx ; if ( nax < Num ) { Type * NextTy = next_type ( N -> PTy , N -> Idx ) ; if ( NextTy != NA [ nax ] -> PTy ) break ; } } ArrayRef < Value * > A ( IdxList , IdxC ) ; Type * InpTy = Input -> getType ( ) ;

Type * ElTy = cast < PointerType > ( InpTy -> getScalarType ( ) ) -> getElementType ( ) ;


<s> Type * Int32Ty = Type :: getInt32Ty ( * Ctx ) ; IdxList [ IdxC ++ ] = ConstantInt :: get ( Int32Ty , <NUM_LIT> ) ; } while ( ++ nax <= Num ) { GepNode * N = NA [ nax - <NUM_LIT> ] ; IdxList [ IdxC ++ ] = N -> Idx ; if ( nax < Num ) { Type * NextTy = next_type ( N -> PTy , N -> Idx ) ; if ( NextTy != NA [ nax ] -> PTy ) break ; } } ArrayRef < Value * > A ( IdxList , IdxC ) ; Type * InpTy = Input -> getType ( ) ; Type * ElTy = cast < PointerType > ( InpTy -> getScalarType ( ) ) -> getElementType ( ) ; NewInst = GetElementPtrInst :: Create ( ElTy , Input , A , <STR_LIT> , At ) ; DEBUG ( dbgs ( ) << <STR_LIT> << * NewInst << '\n' ) ; Input = NewInst ;


<s> if ( isa < PHINode > ( V ) ) continue ; if ( ! isa < Instruction > ( V ) ) continue ; Instruction * In = cast < Instruction > ( V ) ; if ( In -> getParent ( ) != B ) continue ; BasicBlock :: iterator It = In ; if ( std :: distance ( FirstUse , BEnd ) < std :: distance ( It , BEnd ) ) FirstUse = It ;


<s> DEBUG ( dbgs ( ) << <STR_LIT> << Nodes << '\n' ) ; NodeChildrenMap NCM ; NodeVect Roots ; invert_find_roots ( Nodes , NCM , Roots ) ; while ( ! Roots . empty ( ) ) { NodeVect :: iterator First = Roots . begin ( ) ; GepNode * Root = * First , * Last = * First ; Roots . erase ( First ) ; NodeVect NA ; bool LastUsed = false ; unsigned LastCN = <NUM_LIT> ; Value * LocV = Loc [ Last ] ; if ( ! LocV ) continue ; BasicBlock * LastB = cast < BasicBlock > ( LocV ) ; do { NA . push_back ( Last ) ; LastUsed = ( Last -> Flags & GepNode :: Used ) ; if ( LastUsed ) break ; NodeChildrenMap :: iterator CF = NCM . find ( Last ) ; LastCN = ( CF != NCM . end ( ) ) ? CF -> second . size ( ) : <NUM_LIT> ; if ( LastCN != <NUM_LIT> ) break ; GepNode * Child = CF -> second . front ( ) ; BasicBlock * ChildB = cast_or_null < BasicBlock > ( Loc [ Child ] ) ; if ( ChildB != <NUM_LIT> && LastB != ChildB ) break ; Last = Child ; } while ( true ) ; BasicBlock :: iterator InsertAt = LastB -> getTerminator ( ) ; if ( LastUsed || LastCN > <NUM_LIT> ) { ValueVect Urs ; getAllUsersForNode ( Root , Urs , NCM ) ; BasicBlock :: iterator FirstUse = first_use_of_in_block ( Urs , LastB ) ; if ( FirstUse != LastB -> end ( ) ) InsertAt = FirstUse ; } Value * NewInst = fabricateGEP ( NA , InsertAt , LastB ) ; if ( LastCN > <NUM_LIT> ) { NodeVect & Cs = NCM [ Last ] ; for ( NodeVect :: iterator I = Cs . begin ( ) , E = Cs . end ( ) ; I != E ; ++ I ) { GepNode * CN = * I ; CN -> Flags &= ~ GepNode :: Internal ; CN -> Flags |= GepNode :: Root ; CN -> BaseVal = NewInst ; Roots . push_back ( CN ) ; }


<s> GetElementPtrInst * UserG = cast < GetElementPtrInst > ( * UI ) ; if ( isHandledGepForm ( UserG ) ) continue ; } Us . insert ( & UI . getUse ( ) ) ; } Nodes . push_back ( N ) ; NodeOrder . special_insert_for_special_msvc ( N ) ; NodeOrder . insert ( N ) ; GepNode * PN = N ; Type * PtrTy = cast < PointerType > ( PtrOp -> getType ( ) ) -> getElementType ( ) ; for ( User :: op_iterator OI = GepI -> idx_begin ( ) + <NUM_LIT> , OE = GepI -> idx_end ( ) ; OI != OE ; ++ OI ) { Value * Op = * OI ; GepNode * Nx = new ( * Mem ) GepNode ; Nx -> Parent = PN ; Nx -> Flags |= GepNode :: Internal ; Nx -> PTy = PtrTy ; Nx -> Idx = Op ;


<s> Value * PtrOp = GepI -> getPointerOperand ( ) ; ValueToNodeMap :: iterator F = NM . find ( PtrOp ) ; if ( F == NM . end ( ) ) { N -> BaseVal = PtrOp ; N -> Flags |= GepNode :: Root ; } else { N -> Parent = F -> second ; } N -> PTy = PtrOp -> getType ( ) ; N -> Idx = * GepI -> idx_begin ( ) ; UseSet Us ; for ( Value :: user_iterator UI = GepI -> user_begin ( ) , UE = GepI -> user_end ( ) ; UI != UE ; ++ UI ) { if ( isa < GetElementPtrInst > ( * UI ) ) { GetElementPtrInst * UserG = cast < GetElementPtrInst > ( * UI ) ; if ( isHandledGepForm ( UserG ) ) continue ; } Us . insert ( & UI . getUse ( ) ) ; } Nodes . push_back ( N ) ; NodeOrder . special_insert_for_special_msvc ( N ) ; NodeOrder . insert ( N ) ; GepNode * PN = N ; Type * PtrTy = cast < PointerType > ( PtrOp -> getType ( ) ) -> getElementType ( ) ; for ( User :: op_iterator OI = GepI -> idx_begin ( ) + <NUM_LIT> , OE = GepI -> idx_end ( ) ; OI != OE ; ++ OI ) { Value * Op = * OI ; GepNode * Nx = new ( * Mem ) GepNode ; Nx -> Parent = PN ; Nx -> Flags |= GepNode :: Internal ; Nx -> PTy = PtrTy ; Nx -> Idx = Op ; Nodes . push_back ( Nx ) ; NodeOrder . special_insert_for_special_msvc ( Nx ) ; NodeOrder . insert ( Nx ) ; PN = Nx ; PtrTy = next_type ( PtrTy , Op ) ; } if ( ! Us . empty ( ) ) { PN -> Flags |= GepNode :: Used ;

Uses [ PN ] . insert ( Us . begin ( ) , Us . end ( ) ) ;


<s> NodePairSet Eq , Ne ; for ( NodeSetMap :: iterator I = MaybeEq . begin ( ) , E = MaybeEq . end ( ) ; I != E ; ++ I ) { NodeSet & S = I -> second ; for ( NodeSet :: iterator NI = S . begin ( ) , NE = S . end ( ) ; NI != NE ; ++ NI ) { GepNode * N = * NI ; if ( node_class ( N , EqRel ) ) continue ; NodeSet C ; for ( NodeSet :: iterator NJ = std :: next ( NI ) ; NJ != NE ; ++ NJ ) if ( node_eq ( N , * NJ , Eq , Ne ) ) C . insert ( * NJ ) ; if ( ! C . empty ( ) ) { C . insert ( N ) ; std :: pair < NodeSymRel :: iterator , bool > Ins = EqRel . insert ( C ) ;


<s>
}
NodeSymRel
EqRel
;
NodePairSet
Eq
,
Ne
;
for
(
NodeSetMap
::
iterator
I
=
MaybeEq
.
begin
(
)
,
E
=
MaybeEq
.
end
(
)
;
I
!=
E
;
++
I
)
{
NodeSet
&
S
=
I
->
second
;
for
(
NodeSet
::
iterator
NI
=
S
.
begin
(
)
,
NE
=
S
.
end
(
)
;
NI
!=
NE
;
++
NI
)
{
GepNode
*
N
=
*
NI
;
if
(
node_class
(
N
,
EqRel
)
)
continue
;
NodeSet
C
;
for
(
NodeSet
::
iterator
NJ
=
std
::
next
(
NI
)
;
NJ
!=
NE
;
++
NJ
)
if
(
node_eq
(
N
,
*
NJ
,
Eq
,
Ne
)
)
C
.
insert
(
*
NJ
)
;
if
(
!
C
.
empty
(
)
)
{
C
.
insert
(
N
)
;
std
::
pair
<
NodeSymRel
::
iterator
,
bool
>
Ins
=
EqRel
.
insert
(
C
)
;
(
void
)
Ins
;
assert
(
Ins
.
second
&&
<STR_LIT>
)
;
}
}
}
DEBUG
(
{
dbgs
(
)
<<
<STR_LIT>
;
for
(
NodePairSet
::
iterator
I
=
Eq
.
begin
(
)
,
E
=
Eq
.
end
(
)
;
I
!=
E
;
++
I
)
dbgs
(
)
<<
<STR_LIT>
<<
I
->
first
<<
<STR_LIT>
<<
I
->
second
<<
<STR_LIT>
;
dbgs
(
)
<<
<STR_LIT>
;
for
(
NodeSymRel
::
iterator
I
=
EqRel
.
begin
(
)
,
E
=
EqRel
.
end
(
)
;
I
!=
E
;
++
I
)
{
dbgs
(
)
<<
'{'
;
const
NodeSet
&
S
=
*
I
;
for
(
NodeSet
::
const_iterator
J
=
S
.
begin
(
)
,
F
=
S
.
end
(
)
;
J
!=
F
;
++
J
)
{
if
(
J
!=
S
.
begin
(
)
)
dbgs
(
)
<<
','
;
dbgs
(
)
<<
' '
<<
*
J
;


<s> Type * next_type ( Type * Ty , Value * Idx ) {

if ( auto * PTy = dyn_cast < PointerType > ( Ty ) ) return PTy -> getElementType ( ) ;


<s> GepNode * N = * I ; unsigned H = node_hash ( N ) ; MaybeEq [ H ] . insert ( N ) ; } NodeSymRel EqRel ; NodePairSet Eq , Ne ; for ( NodeSetMap :: iterator I = MaybeEq . begin ( ) , E = MaybeEq . end ( ) ; I != E ; ++ I ) { NodeSet & S = I -> second ; for ( NodeSet :: iterator NI = S . begin ( ) , NE = S . end ( ) ; NI != NE ; ++ NI ) { GepNode * N = * NI ; if ( node_class ( N , EqRel ) ) continue ; NodeSet C ; for ( NodeSet :: iterator NJ = std :: next ( NI ) ; NJ != NE ; ++ NJ ) if ( node_eq ( N , * NJ , Eq , Ne ) ) C . insert ( * NJ ) ; if ( ! C . empty ( ) ) { C . insert ( N ) ; std :: pair < NodeSymRel :: iterator , bool > Ins = EqRel . insert ( C ) ; ( void ) Ins ; assert ( Ins . second && <STR_LIT> ) ; }


<s> ValueVect BO ; BO . push_back ( & Fn -> front ( ) ) ; for ( unsigned i = <NUM_LIT> ; i < BO . size ( ) ; ++ i ) { BasicBlock * B = cast < BasicBlock > ( BO [ i ] ) ;

for ( auto DTN : children < DomTreeNode * > ( DT -> getNode ( B ) ) ) BO . push_back ( DTN -> getBlock ( ) ) ;


<s> AU . addRequired < DominatorTreeWrapperPass > ( ) ; AU . addPreserved < DominatorTreeWrapperPass > ( ) ; AU . addRequired < PostDominatorTreeWrapperPass > ( ) ; AU . addPreserved < PostDominatorTreeWrapperPass > ( ) ; AU . addRequired < LoopInfoWrapperPass > ( ) ; AU . addPreserved < LoopInfoWrapperPass > ( ) ;

FunctionPass :: getAnalysisUsage ( AU ) ;


<s> AU . addPreserved < PostDominatorTreeWrapperPass > ( ) ; AU . addRequired < LoopInfoWrapperPass > ( ) ; AU . addPreserved < LoopInfoWrapperPass > ( ) ;


<s> BasicBlock * <ISA_LIT>CommonGEP :: adjustForInvariance ( GepNode * Node , NodeChildrenMap & NCM , NodeToValueMap & Loc ) { ValueVect Bs ; if ( Node -> Flags & GepNode :: Root ) { if ( Instruction * PIn = dyn_cast < Instruction > ( Node -> BaseVal ) ) Bs . push_back ( PIn -> getParent ( ) ) ; } else { Bs . push_back ( Loc [ Node -> Parent ] ) ; } if ( Instruction * IIn = dyn_cast < Instruction > ( Node -> Idx ) ) Bs . push_back ( IIn -> getParent ( ) ) ; BasicBlock * TopB = nearest_common_dominatee ( DT , Bs ) ; BasicBlock * LocB = cast_or_null < BasicBlock > ( Loc [ Node ] ) ; if ( LocB ) { Loop * Lp = LI -> getLoopFor ( LocB ) ; while ( Lp ) { if ( ! isInvariantIn ( Node , Lp ) || ! isInMainPath ( LocB , Lp ) ) break ;

BasicBlock * NewLoc = preheader ( DT , Lp ) ;


<s> ValueVect BO ; getBlockTraversalOrder ( & Fn -> front ( ) , BO ) ; ValueToNodeMap NM ; for ( ValueVect :: iterator I = BO . begin ( ) , E = BO . end ( ) ; I != E ; ++ I ) { BasicBlock * B = cast < BasicBlock > ( * I ) ; for ( BasicBlock :: iterator J = B -> begin ( ) , F = B -> end ( ) ; J != F ; ++ J ) { if ( ! isa < GetElementPtrInst > ( J ) ) continue ; GetElementPtrInst * GepI = cast < GetElementPtrInst > ( J ) ; if ( isHandledGepForm ( GepI ) ) processGepInst ( GepI , NM ) ; } }

DEBUG ( dbgs ( ) << <STR_LIT> << Nodes ) ;


<s> if ( node_class ( N , EqRel ) ) continue ; NodeSet C ; for ( NodeSet :: iterator NJ = std :: next ( NI ) ; NJ != NE ; ++ NJ ) if ( node_eq ( N , * NJ , Eq , Ne ) ) C . insert ( * NJ ) ; if ( ! C . empty ( ) ) { C . insert ( N ) ; std :: pair < NodeSymRel :: iterator , bool > Ins = EqRel . insert ( C ) ; ( void ) Ins ; assert ( Ins . second && <STR_LIT> ) ; } } } DEBUG ( { dbgs ( ) << <STR_LIT> ;

for ( NodePairSet :: iterator I = Eq . begin ( ) , E = Eq . end ( ) ; I != E ; ++ I ) dbgs ( ) << <STR_LIT> << I -> first << <STR_LIT> << I -> second << <STR_LIT> ;


<s> DEBUG ( dbgs ( ) << <STR_LIT> << LocationAsBlock ( Loc ) ) ; if ( OptEnableInv ) { for ( NodeVect :: iterator I = Roots . begin ( ) , E = Roots . end ( ) ; I != E ; ++ I ) adjustForInvariance ( * I , NCM , Loc ) ; DEBUG ( dbgs ( ) << <STR_LIT> << LocationAsBlock ( Loc ) ) ; } if ( OptEnableConst ) { for ( NodeVect :: iterator I = Roots . begin ( ) , E = Roots . end ( ) ; I != E ; ++ I ) separateConstantChains ( * I , NCM , Loc ) ; }

DEBUG ( dbgs ( ) << <STR_LIT> << Uses ) ;


<s> for ( NodeVect :: iterator I = Roots . begin ( ) , E = Roots . end ( ) ; I != E ; ++ I ) adjustForInvariance ( * I , NCM , Loc ) ; DEBUG ( dbgs ( ) << <STR_LIT> << LocationAsBlock ( Loc ) ) ; } if ( OptEnableConst ) { for ( NodeVect :: iterator I = Roots . begin ( ) , E = Roots . end ( ) ; I != E ; ++ I ) separateConstantChains ( * I , NCM , Loc ) ; } DEBUG ( dbgs ( ) << <STR_LIT> << Uses ) ;


<s> FunctionPass * create<ISA_LIT>CommonGEP ( ) { return new <ISA_LIT>CommonGEP ( ) ;


<s>
for
(
const_iterator
I
=
S
.
begin
(
)
,
E
=
S
.
end
(
)
;
I
!=
E
;
++
I
)
OS
<<
*
I
<<
' '
<<
*
*
I
<<
'\n'
;


<s> if ( ! NA [ nax ] -> PTy -> isPointerTy ( ) ) { Type * Int32Ty = Type :: getInt32Ty ( * Ctx ) ; IdxList [ IdxC ++ ] = ConstantInt :: get ( Int32Ty , <NUM_LIT> ) ; } while ( ++ nax <= Num ) { GepNode * N = NA [ nax - <NUM_LIT> ] ; IdxList [ IdxC ++ ] = N -> Idx ; if ( nax < Num ) { Type * NextTy = next_type ( N -> PTy , N -> Idx ) ; if ( NextTy != NA [ nax ] -> PTy ) break ; } } ArrayRef < Value * > A ( IdxList , IdxC ) ; Type * InpTy = Input -> getType ( ) ; Type * ElTy = cast < PointerType > ( InpTy -> getScalarType ( ) ) -> getElementType ( ) ; NewInst = GetElementPtrInst :: Create ( ElTy , Input , A , <STR_LIT> , & * At ) ; DEBUG ( dbgs ( ) << <STR_LIT> << * NewInst << '\n' ) ;


<s> if ( Flags & Root ) BaseVal = N -> BaseVal ; else Parent = N -> Parent ;


<s> if ( Flags & Root ) BaseVal = N -> BaseVal ;


<s> while ( ! Work . empty ( ) ) { NodeVect :: iterator First = Work . begin ( ) ; GepNode * N = * First ; Work . erase ( First ) ; if ( N -> Flags & GepNode :: Used ) { NodeToUsesMap :: iterator UF = Uses . find ( N ) ; assert ( UF != Uses . end ( ) && <STR_LIT> ) ; UseSet & Us = UF -> second ; for ( UseSet :: iterator I = Us . begin ( ) , E = Us . end ( ) ; I != E ; ++ I ) Values . push_back ( ( * I ) -> getUser ( ) ) ; }

NodeChildrenMap :: iterator CF = NCM . find ( N ) ;


<s> AU . addPreserved < PostDominatorTree > ( ) ; AU . addRequired < LoopInfoWrapperPass > ( ) ; AU . addPreserved < LoopInfoWrapperPass > ( ) ;


<s> typedef GTN :: ChildIteratorType Iter ; for ( Iter I = GTN :: child_begin ( DTN ) , E = GTN :: child_end ( DTN ) ; I != E ; ++ I ) getBlockTraversalOrder ( ( * I ) -> getBlock ( ) , Order ) ;


<s> <ISA_LIT>CommonGEP ( ) : FunctionPass ( ID ) {

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


Map . insert ( std :: make_pair ( N , ++ LastNum ) ) ;


<s> Map . insert ( std :: make_pair ( N , ++ LastNum ) ) ;


<s> for ( const_iterator I = Nodes . begin ( ) , E = Nodes . end ( ) ; I != E ; ++ I ) { GepNode * N = * I ; if ( N -> Flags & GepNode :: Root ) {


<s> in_set ( const NodeSet & S ) : NS ( S ) {


<s> bool <ISA_LIT>CommonGEP :: isHandledGepForm ( GetElementPtrInst * GepI ) { if ( ! GepI -> getType ( ) -> isPointerTy ( ) ) return false ; if ( GepI -> idx_begin ( ) == GepI -> idx_end ( ) ) return false ;


<s> if ( GepI -> idx_begin ( ) == GepI -> idx_end ( ) ) return false ;


<s> bool <ISA_LIT>CommonGEP :: isInMainPath ( BasicBlock * B , Loop * L ) { BasicBlock * HB = L -> getHeader ( ) ;

BasicBlock * LB = L -> getLoopLatch ( ) ;


<s> if ( Node -> Flags & GepNode :: Root ) if ( ! isInvariantIn ( Node -> BaseVal , L ) ) return false ; return isInvariantIn ( Node -> Idx , L ) ;


<s> bool <ISA_LIT>CommonGEP :: isInvariantIn ( GepNode * Node , Loop * L ) { if ( Node -> Flags & GepNode :: Root ) if ( ! isInvariantIn ( Node -> BaseVal , L ) ) return false ; return isInvariantIn ( Node -> Idx , L ) ;


<s> return isa < ConstantInt > ( N -> Idx ) ;


<s> return B -> empty ( ) || ( & * B -> begin ( ) == B -> getTerminator ( ) ) ;


<s> LocationAsBlock ( const NodeToValueMap & L ) : Map ( L ) {


<s> void <ISA_LIT>CommonGEP :: materialize ( NodeToValueMap & Loc ) { DEBUG ( dbgs ( ) << <STR_LIT> << Nodes << '\n' ) ; NodeChildrenMap NCM ; NodeVect Roots ; invert_find_roots ( Nodes , NCM , Roots ) ; while ( ! Roots . empty ( ) ) { NodeVect :: iterator First = Roots . begin ( ) ; GepNode * Root = * First , * Last = * First ; Roots . erase ( First ) ; NodeVect NA ; bool LastUsed = false ; unsigned LastCN = <NUM_LIT> ; Value * LocV = Loc [ Last ] ; if ( ! LocV ) continue ; BasicBlock * LastB = cast < BasicBlock > ( LocV ) ; do { NA . push_back ( Last ) ; LastUsed = ( Last -> Flags & GepNode :: Used ) ; if ( LastUsed ) break ; NodeChildrenMap :: iterator CF = NCM . find ( Last ) ;

LastCN = ( CF != NCM . end ( ) ) ? CF -> second . size ( ) : <NUM_LIT> ;


<s> BasicBlock * DomB = cast < BasicBlock > ( * I ) ; while ( ++ I != E ) { if ( ! * I ) continue ; BasicBlock * B = cast < BasicBlock > ( * I ) ;

if ( DT -> dominates ( B , DomB ) ) continue ;


<s> while ( ++ I != E ) { if ( ! * I ) continue ; BasicBlock * B = cast < BasicBlock > ( * I ) ; if ( DT -> dominates ( B , DomB ) ) continue ;

if ( ! DT -> dominates ( DomB , B ) ) return <NUM_LIT> ;


<s> dbgs ( ) << <STR_LIT> ; for ( typename T :: iterator I = Blocks . begin ( ) , E = Blocks . end ( ) ; I != E ; ++ I ) {


<s> int64_t i = CI -> getValue ( ) . getSExtValue ( ) ;

Type * NextTy = cast < StructType > ( Ty ) -> getElementType ( i ) ;


<s> assert ( CI && <STR_LIT> ) ; int64_t i = CI -> getValue ( ) . getSExtValue ( ) ; Type * NextTy = cast < StructType > ( Ty ) -> getElementType ( i ) ; return NextTy ;


<s> NodeOrdering ( ) : LastNum ( <NUM_LIT> ) {


<s> if ( CF != NCM . end ( ) ) { Work . insert ( Work . end ( ) , CF -> second . begin ( ) , CF -> second . end ( ) ) ;

Nodes . insert ( CF -> second . begin ( ) , CF -> second . end ( ) ) ;


<s> Work . push_back ( Root ) ; Nodes . insert ( Root ) ; while ( ! Work . empty ( ) ) { NodeVect :: iterator First = Work . begin ( ) ; GepNode * N = * First ; Work . erase ( First ) ; NodeChildrenMap :: iterator CF = NCM . find ( N ) ; if ( CF != NCM . end ( ) ) { Work . insert ( Work . end ( ) , CF -> second . begin ( ) , CF -> second . end ( ) ) ;


<s> for ( NodeSymRel :: iterator I = Rel . begin ( ) , E = Rel . end ( ) ; I != E ; ++ I ) if ( I -> count ( N ) ) return & * I ;


<s> const NodeSet * node_class ( GepNode * N , NodeSymRel & Rel ) {

for ( NodeSymRel :: iterator I = Rel . begin ( ) , E = Rel . end ( ) ; I != E ; ++ I ) if ( I -> count ( N ) ) return & * I ;


<s> bool node_eq ( GepNode * N1 , GepNode * N2 , NodePairSet & Eq , NodePairSet & Ne ) { if ( node_hash ( N1 ) != node_hash ( N2 ) ) return false ; NodePair NP = node_pair ( N1 , N2 ) ; NodePairSet :: iterator FEq = Eq . find ( NP ) ; if ( FEq != Eq . end ( ) ) return true ; NodePairSet :: iterator FNe = Ne . find ( NP ) ; if ( FNe != Ne . end ( ) ) return false ; bool Root1 = N1 -> Flags & GepNode :: Root ; bool Root2 = N2 -> Flags & GepNode :: Root ; NodePair P = node_pair ( N1 , N2 ) ; if ( Root1 != Root2 || ( Root1 && N1 -> BaseVal != N2 -> BaseVal ) ) { Ne . insert ( P ) ; return false ; } if ( Root1 || node_eq ( N1 -> Parent , N2 -> Parent , Eq , Ne ) ) { Eq . insert ( P ) ; return true ; } return false ;


<s> unsigned node_hash ( GepNode * N ) { FoldingSetNodeID ID ; ID . AddPointer ( N -> Idx ) ; ID . AddPointer ( N -> PTy ) ;


<s> if ( P1 <= P2 ) return std :: make_pair ( N1 , N2 ) ;


<s> BasicBlock * preheader ( DominatorTree * DT , Loop * L ) { if ( BasicBlock * PH = L -> getLoopPreheader ( ) ) return PH ; if ( ! OptSpeculate ) return <NUM_LIT> ; DomTreeNode * DN = DT -> getNode ( L -> getHeader ( ) ) ; if ( ! DN ) return <NUM_LIT> ;

return DN -> getIDom ( ) -> getBlock ( ) ;


<s> BasicBlock * PB = isa < PHINode > ( R ) ? cast < PHINode > ( R ) -> getIncomingBlock ( * U ) : cast < Instruction > ( R ) -> getParent ( ) ; Bs . push_back ( PB ) ; } } NodeChildrenMap :: iterator CF = NCM . find ( Node ) ; if ( CF != NCM . end ( ) ) { NodeVect & Cs = CF -> second ; for ( NodeVect :: iterator I = Cs . begin ( ) , E = Cs . end ( ) ; I != E ; ++ I ) { GepNode * CN = * I ; NodeToValueMap :: iterator LF = Loc . find ( CN ) ; if ( LF == Loc . end ( ) ) continue ; Bs . push_back ( LF -> second ) ; } } BasicBlock * DomB = nearest_common_dominator ( DT , Bs ) ;


<s> NodeVect & Cs = CF -> second ; for ( NodeVect :: iterator I = Cs . begin ( ) , E = Cs . end ( ) ; I != E ; ++ I ) { GepNode * CN = * I ; NodeToValueMap :: iterator LF = Loc . find ( CN ) ; if ( LF == Loc . end ( ) ) continue ; Bs . push_back ( LF -> second ) ; } } BasicBlock * DomB = nearest_common_dominator ( DT , Bs ) ; if ( ! DomB ) return <NUM_LIT> ; Instruction * IdxI = dyn_cast < Instruction > ( Node -> Idx ) ; if ( IdxI && ! DT -> dominates ( IdxI -> getParent ( ) , DomB ) ) return <NUM_LIT> ; while ( is_empty ( DomB ) ) { DomTreeNode * N = ( * DT ) [ DomB ] -> getIDom ( ) ; if ( ! N ) break ; DomB = N -> getBlock ( ) ; } Loc [ Node ] = DomB ;


<s> for ( NodeVect :: iterator I = Cs . begin ( ) , E = Cs . end ( ) ; I != E ; ++ I ) recalculatePlacementRec ( * I , NCM , Loc ) ; } BasicBlock * LB = recalculatePlacement ( Node , NCM , Loc ) ;

DEBUG ( dbgs ( ) << <STR_LIT> << Node << '\n' ) ;


<s> BasicBlock * B = cast < BasicBlock > ( BO [ i - <NUM_LIT> ] ) ; BasicBlock :: InstListType & IL = B -> getInstList ( ) ; typedef BasicBlock :: InstListType :: reverse_iterator reverse_iterator ; ValueVect Ins ; for ( reverse_iterator I = IL . rbegin ( ) , E = IL . rend ( ) ; I != E ; ++ I ) Ins . push_back ( & * I ) ; for ( ValueVect :: iterator I = Ins . begin ( ) , E = Ins . end ( ) ; I != E ; ++ I ) { Instruction * In = cast < Instruction > ( * I ) ;

if ( isInstructionTriviallyDead ( In ) ) In -> eraseFromParent ( ) ;


<s> DEBUG ( dbgs ( ) << <STR_LIT> << Node << <STR_LIT> << * R << '\n' ) ; BasicBlock * PB = cast < Instruction > ( R ) -> getParent ( ) ; GepNode * N = Node ; GepNode * C = <NUM_LIT> , * NewNode = <NUM_LIT> ; while ( is_constant ( N ) && ! ( N -> Flags & GepNode :: Root ) ) { GepNode * NewN = new ( * Mem ) GepNode ( N ) ; Nodes . push_back ( NewN ) ; Loc [ NewN ] = PB ; if ( N == Node ) NewNode = NewN ; NewN -> Flags &= ~ GepNode :: Used ; if ( C ) C -> Parent = NewN ; C = NewN ; N = N -> Parent ; } if ( ! NewNode ) return ; NodeToUsesMap :: iterator UF = Uses . find ( Node ) ;


<s> UseSet & Us = UF -> second ; UseSet LSs ; for ( UseSet :: iterator J = Us . begin ( ) , F = Us . end ( ) ; J != F ; ++ J ) { Use * U = * J ; User * R = U -> getUser ( ) ; if ( LoadInst * Ld = dyn_cast < LoadInst > ( R ) ) { unsigned PtrX = LoadInst :: getPointerOperandIndex ( ) ; if ( & Ld -> getOperandUse ( PtrX ) == U ) LSs . insert ( U ) ; } else if ( StoreInst * St = dyn_cast < StoreInst > ( R ) ) { unsigned PtrX = StoreInst :: getPointerOperandIndex ( ) ; if ( & St -> getOperandUse ( PtrX ) == U ) LSs . insert ( U ) ; } } if ( ! LSs . empty ( ) ) FNs . insert ( std :: make_pair ( N , LSs ) ) ;


<s> if ( N == nullptr ) return new Node ( R ) ; if ( N -> Range == R ) { N -> Count ++ ; return N ; }

if ( R < N -> Range ) N -> Left = add ( N -> Left , R ) ;


<s> static int32_t adjustDown ( int32_t V , uint8_t A , uint8_t O ) {


<s> int32_t U = ( V & - A ) + O ; return U <= V ? U : U - A ;


<s> static int32_t adjustUp ( int32_t V , uint8_t A , uint8_t O ) {


<s> RefMIs . insert ( ED0 . UseMI ) ; Blocks . insert ( DomB ) ; for ( unsigned i = <NUM_LIT> , e = Refs . size ( ) ; i != e ; ++ i ) { const ExtDesc & ED = Extenders [ Refs [ i ] ] ; MachineBasicBlock * MBB = ED . UseMI -> getParent ( ) ; RefMIs . insert ( ED . UseMI ) ; DomB = MDT -> findNearestCommonDominator ( DomB , MBB ) ; Blocks . insert ( MBB ) ; } Register Rs = ExtI . second . Rs ; const MachineInstr * DefI = Rs . isVReg ( ) ? MRI -> getVRegDef ( Rs . Reg ) : nullptr ; assert ( ! DefI || MDT -> dominates ( DefI -> getParent ( ) , DomB ) ) ; MachineBasicBlock :: iterator It ; if ( Blocks . count ( DomB ) ) { MachineBasicBlock :: iterator End = DomB -> end ( ) ; for ( It = DomB -> begin ( ) ; It != End ; ++ It ) if ( RefMIs . count ( & * It ) ) break ; assert ( It != End && <STR_LIT> ) ;


<s> DenseSet < MachineBasicBlock * > Blocks ; DenseSet < MachineInstr * > RefMIs ; const ExtDesc & ED0 = Extenders [ Refs [ <NUM_LIT> ] ] ; MachineBasicBlock * DomB = ED0 . UseMI -> getParent ( ) ; RefMIs . insert ( ED0 . UseMI ) ; Blocks . insert ( DomB ) ; for ( unsigned i = <NUM_LIT> , e = Refs . size ( ) ; i != e ; ++ i ) { const ExtDesc & ED = Extenders [ Refs [ i ] ] ; MachineBasicBlock * MBB = ED . UseMI -> getParent ( ) ; RefMIs . insert ( ED . UseMI ) ; DomB = MDT -> findNearestCommonDominator ( DomB , MBB ) ;


<s> Extenders . clear ( ) ; for ( MachineBasicBlock & MBB : MF ) { if ( MBB . getNumber ( ) == - <NUM_LIT> ) continue ; for ( MachineInstr & MI : MBB ) collectInstr ( MI ) ;


<s> Extenders . clear ( ) ; for ( MachineBasicBlock & MBB : MF ) {

if ( MBB . getNumber ( ) == - <NUM_LIT> ) continue ;


<s> case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : return ; } recordExtender ( MI , HII -> getCExtOpNum ( MI ) ) ;


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


<s> bool contains ( int32_t V ) const { return Min <= V && V <= Max && ( V - Offset ) % Align == <NUM_LIT> ;


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


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


<s> dbgs ( ) << <STR_LIT> << N -> Count << '\n' ; dbgs ( ) << <STR_LIT> << N -> MaxEnd << '\n' ; dbgs ( ) << <STR_LIT> << N -> Range << '\n' ; dbgs ( ) << <STR_LIT> << N -> Left << '\n' ; dbgs ( ) << <STR_LIT> << N -> Right << <STR_LIT> ;


<s> bool empty ( ) const { return Min > Max ;


<s> OffsetRange & extendBy ( int32_t D ) { assert ( D % Align == <NUM_LIT> ) ; if ( D < <NUM_LIT> ) Min = ( INT_MIN - D < Min ) ? Min + D : INT_MIN ;

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


<s> ExtExpr ( Register RS , bool NG , unsigned SH ) : Rs ( RS ) , S ( SH ) , Neg ( NG ) {


<s> ExtValue ( const ExtRoot & ER , int32_t Off ) : ExtRoot ( ER ) , Offset ( Off ) {


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


<s> const MachineOperand & HCE :: getLoadResultOp ( const MachineInstr & MI ) const {


<s> for ( const MachineOperand & Op : MRI -> use_operands ( Rd . Reg ) ) { if ( Rd != Register ( Op ) ) return OffsetRange :: zero ( ) ; Range . intersect ( getOffsetRange ( Rd , * Op . getParent ( ) ) ) ; }


<s> const MachineOperand & getOp ( ) const { return UseMI -> getOperand ( OpNum ) ;


<s> unsigned HCE :: getOperandIndex ( const MachineInstr & MI , const MachineOperand & Op ) const { for ( unsigned i = <NUM_LIT> , n = MI . getNumOperands ( ) ; i != n ; ++ i ) if ( & MI . getOperand ( i ) == & Op ) return i ;


<s> for ( const MachineOperand & Op : MI . operands ( ) ) { if ( ! Op . isReg ( ) || ! Op . isUse ( ) || MRI -> getRegClass ( Op . getReg ( ) ) != & <STR_LIT> ) continue ; assert ( Op . getSubReg ( ) == <NUM_LIT> && <STR_LIT> ) ;