|
|
@@ -0,0 +1,154 @@
|
|
|
+#include "llvm/Pass.h"
|
|
|
+#include "llvm/IR/Function.h"
|
|
|
+#include "llvm/IR/Module.h"
|
|
|
+#include "llvm/IR/BasicBlock.h"
|
|
|
+#include "llvm/IR/Instructions.h"
|
|
|
+#include "llvm/IR/LegacyPassManager.h"
|
|
|
+#include "llvm/Transforms/IPO/PassManagerBuilder.h"
|
|
|
+#include "llvm/Support/raw_ostream.h"
|
|
|
+#include "llvm/Analysis/CFG.h"
|
|
|
+#include "llvm/Analysis/CallGraph.h"
|
|
|
+#include "llvm/IR/IRBuilder.h"
|
|
|
+#include "llvm/Transforms/Utils/ValueMapper.h"
|
|
|
+#include "llvm/Transforms/Utils/Cloning.h"
|
|
|
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
|
|
|
+
|
|
|
+#include "Util/LogSystem.h"
|
|
|
+#include "Util/CallGraphManager.h"
|
|
|
+#include "Util/Utils.h"
|
|
|
+#include "Fusion/SliceAnalyzer.h"
|
|
|
+#include "Fusion/Fusion.h"
|
|
|
+#include "Fusion/CppFusion.h"
|
|
|
+
|
|
|
+#include <vector>
|
|
|
+#include <map>
|
|
|
+#include <set>
|
|
|
+#include <queue>
|
|
|
+#include <random>
|
|
|
+#include <algorithm>
|
|
|
+#include <string>
|
|
|
+
|
|
|
+using namespace llvm;
|
|
|
+
|
|
|
+extern logging::LogSystem logger;
|
|
|
+
|
|
|
+namespace {
|
|
|
+ struct SliceBlocks {
|
|
|
+ std::vector<BasicBlock*> blocks;
|
|
|
+ std::vector<BasicBlock*> backBlocks;
|
|
|
+ };
|
|
|
+
|
|
|
+ // C++项目专用的目标代码识别函数
|
|
|
+ bool isCppTargetCode(const Function &F) {
|
|
|
+ MDNode *MD = F.getMetadata("cpp_project_source");
|
|
|
+ if (!MD) return false;
|
|
|
+
|
|
|
+ if (MDString *MDS = dyn_cast<MDString>(MD->getOperand(0))) {
|
|
|
+ StringRef projectName = MDS->getString();
|
|
|
+ // 对于C++项目,CppTarget是目标代码
|
|
|
+ return projectName == "CppTarget";
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // C++项目专用的掩护代码识别函数
|
|
|
+ bool isCppBunkerCode(const Function &F) {
|
|
|
+ MDNode *MD = F.getMetadata("cpp_project_source");
|
|
|
+ if (!MD) return false;
|
|
|
+
|
|
|
+ if (MDString *MDS = dyn_cast<MDString>(MD->getOperand(0))) {
|
|
|
+ StringRef projectName = MDS->getString();
|
|
|
+ // 对于C++项目,CppBunker是bunker代码
|
|
|
+ return projectName == "CppBunker";
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ struct CppCodeFusionPass : public ModulePass {
|
|
|
+ public:
|
|
|
+ static char ID;
|
|
|
+ CppCodeFusionPass() : ModulePass(ID), callGraph() {}
|
|
|
+
|
|
|
+ bool runOnModule(Module &M) override {
|
|
|
+ auto& logger = logging::LogSystem::getInstance();
|
|
|
+ logger.setGlobalLevel(logging::LogLevel::TRACE);
|
|
|
+ // 配置Log输出权限
|
|
|
+ logger.enableFunction("runOnModule");
|
|
|
+
|
|
|
+ LOG_INFO("runOnModule", "Starting C++ analysis for module: {0}", M.getName().str());
|
|
|
+
|
|
|
+ for (Function &F : M) {
|
|
|
+ if(!F.isDeclaration()){
|
|
|
+ if (isCppTargetCode(F)) {
|
|
|
+ LOG_INFO("runOnModule", "Found C++ target function: {0}", F.getName().str());
|
|
|
+ targetFunctions.insert(F.getName().str());
|
|
|
+ } else if (isCppBunkerCode(F)) {
|
|
|
+ LOG_INFO("runOnModule", "Found C++ bunker function: {0}", F.getName().str());
|
|
|
+ bunkerFunctions.insert(F.getName().str());
|
|
|
+ } else {
|
|
|
+ LOG_INFO("runOnModule", "Skipping function without metadata: {0}", F.getName().str());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ callGraph.buildCallGraph(M, targetFunctions);
|
|
|
+ callGraph.buildCallGraph(M, bunkerFunctions);
|
|
|
+
|
|
|
+ // 遍历模块中的所有函数,对每个函数调用SliceAnalyzer的分析函数
|
|
|
+ for (Function &F : M) {
|
|
|
+ if (!F.isDeclaration()) {
|
|
|
+ std::string fname = F.getName().str();
|
|
|
+ auto criticalPoints = slicefusion::SliceAnalyzer::analyzeFunctionCriticalPoints(F);
|
|
|
+ // 将分析结果存储到callGraph中
|
|
|
+ callGraph[fname].criticalPoints = criticalPoints;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 生成项目调用图
|
|
|
+ callGraph.generateProjectCallGraph();
|
|
|
+ // 遍历模块中的所有函数,对每个函数调用SliceAnalyzer的分析函数
|
|
|
+ for (Function &F : M) {
|
|
|
+ if(!F.isDeclaration()){
|
|
|
+ callGraph.dumpControlFlowGraph(F);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ LOG_INFO("runOnModule", "Creating slices for C++ target functions");
|
|
|
+ for (const auto& targetFuncName : targetFunctions) {
|
|
|
+ LOG_INFO("runOnModule", "C++ targetFuncName: {0}", targetFuncName);
|
|
|
+ if (Function* F = M.getFunction(targetFuncName)) {
|
|
|
+ slicefusion::SliceAnalyzer::createFunctionSlices(*F, callGraph[targetFuncName]);
|
|
|
+ } else {
|
|
|
+ LOG_ERROR("runOnModule", "Could not find function {0} in module", targetFuncName);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ LOG_INFO("runOnModule", "Creating fusion points for C++ bunker functions");
|
|
|
+ for (const auto& bunkerFuncName : bunkerFunctions) {
|
|
|
+ LOG_INFO("runOnModule", "C++ bunkerFuncName: {0}", bunkerFuncName);
|
|
|
+ if (Function* F = M.getFunction(bunkerFuncName)) {
|
|
|
+ slicefusion::SliceAnalyzer::countFusionPoints(*F, callGraph[bunkerFuncName]);
|
|
|
+ } else {
|
|
|
+ LOG_ERROR("runOnModule", "Could not find function {0} in module", bunkerFuncName);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 创建一个C++专用的Fusion对象并保持它的生命周期
|
|
|
+ slicefusion::CppFusion fusion(callGraph);
|
|
|
+ if(fusion.matchFunctionsForFusion(targetFunctions, bunkerFunctions)) {
|
|
|
+ callGraph.generateFusionMatchGraph(targetFunctions, bunkerFunctions, fusion.getFusionPairs());
|
|
|
+ fusion.performCodeFusion(M);
|
|
|
+ }
|
|
|
+
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ private:
|
|
|
+ CallGraphManager callGraph;
|
|
|
+ std::set<std::string> targetFunctions;
|
|
|
+ std::set<std::string> bunkerFunctions;
|
|
|
+ };
|
|
|
+}
|
|
|
+
|
|
|
+char CppCodeFusionPass::ID = 0;
|
|
|
+static RegisterPass<CppCodeFusionPass> X("cpp-codefusion", "C++ Code Fusion Pass");
|