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


<s> void <ISA_LIT>_CCState :: MarkAllocated ( unsigned Reg ) { UsedRegs [ Reg / <NUM_LIT> ] |= <NUM_LIT> << ( Reg


<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 ) , Locs ( locs ) , Context ( c ) {


<s> StackOffset = <NUM_LIT> ; UsedRegs . resize ( ( TM . getRegisterInfo ( ) ->

getNumRegs ( ) + <NUM_LIT> ) / <NUM_LIT> ) ;


<s> void <ISA_LIT>_CCState :: MarkAllocated ( unsigned Reg ) { 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> 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 ) { UsedRegs [ Reg / <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 (


<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 ) ; MarkAllocated ( ShadowReg


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


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


<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> ; addLoc ( CCValAssign :: getReg ( <NUM_LIT> , <STR_LIT> , Reg , <STR_LIT> , CCValAssign :: Full


<s> LLVMContext & getContext ( ) const { return


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


<s> unsigned getNextStackOffset ( ) const { return StackOffset


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


<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> ; UsedRegs . resize ( ( TM . getRegisterInfo ( ) -> getNumRegs (


<s> bool isAllocated ( unsigned Reg ) const { return UsedRegs [ Reg / <NUM_LIT> ] & ( <NUM_LIT> << ( Reg &


<s> bool isAllocated ( unsigned Reg ) const { return UsedRegs [ Reg / <NUM_LIT> ] & ( <NUM_LIT> << ( Reg & <NUM_LIT> )


<s> void <ISA_LIT>_CCState :: MarkAllocated ( unsigned Reg ) { const TargetRegisterInfo & TRI = * TM . getRegisterInfo ( ) ; for ( MCRegAliasIterator AI ( Reg , & TRI , true ) ; AI . isValid ( ) ; ++ AI ) UsedRegs [ *

AI / <NUM_LIT> ] |= <NUM_LIT> << ( * AI & <NUM_LIT> ) ;


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


<s> return MachineFunctionProperties ( ) . set ( MachineFunctionProperties


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


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


<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 ; return false


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


<s> static bool IsUnconditionalJump ( int Opc ) { return ( Opc == <STR_LIT>


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


<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> <ISA_LIT>CFGOptimizer ( const <ISA_LIT>TargetMachine & TM ) : MachineFunctionPass ( ID ) , QTM (

TM ) , QST ( * TM . getSubtargetImpl ( ) ) {


<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> : NewOpcode = <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> ) .


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

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


<s> static bool IsConditionalBranch ( int Opc ) { return ( 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 ( ) ) ) { 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


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


<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 ( ) ) ; for ( const auto & OrigLI : OrigLiveIn ) LayoutSucc -> removeLiveIn ( OrigLI


<s> static bool IsConditionalBranch ( int Opc ) { return ( Opc == <STR_LIT> ) || ( Opc == <STR_LIT> ) || ( Opc == <STR_LIT> ) || ( Opc


<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


<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> : NewOpcode =


<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 : llvm_unreachable ( <STR_LIT>


<s> PassInfo * PI = new PassInfo ( <STR_LIT> , <STR_LIT> , & <ISA_LIT>CFGOptimizer


<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 : llvm_unreachable ( <STR_LIT>


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


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

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


<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


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


<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


<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 { return <STR_LIT>


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


<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 ; CN -> Flags &= ~


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


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


<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


<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 ; return nullptr


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


<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 ; NodePair P = node_pair ( N1 , N2


<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 ) ; return std :: make_pair ( N2 ,


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


<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 ( ) ; Bs . push_back ( PB


<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 ) ; Us . erase (


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


<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 ) ) ; if ( OptEnableInv )


<s> for ( const_iterator I = S . begin ( ) , E = S . end ( ) ; I != E ; ++


<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 ; return NewInst


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


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


<s> for ( auto * DTN : children < DomTreeNode * > ( DT -> getNode ( Root ) ) ) getBlockTraversalOrder ( DTN -> getBlock (


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


<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 .


<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> ) ; UseSet & Us =


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


<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 ; while ( is_empty ( DomB )


<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 ) ; } NewNode -> Flags |= GepNode ::


<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


<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 ) ; } LLVM_DEBUG ( dbgs ( )


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


<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
(
)
<<
','
;
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 ( ) <<


<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 ) ; if ( Idx < Num


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


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


<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


<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


<s> if ( CF != NCM . end ( ) ) { NodeVect & Cs = CF -> second ; for ( GepNode * C : Cs ) recalculatePlacementRec


<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 ) ; for ( Value * I : Ins


<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


<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 ( ) ) ; UseSet & Us =


<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


<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 (


<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' ) ; Input =


<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 (


<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 ) ; NodeOrder . insert ( 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 ; Nx -> Parent


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


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


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


<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 ; } while ( nax <= Num )


<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 ; Nodes . push_back ( Nx


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


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


<s> Type * next_type ( Type * Ty , Value * Idx ) { if ( auto * PTy = dyn_cast < PointerType > (

Ty ) ) return PTy -> getElementType ( ) ;


<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


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


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


<s> for ( Function :: iterator A = F . begin ( ) , Z = F . end ( ) ; A != Z ; ++ A ) for ( BasicBlock :: iterator I = A -> begin ( ) , E = A -> end ( ) ; I != E ; ++ I ) if ( isa <

InvokeInst > ( I ) || isa < LandingPadInst > ( I ) ) return false ;


<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


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


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


<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 ) ; DEBUG ( dbgs ( ) << <STR_LIT> << LocationAsBlock ( Loc )


<s> for ( const_iterator I = S . begin ( ) , E = S . end ( ) ; I != E ; ++ I )


<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' ) ; Input =


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


<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


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


<s> initialize<ISA_LIT>CommonGEPPass ( * PassRegistry ::


<s> <ISA_LIT>CommonGEP ( ) : FunctionPass ( ID ) { initialize<ISA_LIT>CommonGEPPass ( * PassRegistry :: getPassRegistry ( )


<s> void insert ( const GepNode * N ) { Map . insert ( std :: make_pair ( N , ++


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


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


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


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


<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 ( ) ) ?


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


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


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


<s> int64_t i = CI -> getValue ( ) . getSExtValue ( ) ; Type * NextTy = cast < StructType >


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


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


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


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


<s> FoldingSetNodeID ID ; ID . AddPointer ( N


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


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


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


<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 ) ; if ( ! DomB


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


<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 ) ; assert ( UF != Uses .


<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 ,


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


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


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


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


<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 ) ; Blocks . insert


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


<s> bool contains ( int32_t V ) const { return Min <= V && V <= Max && (


<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> ; if ( N -> Left ) dump


<s> void erase ( const Node * N ) { Root = remove (


<s> void erase ( const Node * N ) { Root = remove ( Root , N


<s> if ( D < <NUM_LIT> ) Min = ( INT_MIN - D


<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


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


<s> assert ( MI . mayLoad ( ) ) ; return MI . getOperand


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


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


<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 ; llvm_unreachable ( <STR_LIT>


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


<s> const MachineOperand & HCE :: getStoredValueOp ( const MachineInstr & MI ) const { assert ( MI . mayStore ( ) ) ; return MI . getOperand ( MI . getNumExplicitOperands ( ) - <NUM_LIT>


<s> assert ( MI . mayStore ( ) ) ; return MI . getOperand ( MI . getNumExplicitOperands (


<s> unsigned height ( Node * N ) { return N != nullptr ? N ->


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


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


<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> return Reg != <NUM_LIT> && ! TargetRegisterInfo :: isStackSlot ( Reg ) && TargetRegisterInfo :: isVirtualRegister (


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


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


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


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


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


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

IsAbsSet ) Replaced = replaceInstrExact ( ED , ExtR ) ;


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


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


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


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


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


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


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


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


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

) && llvm :: Register :: isVirtualRegister ( Reg ) ;


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


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


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


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


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


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


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


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


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

PrintInit ( ExtI , * HRI ) << <STR_LIT> << * InitI ) ;


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


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


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


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


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


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

<< getPassName ( ) << '\n' , nullptr ) ;


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


<s> bool isSlot ( ) const { return Reg != <NUM_LIT> && Reg


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


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


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


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


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


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


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


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


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


<s> void print ( const TargetRegisterInfo *


<s> void print ( const TargetRegisterInfo * TRI =


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

<< printMBBReference ( B ) << <STR_LIT> << printMBBReference ( * SB ) << '\n' ;


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


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


<s> <ISA_LIT>ConstEvaluator HCE ( MF ) ; return MachineConstPropagator ( HCE ) . run


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


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


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


<s> LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << printReg ( Reg , & MCE . TRI ) << Cells . get ( Reg ) << '\n' ) ; for ( MachineInstr & MI : MRI -> use_nodbg_instructions


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


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


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


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


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


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


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


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


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


<s> if ( LS1 . isBottom ( ) || LS1 . isProperty ( ) ) return false ; APInt A , CA ; for ( unsigned i = <NUM_LIT> ; i < LS1 . size ( ) ; ++ i ) { bool Eval = constToInt ( LS1 . Values [ i ] , A ) &&

evaluateCTBi ( A , Zeros , Ones , CA ) ;


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


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


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


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


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


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


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


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


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


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


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


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