可以使用什么算法来计算控制流图中的后支配者?
目前我通过使用迭代位向量算法来计算支配者:
#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;
}