// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void SimpleDeadCodeElimination::RemoveDeadVariables(Function* function) { SparseBitVector liveVars; // Scan every instruction in the function and mark any local variable // that appears as an operand. All variables that are not marked are deleted. function->ForEachInstruction([&liveVars](Instruction* instr) -> bool { for(int i = 0; i < instr->SourceOpCount(); i++) { if(auto variableRef = instr->GetSourceOp(i)->As<VariableReference>()) { auto variable = variableRef->GetVariable(); // Only local variables. if(variable && (variable->IsParameter() == false)) { liveVars.SetBit(variable->Id()); } } } return true; }); // Now removed all unused variables. for(int i = 0; i < function->VariableCount(); i++) { auto variable = function->Variables()[i]; if(liveVars.IsSet(variable->Id()) == false) { function->RemoveVariable(variable); i--; } } }
const TBlock* GetStartBlock(const TFunction* function) { // It's possible that the function has multiple exit blocks. // In this case we need to create a fake block that acts like an // "unique" exit block, whose predecessors are the real exit blocks. if(exitBlock_) { // A fake exit block has been already created. return exitBlock_; } StaticList<const TBlock*, 16> exitBlocks; const TBlock* block = function->FirstBlock(); while(block) { if(block->SuccessorCount() == 0) { // This is an exit block. exitBlocks.Add(block); returnBlocks_.SetBit(block->Id()); } block = block->NextBlock(); } // Now return the exit block. If there is no unique block // we create a "fake" one that has all the exit blocks // as its predecessors. This block will be deleted after the analysis. if(exitBlocks.Count() == 1) { // There is a single exit block. return exitBlocks[0]; } else if(exitBlocks.Count() > 1) { // There are multiple exit blocks, create a fake block. exitBlock_ = TBlock::GetBlock("#fakeBlock"); for(int i = 0; i < exitBlocks.Count(); i++) { exitBlock_->AddPredecessor(const_cast<TBlock*>(exitBlocks[i])); } return exitBlock_; } else { // There is no exit block. This can happen, for example, if the last // block represents an infinite loop. In this case return the last block. return function->LastBlock(); } }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void AggregateCopyPropagation::IterateToFixedpoint() { // We use an iterative data-flow algorithm to propagate the copies // that are available on entry of each block. Add the blocks // in reverse-postorder, this minimizes the number of iterations. StaticList<Block*, 64> worklist; SparseBitVector inWorklist; CFGInfo<Block, Function> cfgInfo(funct_->FirstBlock(), false); auto& postorderList = cfgInfo.PostorderList(); int copyCount = infoList_.Count(); // Add all blocks to the worklist. for(int i = 0; i < postorderList.Count(); i++) { auto block = const_cast<Block*>(postorderList[i]); worklist.Add(block); inWorklist.SetBit(block->Id()); } while(worklist.IsNotEmpty()) { // Extract a block from the worklist. auto block = worklist.RemoveLast(); inWorklist.ResetBit(block->Id()); // Compute the 'in' set, which is the intersection // out the 'out' sets of the predecessors. BitVector inSet(copyCount, false); auto predecessorEnum = block->GetPredecessorEnum(); bool first = true; while(predecessorEnum.IsValid()) { auto predecessorBlock = predecessorEnum.Next(); if(first) { inSet = outSets_[predecessorBlock]; first = false; } else inSet.And(outSets_[predecessorBlock]); } // Save the 'in' set, it's needed later // when we want to eliminate the copies. inSets_.Add(block, inSet); // Now compute the new 'out' set, which is the union of the 'copy' set // with the 'in' set, from which the 'kill' set has been subtracted. // Out(B) = Copy(B) U (In(B) - Kill(B)) BitVector outSet = copySets_[block]; inSet.Difference(killSets_[block]); outSet.Or(inSet); if(outSets_[block] != outSet) { // The 'out' set must be updated, and all successors // must be added to the worklist and reprocessed. outSets_[block] = outSet; auto successorEnum = block->GetSuccessorEnum(); while(successorEnum.IsValid()) { auto successorBlock = successorEnum.Next(); if(inWorklist.IsSet(successorBlock->Id()) == false) { worklist.Add(successorBlock); inWorklist.IsSet(successorBlock->Id()); } } } } }