Пример #1
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e l i n q u i s h M a g i c k M e m o r y                               %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  RelinquishMagickMemory() frees memory acquired with AcquireMagickMemory()
%  or AcquireQuantumMemory() for reuse.
%
%  The format of the RelinquishMagickMemory method is:
%
%      void *RelinquishMagickMemory(void *memory)
%
%  A description of each parameter follows:
%
%    o memory: A pointer to a block of memory to free for reuse.
%
*/
MagickExport void *RelinquishMagickMemory(void *memory)
{
  if (memory == (void *) NULL)
    return((void *) NULL);
#if !defined(MAGICKCORE_ZERO_CONFIGURATION_SUPPORT)
  memory_methods.destroy_memory_handler(memory);
#else
  LockSemaphoreInfo(memory_semaphore);
  assert((SizeOfBlock(memory) % (4*sizeof(size_t))) == 0);
  assert((*BlockHeader(NextBlock(memory)) & PreviousBlockBit) != 0);
  if ((*BlockHeader(memory) & PreviousBlockBit) == 0)
    {
      void
        *previous;

      /*
        Coalesce with previous adjacent block.
      */
      previous=PreviousBlock(memory);
      RemoveFreeBlock(previous,AllocationPolicy(SizeOfBlock(previous)));
      *BlockHeader(previous)=(SizeOfBlock(previous)+SizeOfBlock(memory)) |
        (*BlockHeader(previous) & ~SizeMask);
      memory=previous;
    }
  if ((*BlockHeader(NextBlock(NextBlock(memory))) & PreviousBlockBit) == 0)
    {
      void
        *next;

      /*
        Coalesce with next adjacent block.
      */
      next=NextBlock(memory);
      RemoveFreeBlock(next,AllocationPolicy(SizeOfBlock(next)));
      *BlockHeader(memory)=(SizeOfBlock(memory)+SizeOfBlock(next)) |
        (*BlockHeader(memory) & ~SizeMask);
    }
  *BlockFooter(memory,SizeOfBlock(memory))=SizeOfBlock(memory);
  *BlockHeader(NextBlock(memory))&=(~PreviousBlockBit);
  InsertFreeBlock(memory,AllocationPolicy(SizeOfBlock(memory)));
  UnlockSemaphoreInfo(memory_semaphore);
#endif
  return((void *) NULL);
}
Пример #2
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e l i n q u i s h M a g i c k M e m o r y                               %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  RelinquishMagickMemory() zeros memory that has been allocated, frees it for
%  reuse.
%
%  The format of the RelinquishMagickMemory method is:
%
%      void *RelinquishMagickMemory(void *memory)
%
%  A description of each parameter follows:
%
%    o memory: A pointer to a block of memory to free for reuse.
%
*/
MagickExport void *RelinquishMagickMemory(void *memory)
{
  if (memory == (void *) NULL)
    return((void *) NULL);
#if !defined(UseEmbeddableMagick)
  free(memory);
#else
  assert((SizeOfBlock(memory) % (4*sizeof(size_t))) == 0);
  assert((*BlockHeader(NextBlock(memory)) & PreviousBlockBit) != 0);
  AcquireSemaphoreInfo(&memory_semaphore);
  if ((*BlockHeader(memory) & PreviousBlockBit) == 0)
    {
      void
        *previous;

      /*
        Coalesce with previous adjacent block.
      */
      previous=PreviousBlock(memory);
      RemoveFreeBlock(previous,AllocationPolicy(SizeOfBlock(previous)));
      *BlockHeader(previous)=(SizeOfBlock(previous)+SizeOfBlock(memory)) |
        (*BlockHeader(previous) & ~SizeMask);
      memory=previous;
    }
  if ((*BlockHeader(NextBlock(NextBlock(memory))) & PreviousBlockBit) == 0)
    {
      void
        *next;

      /*
        Coalesce with next adjacent block.
      */
      next=NextBlock(memory);
      RemoveFreeBlock(next,AllocationPolicy(SizeOfBlock(next)));
      *BlockHeader(memory)=(SizeOfBlock(memory)+SizeOfBlock(next)) |
        (*BlockHeader(memory) & ~SizeMask);
    }
  *BlockFooter(memory,SizeOfBlock(memory))=SizeOfBlock(memory);
  *BlockHeader(NextBlock(memory))&=(~PreviousBlockBit);
  InsertFreeBlock(memory,AllocationPolicy(SizeOfBlock(memory)));
  RelinquishSemaphoreInfo(memory_semaphore);
#endif
  return((void *) NULL);
}
void SimpleDeadCodeElimination::Execute(Function* function) {
    StaticList<Instruction*, 512> worklist;
    Dictionary<Instruction*, bool> inWorklist; // If an instruction is in the worklist.

    // Try to remove 'store' instructions that have no effect.
    // The algorithm is really simple, but should catch cases like
    // arrays initialized with constants that were propagated already.
    RemoveDeadStores(function);

    // Try to remove copy/set operations that are unused,
    // because the aggregates they target are never referenced.
    RemoveDeadCopyOperations(function);

	// We process the blocks from last to first, and the instructions in the block
	// from last to first too; this allows removing more instructions on each
	// iteration that the usual first-last order.
	for(auto block = function->LastBlock(); block; block = block->PreviousBlock()) {
        // If the block is unreachable we remove all instructions from it,
        // but don't remove the block; this will be handled by the CFG Simplifier,
        // which knows how to repair the Dominator Tree.
        if(block->IsUnreachable() && (block->IsEmpty() == false)) {
            CleanUnreachableBlock(block);
            continue;
        }

        for(auto instr = block->LastInstruction(); instr; 
            instr = instr->PreviousInstruction()) {
            if(GetSafetyInfo()->IsDefinitelyDead(instr)) {
                worklist.Add(instr);
                inWorklist.Add(instr, true);
            }
        }
    }

	// Process while we have instructions in the worklist.
    while(worklist.IsNotEmpty()) {
        auto instr = worklist.RemoveLast();
        inWorklist.Remove(instr);

        // Remove the instruction if it's dead.
        if(GetSafetyInfo()->IsDefinitelyDead(instr)) {
            // All the instructions that where used by this one
            // may be dead now, add them to the worklist.
            for(int i = 0; i < instr->SourceOpCount(); i++) {
                auto sourceOp = instr->GetSourceOp(i);

                // Make sure we don't add an instruction in the worklist twice.
                if(auto definingInstr = sourceOp->DefiningInstruction()) {
                    if(inWorklist.ContainsKey(definingInstr) == false) {
                        worklist.Add(definingInstr);
                        inWorklist.Add(definingInstr, true);
                   }
                }
            }

            InstructionRemoved(instr);
            instr->RemoveFromBlock(true /* free */);
        }
    }

    // If there were removed stored we may now have variables
    // that are not used by any instruction.
    RemoveDeadVariables(function);
}