Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
#include "gtest/gtest.h"
#include "llvm/Analysis/PostDominators.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/NoFolder.h"
#include "llvm/Passes/PassBuilder.h"
static void createCalls(llvm::LLVMContext &context, llvm::Module &module) {
llvm::Type *voidType = llvm::Type::getVoidTy(context);
llvm::GlobalValue::LinkageTypes linkage = llvm::GlobalValue::ExternalLinkage;
llvm::FunctionType *functionType = llvm::FunctionType::get(voidType, false);
llvm::Function *one =
llvm::Function::Create(functionType, linkage, "one", module);
llvm::BasicBlock::Create(context, "entry", one);
llvm::Function *two =
llvm::Function::Create(functionType, linkage, "two", module);
llvm::BasicBlock::Create(context, "entry", two);
llvm::Function *three =
llvm::Function::Create(functionType, linkage, "three", module);
llvm::BasicBlock::Create(context, "entry", three);
llvm::Function *four =
llvm::Function::Create(functionType, linkage, "four", module);
llvm::BasicBlock::Create(context, "entry", four);
llvm::IRBuilder<llvm::NoFolder> builder(&one->getEntryBlock());
builder.CreateCall(two, llvm::None);
builder.SetInsertPoint(&two->getEntryBlock());
builder.CreateCall(three, llvm::None);
builder.SetInsertPoint(&three->getEntryBlock());
builder.CreateCall(one, llvm::None);
}
class MyCGSCCPass : public llvm::PassInfoMixin<MyCGSCCPass> {
public:
llvm::PreservedAnalyses run(llvm::LazyCallGraph::SCC &C,
llvm::CGSCCAnalysisManager &AM,
llvm::LazyCallGraph &CG,
llvm::CGSCCUpdateResult &UR) {
llvm::FunctionAnalysisManager &FAM =
AM.getResult<llvm::FunctionAnalysisManagerCGSCCProxy>(C, CG)
.getManager();
for (llvm::LazyCallGraph::Node &N : C) {
llvm::Function &F = N.getFunction();
llvm::PostDominatorTree &PDT =
FAM.getResult<llvm::PostDominatorTreeAnalysis>(F);
PDT.print(llvm::outs());
}
return llvm::PreservedAnalyses::none();
}
};
TEST(FunctionAnalysisManagerCGSCCProxyTest, example) {
llvm::LLVMContext context;
llvm::Module module("Test module", context);
createCalls(context, module);
llvm::PassBuilder passBuilder;
llvm::LoopAnalysisManager loopAnalysisManager;
llvm::CGSCCAnalysisManager cgsccAnalysisManager;
llvm::FunctionAnalysisManager functionAnalysisManager;
llvm::ModuleAnalysisManager moduleAnalysisManager;
passBuilder.registerLoopAnalyses(loopAnalysisManager);
passBuilder.registerCGSCCAnalyses(cgsccAnalysisManager);
passBuilder.registerFunctionAnalyses(functionAnalysisManager);
passBuilder.registerModuleAnalyses(moduleAnalysisManager);
passBuilder.crossRegisterProxies(loopAnalysisManager, functionAnalysisManager,
cgsccAnalysisManager, moduleAnalysisManager);
llvm::CGSCCPassManager cgsccPassManager;
cgsccPassManager.addPass(MyCGSCCPass());
llvm::ModulePassManager modulePassManager;
modulePassManager.addPass(llvm::createModuleToPostOrderCGSCCPassAdaptor(
std::move(cgsccPassManager)));
// Prints the following:
// =============================--------------------------------
// Inorder PostDominator Tree: DFSNumbers invalid: 0 slow queries.
// [1] <<exit node>> {4294967295,4294967295} [0]
// [2] %entry {4294967295,4294967295} [1]
// Roots: %entry
// =============================--------------------------------
// Inorder PostDominator Tree: DFSNumbers invalid: 0 slow queries.
// [1] <<exit node>> {4294967295,4294967295} [0]
// [2] %entry {4294967295,4294967295} [1]
// Roots: %entry
// =============================--------------------------------
// Inorder PostDominator Tree: DFSNumbers invalid: 0 slow queries.
// [1] <<exit node>> {4294967295,4294967295} [0]
// [2] %entry {4294967295,4294967295} [1]
// Roots: %entry
// =============================--------------------------------
// Inorder PostDominator Tree: DFSNumbers invalid: 0 slow queries.
// [1] <<exit node>> {4294967295,4294967295} [0]
// [2] %entry {4294967295,4294967295} [1]
// Roots: %entry
modulePassManager.run(module, moduleAnalysisManager);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment