从另一个通道中加载 clang 通道

Load clang pass from within another pass

我有两个 LLVM pass,一个需要另一个的输出。所以在 PassB 中我有:

void DiscoPoP::getAnalysisUsage(AnalysisUsage &Info) const{
    Info.addRequired<PassA>();
}

我尝试将下面的代码片段添加到 PassB,但是当 运行 clang -Xclang -load -Xclang LLVMPassB.so 我收到一个错误:undefined symbol: _ZN18PassA2IDE

static RegisterStandardPasses PassLoader(
    PassManagerBuilder::EP_EarlyAsPossible,
    [](const PassManagerBuilder &Builder,
       legacy::PassManagerBase &PM) { PM.add(new PassA()); });

如果我也在 clang 中加载 PassA,它会起作用:clang -Xclang -load -Xclang LLVMPassA.so -Xclang -load -Xclang LLVMPassB.so

但是,如果需要从 PassB 加载它,则必须手动加载它似乎是多余的。有没有办法以编程方式从 PassB 加载 PassA?

I get an error: undefined symbol: _ZN18PassA2IDE

因为 PassA 对 clang 不可见。

If I load PassA in clang as well, it works: clang -Xclang -load -Xclang LLVMPassA.so -Xclang -load -Xclang LLVMPassB.so

符合预期。

But it seems redundant to have to load it manually if it required from the PassB.

只有当 passB 作为标志提供时,clang 才能知道 PassA。除非我们作为标志传递,否则 clang 无法知道 LLVMPassA.so 所在的位置。

Is there a way to load PassA programmatically from PassB?

如果您修改 LLVM 源代码并将两个过程都放在那里,就可以做到这一点。在 LLVM pass 管理器中注册一个 pass 很简单。以https://reviews.llvm.org/D50658(Hot cold splitting pass)为例,具体变化在lib/Transforms/IPO/PassManagerBuilder.cpp,函数createHotColdSplittingPass.