我正在编写我的第一个llvm通道,并且希望从函数的返回基本块中进行DFS操作。
要获得某个函数的返回基本块(如果有),我使用了public void CreateChart(List<ChartSubArea> chartList, string variable, string id)
{
dc.Legend legend2 = new dc.Legend();
dc.LegendPosition legendPosition2 = new dc.LegendPosition()
{ val = dc.LegendPositionValues.Right };
dc.Overlay overlay3 = new dc.Overlay() { Val = false };
legend2.Append(legendPosition2);
legend2.Append(overlay3);
dc.TextProperties textPros = new TextProperties();
textPros.Append(new d.BodyProperties());
textPros.Append(new d.ListStyle());
d.Paragraph paragraph = new d.Paragraph();
d.ParagraphProperties paraPros = new d.ParagraphProperties();
d.DefaultParagraphProperties defaultParaPros = new d.DefaultParagraphProperties();
defaultParaPros.Append(new d.LatinFont() { Typeface = "Arial", PitchFamily = 34, CharacterSet = 0 });
defaultParaPros.Append(new d.ComplexScriptFont() { Typeface = "Arial", PitchFamily = 34, CharacterSet = 0 });
paraPros.Append(defaultParaPros);
paragraph.Append(paraPros);
paragraph.Append(new d.EndParagraphRunProperties() { Language = "en-Us" });
textPros.Append(paragraph);
}
传递,它提供了UnifyFunctionExitNodes
方法。然后,我在getReturnBlock()
中找到了从其返回的块开始对逆CFG进行DFS所需的操作。我认为这是一个C ++问题,而不是llvm/ADT/DepthFirstIterator.h
问题,但是我完全陷入了困境。
我是C ++和llvm
的新手,但是对C相当熟悉。
有一个最小的无效示例:
llvm
第一个循环给了我
#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 */);
第二次屈服
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) {
^~~~~~~~~~~~~~~~~~~
在这两种情况下,我都不知道如何传递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++) {
^
,以使returnBB
/ inverse_depth_first
/ idf_begin
不会产生键入错误。