llvm depth first search from return block

Viewed 599

I'm writing my first llvm pass and would want to do a DFS from the return basic block of a function.

To obtain the return basic block of a function (if there is one), I used the UnifyFunctionExitNodes pass which provides the getReturnBlock() method. Then, I found what I need in llvm/ADT/DepthFirstIterator.h to do a DFS on the inverse CFG from its return's block. I think this is rather a C++ problem than a llvm problem, but I'm completely stuck.

N.B. I'm quite new in C++ and llvm but rather familiar with C.

There is a minimal-not-working example :

#include "llvm/Pass.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Function.h"
#include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/DepthFirstIterator.h"

using namespace llvm;

namespace {
struct Exploration : public llvm::FunctionPass {

    static char ID;

    Exploration() : FunctionPass(ID) {}

    void getAnalysisUsage(llvm::AnalysisUsage &au) const {
        au.setPreservesAll();
        au.addRequiredTransitive<UnifyFunctionExitNodes>();
    }

    virtual bool runOnFunction(llvm::Function &F) override {
        UnifyFunctionExitNodes *UFEN = &getAnalysis<UnifyFunctionExitNodes>();
        BasicBlock *returnBB = UFEN->getReturnBlock();

        if (returnBB != nullptr) {
            errs() << "Return Block : ";
            errs().write_escaped(returnBB->getName()) << '\n';

        } else {
            errs() << "There is no return block\n";
        }

        // first try
        for (BasicBlock *BB : inverse_depth_first(*returnBB)) {
            // visit *BB
        }
        // second try        
        for (auto BB = idf_begin(*returnBB); BB != idf_end(*returnBB); BB++) {
            // visit BB
        }

        return false; // didn't alter the IR
    }

};
}

char Exploration::ID = 0;
// Register the pass with llvm, so that we can call it
static RegisterPass<Exploration> X("Exploration", "Exploration Pass",
                                   false /* Only looks at CFG */,
                                   false /* Analysis Pass */);

The first loop gives me

llvm-pass/Exploration/Exploration.cpp:34:60: error: no matching function for call to ‘inverse_depth_first(llvm::BasicBlock&)’
         for (BasicBlock *BB : inverse_depth_first(*returnBB)) {
                                                            ^
In file included from llvm-pass/Exploration/Exploration.cpp:6:0:
/usr/local/include/llvm/ADT/DepthFirstIterator.h:276:33: note: candidate: template<class T> llvm::iterator_range<llvm::idf_iterator<T> > llvm::inverse_depth_first(const T&)
 iterator_range<idf_iterator<T>> inverse_depth_first(const T& G) {
                                 ^~~~~~~~~~~~~~~~~~~

while the second yields

llvm-pass/Exploration/Exploration.cpp:37:43: error: no matching function for call to ‘idf_begin(llvm::BasicBlock&)’
         for (auto BB = idf_begin(*returnBB); BB != idf_end(*returnBB); BB++) {
                                           ^
In file included from llvm-pass/Exploration/Exploration.cpp:6:0:
/usr/local/include/llvm/ADT/DepthFirstIterator.h:265:17: note: candidate: template<class T> llvm::idf_iterator<T> llvm::idf_begin(const T&)
 idf_iterator<T> idf_begin(const T& G) {
                 ^~~~~~~~~
/usr/local/include/llvm/ADT/DepthFirstIterator.h:265:17: note:   substitution of deduced template arguments resulted in errors seen above
llvm-pass/Exploration/Exploration.cpp:37:69: error: no matching function for call to ‘idf_end(llvm::BasicBlock&)’
         for (auto BB = idf_begin(*returnBB); BB != idf_end(*returnBB); BB++) {
                                                                     ^

I don't know how to pass returnBB in both cases so that inverse_depth_first/idf_begin/idf_end don't produce typing errors.

0 Answers
Related