代码实现——添加一个中端Pass(标准化IR与打印前后变化)
本例子实现的是一个新的 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
评论