// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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--;
        }
    }
}
Beispiel #2
0
	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());
                }
            }
        }
    }
}