@ -93,6 +93,34 @@ namespace mir
s_ops [ 0 ] . GetReg ( ) ! = l_ops [ 0 ] . GetReg ( ) ;
}
static bool TryMergeZeroStores ( MachineInstr & first , MachineInstr & second )
{
if ( first . GetOpcode ( ) ! = Opcode : : StoreStack | |
second . GetOpcode ( ) ! = Opcode : : StoreStack )
return false ;
const auto & f_ops = first . GetOperands ( ) ;
const auto & s_ops = second . GetOperands ( ) ;
if ( f_ops . size ( ) < 2 | | s_ops . size ( ) < 2 )
return false ;
if ( f_ops [ 0 ] . GetKind ( ) ! = Operand : : Kind : : Reg | |
s_ops [ 0 ] . GetKind ( ) ! = Operand : : Kind : : Reg )
return false ;
if ( f_ops [ 0 ] . GetReg ( ) ! = PhysReg : : WZR | |
s_ops [ 0 ] . GetReg ( ) ! = PhysReg : : WZR )
return false ;
if ( f_ops [ 1 ] . GetKind ( ) ! = Operand : : Kind : : FrameIndex | |
s_ops [ 1 ] . GetKind ( ) ! = Operand : : Kind : : FrameIndex )
return false ;
int fi1 = f_ops [ 1 ] . GetFrameIndex ( ) ;
int fi2 = s_ops [ 1 ] . GetFrameIndex ( ) ;
if ( fi2 ! = fi1 + 1 )
return false ;
first = MachineInstr ( Opcode : : StoreStack ,
{ Operand : : Reg ( PhysReg : : XZR ) ,
Operand : : FrameIndex ( fi1 ) } ) ;
return true ;
}
static void RunPeepholeOnBlock ( MachineBasicBlock & block )
{
auto & insts = block . GetInstructions ( ) ;
@ -123,6 +151,20 @@ namespace mir
}
}
if ( ! changed )
{
for ( auto it = insts . begin ( ) ; it ! = insts . end ( ) ; + + it )
{
auto next = std : : next ( it ) ;
if ( next ! = insts . end ( ) & & TryMergeZeroStores ( * it , * next ) )
{
next = insts . erase ( next ) ;
changed = true ;
break ;
}
}
}
if ( ! changed )
{
for ( auto it = insts . begin ( ) ; it ! = insts . end ( ) ; + + it )