本例子实现的是一个新的 Pass,目的是把 LLVM IR 中端中的一些变量和基本块名使用自增数字明明,即:

%reass.1 → %1
loop.exit: → 2:

然后实现把 SimplifyCFGPass 前后的变化 IR 打印出来。

SimplifyCFGPass

直接展示 patch 了,要修改的内容不多:

diff --git a/llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp b/llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp
index f34f0ff0f75e..c7301c894710 100644
--- a/llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp
+++ b/llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp
@@ -44,10 +44,14 @@
 #include "llvm/Transforms/Scalar/SimplifyCFG.h"
 #include "llvm/Transforms/Utils/Local.h"
 #include "llvm/Transforms/Utils/SimplifyCFGOptions.h"
+#include "llvm/Transforms/Utils/MyExtension/ModifyVariablesName.h"
 #include <utility>
 #include <fstream>
 #include <filesystem>
+#include <chrono>
+#include <ctime>
+

 PreservedAnalyses SimplifyCFGPass::run(Function &F,
                                        FunctionAnalysisManager &AM) {
+  auto Now = std::chrono::system_clock::now();
+  auto Timestamp = std::chrono::duration_cast<std::chrono::nanoseconds>(Now.time_since_epoch()).count();
+  std::string TimestampStr = std::to_string(Timestamp);
+  std::string ShortTimestamp = TimestampStr.substr(TimestampStr.length() - 8);
+  ModifyVariablesPass MVP1("before", ShortTimestamp);
+  MVP1.run(F, AM);
   auto &TTI = AM.getResult<TargetIRAnalysis>(F);
   Options.AC = &AM.getResult<AssumptionAnalysis>(F);
   DominatorTree *DT = nullptr;
@@ -441,6 +451,8 @@ PreservedAnalyses SimplifyCFGPass::run(Function &F,
   PreservedAnalyses PA;
   if (RequireAndPreserveDomTree)
     PA.preserve<DominatorTreeAnalysis>();
+  ModifyVariablesPass MVP2("after", ShortTimestamp);
+  MVP2.run(F, AM);
   return PA;
 }

Pass 文件: ModifyVariablesName. cpp

#include "llvm/Transforms/Utils/MyExtension/ModifyVariablesName.h"
#include "llvm/Passes/PassPlugin.h"
#include "llvm/Passes/PassBuilder.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include <chrono>
#include <ctime>
#include <functional>
#include <iomanip>
#include <sstream>

using namespace llvm;

PreservedAnalyses ModifyVariablesPass::run(Function &F, FunctionAnalysisManager &AM) {
    Module *M = F.getParent();
    std::string ModuleName = (M && M->getName() != "") ? M->getName().str() : "UnknownModule";
    std::hash<std::string> HashFunc;
    std::size_t FuncHash = HashFunc(F.getName().str());
    std::stringstream HashStream;
    HashStream << std::hex << std::setw(6) << std::setfill('0') << (FuncHash & 0xFFFFFF);
    std::string FuncHashHex = HashStream.str();
    std::string OutputDir = "/home/yz/clean/DBGMASTER/IR_DUMP_DIR/";
    std::string OutputFilename = OutputDir + ModuleName + "-" + FuncHashHex + "-" + ShortTimestamp + "-" + Suffix + ".ll";
    std::error_code EC;
    raw_fd_ostream OutFile(OutputFilename, EC, sys::fs::OF_None);
    if (!EC) {
        F.print(OutFile, nullptr);
    } else {
        errs() << "Failed to write IR to file: " << OutputFilename << "\n";
    }
    return PreservedAnalyses::none();
}


extern "C" LLVM_ATTRIBUTE_WEAK PassPluginLibraryInfo llvmGetPassPluginInfo() {
    return {
        LLVM_PLUGIN_API_VERSION, "ModifyVariablesPass", "v0.1",
        [](PassBuilder &PB) {
            PB.registerPipelineParsingCallback(
                [](StringRef Name, FunctionPassManager &FPM,
                   ArrayRef<PassBuilder::PipelineElement>) {
                    if (Name == "mod-var") {
                        FPM.addPass(ModifyVariablesPass("error", "0"));
                        return true;
                    }
                    return false;
                });
        }};
}

Pass 文件: ModifyVariablesPass. h

#ifndef MODIFY_VARIABLES_PASS_H
#define MODIFY_VARIABLES_PASS_H

#include "llvm/IR/PassManager.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Instruction.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm;

class ModifyVariablesPass : public llvm::PassInfoMixin<ModifyVariablesPass> {
    std::string Suffix;
    std::string ShortTimestamp;
public:
    explicit ModifyVariablesPass(std::string A, std::string Timestamp) : Suffix(std::move(A)), ShortTimestamp(std::move(Timestamp)) {}

    PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
};

#endif