// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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--; } } }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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()); } } } } }
bool IsReturnBlock(const TBlock* block) { return returnBlocks_.IsSet(block->Id()); }