void *realloc(void *ptr, size_t size){ if (!ptr) { return malloc(size); } if (valid_address(ptr)) { size = align_pointer(size); block_t block = get_block(ptr); if (size <= block->size && BLOCK_SIZE_MIN <= block->size - size) { split_block(block, size); } else { if (block->next && block->next->free && size <= BLOCK_SIZE + block->size + block->next->size) { //merge möglich merge_block(block); if (BLOCK_SIZE_MIN <= block->size - size) { split_block(block, size); } } else { //real malloc void *newptr = malloc(size); if (!newptr) { perror("error at realloc"); return NULL; } block_t newblock = get_block(newptr); copy_block(block, newblock); free(block); return newptr; } } return ptr; } return 0; }
t_block *search_freed_block(size_t size) { t_page *page; t_block *b; size_t mem_width; t_page_type mal_type; mal_type = page_type(size); page = first_page(); b = NULL; while (page != NULL) { if (page->type == mal_type) b = search_freed_block_in_page(page, size); if (b != NULL) break ; page = page->next; } if (b == NULL) return (NULL); mem_width = b->size + BLOCK_SIZE; b->size = size; split_block(b, mem_width); b->is_free = 0; return (b); }
void* mm_realloc(void* ptr, size_t size) { #ifdef MM_USE_STUBS return realloc(ptr, size); #else if(size==0){ free(ptr); return ptr; } if(!ptr) return malloc(size); t_block last; t_block b = valid_addr(ptr,&last); if(!b) return ptr; size_t s = align4(size); if(b->size >= s){ if(b->size > s+BLOCK_SIZE+4) split_block(b,s); return ptr; } void *new = malloc(s); if(!new) return NULL; size_t i,s4,*sp,*newp; s4=s/(sizeof(size_t)); sp=(size_t*)(p); newp=(size_t*)(new); for(i=0;i<s4;i++) newp[i]=sp[i]; free(ptr); return new; //#error Not implemented. #endif }
void* mm_malloc(size_t size) { #ifdef MM_USE_STUBS return calloc(1, size); #else s_block_ptr block, last; size_t s; s = align4(size); if(foot){ last = foot; block = find_block(last, s); if(block){ if((block->size - s) >= (BLOCK_SIZE + 4)) split_block(block, s); block->free = 0; } else{ block = extend_heap(last, s); if(!block) return NULL; } } else{ block = extend_heap(NULL, s); if(!block) return NULL; foot = block; } return block->data; //#error Not implemented. #endif }
void* allocate_new_space(size_t size) { void* extend_heap_ptr = NULL; size_t one_time_alloc = find_one_time_sbrk_size(size); extend_heap_ptr = sbrk(one_time_alloc); MDIC(extend_heap_ptr) -> size = one_time_alloc; MDIC(extend_heap_ptr) -> occupy = false; free_list_add(extend_heap_ptr,size2order(MDIC(extend_heap_ptr)->size)); MDIC(extend_heap_ptr) -> area_head = extend_heap_ptr; MDIC(extend_heap_ptr) -> area_end = extend_heap_ptr + one_time_alloc; total_size += one_time_alloc; if(heap_ptr == NULL) heap_ptr = extend_heap_ptr; L(printf("allocate_new_space(): sbrked %zu bytes at loc %zu, total_size: %zu\n", MDIC(extend_heap_ptr) -> size, (size_t)(extend_heap_ptr - heap_ptr) ,total_size)); if (MDIC(extend_heap_ptr) -> size >= size) { /* Split if necessary, then return */ if(size > MDIC(extend_heap_ptr)->size / 2) return extend_heap_ptr; return split_block(extend_heap_ptr,size); } else { D( printf("new area %zu is smaller than the size %zu needed\n",one_time_alloc,size ) ); exit(0); } }
long mem_get(long request){ long l = request; long lidx = 0; long idx = 2; while(idx != 0){ if(get_length(idx) >= l && get_free(idx)){ /* Gat gevonden waar de aanvraag in past. */ lidx = idx; l = get_length(idx); break; } idx = get_next(idx); } if(lidx == 0){ /* Geen gat groot genoeg. */ return -1; }else if(l == request){ /* Gat precies groot genoeg. */ mem[0] += request; mem[1] += ADMIN_SIZE; set_free(lidx, 0); return lidx + ADMIN_SIZE; }else{ /* Alleen een gat > request. */ return split_block(lidx, request); } }
/********************************************************** * find_fit * Traverse the heap searching for a block to fit asize * Return NULL if no free blocks can handle that size * Assumed that asize is aligned * Uses fit bit option * If we find a block that is close to the request size (4*sizethreshold) * we will use that block * If we can't find a block close to request size then we return the closest * size and split the block before using it **********************************************************/ void * find_fit(size_t asize, int *list_broken) { if(asize>maxBlockSize1) return NULL; size_t bestfit = mem_heapsize(); size_t curfit; void *bestfitptr = NULL; void *free_bp; int sizethreshold = 2*DSIZE; for (free_bp = free_listp; free_bp != NULL; free_bp = *((void **)free_bp)) { if (asize <= GET_SIZE(HDRP(free_bp))) { curfit = GET_SIZE(HDRP(free_bp)) - asize; if (curfit < 4*sizethreshold) { bestfitptr = free_bp; break; } if (curfit < bestfit) { bestfit = curfit; bestfitptr = free_bp; } } } if ((bestfitptr != NULL) && (GET_SIZE(HDRP(bestfitptr)) - asize >= sizethreshold)) { bestfitptr = split_block (bestfitptr, asize); *list_broken = 1; } return bestfitptr; }
list_for_each(p, heap) { uint64_t start = (p->start + mask) & ~mask; if (p->file_priv == NULL && start + size <= p->start + p->size) return split_block(p, start, size, file_priv); }
void * wf_malloc (size_t size){ t_block b, last;//, size_of_whole_block; size_t s; //aligning the requested size using the macro defined in my_malloc.h s = ALIGN_SIZE(size, sizeof(char*)); //if base is initialized, we can proceed to implement malloc //size_of_used_block += size; if(base){ //first find a block last = base; b = find_worst_block (&last,s); //size_of_whole_block=last; if (b){ // size_of_whole_block->size += b->size; //is it big enough to be split if((b->size - s)>= (BLOCK_SIZE + 4 )) split_block (b,s); b->free = 0;//mark the chunk as used } else {//otherwise we extend the heap(NO FITTING BLOCK ) b = extend_heap(last,s); if (!b) return NULL; } } else {//Heap is empty (first time allocation) b = extend_heap(NULL,s); if(!b) return(NULL); base = b; } //size_of_whole_block->size += b->size; head = b; return (b->data); }
/* * ShmemDynAlloc */ void * ShmemDynAlloc(Size size) { void *block = NULL; Size padded_size; size = Max(ALIGN(size), MIN_ALLOC_SIZE); for (padded_size = 1; padded_size < size && padded_size <= 1024; padded_size *= 2); size = Max(size, padded_size); block = get_block(size); if (block == NULL) { /* * Don't request fewer than 1k from ShmemAlloc. * The more contiguous memory we have, the better we * can combat fragmentation. */ Size alloc_size = Max(size, MIN_SHMEM_ALLOC_SIZE); block = ShmemAlloc(BLOCK_SIZE(alloc_size)); memset(block, 0, BLOCK_SIZE(alloc_size)); block = (void *) ((intptr_t) block + sizeof(Header)); init_block(block, alloc_size, true); mark_allocated(block); } if (get_size(block) - size >= MIN_BLOCK_SIZE) split_block(block, size); Assert(is_allocated(block)); return block; }
//allocate memory void *malloc(size_t size){ t_block newBlock, last; size_t newSize = align8(size); if(base){ last = (t_block) base; newBlock = find_block(&last, newSize); if(newBlock){ //can we split if((newBlock->size - newSize) >= (OFFSET + PTR_SIZE)){ split_block(newBlock, newSize); } newBlock->block_free = false; } else { //Can't find block, try extending the heap newBlock = extend_heap(last, newSize); if(!newBlock){ //cannot extend heap return 0x0; } } } else { //first call newBlock = extend_heap(0x0, newSize); if(!newBlock){ //failed to extend return 0x0; } base = newBlock; } return newBlock->data; }
//No. 2 Best fit algorithm void * bf_malloc(size_t size){ t_block b,last;//,size_of_whole_block; size_t s; s = ALIGN_SIZE(size, sizeof(char*)); //size_of_used_block += size; if (base){ //find the best block last = base; b = find_best_block (&last, s); //size_of_whole_block=last; if (b){ // size_of_whole_block->size += b->size; //is it big enough to be split if ((b->size - s)>= (BLOCK_SIZE + 4 )) split_block (b,s); b->free = 0;//mark the chunk as used } else {//otherwise we extend the heap(NO FITTING BLOCK ) b = extend_heap(last,s); if (!b) return NULL; } } else {//Heap is empty (first time allocation) b = extend_heap(NULL,s); if(!b) return(NULL); base = b; } //size_of_whole_block->size += b->size; head = b; return (b-> data); }
void* malloc(size_t size) { block_t* block; if(size <= 0) return NULL; unsigned char index; size = adjust_size(size, &index); if(index > K_VALUE) return NULL; if(!global_memory){ /*first time*/ global_memory = sbrk(1<<K_VALUE); if(global_memory == (void*)-1) return NULL; block = global_memory; block->reserved = 0; block->kval = K_VALUE; block->succ = NULL; block->pred = NULL; free_list[K_VALUE] = block; } block = reserve_first(index); if(block) return (block + 1); unsigned char new_index = index; while(!free_list[new_index] ){ ++new_index; if(new_index > K_VALUE) return NULL; } while(new_index > index){ block = remove_first(new_index); block->reserved = 0; block->succ = NULL; block->pred = NULL; block_t* new_block = split_block(block); --new_index; block->succ = new_block; new_block->pred = block; free_list[new_index] = block; } block = reserve_first(index); return (block+1); }
void *mm_malloc(size_t size) { //The malloc routine which allocates free blocks //if we are given zero size, then there's nothing to malloc! if (size == 0) return NULL ; int new_size = ALIGN(size + BLK_HDR_FTR_SIZE); //check if there's a free block that will contain that size blockHdr *free_block = find_fit(new_size); if (free_block == NULL ) { //if there's no free block, then create one! //But keep track of epilogue before calling sbrk()! blockHdr *epilogue = GET_EPILOGUE; epilogue->size = BLK_HDR_SIZE; //call sbrk to get more space free_block = mem_sbrk(new_size + BLK_HDR_SIZE); //if there's an error return NULL if (free_block <= 0) return NULL ; //get the start of the freeblock free_block = (blockHdr *) ((char *) free_block - epilogue->size); //free_block size taking epilogue into account free_block->size = ((epilogue->size) + new_size) | 1; //now set the footer size of the newly created block blockFtr *ftr = (blockFtr *) ((char *) free_block - BLK_FTR_SIZE + ((free_block->size) & ~1)); ftr->size = free_block->size; //adjust the epilogue epilogue = GET_EPILOGUE; epilogue->next_p = epilogue; epilogue->prior_p = epilogue; epilogue->size = BLK_HDR_SIZE | 1; } else { //otherwise, use the free block! //if there's too much space, split the space and put remainder in appropriate free list free_block = split_block(free_block->size, new_size, free_block); //use the space you now have free_block->size |= 1; blockFtr *ftr = (blockFtr *) ((char *) free_block - BLK_FTR_SIZE + ((free_block->size) & ~1)); ftr->size |= 1; //set footer to allocated //and remove the free block from the doubly linked list remove_from_free_lists(free_block); } return (void *) ((char *) free_block + BLK_HDR_SIZE); }
static basic_block split_block_and_df_analyze (basic_block bb, rtx insn) { basic_block next; next = split_block (bb, insn)->dest; df_analyze (); return next; }
/* Allocate _length number of bytes of free memory and returns the address of the allocated portion. Returns 0 when out of memory. */ extern Addr my_malloc(unsigned int _length) { // Round up to the size we need int needed_size = basic_logarithm(_length); // Check if there is already a free block of the needed size if (freelist[needed_size][0] != NULL) { // There is already a block free Header* available = freelist[needed_size][0]; remove_header(available); available->is_allocated = true; return (void*) get_free_space(available); } else { // There isn't a block free // We need to break up a bigger block // Find the smallest available int power = needed_size + 1; while (power < 32 && freelist[power][0] == NULL) { power++; } if (power == 32) { // No block big enough free //printf("None big enough\n"); return NULL; } assert(freelist[power][0] != NULL); Header* header, *split; while (freelist[needed_size][0] == NULL) { header = freelist[power][0]; remove_header(header); split = split_block(header); if (header == split) { // Block can't split further header->is_allocated = true; return get_free_space(header); } else if (split == NULL) { // Split failed return NULL; } else { header->size -= 1; split->size = header->size - 1; add_header(header); add_header(split); } power--; } // We have a block ready Header* ready = freelist[needed_size][0]; remove_header(ready); ready->is_allocated = true; return get_free_space(ready); } }
/** * Allocate memory block * * Allocates a block of size bytes of memory, returning a pointer to the * beginning of the block. The content of the newly allocated block of * memory is not initialized, remaining with indeterminate values. * * @param size * Size of the memory block, in bytes. * * @return * On success, a pointer to the memory block allocated by the function. * * The type of this pointer is always void*, which can be cast to the * desired type of data pointer in order to be dereferenceable. * * If the function failed to allocate the requested block of memory, * a null pointer is returned. * * @see http://www.cplusplus.com/reference/clibrary/cstdlib/malloc/ */ void *malloc(size_t size) { if(size<=0) return NULL; if(free_list_ptr == NULL) free_list_ptr = free_list_init(); L( actual_size += size); size_t size_plus_dic = find_new_alloc_size(size); void *block_ptr = block_available(size_plus_dic); if (block_ptr == NULL) { /* Allocate new space from sbrk() */ block_ptr = allocate_new_space(size_plus_dic); D(printf("malloc(): find new space at loc %zu with length %zu, occupy:%d\n", (size_t)(block_ptr - heap_ptr),MDIC(block_ptr)->size, MDIC(block_ptr)->occupy )); // store the size_plus_dic into the block MDIC(block_ptr) -> occupy = true; free_list_delete(block_ptr , size2order( MDIC(block_ptr)->size )); // delete from free list. L( printf("size actual_size total_size: %zu %zu %zu\n",size,actual_size,total_size) ); return block_ptr + sizeof(mem_dic); } else { if (MDIC(block_ptr)->size > size_plus_dic) block_ptr = split_block(block_ptr,size_plus_dic); if ( !block_ptr || MDIC(block_ptr)->size != size_plus_dic){ D( printf("Error in malloc(): size after split cannot match\n") ); return NULL; } /* Assign the size to the block, split the block if necessary */ D( printf("malloc(): find old space at loc %zu with length %zu, occupy:%d\n", (size_t)(block_ptr - heap_ptr),MDIC(block_ptr)->size, MDIC(block_ptr)->occupy ) ); MDIC(block_ptr) -> occupy = true; free_list_delete(block_ptr,size2order( MDIC(block_ptr)->size )); L( printf("size actual_size total_size: %zu %zu %zu\n",size,actual_size,total_size) ); return block_ptr + sizeof(mem_dic); } return NULL; }
static struct mem_block *alloc_block(struct mem_block *heap, int size, int align2, struct drm_file *file_priv) { struct mem_block *p; int mask = (1 << align2) - 1; list_for_each(p, heap) { int start = (p->start + mask) & ~mask; if (p->file_priv == 0 && start + size <= p->start + p->size) return split_block(p, start, size, file_priv); }
static bool remove_exits_and_undefined_stmts (struct loop *loop, unsigned int npeeled) { struct nb_iter_bound *elt; bool changed = false; for (elt = loop->bounds; elt; elt = elt->next) { /* If statement is known to be undefined after peeling, turn it into unreachable (or trap when debugging experience is supposed to be good). */ if (!elt->is_exit && wi::ltu_p (elt->bound, npeeled)) { gimple_stmt_iterator gsi = gsi_for_stmt (elt->stmt); gcall *stmt = gimple_build_call (builtin_decl_implicit (BUILT_IN_UNREACHABLE), 0); gimple_set_location (stmt, gimple_location (elt->stmt)); gsi_insert_before (&gsi, stmt, GSI_NEW_STMT); split_block (gimple_bb (stmt), stmt); changed = true; if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "Forced statement unreachable: "); print_gimple_stmt (dump_file, elt->stmt, 0, 0); } } /* If we know the exit will be taken after peeling, update. */ else if (elt->is_exit && wi::leu_p (elt->bound, npeeled)) { basic_block bb = gimple_bb (elt->stmt); edge exit_edge = EDGE_SUCC (bb, 0); if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "Forced exit to be taken: "); print_gimple_stmt (dump_file, elt->stmt, 0, 0); } if (!loop_exit_edge_p (loop, exit_edge)) exit_edge = EDGE_SUCC (bb, 1); gcc_checking_assert (loop_exit_edge_p (loop, exit_edge)); gcond *cond_stmt = as_a <gcond *> (elt->stmt); if (exit_edge->flags & EDGE_TRUE_VALUE) gimple_cond_make_true (cond_stmt); else gimple_cond_make_false (cond_stmt); update_stmt (cond_stmt); changed = true; } } return changed; }
static struct mem_block *alloc_block(struct mem_block *heap, int size, int align2, struct drm_file *file_priv) { struct mem_block *p; int mask = (1 << align2) - 1; for (p = heap->next; p != heap; p = p->next) { int start = (p->start + mask) & ~mask; if (p->file_priv == NULL && start + size <= p->start + p->size) return split_block(p, start, size, file_priv); } return NULL; }
static struct mem_block *alloc_block( struct mem_block *heap, int size, int align2, int pid ) { struct mem_block *p; int mask = (1 << align2)-1; for (p = heap->next ; p != heap ; p = p->next) { int start = (p->start + mask) & ~mask; if (p->pid == 0 && start + size <= p->start + p->size) return split_block( p, start, size, pid ); } return NULL; }
/* * Allocate a block. */ void* kmalloc(size_t size) { struct block* b; size = ALIGNUP(size) + sizeof(struct block); b = find_smallest(size); if (!b) return NULL; split_block(b, size); #if defined(DEBUG_MEMORY) kprintf("mem: alloc %x+%x\n", b, b->length); #endif return b+1; }
void *malloc_reg(size_t size, t_zone *zone) { t_chunk *chunk; t_block *block; block = available_block_in_zone(zone, size); if (block == NULL) { ft_printf("no_block_available\tcreating chunk...\n"); chunk = create_chunk(zone); if (chunk == NULL) return (NULL); block = available_block_in_chunk(chunk, size); } return (split_block(block, size) + 1); }
void placeBlock(BlockInfo * ptrFreeBlock, size_t reqSize){ printf("Placing block\n"); BlockInfo * nextBlock = NULL; size_t blockSize; size_t precedingBlockUseTag; blockSize = SIZE(ptrFreeBlock->sizeAndTags); precedingBlockUseTag = (ptrFreeBlock->sizeAndTags) & TAG_PRECEDING_USED; if (blockSize - reqSize >= MIN_BLOCK_SIZE){ ptrFreeBlock->sizeAndTags = reqSize | TAG_USED |precedingBlockUseTag; split_block(ptrFreeBlock, blockSize, precedingBlockUseTag); } else{ ptrFreeBlock->sizeAndTags = blockSize | TAG_USED | precedingBlockUseTag; nextBlock = (BlockInfo *) UNSCALED_POINTER_ADD(ptrFreeBlock, SIZE(ptrFreeBlock->sizeAndTags)); set_next_block(nextBlock, TAG_PRECEDING_USED); } }
static basic_block hoist_edge_and_branch_if_true (gimple_stmt_iterator *gsip, tree cond, edge e_true, bool update_dominators) { tree tmp; gcond *cond_stmt; edge e_false; basic_block new_bb, split_bb = gsi_bb (*gsip); bool dominated_e_true = false; gcc_assert (e_true->src == split_bb); if (update_dominators && get_immediate_dominator (CDI_DOMINATORS, e_true->dest) == split_bb) dominated_e_true = true; tmp = force_gimple_operand_gsi (gsip, cond, /*simple=*/true, NULL, /*before=*/true, GSI_SAME_STMT); cond_stmt = gimple_build_cond_from_tree (tmp, NULL_TREE, NULL_TREE); gsi_insert_before (gsip, cond_stmt, GSI_SAME_STMT); e_false = split_block (split_bb, cond_stmt); new_bb = e_false->dest; redirect_edge_pred (e_true, split_bb); e_true->flags &= ~EDGE_FALLTHRU; e_true->flags |= EDGE_TRUE_VALUE; e_false->flags &= ~EDGE_FALLTHRU; e_false->flags |= EDGE_FALSE_VALUE; e_false->probability = REG_BR_PROB_BASE - e_true->probability; e_false->count = split_bb->count - e_true->count; new_bb->count = e_false->count; if (update_dominators) { if (dominated_e_true) set_immediate_dominator (CDI_DOMINATORS, e_true->dest, split_bb); set_immediate_dominator (CDI_DOMINATORS, e_false->dest, split_bb); } return new_bb; }
static basic_block make_forwarder_block (basic_block bb, int redirect_latch, int redirect_nonlatch, edge except, int conn_latch) { edge e, next_e, fallthru; basic_block dummy; rtx insn; insn = PREV_INSN (first_insn_after_basic_block_note (bb)); /* For empty block split_block will return NULL. */ if (BB_END (bb) == insn) emit_note_after (NOTE_INSN_DELETED, insn); fallthru = split_block (bb, insn); dummy = fallthru->src; bb = fallthru->dest; bb->aux = xmalloc (sizeof (int)); HEADER_BLOCK (dummy) = 0; HEADER_BLOCK (bb) = 1; /* Redirect back edges we want to keep. */ for (e = dummy->pred; e; e = next_e) { next_e = e->pred_next; if (e == except || !((redirect_latch && LATCH_EDGE (e)) || (redirect_nonlatch && !LATCH_EDGE (e)))) { dummy->frequency -= EDGE_FREQUENCY (e); dummy->count -= e->count; if (dummy->frequency < 0) dummy->frequency = 0; if (dummy->count < 0) dummy->count = 0; redirect_edge_with_latch_update (e, bb); } } alloc_aux_for_edge (fallthru, sizeof (int)); LATCH_EDGE (fallthru) = conn_latch; return dummy; }
struct mem_block * nouveau_mem_alloc_block(struct mem_block *heap, uint64_t size, int align2, struct drm_file *file_priv, int tail) { struct mem_block *p; uint64_t mask = (1 << align2) - 1; if (!heap) return NULL; if (tail) { list_for_each_prev(p, heap) { uint64_t start = ((p->start + p->size) - size) & ~mask; if (p->file_priv == NULL && start >= p->start && start + size <= p->start + p->size) return split_block(p, start, size, file_priv); } } else {
int Connection::handle_block() { size_t tsize = mreq_->tsize(); int retval = 0; // check whether there is one full message while (tsize >= proto_->head_size()) { size_t msize = proto_->calc_size(*mreq_); if ((ssize_t)msize < 0) { SYSLOG_ERROR("%s invalid message(len=%lu, data=%s): %m", name(), (unsigned long)msize, beyondy::toString(mreq_->rptr(), std::min(size_t(16), msize)).c_str()); retval = -1; } else if (msize < tsize) { if ((retval = split_block(msize)) < 0) break; tsize -= msize; continue; } else if (msize == tsize) { // exactly one message if ((retval = sched_->on_request(mreq_)) < 0) { // have to drop it SYSLOG_ERROR("%s drop message(len=%lu, data=%s): %m", name(), (unsigned long)msize, beyondy::toString(mreq_->rptr(), std::min(size_t(16), msize)).c_str()); delete mreq_; } mbr_ = mreq_ = NULL; break; } else { // not enough for one message // TODO: adjust??? retval = 0; break; } } return retval; }
void *malloc(size_t size) { t_block ptr, last; size_t temp_s = size; if (first_block) { /*First find a block*/ printf("mark first_block is not NULL now.\n"); last = first_block; ptr = find_block(&last, temp_s); /*split if yes*/ if (ptr) { printf("mark start of split_block"); if((ptr->size - temp_s) >= BLOCK_SIZE + 1) split_block(ptr, temp_s); ptr->is_free = FREE_N; } else { /*No fitting block, extend it*/ printf("====extend block because theres no fit block====\n"); ptr = extend_block(last, temp_s); if(!ptr) { fprintf(stderr, "extend block failed because of{ %s }\n", strerror(errno)); return NULL; } } } else { /*first time to allocate memory*/ ptr = extend_block(NULL, temp_s); if(!ptr) return NULL; first_block = ptr; } printf("====end of page ====\n"); return (void*)ptr->data; }
/* If we have assembler epilogues, the block falling through to exit must be the last one in the reordered chain when we reach final. Ensure that this condition is met. */ static void fixup_fallthru_exit_predecessor (void) { edge e; edge_iterator ei; basic_block bb = NULL; /* This transformation is not valid before reload, because we might separate a call from the instruction that copies the return value. */ gcc_assert (reload_completed); FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds) if (e->flags & EDGE_FALLTHRU) bb = e->src; if (bb && bb->aux) { basic_block c = ENTRY_BLOCK_PTR->next_bb; /* If the very first block is the one with the fall-through exit edge, we have to split that block. */ if (c == bb) { bb = split_block (bb, NULL)->dest; bb->aux = c->aux; c->aux = bb; bb->il.rtl->footer = c->il.rtl->footer; c->il.rtl->footer = NULL; } while (c->aux != bb) c = c->aux; c->aux = bb->aux; while (c->aux) c = c->aux; c->aux = bb; bb->aux = NULL; } }