@ -123,31 +123,49 @@ bool sort_mem_region(const mem_cfg_t &a, const mem_cfg_t &b)
return ( a . base < b . base ) ;
}
void merge_overlapping_memory_regions ( std : : vector < mem_cfg_t > & mems )
static bool check_mem_overlap ( const mem_cfg_t & L , const mem_cfg_t & R )
{
// check the user specified memory regions and merge the overlapping or
// eliminate the containing parts
assert ( ! mems . empty ( ) ) ;
const reg_t L_end = L . base + L . size - 1 ;
const reg_t R_end = R . base + R . size - 1 ;
return std : : max ( L . base , R . base ) < = std : : min ( L_end , R_end ) ;
}
static mem_cfg_t merge_mem_regions ( const mem_cfg_t & L , const mem_cfg_t & R )
{
// one can merge only intersecting regions
assert ( check_mem_overlap ( L , R ) ) ;
const reg_t merged_base = std : : min ( L . base , R . base ) ;
const reg_t merged_end_incl = std : : max ( L . base + L . size - 1 , R . base + R . size - 1 ) ;
const reg_t merged_size = merged_end_incl - merged_base + 1 ;
return mem_cfg_t ( merged_base , merged_size ) ;
}
// check the user specified memory regions and merge the overlapping or
// eliminate the containing parts
static std : : vector < mem_cfg_t >
merge_overlapping_memory_regions ( std : : vector < mem_cfg_t > mems )
{
if ( mems . empty ( ) )
return { } ;
std : : sort ( mems . begin ( ) , mems . end ( ) , sort_mem_region ) ;
for ( auto it = mems . begin ( ) + 1 ; it ! = mems . end ( ) ; ) {
reg_t start = prev ( it ) - > base ;
reg_t end = prev ( it ) - > base + prev ( it ) - > size ;
reg_t start2 = it - > base ;
reg_t end2 = it - > base + it - > size ;
//contains -> remove
if ( start2 > = start & & end2 < = end ) {
it = mems . erase ( it ) ;
//partial overlapped -> extend
} else if ( start2 > = start & & start2 < end ) {
prev ( it ) - > size = std : : max ( end , end2 ) - start ;
it = mems . erase ( it ) ;
// no overlapping -> keep it
} else {
it + + ;
std : : vector < mem_cfg_t > merged_mem ;
merged_mem . push_back ( mems . front ( ) ) ;
for ( auto mem_it = std : : next ( mems . begin ( ) ) ; mem_it ! = mems . end ( ) ; + + mem_it ) {
const auto & mem_int = * mem_it ;
if ( ! check_mem_overlap ( merged_mem . back ( ) , mem_int ) ) {
merged_mem . push_back ( mem_int ) ;
continue ;
}
merged_mem . back ( ) = merge_mem_regions ( merged_mem . back ( ) , mem_int ) ;
}
return merged_mem ;
}
static std : : vector < mem_cfg_t > parse_mem_layout ( const char * arg )
@ -217,9 +235,10 @@ static std::vector<mem_cfg_t> parse_mem_layout(const char* arg)
arg = p + 1 ;
}
merge_overlapping_memory_regions ( res ) ;
auto merged_mem = merge_overlapping_memory_regions ( res ) ;
return res ;
assert ( ! merged_mem . empty ( ) ) ;
return merged_mem ;
}
static std : : vector < std : : pair < reg_t , mem_t * > > make_mems ( const std : : vector < mem_cfg_t > & layout )