图形后置优势算法?

时间:2014-11-30 17:04:41

标签: c++ algorithm graph graph-theory

可以使用什么算法来计算控制流图中的后支配者?

目前我通过使用迭代位向量算法来计算支配者:

#include <iostream>
#include <list>
#include <stack>
#include <vector>
#include <memory>
#include <map>

class BasicBlock
{
public:
    BasicBlock(std::string name) : mName(name) { }

    void AllocateDominatorsAndSetToTrue(const size_t nBlocks)
    {
        mDominators.resize(nBlocks);
        for (size_t i = 0; i < nBlocks; i++)
        {
            mDominators[i] = true;
        }
    }

    void SetAllDominatorsTo(bool value)
    {
        for (size_t i = 0; i < mDominators.size(); i++)
        {
            mDominators[i] = value;
        }
    }

    std::string mName;

    int mId = 0;

    // Links to blocks before this one
    std::vector<BasicBlock*> mPredecessors;

    // Links to blocks after this one
    std::vector<BasicBlock*> mSucessors;

    std::vector<bool> mDominators;
    std::vector<BasicBlock*> mImmediateDominator;
};

class ControlFlowGraph
{
public:
    void AddBasicBlock(std::string name)
    {
        mBasicBlocks.emplace_back(std::make_unique<BasicBlock>(name));
    }

    void AddSucessor(std::string block, std::string target)
    {
        FindBlock(block)->mSucessors.emplace_back(FindBlock(target));
    }

    void AddPredecessor(std::string block, std::string target)
    {
        FindBlock(block)->mPredecessors.emplace_back(FindBlock(target));
    }

    BasicBlock* FindBlock(std::string name)
    {
        for (const auto& block : mBasicBlocks)
        {
            if (block->mName == name)
            {
                return block.get();
            }
        }
        return nullptr;
    }

    void CalculateDominators()
    {
        const size_t nBlocks = mBasicBlocks.size();
        int i = 0;
        for (std::unique_ptr<BasicBlock>& block : mBasicBlocks)
        {
            block->mId = i++;
            block->AllocateDominatorsAndSetToTrue(nBlocks);
        }

        BasicBlock* block = mBasicBlocks[0].get();
        block->SetAllDominatorsTo(false);
        block->mDominators[block->mId] = true; // block always dominates itself

        bool changed = false;
        do
        {
            changed = false;
            for (std::unique_ptr<BasicBlock>& b : mBasicBlocks)
            {
                if (b == mBasicBlocks[0]) // Is it the entry node?
                {
                    continue;
                }
                for (BasicBlock* pred : b->mPredecessors)
                {
                    auto T = b->mDominators;
                    for (size_t i = 0; i < nBlocks; i++)
                    {
                        if (b->mDominators[i] && pred->mDominators[i])
                        {
                            b->mDominators[i] = true;
                        }
                        else
                        {
                            b->mDominators[i] = false;
                        }
                    }
                    b->mDominators[b->mId] = true; // block always dominates itself
                    if (b->mDominators != T)
                    {
                        changed = true;
                    }
                }
            }
        } 
        while (changed);
    }

    void CalculateImmediateDominators()
    {
        // ??
    }

    std::vector<std::unique_ptr<BasicBlock>> mBasicBlocks;
};

int main()
{
    ControlFlowGraph graph;

    graph.AddBasicBlock("1");
    graph.AddBasicBlock("2");
    graph.AddBasicBlock("3");
    graph.AddBasicBlock("4");
    graph.AddBasicBlock("5");
    graph.AddBasicBlock("6");

    graph.AddSucessor("1", "2");
    graph.AddSucessor("2", "3");
    graph.AddSucessor("2", "4");
    graph.AddSucessor("3", "2");
    graph.AddSucessor("4", "5");
    graph.AddSucessor("4", "6");
    graph.AddSucessor("5", "4");
    graph.AddSucessor("6", "2");

    graph.AddPredecessor("2", "1");
    graph.AddPredecessor("3", "2");
    graph.AddPredecessor("4", "2");
    graph.AddPredecessor("5", "4");
    graph.AddPredecessor("6", "4");


    graph.CalculateDominators();
    graph.CalculateImmediateDominators();

    return 0;
}

0 个答案:

没有答案