diff --git a/0001-Pin-gcc-client-Bugfix-for-ConstOp.patch b/0001-Pin-gcc-client-Bugfix-for-ConstOp.patch new file mode 100644 index 0000000000000000000000000000000000000000..5a4985e9c7ebf7983117aedf41d3d62524e39d37 --- /dev/null +++ b/0001-Pin-gcc-client-Bugfix-for-ConstOp.patch @@ -0,0 +1,34 @@ +From 3bbf6ad7dd4cd77e98aa31f0c6bd41ba321b8290 Mon Sep 17 00:00:00 2001 +From: benniaobufeijiushiji +Date: Wed, 28 Dec 2022 15:04:28 +0800 +Subject: [PATCH 1/9] [Pin-gcc-client] Bugfix for ConstOp Support both signed + const int and unsigned const int + + +diff --git a/lib/Translate/GimpleToPluginOps.cpp b/lib/Translate/GimpleToPluginOps.cpp +index a5380a7..3a71ffe 100644 +--- a/lib/Translate/GimpleToPluginOps.cpp ++++ b/lib/Translate/GimpleToPluginOps.cpp +@@ -812,9 +812,16 @@ Value GimpleToPluginOps::TreeToValue(uint64_t treeId) + mlir::Value opValue; + switch (TREE_CODE(t)) { + case INTEGER_CST : { +- unsigned HOST_WIDE_INT init = tree_to_uhwi(t); +- // FIXME : AnyAttr! +- mlir::Attribute initAttr = builder.getI64IntegerAttr(init); ++ mlir::Attribute initAttr; ++ if (tree_fits_shwi_p(t)) { ++ signed HOST_WIDE_INT sinit = tree_to_shwi(t); ++ initAttr = builder.getI64IntegerAttr(sinit); ++ } else if (tree_fits_uhwi_p(t)) { ++ unsigned HOST_WIDE_INT uinit = tree_to_uhwi(t); ++ initAttr = builder.getI64IntegerAttr(uinit); ++ } else { ++ abort(); ++ } + opValue = builder.create( + builder.getUnknownLoc(), treeId, IDefineCode::IntCST, + readOnly, initAttr, rPluginType); +-- +2.27.0.windows.1 + diff --git a/0002-Refactoring-Code-refactoring-of-Communication-Subsys.patch b/0002-Refactoring-Code-refactoring-of-Communication-Subsys.patch new file mode 100644 index 0000000000000000000000000000000000000000..ef0750ff6860bd07b098f7766f3e49bd0a4e1170 --- /dev/null +++ b/0002-Refactoring-Code-refactoring-of-Communication-Subsys.patch @@ -0,0 +1,2327 @@ +From e5e442c4b900eff2023232b2000c7be4048c68cc Mon Sep 17 00:00:00 2001 +From: dingguangya +Date: Tue, 7 Feb 2023 19:11:26 +0800 +Subject: [PATCH 2/9] [Refactoring] Code refactoring of Communication Subsystem + [1/3]. Code refactoring of PluginClient. + + +diff --git a/lib/PluginClient/PluginClient.cpp b/lib/PluginClient/PluginClient.cpp +index de15140..18877c2 100644 +--- a/lib/PluginClient/PluginClient.cpp ++++ b/lib/PluginClient/PluginClient.cpp +@@ -19,27 +19,16 @@ + Description: + This file contains the implementation of the PluginClient class.. + */ ++#include ++#include "gccPlugin/gccPlugin.h" + #include "Dialect/PluginDialect.h" + #include "Dialect/PluginTypes.h" + #include "PluginAPI/PluginClientAPI.h" +-#include "IRTrans/IRTransPlugin.h" +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include + + namespace PinClient { + using namespace mlir::Plugin; + using namespace mlir; +-using std::ios; +-static std::shared_ptr g_plugin = nullptr; +-const char *g_portFilePath = "/tmp/grpc_ports_pin_client.txt"; +-static std::shared_ptr g_grpcChannel = nullptr; ++static PluginClient g_plugin; + + std::map g_injectPoint { + {HANDLE_PARSE_TYPE, PLUGIN_FINISH_TYPE}, +@@ -56,15 +45,9 @@ std::map g_injectPoint { + {HANDLE_MANAGER_SETUP, PLUGIN_PASS_MANAGER_SETUP}, + }; + +-std::shared_ptr PluginClient::GetInstance(void) +-{ +- return g_plugin; +-} +- +-static uintptr_t GetID(Json::Value node) ++PluginClient *PluginClient::GetInstance() + { +- string id = node.asString(); +- return atol(id.c_str()); ++ return &g_plugin; + } + + int PluginClient::GetEvent(InjectPoint inject, plugin_event *event) +@@ -77,1138 +60,861 @@ int PluginClient::GetEvent(InjectPoint inject, plugin_event *event) + return -1; + } + +-Json::Value PluginClient::TypeJsonSerialize (PluginIR::PluginTypeBase& type) ++void PluginClient::GetGccData(const string& funcName, const string& param, string& key, string& result) + { +- Json::Value root; +- Json::Value operationObj; +- Json::Value item; +- +- uint64_t ReTypeId; +- uint64_t ReTypeWidth; +- +- ReTypeId = static_cast(type.getPluginTypeID()); +- item["id"] = std::to_string(ReTypeId); +- +- if (auto elemTy = type.dyn_cast()) { +- auto baseTy = elemTy.getElementType().dyn_cast(); +- item["elementType"] = TypeJsonSerialize(baseTy); +- if (elemTy.isReadOnlyElem()) { +- item["elemConst"] = "1"; +- }else { +- item["elemConst"] = "0"; +- } ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI pluginAPI(context); ++ uint64_t gccDataAddr = (uint64_t)atol(param.c_str()); ++ if (gccDataAddr == 0) { ++ LOGE("%s gcc_data address is NULL!\n", __func__); ++ return; + } +- +- if (type.getPluginIntOrFloatBitWidth() != 0) { +- ReTypeWidth = type.getPluginIntOrFloatBitWidth(); +- item["width"] = std::to_string(ReTypeWidth); ++ if (funcName == "GetDeclSourceFile") { ++ string sourceFile = pluginAPI.GetDeclSourceFile(gccDataAddr); ++ json.StringSerialize(sourceFile, result); ++ key = "StringResult"; ++ } else if (funcName == "GetDeclSourceLine") { ++ int line = pluginAPI.GetDeclSourceLine(gccDataAddr); ++ json.IntegerSerialize(line, result); ++ key = "IntegerResult"; ++ } else if (funcName == "GetDeclSourceColumn") { ++ int column = pluginAPI.GetDeclSourceColumn(gccDataAddr); ++ json.IntegerSerialize(column, result); ++ key = "IntegerResult"; ++ } else if (funcName == "VariableName") { ++ string variableName = pluginAPI.VariableName(gccDataAddr); ++ json.StringSerialize(variableName, result); ++ key = "StringResult"; ++ } else if (funcName == "FuncName") { ++ string funcName = pluginAPI.FuncName(gccDataAddr); ++ json.StringSerialize(funcName, result); ++ key = "StringResult"; ++ } else { ++ LOGW("function: %s not found!\n", funcName.c_str()); + } ++} + +- if (type.isSignedPluginInteger()) { +- item["signed"] = "1"; +- } ++void GetAllFuncResult(PluginClient *client, Json::Value& root, string& result) ++{ ++ // Load our Dialect in this MLIR Context. ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ vector allFuncOps = clientAPI.GetAllFunc(); ++ PluginJson json = client->GetJson(); ++ json.FunctionOpJsonSerialize(allFuncOps, result); ++ client->ReceiveSendMsg("FuncOpResult", result); ++} + +- if (type.isUnsignedPluginInteger()) { +- item["signed"] = "0"; +- } ++void GetLocalDeclsResult(PluginClient *client, Json::Value& root, string& result) ++{ ++ /// Json格式 ++ /// { ++ /// "funcId":"xxxx" ++ /// } ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ std::string funcIdKey = "funcId"; ++ uint64_t funcID = atol(root[funcIdKey].asString().c_str()); ++ vector decls = clientAPI.GetDecls(funcID); ++ PluginJson json = client->GetJson(); ++ json.LocalDeclsJsonSerialize(decls, result); ++ client->ReceiveSendMsg("LocalDeclOpResult", result); ++} + +- root["type"] = item; +- return root; ++void GetLoopsFromFuncResult(PluginClient *client, Json::Value& root, string& result) ++{ ++ /// Json格式 ++ /// { ++ /// "funcId":"xxxx" ++ /// } ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ std::string funcIdKey = "funcId"; ++ uint64_t funcID = atol(root[funcIdKey].asString().c_str()); ++ vector irLoops = clientAPI.GetLoopsFromFunc(funcID); ++ PluginJson json = client->GetJson(); ++ json.LoopOpsJsonSerialize(irLoops, result); ++ client->ReceiveSendMsg("LoopOpsResult", result); + } + +-PluginIR::PluginTypeBase PluginClient::TypeJsonDeSerialize(const string& data, mlir::MLIRContext &context) ++void GetLoopByIdResult(PluginClient *client, Json::Value& root, string& result) + { +- Json::Value root; +- Json::Reader reader; +- Json::Value node; +- reader.parse(data, root); ++ /// Json格式 ++ /// { ++ /// "loopId":"xxxx" ++ /// } ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ std::string loopIdKey = "loopId"; ++ uint64_t loopId = atol(root[loopIdKey].asString().c_str()); ++ LoopOp irLoop = clientAPI.GetLoopById(loopId); ++ PluginJson json = client->GetJson(); ++ json.LoopOpJsonSerialize(irLoop, result); ++ client->ReceiveSendMsg("LoopOpResult", result); ++} + +- PluginIR::PluginTypeBase baseType; ++void IsBlockInsideResult(PluginClient *client, Json::Value& root, string& result) ++{ ++ /// Json格式 ++ /// { ++ /// "loopId":"xxxx", ++ /// "blockId":"xxxx" ++ /// } ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ std::string loopIdKey = "loopId"; ++ std::string blockIdKey = "blockId"; ++ uint64_t loopId = atol(root[loopIdKey].asString().c_str()); ++ uint64_t blockId = atol(root[blockIdKey].asString().c_str()); ++ bool res = clientAPI.IsBlockInside(loopId, blockId); ++ client->ReceiveSendMsg("BoolResult", std::to_string((uint64_t)res)); ++} + +- Json::Value type = root["type"]; +- uint64_t id = GetID(type["id"]); +- PluginIR::PluginTypeID PluginTypeId = static_cast(id); ++void AllocateNewLoopResult(PluginClient *client, Json::Value& root, string& result) ++{ ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ uint64_t newLoopId = clientAPI.AllocateNewLoop(); ++ LoopOp newLoop = clientAPI.GetLoopById(newLoopId); ++ PluginJson json = client->GetJson(); ++ json.LoopOpJsonSerialize(newLoop, result); ++ client->ReceiveSendMsg("LoopOpResult", result); ++} + +- if (type["signed"] && (id >= static_cast(PluginIR::UIntegerTy1ID) +- && id <= static_cast(PluginIR::IntegerTy64ID))) { +- string s = type["signed"].asString(); +- uint64_t width = GetID(type["width"]); +- if (s == "1") { +- baseType = PluginIR::PluginIntegerType::get(&context, width, PluginIR::PluginIntegerType::Signed); +- } +- else { +- baseType = PluginIR::PluginIntegerType::get(&context, width, PluginIR::PluginIntegerType::Unsigned); +- } +- } +- else if (type["width"] && (id == static_cast(PluginIR::FloatTyID) +- || id == static_cast(PluginIR::DoubleTyID)) ) { +- uint64_t width = GetID(type["width"]); +- baseType = PluginIR::PluginFloatType::get(&context, width); +- }else if (id == static_cast(PluginIR::PointerTyID)) { +- mlir::Type elemTy = TypeJsonDeSerialize(type["elementType"].toStyledString(), context); +- baseType = PluginIR::PluginPointerType::get(&context, elemTy, type["elemConst"].asString() == "1" ? 1 : 0); +- }else { +- if (PluginTypeId == PluginIR::VoidTyID) +- baseType = PluginIR::PluginVoidType::get(&context); +- if (PluginTypeId == PluginIR::BooleanTyID) +- baseType = PluginIR::PluginBooleanType::get(&context); +- if (PluginTypeId == PluginIR::UndefTyID) +- baseType = PluginIR::PluginUndefType::get(&context); +- } ++void RedirectFallthroughTargetResult(PluginClient *client, Json::Value& root, string& result) ++{ ++ /// Json格式 ++ /// { ++ /// "src":"xxxx", ++ /// "dest":"xxxx", ++ /// } ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ std::string srcKey = "src"; ++ uint64_t src = atol(root[srcKey].asString().c_str()); ++ std::string destKey = "dest"; ++ uint64_t dest = atol(root[destKey].asString().c_str()); ++ clientAPI.RedirectFallthroughTarget(src, dest); ++ PluginJson json = client->GetJson(); ++ json.NopJsonSerialize(result); ++ client->ReceiveSendMsg("VoidResult", result); ++} + +- return baseType; ++void DeleteLoopResult(PluginClient *client, Json::Value& root, string& result) ++{ ++ /// Json格式 ++ /// { ++ /// "loopId":"xxxx", ++ /// } ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ std::string loopIdKey = "loopId"; ++ uint64_t loopId = atol(root[loopIdKey].asString().c_str()); ++ clientAPI.DeleteLoop(loopId); ++ PluginJson json = client->GetJson(); ++ json.NopJsonSerialize(result); ++ client->ReceiveSendMsg("VoidResult", result); + } + +-void PluginClient::FunctionOpJsonSerialize(vector& data, string& out) ++void AddBlockToLoopResult(PluginClient *client, Json::Value& root, string& result) + { +- Json::Value root; +- Json::Value operationObj; +- Json::Value item; ++ /// Json格式 ++ /// { ++ /// "loopId":"xxxx", ++ /// "blockId":"xxxx", ++ /// } ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ std::string loopIdKey = "loopId"; ++ uint64_t loopId = atol(root[loopIdKey].asString().c_str()); ++ std::string blockIdKey = "blockId"; ++ uint64_t blockId = atol(root[blockIdKey].asString().c_str()); ++ clientAPI.AddBlockToLoop(blockId, loopId); ++ PluginJson json = client->GetJson(); ++ json.NopJsonSerialize(result); ++ client->ReceiveSendMsg("VoidResult", result); ++} + +- int i = 0; +- string operation; +- +- for (auto& d: data) { +- item["id"] = std::to_string(d.idAttr().getInt()); +- // item["opCode"] = OP_FUNCTION; +- if (d.declaredInlineAttr().getValue()) +- item["attributes"]["declaredInline"] = "1"; +- else +- item["attributes"]["declaredInline"] = "0"; +- item["attributes"]["funcName"] = d.funcNameAttr().getValue().str().c_str(); +- auto ®ion = d.getRegion(); +- size_t bbIdx = 0; +- for (auto &b : region) { +- string blockStr = "block" + std::to_string(bbIdx++); +- uint64_t bbAddress = 0; +- size_t opIdx = 0; +- for (auto &inst : b) { +- if (isa(inst)) continue; +- else if (isa(inst)) continue; +- else if (isa(inst)) continue; +- else if (isa(inst)) continue; +- string opStr = "Operation" + std::to_string(opIdx++); +- item["region"][blockStr]["ops"][opStr] = OperationJsonSerialize(&inst, bbAddress); +- } +- assert(bbAddress != 0); +- item["region"][blockStr]["address"] = std::to_string(bbAddress); +- } +- operation = "FunctionOp" + std::to_string(i++); +- root[operation] = item; +- item.clear(); +- } +- out = root.toStyledString(); ++void AddLoopResult(PluginClient *client, Json::Value& root, string& result) ++{ ++ /// Json格式 ++ /// { ++ /// "loopId":"xxxx", ++ /// "outerId":"xxxx" ++ /// "funcId":"xxxx" ++ /// } ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ std::string loopIdKey = "loopId"; ++ std::string outerIdKey = "outerId"; ++ std::string funcIdKey = "funcId"; ++ uint64_t loopID = atol(root[loopIdKey].asString().c_str()); ++ uint64_t outerID = atol(root[outerIdKey].asString().c_str()); ++ uint64_t funcID = atol(root[funcIdKey].asString().c_str()); ++ clientAPI.AddLoop(loopID, outerID, funcID); ++ LoopOp irLoop = clientAPI.GetLoopById(loopID); ++ PluginJson json = client->GetJson(); ++ json.LoopOpJsonSerialize(irLoop, result); ++ client->ReceiveSendMsg("LoopOpResult", result); + } + +-Json::Value PluginClient::OperationJsonSerialize(mlir::Operation *operation, +- uint64_t &bbId) ++void GetBlocksInLoopResult(PluginClient *client, Json::Value& root, string& result) + { +- Json::Value root; +- if (AssignOp op = llvm::dyn_cast(operation)) { +- root = AssignOpJsonSerialize(op); +- } else if (CallOp op = llvm::dyn_cast(operation)) { +- root = CallOpJsonSerialize(op); +- } else if (CondOp op = llvm::dyn_cast(operation)) { +- root = CondOpJsonSerialize(op, bbId); +- } else if (PhiOp op = llvm::dyn_cast(operation)) { +- root = PhiOpJsonSerialize(op); +- } else if (FallThroughOp op = llvm::dyn_cast(operation)) { +- root = FallThroughOpJsonSerialize(op, bbId); +- } else if (RetOp op = llvm::dyn_cast(operation)) { +- root = RetOpJsonSerialize(op, bbId); +- } else if (BaseOp op = llvm::dyn_cast(operation)) { +- root = BaseOpJsonSerialize(op); +- } +- root["OperationName"] = operation->getName().getStringRef().str(); +- return root; ++ /// Json格式 ++ /// { ++ /// "loopId":"xxxx", ++ /// } ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ std::string loopIdKey = "loopId"; ++ uint64_t loopId = atol(root[loopIdKey].asString().c_str()); ++ vector blocks = clientAPI.GetBlocksInLoop(loopId); ++ PluginJson json = client->GetJson(); ++ json.BlocksJsonSerialize(blocks, result); ++ client->ReceiveSendMsg("IdsResult", result); + } + +-Json::Value PluginClient::BaseOpJsonSerialize(BaseOp data) ++void GetHeaderResult(PluginClient *client, Json::Value& root, string& result) + { +- Json::Value root; +- root["id"] = std::to_string(data.idAttr().getInt()); +- root["opCode"] = data.opCodeAttr().getValue().str().c_str(); +- return root; ++ /// Json格式 ++ /// { ++ /// "loopId":"xxxx", ++ /// } ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ std::string loopIdKey = "loopId"; ++ uint64_t loopId = atol(root[loopIdKey].asString().c_str()); ++ uint64_t blockId = clientAPI.GetHeader(loopId); ++ client->ReceiveSendMsg("IdResult", std::to_string(blockId)); + } + +-Json::Value PluginClient::RetOpJsonSerialize(RetOp data, uint64_t &bbId) ++void GetLatchResult(PluginClient *client, Json::Value& root, string& result) + { +- Json::Value root; +- bbId = data.addressAttr().getInt(); +- root["address"] = std::to_string(bbId); +- return root; ++ /// Json格式 ++ /// { ++ /// "loopId":"xxxx", ++ /// } ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ std::string loopIdKey = "loopId"; ++ uint64_t loopId = atol(root[loopIdKey].asString().c_str()); ++ uint64_t blockId = clientAPI.GetLatch(loopId); ++ client->ReceiveSendMsg("IdResult", std::to_string(blockId)); + } + +-Json::Value PluginClient::FallThroughOpJsonSerialize(FallThroughOp data, +- uint64_t &bbId) ++void SetHeaderResult(PluginClient *client, Json::Value& root, string& result) + { +- Json::Value root; +- bbId = data.addressAttr().getInt(); +- root["address"] = std::to_string(bbId); +- root["destaddr"] = std::to_string(data.destaddrAttr().getInt()); +- return root; ++ /// Json格式 ++ /// { ++ /// "loopId":"xxxx", ++ /// "blockId":"xxxx", ++ /// } ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ std::string loopIdKey = "loopId"; ++ uint64_t loopId = atol(root[loopIdKey].asString().c_str()); ++ std::string blockIdKey = "blockId"; ++ uint64_t blockId = atol(root[blockIdKey].asString().c_str()); ++ clientAPI.SetHeader(loopId, blockId); ++ PluginJson json = client->GetJson(); ++ json.NopJsonSerialize(result); ++ client->ReceiveSendMsg("VoidResult", result); + } + +-void PluginClient::LocalDeclsJsonSerialize(vector& decls, string& out) ++void SetLatchResult(PluginClient *client, Json::Value& root, string& result) + { +- Json::Value root; +- Json::Value operationObj; +- Json::Value item; +- int i = 0; +- string operation; +- +- for (auto& decl: decls) { +- item["id"] = std::to_string(decl.idAttr().getInt()); +- item["attributes"]["symName"] = decl.symNameAttr().getValue().str().c_str(); +- item["attributes"]["typeID"] = decl.typeIDAttr().getInt(); +- item["attributes"]["typeWidth"] = decl.typeWidthAttr().getInt(); +- operation = "localDecl" + std::to_string(i++); +- root[operation] = item; +- item.clear(); +- } +- out = root.toStyledString(); ++ /// Json格式 ++ /// { ++ /// "loopId":"xxxx", ++ /// "blockId":"xxxx", ++ /// } ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ std::string loopIdKey = "loopId"; ++ uint64_t loopId = atol(root[loopIdKey].asString().c_str()); ++ std::string blockIdKey = "blockId"; ++ uint64_t blockId = atol(root[blockIdKey].asString().c_str()); ++ clientAPI.SetLatch(loopId, blockId); ++ PluginJson json = client->GetJson(); ++ json.NopJsonSerialize(result); ++ client->ReceiveSendMsg("VoidResult", result); + } + +-void PluginClient::LoopOpsJsonSerialize(vector& loops, string& out) ++void GetLoopExitsResult(PluginClient *client, Json::Value& root, string& result) + { +- Json::Value root; +- Json::Value operationObj; +- Json::Value item; +- int i = 0; +- string operation; +- +- for (auto&loop: loops) { +- item["id"] = std::to_string(loop.idAttr().getInt()); +- item["index"] = std::to_string(loop.indexAttr().getInt()); +- item["attributes"]["innerLoopId"] = std::to_string(loop.innerLoopIdAttr().getInt()); +- item["attributes"]["outerLoopId"] = std::to_string(loop.outerLoopIdAttr().getInt()); +- item["attributes"]["numBlock"] = std::to_string(loop.numBlockAttr().getInt()); +- operation = "loopOp" + std::to_string(i++); +- root[operation] = item; +- item.clear(); +- } +- out = root.toStyledString(); ++ /// Json格式 ++ /// { ++ /// "loopId":"xxxx", ++ /// } ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ std::string loopIdKey = "loopId"; ++ uint64_t loopId = atol(root[loopIdKey].asString().c_str()); ++ vector > edges = clientAPI.GetLoopExits(loopId); ++ PluginJson json = client->GetJson(); ++ json.EdgesJsonSerialize(edges, result); ++ client->ReceiveSendMsg("EdgesResult", result); + } + +-void PluginClient::LoopOpJsonSerialize(mlir::Plugin::LoopOp& loop, string& out) ++void GetLoopSingleExitResult(PluginClient *client, Json::Value& root, string& result) + { +- Json::Value root; +- root["id"] = std::to_string(loop.idAttr().getInt()); +- root["index"] = std::to_string(loop.indexAttr().getInt()); +- root["attributes"]["innerLoopId"] = std::to_string(loop.innerLoopIdAttr().getInt()); +- root["attributes"]["outerLoopId"] = std::to_string(loop.outerLoopIdAttr().getInt()); +- root["attributes"]["numBlock"] = std::to_string(loop.numBlockAttr().getInt()); +- out = root.toStyledString(); ++ /// Json格式 ++ /// { ++ /// "loopId":"xxxx", ++ /// } ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ std::string loopIdKey = "loopId"; ++ uint64_t loopId = atol(root[loopIdKey].asString().c_str()); ++ std::pair edge = clientAPI.GetLoopSingleExit(loopId); ++ PluginJson json = client->GetJson(); ++ json.EdgeJsonSerialize(edge, result); ++ client->ReceiveSendMsg("EdgeResult", result); + } + +-void PluginClient::BlocksJsonSerialize(vector& blocks, string& out) ++void GetBlockLoopFatherResult(PluginClient *client, Json::Value& root, string& result) + { +- Json::Value root; +- Json::Value item; +- int i = 0; +- string index; ++ /// Json格式 ++ /// { ++ /// "blockId":"xxxx", ++ /// } ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ std::string blockIdKey = "blockId"; ++ uint64_t blockId = atol(root[blockIdKey].asString().c_str()); ++ LoopOp loopFather = clientAPI.GetBlockLoopFather(blockId); ++ PluginJson json = client->GetJson(); ++ json.LoopOpJsonSerialize(loopFather, result); ++ client->ReceiveSendMsg("LoopOpResult", result); ++} + +- for(auto& block : blocks) { +- item["id"] = std::to_string(block); +- index = "block" + std::to_string(i++); +- root[index] = item; +- item.clear(); +- } +- out = root.toStyledString(); ++void CreateBlockResult(PluginClient *client, Json::Value& root, string& result) ++{ ++ /// Json格式 ++ /// { ++ /// "bbaddr":"xxxx", ++ /// "funcaddr":"xxxx" ++ /// } ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ uint64_t blockAddr = atol(root["bbaddr"].asString().c_str()); ++ uint64_t funcAddr = atol(root["funcaddr"].asString().c_str()); ++ uint64_t newBBAddr = clientAPI.CreateBlock(funcAddr, blockAddr); ++ client->ReceiveSendMsg("IdResult", std::to_string(newBBAddr)); + } + +-void PluginClient::EdgesJsonSerialize(vector >& edges, string& out) ++void DeleteBlockResult(PluginClient *client, Json::Value& root, string& result) + { +- Json::Value root; +- Json::Value item; +- int i = 0; +- string index; +- +- for(auto& edge : edges) { +- item["src"] = std::to_string(edge.first); +- item["dest"] = std::to_string(edge.second); +- index = "edge" + std::to_string(i++); +- root[index] = item; +- item.clear(); +- } +- out = root.toStyledString(); ++ /// Json格式 ++ /// { ++ /// "bbaddr":"xxxx", ++ /// } ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ std::string funcKey = "funcaddr"; ++ std::string BlockIdKey = "bbaddr"; ++ uint64_t bbaddr = atol(root[BlockIdKey].asString().c_str()); ++ uint64_t funcaddr = atol(root[funcKey].asString().c_str()); ++ clientAPI.DeleteBlock(funcaddr, bbaddr); ++ PluginJson json = client->GetJson(); ++ json.NopJsonSerialize(result); ++ client->ReceiveSendMsg("VoidResult", result); + } + +-void PluginClient::EdgeJsonSerialize(pair& edge, string& out) ++void SetImmediateDominatorResult(PluginClient *client, Json::Value& root, string& result) + { +- Json::Value root; +- root["src"] = std::to_string(edge.first); +- root["dest"] = std::to_string(edge.second); +- out = root.toStyledString(); ++ /// Json格式 ++ /// { ++ /// "dir":"xxxx", ++ /// "bbaddr":"xxxx", ++ /// "domiaddr":"xxxx", ++ /// } ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ std::string dirIdKey = "dir"; ++ uint64_t dir = atol(root[dirIdKey].asString().c_str()); ++ std::string BlockIdKey = "bbaddr"; ++ uint64_t bbaddr = atol(root[BlockIdKey].asString().c_str()); ++ std::string domiIdKey = "domiaddr"; ++ uint64_t domiaddr = atol(root[domiIdKey].asString().c_str()); ++ clientAPI.SetImmediateDominator(dir, bbaddr, domiaddr); ++ PluginJson json = client->GetJson(); ++ json.NopJsonSerialize(result); ++ client->ReceiveSendMsg("VoidResult", result); + } + +-// void类型的Json序列化 +-void PluginClient::NopJsonSerialize(string& out) ++void GetImmediateDominatorResult(PluginClient *client, Json::Value& root, string& result) + { +- Json::Value root; +- out = root.toStyledString(); ++ /// Json格式 ++ /// { ++ /// "dir":"xxxx", ++ /// "bbaddr":"xxxx", ++ /// } ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ std::string dirIdKey = "dir"; ++ uint64_t dir = atol(root[dirIdKey].asString().c_str()); ++ std::string BlockIdKey = "bbaddr"; ++ uint64_t bbaddr = atol(root[BlockIdKey].asString().c_str()); ++ uint64_t ret = clientAPI.GetImmediateDominator(dir, bbaddr); ++ client->ReceiveSendMsg("IdResult", std::to_string(ret)); + } + +-void PluginClient::GetPhiOpsJsonSerialize(vector phiOps, string & out) ++void RecomputeDominatorResult(PluginClient *client, Json::Value& root, string& result) + { +- Json::Value root; +- Json::Value item; +- int i = 0; +- string operation; +- uint64_t placeholder = 0; +- for (auto phi : phiOps) { +- item = OperationJsonSerialize(phi.getOperation(), placeholder); +- operation = "operation" + std::to_string(i++); +- root[operation] = item; +- item.clear(); +- } +- out = root.toStyledString(); ++ /// Json格式 ++ /// { ++ /// "dir":"xxxx", ++ /// "bbaddr":"xxxx", ++ /// } ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ std::string dirIdKey = "dir"; ++ uint64_t dir = atol(root[dirIdKey].asString().c_str()); ++ std::string BlockIdKey = "bbaddr"; ++ uint64_t bbaddr = atol(root[BlockIdKey].asString().c_str()); ++ uint64_t ret = clientAPI.RecomputeDominator(dir, bbaddr); ++ client->ReceiveSendMsg("IdResult", std::to_string(ret)); + } + +-Json::Value PluginClient::CallOpJsonSerialize(CallOp& data) ++void GetPhiOpResult(PluginClient *client, Json::Value& root, string& result) + { +- Json::Value item; +- item["id"] = std::to_string(data.idAttr().getInt()); +- item["callee"] = data.callee().str(); +- item["OperationName"] = data.getOperation()->getName().getStringRef().str(); +- size_t opIdx = 0; +- for (mlir::Value v : data.getArgOperands()) { +- string input = "input" + std::to_string(opIdx++); +- item["operands"][input] = ValueJsonSerialize(v); +- } +- // auto retTy = data.getResultType().dyn_cast(); +- // item["retType"] = TypeJsonSerialize(retTy); +- return item; ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ uint64_t id = atol(root[std::to_string(0)].asString().c_str()); ++ PhiOp op = clientAPI.GetPhiOp(id); ++ PluginJson json = client->GetJson(); ++ Json::Value phiOpResult = json.PhiOpJsonSerialize(op); ++ client->ReceiveSendMsg("OpsResult", phiOpResult.toStyledString()); + } + +-Json::Value PluginClient::CondOpJsonSerialize(CondOp& data, uint64_t &bbId) ++void GetCallOpResult(PluginClient *client, Json::Value& root, string& result) + { +- Json::Value item; +- item["id"] = std::to_string(data.idAttr().getInt()); +- item["condCode"] = std::to_string(data.condCodeAttr().getInt()); +- item["lhs"] = ValueJsonSerialize(data.GetLHS()); +- item["rhs"] = ValueJsonSerialize(data.GetRHS()); +- bbId = data.addressAttr().getInt(); +- item["address"] = std::to_string(bbId); +- item["tbaddr"] = std::to_string(data.tbaddrAttr().getInt()); +- item["fbaddr"] = std::to_string(data.fbaddrAttr().getInt()); +- return item; ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ uint64_t id = atol(root[std::to_string(0)].asString().c_str()); ++ CallOp op = clientAPI.GetCallOp(id); ++ PluginJson json = client->GetJson(); ++ Json::Value opResult = json.CallOpJsonSerialize(op); ++ client->ReceiveSendMsg("OpsResult", opResult.toStyledString()); + } + +-Json::Value PluginClient::PhiOpJsonSerialize(PhiOp& data) ++void SetLhsInCallOpResult(PluginClient *client, Json::Value& root, string& result) + { +- Json::Value item; +- item["id"] = std::to_string(data.idAttr().getInt()); +- item["capacity"] = std::to_string(data.capacityAttr().getInt()); +- item["nArgs"] = std::to_string(data.nArgsAttr().getInt()); +- item["OperationName"] = data.getOperation()->getName().getStringRef().str(); +- size_t opIdx = 0; +- for (mlir::Value v : data.operands()) { +- string input = "input" + std::to_string(opIdx++); +- item["operands"][input] = ValueJsonSerialize(v); +- } +- // auto retTy = data.getResultType().dyn_cast(); +- // item["retType"] = TypeJsonSerialize(retTy); +- return item; ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ uint64_t callId = atol(root["callId"].asString().c_str()); ++ uint64_t lhsId = atol(root["lhsId"].asString().c_str()); ++ bool ret = clientAPI.SetLhsInCallOp(callId, lhsId); ++ client->ReceiveSendMsg("BoolResult", std::to_string(ret)); + } + +-Json::Value PluginClient::SSAOpJsonSerialize(SSAOp& data) ++void AddArgInPhiOpResult(PluginClient *client, Json::Value& root, string& result) + { +- Json::Value item; +- item["id"] = std::to_string(data.idAttr().getInt()); +- item["defCode"] = std::to_string(data.defCodeAttr().getInt()); +- item["readOnly"] = std::to_string(data.readOnlyAttr().getValue()); +- item["nameVarId"] = std::to_string(data.nameVarIdAttr().getInt()); +- item["ssaParmDecl"] = std::to_string(data.ssaParmDeclAttr().getInt()); +- item["version"] = std::to_string(data.versionAttr().getInt()); +- item["definingId"] = std::to_string(data.definingIdAttr().getInt()); +- auto retTy = data.getResultType().dyn_cast(); +- item["retType"] = TypeJsonSerialize(retTy); +- return item; ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ uint64_t phiId = atol(root["phiId"].asString().c_str()); ++ uint64_t argId = atol(root["argId"].asString().c_str()); ++ uint64_t predId = atol(root["predId"].asString().c_str()); ++ uint64_t succId = atol(root["succId"].asString().c_str()); ++ uint32_t ret = clientAPI.AddArgInPhiOp(phiId, argId, predId, succId); ++ client->ReceiveSendMsg("IdResult", std::to_string(ret)); + } + +-Json::Value PluginClient::AssignOpJsonSerialize(AssignOp& data) ++void CreateCallOpResult(PluginClient *client, Json::Value& root, string& result) + { +- Json::Value item; +- item["id"] = std::to_string(data.idAttr().getInt()); +- item["exprCode"] = std::to_string(data.exprCodeAttr().getInt()); +- item["OperationName"] = data.getOperation()->getName().getStringRef().str(); +- size_t opIdx = 0; +- for (mlir::Value v : data.operands()) { +- string input = "input" + std::to_string(opIdx++); +- item["operands"][input] = ValueJsonSerialize(v); ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ uint64_t blockId = atol(root["blockId"].asString().c_str()); ++ uint64_t funcId = atol(root["funcId"].asString().c_str()); ++ vector argIds; ++ Json::Value argIdsJson = root["argIds"]; ++ Json::Value::Members member = argIdsJson.getMemberNames(); ++ for (Json::Value::Members::iterator opIter = member.begin(); opIter != member.end(); opIter++) { ++ string key = *opIter; ++ uint64_t id = atol(argIdsJson[key.c_str()].asString().c_str()); ++ argIds.push_back(id); + } +- // auto retTy = data.getResultType().dyn_cast(); +- // item["retType"] = TypeJsonSerialize(retTy); +- return item; ++ uint64_t ret = clientAPI.CreateCallOp(blockId, funcId, argIds); ++ client->ReceiveSendMsg("IdResult", std::to_string(ret)); + } + +-Json::Value PluginClient::ValueJsonSerialize(mlir::Value data) ++void CreateAssignOpResult(PluginClient *client, Json::Value& root, string& result) + { +- Json::Value root; +- if (ConstOp cOp = data.getDefiningOp()) { +- auto retTy = data.getType().dyn_cast(); +- root["retType"] = TypeJsonSerialize(retTy); +- root["id"] = std::to_string(cOp.idAttr().getInt()); +- root["defCode"] = std::to_string( +- static_cast(IDefineCode::IntCST)); +- root["value"] = std::to_string( +- cOp.initAttr().cast().getInt()); +- } else if (MemOp mOp = data.getDefiningOp()) { +- root = MemOpJsonSerialize(mOp); +- } else if (SSAOp sOp = data.getDefiningOp()) { +- root = SSAOpJsonSerialize(sOp); +- } else if (PlaceholderOp phOp = data.getDefiningOp()) { +- root["id"] = std::to_string(phOp.idAttr().getInt()); +- root["defCode"] = std::to_string(phOp.defCodeAttr().getInt()); +- auto retTy = phOp.getResultType().dyn_cast(); +- root["retType"] = TypeJsonSerialize(retTy); +- } else { +- LOGE("ERROR: Can't Serialize!"); ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ uint64_t blockId = atol(root["blockId"].asString().c_str()); ++ int condCode = atol(root["exprCode"].asString().c_str()); ++ vector argIds; ++ Json::Value argIdsJson = root["argIds"]; ++ Json::Value::Members member = argIdsJson.getMemberNames(); ++ for (Json::Value::Members::iterator opIter = member.begin(); opIter != member.end(); opIter++) { ++ string key = *opIter; ++ uint64_t id = atol(argIdsJson[key.c_str()].asString().c_str()); ++ argIds.push_back(id); + } +- return root; ++ uint64_t ret = clientAPI.CreateAssignOp(blockId, IExprCode(condCode), argIds); ++ client->ReceiveSendMsg("IdResult", std::to_string(ret)); + } + +-Json::Value PluginClient::MemOpJsonSerialize(MemOp& data) ++void CreateCondOpResult(PluginClient *client, Json::Value& root, string& result) + { +- Json::Value root; +- root["id"] = std::to_string(data.idAttr().getInt()); +- root["defCode"] = std::to_string(data.defCodeAttr().getInt()); +- root["readOnly"] = std::to_string(data.readOnlyAttr().getValue()); +- mlir::Value base = data.GetBase(); +- mlir::Value offset = data.GetOffset(); +- root["base"] = ValueJsonSerialize(base); +- root["offset"] = ValueJsonSerialize(offset); +- auto retTy = data.getResultType().dyn_cast(); +- root["retType"] = TypeJsonSerialize(retTy); +- return root; ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ uint64_t blockId = atol(root["blockId"].asString().c_str()); ++ int condCode = atol(root["condCode"].asString().c_str()); ++ uint64_t lhsId = atol(root["lhsId"].asString().c_str()); ++ uint64_t rhsId = atol(root["rhsId"].asString().c_str()); ++ uint64_t tbaddr = atol(root["tbaddr"].asString().c_str()); ++ uint64_t fbaddr = atol(root["fbaddr"].asString().c_str()); ++ uint64_t ret = clientAPI.CreateCondOp(blockId, IComparisonCode(condCode), lhsId, rhsId, tbaddr, fbaddr); ++ client->ReceiveSendMsg("IdResult", std::to_string(ret)); + } + +-void PluginClient::IRTransBegin(const string& funcName, const string& param) ++void CreateFallthroughOpResult(PluginClient *client, Json::Value& root, string& result) + { +- string result; +- +- Json::Value root; +- Json::Reader reader; +- reader.parse(param, root); +- LOGD("%s func:%s,param:%s\n", __func__, funcName.c_str(), param.c_str()); ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ uint64_t address = atol(root["address"].asString().c_str()); ++ uint64_t destaddr = atol(root["destaddr"].asString().c_str()); ++ clientAPI.CreateFallthroughOp(address, destaddr); ++ PluginJson json = client->GetJson(); ++ json.NopJsonSerialize(result); ++ client->ReceiveSendMsg("VoidResult", result); ++} + +- if (funcName == "GetAllFunc") { +- // Load our Dialect in this MLIR Context. +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- PluginAPI::PluginClientAPI clientAPI(context); +- vector allFuncOps = clientAPI.GetAllFunc(); +- FunctionOpJsonSerialize(allFuncOps, result); +- this->ReceiveSendMsg("FuncOpResult", result); +- } else if (funcName == "GetLocalDecls") { +- /// Json格式 +- /// { +- /// "funcId":"xxxx" +- /// } +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- PluginAPI::PluginClientAPI clientAPI(context); +- std::string funcIdKey = "funcId"; +- uint64_t funcID = atol(root[funcIdKey].asString().c_str()); +- vector decls = clientAPI.GetDecls(funcID); +- LocalDeclsJsonSerialize(decls, result); +- this->ReceiveSendMsg("LocalDeclOpResult", result); +- } else if (funcName == "GetLoopsFromFunc") { +- /// Json格式 +- /// { +- /// "funcId":"xxxx" +- /// } +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- PluginAPI::PluginClientAPI clientAPI(context); +- std::string funcIdKey = "funcId"; +- uint64_t funcID = atol(root[funcIdKey].asString().c_str()); +- vector irLoops = clientAPI.GetLoopsFromFunc(funcID); +- LoopOpsJsonSerialize(irLoops, result); +- this->ReceiveSendMsg("LoopOpsResult", result); +- } else if (funcName == "GetLoopById") { +- /// Json格式 +- /// { +- /// "loopId":"xxxx" +- /// } +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- PluginAPI::PluginClientAPI clientAPI(context); +- std::string loopIdKey = "loopId"; +- uint64_t loopId = atol(root[loopIdKey].asString().c_str()); +- LoopOp irLoop = clientAPI.GetLoopById(loopId); +- LoopOpJsonSerialize(irLoop, result); +- this->ReceiveSendMsg("LoopOpResult", result); +- } else if (funcName == "IsBlockInside") { +- /// Json格式 +- /// { +- /// "loopId":"xxxx", +- /// "blockId":"xxxx" +- /// } +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- PluginAPI::PluginClientAPI clientAPI(context); +- std::string loopIdKey = "loopId"; +- std::string blockIdKey = "blockId"; +- uint64_t loopId = atol(root[loopIdKey].asString().c_str()); +- uint64_t blockId = atol(root[blockIdKey].asString().c_str()); +- bool res = clientAPI.IsBlockInside(loopId, blockId); +- this->ReceiveSendMsg("BoolResult", std::to_string((uint64_t)res)); +- } else if (funcName == "AllocateNewLoop") { +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- PluginAPI::PluginClientAPI clientAPI(context); +- uint64_t newLoopId = clientAPI.AllocateNewLoop(); +- LoopOp newLoop = clientAPI.GetLoopById(newLoopId); +- LoopOpJsonSerialize(newLoop, result); +- this->ReceiveSendMsg("LoopOpResult", result); +- } else if (funcName == "RedirectFallthroughTarget") { +- /// Json格式 +- /// { +- /// "src":"xxxx", +- /// "dest":"xxxx", +- /// } +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- PluginAPI::PluginClientAPI clientAPI(context); +- std::string srcKey = "src"; +- uint64_t src = atol(root[srcKey].asString().c_str()); +- std::string destKey = "dest"; +- uint64_t dest = atol(root[destKey].asString().c_str()); +- clientAPI.RedirectFallthroughTarget(src, dest); +- NopJsonSerialize(result); +- this->ReceiveSendMsg("VoidResult", result); +- } else if (funcName == "DeleteLoop") { +- /// Json格式 +- /// { +- /// "loopId":"xxxx", +- /// } +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- PluginAPI::PluginClientAPI clientAPI(context); +- std::string loopIdKey = "loopId"; +- uint64_t loopId = atol(root[loopIdKey].asString().c_str()); +- clientAPI.DeleteLoop(loopId); +- NopJsonSerialize(result); +- this->ReceiveSendMsg("VoidResult", result); +- } else if (funcName == "AddBlockToLoop") { +- /// Json格式 +- /// { +- /// "loopId":"xxxx", +- /// "blockId":"xxxx", +- /// } +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- PluginAPI::PluginClientAPI clientAPI(context); +- std::string loopIdKey = "loopId"; +- uint64_t loopId = atol(root[loopIdKey].asString().c_str()); +- std::string blockIdKey = "blockId"; +- uint64_t blockId = atol(root[blockIdKey].asString().c_str()); +- clientAPI.AddBlockToLoop(blockId, loopId); +- NopJsonSerialize(result); +- this->ReceiveSendMsg("VoidResult", result); +- } else if (funcName == "AddLoop") { +- /// Json格式 +- /// { +- /// "loopId":"xxxx", +- /// "outerId":"xxxx" +- /// "funcId":"xxxx" +- /// } +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- PluginAPI::PluginClientAPI clientAPI(context); +- std::string loopIdKey = "loopId"; +- std::string outerIdKey = "outerId"; +- std::string funcIdKey = "funcId"; +- uint64_t loopID = atol(root[loopIdKey].asString().c_str()); +- uint64_t outerID = atol(root[outerIdKey].asString().c_str()); +- uint64_t funcID = atol(root[funcIdKey].asString().c_str()); +- clientAPI.AddLoop(loopID, outerID, funcID); +- LoopOp irLoop = clientAPI.GetLoopById(loopID); +- LoopOpJsonSerialize(irLoop, result); +- this->ReceiveSendMsg("LoopOpResult", result); +- } else if (funcName == "GetBlocksInLoop") { +- /// Json格式 +- /// { +- /// "loopId":"xxxx", +- /// } +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- PluginAPI::PluginClientAPI clientAPI(context); +- std::string loopIdKey = "loopId"; +- uint64_t loopId = atol(root[loopIdKey].asString().c_str()); +- vector blocks = clientAPI.GetBlocksInLoop(loopId); +- BlocksJsonSerialize(blocks, result); +- this->ReceiveSendMsg("IdsResult", result); +- } else if (funcName == "GetHeader") { +- /// Json格式 +- /// { +- /// "loopId":"xxxx", +- /// } +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- PluginAPI::PluginClientAPI clientAPI(context); +- std::string loopIdKey = "loopId"; +- uint64_t loopId = atol(root[loopIdKey].asString().c_str()); +- uint64_t blockId = clientAPI.GetHeader(loopId); +- this->ReceiveSendMsg("IdResult", std::to_string(blockId)); +- } else if (funcName == "GetLatch") { +- /// Json格式 +- /// { +- /// "loopId":"xxxx", +- /// } +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- PluginAPI::PluginClientAPI clientAPI(context); +- std::string loopIdKey = "loopId"; +- uint64_t loopId = atol(root[loopIdKey].asString().c_str()); +- uint64_t blockId = clientAPI.GetLatch(loopId); +- this->ReceiveSendMsg("IdResult", std::to_string(blockId)); +- } else if (funcName == "SetHeader") { +- /// Json格式 +- /// { +- /// "loopId":"xxxx", +- /// "blockId":"xxxx", +- /// } +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- PluginAPI::PluginClientAPI clientAPI(context); +- std::string loopIdKey = "loopId"; +- uint64_t loopId = atol(root[loopIdKey].asString().c_str()); +- std::string blockIdKey = "blockId"; +- uint64_t blockId = atol(root[blockIdKey].asString().c_str()); +- clientAPI.SetHeader(loopId, blockId); +- NopJsonSerialize(result); +- this->ReceiveSendMsg("VoidResult", result); +- } else if (funcName == "SetLatch") { +- /// Json格式 +- /// { +- /// "loopId":"xxxx", +- /// "blockId":"xxxx", +- /// } +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- PluginAPI::PluginClientAPI clientAPI(context); +- std::string loopIdKey = "loopId"; +- uint64_t loopId = atol(root[loopIdKey].asString().c_str()); +- std::string blockIdKey = "blockId"; +- uint64_t blockId = atol(root[blockIdKey].asString().c_str()); +- clientAPI.SetLatch(loopId, blockId); +- NopJsonSerialize(result); +- this->ReceiveSendMsg("VoidResult", result); +- } else if (funcName == "GetLoopExits") { +- /// Json格式 +- /// { +- /// "loopId":"xxxx", +- /// } +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- PluginAPI::PluginClientAPI clientAPI(context); +- std::string loopIdKey = "loopId"; +- uint64_t loopId = atol(root[loopIdKey].asString().c_str()); +- vector > edges = clientAPI.GetLoopExits(loopId); +- EdgesJsonSerialize(edges, result); +- this->ReceiveSendMsg("EdgesResult", result); +- } else if (funcName == "GetLoopSingleExit") { +- /// Json格式 +- /// { +- /// "loopId":"xxxx", +- /// } +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- PluginAPI::PluginClientAPI clientAPI(context); +- std::string loopIdKey = "loopId"; +- uint64_t loopId = atol(root[loopIdKey].asString().c_str()); +- pair edge = clientAPI.GetLoopSingleExit(loopId); +- EdgeJsonSerialize(edge, result); +- this->ReceiveSendMsg("EdgeResult", result); +- } else if (funcName == "GetBlockLoopFather") { +- /// Json格式 +- /// { +- /// "blockId":"xxxx", +- /// } +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- PluginAPI::PluginClientAPI clientAPI(context); +- std::string blockIdKey = "blockId"; +- uint64_t blockId = atol(root[blockIdKey].asString().c_str()); +- LoopOp loopFather = clientAPI.GetBlockLoopFather(blockId); +- LoopOpJsonSerialize(loopFather, result); +- this->ReceiveSendMsg("LoopOpResult", result); +- } else if (funcName == "CreateBlock") { +- /// Json格式 +- /// { +- /// "bbaddr":"xxxx", +- /// "funcaddr":"xxxx" +- /// } +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- PluginAPI::PluginClientAPI clientAPI(context); +- uint64_t blockAddr = atol(root["bbaddr"].asString().c_str()); +- uint64_t funcAddr = atol(root["funcaddr"].asString().c_str()); +- uint64_t newBBAddr = clientAPI.CreateBlock(funcAddr, blockAddr); +- this->ReceiveSendMsg("IdResult", std::to_string(newBBAddr)); +- } else if (funcName == "DeleteBlock") { +- /// Json格式 +- /// { +- /// "bbaddr":"xxxx", +- /// } +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- PluginAPI::PluginClientAPI clientAPI(context); +- std::string funcKey = "funcaddr"; +- std::string BlockIdKey = "bbaddr"; +- uint64_t bbaddr = atol(root[BlockIdKey].asString().c_str()); +- uint64_t funcaddr = atol(root[funcKey].asString().c_str()); +- clientAPI.DeleteBlock(funcaddr, bbaddr); +- NopJsonSerialize(result); +- this->ReceiveSendMsg("VoidResult", result); +- } else if (funcName == "SetImmediateDominator") { +- /// Json格式 +- /// { +- /// "dir":"xxxx", +- /// "bbaddr":"xxxx", +- /// "domiaddr":"xxxx", +- /// } +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- PluginAPI::PluginClientAPI clientAPI(context); +- std::string dirIdKey = "dir"; +- uint64_t dir = atol(root[dirIdKey].asString().c_str()); +- std::string BlockIdKey = "bbaddr"; +- uint64_t bbaddr = atol(root[BlockIdKey].asString().c_str()); +- std::string domiIdKey = "domiaddr"; +- uint64_t domiaddr = atol(root[domiIdKey].asString().c_str()); +- clientAPI.SetImmediateDominator(dir, bbaddr, domiaddr); +- NopJsonSerialize(result); +- this->ReceiveSendMsg("VoidResult", result); +- } else if (funcName == "GetImmediateDominator") { +- /// Json格式 +- /// { +- /// "dir":"xxxx", +- /// "bbaddr":"xxxx", +- /// } +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- PluginAPI::PluginClientAPI clientAPI(context); +- std::string dirIdKey = "dir"; +- uint64_t dir = atol(root[dirIdKey].asString().c_str()); +- std::string BlockIdKey = "bbaddr"; +- uint64_t bbaddr = atol(root[BlockIdKey].asString().c_str()); +- uint64_t ret = clientAPI.GetImmediateDominator(dir, bbaddr); +- this->ReceiveSendMsg("IdResult", std::to_string(ret)); +- } else if (funcName == "RecomputeDominator") { +- /// Json格式 +- /// { +- /// "dir":"xxxx", +- /// "bbaddr":"xxxx", +- /// } +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- PluginAPI::PluginClientAPI clientAPI(context); +- std::string dirIdKey = "dir"; +- uint64_t dir = atol(root[dirIdKey].asString().c_str()); +- std::string BlockIdKey = "bbaddr"; +- uint64_t bbaddr = atol(root[BlockIdKey].asString().c_str()); +- uint64_t ret = clientAPI.RecomputeDominator(dir, bbaddr); +- this->ReceiveSendMsg("IdResult", std::to_string(ret)); +- } else if (funcName == "GetPhiOp") { +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- PluginAPI::PluginClientAPI clientAPI(context); +- uint64_t id = atol(root[std::to_string(0)].asString().c_str()); +- PhiOp op = clientAPI.GetPhiOp(id); +- Json::Value result = PhiOpJsonSerialize(op); +- this->ReceiveSendMsg("OpsResult", result.toStyledString()); +- } else if (funcName == "GetCallOp") { +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- PluginAPI::PluginClientAPI clientAPI(context); +- uint64_t id = atol(root[std::to_string(0)].asString().c_str()); +- CallOp op = clientAPI.GetCallOp(id); +- Json::Value result = CallOpJsonSerialize(op); +- this->ReceiveSendMsg("OpsResult", result.toStyledString()); +- } else if (funcName == "SetLhsInCallOp") { +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- PluginAPI::PluginClientAPI clientAPI(context); +- uint64_t callId = atol(root["callId"].asString().c_str()); +- uint64_t lhsId = atol(root["lhsId"].asString().c_str()); +- bool ret = clientAPI.SetLhsInCallOp(callId, lhsId); +- this->ReceiveSendMsg("BoolResult", std::to_string(ret)); +- } else if (funcName == "AddArgInPhiOp") { +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- PluginAPI::PluginClientAPI clientAPI(context); +- uint64_t phiId = atol(root["phiId"].asString().c_str()); +- uint64_t argId = atol(root["argId"].asString().c_str()); +- uint64_t predId = atol(root["predId"].asString().c_str()); +- uint64_t succId = atol(root["succId"].asString().c_str()); +- uint32_t ret = clientAPI.AddArgInPhiOp(phiId, argId, predId, succId); +- this->ReceiveSendMsg("IdResult", std::to_string(ret)); +- } else if (funcName == "CreateCallOp") { +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- PluginAPI::PluginClientAPI clientAPI(context); +- uint64_t blockId = atol(root["blockId"].asString().c_str()); +- uint64_t funcId = atol(root["funcId"].asString().c_str()); +- vector argIds; +- Json::Value argIdsJson = root["argIds"]; +- Json::Value::Members member = argIdsJson.getMemberNames(); +- for (Json::Value::Members::iterator opIter = member.begin(); +- opIter != member.end(); opIter++) { +- string key = *opIter; +- uint64_t id = atol(argIdsJson[key.c_str()].asString().c_str()); +- argIds.push_back(id); +- } +- uint64_t ret = clientAPI.CreateCallOp(blockId, funcId, argIds); +- this->ReceiveSendMsg("IdResult", std::to_string(ret)); +- } else if (funcName == "CreateAssignOp") { +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- PluginAPI::PluginClientAPI clientAPI(context); +- uint64_t blockId = atol(root["blockId"].asString().c_str()); +- int condCode = atol(root["exprCode"].asString().c_str()); +- vector argIds; +- Json::Value argIdsJson = root["argIds"]; +- Json::Value::Members member = argIdsJson.getMemberNames(); +- for (Json::Value::Members::iterator opIter = member.begin(); +- opIter != member.end(); opIter++) { +- string key = *opIter; +- uint64_t id = atol(argIdsJson[key.c_str()].asString().c_str()); +- argIds.push_back(id); +- } +- uint64_t ret = clientAPI.CreateAssignOp( +- blockId, IExprCode(condCode), argIds); +- this->ReceiveSendMsg("IdResult", std::to_string(ret)); +- } else if (funcName == "CreateCondOp") { +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- PluginAPI::PluginClientAPI clientAPI(context); +- uint64_t blockId = atol(root["blockId"].asString().c_str()); +- int condCode = atol(root["condCode"].asString().c_str()); +- uint64_t lhsId = atol(root["lhsId"].asString().c_str()); +- uint64_t rhsId = atol(root["rhsId"].asString().c_str()); +- uint64_t tbaddr = atol(root["tbaddr"].asString().c_str()); +- uint64_t fbaddr = atol(root["fbaddr"].asString().c_str()); +- uint64_t ret = clientAPI.CreateCondOp(blockId, IComparisonCode(condCode), +- lhsId, rhsId, tbaddr, fbaddr); +- this->ReceiveSendMsg("IdResult", std::to_string(ret)); +- } else if (funcName == "CreateFallthroughOp") { +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- PluginAPI::PluginClientAPI clientAPI(context); +- uint64_t address = atol(root["address"].asString().c_str()); +- uint64_t destaddr = atol(root["destaddr"].asString().c_str()); +- clientAPI.CreateFallthroughOp(address, destaddr); +- NopJsonSerialize(result); +- this->ReceiveSendMsg("VoidResult", result); +- } else if (funcName == "GetResultFromPhi") { +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- PluginAPI::PluginClientAPI clientAPI(context); +- uint64_t id = atol(root["id"].asString().c_str()); +- mlir::Value ret = clientAPI.GetResultFromPhi(id); +- this->ReceiveSendMsg("ValueResult", +- ValueJsonSerialize(ret).toStyledString()); +- } else if (funcName == "CreatePhiOp") { +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- PluginAPI::PluginClientAPI clientAPI(context); +- uint64_t argId = atol(root["argId"].asString().c_str()); +- uint64_t blockId = atol(root["blockId"].asString().c_str()); +- PhiOp op = clientAPI.CreatePhiOp(argId, blockId); +- Json::Value result = PhiOpJsonSerialize(op); +- this->ReceiveSendMsg("OpsResult", result.toStyledString()); +- } else if (funcName == "CreateConstOp") { +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- PluginAPI::PluginClientAPI clientAPI(context); +- PluginIR::PluginTypeBase type = TypeJsonDeSerialize(root.toStyledString(), context); +- uint64_t value = atol(root["value"].asString().c_str()); +- mlir::OpBuilder opBuilder = mlir::OpBuilder(&context); +- mlir::Attribute attr = opBuilder.getI64IntegerAttr(value); +- mlir::Value ret = clientAPI.CreateConstOp(attr, type); +- this->ReceiveSendMsg("ValueResult", +- ValueJsonSerialize(ret).toStyledString()); +- } else if (funcName == "UpdateSSA") { +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- PluginAPI::PluginClientAPI clientAPI(context); +- bool ret = clientAPI.UpdateSSA(); +- this->ReceiveSendMsg("BoolResult", std::to_string((uint64_t)ret)); +- } else if (funcName == "GetAllPhiOpInsideBlock") { +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- PluginAPI::PluginClientAPI clientAPI(context); +- uint64_t bb = atol(root["bbAddr"].asString().c_str()); +- vector phiOps = clientAPI.GetPhiOpsInsideBlock(bb); +- GetPhiOpsJsonSerialize(phiOps, result); +- this->ReceiveSendMsg("GetPhiOps", result); +- } else if (funcName == "IsDomInfoAvailable") { +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- PluginAPI::PluginClientAPI clientAPI(context); +- bool ret = clientAPI.IsDomInfoAvailable(); +- this->ReceiveSendMsg("BoolResult", std::to_string((uint64_t)ret)); +- } else if (funcName == "GetCurrentDefFromSSA") { +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- uint64_t varId = atol(root["varId"].asString().c_str()); +- PluginAPI::PluginClientAPI clientAPI(context); +- mlir::Value ret = clientAPI.GetCurrentDefFromSSA(varId); +- this->ReceiveSendMsg("ValueResult", +- ValueJsonSerialize(ret).toStyledString()); +- } else if (funcName == "SetCurrentDefInSSA") { +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- uint64_t varId = atol(root["varId"].asString().c_str()); +- uint64_t defId = atol(root["defId"].asString().c_str()); +- PluginAPI::PluginClientAPI clientAPI(context); +- bool ret = clientAPI.SetCurrentDefInSSA(varId, defId); +- this->ReceiveSendMsg("BoolResult", std::to_string((uint64_t)ret)); +- } else if (funcName == "CopySSAOp") { +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- PluginAPI::PluginClientAPI clientAPI(context); +- uint64_t id = atol(root["id"].asString().c_str()); +- mlir::Value ret = clientAPI.CopySSAOp(id); +- this->ReceiveSendMsg("ValueResult", +- ValueJsonSerialize(ret).toStyledString()); +- } else if (funcName == "CreateSSAOp") { +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- PluginAPI::PluginClientAPI clientAPI(context); +- PluginIR::PluginTypeBase type = TypeJsonDeSerialize(root.toStyledString(), context); +- mlir::Value ret = clientAPI.CreateSSAOp(type); +- this->ReceiveSendMsg("ValueResult", +- ValueJsonSerialize(ret).toStyledString()); +- } else if (funcName == "CreateNewDef") { +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- PluginAPI::PluginClientAPI clientAPI(context); +- uint64_t opId = atol(root["opId"].asString().c_str()); +- uint64_t valueId = atol(root["valueId"].asString().c_str()); +- uint64_t defId = atol(root["defId"].asString().c_str()); +- mlir::Value ret = clientAPI.CreateNewDef(valueId, opId, defId); +- this->ReceiveSendMsg("ValueResult", +- ValueJsonSerialize(ret).toStyledString()); +- } else if (funcName == "RemoveEdge") { +- /// Json格式 +- /// { +- /// "src":"xxxx", +- /// "dest":"xxxx", +- /// } +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- PluginAPI::PluginClientAPI clientAPI(context); +- std::string srcKey = "src"; +- uint64_t src = atol(root[srcKey].asString().c_str()); +- std::string destKey = "dest"; +- uint64_t dest = atol(root[destKey].asString().c_str()); +- clientAPI.RemoveEdge(src, dest); +- NopJsonSerialize(result); +- this->ReceiveSendMsg("VoidResult", result); +- } else if (funcName == "ConfirmValue") { +- /// Json格式 +- /// { +- /// "valId":"xxxx", +- /// } +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- PluginAPI::PluginClientAPI clientAPI(context); +- std::string valIdKey = "valId"; +- uint64_t valId = atol(root[valIdKey].asString().c_str()); +- mlir::Value v = clientAPI.GetValue(valId); +- Json::Value valueJson = ValueJsonSerialize(v); +- result = valueJson.toStyledString(); +- this->ReceiveSendMsg("ValueResult", result); +- } else if (funcName == "BuildMemRef") { +- /// Json格式 +- /// { +- /// "baseId":"xxxx", +- /// "offsetId":"xxxx", +- /// "type":"xxxx", +- /// } +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- PluginAPI::PluginClientAPI clientAPI(context); +- std::string baseIdKey = "baseId"; +- std::string offsetIdKey = "offsetId"; +- std::string typeKey = "type"; +- uint64_t baseId = atol(root[baseIdKey].asString().c_str()); +- uint64_t offsetId = atol(root[offsetIdKey].asString().c_str()); +- Json::Value type = root[typeKey]; +- PluginIR::PluginTypeBase pType = TypeJsonDeSerialize(type.toStyledString(), context); +- mlir::Value v = clientAPI.BuildMemRef(pType, baseId, offsetId); +- Json::Value valueJson = ValueJsonSerialize(v); +- result = valueJson.toStyledString(); +- this->ReceiveSendMsg("ValueResult", result); +- } else if (funcName == "DebugValue") { +- /// Json格式 +- /// { +- /// "valId":"xxxx", +- /// } +- mlir::MLIRContext context; +- context.getOrLoadDialect(); +- PluginAPI::PluginClientAPI clientAPI(context); +- std::string valIdKey = "valId"; +- uint64_t valId = atol(root[valIdKey].asString().c_str()); +- clientAPI.DebugValue(valId); +- NopJsonSerialize(result); +- this->ReceiveSendMsg("ValueResult", result); +- } else { +- LOGW("function: %s not found!\n", funcName.c_str()); +- } ++void GetResultFromPhiResult(PluginClient *client, Json::Value& root, string& result) ++{ ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ uint64_t id = atol(root["id"].asString().c_str()); ++ mlir::Value ret = clientAPI.GetResultFromPhi(id); ++ PluginJson json = client->GetJson(); ++ client->ReceiveSendMsg("ValueResult", json.ValueJsonSerialize(ret).toStyledString()); ++} + +- LOGD("IR function: %s\n", funcName.c_str()); +- this->SetPluginAPIName(""); +- this->SetUserFuncState(STATE_RETURN); +- this->ReceiveSendMsg(funcName, "done"); ++void CreatePhiOpResult(PluginClient *client, Json::Value& root, string& result) ++{ ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ uint64_t argId = atol(root["argId"].asString().c_str()); ++ uint64_t blockId = atol(root["blockId"].asString().c_str()); ++ PhiOp op = clientAPI.CreatePhiOp(argId, blockId); ++ PluginJson json = client->GetJson(); ++ Json::Value opResult = json.PhiOpJsonSerialize(op); ++ client->ReceiveSendMsg("OpsResult", opResult.toStyledString()); + } + +-int PluginClient::GetInitInfo(string& serverPath, string& shaPath, int& timeout) ++void CreateConstOpResult(PluginClient *client, Json::Value& root, string& result) + { +- Json::Value root; +- Json::Reader reader; +- std::ifstream ifs; +- string configFilePath; +- string serverDir; +- if (serverPath == "") { +- configFilePath = "/usr/local/bin/pin-gcc-client.json"; // server路径为空,配置文件默认路径 +- LOGW("input serverPath is NULL, read default:%s\n", configFilePath.c_str()); +- } else { +- int index = serverPath.find_last_of("/"); +- serverDir = serverPath.substr(0, index); +- configFilePath = serverDir + "/pin-gcc-client.json"; // 配置文件和server在同一目录 +- } ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ PluginJson json = client->GetJson(); ++ PluginIR::PluginTypeBase type = json.TypeJsonDeSerialize(root.toStyledString(), context); ++ uint64_t value = atol(root["value"].asString().c_str()); ++ mlir::OpBuilder opBuilder = mlir::OpBuilder(&context); ++ mlir::Attribute attr = opBuilder.getI64IntegerAttr(value); ++ mlir::Value ret = clientAPI.CreateConstOp(attr, type); ++ client->ReceiveSendMsg("ValueResult", json.ValueJsonSerialize(ret).toStyledString()); ++} + +- ifs.open(configFilePath.c_str()); +- if (!ifs) { +- shaPath = serverDir + "/libpin_user.sha256"; // sha256文件默认和server在同一目录 +- LOGW("open %s fail! use default sha256file:%s\n", configFilePath.c_str(), shaPath.c_str()); +- return -1; +- } +- reader.parse(ifs, root); +- ifs.close(); ++void UpdateSSAResult(PluginClient *client, Json::Value& root, string& result) ++{ ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ bool ret = clientAPI.UpdateSSA(); ++ client->ReceiveSendMsg("BoolResult", std::to_string((uint64_t)ret)); ++} + +- if (serverPath == "") { +- if (!root["path"].isString()) { +- LOGE("path in config.json is not string\n"); +- return 0; +- } +- serverPath = root["path"].asString(); +- int index = serverPath.find_last_of("/"); +- serverDir = serverPath.substr(0, index); +- } +- int timeoutJson = root["timeout"].asInt(); +- if ((timeoutJson >= 50) && (timeoutJson <= 5000)) { // 不在50~5000ms范围内,使用默认值 +- timeout = timeoutJson; +- LOGI("the timeout is:%d\n", timeout); +- } else { +- LOGW("timeout read from %s is:%d,should be 50~5000,use default:%d\n", +- configFilePath.c_str(), timeoutJson, timeout); +- } +- shaPath = root["sha256file"].asString(); +- int ret = access(shaPath.c_str(), F_OK); +- if ((shaPath == "") || (ret != 0)) { +- shaPath = serverDir + "/libpin_user.sha256"; // sha256文件默认和server在同一目录 +- LOGW("sha256 file not found,use default:%s\n", shaPath.c_str()); +- } +- return 0; ++void GetAllPhiOpInsideBlockResult(PluginClient *client, Json::Value& root, string& result) ++{ ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ uint64_t bb = atol(root["bbAddr"].asString().c_str()); ++ vector phiOps = clientAPI.GetPhiOpsInsideBlock(bb); ++ PluginJson json = client->GetJson(); ++ json.GetPhiOpsJsonSerialize(phiOps, result); ++ client->ReceiveSendMsg("GetPhiOps", result); + } + +-void PluginClient::GetArg(struct plugin_name_args *pluginInfo, string& serverPath, +- string& arg, LogPriority& logLevel) ++void IsDomInfoAvailableResult(PluginClient *client, Json::Value& root, string& result) + { +- Json::Value root; +- map compileArgs; +- for (int i = 0; i < pluginInfo->argc; i++) { +- string key = pluginInfo->argv[i].key; +- if (key == "server_path") { +- serverPath = pluginInfo->argv[i].value; +- } else if (key == "log_level") { +- logLevel = (LogPriority)atoi(pluginInfo->argv[i].value); +- SetLogPriority(logLevel); +- } else { +- string value = pluginInfo->argv[i].value; +- compileArgs[key] = value; +- root[key] = value; +- } +- } +- arg = root.toStyledString(); +- for (auto it = compileArgs.begin(); it != compileArgs.end(); it++) { +- CheckSafeCompileFlag(it->first, it->second); +- } ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ bool ret = clientAPI.IsDomInfoAvailable(); ++ client->ReceiveSendMsg("BoolResult", std::to_string((uint64_t)ret)); + } + +-int PluginClient::CheckSHA256(const string& shaPath) ++void GetCurrentDefFromSSAResult(PluginClient *client, Json::Value& root, string& result) + { +- if (shaPath == "") { +- LOGE("sha256file Path is NULL,check:%s\n", shaPath.c_str()); +- return -1; +- } +- int index = shaPath.find_last_of("/"); +- string dir = shaPath.substr(0, index); +- string filename = shaPath.substr(index+1, -1); ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ uint64_t varId = atol(root["varId"].asString().c_str()); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ mlir::Value ret = clientAPI.GetCurrentDefFromSSA(varId); ++ PluginJson json = client->GetJson(); ++ client->ReceiveSendMsg("ValueResult", json.ValueJsonSerialize(ret).toStyledString()); ++} + +- string cmd = "cd " + dir + " && " + "sha256sum -c " + filename + " --quiet"; +- int ret = system(cmd.c_str()); +- return ret; ++void SetCurrentDefInSSAResult(PluginClient *client, Json::Value& root, string& result) ++{ ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ uint64_t varId = atol(root["varId"].asString().c_str()); ++ uint64_t defId = atol(root["defId"].asString().c_str()); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ bool ret = clientAPI.SetCurrentDefInSSA(varId, defId); ++ client->ReceiveSendMsg("BoolResult", std::to_string((uint64_t)ret)); + } + +-void PluginClient::CheckSafeCompileFlag(const string& argName, const string& param) ++void CopySSAOpResult(PluginClient *client, Json::Value& root, string& result) + { +- vector safeCompileFlags = { +- "-z noexecstack", +- "-fno-stack-protector", +- "-fstack-protector-all", +- "-D_FORTIFY_SOURCE", +- "-fPic", +- "-fPIE", +- "-fstack-protector-strong", +- "-fvisibility", +- "-ftrapv", +- "-fstack-check", +- }; +- +- for (auto& v : safeCompileFlags) { +- if (param.find(v) != string::npos) { +- LOGW("%s:%s have safe compile parameter:%s !!!\n", argName.c_str(), param.c_str(), v.c_str()); +- } +- } ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ uint64_t id = atol(root["id"].asString().c_str()); ++ mlir::Value ret = clientAPI.CopySSAOp(id); ++ PluginJson json = client->GetJson(); ++ client->ReceiveSendMsg("ValueResult", json.ValueJsonSerialize(ret).toStyledString()); + } + +-bool PluginClient::DeletePortFromLockFile(unsigned short port) ++void CreateSSAOpResult(PluginClient *client, Json::Value& root, string& result) + { +- int portFileFd = open(g_portFilePath, O_RDWR); +- if (portFileFd == -1) { +- LOGE("%s open file %s fail\n", __func__, g_portFilePath); +- return false; +- } +- LOGI("delete port:%d\n", port); ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ PluginJson json = client->GetJson(); ++ PluginIR::PluginTypeBase type = json.TypeJsonDeSerialize(root.toStyledString(), context); ++ mlir::Value ret = clientAPI.CreateSSAOp(type); ++ client->ReceiveSendMsg("ValueResult", json.ValueJsonSerialize(ret).toStyledString()); ++} + +- flock(portFileFd, LOCK_EX); +- string grpcPorts = ""; +- ReadPortsFromLockFile(portFileFd, grpcPorts); ++void CreateNewDefResult(PluginClient *client, Json::Value& root, string& result) ++{ ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ uint64_t opId = atol(root["opId"].asString().c_str()); ++ uint64_t valueId = atol(root["valueId"].asString().c_str()); ++ uint64_t defId = atol(root["defId"].asString().c_str()); ++ mlir::Value ret = clientAPI.CreateNewDef(valueId, opId, defId); ++ PluginJson json = client->GetJson(); ++ client->ReceiveSendMsg("ValueResult", json.ValueJsonSerialize(ret).toStyledString()); ++} + +- string portStr = std::to_string(port) + "\n"; +- string::size_type pos = grpcPorts.find(portStr); +- if (pos == string::npos) { +- close(portFileFd); +- return true; +- } +- grpcPorts = grpcPorts.erase(pos, portStr.size()); ++void RemoveEdgeResult(PluginClient *client, Json::Value& root, string& result) ++{ ++ /// Json格式 ++ /// { ++ /// "src":"xxxx", ++ /// "dest":"xxxx", ++ /// } ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ std::string srcKey = "src"; ++ uint64_t src = atol(root[srcKey].asString().c_str()); ++ std::string destKey = "dest"; ++ uint64_t dest = atol(root[destKey].asString().c_str()); ++ clientAPI.RemoveEdge(src, dest); ++ PluginJson json = client->GetJson(); ++ json.NopJsonSerialize(result); ++ client->ReceiveSendMsg("VoidResult", result); ++} + +- ftruncate(portFileFd, 0); +- lseek(portFileFd, 0, SEEK_SET); +- write(portFileFd, grpcPorts.c_str(), grpcPorts.size()); +- close(portFileFd); ++void ConfirmValueResult(PluginClient *client, Json::Value& root, string& result) ++{ ++ /// Json格式 ++ /// { ++ /// "valId":"xxxx", ++ /// } ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ std::string valIdKey = "valId"; ++ uint64_t valId = atol(root[valIdKey].asString().c_str()); ++ mlir::Value v = clientAPI.GetValue(valId); ++ PluginJson json = client->GetJson(); ++ Json::Value valueJson = json.ValueJsonSerialize(v); ++ result = valueJson.toStyledString(); ++ client->ReceiveSendMsg("ValueResult", result); ++} + +- return true; ++void BuildMemRefResult(PluginClient *client, Json::Value& root, string& result) ++{ ++ /// Json格式 ++ /// { ++ /// "baseId":"xxxx", ++ /// "offsetId":"xxxx", ++ /// "type":"xxxx", ++ /// } ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ std::string baseIdKey = "baseId"; ++ std::string offsetIdKey = "offsetId"; ++ std::string typeKey = "type"; ++ uint64_t baseId = atol(root[baseIdKey].asString().c_str()); ++ uint64_t offsetId = atol(root[offsetIdKey].asString().c_str()); ++ Json::Value type = root[typeKey]; ++ PluginJson json = client->GetJson(); ++ PluginIR::PluginTypeBase pType = json.TypeJsonDeSerialize(type.toStyledString(), context); ++ mlir::Value v = clientAPI.BuildMemRef(pType, baseId, offsetId); ++ Json::Value valueJson = json.ValueJsonSerialize(v); ++ result = valueJson.toStyledString(); ++ client->ReceiveSendMsg("ValueResult", result); ++} ++ ++void DebugValueResult(PluginClient *client, Json::Value& root, string& result) ++{ ++ /// Json格式 ++ /// { ++ /// "valId":"xxxx", ++ /// } ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ std::string valIdKey = "valId"; ++ uint64_t valId = atol(root[valIdKey].asString().c_str()); ++ clientAPI.DebugValue(valId); ++ PluginJson json = client->GetJson(); ++ json.NopJsonSerialize(result); ++ client->ReceiveSendMsg("ValueResult", result); ++} ++ ++typedef std::function GetResultFunc; ++std::map g_getResultFunc = { ++ {"GetAllFunc", GetAllFuncResult}, ++ {"GetLocalDecls", GetLocalDeclsResult}, ++ {"GetLoopsFromFunc", GetLoopsFromFuncResult}, ++ {"GetLoopById", GetLoopByIdResult}, ++ {"IsBlockInside", IsBlockInsideResult}, ++ {"AllocateNewLoop", AllocateNewLoopResult}, ++ {"RedirectFallthroughTarget", RedirectFallthroughTargetResult}, ++ {"DeleteLoop", DeleteLoopResult}, ++ {"AddBlockToLoop", AddBlockToLoopResult}, ++ {"AddLoop", AddLoopResult}, ++ {"GetBlocksInLoop", GetBlocksInLoopResult}, ++ {"GetHeader", GetHeaderResult}, ++ {"GetLatch", GetLatchResult}, ++ {"SetHeader", SetHeaderResult}, ++ {"SetLatch", SetLatchResult}, ++ {"GetLoopExits", GetLoopExitsResult}, ++ {"GetLoopSingleExit", GetLoopSingleExitResult}, ++ {"GetBlockLoopFather", GetBlockLoopFatherResult}, ++ {"CreateBlock", CreateBlockResult}, ++ {"DeleteBlock", DeleteBlockResult}, ++ {"SetImmediateDominator", SetImmediateDominatorResult}, ++ {"GetImmediateDominator", GetImmediateDominatorResult}, ++ {"RecomputeDominator", RecomputeDominatorResult}, ++ {"GetPhiOp", GetPhiOpResult}, ++ {"GetCallOp", GetCallOpResult}, ++ {"SetLhsInCallOp", SetLhsInCallOpResult}, ++ {"AddArgInPhiOp", AddArgInPhiOpResult}, ++ {"CreateCallOp", CreateCallOpResult}, ++ {"CreateAssignOp", CreateAssignOpResult}, ++ {"CreateCondOp", CreateCondOpResult}, ++ {"CreateFallthroughOp", CreateFallthroughOpResult}, ++ {"GetResultFromPhi", GetResultFromPhiResult}, ++ {"CreatePhiOp", CreatePhiOpResult}, ++ {"CreateConstOp", CreateConstOpResult}, ++ {"UpdateSSA", UpdateSSAResult}, ++ {"GetAllPhiOpInsideBlock", GetAllPhiOpInsideBlockResult}, ++ {"IsDomInfoAvailable", IsDomInfoAvailableResult}, ++ {"GetCurrentDefFromSSA", GetCurrentDefFromSSAResult}, ++ {"SetCurrentDefInSSA", SetCurrentDefInSSAResult}, ++ {"CopySSAOp", CopySSAOpResult}, ++ {"CreateSSAOp", CreateSSAOpResult}, ++ {"CreateNewDef", CreateNewDefResult}, ++ {"RemoveEdge", RemoveEdgeResult}, ++ {"ConfirmValue", ConfirmValueResult}, ++ {"BuildMemRef", BuildMemRefResult}, ++ {"DebugValue", DebugValueResult}, ++}; ++ ++void PluginClient::GetIRTransResult(void *gccData, const string& funcName, const string& param) ++{ ++ string result; ++ Json::Value root; ++ Json::Reader reader; ++ reader.parse(param, root); ++ LOGD("%s func:%s,param:%s\n", __func__, funcName.c_str(), param.c_str()); ++ ++ if (funcName == "GetInjectDataAddress") { ++ int64_t ptrAddress = (int64_t)gccData; ++ json.IntegerSerialize(ptrAddress, result); ++ this->ReceiveSendMsg("IntegerResult", result); ++ } else if (funcName == "GetIncludeFile") { ++ if (gccData != nullptr) { ++ string includeFile = (char *)gccData; ++ json.StringSerialize(includeFile, result); ++ this->ReceiveSendMsg("StringResult", result); ++ } else { ++ LOGE("%s gcc_data address is NULL!\n", __func__); ++ } ++ } else { ++ auto it = g_getResultFunc.find(funcName); ++ if (it != g_getResultFunc.end()) { ++ it->second(this, root, result); ++ } else { ++ string key = ""; ++ GetGccData(funcName, param, key, result); ++ if (key != "") { ++ this->ReceiveSendMsg(key, result); ++ } ++ } ++ } ++ ++ LOGD("IR function: %s\n", funcName.c_str()); ++ this->SetPluginAPIName(""); ++ this->SetUserFuncState(STATE_RETURN); ++ this->ReceiveSendMsg(funcName, "done"); + } + ++// attribute:value说明 ++// start:ok 启动成功 ++// stop:ok 关闭成功 ++// userFunc:execution completed 函数执行完毕,执行下一个函数 ++// injectPoit:xxxx 注册点,xxxx是server传递过来的唯一值,gcc回调时,将xxxx返回server解析,执行对应的函数 ++// xxxx:yyyy 此类都认为是api函数,xxxx为函数名,yyyy为形参 + void PluginClient::ReceiveSendMsg(const string& attribute, const string& value) + { + ClientContext context; +@@ -1219,31 +925,29 @@ void PluginClient::ReceiveSendMsg(const string& attribute, const string& value) + clientMsg.set_value(value); + stream->Write(clientMsg); + stream->WritesDone(); +- TimerStart(timeout); +- if (g_grpcChannel->GetState(true) != GRPC_CHANNEL_READY) { ++ TimerStart(input.GetTimeout()); ++ ++ if (grpcChannel->GetState(true) != GRPC_CHANNEL_READY) { + LOGW("client pid:%d grpc channel not ready!\n", getpid()); + return; + } + ServerMsg serverMsg; + while (stream->Read(&serverMsg)) { +- TimerStart(0); +- if (serverMsg.attribute() != "injectPoint") { // 日志不记录注册的函数名信息 ++ TimerStart(0); // 定时值0,关闭定时器 ++ if (serverMsg.attribute() != grpckey[INJECT]) { // 日志不记录注册的函数名信息 + LOGD("rec from server:%s,%s\n", serverMsg.attribute().c_str(), serverMsg.value().c_str()); + } +- if ((serverMsg.attribute() == "start") && (serverMsg.value() == "ok")) { ++ if ((serverMsg.attribute() == grpckey[START]) && (serverMsg.value() == grpcValue[START_VALUE])) { + LOGI("server has been started!\n"); +- if (!DeletePortFromLockFile(GetGrpcPort())) { +- LOGE("DeletePortFromLockFile fail\n"); +- } +- } else if ((serverMsg.attribute() == "stop") && (serverMsg.value() == "ok")) { ++ DeleteGrpcPort(); ++ } else if ((serverMsg.attribute() == grpckey[STOP]) && (serverMsg.value() == grpcValue[STOP_VALUE])) { + LOGI("server has been closed!\n"); + Status status = stream->Finish(); + if (!status.ok()) { +- LOGE("error code:%d,%s\n", status.error_code(), status.error_message().c_str()); +- LOGE("RPC failed\n"); ++ LOGE("RPC failed,error code:%d,%s\n", status.error_code(), status.error_message().c_str()); + } + CloseLog(); +- } else if ((serverMsg.attribute() == "userFunc") && (serverMsg.value() == "execution completed")) { ++ } else if ((serverMsg.attribute() == grpckey[USERFUNC]) && (serverMsg.value() == grpcValue[USERFUNC_VALUE])) { + SetUserFuncState(STATE_END); // server已接收到对应函数所需数据 + } else { + ServerMsgProc(serverMsg.attribute(), serverMsg.value()); +@@ -1258,9 +962,10 @@ int PluginClient::AddRegisteredUserFunc(const string& value) + string name = value.substr(index + 1, -1); + InjectPoint inject = (InjectPoint)atoi(point.c_str()); + if (inject >= HANDLE_MAX) { ++ LOGE("AddRegisteredUserFunc %s err!\n", value.c_str()); + return -1; + } +- ++ + registeredUserFunc[inject].push_back(name); + return 0; + } +@@ -1270,63 +975,75 @@ ManagerSetupData GetPassInfoData(const string& data) + ManagerSetupData setupData; + Json::Value root; + Json::Reader reader; +- reader.parse(data, root); ++ string jsonData = data.substr(data.find_first_of(":") + 1, -1); ++ reader.parse(jsonData, root); + +- setupData.refPassName = (RefPassName)root["refPassName"].asInt(); +- setupData.passNum = root["passNum"].asInt(); +- setupData.passPosition = (PassPosition)root["passPosition"].asInt(); ++ if (root[passValue[PASS_NAME]].isInt()) { ++ setupData.refPassName = (RefPassName)root[passValue[PASS_NAME]].asInt(); ++ } ++ if (root[passValue[PASS_NUM]].isInt()) { ++ setupData.passNum = root[passValue[PASS_NUM]].asInt(); ++ } ++ if (root[passValue[PASS_POSITION]].isInt()) { ++ setupData.passPosition = (PassPosition)root[passValue[PASS_POSITION]].asInt(); ++ } ++ + return setupData; + } + ++// attribute不为"injectPoint"时,attribute为"funcName",value为函数参数 ++// attribute为"injectPoint"时, value为"inject:funcName+函数指针地址" + void PluginClient::ServerMsgProc(const string& attribute, const string& value) + { +- std::shared_ptr client = PluginClient::GetInstance(); +- if (attribute == "injectPoint") { +- if (value == "finished") { +- string pluginName = client->GetPluginName(); +- InjectPoint inject; +- map> userFuncs = client->GetRegisteredUserFunc(); +- for (auto it = userFuncs.begin(); it != userFuncs.end(); it++) { +- inject = it->first; +- if (inject == HANDLE_MANAGER_SETUP) { +- string data = it->second.front(); +- ManagerSetupData setupData = GetPassInfoData(data); +- RegisterPassManagerSetup(inject, setupData, pluginName); +- } else { +- RegisterPluginEvent(inject, pluginName); // 注册event ++ if (attribute != grpckey[INJECT]) { ++ SetPluginAPIParam(value); ++ SetPluginAPIName(attribute); ++ SetUserFuncState(STATE_BEGIN); ++ return; ++ } ++ ++ if (value == grpcValue[FINISH_VALUE]) { ++ string pluginName = GetPluginName(); ++ InjectPoint inject; ++ map> userFuncs = GetRegisteredUserFunc(); ++ for (auto it = userFuncs.begin(); it != userFuncs.end(); it++) { ++ inject = it->first; // first为注册点 ++ if (inject == HANDLE_MANAGER_SETUP) { ++ for (unsigned int i = 0; i < it->second.size(); i++) { ++ ManagerSetupData setupData = GetPassInfoData(it->second[i]); ++ RegisterPassManagerSetup(i, setupData, pluginName); + } ++ } else { ++ RegisterPluginEvent(inject, pluginName); // 注册event + } +- client->SetInjectFlag(true); +- } else { +- client->AddRegisteredUserFunc(value); + } ++ SetInjectFlag(true); + } else { +- client->SetPluginAPIParam(value); +- client->SetPluginAPIName(attribute); +- client->SetUserFuncState(STATE_BEGIN); ++ AddRegisteredUserFunc(value); + } + } + + void TimeoutFunc(union sigval sig) + { + LOGW("client pid:%d timeout!\n", getpid()); +- g_plugin->SetUserFuncState(STATE_TIMEOUT); ++ PluginClient::GetInstance()->SetUserFuncState(STATE_TIMEOUT); + } + + void PluginClient::TimerStart(int interval) + { +- int msTons = 1000000; // ms转ns倍数 +- int msTos = 1000; // s转ms倍数 ++ const int msTons = 1000000; // ms转ns倍数 ++ const int msTos = 1000; // s转ms倍数 + struct itimerspec time_value; + time_value.it_value.tv_sec = (interval / msTos); + time_value.it_value.tv_nsec = (interval % msTos) * msTons; + time_value.it_interval.tv_sec = 0; + time_value.it_interval.tv_nsec = 0; +- +- timer_settime(timerId, 0, &time_value, NULL); ++ ++ const int timeFlag = 0; // 0 表示希望timer首次到期时的时间与启动timer的时间间隔 ++ timer_settime(timerId, timeFlag, &time_value, NULL); + } + +-bool PluginClient::TimerInit(void) ++bool PluginClient::TimerInit(clockid_t id) + { + struct sigevent evp; + int sival = 124; // 传递整型参数,可以自定义 +@@ -1336,130 +1053,122 @@ bool PluginClient::TimerInit(void) + evp.sigev_notify = SIGEV_THREAD; + evp.sigev_notify_function = TimeoutFunc; + +- if (timer_create(CLOCK_REALTIME, &evp, &timerId) == -1) { ++ if (timer_create(id, &evp, &timerId) == -1) { + LOGE("timer create fail\n"); + return false; + } + return true; + } + +-int PluginClient::OpenLockFile(const char *path) ++static bool WaitServer(const string& port) + { +- int portFileFd = -1; +- if (access(path, F_OK) == -1) { +- mode_t mask = umask(0); +- mode_t mode = 0666; +- portFileFd = open(path, O_CREAT | O_RDWR, mode); +- umask(mask); +- } else { +- portFileFd = open(path, O_RDWR); +- } +- +- if (portFileFd == -1) { +- LOGE("open file %s fail\n", path); +- } +- return portFileFd; +-} +- +-void PluginClient::ReadPortsFromLockFile(int fd, string& grpcPorts) +-{ +- int fileLen = lseek(fd, 0, SEEK_END); +- lseek(fd, 0, SEEK_SET); +- char *buf = new char[fileLen + 1]; +- read(fd, buf, fileLen); +- buf[fileLen] = '\0'; +- grpcPorts = buf; +- delete[] buf; +-} +- +-unsigned short PluginClient::FindUnusedPort(void) +-{ +- unsigned short basePort = 40000; // grpc通信端口号从40000开始 +- unsigned short foundPort = 0; // 可以使用的端口号 +- struct sockaddr_in serverAddr; +- memset(&serverAddr, 0, sizeof(serverAddr)); +- serverAddr.sin_family = AF_INET; +- serverAddr.sin_addr.s_addr = inet_addr("0.0.0.0"); +- +- int portFileFd = OpenLockFile(g_portFilePath); +- if (portFileFd == -1) { +- return 0; +- } +- +- flock(portFileFd, LOCK_EX); +- string grpcPorts = ""; +- ReadPortsFromLockFile(portFileFd, grpcPorts); +- +- while (++basePort < UINT16_MAX) { +- int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); +- serverAddr.sin_port = htons(basePort); +- int ret = connect(sock, (struct sockaddr*)&serverAddr, sizeof(serverAddr)); +- if (sock != -1) { +- close(sock); +- } +- if ((ret == -1) && (errno == ECONNREFUSED)) { +- string strPort = std::to_string(basePort) + "\n"; +- if (grpcPorts.find(strPort) == grpcPorts.npos) { +- foundPort = basePort; +- LOGI("found port:%d\n", foundPort); +- lseek(portFileFd, 0, SEEK_END); +- write(portFileFd, strPort.c_str(), strPort.size()); +- break; +- } ++ const int delay = 50; ++ const int cnt = 4000; ++ mode_t mask = umask(0); ++ mode_t mode = 0666; // 权限是rwrwrw,跨进程时,其他用户也要可以访问 ++ string semFile = "wait_server_startup" + port; ++ sem_t *sem = sem_open(semFile.c_str(), O_CREAT, mode, 0); ++ umask(mask); ++ int i = 0; ++ for (; i < cnt; i++) { ++ if (sem_trywait(sem) == 0) { ++ break; ++ } else { ++ usleep(delay); + } + } +- +- if (basePort == UINT16_MAX) { +- ftruncate(portFileFd, 0); +- lseek(portFileFd, 0, SEEK_SET); ++ sem_close(sem); ++ sem_unlink(semFile.c_str()); ++ if (i >= cnt) { ++ return false; + } +- +- close(portFileFd); // 关闭文件fd会同时释放文件锁 +- return foundPort; ++ return true; + } + +-int ServerStart(int timeout, const string& serverPath, pid_t& pid, string& port, const LogPriority logLevel) ++int PluginClient::ServerStart(pid_t& pid) + { +- unsigned short portNum = PluginClient::FindUnusedPort(); +- if (portNum == 0) { ++ if (!grpcPort.FindUnusedPort()) { + LOGE("cannot find port for grpc,port 40001-65535 all used!\n"); + return -1; + } ++ + int ret = 0; +- port = std::to_string(portNum); ++ unsigned short portNum = grpcPort.GetPort(); ++ string port = std::to_string(portNum); + pid = vfork(); + if (pid == 0) { + LOGI("start plugin server!\n"); +- string paramTimeout = std::to_string(timeout); +- if (execl(serverPath.c_str(), paramTimeout.c_str(), port.c_str(), +- std::to_string(logLevel).c_str(), NULL) == -1) { +- PluginClient::DeletePortFromLockFile(portNum); ++ string serverPath = input.GetServerPath(); ++ if (execl(serverPath.c_str(), port.c_str(), std::to_string(input.GetLogLevel()).c_str(), NULL) == -1) { ++ DeleteGrpcPort(); + LOGE("server start fail! please check serverPath:%s\n", serverPath.c_str()); + ret = -1; + _exit(0); + } + } +- int delay = 500000; // 500ms +- usleep(delay); // wait server start + ++ if (!WaitServer(port)) { ++ ret = -1; ++ } + return ret; + } + +-int ClientStart(int timeout, const string& arg, const string& pluginName, const string& port) ++int PluginClient::ClientStart() + { +- string serverPort = "localhost:" + port; +- g_grpcChannel = grpc::CreateChannel(serverPort, grpc::InsecureChannelCredentials()); +- g_plugin = std::make_shared(g_grpcChannel); +- g_plugin->SetInjectFlag(false); +- g_plugin->SetTimeout(timeout); +- g_plugin->SetUserFuncState(STATE_WAIT_BEGIN); +- +- if (!g_plugin->TimerInit()) { +- return 0; ++ setenv("no_grpc_proxy", "localhost", 1); // 关闭localhost的代理,因为server和client运行在同一个机器上,需要通过localhost建立连接 ++ string serverPort = "localhost:" + std::to_string(grpcPort.GetPort()); ++ grpcChannel = grpc::CreateChannel(serverPort, grpc::InsecureChannelCredentials()); ++ serviceStub = PluginService::NewStub(grpcChannel); ++ SetInjectFlag(false); ++ SetUserFuncState(STATE_WAIT_BEGIN); ++ SetStartFlag(true); ++ if (!TimerInit(CLOCK_REALTIME)) { ++ return -1; + } +- unsigned short grpcPort = (unsigned short)atoi(port.c_str()); +- g_plugin->SetGrpcPort(grpcPort); +- g_plugin->ReceiveSendMsg("start", arg); ++ ReceiveSendMsg(grpckey[START], input.GetArgs()); + return 0; + } ++ ++void PluginClient::Init(struct plugin_name_args *pluginInfo, const string& pluginName, pid_t& serverPid) ++{ ++ SetPluginName(pluginName); ++ SetStartFlag(false); ++ ++ // inputCheck模块初始化,并对输入参数进行检查 ++ input.GetInputArgs(pluginInfo); ++ if (input.GetInitInfo() != 0) { ++ LOGD("read default info from pin-gcc-client.json fail! use the default timeout=%dms\n", input.GetTimeout()); ++ } ++ if (input.GetServerPath() == "") { ++ LOGE("server path is NULL!\n"); ++ return; ++ } ++ if (input.CheckSHA256() != 0) { ++ LOGE("sha256 check sha256 file:%s fail!\n", input.GetShaPath().c_str()); ++ return; ++ } else { ++ LOGI("sha256 check success!\n"); ++ } ++ ++ // 查找未使用的端口号,并启动server和client ++ if (ServerStart(serverPid) != 0) { ++ DeleteGrpcPort(); ++ return; ++ } ++ if (ClientStart() != 0) { ++ return; ++ } ++ ++ // 等待用户完成注入点的注册或者server异常退出后,再接着执行gcc编译 ++ int status; ++ while (1) { ++ if ((GetInjectFlag()) || (GetUserFuncState() == STATE_TIMEOUT)) { ++ break; ++ } ++ if (serverPid == waitpid(-1, &status, WNOHANG)) { ++ DeleteGrpcPort(); ++ break; ++ } ++ } ++} + } // namespace PinClient +-- +2.27.0.windows.1 + diff --git a/0003-Refactoring-Code-refactoring-of-Communication-Subsys.patch b/0003-Refactoring-Code-refactoring-of-Communication-Subsys.patch new file mode 100644 index 0000000000000000000000000000000000000000..010ca02a506c4844aee41d38884e182b8e649412 --- /dev/null +++ b/0003-Refactoring-Code-refactoring-of-Communication-Subsys.patch @@ -0,0 +1,839 @@ +From 1e14f9e453c9504cff141ce9059c0eeb405e73ed Mon Sep 17 00:00:00 2001 +From: huitailangzju <804544223@qq.com> +Date: Tue, 7 Feb 2023 19:18:42 +0800 +Subject: [PATCH 3/9] [Refactoring] Code refactoring of Communication Subsystem + [2/3]. Add PluginGrpcPort, PluginInputCheck and PluginJson. + + +diff --git a/lib/PluginClient/PluginGrpcPort.cpp b/lib/PluginClient/PluginGrpcPort.cpp +new file mode 100755 +index 0000000..c6b9a1f +--- /dev/null ++++ b/lib/PluginClient/PluginGrpcPort.cpp +@@ -0,0 +1,159 @@ ++/* Copyright (c) 2022-2022 Huawei Technologies Co., Ltd. ++ ++ This program is free software; you can redistribute it and/or modify it ++ under the terms of the GNU General Public License as published by the ++ Free Software Foundation; either version 3, or (at your option) any ++ later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; see the file COPYING3. If not see ++ . ++ ++ Author: Mingchuan Wu and Yancheng Li ++ Create: 2022-08-18 ++ Description: ++ This file contains the implementation of the PluginGrpcPort class. ++ 主要完成功能:查找未使用的端口号,并将端口号写入到共享文件中,通过文件锁控制多进程间访问,并提供 ++ DeletePortFromLockFile接口在退出时删除写入的端口号 ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "PluginClient/PluginLog.h" ++#include "PluginClient/PluginGrpcPort.h" ++ ++namespace PinClient { ++int PluginGrpcPort::OpenFile(const char *path) ++{ ++ int portFileFd = -1; ++ if (access(path, F_OK) == -1) { ++ mode_t mask = umask(0); ++ mode_t mode = 0666; // 权限是rwrwrw,跨进程时,其他用户也要可以访问 ++ portFileFd = open(path, O_CREAT | O_RDWR, mode); ++ umask(mask); ++ } else { ++ portFileFd = open(path, O_RDWR); ++ } ++ ++ if (portFileFd == -1) { ++ LOGE("open file %s fail\n", path); ++ } ++ return portFileFd; ++} ++ ++bool PluginGrpcPort::ReadPortsFromLockFile(int fd, string& grpcPorts) ++{ ++ if (flock(fd, LOCK_EX) != 0) { ++ return false; ++ } ++ ++ int fileLen = lseek(fd, 0, SEEK_END); ++ lseek(fd, 0, SEEK_SET); ++ char *buf = new char[fileLen + 1]; ++ if (buf == NULL) { ++ return false; ++ } ++ if (read(fd, buf, fileLen) < 0) { ++ return false; ++ } ++ buf[fileLen] = '\0'; ++ grpcPorts = buf; ++ delete[] buf; ++ return true; ++} ++ ++bool PluginGrpcPort::FindUnusedPort() ++{ ++ unsigned short basePort = GetBasePort(); ++ int portFileFd = OpenFile(lockFilePath.c_str()); ++ if (portFileFd == -1) { ++ return false; ++ } ++ ++ string grpcPorts = ""; ++ if (!ReadPortsFromLockFile(portFileFd, grpcPorts)) { ++ close(portFileFd); ++ return false; ++ } ++ ++ // 不使用UINT16_MAX端口号,端口号为UINT16_MAX时作异常处理 ++ while (++basePort < UINT16_MAX) { ++ int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); ++ struct sockaddr_in serverAddr; ++ memset(&serverAddr, 0, sizeof(serverAddr)); ++ serverAddr.sin_family = AF_INET; ++ serverAddr.sin_addr.s_addr = inet_addr("0.0.0.0"); ++ serverAddr.sin_port = htons(basePort); ++ int ret = connect(sock, (struct sockaddr*)&serverAddr, sizeof(serverAddr)); ++ if (sock != -1) { ++ close(sock); ++ } ++ if ((ret == -1) && (errno == ECONNREFUSED)) { ++ string strPort = std::to_string(basePort) + "\n"; ++ if (grpcPorts.find(strPort) == grpcPorts.npos) { ++ port = basePort; ++ LOGI("found port:%d\n", port); ++ lseek(portFileFd, 0, SEEK_END); ++ write(portFileFd, strPort.c_str(), strPort.size()); ++ break; ++ } ++ } ++ } ++ ++ if (basePort == UINT16_MAX) { ++ ftruncate(portFileFd, 0); // 清空锁文件,避免异常未删除释放的端口号,导致无端口使用 ++ lseek(portFileFd, 0, SEEK_SET); ++ close(portFileFd); // 关闭文件fd会同时释放文件锁 ++ return false; ++ } ++ ++ close(portFileFd); // 关闭文件fd会同时释放文件锁 ++ return true; ++} ++ ++bool PluginGrpcPort::DeletePortFromLockFile() ++{ ++ if (port == 0) { ++ return true; ++ } ++ int portFileFd = open(lockFilePath.c_str(), O_RDWR); ++ if (portFileFd == -1) { ++ LOGE("%s open file %s fail\n", __func__, lockFilePath.c_str()); ++ return false; ++ } ++ LOGI("delete port:%d\n", port); ++ ++ string grpcPorts = ""; ++ if (!ReadPortsFromLockFile(portFileFd, grpcPorts)) { ++ close(portFileFd); ++ port = 0; ++ return false; ++ } ++ ++ string portStr = std::to_string(port) + "\n"; ++ string::size_type pos = grpcPorts.find(portStr); ++ if (pos == string::npos) { ++ close(portFileFd); ++ port = 0; ++ return true; ++ } ++ grpcPorts = grpcPorts.erase(pos, portStr.size()); ++ ++ ftruncate(portFileFd, 0); ++ lseek(portFileFd, 0, SEEK_SET); ++ write(portFileFd, grpcPorts.c_str(), grpcPorts.size()); ++ close(portFileFd); ++ port = 0; ++ return true; ++} ++} // namespace PinClient +diff --git a/lib/PluginClient/PluginInputCheck.cpp b/lib/PluginClient/PluginInputCheck.cpp +new file mode 100755 +index 0000000..12cfcdc +--- /dev/null ++++ b/lib/PluginClient/PluginInputCheck.cpp +@@ -0,0 +1,194 @@ ++/* Copyright (c) 2022-2022 Huawei Technologies Co., Ltd. ++ ++ This program is free software; you can redistribute it and/or modify it ++ under the terms of the GNU General Public License as published by the ++ Free Software Foundation; either version 3, or (at your option) any ++ later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; see the file COPYING3. If not see ++ . ++ ++ Author: Mingchuan Wu and Yancheng Li ++ Create: 2022-08-18 ++ Description: ++ This file contains the implementation of the PluginInputCheck class. ++*/ ++ ++#include ++#include "PluginClient/PluginInputCheck.h" ++ ++namespace PinClient { ++// 对server可执行文件进行检查,后续可以在此函数中扩展是否可执行,文件权限等检查 ++int PluginInputCheck::CheckServerFile() ++{ ++ int ret = access(serverPath.c_str(), F_OK); ++ return ret; ++} ++ ++// 对sha256文件进行检查,后续可以在此函数中扩展文件权限、是否为空等检查 ++int PluginInputCheck::CheckShaFile() ++{ ++ int ret = access(shaPath.c_str(), F_OK); ++ return ret; ++} ++ ++bool PluginInputCheck::ReadConfigfile(Json::Value& root) ++{ ++ Json::Reader reader; ++ std::ifstream ifs(configFilePath.c_str()); ++ if (!ifs.is_open()) { ++ LOGW("open %s fail! use default sha256file:%s\n", configFilePath.c_str(), shaPath.c_str()); ++ return false; ++ } ++ ++ if (!reader.parse(ifs, root)) { ++ printf("parse %s fail! check the file format!\n", configFilePath.c_str()); ++ ifs.close(); ++ return false; ++ } ++ ++ ifs.close(); ++ return true; ++} ++ ++void PluginInputCheck::SetTimeout(int time) ++{ ++ const int timeoutMin = 50; ++ const int timeoutMax = 5000; ++ if ((time >= timeoutMin) && (time <= timeoutMax)) { // 不在50~5000ms范围内,使用默认值 ++ timeout = time; ++ LOGI("the timeout is:%d\n", timeout); ++ return; ++ } ++ LOGW("SetTimeout:%d,should be 50~5000,use default:%d\n", time, timeout); ++} ++ ++int PluginInputCheck::GetInitInfo() ++{ ++ Json::Value root; ++ if (!ReadConfigfile(root)) { ++ return -1; ++ } ++ ++ if (serverPath == "") { ++ if (root[jsonkey[PATH]].isString()) { ++ serverPath = root[jsonkey[PATH]].asString(); ++ } else { ++ LOGW("serverPath in config.json is not string!\n"); ++ } ++ } ++ if (CheckServerFile() != 0) { ++ LOGE("serverPath:%s not exist!\n", serverPath.c_str()); ++ serverPath = ""; ++ return -1; ++ } ++ ++ if (root[jsonkey[TIMEOUT]].isInt()) { ++ int timeoutJson = root[jsonkey[TIMEOUT]].asInt(); ++ SetTimeout(timeoutJson); ++ } ++ ++ if (root[jsonkey[SHA256]].isString()) { ++ shaPath = root[jsonkey[SHA256]].asString(); ++ } else { ++ LOGW("sha256file int config.json is not string!\n"); ++ } ++ ++ if ((shaPath == "") || (CheckShaFile() != 0)) { ++ shaPath = GetServerDir() + shaFile; // sha256文件默认和server在同一目录 ++ LOGW("sha256 file not found,use default:%s\n", shaPath.c_str()); ++ } ++ return 0; ++} ++ ++std::map g_keyMap { ++ {"server_path", KEY_SERVER_PATH}, ++ {"log_level", KEY_LOG_LEVEL}, ++}; ++void PluginInputCheck::GetInputArgs(struct plugin_name_args *pluginInfo) ++{ ++ Json::Value root; ++ map compileArgs; ++ ++ for (int i = 0; i < pluginInfo->argc; i++) { ++ string key = pluginInfo->argv[i].key; ++ int keyTag = -1; ++ auto it = g_keyMap.find(key); ++ if (it != g_keyMap.end()) { ++ keyTag = it->second; ++ } ++ switch (keyTag) { ++ case KEY_SERVER_PATH: ++ serverPath = pluginInfo->argv[i].value; ++ if (serverPath != "") { ++ configFilePath = GetServerDir() + "/pin-gcc-client.json"; // 配置文件和server在同一目录 ++ shaPath = GetServerDir() + shaFile; // sha256文件默认和server在同一目录 ++ } ++ break; ++ case KEY_LOG_LEVEL: ++ logLevel = (LogPriority)atoi(pluginInfo->argv[i].value); ++ SetLogPriority(logLevel); ++ break; ++ default: ++ string value = pluginInfo->argv[i].value; ++ compileArgs[key] = value; ++ root[key] = value; ++ break; ++ } ++ } ++ ++ args = root.toStyledString(); ++ for (auto it = compileArgs.begin(); it != compileArgs.end(); it++) { ++ CheckSafeCompileFlag(it->first, it->second); ++ } ++} ++ ++int PluginInputCheck::CheckSHA256() ++{ ++ if (shaPath == "") { ++ LOGE("sha256file Path is NULL!\n"); ++ return -1; ++ } ++ int index = shaPath.find_last_of("/"); ++ string dir = shaPath.substr(0, index); ++ string filename = shaPath.substr(index+1, -1); ++ ++ string cmd = "cd " + dir + " && " + "sha256sum -c " + filename + " --quiet"; ++ int ret = system(cmd.c_str()); ++ return ret; ++} ++ ++void PluginInputCheck::CheckSafeCompileFlag(const string& argName, const string& param) ++{ ++ for (auto& compileFlag : safeCompileFlags) { ++ if (param.find(compileFlag) != string::npos) { ++ LOGW("%s:%s have safe compile parameter:%s !!!\n", argName.c_str(), param.c_str(), compileFlag.c_str()); ++ } ++ } ++} ++ ++PluginInputCheck::PluginInputCheck() ++{ ++ shaPath = ""; ++ serverPath = ""; ++ logLevel = PRIORITY_WARN; ++ timeout = 200; // 默认超时时间200ms ++ SetConfigPath("/usr/local/bin/pin-gcc-client.json"); ++ safeCompileFlags.push_back("-z noexecstack"); ++ safeCompileFlags.push_back("-fno-stack-protector"); ++ safeCompileFlags.push_back("-fstack-protector-all"); ++ safeCompileFlags.push_back("-D_FORTIFY_SOURCE"); ++ safeCompileFlags.push_back("-fPic"); ++ safeCompileFlags.push_back("-fPIE"); ++ safeCompileFlags.push_back("-fstack-protector-strong"); ++ safeCompileFlags.push_back("-fvisibility"); ++ safeCompileFlags.push_back("-ftrapv"); ++ safeCompileFlags.push_back("-fstack-check"); ++} ++} // namespace PinClient +diff --git a/lib/PluginClient/PluginJson.cpp b/lib/PluginClient/PluginJson.cpp +new file mode 100755 +index 0000000..22cd489 +--- /dev/null ++++ b/lib/PluginClient/PluginJson.cpp +@@ -0,0 +1,458 @@ ++/* Copyright (c) 2022-2022 Huawei Technologies Co., Ltd. ++ ++ This program is free software; you can redistribute it and/or modify it ++ under the terms of the GNU General Public License as published by the ++ Free Software Foundation; either version 3, or (at your option) any ++ later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; see the file COPYING3. If not see ++ . ++ ++ Author: Mingchuan Wu and Yancheng Li ++ Create: 2022-08-18 ++ Description: ++ This file contains the implementation of the PluginJson class. ++*/ ++ ++#include ++#include "PluginAPI/PluginClientAPI.h" ++#include "PluginClient/PluginLog.h" ++#include "PluginClient/PluginJson.h" ++ ++namespace PinClient { ++using std::map; ++using namespace mlir::Plugin; ++using namespace mlir; ++ ++static uintptr_t GetID(Json::Value node) ++{ ++ string id = node.asString(); ++ return atol(id.c_str()); ++} ++ ++Json::Value PluginJson::TypeJsonSerialize(PluginIR::PluginTypeBase& type) ++{ ++ Json::Value root; ++ Json::Value operationObj; ++ Json::Value item; ++ ++ uint64_t ReTypeId; ++ uint64_t ReTypeWidth; ++ ++ ReTypeId = static_cast(type.getPluginTypeID()); ++ item["id"] = std::to_string(ReTypeId); ++ ++ if (auto elemTy = type.dyn_cast()) { ++ auto baseTy = elemTy.getElementType().dyn_cast(); ++ item["elementType"] = TypeJsonSerialize(baseTy); ++ if (elemTy.isReadOnlyElem()) { ++ item["elemConst"] = "1"; ++ } else { ++ item["elemConst"] = "0"; ++ } ++ } ++ ++ if (type.getPluginIntOrFloatBitWidth() != 0) { ++ ReTypeWidth = type.getPluginIntOrFloatBitWidth(); ++ item["width"] = std::to_string(ReTypeWidth); ++ } ++ ++ if (type.isSignedPluginInteger()) { ++ item["signed"] = "1"; ++ } ++ ++ if (type.isUnsignedPluginInteger()) { ++ item["signed"] = "0"; ++ } ++ ++ root["type"] = item; ++ return root; ++} ++ ++PluginIR::PluginTypeBase PluginJson::TypeJsonDeSerialize(const string& data, mlir::MLIRContext &context) ++{ ++ Json::Value root; ++ Json::Reader reader; ++ Json::Value node; ++ reader.parse(data, root); ++ ++ PluginIR::PluginTypeBase baseType; ++ ++ Json::Value type = root["type"]; ++ uint64_t id = GetID(type["id"]); ++ PluginIR::PluginTypeID PluginTypeId = static_cast(id); ++ ++ if (type["signed"] && (id >= static_cast(PluginIR::UIntegerTy1ID) ++ && id <= static_cast(PluginIR::IntegerTy64ID))) { ++ string s = type["signed"].asString(); ++ uint64_t width = GetID(type["width"]); ++ if (s == "1") { ++ baseType = PluginIR::PluginIntegerType::get(&context, width, PluginIR::PluginIntegerType::Signed); ++ } else { ++ baseType = PluginIR::PluginIntegerType::get(&context, width, PluginIR::PluginIntegerType::Unsigned); ++ } ++ } else if (type["width"] && (id == static_cast(PluginIR::FloatTyID) ++ || id == static_cast(PluginIR::DoubleTyID))) { ++ uint64_t width = GetID(type["width"]); ++ baseType = PluginIR::PluginFloatType::get(&context, width); ++ } else if (id == static_cast(PluginIR::PointerTyID)) { ++ mlir::Type elemTy = TypeJsonDeSerialize(type["elementType"].toStyledString(), context); ++ baseType = PluginIR::PluginPointerType::get(&context, elemTy, type["elemConst"].asString() == "1" ? 1 : 0); ++ } else { ++ if (PluginTypeId == PluginIR::VoidTyID) { ++ baseType = PluginIR::PluginVoidType::get(&context); ++ } ++ if (PluginTypeId == PluginIR::BooleanTyID) { ++ baseType = PluginIR::PluginBooleanType::get(&context); ++ } ++ if (PluginTypeId == PluginIR::UndefTyID) { ++ baseType = PluginIR::PluginUndefType::get(&context); ++ } ++ } ++ ++ return baseType; ++} ++ ++void PluginJson::FunctionOpJsonSerialize(vector& data, string& out) ++{ ++ Json::Value root; ++ Json::Value operationObj; ++ Json::Value item; ++ ++ int i = 0; ++ string operation; ++ ++ for (auto& d: data) { ++ item["id"] = std::to_string(d.idAttr().getInt()); ++ if (d.declaredInlineAttr().getValue()) { ++ item["attributes"]["declaredInline"] = "1"; ++ } else { ++ item["attributes"]["declaredInline"] = "0"; ++ } ++ item["attributes"]["funcName"] = d.funcNameAttr().getValue().str().c_str(); ++ auto ®ion = d.getRegion(); ++ size_t bbIdx = 0; ++ for (auto &b : region) { ++ string blockStr = "block" + std::to_string(bbIdx++); ++ uint64_t bbAddress = 0; ++ size_t opIdx = 0; ++ for (auto &inst : b) { ++ if (isa(inst)) { ++ continue; ++ } else if (isa(inst)) { ++ continue; ++ } else if (isa(inst)) { ++ continue; ++ } else if (isa(inst)) { ++ continue; ++ } ++ string opStr = "Operation" + std::to_string(opIdx++); ++ item["region"][blockStr]["ops"][opStr] = OperationJsonSerialize(&inst, bbAddress); ++ } ++ assert(bbAddress != 0); ++ item["region"][blockStr]["address"] = std::to_string(bbAddress); ++ } ++ operation = "FunctionOp" + std::to_string(i++); ++ root[operation] = item; ++ item.clear(); ++ } ++ out = root.toStyledString(); ++} ++ ++Json::Value PluginJson::OperationJsonSerialize(mlir::Operation *operation, uint64_t &bbId) ++{ ++ Json::Value root; ++ if (AssignOp op = llvm::dyn_cast(operation)) { ++ root = AssignOpJsonSerialize(op); ++ } else if (CallOp op = llvm::dyn_cast(operation)) { ++ root = CallOpJsonSerialize(op); ++ } else if (CondOp op = llvm::dyn_cast(operation)) { ++ root = CondOpJsonSerialize(op, bbId); ++ } else if (PhiOp op = llvm::dyn_cast(operation)) { ++ root = PhiOpJsonSerialize(op); ++ } else if (FallThroughOp op = llvm::dyn_cast(operation)) { ++ root = FallThroughOpJsonSerialize(op, bbId); ++ } else if (RetOp op = llvm::dyn_cast(operation)) { ++ root = RetOpJsonSerialize(op, bbId); ++ } else if (BaseOp op = llvm::dyn_cast(operation)) { ++ root = BaseOpJsonSerialize(op); ++ } ++ root["OperationName"] = operation->getName().getStringRef().str(); ++ return root; ++} ++ ++Json::Value PluginJson::BaseOpJsonSerialize(BaseOp data) ++{ ++ Json::Value root; ++ root["id"] = std::to_string(data.idAttr().getInt()); ++ root["opCode"] = data.opCodeAttr().getValue().str().c_str(); ++ return root; ++} ++ ++Json::Value PluginJson::RetOpJsonSerialize(RetOp data, uint64_t &bbId) ++{ ++ Json::Value root; ++ bbId = data.addressAttr().getInt(); ++ root["address"] = std::to_string(bbId); ++ return root; ++} ++ ++Json::Value PluginJson::FallThroughOpJsonSerialize(FallThroughOp data, uint64_t &bbId) ++{ ++ Json::Value root; ++ bbId = data.addressAttr().getInt(); ++ root["address"] = std::to_string(bbId); ++ root["destaddr"] = std::to_string(data.destaddrAttr().getInt()); ++ return root; ++} ++ ++void PluginJson::LocalDeclsJsonSerialize(vector& decls, string& out) ++{ ++ Json::Value root; ++ Json::Value operationObj; ++ Json::Value item; ++ int i = 0; ++ string operation; ++ ++ for (auto& decl: decls) { ++ item["id"] = std::to_string(decl.idAttr().getInt()); ++ item["attributes"]["symName"] = decl.symNameAttr().getValue().str().c_str(); ++ item["attributes"]["typeID"] = decl.typeIDAttr().getInt(); ++ item["attributes"]["typeWidth"] = decl.typeWidthAttr().getInt(); ++ operation = "localDecl" + std::to_string(i++); ++ root[operation] = item; ++ item.clear(); ++ } ++ out = root.toStyledString(); ++} ++ ++void PluginJson::LoopOpsJsonSerialize(vector& loops, string& out) ++{ ++ Json::Value root; ++ Json::Value operationObj; ++ Json::Value item; ++ int i = 0; ++ string operation; ++ ++ for (auto& loop: loops) { ++ item["id"] = std::to_string(loop.idAttr().getInt()); ++ item["index"] = std::to_string(loop.indexAttr().getInt()); ++ item["attributes"]["innerLoopId"] = std::to_string(loop.innerLoopIdAttr().getInt()); ++ item["attributes"]["outerLoopId"] = std::to_string(loop.outerLoopIdAttr().getInt()); ++ item["attributes"]["numBlock"] = std::to_string(loop.numBlockAttr().getInt()); ++ operation = "loopOp" + std::to_string(i++); ++ root[operation] = item; ++ item.clear(); ++ } ++ out = root.toStyledString(); ++} ++ ++void PluginJson::LoopOpJsonSerialize(mlir::Plugin::LoopOp& loop, string& out) ++{ ++ Json::Value root; ++ root["id"] = std::to_string(loop.idAttr().getInt()); ++ root["index"] = std::to_string(loop.indexAttr().getInt()); ++ root["attributes"]["innerLoopId"] = std::to_string(loop.innerLoopIdAttr().getInt()); ++ root["attributes"]["outerLoopId"] = std::to_string(loop.outerLoopIdAttr().getInt()); ++ root["attributes"]["numBlock"] = std::to_string(loop.numBlockAttr().getInt()); ++ out = root.toStyledString(); ++} ++ ++void PluginJson::BlocksJsonSerialize(vector& blocks, string& out) ++{ ++ Json::Value root; ++ Json::Value item; ++ int i = 0; ++ string index; ++ ++ for (auto& block : blocks) { ++ item["id"] = std::to_string(block); ++ index = "block" + std::to_string(i++); ++ root[index] = item; ++ item.clear(); ++ } ++ out = root.toStyledString(); ++} ++ ++void PluginJson::EdgesJsonSerialize(vector >& edges, string& out) ++{ ++ Json::Value root; ++ Json::Value item; ++ int i = 0; ++ string index; ++ ++ for (auto& edge : edges) { ++ item["src"] = std::to_string(edge.first); ++ item["dest"] = std::to_string(edge.second); ++ index = "edge" + std::to_string(i++); ++ root[index] = item; ++ item.clear(); ++ } ++ out = root.toStyledString(); ++} ++ ++void PluginJson::EdgeJsonSerialize(std::pair& edge, string& out) ++{ ++ Json::Value root; ++ root["src"] = std::to_string(edge.first); ++ root["dest"] = std::to_string(edge.second); ++ out = root.toStyledString(); ++} ++ ++// void类型的Json序列化 ++void PluginJson::NopJsonSerialize(string& out) ++{ ++ Json::Value root; ++ out = root.toStyledString(); ++} ++ ++void PluginJson::GetPhiOpsJsonSerialize(vector phiOps, string & out) ++{ ++ Json::Value root; ++ Json::Value item; ++ int i = 0; ++ string operation; ++ uint64_t placeholder = 0; ++ for (auto phi : phiOps) { ++ item = OperationJsonSerialize(phi.getOperation(), placeholder); ++ operation = "operation" + std::to_string(i++); ++ root[operation] = item; ++ item.clear(); ++ } ++ out = root.toStyledString(); ++} ++ ++Json::Value PluginJson::CallOpJsonSerialize(CallOp& data) ++{ ++ Json::Value item; ++ item["id"] = std::to_string(data.idAttr().getInt()); ++ item["callee"] = data.callee().str(); ++ item["OperationName"] = data.getOperation()->getName().getStringRef().str(); ++ size_t opIdx = 0; ++ for (mlir::Value v : data.getArgOperands()) { ++ string input = "input" + std::to_string(opIdx++); ++ item["operands"][input] = ValueJsonSerialize(v); ++ } ++ ++ return item; ++} ++ ++Json::Value PluginJson::CondOpJsonSerialize(CondOp& data, uint64_t &bbId) ++{ ++ Json::Value item; ++ item["id"] = std::to_string(data.idAttr().getInt()); ++ item["condCode"] = std::to_string(data.condCodeAttr().getInt()); ++ item["lhs"] = ValueJsonSerialize(data.GetLHS()); ++ item["rhs"] = ValueJsonSerialize(data.GetRHS()); ++ bbId = data.addressAttr().getInt(); ++ item["address"] = std::to_string(bbId); ++ item["tbaddr"] = std::to_string(data.tbaddrAttr().getInt()); ++ item["fbaddr"] = std::to_string(data.fbaddrAttr().getInt()); ++ return item; ++} ++ ++Json::Value PluginJson::PhiOpJsonSerialize(PhiOp& data) ++{ ++ Json::Value item; ++ item["id"] = std::to_string(data.idAttr().getInt()); ++ item["capacity"] = std::to_string(data.capacityAttr().getInt()); ++ item["nArgs"] = std::to_string(data.nArgsAttr().getInt()); ++ item["OperationName"] = data.getOperation()->getName().getStringRef().str(); ++ size_t opIdx = 0; ++ for (mlir::Value v : data.operands()) { ++ string input = "input" + std::to_string(opIdx++); ++ item["operands"][input] = ValueJsonSerialize(v); ++ } ++ ++ return item; ++} ++ ++Json::Value PluginJson::SSAOpJsonSerialize(SSAOp& data) ++{ ++ Json::Value item; ++ item["id"] = std::to_string(data.idAttr().getInt()); ++ item["defCode"] = std::to_string(data.defCodeAttr().getInt()); ++ item["readOnly"] = std::to_string(data.readOnlyAttr().getValue()); ++ item["nameVarId"] = std::to_string(data.nameVarIdAttr().getInt()); ++ item["ssaParmDecl"] = std::to_string(data.ssaParmDeclAttr().getInt()); ++ item["version"] = std::to_string(data.versionAttr().getInt()); ++ item["definingId"] = std::to_string(data.definingIdAttr().getInt()); ++ auto retTy = data.getResultType().dyn_cast(); ++ item["retType"] = TypeJsonSerialize(retTy); ++ return item; ++} ++ ++Json::Value PluginJson::AssignOpJsonSerialize(AssignOp& data) ++{ ++ Json::Value item; ++ item["id"] = std::to_string(data.idAttr().getInt()); ++ item["exprCode"] = std::to_string(data.exprCodeAttr().getInt()); ++ item["OperationName"] = data.getOperation()->getName().getStringRef().str(); ++ size_t opIdx = 0; ++ for (mlir::Value v : data.operands()) { ++ string input = "input" + std::to_string(opIdx++); ++ item["operands"][input] = ValueJsonSerialize(v); ++ } ++ ++ return item; ++} ++ ++Json::Value PluginJson::ValueJsonSerialize(mlir::Value data) ++{ ++ Json::Value root; ++ if (ConstOp cOp = data.getDefiningOp()) { ++ auto retTy = data.getType().dyn_cast(); ++ root["retType"] = TypeJsonSerialize(retTy); ++ root["id"] = std::to_string(cOp.idAttr().getInt()); ++ root["defCode"] = std::to_string(static_cast(IDefineCode::IntCST)); ++ root["value"] = std::to_string(cOp.initAttr().cast().getInt()); ++ } else if (MemOp mOp = data.getDefiningOp()) { ++ root = MemOpJsonSerialize(mOp); ++ } else if (SSAOp sOp = data.getDefiningOp()) { ++ root = SSAOpJsonSerialize(sOp); ++ } else if (PlaceholderOp phOp = data.getDefiningOp()) { ++ root["id"] = std::to_string(phOp.idAttr().getInt()); ++ root["defCode"] = std::to_string(phOp.defCodeAttr().getInt()); ++ auto retTy = phOp.getResultType().dyn_cast(); ++ root["retType"] = TypeJsonSerialize(retTy); ++ } else { ++ LOGE("ERROR: Can't Serialize!"); ++ } ++ return root; ++} ++ ++Json::Value PluginJson::MemOpJsonSerialize(MemOp& data) ++{ ++ Json::Value root; ++ root["id"] = std::to_string(data.idAttr().getInt()); ++ root["defCode"] = std::to_string(data.defCodeAttr().getInt()); ++ root["readOnly"] = std::to_string(data.readOnlyAttr().getValue()); ++ mlir::Value base = data.GetBase(); ++ mlir::Value offset = data.GetOffset(); ++ root["base"] = ValueJsonSerialize(base); ++ root["offset"] = ValueJsonSerialize(offset); ++ auto retTy = data.getResultType().dyn_cast(); ++ root["retType"] = TypeJsonSerialize(retTy); ++ return root; ++} ++ ++void PluginJson::IntegerSerialize(int64_t data, string& out) ++{ ++ Json::Value root; ++ root["integerData"] = data; ++ out = root.toStyledString(); ++} ++ ++void PluginJson::StringSerialize(const string& data, string& out) ++{ ++ Json::Value root; ++ root["stringData"] = data; ++ out = root.toStyledString(); ++} ++} // namespace PinClient +-- +2.27.0.windows.1 + diff --git a/0004-Refactoring-Code-refactoring-of-Communication-Subsys.patch b/0004-Refactoring-Code-refactoring-of-Communication-Subsys.patch new file mode 100644 index 0000000000000000000000000000000000000000..9492f1d1bd4ec40fa2911896ed4c8545432d319c --- /dev/null +++ b/0004-Refactoring-Code-refactoring-of-Communication-Subsys.patch @@ -0,0 +1,2397 @@ +From 62597c33d89c967f7d4a4255699cd12a91b42a91 Mon Sep 17 00:00:00 2001 +From: Mingchuan Wu +Date: Tue, 7 Feb 2023 19:38:52 +0800 +Subject: [PATCH 4/9] [Refactoring] Code refactoring of Communication Subsystem + [3/3]. Code refactoring of communication subsystem. + + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index d688fdf..fcd737b 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -89,9 +89,12 @@ add_subdirectory(include) + add_subdirectory(lib) + + add_library(pin_gcc_client SHARED ++ "lib/gccPlugin/gccPlugin.cpp" + "lib/PluginClient/PluginLog.cpp" ++ "lib/PluginClient/PluginJson.cpp" ++ "lib/PluginClient/PluginInputCheck.cpp" ++ "lib/PluginClient/PluginGrpcPort.cpp" + "lib/PluginClient/PluginClient.cpp" +- "lib/IRTrans/IRTransPlugin.cpp" + ) + + target_link_libraries(pin_gcc_client +diff --git a/configs/pin-gcc-client.json b/configs/pin-gcc-client.json +index 390f8bf..bd0ff0c 100755 +--- a/configs/pin-gcc-client.json ++++ b/configs/pin-gcc-client.json +@@ -1,10 +1,10 @@ + { +- //server路径 ++ "//" : "server路径", + "path" : "/usr/local/bin/pin_server", + +- //libuser.so sha256文件名 ++ "//" : "libuser.so sha256文件名", + "sha256file" : "/usr/local/lib/libpin_user.sha256", + +- //超时时间,单位ms +- "timeout" : 200, ++ "//" : "超时时间,单位ms", ++ "timeout" : 200 + } +\ No newline at end of file +diff --git a/include/Dialect/PluginDialect.h b/include/Dialect/PluginDialect.h +index c5d3ad8..8cdb593 100644 +--- a/include/Dialect/PluginDialect.h ++++ b/include/Dialect/PluginDialect.h +@@ -16,11 +16,11 @@ + + + */ +-//===----------------------------------------------------------------------===// +-// ++// ===----------------------------------------------------------------------===// ++// + // This is the header file for the Plugin dialect. + // +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + + #ifndef PLUGIN_DIALECT_H + #define PLUGIN_DIALECT_H +diff --git a/include/Dialect/PluginOps.h b/include/Dialect/PluginOps.h +index 25089fe..a2fb310 100644 +--- a/include/Dialect/PluginOps.h ++++ b/include/Dialect/PluginOps.h +@@ -16,11 +16,11 @@ + + + */ +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // +-// This is the header file for operations in Plugin dialect. ++// This is the header file for operations in Plugin dialect. + // +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + + #ifndef Plugin_OPS_H + #define Plugin_OPS_H +diff --git a/include/Dialect/PluginTypes.h b/include/Dialect/PluginTypes.h +index 60ba258..157b868 100644 +--- a/include/Dialect/PluginTypes.h ++++ b/include/Dialect/PluginTypes.h +@@ -74,13 +74,13 @@ private: + unsigned size; + }; // class PluginTypeBase + +-namespace detail { ++namespace Detail { + struct PluginIntegerTypeStorage; + struct PluginFloatTypeStorage; + struct PluginPointerTypeStorage; + } + +-class PluginIntegerType : public Type::TypeBase { ++class PluginIntegerType : public Type::TypeBase { + public: + using Base::Base; + +@@ -104,7 +104,7 @@ public: + SignednessSemantics getSignedness() const; + }; + +-class PluginFloatType : public Type::TypeBase { ++class PluginFloatType : public Type::TypeBase { + public: + using Base::Base; + +@@ -115,7 +115,7 @@ public: + unsigned getWidth() const; + }; + +-class PluginPointerType : public Type::TypeBase { ++class PluginPointerType : public Type::TypeBase { + public: + using Base::Base; + +@@ -133,7 +133,6 @@ public: + using Base::Base; + + PluginTypeID getPluginTypeID (); +- + }; // class PluginVoidType + + class PluginUndefType : public Type::TypeBase { +@@ -141,7 +140,6 @@ public: + using Base::Base; + + PluginTypeID getPluginTypeID (); +- + }; // class PluginUndefType + + class PluginBooleanType : public Type::TypeBase { +@@ -149,7 +147,6 @@ public: + using Base::Base; + + PluginTypeID getPluginTypeID (); +- + }; // class PluginBooleanType + + } // namespace PluginIR +diff --git a/include/PluginAPI/BasicPluginOpsAPI.h b/include/PluginAPI/BasicPluginOpsAPI.h +index 5eb1eed..8c47c58 100644 +--- a/include/PluginAPI/BasicPluginOpsAPI.h ++++ b/include/PluginAPI/BasicPluginOpsAPI.h +@@ -43,6 +43,12 @@ public: + BasicPluginOpsAPI() = default; + virtual ~BasicPluginOpsAPI() = default; + ++ virtual string GetDeclSourceFile(uint64_t gccDataAddr) = 0; ++ virtual string VariableName(int64_t gccDataAddr) = 0; ++ virtual string FuncName(int64_t gccDataAddr) = 0; ++ virtual int GetDeclSourceLine(uint64_t gccDataAddr) = 0; ++ virtual int GetDeclSourceColumn(uint64_t gccDataAddr) = 0; ++ + virtual uint64_t CreateBlock(uint64_t, uint64_t) = 0; + virtual void DeleteBlock(uint64_t, uint64_t) = 0; + virtual void SetImmediateDominator(uint64_t, uint64_t, uint64_t) = 0; +diff --git a/include/PluginAPI/PluginClientAPI.h b/include/PluginAPI/PluginClientAPI.h +index cb81986..07d6e52 100644 +--- a/include/PluginAPI/PluginClientAPI.h ++++ b/include/PluginAPI/PluginClientAPI.h +@@ -33,6 +33,12 @@ public: + PluginClientAPI () = default; + ~PluginClientAPI () = default; + ++ string GetDeclSourceFile(uint64_t gccDataAddr) override; ++ string VariableName(int64_t gccDataAddr) override; ++ string FuncName(int64_t gccDataAddr) override; ++ int GetDeclSourceLine(uint64_t gccDataAddr) override; ++ int GetDeclSourceColumn(uint64_t gccDataAddr) override; ++ + uint64_t CreateBlock(uint64_t, uint64_t) override; + void DeleteBlock(uint64_t, uint64_t) override; + void SetImmediateDominator(uint64_t, uint64_t, uint64_t) override; +diff --git a/include/PluginClient/GrpcKey.def b/include/PluginClient/GrpcKey.def +new file mode 100755 +index 0000000..f996544 +--- /dev/null ++++ b/include/PluginClient/GrpcKey.def +@@ -0,0 +1,6 @@ ++/* Definition of GRPC key name */ ++ ++GRPC_KEY(START, "start") ++GRPC_KEY(STOP, "stop") ++GRPC_KEY(USERFUNC, "userFunc") ++GRPC_KEY(INJECT, "injectPoint") +diff --git a/include/PluginClient/GrpcValue.def b/include/PluginClient/GrpcValue.def +new file mode 100755 +index 0000000..d9b391b +--- /dev/null ++++ b/include/PluginClient/GrpcValue.def +@@ -0,0 +1,6 @@ ++/* Definition of GRPC value */ ++ ++GRPC_VALUE(START_VALUE, "ok") ++GRPC_VALUE(STOP_VALUE, "ok") ++GRPC_VALUE(USERFUNC_VALUE, "execution completed") ++GRPC_VALUE(FINISH_VALUE, "finished") +diff --git a/include/PluginClient/JsonKey.def b/include/PluginClient/JsonKey.def +new file mode 100755 +index 0000000..adbd27e +--- /dev/null ++++ b/include/PluginClient/JsonKey.def +@@ -0,0 +1,5 @@ ++/* Definition of JsonKey */ ++ ++JSON_KEY(PATH, "path") ++JSON_KEY(SHA256, "sha256file") ++JSON_KEY(TIMEOUT, "timeout") +diff --git a/include/PluginClient/PassValue.def b/include/PluginClient/PassValue.def +new file mode 100755 +index 0000000..b9090ea +--- /dev/null ++++ b/include/PluginClient/PassValue.def +@@ -0,0 +1,5 @@ ++/* Definition of PASS value */ ++ ++PASS_VALUE(PASS_NAME, "refPassName") ++PASS_VALUE(PASS_NUM, "passNum") ++PASS_VALUE(PASS_POSITION, "passPosition") +diff --git a/include/PluginClient/PluginClient.h b/include/PluginClient/PluginClient.h +index a0137b5..89d7573 100644 +--- a/include/PluginClient/PluginClient.h ++++ b/include/PluginClient/PluginClient.h +@@ -18,35 +18,26 @@ + Create: 2022-08-18 + Description: + This file contains the declaration of the PluginClient class. ++ 主要完成功能:完成和server之间grpc通信及数据解析,获取gcc插件数据并进行IR转换,完成 ++ gcc注册点注入及参数保存。提供GetInstance获取client对象唯一实例,完成插件初始化并启动 ++ server子进程,处理超时异常事件 + */ + + #ifndef PLUGIN_CLIENT_H + #define PLUGIN_CLIENT_H + +-#include +-#include +-#include +-#include +-#include +-#include +- + #include "Dialect/PluginOps.h" + #include "Dialect/PluginTypes.h" + #include + #include "plugin.grpc.pb.h" +-#include "gcc-plugin.h" + #include "PluginAPI/PluginClientAPI.h" ++#include "PluginClient/PluginGrpcPort.h" ++#include "PluginClient/PluginInputCheck.h" ++#include "PluginClient/PluginJson.h" + #include "PluginClient/PluginLog.h" + #include "Dialect/PluginDialect.h" + + namespace PinClient { +-using std::cout; +-using std::string; +-using std::endl; +-using std::vector; +-using std::map; +-using std::pair; +- + using plugin::PluginService; + using grpc::Channel; + using grpc::ClientContext; +@@ -55,6 +46,45 @@ using grpc::Status; + using plugin::ClientMsg; + using plugin::ServerMsg; + ++enum Grpckey { ++#define GRPC_KEY(KEY, NAME) KEY, ++#include "GrpcKey.def" ++#undef GRPC_KEY ++MAX_GRPC_KEYS ++}; ++ ++#define GRPC_KEY(KEY, NAME) NAME, ++const char *const grpckey[] = { ++#include "GrpcKey.def" ++}; ++#undef GRPC_KEY ++ ++enum GrpcValue { ++#define GRPC_VALUE(KEY, NAME) KEY, ++#include "GrpcValue.def" ++#undef GRPC_VALUE ++MAX_GRPC_VALUES ++}; ++ ++#define GRPC_VALUE(KEY, NAME) NAME, ++const char *const grpcValue[] = { ++#include "GrpcValue.def" ++}; ++#undef GRPC_VALUE ++ ++enum PassValue { ++#define PASS_VALUE(KEY, NAME) KEY, ++#include "PassValue.def" ++#undef PASS_VALUE ++MAX_PASS_VALUES ++}; ++ ++#define PASS_VALUE(KEY, NAME) NAME, ++const char *const passValue[] = { ++#include "PassValue.def" ++}; ++#undef PASS_VALUE ++ + enum InjectPoint : uint8_t { + HANDLE_PARSE_TYPE = 0, + HANDLE_PARSE_DECL, +@@ -68,8 +98,10 @@ enum InjectPoint : uint8_t { + HANDLE_AFTER_ALL_PASS, + HANDLE_COMPILE_END, + HANDLE_MANAGER_SETUP, ++ HANDLE_INCLUDE_FILE, + HANDLE_MAX, + }; ++ + typedef enum { + STATE_WAIT_BEGIN = 0, + STATE_BEGIN, +@@ -101,50 +133,17 @@ struct ManagerSetupData { + + class PluginClient { + public: +- PluginClient() = default; +- ~PluginClient() = default; +- PluginClient(std::shared_ptr channel) : serviceStub(PluginService::NewStub(channel)) {} + /* 定义的grpc服务端和客户端通信的接口函数 */ + void ReceiveSendMsg(const string& attribute, const string& value); + /* 获取client对象实例,有且只有一个实例对象 */ +- static std::shared_ptr GetInstance(void); +- void OpJsonSerialize(vector& data, string& out); +- void LoopOpsJsonSerialize(vector& loops, string& out); +- void LoopOpJsonSerialize(mlir::Plugin::LoopOp& loop, string& out); +- void BlocksJsonSerialize(vector&, string&); +- void EdgesJsonSerialize(vector >&, string&); +- void EdgeJsonSerialize(pair&, string&); +- void NopJsonSerialize(string&); +- void FunctionOpJsonSerialize(vector& data, string& out); +- void LocalDeclsJsonSerialize(vector& decls, string& out); +- void GetPhiOpsJsonSerialize(vector phiOps, string& out); +- Json::Value OperationJsonSerialize(mlir::Operation *, uint64_t&); +- Json::Value CallOpJsonSerialize(mlir::Plugin::CallOp& data); +- Json::Value CondOpJsonSerialize(mlir::Plugin::CondOp& data, uint64_t&); +- Json::Value PhiOpJsonSerialize(mlir::Plugin::PhiOp& data); +- Json::Value AssignOpJsonSerialize(mlir::Plugin::AssignOp& data); +- Json::Value BaseOpJsonSerialize(mlir::Plugin::BaseOp data); +- Json::Value FallThroughOpJsonSerialize(mlir::Plugin::FallThroughOp data, uint64_t&); +- Json::Value RetOpJsonSerialize(mlir::Plugin::RetOp data, uint64_t&); +- Json::Value ValueJsonSerialize(mlir::Value value); +- Json::Value MemOpJsonSerialize(mlir::Plugin::MemOp& data); +- Json::Value SSAOpJsonSerialize(mlir::Plugin::SSAOp& data); +- /* 将Type类型数据序列化 */ +- Json::Value TypeJsonSerialize(PluginIR::PluginTypeBase& type); +- PluginIR::PluginTypeBase TypeJsonDeSerialize(const string& data, mlir::MLIRContext &context); ++ static PluginClient *GetInstance(); + /* 获取gcc插件数据并进行IR转换,将转换后的数据序列化返回给server。param:函数入参序列化后的数据 */ +- void IRTransBegin(const string& funname, const string& param); +- /* 从配置文件读取初始化信息 */ +- static int GetInitInfo(string& serverPath, string& shaPath, int& timeout); +- /* 进行sha256校验 */ +- static int CheckSHA256(const string& shaPath); +- static void CheckSafeCompileFlag(const string& argName, const string& param); +- /* 解析gcc编译时传递的-fplugin-arg参数 */ +- static void GetArg(struct plugin_name_args *pluginInfo, string& serverPath, string& arg, LogPriority& logLevel); ++ void GetIRTransResult(void *gccData, const string& funname, const string& param); ++ void GetGccData(const string& funcName, const string& param, string& key, string& result); + /* 将服务端传递的InjectPoint转换为plugin_event */ + static int GetEvent(InjectPoint inject, plugin_event *event); +- static unsigned short FindUnusedPort(void); // 查找未被使用的端口号,确保并发情况下server和client一对一 +- UserFuncStateEnum GetUserFuncState(void) ++ void Init(struct plugin_name_args *pluginInfo, const string& pluginName, pid_t& serverPid); ++ UserFuncStateEnum GetUserFuncState() + { + return userFuncState; + } +@@ -168,10 +167,6 @@ public: + { + pluginAPIParams = name; + } +- void SetTimeout(int time) +- { +- timeout = time; +- } + void SetPluginName(const string& pluginName) + { + this->pluginName = pluginName; +@@ -188,19 +183,11 @@ public: + { + return injectFlag; + } +- void SetGrpcPort(unsigned short port) +- { +- grpcPort = port; +- } +- unsigned short GetGrpcPort(void) +- { +- return grpcPort; +- } +- bool TimerInit(void); ++ bool TimerInit(clockid_t id); + void TimerStart(int interval); + /* 保存注入点和函数名信息,value格式为 注入点:函数名称 */ + int AddRegisteredUserFunc(const string& value); +- map>& GetRegisteredUserFunc(void) ++ map>& GetRegisteredUserFunc() + { + return registeredUserFunc; + } +@@ -210,13 +197,24 @@ public: + } + /* grpc消息处理函数 */ + void ServerMsgProc(const string& attribute, const string& value); +- /* grpc的server被client拉起之前将port记录在/tmp/grpc_ports_pin_client.txt中, server和client建立通信后从文件中删除port,避免多进程时端口冲突 +- 文件若不存在,先创建文件 */ +- static int OpenLockFile(const char *path); +- /* 读取文件中保存的grpc端口号 */ +- static void ReadPortsFromLockFile(int fd, string& grpcPorts); +- /* server启动异常或者grpc建立通信后,将文件中记录的端口号删除 */ +- static bool DeletePortFromLockFile(unsigned short port); ++ int ClientStart(); ++ int ServerStart(pid_t& pid); // pid server线程pid ++ bool DeleteGrpcPort() ++ { ++ return grpcPort.DeletePortFromLockFile(); ++ } ++ bool GetStartFlag() ++ { ++ return startFlag; ++ } ++ void SetStartFlag(bool flag) ++ { ++ startFlag = flag; ++ } ++ PluginJson &GetJson(void) ++ { ++ return json; ++ } + + private: + std::unique_ptr serviceStub; // 保存grpc客户端stub对象 +@@ -225,18 +223,17 @@ private: + volatile UserFuncStateEnum userFuncState; + string pluginAPIName; // 保存用户调用PluginAPI的函数名 + string pluginAPIParams; // 保存用户调用PluginAPI函数的参数 +- int timeout; + timer_t timerId; + string pluginName; // 向gcc插件注册回调函数时需要 + bool injectFlag; // 是否完成将注册点信息注册到gcc +- unsigned short grpcPort; // server和client使用的端口号 ++ PluginGrpcPort grpcPort; ++ PluginInputCheck input; ++ PluginJson json; + /* 保存注册点和函数信息 */ + map> registeredUserFunc; ++ std::shared_ptr grpcChannel; ++ bool startFlag; + }; +- +-/* pid:子进程server返回的pid,port:查找到的未使用的端口号 */ +-int ServerStart(int timeout, const string& serverPath, pid_t& pid, string& port, const LogPriority logLevel); +-int ClientStart(int timeout, const string& arg, const string& pluginName, const string& port); + } // namespace PinClient + + #endif +diff --git a/include/PluginClient/PluginGrpcPort.h b/include/PluginClient/PluginGrpcPort.h +new file mode 100755 +index 0000000..cd06864 +--- /dev/null ++++ b/include/PluginClient/PluginGrpcPort.h +@@ -0,0 +1,73 @@ ++/* Copyright (c) 2022-2022 Huawei Technologies Co., Ltd. ++ ++ This program is free software; you can redistribute it and/or modify it ++ under the terms of the GNU General Public License as published by the ++ Free Software Foundation; either version 3, or (at your option) any ++ later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; see the file COPYING3. If not see ++ . ++ ++ Author: Mingchuan Wu and Yancheng Li ++ Create: 2022-08-18 ++ Description: ++ This file contains the declaration of the PluginGrpcPort class. ++ 主要完成功能:查找未使用的端口号,并将端口号写入到共享文件中,通过文件锁控制多进程间访问,并提供 ++ DeletePortFromLockFile接口在退出时删除写入的端口号 ++*/ ++ ++#ifndef PLUGIN_GRPC_PORT_H ++#define PLUGIN_GRPC_PORT_H ++ ++#include ++ ++namespace PinClient { ++using std::string; ++ ++class PluginGrpcPort { ++public: ++ PluginGrpcPort() ++ { ++ const int startPort = 40000; ++ lockFilePath = "/tmp/grpc_ports_pin_client.txt"; ++ basePort = startPort; ++ port = 0; ++ } ++ bool FindUnusedPort(); // 查找未被使用的端口号,确保并发情况下server和client一对一 ++ /* grpc的server被client拉起之前将port记录在/tmp/grpc_ports_pin_client.txt中, server和client建立通信后从文件中删除port,避免多进程时端口冲突 ++ 文件若不存在,先创建文件 */ ++ int OpenFile(const char *path); ++ /* 读取文件中保存的grpc端口号 */ ++ bool ReadPortsFromLockFile(int fd, string& grpcPorts); ++ /* server启动异常或者grpc建立通信后,将文件中记录的端口号删除 */ ++ bool DeletePortFromLockFile(); ++ unsigned short GetPort() ++ { ++ return port; ++ } ++ void SetLockFilePath(const string& path) ++ { ++ lockFilePath = path; ++ } ++ void SetBasePort(unsigned short port) ++ { ++ basePort = port; ++ } ++ unsigned short GetBasePort() ++ { ++ return basePort; ++ } ++ ++private: ++ unsigned short port; // server和client使用的端口号 ++ string lockFilePath; ++ unsigned short basePort; ++}; ++} // namespace PinClient ++#endif +\ No newline at end of file +diff --git a/include/PluginClient/PluginInputCheck.h b/include/PluginClient/PluginInputCheck.h +new file mode 100755 +index 0000000..cbbfc3f +--- /dev/null ++++ b/include/PluginClient/PluginInputCheck.h +@@ -0,0 +1,136 @@ ++/* Copyright (c) 2022-2022 Huawei Technologies Co., Ltd. ++ ++ This program is free software; you can redistribute it and/or modify it ++ under the terms of the GNU General Public License as published by the ++ Free Software Foundation; either version 3, or (at your option) any ++ later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; see the file COPYING3. If not see ++ . ++ ++ Author: Mingchuan Wu and Yancheng Li ++ Create: 2022-08-18 ++ Description: ++ This file contains the declaration of the PluginInputCheck class. ++ 主要完成功能:获取gcc编译时的参数,读取config.json配置文件,完成sha256校验,完成 ++ 安全编译选项参数检查,并保存serverPath,shaPath,timeout等信息 ++*/ ++ ++#ifndef PLUGIN_INPUT_CHECK_H ++#define PLUGIN_INPUT_CHECK_H ++ ++#include ++#include ++#include ++#include "gcc-plugin.h" ++#include "PluginClient/PluginLog.h" ++ ++namespace PinClient { ++using std::map; ++using std::string; ++using std::vector; ++ ++enum Jsonkey { ++#define JSON_KEY(KEY, NAME) KEY, ++#include "JsonKey.def" ++#undef JSON_KEY ++MAX_JSON_KEYS ++}; ++ ++#define JSON_KEY(KEY, NAME) NAME, ++const char *const jsonkey[] = { ++#include "JsonKey.def" ++}; ++#undef JSON_KEY ++ ++enum { ++ KEY_SERVER_PATH, ++ KEY_LOG_LEVEL, ++}; ++ ++class PluginInputCheck { ++public: ++ const string shaFile = "/libpin_user.sha256"; ++ PluginInputCheck(); ++ /* 从配置文件读取初始化信息 */ ++ int GetInitInfo(); ++ int CheckServerFile(); // 对server文件进行检查 ++ int CheckShaFile(); // 对sha256校验文件进行检查 ++ bool ReadConfigfile(Json::Value& root); ++ /* 进行sha256校验 */ ++ int CheckSHA256(); ++ void CheckSafeCompileFlag(const string& argName, const string& param); ++ /* 解析gcc编译时传递的-fplugin-arg参数 */ ++ void GetInputArgs(struct plugin_name_args *pluginInfo); ++ int mapFind(const std::map& map, const string& key) ++ { ++ auto it = map.find(key); ++ if (it != map.end()) { ++ return it->second; ++ } ++ return -1; ++ } ++ string& GetArgs() ++ { ++ return args; ++ } ++ string& GetServerPath() ++ { ++ return serverPath; ++ } ++ void SetServerPath(const string& path) ++ { ++ serverPath = path; ++ } ++ LogPriority GetLogLevel() ++ { ++ return logLevel; ++ } ++ void SetLogLevel(LogPriority level) ++ { ++ logLevel = level; ++ } ++ string& GetShaPath() ++ { ++ return shaPath; ++ } ++ void SetShaPath(const string& path) ++ { ++ shaPath = path; ++ } ++ int GetTimeout() ++ { ++ return timeout; ++ } ++ void SetTimeout(int time); ++ void SetConfigPath(const string& path) ++ { ++ configFilePath = path; ++ } ++ string& GetConfigPath() ++ { ++ return configFilePath; ++ } ++ string GetServerDir() ++ { ++ int index = serverPath.find_last_of("/"); ++ return serverPath.substr(0, index); ++ } ++ ++private: ++ string args; ++ string serverPath; ++ string configFilePath; ++ LogPriority logLevel; ++ string shaPath; ++ int timeout; ++ vector safeCompileFlags; ++}; ++} // namespace PinClient ++#endif +\ No newline at end of file +diff --git a/include/PluginClient/PluginJson.h b/include/PluginClient/PluginJson.h +new file mode 100755 +index 0000000..91bd925 +--- /dev/null ++++ b/include/PluginClient/PluginJson.h +@@ -0,0 +1,70 @@ ++/* Copyright (c) 2022-2022 Huawei Technologies Co., Ltd. ++ ++ This program is free software; you can redistribute it and/or modify it ++ under the terms of the GNU General Public License as published by the ++ Free Software Foundation; either version 3, or (at your option) any ++ later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; see the file COPYING3. If not see ++ . ++ ++ Author: Mingchuan Wu and Yancheng Li ++ Create: 2022-08-18 ++ Description: ++ This file contains the declaration of the PluginJson class. ++ 主要完成功能:将operation、Decl、Type、Inter、string等类型数据序列化 ++*/ ++ ++#ifndef PLUGIN_JSON_H ++#define PLUGIN_JSON_H ++ ++#include ++#include ++ ++#include "Dialect/PluginDialect.h" ++#include "Dialect/PluginOps.h" ++#include "Dialect/PluginTypes.h" ++ ++namespace PinClient { ++using std::string; ++using std::vector; ++ ++class PluginJson { ++public: ++ void OpJsonSerialize(vector& data, string& out); ++ void LoopOpsJsonSerialize(vector& loops, string& out); ++ void LoopOpJsonSerialize(mlir::Plugin::LoopOp& loop, string& out); ++ void BlocksJsonSerialize(vector&, string&); ++ void EdgesJsonSerialize(vector >&, string&); ++ void EdgeJsonSerialize(std::pair&, string&); ++ void NopJsonSerialize(string&); ++ void FunctionOpJsonSerialize(vector& data, string& out); ++ void LocalDeclsJsonSerialize(vector& decls, string& out); ++ void GetPhiOpsJsonSerialize(vector phiOps, string& out); ++ Json::Value OperationJsonSerialize(mlir::Operation *, uint64_t&); ++ Json::Value CallOpJsonSerialize(mlir::Plugin::CallOp& data); ++ Json::Value CondOpJsonSerialize(mlir::Plugin::CondOp& data, uint64_t&); ++ Json::Value PhiOpJsonSerialize(mlir::Plugin::PhiOp& data); ++ Json::Value AssignOpJsonSerialize(mlir::Plugin::AssignOp& data); ++ Json::Value BaseOpJsonSerialize(mlir::Plugin::BaseOp data); ++ Json::Value FallThroughOpJsonSerialize(mlir::Plugin::FallThroughOp data, uint64_t&); ++ Json::Value RetOpJsonSerialize(mlir::Plugin::RetOp data, uint64_t&); ++ Json::Value ValueJsonSerialize(mlir::Value value); ++ Json::Value MemOpJsonSerialize(mlir::Plugin::MemOp& data); ++ Json::Value SSAOpJsonSerialize(mlir::Plugin::SSAOp& data); ++ /* 将Type类型数据序列化 */ ++ Json::Value TypeJsonSerialize(PluginIR::PluginTypeBase& type); ++ PluginIR::PluginTypeBase TypeJsonDeSerialize(const string& data, mlir::MLIRContext &context); ++ /* 将整数型数据序列化 */ ++ void IntegerSerialize(int64_t data, string& out); ++ /* 将字符串型数据序列化 */ ++ void StringSerialize(const string& data, string& out); ++}; ++} // namespace PinClient ++#endif +diff --git a/include/PluginClient/PluginLog.h b/include/PluginClient/PluginLog.h +index a91a1db..8fafa85 100644 +--- a/include/PluginClient/PluginLog.h ++++ b/include/PluginClient/PluginLog.h +@@ -18,14 +18,14 @@ + Create: 2022-08-18 + Description: + This file contains the declaration of the Plugin_Log class. ++ 主要完成功能:提供LOGE、LOGW、LOGI、LOGD四个log保存接口,并提供SetLogPriority接口 ++ 设置log级别 + */ + + #ifndef PLUGIN_LOG_H + #define PLUGIN_LOG_H + + namespace PinClient { +-#define LOG_FILE_SIZE (10 * 1024 * 1024) +- + enum LogPriority : uint8_t { + PRIORITY_ERROR = 0, + PRIORITY_WARN, +@@ -33,12 +33,13 @@ enum LogPriority : uint8_t { + PRIORITY_DEBUG + }; + void LogPrint(LogPriority priority, const char *tag, const char *fmt, ...); +-void CloseLog(void); ++void CloseLog(); + bool SetLogPriority(LogPriority priority); ++void SetLogFileSize(unsigned int size); // 设置log文件大小,默认为10M,当日志超过10M后,重新命名 + + #define LOGE(...) LogPrint(PRIORITY_ERROR, "ERROR:", __VA_ARGS__) + #define LOGW(...) LogPrint(PRIORITY_WARN, "WARN:", __VA_ARGS__) +-#define LOGI(...) LogPrint(PRIORITY_INFO, "", __VA_ARGS__) ++#define LOGI(...) LogPrint(PRIORITY_INFO, "INFO:", __VA_ARGS__) + #define LOGD(...) LogPrint(PRIORITY_DEBUG, "DEBUG:", __VA_ARGS__) + } // namespace PinClient + +diff --git a/include/Translate/GimpleToPluginOps.h b/include/Translate/GimpleToPluginOps.h +index 689ece3..5f8bdf0 100644 +--- a/include/Translate/GimpleToPluginOps.h ++++ b/include/Translate/GimpleToPluginOps.h +@@ -36,18 +36,24 @@ + + namespace PluginIR { + using std::vector; ++using std::string; + using namespace mlir::Plugin; + +-namespace detail { ++namespace Detail { + class BlockFromGimpleTranslatorImpl; + // class BlockToPluginIRTranslatorImpl; +-} // namespace detail ++} // namespace Detail + + class GimpleToPluginOps { + public: + GimpleToPluginOps (mlir::MLIRContext &); + ~GimpleToPluginOps (); + ++ string DeclSourceFile(uint64_t gccDataAddr); ++ string GetVariableName(uint64_t gccDataAddr); ++ string GetFuncName(uint64_t gccDataAddr); ++ int DeclSourceLine(uint64_t gccDataAddr); ++ int DeclSourceColumn(uint64_t gccDataAddr); + /* ToPluginInterface */ + uint64_t CreateBlock(uint64_t, uint64_t); + void DeleteBlock(uint64_t, uint64_t); +@@ -107,7 +113,7 @@ private: + TypeToPluginIRTranslator pluginTypeTranslator; + + // process basic_block +- std::unique_ptr bbTranslator; ++ std::unique_ptr bbTranslator; + bool ProcessBasicBlock(intptr_t, Region&); + bool ProcessGimpleStmt(intptr_t, Region&); + }; +diff --git a/include/Translate/ToPluginOpsInterface.h b/include/Translate/ToPluginOpsInterface.h +deleted file mode 100644 +index 6d2b74b..0000000 +--- a/include/Translate/ToPluginOpsInterface.h ++++ /dev/null +@@ -1,59 +0,0 @@ +-/* Copyright (c) 2022-2022 Huawei Technologies Co., Ltd. +- +- This program is free software; you can redistribute it and/or modify it +- under the terms of the GNU General Public License as published by the +- Free Software Foundation; either version 3, or (at your option) any +- later version. +- +- This program is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- GNU General Public License for more details. +- +- You should have received a copy of the GNU General Public License +- along with this program; see the file COPYING3. If not see +- . +- +- Author: Mingchuan Wu and Yancheng Li +- Create: 2022-08-18 +- Description: +- This file contains the declaration of the ToPluginInterface class +-*/ +- +-#ifndef TO_PLUGINOPS_INTERFACE_H +-#define TO_PLUGINOPS_INTERFACE_H +- +-#include +-#include "Dialect/PluginOps.h" +- +-namespace PluginIR { +-using std::vector; +-using namespace mlir::Plugin; +- +-/* The ToPluginInterface class defines the plugin interfaces that different +- compilers need to implement. */ +-class ToPluginOpsInterface { +-public: +- /* Operation. */ +- virtual vector GetAllFunction() = 0; +- virtual vector GetAllDecls(uint64_t) = 0; +- virtual vector GetAllLoops(uint64_t) = 0; +- virtual LoopOp GetLoop(uint64_t) = 0; +- virtual bool IsBlockInside(uint64_t, uint64_t) = 0; +- virtual vector GetBlocksInLoop(uint64_t) = 0; +- virtual uint64_t AllocateNewLoop(void) = 0; +- virtual void DeleteLoop(uint64_t) = 0; +- virtual void AddLoop (uint64_t, uint64_t, uint64_t) = 0; +- virtual uint64_t GetHeader(uint64_t) = 0; +- virtual uint64_t GetLatch(uint64_t) = 0; +- virtual vector > GetLoopExits(uint64_t) = 0; +- virtual std::pair GetLoopSingleExit(uint64_t) = 0; +- virtual LoopOp GetBlockLoopFather(uint64_t) = 0; +- virtual bool UpdateSSA() = 0; +- virtual vector GetPhiOpsInsideBlock(uint64_t) = 0; +- virtual bool IsDomInfoAvailable() = 0; +- +-}; +-} // namespace PluginIR +- +-#endif // TO_PLUGINOPS_INTERFACE_H +\ No newline at end of file +diff --git a/include/Translate/TypeTranslation.h b/include/Translate/TypeTranslation.h +index 964305c..98d279c 100644 +--- a/include/Translate/TypeTranslation.h ++++ b/include/Translate/TypeTranslation.h +@@ -36,10 +36,10 @@ namespace PluginIR { + using std::vector; + using namespace mlir; + +-namespace detail { ++namespace Detail { + class TypeFromPluginIRTranslatorImpl; + class TypeToPluginIRTranslatorImpl; +-} // namespace detail ++} // namespace Detail + + class TypeFromPluginIRTranslator { + public: +@@ -54,7 +54,7 @@ public: + uint64_t getBitWidth (PluginTypeBase type); + + private: +- std::unique_ptr impl; ++ std::unique_ptr impl; + }; + + class TypeToPluginIRTranslator { +@@ -65,7 +65,7 @@ public: + uintptr_t translateType (PluginTypeBase type); + + private: +- std::unique_ptr impl; ++ std::unique_ptr impl; + }; + + } // namespace PluginIR +diff --git a/include/IRTrans/IRTransPlugin.h b/include/gccPlugin/gccPlugin.h +similarity index 83% +rename from include/IRTrans/IRTransPlugin.h +rename to include/gccPlugin/gccPlugin.h +index 400e8e0..bb2e0d3 100755 +--- a/include/IRTrans/IRTransPlugin.h ++++ b/include/gccPlugin/gccPlugin.h +@@ -18,6 +18,8 @@ + Create: 2022-08-18 + Description: + This file contains the declaration of the RegisterPluginEvent. ++ 主要完成功能:提供RegisterPluginEvent和RegisterPassManagerSetup两个注册gcc ++ 回调点接口 + */ + + #ifndef IRTRANS_PLUGIN_H +@@ -26,6 +28,6 @@ + #include "PluginClient/PluginClient.h" + + int RegisterPluginEvent(PinClient::InjectPoint inject, const std::string& pluginName); +-int RegisterPassManagerSetup(PinClient::InjectPoint inject, const PinClient::ManagerSetupData& setupData, ++void RegisterPassManagerSetup(unsigned int index, const PinClient::ManagerSetupData& setupData, + const std::string& pluginName); + #endif +diff --git a/lib/Dialect/PluginDialect.cpp b/lib/Dialect/PluginDialect.cpp +index 7071e64..527c076 100644 +--- a/lib/Dialect/PluginDialect.cpp ++++ b/lib/Dialect/PluginDialect.cpp +@@ -16,11 +16,11 @@ + + + */ +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // + // This file defines Plugin dialect. + // +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + + #include "Dialect/PluginDialect.h" + #include "Dialect/PluginOps.h" +@@ -29,20 +29,21 @@ + using namespace mlir; + using namespace mlir::Plugin; + +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // Plugin dialect. +-//===----------------------------------------------------------------------===// +- +-void PluginDialect::initialize() { +- addTypes(); +- +- addOperations< ++// ===----------------------------------------------------------------------===// ++ ++void PluginDialect::initialize() ++{ ++ addTypes(); ++ ++ addOperations< + #define GET_OP_LIST + #include "Dialect/PluginOps.cpp.inc" +- >(); ++ >(); + } +\ No newline at end of file +diff --git a/lib/Dialect/PluginOps.cpp b/lib/Dialect/PluginOps.cpp +index ac2a4ee..052ebfd 100644 +--- a/lib/Dialect/PluginOps.cpp ++++ b/lib/Dialect/PluginOps.cpp +@@ -16,11 +16,11 @@ + + + */ +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // + // This file defines operations in the Plugin dialect. + // +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + + #include "Dialect/PluginDialect.h" + #include "Dialect/PluginOps.h" +@@ -33,7 +33,8 @@ using namespace mlir; + using namespace mlir::Plugin; + + void FunctionOp::build(mlir::OpBuilder &builder, mlir::OperationState &state, +- uint64_t id, StringRef funcName, bool declaredInline) { ++ uint64_t id, StringRef funcName, bool declaredInline) ++{ + FunctionOp::build(builder, state, + builder.getI64IntegerAttr(id), + builder.getStringAttr(funcName), +@@ -41,8 +42,8 @@ void FunctionOp::build(mlir::OpBuilder &builder, mlir::OperationState &state, + } + + void LocalDeclOp::build(mlir::OpBuilder &builder, mlir::OperationState &state, +- uint64_t id, StringRef symName, +- int64_t typeID, uint64_t typeWidth) { ++ uint64_t id, StringRef symName, int64_t typeID, uint64_t typeWidth) ++{ + LocalDeclOp::build(builder, state, + builder.getI64IntegerAttr(id), + builder.getStringAttr(symName), +@@ -51,8 +52,8 @@ void LocalDeclOp::build(mlir::OpBuilder &builder, mlir::OperationState &state, + } + + void LoopOp::build(mlir::OpBuilder &builder, mlir::OperationState &state, +- uint64_t id, uint32_t index, uint64_t innerLoopId, +- uint64_t outerLoopId, uint32_t numBlock) { ++ uint64_t id, uint32_t index, uint64_t innerLoopId, uint64_t outerLoopId, uint32_t numBlock) ++{ + LoopOp::build(builder, state, + builder.getI64IntegerAttr(id), + builder.getI32IntegerAttr(index), +@@ -61,12 +62,11 @@ void LoopOp::build(mlir::OpBuilder &builder, mlir::OperationState &state, + builder.getI32IntegerAttr(numBlock)); + } + +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // PlaceholderOp + + void PlaceholderOp::build(OpBuilder &builder, OperationState &state, +- uint64_t id, IDefineCode defCode, bool readOnly, +- Type retType) ++ uint64_t id, IDefineCode defCode, bool readOnly, Type retType) + { + state.addAttribute("id", builder.getI64IntegerAttr(id)); + state.addAttribute("defCode", +@@ -75,12 +75,11 @@ void PlaceholderOp::build(OpBuilder &builder, OperationState &state, + state.addTypes(retType); + } + +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // MemOp + + void MemOp::build(OpBuilder &builder, OperationState &state, +- uint64_t id, IDefineCode defCode, bool readOnly, +- Value addr, Value offset, Type retType) ++ uint64_t id, IDefineCode defCode, bool readOnly, Value addr, Value offset, Type retType) + { + state.addAttribute("id", builder.getI64IntegerAttr(id)); + state.addAttribute("readOnly", builder.getBoolAttr(readOnly)); +@@ -90,13 +89,11 @@ void MemOp::build(OpBuilder &builder, OperationState &state, + if (retType) state.addTypes(retType); + } + +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // SSAOp + +-void SSAOp::build(OpBuilder &builder, OperationState &state, uint64_t id, +- IDefineCode defCode, bool readOnly, uint64_t nameVarId, +- uint64_t ssaParmDecl, uint64_t version, +- uint64_t definingId, Type retType) ++void SSAOp::build(OpBuilder &builder, OperationState &state, uint64_t id, IDefineCode defCode, bool readOnly, ++ uint64_t nameVarId, uint64_t ssaParmDecl, uint64_t version, uint64_t definingId, Type retType) + { + state.addAttribute("id", builder.getI64IntegerAttr(id)); + state.addAttribute("defCode", +@@ -105,16 +102,15 @@ void SSAOp::build(OpBuilder &builder, OperationState &state, uint64_t id, + state.addAttribute("nameVarId", builder.getI64IntegerAttr(nameVarId)); + state.addAttribute("ssaParmDecl", builder.getI64IntegerAttr(ssaParmDecl)); + state.addAttribute("version", builder.getI64IntegerAttr(version)); +- state.addAttribute("definingId", builder.getI64IntegerAttr(definingId)); ++ state.addAttribute("definingId", builder.getI64IntegerAttr(definingId)); + state.addTypes(retType); + } + +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // ConstOp + + void ConstOp::build(OpBuilder &builder, OperationState &state, uint64_t id, +- IDefineCode defCode, bool readOnly, Attribute init, +- Type retType) ++ IDefineCode defCode, bool readOnly, Attribute init, Type retType) + { + state.addAttribute("id", builder.getI64IntegerAttr(id)); + state.addAttribute("defCode", +@@ -124,12 +120,11 @@ void ConstOp::build(OpBuilder &builder, OperationState &state, uint64_t id, + if (retType) state.addTypes(retType); + } + +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // PointerOp + + void PointerOp::build(OpBuilder &builder, OperationState &state, uint64_t id, +- IDefineCode defCode, bool readOnly, Type retType, +- bool pointeeReadOnly) ++ IDefineCode defCode, bool readOnly, Type retType, bool pointeeReadOnly) + { + state.addAttribute("id", builder.getI64IntegerAttr(id)); + state.addAttribute("defCode", +@@ -139,12 +134,11 @@ void PointerOp::build(OpBuilder &builder, OperationState &state, uint64_t id, + state.addAttribute("pointeeReadOnly", builder.getBoolAttr(pointeeReadOnly)); + } + +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // CallOp + + void CallOp::build(OpBuilder &builder, OperationState &state, +- uint64_t id, StringRef callee, +- ArrayRef arguments, Type retType) ++ uint64_t id, StringRef callee, ArrayRef arguments, Type retType) + { + state.addAttribute("id", builder.getI64IntegerAttr(id)); + state.addOperands(arguments); +@@ -154,21 +148,25 @@ void CallOp::build(OpBuilder &builder, OperationState &state, + + /// Return the callee of the generic call operation, this is required by the + /// call interface. +-CallInterfaceCallable CallOp::getCallableForCallee() { ++CallInterfaceCallable CallOp::getCallableForCallee() ++{ + return (*this)->getAttrOfType("callee"); + } + + /// Get the argument operands to the called function, this is required by the + /// call interface. +-Operation::operand_range CallOp::getArgOperands() { return inputs(); } ++Operation::operand_range CallOp::getArgOperands() ++{ ++ return inputs(); ++} + +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // CondOp + +-void CondOp::build(OpBuilder &builder, OperationState &state, +- uint64_t id, uint64_t address, IComparisonCode condCode, +- Value lhs, Value rhs, Block* tb, Block* fb, uint64_t tbaddr, +- uint64_t fbaddr, Value trueLabel, Value falseLabel) { ++void CondOp::build(OpBuilder &builder, OperationState &state, uint64_t id, uint64_t address, ++ IComparisonCode condCode, Value lhs, Value rhs, Block* tb, Block* fb, uint64_t tbaddr, ++ uint64_t fbaddr, Value trueLabel, Value falseLabel) ++{ + state.addAttribute("id", builder.getI64IntegerAttr(id)); + state.addAttribute("address", builder.getI64IntegerAttr(address)); + state.addOperands({lhs, rhs}); +@@ -182,29 +180,29 @@ void CondOp::build(OpBuilder &builder, OperationState &state, + if (falseLabel != nullptr) state.addOperands(falseLabel); + } + +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // PhiOp + +-void PhiOp::build(OpBuilder &builder, OperationState &state, +- uint64_t id, uint32_t capacity, uint32_t nArgs, +- ArrayRef operands, Type resultType) { ++void PhiOp::build(OpBuilder &builder, OperationState &state, uint64_t id, uint32_t capacity, ++ uint32_t nArgs, ArrayRef operands, Type resultType) ++{ + state.addAttribute("id", builder.getI64IntegerAttr(id)); + state.addAttribute("capacity", builder.getI32IntegerAttr(capacity)); + state.addAttribute("nArgs", builder.getI32IntegerAttr(nArgs)); + state.addOperands(operands); +- if (resultType != nullptr) state.addTypes(resultType); ++ if (resultType != nullptr) { ++ state.addTypes(resultType); ++ } + } + +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // AssignOp + +-void AssignOp::build(OpBuilder &builder, OperationState &state, +- uint64_t id, IExprCode exprCode, +- ArrayRef operands, Type resultType) ++void AssignOp::build(OpBuilder &builder, OperationState &state, uint64_t id, ++ IExprCode exprCode, ArrayRef operands, Type resultType) + { + state.addAttribute("id", builder.getI64IntegerAttr(id)); +- state.addAttribute("exprCode", +- builder.getI32IntegerAttr(static_cast(exprCode))); ++ state.addAttribute("exprCode", builder.getI32IntegerAttr(static_cast(exprCode))); + state.addOperands(operands); + if (resultType != nullptr) state.addTypes(resultType); + } +@@ -216,47 +214,46 @@ void AssignOp::build(OpBuilder &builder, OperationState &state, + /// or `false` on success. This allows for easily chaining together a set of + /// parser rules. These rules are used to populate an `mlir::OperationState` + /// similarly to the `build` methods described above. +-static mlir::ParseResult parseAssignOp(mlir::OpAsmParser &parser, +- mlir::OperationState &result) { +- mlir::DenseElementsAttr value; +- if (parser.parseOptionalAttrDict(result.attributes) || +- parser.parseAttribute(value, "value", result.attributes)) +- return failure(); +- +- result.addTypes(value.getType()); +- return success(); ++static mlir::ParseResult parseAssignOp(mlir::OpAsmParser &parser, mlir::OperationState &result) ++{ ++ mlir::DenseElementsAttr value; ++ if (parser.parseOptionalAttrDict(result.attributes) || ++ parser.parseAttribute(value, "value", result.attributes)) { ++ return failure(); ++ } ++ ++ result.addTypes(value.getType()); ++ return success(); + } + + /// The 'OpAsmPrinter' class is a stream that allows for formatting + /// strings, attributes, operands, types, etc. +-static void print(mlir::OpAsmPrinter &printer, AssignOp op) { +- printer << "assign "; +- printer.printType(op.getType()); +-// printer << op.value(); ++static void print(mlir::OpAsmPrinter &printer, AssignOp op) ++{ ++ printer << "assign "; ++ printer.printType(op.getType()); + } + +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // BaseOp + +-void BaseOp::build(OpBuilder &builder, OperationState &state, +- uint64_t id, StringRef opCode) ++void BaseOp::build(OpBuilder &builder, OperationState &state, uint64_t id, StringRef opCode) + { + state.addAttribute("id", builder.getI64IntegerAttr(id)); + state.addAttribute("opCode", builder.getStringAttr(opCode)); + } + +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // FallThroughOp + +-void FallThroughOp::build(OpBuilder &builder, OperationState &state, +- uint64_t address, Block* dest, uint64_t destaddr) ++void FallThroughOp::build(OpBuilder &builder, OperationState &state, uint64_t address, Block* dest, uint64_t destaddr) + { + state.addAttribute("address", builder.getI64IntegerAttr(address)); + state.addAttribute("destaddr", builder.getI64IntegerAttr(destaddr)); + state.addSuccessors(dest); + } + +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // RetOp + + void RetOp::build(OpBuilder &builder, OperationState &state, uint64_t address) +@@ -264,9 +261,9 @@ void RetOp::build(OpBuilder &builder, OperationState &state, uint64_t address) + state.addAttribute("address", builder.getI64IntegerAttr(address)); + } + +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // TableGen'd op method definitions +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + + #define GET_OP_CLASSES + #include "Dialect/PluginOps.cpp.inc" +\ No newline at end of file +diff --git a/lib/Dialect/PluginTypes.cpp b/lib/Dialect/PluginTypes.cpp +index edccdd5..396bf0f 100644 +--- a/lib/Dialect/PluginTypes.cpp ++++ b/lib/Dialect/PluginTypes.cpp +@@ -28,7 +28,7 @@ using namespace mlir; + using namespace PluginIR; + + namespace PluginIR { +-namespace detail { ++namespace Detail { + /// Integer Type Storage and Uniquing. + struct PluginIntegerTypeStorage : public TypeStorage { + PluginIntegerTypeStorage(unsigned width, +@@ -38,16 +38,18 @@ namespace detail { + /// The hash key used for uniquing. + using KeyTy = std::pair; + +- static llvm::hash_code hashKey(const KeyTy &key) { ++ static llvm::hash_code hashKey(const KeyTy &key) ++ { + return llvm::hash_value(key); + } + +- bool operator==(const KeyTy &key) const { ++ bool operator==(const KeyTy &key) const ++ { + return KeyTy(width, signedness) == key; + } + +- static PluginIntegerTypeStorage *construct(TypeStorageAllocator &allocator, +- KeyTy key) { ++ static PluginIntegerTypeStorage *construct(TypeStorageAllocator &allocator, KeyTy key) ++ { + return new (allocator.allocate()) + PluginIntegerTypeStorage(key.first, key.second); + } +@@ -62,12 +64,13 @@ namespace detail { + /// The hash key used for uniquing. + using KeyTy = unsigned; + +- bool operator==(const KeyTy &key) const { ++ bool operator==(const KeyTy &key) const ++ { + return KeyTy(width) == key; + } + +- static PluginFloatTypeStorage *construct(TypeStorageAllocator &allocator, +- KeyTy key) { ++ static PluginFloatTypeStorage *construct(TypeStorageAllocator &allocator, KeyTy key) ++ { + return new (allocator.allocate()) + PluginFloatTypeStorage(key); + } +@@ -81,26 +84,27 @@ namespace detail { + PluginPointerTypeStorage(const KeyTy &key) + : pointee(std::get<0>(key)), readOnlyPointee(std::get<1>(key)) {} + +- static PluginPointerTypeStorage *construct(TypeStorageAllocator &allocator, +- KeyTy key) { ++ static PluginPointerTypeStorage *construct(TypeStorageAllocator &allocator, KeyTy key) ++ { + return new (allocator.allocate()) + PluginPointerTypeStorage(key); + } + +- bool operator==(const KeyTy &key) const { ++ bool operator==(const KeyTy &key) const ++ { + return std::make_tuple(pointee, readOnlyPointee) == key; + } + + Type pointee; + unsigned readOnlyPointee; + }; +-} // namespace detail ++} // namespace Detail + } // namespace PluginIR + + +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // Plugin TypeBase +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + + PluginTypeID PluginTypeBase::getPluginTypeID () + { +@@ -119,7 +123,7 @@ PluginTypeID PluginTypeBase::getPluginTypeID () + if (auto Ty = dyn_cast()) { + return Ty.getPluginTypeID (); + } +- return PluginTypeID::UndefTyID; ++ return PluginTypeID::UndefTyID; + } + + unsigned PluginTypeBase::getPluginIntOrFloatBitWidth () +@@ -159,9 +163,9 @@ unsigned PluginTypeBase::getTypeSize () + return size; + } + +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // Plugin Integer Type +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + + unsigned PluginIntegerType::getWidth() const + { +@@ -175,10 +179,8 @@ PluginIntegerType::SignednessSemantics PluginIntegerType::getSignedness() const + + PluginTypeID PluginIntegerType::getPluginTypeID() + { +- if (isSigned()) +- { +- switch (getWidth()) +- { ++ if (isSigned()) { ++ switch (getWidth()) { + case 1: + return PluginTypeID::IntegerTy1ID; + case 8: +@@ -193,10 +195,8 @@ PluginTypeID PluginIntegerType::getPluginTypeID() + return PluginTypeID::UndefTyID; + } + } +- if (isUnsigned()) +- { +- switch (getWidth()) +- { ++ if (isUnsigned()) { ++ switch (getWidth()) { + case 1: + return PluginTypeID::UIntegerTy1ID; + case 8: +@@ -214,14 +214,15 @@ PluginTypeID PluginIntegerType::getPluginTypeID() + return PluginTypeID::UndefTyID; + } + +-PluginIntegerType PluginIntegerType::get (MLIRContext *context, unsigned width, PluginIntegerType::SignednessSemantics signedness) ++PluginIntegerType PluginIntegerType::get (MLIRContext *context, unsigned width, ++ PluginIntegerType::SignednessSemantics signedness) + { + return Base::get(context, width, signedness); + } + +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // Plugin Float Type +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + + unsigned PluginFloatType::getWidth () const + { +@@ -230,10 +231,12 @@ unsigned PluginFloatType::getWidth () const + + PluginTypeID PluginFloatType::getPluginTypeID() + { +- if (getWidth() == 32) ++ if (getWidth() == 32) { + return PluginTypeID::FloatTyID; +- if (getWidth() == 64) ++ } ++ if (getWidth() == 64) { + return PluginTypeID::DoubleTyID; ++ } + return PluginTypeID::UndefTyID; + } + +@@ -242,36 +245,36 @@ PluginFloatType PluginFloatType::get (MLIRContext *context, unsigned width) + return Base::get(context, width); + } + +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // Plugin Boolean Type +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + + PluginTypeID PluginBooleanType::getPluginTypeID() + { + return PluginTypeID::BooleanTyID; + } + +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // Plugin Void Type +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + + PluginTypeID PluginVoidType::getPluginTypeID() + { + return PluginTypeID::VoidTyID; + } + +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // Plugin Undef Type +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + + PluginTypeID PluginUndefType::getPluginTypeID() + { + return PluginTypeID::UndefTyID; + } + +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // Plugin Pointer Type +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + + PluginTypeID PluginPointerType::getPluginTypeID() + { +@@ -291,4 +294,4 @@ unsigned PluginPointerType::isReadOnlyElem() + PluginPointerType PluginPointerType::get (MLIRContext *context, Type pointee, unsigned readOnlyPointee) + { + return Base::get(context, pointee, readOnlyPointee); +-} +\ No newline at end of file ++} +diff --git a/lib/PluginAPI/PluginClientAPI.cpp b/lib/PluginAPI/PluginClientAPI.cpp +index 1c4dbf9..5e454d7 100644 +--- a/lib/PluginAPI/PluginClientAPI.cpp ++++ b/lib/PluginAPI/PluginClientAPI.cpp +@@ -19,6 +19,32 @@ + #include "PluginAPI/PluginClientAPI.h" + + namespace PluginAPI { ++ ++string PluginClientAPI::GetDeclSourceFile(uint64_t gccDataAddr) ++{ ++ return gimpleConversion.DeclSourceFile(gccDataAddr); ++} ++ ++string PluginClientAPI::VariableName(int64_t gccDataAddr) ++{ ++ return gimpleConversion.GetVariableName(gccDataAddr); ++} ++ ++string PluginClientAPI::FuncName(int64_t gccDataAddr) ++{ ++ return gimpleConversion.GetFuncName(gccDataAddr); ++} ++ ++int PluginClientAPI::GetDeclSourceLine(uint64_t gccDataAddr) ++{ ++ return gimpleConversion.DeclSourceLine(gccDataAddr); ++} ++ ++int PluginClientAPI::GetDeclSourceColumn(uint64_t gccDataAddr) ++{ ++ return gimpleConversion.DeclSourceColumn(gccDataAddr); ++} ++ + uint64_t PluginClientAPI::CreateBlock(uint64_t funcAddr, uint64_t bbAddr) + { + return gimpleConversion.CreateBlock(funcAddr, bbAddr); +@@ -142,20 +168,17 @@ bool PluginClientAPI::SetLhsInCallOp(uint64_t callId, uint64_t lhsId) + return gimpleConversion.SetGimpleCallLHS(callId, lhsId); + } + +-uint32_t PluginClientAPI::AddArgInPhiOp(uint64_t phiId, uint64_t argId, +- uint64_t predId, uint64_t succId) ++uint32_t PluginClientAPI::AddArgInPhiOp(uint64_t phiId, uint64_t argId, uint64_t predId, uint64_t succId) + { + return gimpleConversion.AddPhiArg(phiId, argId, predId, succId); + } + +-uint64_t PluginClientAPI::CreateCallOp(uint64_t blockId, uint64_t funcId, +- vector &argIds) ++uint64_t PluginClientAPI::CreateCallOp(uint64_t blockId, uint64_t funcId, vector &argIds) + { + return gimpleConversion.CreateGcallVec(blockId, funcId, argIds); + } + +-uint64_t PluginClientAPI::CreateAssignOp(uint64_t blockId, IExprCode iCode, +- vector &argIds) ++uint64_t PluginClientAPI::CreateAssignOp(uint64_t blockId, IExprCode iCode, vector &argIds) + { + return gimpleConversion.CreateGassign(blockId, iCode, argIds); + } +@@ -170,8 +193,7 @@ mlir::Value PluginClientAPI::CreateConstOp(mlir::Attribute attr, mlir::Type type + } + + uint64_t PluginClientAPI::CreateCondOp(uint64_t blockId, IComparisonCode iCode, +- uint64_t LHS, uint64_t RHS, +- uint64_t tbaddr, uint64_t fbaddr) ++ uint64_t LHS, uint64_t RHS, uint64_t tbaddr, uint64_t fbaddr) + { + return gimpleConversion.CreateGcond(blockId, iCode, LHS, RHS, tbaddr, fbaddr); + } +diff --git a/lib/PluginClient/PluginLog.cpp b/lib/PluginClient/PluginLog.cpp +index ad2b985..6cdf7af 100644 +--- a/lib/PluginClient/PluginLog.cpp ++++ b/lib/PluginClient/PluginLog.cpp +@@ -36,6 +36,7 @@ constexpr int LOG_BUF_SIZE = 10240; + constexpr int BASE_DATE = 1900; + static LogPriority g_priority = PRIORITY_WARN; // log打印的级别控制 + static std::mutex g_mutex; // 线程锁 ++static unsigned int g_logFileSize = 10 * 1024 * 1024; + + shared_ptr g_fs; + static void LogWriteInit(const string& data); +@@ -44,16 +45,22 @@ static void (*g_writeToLog)(const string& data) = LogWriteInit; + static void GetLogFileName(string& fileName) + { + time_t nowTime = time(nullptr); ++ if (nowTime == -1) { ++ printf("%s fail\n", __func__); ++ } + struct tm *t = localtime(&nowTime); + char buf[100]; +- sprintf(buf, "/tmp/pin_client%d_%4d%02d%02d_%02d_%02d_%02d.log", getpid(), ++ int ret = sprintf(buf, "/tmp/pin_client%d_%4d%02d%02d_%02d_%02d_%02d.log", getpid(), + t->tm_year + BASE_DATE, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec); ++ if (ret < 0) { ++ printf("%s sprintf fail\n", __func__); ++ } + fileName = buf; + } + + static void LogWriteFile(const string& data) + { +- if (g_fs->tellg() > LOG_FILE_SIZE) { ++ if (g_fs->tellg() > g_logFileSize) { + g_fs->close(); + string fileName; + GetLogFileName(fileName); +@@ -75,7 +82,7 @@ static void LogWriteInit(const string& data) + g_writeToLog(data); + } + +-void CloseLog(void) ++void CloseLog() + { + if (g_fs) { + if (g_fs->is_open()) { +@@ -84,14 +91,24 @@ void CloseLog(void) + } + } + ++void SetLogFileSize(unsigned int size) ++{ ++ g_logFileSize = size; ++} ++ + static void LogWrite(const char *tag, const char *msg) + { + time_t nowTime = time(nullptr); ++ if (nowTime == -1) { ++ printf("%s fail\n", __func__); ++ } + struct tm *t = localtime(&nowTime); + char buf[30]; +- sprintf(buf, "%4d-%02d-%02d %02d:%02d:%02d ", t->tm_year + BASE_DATE, t->tm_mon + 1, t->tm_mday, ++ int ret = sprintf(buf, "%4d-%02d-%02d %02d:%02d:%02d ", t->tm_year + BASE_DATE, t->tm_mon + 1, t->tm_mday, + t->tm_hour, t->tm_min, t->tm_sec); +- ++ if (ret < 0) { ++ printf("%s sprintf fail\n", __func__); ++ } + string stag = tag; + string smsg = msg; + string data = buf + stag + smsg; +@@ -104,7 +121,10 @@ void LogPrint(LogPriority priority, const char *tag, const char *fmt, ...) + char buf[LOG_BUF_SIZE]; + + va_start(ap, fmt); +- vsnprintf(buf, LOG_BUF_SIZE, fmt, ap); ++ int ret = vsnprintf(buf, LOG_BUF_SIZE, fmt, ap); ++ if (ret < 0) { ++ printf("%s vsnprintf fail\n", __func__); ++ } + va_end(ap); + + if (priority <= g_priority) { +diff --git a/lib/Translate/GimpleToPluginOps.cpp b/lib/Translate/GimpleToPluginOps.cpp +index 3a71ffe..b5974aa 100644 +--- a/lib/Translate/GimpleToPluginOps.cpp ++++ b/lib/Translate/GimpleToPluginOps.cpp +@@ -53,7 +53,7 @@ namespace PluginIR { + using namespace mlir::Plugin; + using namespace mlir; + +-namespace detail { ++namespace Detail { + class BlockFromGimpleTranslatorImpl { + public: + std::map blockMaps; +@@ -65,13 +65,13 @@ private: + mlir::MLIRContext &context; + }; + +-} // namespace detail ++} // namespace Detail + +-GimpleToPluginOps::GimpleToPluginOps (mlir::MLIRContext &context) : +- builder(&context), typeTranslator(context), bbTranslator(new detail::BlockFromGimpleTranslatorImpl(context)) ++GimpleToPluginOps::GimpleToPluginOps(mlir::MLIRContext &context) : builder(&context), ++ typeTranslator(context), bbTranslator(new Detail::BlockFromGimpleTranslatorImpl(context)) + {} + +-GimpleToPluginOps::~GimpleToPluginOps () ++GimpleToPluginOps::~GimpleToPluginOps() + {} + + static IComparisonCode TranslateCmpCode(enum tree_code ccode) +@@ -151,7 +151,6 @@ static IExprCode TranslateExprCode(enum tree_code ccode) + case NOP_EXPR: + return IExprCode::Nop; + default: +- // printf("tcc_binary: %d not suppoted!\n", ccode); + break; + } + return IExprCode::UNDEF; +@@ -185,7 +184,6 @@ static enum tree_code TranslateExprCodeToTreeCode(IExprCode ccode) + case IExprCode::Nop: + return NOP_EXPR; + default: +- // printf("tcc_binary: %d not suppoted!\n", ccode); + break; + } + // FIXME. +@@ -220,6 +218,40 @@ static StringRef GimpleCodeToOperationName(enum gimple_code tcode) + return ret; + } + ++string GimpleToPluginOps::DeclSourceFile(uint64_t gccDataAddr) ++{ ++ tree decl = (tree)gccDataAddr; ++ string sourceFile = DECL_SOURCE_FILE(decl); ++ return sourceFile; ++} ++ ++string GimpleToPluginOps::GetVariableName(uint64_t gccDataAddr) ++{ ++ tree decl = (tree)gccDataAddr; ++ string pointer = DECL_NAME(decl) != NULL_TREE ? IDENTIFIER_POINTER(DECL_NAME(decl)) : ""; ++ return pointer; ++} ++ ++string GimpleToPluginOps::GetFuncName(uint64_t gccDataAddr) ++{ ++ string funcName = function_name((function *)gccDataAddr); ++ return funcName; ++} ++ ++int GimpleToPluginOps::DeclSourceLine(uint64_t gccDataAddr) ++{ ++ tree decl = (tree)gccDataAddr; ++ int line = DECL_SOURCE_LINE(decl); ++ return line; ++} ++ ++int GimpleToPluginOps::DeclSourceColumn(uint64_t gccDataAddr) ++{ ++ tree decl = (tree)gccDataAddr; ++ int column = DECL_SOURCE_COLUMN(decl); ++ return column; ++} ++ + uint64_t GimpleToPluginOps::CreateBlock(uint64_t funcAddr, uint64_t bbAddr) + { + basic_block address = reinterpret_cast(bbAddr); +@@ -484,7 +516,7 @@ void GimpleToPluginOps::RedirectFallthroughTarget(uint64_t src, uint64_t dest) + { + basic_block srcbb = reinterpret_cast(reinterpret_cast(src)); + basic_block destbb = reinterpret_cast(reinterpret_cast(dest)); +- assert(single_succ_p (srcbb)); ++ assert(single_succ_p(srcbb)); + redirect_edge_and_branch (single_succ_edge(srcbb), destbb); + } + +@@ -537,7 +569,7 @@ Operation *GimpleToPluginOps::BuildOperation(uint64_t id) + break; + } + case GIMPLE_COND: { +- assert(EDGE_COUNT (stmt->bb->succs) == 2); ++ assert(EDGE_COUNT(stmt->bb->succs) == 2); + Block* trueBlock = bbTranslator->blockMaps[EDGE_SUCC(stmt->bb, 0)->dest]; + Block* falseBlock = bbTranslator->blockMaps[EDGE_SUCC(stmt->bb, 1)->dest]; + CondOp condOp = BuildCondOp(id, (uint64_t)stmt->bb, +@@ -644,15 +676,13 @@ uint64_t GimpleToPluginOps::CreateGcallVec(uint64_t blockId, uint64_t funcId, + gcall *ret = gimple_build_call_vec (fn, vargs); + basic_block bb = reinterpret_cast(blockId); + if (bb != nullptr) { +- gimple_stmt_iterator si; +- si = gsi_last_bb (bb); ++ gimple_stmt_iterator si = gsi_last_bb (bb); + gsi_insert_after (&si, ret, GSI_NEW_STMT); + } + return reinterpret_cast(reinterpret_cast(ret)); + } + +-uint32_t GimpleToPluginOps::AddPhiArg(uint64_t phiId, uint64_t argId, +- uint64_t predId, uint64_t succId) ++uint32_t GimpleToPluginOps::AddPhiArg(uint64_t phiId, uint64_t argId, uint64_t predId, uint64_t succId) + { + gphi *phi = reinterpret_cast(phiId); + tree arg = reinterpret_cast(argId); +@@ -681,31 +711,25 @@ uint64_t GimpleToPluginOps::CreateGassign(uint64_t blockId, IExprCode iCode, + if (iCode == IExprCode::UNDEF) { + ret = gimple_build_assign(vargs[0], vargs[1]); + } else { +- ret = gimple_build_assign(vargs[0], +- TranslateExprCodeToTreeCode(iCode), +- vargs[1]); ++ ret = gimple_build_assign(vargs[0], TranslateExprCodeToTreeCode(iCode), vargs[1]); + } + } else if (vargs.size() == 3) { +- ret = gimple_build_assign(vargs[0], TranslateExprCodeToTreeCode(iCode), +- vargs[1], vargs[2]); ++ ret = gimple_build_assign(vargs[0], TranslateExprCodeToTreeCode(iCode), vargs[1], vargs[2]); + } else if (vargs.size() == 4) { +- ret = gimple_build_assign(vargs[0], TranslateExprCodeToTreeCode(iCode), +- vargs[1], vargs[2], vargs[3]); ++ ret = gimple_build_assign(vargs[0], TranslateExprCodeToTreeCode(iCode), vargs[1], vargs[2], vargs[3]); + } else { + printf("ERROR size: %ld.\n", vargs.size()); + } + basic_block bb = reinterpret_cast(blockId); + if (bb != nullptr) { +- gimple_stmt_iterator si; +- si = gsi_last_bb (bb); ++ gimple_stmt_iterator si = gsi_last_bb (bb); + gsi_insert_after (&si, ret, GSI_NEW_STMT); + } + return reinterpret_cast(reinterpret_cast(ret)); + } + + uint64_t GimpleToPluginOps::CreateGcond(uint64_t blockId, IComparisonCode iCode, +- uint64_t lhsId, uint64_t rhsId, +- uint64_t tbaddr, uint64_t fbaddr) ++ uint64_t lhsId, uint64_t rhsId, uint64_t tbaddr, uint64_t fbaddr) + { + tree lhs = reinterpret_cast(lhsId); + tree rhs = reinterpret_cast(rhsId); +@@ -713,14 +737,13 @@ uint64_t GimpleToPluginOps::CreateGcond(uint64_t blockId, IComparisonCode iCode, + lhs, rhs, NULL_TREE, NULL_TREE); + basic_block bb = reinterpret_cast(blockId); + if (bb != nullptr) { +- gimple_stmt_iterator si; +- si = gsi_last_bb (bb); ++ gimple_stmt_iterator si = gsi_last_bb (bb); + gsi_insert_after (&si, ret, GSI_NEW_STMT); + } + basic_block tb = reinterpret_cast(tbaddr); + basic_block fb = reinterpret_cast(fbaddr); +- assert(make_edge (bb, tb, EDGE_TRUE_VALUE)); +- assert(make_edge (bb, fb, EDGE_FALSE_VALUE)); ++ assert(make_edge(bb, tb, EDGE_TRUE_VALUE)); ++ assert(make_edge(bb, fb, EDGE_FALSE_VALUE)); + return reinterpret_cast(reinterpret_cast(ret)); + } + +@@ -728,12 +751,11 @@ void GimpleToPluginOps::CreateFallthroughOp(uint64_t addr, uint64_t destaddr) + { + basic_block src = reinterpret_cast(addr); + basic_block dest = reinterpret_cast(destaddr); +- assert(make_single_succ_edge (src, dest, EDGE_FALLTHRU)); ++ assert(make_single_succ_edge(src, dest, EDGE_FALLTHRU)); + } + + CondOp GimpleToPluginOps::BuildCondOp(uint64_t gcondId, uint64_t address, +- Block* b1, Block* b2, uint64_t tbaddr, +- uint64_t fbaddr) ++ Block* b1, Block* b2, uint64_t tbaddr, uint64_t fbaddr) + { + gcond *stmt = reinterpret_cast(gcondId); + tree lhsPtr = gimple_cond_lhs(stmt); +@@ -812,16 +834,9 @@ Value GimpleToPluginOps::TreeToValue(uint64_t treeId) + mlir::Value opValue; + switch (TREE_CODE(t)) { + case INTEGER_CST : { +- mlir::Attribute initAttr; +- if (tree_fits_shwi_p(t)) { +- signed HOST_WIDE_INT sinit = tree_to_shwi(t); +- initAttr = builder.getI64IntegerAttr(sinit); +- } else if (tree_fits_uhwi_p(t)) { +- unsigned HOST_WIDE_INT uinit = tree_to_uhwi(t); +- initAttr = builder.getI64IntegerAttr(uinit); +- } else { +- abort(); +- } ++ unsigned HOST_WIDE_INT init = tree_to_uhwi(t); ++ // FIXME : AnyAttr! ++ mlir::Attribute initAttr = builder.getI64IntegerAttr(init); + opValue = builder.create( + builder.getUnknownLoc(), treeId, IDefineCode::IntCST, + readOnly, initAttr, rPluginType); +@@ -863,11 +878,9 @@ Value GimpleToPluginOps::TreeToValue(uint64_t treeId) + void GimpleToPluginOps::DebugValue(uint64_t valId) + { + tree t = reinterpret_cast(valId); +- // debug_tree (t); + } + +-mlir::Value GimpleToPluginOps::BuildMemRef(PluginIR::PluginTypeBase type, +- uint64_t baseId, uint64_t offsetId) ++mlir::Value GimpleToPluginOps::BuildMemRef(PluginIR::PluginTypeBase type, uint64_t baseId, uint64_t offsetId) + { + tree refType = (tree)pluginTypeTranslator.translateType(type); + tree base = (tree)baseId; +@@ -883,7 +896,7 @@ bool GimpleToPluginOps::ProcessGimpleStmt(intptr_t bbPtr, Region& rg) + for (gphi_iterator si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si)) { + gphi *p = si.phi (); + uint64_t id = reinterpret_cast(reinterpret_cast(p)); +- BuildPhiOp(id); // FIXME: Check result. ++ BuildPhiOp(id); // FIXME: Check result. + } + + for (gimple_stmt_iterator si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si)) { +@@ -892,7 +905,7 @@ bool GimpleToPluginOps::ProcessGimpleStmt(intptr_t bbPtr, Region& rg) + if (BuildOperation(id) == nullptr) { + printf("ERROR: BuildOperation!"); + } +- if(gimple_code(stmt) == GIMPLE_COND) { ++ if (gimple_code(stmt) == GIMPLE_COND) { + putTerminator = true; + } + } +@@ -907,7 +920,6 @@ bool GimpleToPluginOps::ProcessGimpleStmt(intptr_t bbPtr, Region& rg) + // Process other condition, such as return + builder.create(builder.getUnknownLoc(), (uint64_t)bb); + } else { +- // Should unreachable; + assert(false); + } + } +diff --git a/lib/Translate/TypeTranslation.cpp b/lib/Translate/TypeTranslation.cpp +index 66521a9..7c7cff4 100644 +--- a/lib/Translate/TypeTranslation.cpp ++++ b/lib/Translate/TypeTranslation.cpp +@@ -49,7 +49,7 @@ + using namespace mlir; + + namespace PluginIR { +-namespace detail { ++namespace Detail { + /* Support for translating Plugin IR types to MLIR Plugin dialect types. */ + class TypeFromPluginIRTranslatorImpl { + public: +@@ -82,7 +82,8 @@ private: + PluginTypeBase translatePrimitiveType (tree type) + { + if (TREE_CODE(type) == INTEGER_TYPE) +- return PluginIntegerType::get(&context, getBitWidth(type), isUnsigned(type) ? PluginIntegerType::Unsigned : PluginIntegerType::Signed); ++ return PluginIntegerType::get(&context, getBitWidth(type), ++ isUnsigned(type) ? PluginIntegerType::Unsigned : PluginIntegerType::Signed); + if (TREE_CODE(type) == REAL_TYPE) + return PluginFloatType::get(&context, getBitWidth(type)); + if (TREE_CODE(type) == BOOLEAN_TYPE) +@@ -90,7 +91,8 @@ private: + if (TREE_CODE(type) == VOID_TYPE) + return PluginVoidType::get(&context); + if (TREE_CODE(type) == POINTER_TYPE) +- return PluginPointerType::get(&context, translatePrimitiveType(TREE_TYPE(type)), TYPE_READONLY(TREE_TYPE(type)) ? 1 : 0); ++ return PluginPointerType::get(&context, translatePrimitiveType(TREE_TYPE(type)), ++ TYPE_READONLY(TREE_TYPE(type)) ? 1 : 0); + return PluginUndefType::get(&context); + } + +@@ -111,19 +113,20 @@ public: + } + + private: +- unsigned getBitWidth (PluginIntegerType type) ++ unsigned getBitWidth(PluginIntegerType type) + { + return type.getWidth(); + } + +- bool isUnsigned (PluginIntegerType type) ++ bool isUnsigned(PluginIntegerType type) + { +- if(type.isUnsigned()) ++ if (type.isUnsigned()) { + return true; ++ } + return false; + } + +- tree translatePrimitiveType (PluginTypeBase type) ++ tree translatePrimitiveType(PluginTypeBase type) + { + if (auto Ty = type.dyn_cast()) { + if (isUnsigned(Ty)) { +@@ -178,14 +181,13 @@ private: + } + return NULL; + } +- + }; + +-} // namespace detail ++} // namespace Detail + } // namespace PluginIR + + PluginIR::TypeFromPluginIRTranslator::TypeFromPluginIRTranslator(mlir::MLIRContext &context) +- : impl(new detail::TypeFromPluginIRTranslatorImpl(context)) {} ++ : impl(new Detail::TypeFromPluginIRTranslatorImpl(context)) {} + + PluginIR::TypeFromPluginIRTranslator::~TypeFromPluginIRTranslator() {} + +@@ -206,7 +208,7 @@ uint64_t PluginIR::TypeFromPluginIRTranslator::getBitWidth(PluginTypeBase type) + + + PluginIR::TypeToPluginIRTranslator::TypeToPluginIRTranslator() +- : impl(new detail::TypeToPluginIRTranslatorImpl()) {} ++ : impl(new Detail::TypeToPluginIRTranslatorImpl()) {} + + PluginIR::TypeToPluginIRTranslator::~TypeToPluginIRTranslator() {} + +diff --git a/lib/IRTrans/IRTransPlugin.cpp b/lib/gccPlugin/gccPlugin.cpp +old mode 100644 +new mode 100755 +similarity index 52% +rename from lib/IRTrans/IRTransPlugin.cpp +rename to lib/gccPlugin/gccPlugin.cpp +index 459cef0..103d709 +--- a/lib/IRTrans/IRTransPlugin.cpp ++++ b/lib/gccPlugin/gccPlugin.cpp +@@ -17,78 +17,81 @@ + Author: Mingchuan Wu and Yancheng Li + Create: 2022-08-18 + Description: +- This file contains the declaration of the PluginAPI class. ++ This file contains the functions of gcc plugin callback and init. ++ 主要完成功能:实现RegisterPluginEvent和RegisterPassManagerSetup功能,完成gcc ++ 版本号检查,当触发注册点对应事件时,回调server注册的用户函数 ++ plugin_init为整个程序入口函数 + */ + +-#include +-#include +-#include + #include +-#include + #include "PluginClient/PluginClient.h" + #include "plugin-version.h" +-#include "IRTrans/IRTransPlugin.h" +-#include "context.h" + #include "tree-pass.h" + #include "tree.h" +-#include "tree-cfg.h" ++#include "context.h" ++#include "gccPlugin/gccPlugin.h" + + using namespace PinClient; + +-using std::vector; + int plugin_is_GPL_compatible; + static pid_t g_serverPid; + +-/* gcc插件end事件回调函数 */ +-static void GccEnd(void *gccData, void *userData) ++/* gcc插件end事件回调函数,停止插件服务端,等待子进程结束,删除端口号 */ ++void GccEnd(void *gccData, void *userData) + { + int status = 0; +- std::shared_ptr client = PluginClient::GetInstance(); +- if (client == nullptr) { ++ PluginClient *client = PluginClient::GetInstance(); ++ if (!client->GetStartFlag()) { + return; + } ++ + LOGI("gcc optimize has been done! now close server...\n"); + client->ReceiveSendMsg("stop", ""); + if (client->GetUserFuncState() != STATE_TIMEOUT) { + waitpid(g_serverPid, &status, 0); + } else { +- client->DeletePortFromLockFile(client->GetGrpcPort()); ++ client->DeleteGrpcPort(); + } +- + LOGI("client pid:%d quit\n", getpid()); + } + ++static void WaitIRTrans(void *gccData, PluginClient *client) ++{ ++ while (1) { ++ UserFuncStateEnum state = client->GetUserFuncState(); ++ /* server获取到client对应函数的执行结果后,向client回复已执行完,跳出循环执行下一个函数 */ ++ if (state == STATE_END) { ++ client->SetUserFuncState(STATE_WAIT_BEGIN); ++ break; ++ } else if (state == STATE_TIMEOUT) { ++ break; ++ } else if (state == STATE_BEGIN) { ++ string funcName = client->GetPluginAPIName(); ++ string param = client->GetPluginAPIParam(); ++ if (funcName != "") { ++ client->SetUserFuncState(STATE_WAIT_IR); ++ client->GetIRTransResult(gccData, funcName, param); ++ } ++ } ++ } ++} ++ + /* gcc插件回调函数,当注册的plugin_event触发时,进入此函数 */ +-static void GccEventCallback(void *gccData, void *userData) ++void GccEventCallback(void *gccData, void *userData) + { +- std::shared_ptr client = PluginClient::GetInstance(); ++ PluginClient *client = PluginClient::GetInstance(); + InjectPoint *inject = (InjectPoint *)userData; + vector userFuncs = client->GetFuncNameByInject(*inject); + string key = "injectPoint"; + string value; ++ + for (auto &userFunc : userFuncs) { + if (client->GetUserFuncState() == STATE_TIMEOUT) { + break; + } + value = std::to_string(*inject) + ":" + userFunc; + client->ReceiveSendMsg(key, value); +- while (1) { +- UserFuncStateEnum state = client->GetUserFuncState(); +- /* server获取到client对应函数的执行结果后,向client回复已执行完,跳出循环执行下一个函数 */ +- if (state == STATE_END) { +- client->SetUserFuncState(STATE_WAIT_BEGIN); +- break; +- } else if (state == STATE_TIMEOUT) { +- break; +- } else if (state == STATE_BEGIN) { +- string funcName = client->GetPluginAPIName(); +- string param = client->GetPluginAPIParam(); +- if (funcName != "") { +- client->SetUserFuncState(STATE_WAIT_IR); +- client->IRTransBegin(funcName, param); +- } +- } +- } ++ WaitIRTrans(gccData, client); + } + LOGI("%s end!\n", __func__); + } +@@ -107,6 +110,7 @@ static InjectPoint g_event[] = { + HANDLE_AFTER_ALL_PASS, + HANDLE_COMPILE_END, + HANDLE_MANAGER_SETUP, ++ HANDLE_INCLUDE_FILE, + HANDLE_MAX + }; + +@@ -121,84 +125,67 @@ int RegisterPluginEvent(InjectPoint inject, const string& pluginName) + return 0; + } + +-void ManagerSetupCallback(void) ++static void ManagerSetupCallback(unsigned int index, function *fun) + { + string key = "injectPoint"; + InjectPoint inject = HANDLE_MANAGER_SETUP; +- std::shared_ptr client = PluginClient::GetInstance(); ++ PluginClient *client = PluginClient::GetInstance(); + vector userFuncs = client->GetFuncNameByInject(inject); +- for (auto &userFunc : userFuncs) { +- if (client->GetUserFuncState() == STATE_TIMEOUT) { +- break; +- } +- string value = std::to_string(inject) + ":" + userFunc; ++ if (index < userFuncs.size()) { ++ string name = userFuncs[index].substr(0, userFuncs[index].find_first_of(",")); ++ string value = std::to_string(inject) + ":" + name + ",params:" + std::to_string((uintptr_t)fun); + client->ReceiveSendMsg(key, value); +- while (1) { +- UserFuncStateEnum state = client->GetUserFuncState(); +- /* server获取到client对应函数的执行结果后,向client回复已执行完,跳出循环执行下一个函数 */ +- if (state == STATE_END) { +- client->SetUserFuncState(STATE_WAIT_BEGIN); +- break; +- } else if (state == STATE_TIMEOUT) { +- break; +- } else if (state == STATE_BEGIN) { +- string funcName = client->GetPluginAPIName(); +- string param = client->GetPluginAPIParam(); +- if (funcName != "") { +- client->SetUserFuncState(STATE_WAIT_IR); +- client->IRTransBegin(funcName, param); +- } +- } +- } ++ WaitIRTrans(nullptr, client); + } + } + +-struct RltPass: rtl_opt_pass { ++struct RtlPass: rtl_opt_pass { + public: +- RltPass(pass_data passData): rtl_opt_pass(passData, g) ++ RtlPass(pass_data passData, unsigned int indx): rtl_opt_pass(passData, g), index(indx) + { + } +- unsigned int execute(function *fun) override ++ /* unsigned int execute(function *fun) override + { +- ManagerSetupCallback(); ++ ManagerSetupCallback(index, fun); + return 0; +- } +- RltPass* clone() override +- { +- return this; +- } ++ } */ ++ ++private: ++ unsigned int index; + }; + + struct SimpleIPAPass: simple_ipa_opt_pass { + public: +- SimpleIPAPass(pass_data passData): simple_ipa_opt_pass(passData, g) ++ SimpleIPAPass(pass_data passData, unsigned int indx): simple_ipa_opt_pass(passData, g), index(indx) + { + } +- unsigned int execute(function *fun) override ++ /* unsigned int execute(function *fun) override + { +- ManagerSetupCallback(); ++ ManagerSetupCallback(index, fun); + return 0; +- } +- SimpleIPAPass* clone() override +- { +- return this; +- } ++ } */ ++ ++private: ++ unsigned int index; + }; + + struct GimplePass: gimple_opt_pass { + public: +- GimplePass(pass_data passData): gimple_opt_pass(passData, g) ++ GimplePass(pass_data passData, unsigned int indx): gimple_opt_pass(passData, g), index(indx) + { + } + unsigned int execute(function *fun) override + { +- ManagerSetupCallback(); ++ ManagerSetupCallback(index, fun); + return 0; + } + GimplePass* clone() override + { + return this; + } ++ ++private: ++ unsigned int index; + }; + + static std::map g_refPassName { +@@ -208,16 +195,13 @@ static std::map g_refPassName { + {PASS_LOOP, "loop"}, + }; + +-int RegisterPassManagerSetup(InjectPoint inject, const ManagerSetupData& setupData, const string& pluginName) ++void RegisterPassManagerSetup(unsigned int index, const ManagerSetupData& setupData, const string& pluginName) + { +- if (inject != HANDLE_MANAGER_SETUP) { +- return -1; +- } +- + struct register_pass_info passInfo; ++ string passDataName = "managerSetupPass_" + g_refPassName[setupData.refPassName]; + pass_data passData = { + .type = GIMPLE_PASS, +- .name = "managerSetupPass", ++ .name = passDataName.c_str(), + .optinfo_flags = OPTGROUP_NONE, + .tv_id = TV_NONE, + .properties_required = 0, +@@ -233,27 +217,28 @@ int RegisterPassManagerSetup(InjectPoint inject, const ManagerSetupData& setupDa + switch (setupData.refPassName) { + case PASS_CFG: + passData.type = GIMPLE_PASS; +- passInfo.pass = new GimplePass(passData); ++ passInfo.pass = new GimplePass(passData, index); + break; + case PASS_PHIOPT: + passData.type = GIMPLE_PASS; +- passInfo.pass = new GimplePass(passData); ++ passInfo.pass = new GimplePass(passData, index); + break; + case PASS_SSA: + passData.type = GIMPLE_PASS; +- passInfo.pass = new GimplePass(passData); ++ passInfo.pass = new GimplePass(passData, index); + break; + case PASS_LOOP: + passData.type = GIMPLE_PASS; +- passInfo.pass = new GimplePass(passData); ++ passInfo.pass = new GimplePass(passData, index); + break; + default: +- passInfo.pass = new GimplePass(passData); ++ passInfo.pass = new GimplePass(passData, index); + break; + } + +- register_callback(pluginName.c_str(), PLUGIN_PASS_MANAGER_SETUP, NULL, &passInfo); +- return 0; ++ if (pluginName != "") { ++ register_callback(pluginName.c_str(), PLUGIN_PASS_MANAGER_SETUP, NULL, &passInfo); ++ } + } + + static bool PluginVersionCheck(struct plugin_gcc_version *gccVersion, struct plugin_gcc_version *pluginVersion) +@@ -274,46 +259,14 @@ static bool PluginVersionCheck(struct plugin_gcc_version *gccVersion, struct plu + + int plugin_init(struct plugin_name_args *pluginInfo, struct plugin_gcc_version *version) + { ++ if (!PluginVersionCheck(version, &gcc_version)) { ++ LOGE("incompatible gcc/plugin versions\n"); ++ return 1; ++ } + string pluginName = pluginInfo->base_name; + register_callback(pluginName.c_str(), PLUGIN_FINISH, &GccEnd, NULL); + +- int timeout = 200; // 默认超时时间200ms +- string shaPath; +- string serverPath = ""; +- string arg = ""; +- LogPriority logLevel = PRIORITY_WARN; +- PluginClient::GetArg(pluginInfo, serverPath, arg, logLevel); +- if (PluginClient::GetInitInfo(serverPath, shaPath, timeout) != 0) { +- LOGD("read default info from pin-gcc-client.json fail! use the default timeout=%dms\n", timeout); +- } +- if (serverPath == "") { +- LOGE("server path is NULL!\n"); +- return 0; +- } +- +- if (PluginClient::CheckSHA256(shaPath) != 0) { +- LOGE("sha256 check sha256 file:%s fail!\n", shaPath.c_str()); +- return 0; +- } else { +- LOGD("sha256 check success!\n"); +- } +- +- string port; +- int status; +- if (ServerStart(timeout, serverPath, g_serverPid, port, logLevel) != 0) { +- return 0; +- } +- ClientStart(timeout, arg, pluginName, port); +- std::shared_ptr client = PluginClient::GetInstance(); +- while (1) { +- if ((client->GetInjectFlag()) || (client->GetUserFuncState() == STATE_TIMEOUT)) { +- break; +- } +- if (g_serverPid == waitpid(-1, &status, WNOHANG)) { +- PluginClient::DeletePortFromLockFile((unsigned short)atoi(port.c_str())); +- break; +- } +- } ++ PluginClient::GetInstance()->Init(pluginInfo, pluginName, g_serverPid); + return 0; + } + +-- +2.27.0.windows.1 + diff --git a/0005-Pin-gcc-client-Add-DebugOp.patch b/0005-Pin-gcc-client-Add-DebugOp.patch new file mode 100644 index 0000000000000000000000000000000000000000..8f5a66859ddc6b299c1bd27b56484268640a5720 --- /dev/null +++ b/0005-Pin-gcc-client-Add-DebugOp.patch @@ -0,0 +1,106 @@ +From c0da500cd20a295521d650cfcdb277b66d18bba5 Mon Sep 17 00:00:00 2001 +From: benniaobufeijiushiji +Date: Sun, 19 Feb 2023 11:44:30 +0800 +Subject: [PATCH 5/9] [Pin-gcc-client] Add DebugOp + + +diff --git a/include/Dialect/PluginOps.td b/include/Dialect/PluginOps.td +index c48d002..bac84be 100644 +--- a/include/Dialect/PluginOps.td ++++ b/include/Dialect/PluginOps.td +@@ -235,6 +235,16 @@ def BaseOp : Plugin_Op<"statement_base", [NoSideEffect]> { + ]; + } + ++def DebugOp : Plugin_Op<"debug", [NoSideEffect]> { ++ let summary = "DebugOp."; ++ let description = [{TODO}]; ++ let arguments = (ins UI64Attr:$id); ++ let results = (outs AnyType); ++ let builders = [ ++ OpBuilderDAG<(ins "uint64_t":$id)> ++ ]; ++} ++ + // Terminators + // Opaque builder used for terminator operations that contain successors. + +diff --git a/include/PluginClient/PluginJson.h b/include/PluginClient/PluginJson.h +index 91bd925..a0aac8a 100755 +--- a/include/PluginClient/PluginJson.h ++++ b/include/PluginClient/PluginJson.h +@@ -53,6 +53,7 @@ public: + Json::Value PhiOpJsonSerialize(mlir::Plugin::PhiOp& data); + Json::Value AssignOpJsonSerialize(mlir::Plugin::AssignOp& data); + Json::Value BaseOpJsonSerialize(mlir::Plugin::BaseOp data); ++ Json::Value DebugOpJsonSerialize(mlir::Plugin::DebugOp data); + Json::Value FallThroughOpJsonSerialize(mlir::Plugin::FallThroughOp data, uint64_t&); + Json::Value RetOpJsonSerialize(mlir::Plugin::RetOp data, uint64_t&); + Json::Value ValueJsonSerialize(mlir::Value value); +diff --git a/lib/Dialect/PluginOps.cpp b/lib/Dialect/PluginOps.cpp +index 052ebfd..da5f3f3 100644 +--- a/lib/Dialect/PluginOps.cpp ++++ b/lib/Dialect/PluginOps.cpp +@@ -243,6 +243,15 @@ void BaseOp::build(OpBuilder &builder, OperationState &state, uint64_t id, Strin + state.addAttribute("opCode", builder.getStringAttr(opCode)); + } + ++//===----------------------------------------------------------------------===// ++// DebugOp ++ ++void DebugOp::build(OpBuilder &builder, OperationState &state, ++ uint64_t id) ++{ ++ state.addAttribute("id", builder.getI64IntegerAttr(id)); ++} ++ + // ===----------------------------------------------------------------------===// + // FallThroughOp + +diff --git a/lib/PluginClient/PluginJson.cpp b/lib/PluginClient/PluginJson.cpp +index 22cd489..ccadf10 100755 +--- a/lib/PluginClient/PluginJson.cpp ++++ b/lib/PluginClient/PluginJson.cpp +@@ -182,6 +182,8 @@ Json::Value PluginJson::OperationJsonSerialize(mlir::Operation *operation, uint6 + root = RetOpJsonSerialize(op, bbId); + } else if (BaseOp op = llvm::dyn_cast(operation)) { + root = BaseOpJsonSerialize(op); ++ } else if (DebugOp op = llvm::dyn_cast(operation)) { ++ root = DebugOpJsonSerialize(op); + } + root["OperationName"] = operation->getName().getStringRef().str(); + return root; +@@ -203,6 +205,13 @@ Json::Value PluginJson::RetOpJsonSerialize(RetOp data, uint64_t &bbId) + return root; + } + ++Json::Value PluginJson::DebugOpJsonSerialize(DebugOp data) ++{ ++ Json::Value root; ++ root["id"] = std::to_string(data.idAttr().getInt()); ++ return root; ++} ++ + Json::Value PluginJson::FallThroughOpJsonSerialize(FallThroughOp data, uint64_t &bbId) + { + Json::Value root; +diff --git a/lib/Translate/GimpleToPluginOps.cpp b/lib/Translate/GimpleToPluginOps.cpp +index b5974aa..2f46f6f 100644 +--- a/lib/Translate/GimpleToPluginOps.cpp ++++ b/lib/Translate/GimpleToPluginOps.cpp +@@ -579,6 +579,12 @@ Operation *GimpleToPluginOps::BuildOperation(uint64_t id) + ret = condOp.getOperation(); + break; + } ++ case GIMPLE_DEBUG: { ++ DebugOp debugOp = builder.create( ++ builder.getUnknownLoc(), id); ++ ret = debugOp.getOperation(); ++ break; ++ } + default: { + BaseOp baseOp = builder.create( + builder.getUnknownLoc(), id, BaseOp::getOperationName()); +-- +2.27.0.windows.1 + diff --git a/0006-Pin-gcc-client-Bugfix-for-ConstOp.patch b/0006-Pin-gcc-client-Bugfix-for-ConstOp.patch new file mode 100644 index 0000000000000000000000000000000000000000..c83a8f8d9a5161f205b9100344ac9a1ed931af48 --- /dev/null +++ b/0006-Pin-gcc-client-Bugfix-for-ConstOp.patch @@ -0,0 +1,38 @@ +From 3750fd8c57d37a103b698eb7e479a98ccc68bd02 Mon Sep 17 00:00:00 2001 +From: benniaobufeijiushiji +Date: Sun, 19 Feb 2023 11:48:16 +0800 +Subject: [PATCH 6/9] [Pin-gcc-client] Bugfix for ConstOp Support both signed + const int and unsigned const int + + +diff --git a/lib/Translate/GimpleToPluginOps.cpp b/lib/Translate/GimpleToPluginOps.cpp +index 2f46f6f..5ecab75 100644 +--- a/lib/Translate/GimpleToPluginOps.cpp ++++ b/lib/Translate/GimpleToPluginOps.cpp +@@ -840,13 +840,16 @@ Value GimpleToPluginOps::TreeToValue(uint64_t treeId) + mlir::Value opValue; + switch (TREE_CODE(t)) { + case INTEGER_CST : { +- unsigned HOST_WIDE_INT init = tree_to_uhwi(t); +- // FIXME : AnyAttr! +- mlir::Attribute initAttr = builder.getI64IntegerAttr(init); +- opValue = builder.create( +- builder.getUnknownLoc(), treeId, IDefineCode::IntCST, +- readOnly, initAttr, rPluginType); +- break; ++ mlir::Attribute initAttr; ++ if (tree_fits_shwi_p(t)) { ++ signed HOST_WIDE_INT sinit = tree_to_shwi(t); ++ initAttr = builder.getI64IntegerAttr(sinit); ++ } else if (tree_fits_uhwi_p(t)) { ++ unsigned HOST_WIDE_INT uinit = tree_to_uhwi(t); ++ initAttr = builder.getI64IntegerAttr(uinit); ++ } else { ++ abort(); ++ } + } + case MEM_REF : { + tree operand0 = TREE_OPERAND(t, 0); +-- +2.27.0.windows.1 + diff --git a/0007-Pin-gcc-client-Add-API-for-LTO-judgement.patch b/0007-Pin-gcc-client-Add-API-for-LTO-judgement.patch new file mode 100644 index 0000000000000000000000000000000000000000..08e5c38d4334da0fd426260e2ae4f97a4361ea80 --- /dev/null +++ b/0007-Pin-gcc-client-Add-API-for-LTO-judgement.patch @@ -0,0 +1,131 @@ +From 9dc1cc4cb0eeb114ac9b5daea3005f2caa1ccf5b Mon Sep 17 00:00:00 2001 +From: benniaobufeijiushiji +Date: Sun, 19 Feb 2023 14:41:49 +0800 +Subject: [PATCH 7/9] [Pin-gcc-client] Add API for LTO judgement + + +diff --git a/include/PluginAPI/BasicPluginOpsAPI.h b/include/PluginAPI/BasicPluginOpsAPI.h +index 8c47c58..ca74588 100644 +--- a/include/PluginAPI/BasicPluginOpsAPI.h ++++ b/include/PluginAPI/BasicPluginOpsAPI.h +@@ -95,6 +95,9 @@ public: + virtual mlir::Value BuildMemRef(PluginTypeBase, uint64_t, uint64_t) = 0; + virtual void RedirectFallthroughTarget(uint64_t, uint64_t) = 0; + virtual void RemoveEdge(uint64_t, uint64_t) = 0; ++ ++ virtual bool IsLtoOptimize() = 0; ++ virtual bool IsWholeProgram() = 0; + }; // class BasicPluginOpsAPI + } // namespace PluginAPI + +diff --git a/include/PluginAPI/PluginClientAPI.h b/include/PluginAPI/PluginClientAPI.h +index 07d6e52..727d329 100644 +--- a/include/PluginAPI/PluginClientAPI.h ++++ b/include/PluginAPI/PluginClientAPI.h +@@ -95,6 +95,9 @@ public: + + void RedirectFallthroughTarget(uint64_t, uint64_t) override; + void RemoveEdge(uint64_t, uint64_t) override; ++ ++ bool IsLtoOptimize() override; ++ bool IsWholeProgram() override; + private: + PluginIR::GimpleToPluginOps gimpleConversion; + }; // class PluginClientAPI +diff --git a/include/Translate/GimpleToPluginOps.h b/include/Translate/GimpleToPluginOps.h +index 5f8bdf0..2ecf5ac 100644 +--- a/include/Translate/GimpleToPluginOps.h ++++ b/include/Translate/GimpleToPluginOps.h +@@ -106,6 +106,10 @@ public: + + void RedirectFallthroughTarget(uint64_t, uint64_t); + void RemoveEdge(uint64_t, uint64_t); ++ ++ bool IsLtoOptimize(); ++ bool IsWholeProgram(); ++ + private: + GimpleToPluginOps () = delete; + mlir::OpBuilder builder; +diff --git a/lib/PluginAPI/PluginClientAPI.cpp b/lib/PluginAPI/PluginClientAPI.cpp +index 5e454d7..362ede1 100644 +--- a/lib/PluginAPI/PluginClientAPI.cpp ++++ b/lib/PluginAPI/PluginClientAPI.cpp +@@ -280,4 +280,14 @@ void PluginClientAPI::RemoveEdge(uint64_t src, uint64_t dest) + return gimpleConversion.RemoveEdge(src, dest); + } + ++bool PluginClientAPI::IsLtoOptimize() ++{ ++ return gimpleConversion.IsLtoOptimize(); ++} ++ ++bool PluginClientAPI::IsWholeProgram() ++{ ++ return gimpleConversion.IsWholeProgram(); ++} ++ + } // namespace PluginAPI +\ No newline at end of file +diff --git a/lib/PluginClient/PluginClient.cpp b/lib/PluginClient/PluginClient.cpp +index 18877c2..81b59c0 100644 +--- a/lib/PluginClient/PluginClient.cpp ++++ b/lib/PluginClient/PluginClient.cpp +@@ -820,6 +820,24 @@ void DebugValueResult(PluginClient *client, Json::Value& root, string& result) + client->ReceiveSendMsg("ValueResult", result); + } + ++void IsLtoOptimizeResult(PluginClient *client, Json::Value& root, string& result) ++{ ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ bool lto = clientAPI.IsLtoOptimize(); ++ client->ReceiveSendMsg("BoolResult", std::to_string(lto)); ++} ++ ++void IsWholeProgramResult(PluginClient *client, Json::Value& root, string& result) ++{ ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ bool wholePR = clientAPI.IsWholeProgram(); ++ client->ReceiveSendMsg("BoolResult", std::to_string(wholePR)); ++} ++ + typedef std::function GetResultFunc; + std::map g_getResultFunc = { + {"GetAllFunc", GetAllFuncResult}, +@@ -868,6 +886,8 @@ std::map g_getResultFunc = { + {"ConfirmValue", ConfirmValueResult}, + {"BuildMemRef", BuildMemRefResult}, + {"DebugValue", DebugValueResult}, ++ {"IsLtoOptimize",IsLtoOptimizeResult}, ++ {"IsWholeProgram",IsWholeProgramResult}, + }; + + void PluginClient::GetIRTransResult(void *gccData, const string& funcName, const string& param) +diff --git a/lib/Translate/GimpleToPluginOps.cpp b/lib/Translate/GimpleToPluginOps.cpp +index 5ecab75..c4e5611 100644 +--- a/lib/Translate/GimpleToPluginOps.cpp ++++ b/lib/Translate/GimpleToPluginOps.cpp +@@ -529,6 +529,16 @@ void GimpleToPluginOps::RemoveEdge(uint64_t src, uint64_t dest) + remove_edge(e); + } + ++bool GimpleToPluginOps::IsLtoOptimize() ++{ ++ return in_lto_p; ++} ++ ++bool GimpleToPluginOps::IsWholeProgram() ++{ ++ return flag_whole_program; ++} ++ + FunctionOp GimpleToPluginOps::BuildFunctionOp(uint64_t functionId) + { + function *fn = reinterpret_cast(functionId); +-- +2.27.0.windows.1 + diff --git a/0008-Pin-gcc-client-Fix-bug-for-BuildCallOp.patch b/0008-Pin-gcc-client-Fix-bug-for-BuildCallOp.patch new file mode 100644 index 0000000000000000000000000000000000000000..cb294ad5ebb47107fb5fada07e289d74c0514a81 --- /dev/null +++ b/0008-Pin-gcc-client-Fix-bug-for-BuildCallOp.patch @@ -0,0 +1,115 @@ +From d8c42ec77001c29291a31484031cb7b5f2b52d48 Mon Sep 17 00:00:00 2001 +From: Mingchuan Wu +Date: Tue, 21 Feb 2023 16:53:09 +0800 +Subject: [PATCH 8/9] [Pin-gcc-client] Fix bug for BuildCallOp. Now we can + convert the function pointer. + + +diff --git a/include/Dialect/PluginOps.td b/include/Dialect/PluginOps.td +index bac84be..713623c 100644 +--- a/include/Dialect/PluginOps.td ++++ b/include/Dialect/PluginOps.td +@@ -85,12 +85,15 @@ def CallOp : Plugin_Op<"call", [ + The arguments list must match the arguments expected by the callee. + }]; + let arguments = (ins UI64Attr:$id, +- FlatSymbolRefAttr:$callee, ++ OptionalAttr:$callee, + Variadic:$inputs); + let results = (outs Optional:$result); + let builders = [ + OpBuilderDAG<(ins "uint64_t":$id, "StringRef":$callee, +- "ArrayRef":$arguments, "Type":$retType)> ++ "ArrayRef":$arguments, "Type":$retType)>, ++ OpBuilderDAG<(ins "uint64_t":$id, ++ "ArrayRef":$arguments, ++ "Type":$retType)> + ]; + let extraClassDeclaration = [{ + Type getResultType() { return this->getOperation()->getResult(0).getType(); } +diff --git a/lib/Dialect/PluginOps.cpp b/lib/Dialect/PluginOps.cpp +index da5f3f3..1ea3b5a 100644 +--- a/lib/Dialect/PluginOps.cpp ++++ b/lib/Dialect/PluginOps.cpp +@@ -146,6 +146,14 @@ void CallOp::build(OpBuilder &builder, OperationState &state, + if (retType != nullptr) state.addTypes(retType); + } + ++void CallOp::build(OpBuilder &builder, OperationState &state, ++ uint64_t id, ArrayRef arguments, Type retType) ++{ ++ state.addAttribute("id", builder.getI64IntegerAttr(id)); ++ state.addOperands(arguments); ++ if (retType != nullptr) state.addTypes(retType); ++} ++ + /// Return the callee of the generic call operation, this is required by the + /// call interface. + CallInterfaceCallable CallOp::getCallableForCallee() +diff --git a/lib/PluginClient/PluginJson.cpp b/lib/PluginClient/PluginJson.cpp +index ccadf10..966d35e 100755 +--- a/lib/PluginClient/PluginJson.cpp ++++ b/lib/PluginClient/PluginJson.cpp +@@ -341,7 +341,10 @@ Json::Value PluginJson::CallOpJsonSerialize(CallOp& data) + { + Json::Value item; + item["id"] = std::to_string(data.idAttr().getInt()); +- item["callee"] = data.callee().str(); ++ Optional calleeName = data.callee(); ++ if (calleeName) { ++ item["callee"] = calleeName->str(); ++ } + item["OperationName"] = data.getOperation()->getName().getStringRef().str(); + size_t opIdx = 0; + for (mlir::Value v : data.getArgOperands()) { +diff --git a/lib/Translate/GimpleToPluginOps.cpp b/lib/Translate/GimpleToPluginOps.cpp +index c4e5611..515e5e6 100644 +--- a/lib/Translate/GimpleToPluginOps.cpp ++++ b/lib/Translate/GimpleToPluginOps.cpp +@@ -645,10 +645,6 @@ uint64_t GimpleToPluginOps::CreateGphiNode(uint64_t argId, uint64_t blockId) + CallOp GimpleToPluginOps::BuildCallOp(uint64_t gcallId) + { + gcall *stmt = reinterpret_cast(gcallId); +- tree fndecl = gimple_call_fndecl(stmt); +- if (fndecl == NULL_TREE || DECL_NAME(fndecl) == NULL_TREE) { +- return nullptr; +- } + llvm::SmallVector ops; + ops.reserve(gimple_call_num_args(stmt)); + for (unsigned i = 0; i < gimple_call_num_args(stmt); i++) { +@@ -658,11 +654,18 @@ CallOp GimpleToPluginOps::BuildCallOp(uint64_t gcallId) + Value arg = TreeToValue(argId); + ops.push_back(arg); + } +- StringRef callName(IDENTIFIER_POINTER(DECL_NAME(fndecl))); + tree returnType = gimple_call_return_type(stmt); + PluginTypeBase rPluginType = typeTranslator.translateType((intptr_t)returnType); +- CallOp ret = builder.create(builder.getUnknownLoc(), +- gcallId, callName, ops, rPluginType); ++ tree fndecl = gimple_call_fndecl(stmt); ++ CallOp ret; ++ if (fndecl == NULL_TREE || DECL_NAME(fndecl) == NULL_TREE) { ++ ret = builder.create(builder.getUnknownLoc(), ++ gcallId, ops, rPluginType); ++ } else { ++ StringRef callName(IDENTIFIER_POINTER(DECL_NAME(fndecl))); ++ ret = builder.create(builder.getUnknownLoc(), ++ gcallId, callName, ops, rPluginType); ++ } + return ret; + } + +@@ -860,6 +863,10 @@ Value GimpleToPluginOps::TreeToValue(uint64_t treeId) + } else { + abort(); + } ++ opValue = builder.create( ++ builder.getUnknownLoc(), treeId, IDefineCode::IntCST, ++ readOnly, initAttr, rPluginType); ++ break; + } + case MEM_REF : { + tree operand0 = TREE_OPERAND(t, 0); +-- +2.27.0.windows.1 + diff --git a/0009-Pin-gcc-client-Support-functiontype-structtype.eg.patch b/0009-Pin-gcc-client-Support-functiontype-structtype.eg.patch new file mode 100644 index 0000000000000000000000000000000000000000..833bffd4e200a3574768bb18ae98ae9889ee31f0 --- /dev/null +++ b/0009-Pin-gcc-client-Support-functiontype-structtype.eg.patch @@ -0,0 +1,721 @@ +From 307831e1210fd9aa4453d774308f63812198b555 Mon Sep 17 00:00:00 2001 +From: d00573793 +Date: Tue, 21 Feb 2023 11:09:39 +0800 +Subject: [PATCH 9/9] [Pin-gcc-client] Support functiontype structtype.eg. + + +diff --git a/include/Dialect/PluginOps.td b/include/Dialect/PluginOps.td +index c48d002..64a0c3d 100644 +--- a/include/Dialect/PluginOps.td ++++ b/include/Dialect/PluginOps.td +@@ -32,15 +32,19 @@ def FunctionOp : Plugin_Op<"function", [NoSideEffect]> { + + let arguments = (ins UI64Attr:$id, + StrAttr:$funcName, +- OptionalAttr:$declaredInline); ++ OptionalAttr:$declaredInline, ++ TypeAttr:$type); + let regions = (region AnyRegion:$bodyRegion); + + // Add custom build methods for the operation. These method populates + // the `state` that MLIR uses to create operations, i.e. these are used when + // using `builder.create(...)`. + let builders = [ +- OpBuilderDAG<(ins "uint64_t":$id, "StringRef":$funcName, "bool":$declaredInline)> ++ OpBuilderDAG<(ins "uint64_t":$id, "StringRef":$funcName, "bool":$declaredInline, "Type":$type)> + ]; ++ let extraClassDeclaration = [{ ++ Type getResultType(); ++ }]; + } + + def LocalDeclOp : Plugin_Op<"declaration", [NoSideEffect]> { +diff --git a/include/Dialect/PluginTypes.h b/include/Dialect/PluginTypes.h +index 157b868..da16886 100644 +--- a/include/Dialect/PluginTypes.h ++++ b/include/Dialect/PluginTypes.h +@@ -78,6 +78,9 @@ namespace Detail { + struct PluginIntegerTypeStorage; + struct PluginFloatTypeStorage; + struct PluginPointerTypeStorage; ++ struct PluginTypeAndSizeStorage; ++ struct PluginFunctionTypeStorage; ++ struct PluginStructTypeStorage; + } + + class PluginIntegerType : public Type::TypeBase { +@@ -128,6 +131,60 @@ public: + unsigned isReadOnlyElem(); + }; // class PluginPointerType + ++class PluginArrayType : public Type::TypeBase { ++public: ++ using Base::Base; ++ ++ PluginTypeID getPluginTypeID (); ++ ++ static bool isValidElementType(Type type); ++ ++ static PluginArrayType get(MLIRContext *context, Type elementType, unsigned numElements); ++ ++ Type getElementType(); ++ ++ unsigned getNumElements(); ++}; // class PluginArrayType ++ ++class PluginFunctionType : public Type::TypeBase { ++public: ++ using Base::Base; ++ ++ PluginTypeID getPluginTypeID (); ++ ++ static bool isValidArgumentType(Type type); ++ ++ static bool isValidResultType(Type type); ++ ++ static PluginFunctionType get(MLIRContext *context, Type result, ArrayRef arguments); ++ ++ Type getReturnType(); ++ ++ unsigned getNumParams(); ++ ++ Type getParamType(unsigned i); ++ ++ ArrayRef getParams(); ++}; // class PluginFunctionType ++ ++class PluginStructType : public Type::TypeBase { ++public: ++ using Base::Base; ++ ++ PluginTypeID getPluginTypeID (); ++ ++ static bool isValidElementType(Type type); ++ ++ static PluginStructType get(MLIRContext *context, StringRef name, ArrayRef elements, ArrayRef elemNames); ++ ++ StringRef getName(); ++ ++ ArrayRef getBody(); ++ ++ ArrayRef getElementNames(); ++ ++}; // class PluginStructType ++ + class PluginVoidType : public Type::TypeBase { + public: + using Base::Base; +diff --git a/include/PluginClient/PluginJson.h b/include/PluginClient/PluginJson.h +index 91bd925..3c9fe1f 100755 +--- a/include/PluginClient/PluginJson.h ++++ b/include/PluginClient/PluginJson.h +@@ -59,7 +59,7 @@ public: + Json::Value MemOpJsonSerialize(mlir::Plugin::MemOp& data); + Json::Value SSAOpJsonSerialize(mlir::Plugin::SSAOp& data); + /* 将Type类型数据序列化 */ +- Json::Value TypeJsonSerialize(PluginIR::PluginTypeBase& type); ++ Json::Value TypeJsonSerialize(PluginIR::PluginTypeBase type); + PluginIR::PluginTypeBase TypeJsonDeSerialize(const string& data, mlir::MLIRContext &context); + /* 将整数型数据序列化 */ + void IntegerSerialize(int64_t data, string& out); +diff --git a/lib/Dialect/PluginDialect.cpp b/lib/Dialect/PluginDialect.cpp +index 527c076..69a0aa5 100644 +--- a/lib/Dialect/PluginDialect.cpp ++++ b/lib/Dialect/PluginDialect.cpp +@@ -38,6 +38,9 @@ void PluginDialect::initialize() + addTypes(); +diff --git a/lib/Dialect/PluginOps.cpp b/lib/Dialect/PluginOps.cpp +index 052ebfd..db2574c 100644 +--- a/lib/Dialect/PluginOps.cpp ++++ b/lib/Dialect/PluginOps.cpp +@@ -24,6 +24,7 @@ + + #include "Dialect/PluginDialect.h" + #include "Dialect/PluginOps.h" ++#include "Dialect/PluginTypes.h" + + #include "mlir/IR/Builders.h" + #include "mlir/IR/BuiltinTypes.h" +@@ -32,13 +33,20 @@ + using namespace mlir; + using namespace mlir::Plugin; + +-void FunctionOp::build(mlir::OpBuilder &builder, mlir::OperationState &state, +- uint64_t id, StringRef funcName, bool declaredInline) ++void FunctionOp::build(OpBuilder &builder, OperationState &state, ++ uint64_t id, StringRef funcName, bool declaredInline, Type type) + { +- FunctionOp::build(builder, state, +- builder.getI64IntegerAttr(id), +- builder.getStringAttr(funcName), +- builder.getBoolAttr(declaredInline)); ++ state.addRegion(); ++ state.addAttribute("id", builder.getI64IntegerAttr(id)); ++ state.addAttribute("funcName", builder.getStringAttr(funcName)); ++ state.addAttribute("declaredInline", builder.getBoolAttr(declaredInline)); ++ if (type) state.addAttribute("type", TypeAttr::get(type)); ++} ++ ++Type FunctionOp::getResultType() ++{ ++ PluginIR::PluginFunctionType resultType = type().dyn_cast(); ++ return resultType; + } + + void LocalDeclOp::build(mlir::OpBuilder &builder, mlir::OperationState &state, +diff --git a/lib/Dialect/PluginTypes.cpp b/lib/Dialect/PluginTypes.cpp +index 396bf0f..329a2b6 100644 +--- a/lib/Dialect/PluginTypes.cpp ++++ b/lib/Dialect/PluginTypes.cpp +@@ -98,6 +98,80 @@ namespace Detail { + Type pointee; + unsigned readOnlyPointee; + }; ++ ++ struct PluginTypeAndSizeStorage : public TypeStorage { ++ using KeyTy = std::tuple; ++ ++ PluginTypeAndSizeStorage(const KeyTy &key) ++ : elementType(std::get<0>(key)), numElements(std::get<1>(key)) {} ++ ++ static PluginTypeAndSizeStorage *construct(TypeStorageAllocator &allocator, KeyTy key) ++ { ++ return new (allocator.allocate()) ++ PluginTypeAndSizeStorage(key); ++ } ++ ++ bool operator==(const KeyTy &key) const ++ { ++ return std::make_tuple(elementType, numElements) == key; ++ } ++ ++ Type elementType; ++ unsigned numElements; ++ }; ++ ++ struct PluginFunctionTypeStorage : public TypeStorage { ++ using KeyTy = std::tuple>; ++ ++ PluginFunctionTypeStorage(Type resultType, ArrayRef argumentTypes) ++ : resultType(resultType), argumentTypes(argumentTypes) {} ++ ++ static PluginFunctionTypeStorage *construct(TypeStorageAllocator &allocator, KeyTy key) ++ { ++ return new (allocator.allocate()) ++ PluginFunctionTypeStorage(std::get<0>(key), allocator.copyInto(std::get<1>(key))); ++ } ++ ++ static unsigned hashKey(const KeyTy &key) { ++ // LLVM doesn't like hashing bools in tuples. ++ return llvm::hash_combine(std::get<0>(key), std::get<1>(key)); ++ } ++ ++ bool operator==(const KeyTy &key) const ++ { ++ return std::make_tuple(resultType, argumentTypes) == key; ++ } ++ ++ Type resultType; ++ ArrayRef argumentTypes; ++ }; ++ ++ struct PluginStructTypeStorage : public TypeStorage { ++ using KeyTy = std::tuple, ArrayRef>; ++ ++ PluginStructTypeStorage(StringRef name, ArrayRef elements, ArrayRef elemNames) ++ : name(name), elements(elements), elemNames(elemNames) {} ++ ++ static PluginStructTypeStorage *construct(TypeStorageAllocator &allocator, KeyTy key) ++ { ++ return new (allocator.allocate()) ++ PluginStructTypeStorage(std::get<0>(key), allocator.copyInto(std::get<1>(key)), allocator.copyInto(std::get<2>(key))); ++ } ++ ++ static unsigned hashKey(const KeyTy &key) { ++ // LLVM doesn't like hashing bools in tuples. ++ return llvm::hash_combine(std::get<0>(key), std::get<1>(key), std::get<2>(key)); ++ } ++ ++ bool operator==(const KeyTy &key) const ++ { ++ return std::make_tuple(name, elements, elemNames) == key; ++ } ++ ++ StringRef name; ++ ArrayRef elements; ++ ArrayRef elemNames; ++ }; + } // namespace Detail + } // namespace PluginIR + +@@ -123,6 +197,15 @@ PluginTypeID PluginTypeBase::getPluginTypeID () + if (auto Ty = dyn_cast()) { + return Ty.getPluginTypeID (); + } ++ if (auto Ty = dyn_cast()) { ++ return Ty.getPluginTypeID (); ++ } ++ if (auto Ty = dyn_cast()) { ++ return Ty.getPluginTypeID (); ++ } ++ if (auto Ty = dyn_cast()) { ++ return Ty.getPluginTypeID (); ++ } + return PluginTypeID::UndefTyID; + } + +@@ -295,3 +378,108 @@ PluginPointerType PluginPointerType::get (MLIRContext *context, Type pointee, un + { + return Base::get(context, pointee, readOnlyPointee); + } ++ ++ ++// ===----------------------------------------------------------------------===// ++// Plugin Array Type ++// ===----------------------------------------------------------------------===// ++ ++PluginTypeID PluginArrayType::getPluginTypeID() ++{ ++ return PluginTypeID::ArrayTyID; ++} ++ ++bool PluginArrayType::isValidElementType(Type type) ++{ ++ return !type.isa(); ++} ++ ++PluginArrayType PluginArrayType::get(MLIRContext *context, Type elementType, unsigned numElements) ++{ ++ return Base::get(context, elementType, numElements); ++} ++ ++Type PluginArrayType::getElementType() ++{ ++ return getImpl()->elementType; ++} ++ ++unsigned PluginArrayType::getNumElements() ++{ ++ return getImpl()->numElements; ++} ++ ++// ===----------------------------------------------------------------------===// ++// Plugin Function Type ++// ===----------------------------------------------------------------------===// ++ ++PluginTypeID PluginFunctionType::getPluginTypeID() ++{ ++ return PluginTypeID::FunctionTyID; ++} ++ ++bool PluginFunctionType::isValidArgumentType(Type type) ++{ ++ return !type.isa(); ++} ++ ++bool PluginFunctionType::isValidResultType(Type type) { ++ return !type.isa(); ++} ++ ++PluginFunctionType PluginFunctionType::get(MLIRContext *context, Type result, ArrayRef arguments) ++{ ++ return Base::get(context, result, arguments); ++} ++ ++Type PluginFunctionType::getReturnType() ++{ ++ return getImpl()->resultType; ++} ++ ++unsigned PluginFunctionType::getNumParams() ++{ ++ return getImpl()->argumentTypes.size(); ++} ++ ++Type PluginFunctionType::getParamType(unsigned i) { ++ return getImpl()->argumentTypes[i]; ++} ++ ++ArrayRef PluginFunctionType::getParams() ++{ ++ return getImpl()->argumentTypes; ++} ++ ++// ===----------------------------------------------------------------------===// ++// Plugin Struct Type ++// ===----------------------------------------------------------------------===// ++ ++PluginTypeID PluginStructType::getPluginTypeID() ++{ ++ return PluginTypeID::StructTyID; ++} ++ ++bool PluginStructType::isValidElementType(Type type) { ++ return !type.isa(); ++} ++ ++PluginStructType PluginStructType::get(MLIRContext *context, StringRef name, ArrayRef elements, ArrayRef elemNames) ++{ ++ return Base::get(context, name, elements, elemNames); ++} ++ ++StringRef PluginStructType::getName() ++{ ++ return getImpl()->name; ++} ++ ++ArrayRef PluginStructType::getBody() ++{ ++ return getImpl()->elements; ++} ++ ++ArrayRef PluginStructType::getElementNames() ++{ ++ return getImpl()->elemNames; ++} +\ No newline at end of file +diff --git a/lib/PluginClient/PluginJson.cpp b/lib/PluginClient/PluginJson.cpp +index 22cd489..a9db475 100755 +--- a/lib/PluginClient/PluginJson.cpp ++++ b/lib/PluginClient/PluginJson.cpp +@@ -20,6 +20,7 @@ + This file contains the implementation of the PluginJson class. + */ + ++#include + #include + #include "PluginAPI/PluginClientAPI.h" + #include "PluginClient/PluginLog.h" +@@ -36,7 +37,7 @@ static uintptr_t GetID(Json::Value node) + return atol(id.c_str()); + } + +-Json::Value PluginJson::TypeJsonSerialize(PluginIR::PluginTypeBase& type) ++Json::Value PluginJson::TypeJsonSerialize(PluginIR::PluginTypeBase type) + { + Json::Value root; + Json::Value operationObj; +@@ -48,6 +49,41 @@ Json::Value PluginJson::TypeJsonSerialize(PluginIR::PluginTypeBase& type) + ReTypeId = static_cast(type.getPluginTypeID()); + item["id"] = std::to_string(ReTypeId); + ++ if (auto Ty = type.dyn_cast()) { ++ std::string tyName = Ty.getName().str(); ++ item["structtype"] = tyName; ++ size_t paramIndex = 0; ++ ArrayRef paramsType = Ty.getBody(); ++ for (auto ty :paramsType) { ++ string paramStr = "elemType" + std::to_string(paramIndex++); ++ item["structelemType"][paramStr] = TypeJsonSerialize(ty.dyn_cast()); ++ } ++ paramIndex = 0; ++ ArrayRef paramsNames = Ty.getElementNames(); ++ for (auto name :paramsNames) { ++ string paramStr = "elemName" + std::to_string(paramIndex++); ++ item["structelemName"][paramStr] = name.str(); ++ } ++ } ++ ++ if (auto Ty = type.dyn_cast()) { ++ auto fnrestype = Ty.getReturnType().dyn_cast(); ++ item["fnreturntype"] = TypeJsonSerialize(fnrestype); ++ size_t paramIndex = 0; ++ ArrayRef paramsType = Ty.getParams(); ++ for (auto ty : Ty.getParams()) { ++ string paramStr = "argType" + std::to_string(paramIndex++); ++ item["fnargsType"][paramStr] = TypeJsonSerialize(ty.dyn_cast()); ++ } ++ } ++ ++ if (auto Ty = type.dyn_cast()) { ++ auto elemTy = Ty.getElementType().dyn_cast(); ++ item["elementType"] = TypeJsonSerialize(elemTy); ++ uint64_t elemNum = Ty.getNumElements(); ++ item["arraysize"] = std::to_string(elemNum); ++ } ++ + if (auto elemTy = type.dyn_cast()) { + auto baseTy = elemTy.getElementType().dyn_cast(); + item["elementType"] = TypeJsonSerialize(baseTy); +@@ -104,7 +140,40 @@ PluginIR::PluginTypeBase PluginJson::TypeJsonDeSerialize(const string& data, mli + } else if (id == static_cast(PluginIR::PointerTyID)) { + mlir::Type elemTy = TypeJsonDeSerialize(type["elementType"].toStyledString(), context); + baseType = PluginIR::PluginPointerType::get(&context, elemTy, type["elemConst"].asString() == "1" ? 1 : 0); +- } else { ++ } else if (id == static_cast(PluginIR::ArrayTyID)) { ++ mlir::Type elemTy = TypeJsonDeSerialize(type["elementType"].toStyledString(), context); ++ uint64_t elemNum = GetID(type["arraysize"]); ++ baseType = PluginIR::PluginArrayType::get(&context, elemTy, elemNum); ++ } else if (id == static_cast(PluginIR::FunctionTyID)) { ++ mlir::Type returnTy = TypeJsonDeSerialize(type["fnreturntype"].toStyledString(), context); ++ llvm::SmallVector typelist; ++ Json::Value::Members fnTypeNum = type["fnargsType"].getMemberNames(); ++ uint64_t argsNum = fnTypeNum.size(); ++ for (size_t paramIndex = 0; paramIndex < argsNum; paramIndex++) { ++ string Key = "argType" + std::to_string(paramIndex); ++ mlir::Type paramTy = TypeJsonDeSerialize(type["fnargsType"][Key].toStyledString(), context); ++ typelist.push_back(paramTy); ++ } ++ baseType = PluginIR::PluginFunctionType::get(&context, returnTy, typelist); ++ } else if (id == static_cast(PluginIR::StructTyID)) { ++ StringRef tyName = type["structtype"].toStyledString(); ++ llvm::SmallVector typelist; ++ Json::Value::Members elemTypeNum = type["structelemType"].getMemberNames(); ++ for (size_t paramIndex = 0; paramIndex < elemTypeNum.size(); paramIndex++) { ++ string Key = "elemType" + std::to_string(paramIndex); ++ mlir::Type paramTy = TypeJsonDeSerialize(type["structelemType"][Key].toStyledString(), context); ++ typelist.push_back(paramTy); ++ } ++ llvm::SmallVector names; ++ Json::Value::Members elemNameNum = type["structelemName"].getMemberNames(); ++ for (size_t paramIndex = 0; paramIndex < elemTypeNum.size(); paramIndex++) { ++ string Key = "elemName" + std::to_string(paramIndex); ++ StringRef elemName = type["structelemName"][Key].toStyledString(); ++ names.push_back(elemName); ++ } ++ baseType = PluginIR::PluginStructType::get(&context, tyName, typelist, names); ++ } ++ else { + if (PluginTypeId == PluginIR::VoidTyID) { + baseType = PluginIR::PluginVoidType::get(&context); + } +@@ -127,7 +196,6 @@ void PluginJson::FunctionOpJsonSerialize(vector& data, string& out) + + int i = 0; + string operation; +- + for (auto& d: data) { + item["id"] = std::to_string(d.idAttr().getInt()); + if (d.declaredInlineAttr().getValue()) { +@@ -136,6 +204,14 @@ void PluginJson::FunctionOpJsonSerialize(vector& data, string& out) + item["attributes"]["declaredInline"] = "0"; + } + item["attributes"]["funcName"] = d.funcNameAttr().getValue().str().c_str(); ++ ++ mlir::Type fnty = d.type(); ++ if (auto ty = fnty.dyn_cast()) { ++ if (auto retTy = ty.dyn_cast()) { ++ item["retType"] = TypeJsonSerialize(retTy); ++ } ++ } ++ + auto ®ion = d.getRegion(); + size_t bbIdx = 0; + for (auto &b : region) { +diff --git a/lib/Translate/GimpleToPluginOps.cpp b/lib/Translate/GimpleToPluginOps.cpp +index b5974aa..3e2321a 100644 +--- a/lib/Translate/GimpleToPluginOps.cpp ++++ b/lib/Translate/GimpleToPluginOps.cpp +@@ -536,9 +536,12 @@ FunctionOp GimpleToPluginOps::BuildFunctionOp(uint64_t functionId) + bool declaredInline = false; + if (DECL_DECLARED_INLINE_P(fn->decl)) + declaredInline = true; ++ tree returnType = TREE_TYPE(fn->decl); ++ PluginTypeBase rPluginType = typeTranslator.translateType((intptr_t)returnType); + auto location = builder.getUnknownLoc(); ++ auto Ty = rPluginType.dyn_cast(); + FunctionOp retOp = builder.create(location, functionId, +- funcName, declaredInline); ++ funcName, declaredInline, Ty); + auto& fr = retOp.bodyRegion(); + if (fn->cfg == nullptr) return retOp; + if (!ProcessBasicBlock((intptr_t)ENTRY_BLOCK_PTR_FOR_FN(fn), fr)) { +diff --git a/lib/Translate/TypeTranslation.cpp b/lib/Translate/TypeTranslation.cpp +index 7c7cff4..ad840f7 100644 +--- a/lib/Translate/TypeTranslation.cpp ++++ b/lib/Translate/TypeTranslation.cpp +@@ -45,10 +45,12 @@ + #include "ssa.h" + #include "output.h" + #include "langhooks.h" ++#include "print-tree.h" ++#include "stor-layout.h" + +-using namespace mlir; + + namespace PluginIR { ++using namespace mlir; + namespace Detail { + /* Support for translating Plugin IR types to MLIR Plugin dialect types. */ + class TypeFromPluginIRTranslatorImpl { +@@ -77,6 +79,77 @@ private: + return false; + } + ++ unsigned getDomainIndex (tree type) ++ { ++ return tree_to_shwi(TYPE_MAX_VALUE(TYPE_DOMAIN(type)))+1; ++ } ++ ++ llvm::SmallVector getArgsType (tree type) ++ { ++ tree parmlist = TYPE_ARG_TYPES (type); ++ tree parmtype; ++ llvm::SmallVector typelist; ++ for (; parmlist; parmlist = TREE_CHAIN (parmlist)) ++ { ++ parmtype = TREE_VALUE (parmlist); ++ typelist.push_back(translatePrimitiveType(parmtype)); ++ } ++ return typelist; ++ } ++ ++ const char *getTypeName (tree type) ++ { ++ const char *tname = NULL; ++ ++ if (type == NULL) ++ { ++ return NULL; ++ } ++ ++ if (TYPE_NAME (type) != NULL) ++ { ++ if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE) ++ { ++ tname = IDENTIFIER_POINTER (TYPE_NAME (type)); ++ } ++ else if (DECL_NAME (TYPE_NAME (type)) != NULL) ++ { ++ tname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))); ++ } ++ } ++ return tname; ++ } ++ ++ llvm::SmallVector getElemType(tree type) ++ { ++ llvm::SmallVector typelist; ++ tree parmtype; ++ for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) ++ { ++ if (TREE_CODE (field) == FIELD_DECL) ++ { ++ parmtype = TREE_TYPE(field); ++ typelist.push_back(translatePrimitiveType(parmtype)); ++ } ++ } ++ return typelist; ++ } ++ ++ llvm::SmallVector getElemNames(tree type) ++ { ++ llvm::SmallVector names; ++ StringRef name; ++ for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) ++ { ++ if (TREE_CODE (field) == FIELD_DECL) ++ { ++ name = IDENTIFIER_POINTER ( DECL_NAME(field)); ++ names.push_back(name); ++ } ++ } ++ return names; ++ } ++ + /* Translates the given primitive, i.e. non-parametric in MLIR nomenclature, + type. */ + PluginTypeBase translatePrimitiveType (tree type) +@@ -93,12 +166,21 @@ private: + if (TREE_CODE(type) == POINTER_TYPE) + return PluginPointerType::get(&context, translatePrimitiveType(TREE_TYPE(type)), + TYPE_READONLY(TREE_TYPE(type)) ? 1 : 0); ++ if (TREE_CODE(type) == ARRAY_TYPE) ++ return PluginArrayType::get(&context,translatePrimitiveType(TREE_TYPE(type)), getDomainIndex(type)); ++ if (TREE_CODE(type) == FUNCTION_TYPE) { ++ llvm::SmallVector argsType = getArgsType(type); ++ return PluginFunctionType::get(&context, translatePrimitiveType(TREE_TYPE(type)),argsType); ++ } ++ if (TREE_CODE(type) == RECORD_TYPE) { ++ return PluginStructType::get(&context, getTypeName(type), getElemType(type), getElemNames(type)); ++ } + return PluginUndefType::get(&context); + } + + /* The context in which MLIR types are created. */ + mlir::MLIRContext &context; +-}; ++}; // class TypeFromPluginIRTranslatorImpl + + /* Support for translating MLIR Plugin dialect types to Plugin IR types . */ + class TypeToPluginIRTranslatorImpl { +@@ -126,6 +208,16 @@ private: + return false; + } + ++ auto_vec getParamsType(PluginFunctionType Ty) ++ { ++ auto_vec paramTypes; ++ ArrayRef ArgsTypes = Ty.getParams(); ++ for (auto ty :ArgsTypes) { ++ paramTypes.safe_push(translatePrimitiveType(ty.dyn_cast())); ++ } ++ return paramTypes; ++ } ++ + tree translatePrimitiveType(PluginTypeBase type) + { + if (auto Ty = type.dyn_cast()) { +@@ -179,9 +271,50 @@ private: + TYPE_READONLY(elmTy) = elmConst ? 1 : 0; + return build_pointer_type(elmTy); + } ++ if (auto Ty = type.dyn_cast()) { ++ mlir::Type elmType = Ty.getElementType(); ++ auto ty = elmType.dyn_cast(); ++ tree elmTy = translatePrimitiveType(ty); ++ unsigned elmNum = Ty.getNumElements(); ++ tree index = build_index_type (size_int (elmNum)); ++ return build_array_type(elmTy, index); ++ } ++ if (auto Ty = type.dyn_cast()) { ++ Type resultType = Ty.getReturnType(); ++ tree returnType = translatePrimitiveType(resultType.dyn_cast()); ++ auto_vec paramTypes = getParamsType(Ty); ++ return build_function_type_array(returnType, paramTypes.length (), paramTypes.address ()); ++ } ++ if (auto Ty = type.dyn_cast()) { ++ ArrayRef elemTypes = Ty.getBody(); ++ ArrayRef elemNames = Ty.getElementNames(); ++ StringRef tyName = Ty.getName(); ++ unsigned fieldSize = elemNames.size(); ++ ++ tree fields[fieldSize]; ++ tree ret; ++ unsigned i; ++ ++ ret = make_node (RECORD_TYPE); ++ for (i = 0; i < fieldSize; i++) ++ { ++ mlir::Type elemTy = elemTypes[i]; ++ auto ty = elemTy.dyn_cast(); ++ tree elmType = translatePrimitiveType(ty); ++ fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, get_identifier (elemNames[i].str().c_str()), elmType); ++ DECL_CONTEXT (fields[i]) = ret; ++ if (i) DECL_CHAIN (fields[i - 1]) = fields[i]; ++ } ++ tree typeDecl = build_decl (input_location, TYPE_DECL, get_identifier (tyName.str().c_str()), ret); ++ DECL_ARTIFICIAL (typeDecl) = 1; ++ TYPE_FIELDS (ret) = fields[0]; ++ TYPE_NAME (ret) = typeDecl; ++ layout_type (ret); ++ return ret; ++ } + return NULL; + } +-}; ++}; // class TypeToPluginIRTranslatorImpl + + } // namespace Detail + } // namespace PluginIR +-- +2.27.0.windows.1 + diff --git a/pin-gcc-client.spec b/pin-gcc-client.spec index bb2d8705c539076c7cdd11d6ad930a2dd48b6e51..1e9321fd6faefdc8654c653464191bce4f419555 100644 --- a/pin-gcc-client.spec +++ b/pin-gcc-client.spec @@ -1,6 +1,6 @@ Name: pin-gcc-client Version: 0.4.0 -Release: 1 +Release: 2 Summary: A Pin (Plug-IN framework) client is implemented based on GCC plugin and can execute the compiler optimization pass in GCC. License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ with exceptions and LGPLv2+ and BSD URL: https://gitee.com/src-openeuler/pin-gcc-client @@ -10,6 +10,16 @@ BuildRequires: gcc gcc-c++ gcc-plugin-devel cmake make pkgconfig grpc grpc-plug BuildRequires: llvm-mlir llvm-mlir-static llvm-mlir-devel llvm-devel Requires: gcc grpc protobuf +Patch1: 0001-Pin-gcc-client-Bugfix-for-ConstOp.patch +Patch2: 0002-Refactoring-Code-refactoring-of-Communication-Subsys.patch +Patch3: 0003-Refactoring-Code-refactoring-of-Communication-Subsys.patch +Patch4: 0004-Refactoring-Code-refactoring-of-Communication-Subsys.patch +Patch5: 0005-Pin-gcc-client-Add-DebugOp.patch +Patch6: 0006-Pin-gcc-client-Bugfix-for-ConstOp.patch +Patch7: 0007-Pin-gcc-client-Add-API-for-LTO-judgement.patch +Patch8: 0008-Pin-gcc-client-Fix-bug-for-BuildCallOp.patch +Patch9: 0009-Pin-gcc-client-Support-functiontype-structtype.eg.patch + %description A Pin (Plug-IN framework) client is implemented based on GCC plugin and can execute the compiler optimization pass in GCC. @@ -19,6 +29,16 @@ A Pin (Plug-IN framework) client is implemented based on GCC plugin and can exec %prep %setup -q +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 +%patch6 -p1 +%patch7 -p1 +%patch8 -p1 +%patch9 -p1 + mkdir -p _build cd _build %{cmake} .. -DCMAKE_INSTALL_PREFIX=%{_usr} -DCMAKE_INSTALL_LIBDIR=%{_libdir} -DMLIR_DIR=/usr/lib64/cmake/mlir -DLLVM_DIR=/usr/lib64/cmake/llvm @@ -42,6 +62,12 @@ cd _build %attr(0644,root,root) %{_bindir}/pin-gcc-client.json %changelog +* Wed Feb 22 2023 dingguangya - 0.4.0-2 +- Type:Update +- ID:NA +- SUG:NA +- DESC:Sync patch from openEuler/pin-gcc-client + * Tue Dec 20 2022 zhaowenyu <804544223@qq.com> - 0.4.0-1 - Type:Update - ID:NA