<commit_before>#include <llvm/IR/Function.h>
#include <llvm/Analysis/PostDominators.h>

#include "analysis/BFS.h"
#include "analysis/PostDominanceFrontiers.h"

#include "llvm/LLVMDependenceGraph.h"

namespace dg {

void LLVMDependenceGraph::computePostDominators(bool addPostDomFrontiers)
{
    using namespace llvm;

    PostDominatorTree *pdtree = new PostDominatorTree();
    analysis::PostDominanceFrontiers<LLVMNode> pdfrontiers;

    // iterate over all functions
    for (auto F : getConstructedFunctions()) {
        // root of post-dominator tree
        LLVMBBlock *root = nullptr;
        Value *val = const_cast<Value *>(F.first);
        Function& f = *cast<Function>(val);
        // compute post-dominator tree for this function
        pdtree->runOnFunction(f);

        // add immediate post-dominator edges
        auto our_blocks = F.second->getBlocks();
        bool built = false;
        for (auto it : our_blocks) {
            LLVMBBlock *BB = it.second;
            BasicBlock *B = cast<BasicBlock>(const_cast<Value *>(it.first));
            DomTreeNode *N = pdtree->getNode(B);
            // when function contains infinite loop, we're screwed
            // and we don't have anything
            // FIXME: just check for the root, don't iterate over all blocks, stupid...
            if (!N)
                continue;

            DomTreeNode *idom = N->getIDom();
            BasicBlock *idomBB = idom ? idom->getBlock() : nullptr;
            built = true;

            if (idomBB) {
                LLVMBBlock *pb = our_blocks[idomBB];
                assert(pb && "Do not have constructed BB");
                BB->setIPostDom(pb);
                assert(cast<BasicBlock>(BB->getKey())->getParent()
                        == cast<BasicBlock>(pb->getKey())->getParent()
                        && "BBs are from diferent functions");
            // if we do not have idomBB, then the idomBB is a root BB
            } else {
                // PostDominatorTree may has special root without BB set
                // or it is the node without immediate post-dominator
                if (!root) {
                    root = new LLVMBBlock();
                    root->setKey(nullptr);
                    F.second->setPostDominatorTreeRoot(root);
                }

                BB->setIPostDom(root);
            }
        }

        // well, if we haven't built the pdtree, this is probably infinite loop
        // that has no pdtree. Until we have anything better, just add sound
        // edges that are not so precise - to predecessors.
        if (!built) {
            for (auto it : our_blocks) {
                LLVMBBlock *BB = it.second;
                for (const LLVMBBlock::BBlockEdge& succ : BB->successors())
                    succ.target->addPostDomFrontier(BB);
            }
        }

        if (addPostDomFrontiers) {
            // assert(root && "BUG: must have root");
            if (root)
                pdfrontiers.compute(root);
        }
    }

    delete pdtree;
}

} // namespace dg
<commit_msg>fix computing post-dominator tree on LLVM 3.9<commit_after>#include <llvm/IR/Function.h>
#include <llvm/Analysis/PostDominators.h>

#include "analysis/BFS.h"
#include "analysis/PostDominanceFrontiers.h"

#include "llvm/LLVMDependenceGraph.h"

namespace dg {

void LLVMDependenceGraph::computePostDominators(bool addPostDomFrontiers)
{
    using namespace llvm;
    // iterate over all functions
    for (auto F : getConstructedFunctions()) {
        analysis::PostDominanceFrontiers<LLVMNode> pdfrontiers;

        // root of post-dominator tree
        LLVMBBlock *root = nullptr;
        Value *val = const_cast<Value *>(F.first);
        Function& f = *cast<Function>(val);
        PostDominatorTree *pdtree;

#if LLVM_VERSION_MINOR < 8
        pdtree = new PostDominatorTree();
        // compute post-dominator tree for this function
        pdtree->runOnFunction(f);
#else
        PostDominatorTreeAnalysis PDT;
        pdtree = new PostDominatorTree(PDT.run(f));
#endif

        // add immediate post-dominator edges
        auto our_blocks = F.second->getBlocks();
        bool built = false;
        for (auto it : our_blocks) {
            LLVMBBlock *BB = it.second;
            BasicBlock *B = cast<BasicBlock>(const_cast<Value *>(it.first));
            DomTreeNode *N = pdtree->getNode(B);
            // when function contains infinite loop, we're screwed
            // and we don't have anything
            // FIXME: just check for the root,
            // don't iterate over all blocks, stupid...
            if (!N)
                continue;

            DomTreeNode *idom = N->getIDom();
            BasicBlock *idomBB = idom ? idom->getBlock() : nullptr;
            built = true;

            if (idomBB) {
                LLVMBBlock *pb = our_blocks[idomBB];
                assert(pb && "Do not have constructed BB");
                BB->setIPostDom(pb);
                assert(cast<BasicBlock>(BB->getKey())->getParent()
                        == cast<BasicBlock>(pb->getKey())->getParent()
                        && "BBs are from diferent functions");
            // if we do not have idomBB, then the idomBB is a root BB
            } else {
                // PostDominatorTree may has special root without BB set
                // or it is the node without immediate post-dominator
                if (!root) {
                    root = new LLVMBBlock();
                    root->setKey(nullptr);
                    F.second->setPostDominatorTreeRoot(root);
                }

                BB->setIPostDom(root);
            }
        }

        // well, if we haven't built the pdtree, this is probably infinite loop
        // that has no pdtree. Until we have anything better, just add sound
        // edges that are not so precise - to predecessors.
        if (!built) {
            for (auto it : our_blocks) {
                LLVMBBlock *BB = it.second;
                for (const LLVMBBlock::BBlockEdge& succ : BB->successors())
                    succ.target->addPostDomFrontier(BB);
            }
        }

        if (addPostDomFrontiers) {
            // assert(root && "BUG: must have root");
            if (root)
                pdfrontiers.compute(root);
        }

        delete pdtree;
    }
}

} // namespace dg

{'fraction_non_alphanumeric': 0.10454115421002838, 'fraction_numerical': 0.0004730368968779565, 'mean_word_length': 1.7747156605424321, 'pattern_counts': {'":': 0, '<': 22, '<?xml version=': 0, '>': 51, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2960706', 'n_tokens_mistral': 1797, 'n_tokens_neox': 1750, 'n_words': 481}