pin-gcc-client/0003-Refactoring-Code-refactoring-of-Communication-Subsys.patch
d00573793 fdcab1229a [sync] Sync patch from openeuler/pin-gcc-client
(cherry picked from commit c479a0e1cdb0f7672c180d94662776012d7bc37a)
2023-02-27 09:22:08 +08:00

840 lines
28 KiB
Diff
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
+ <http://www.gnu.org/licenses/>.
+
+ Author: Mingchuan Wu and Yancheng Li
+ Create: 2022-08-18
+ Description:
+ This file contains the implementation of the PluginGrpcPort class.
+ 主要完成功能:查找未使用的端口号,并将端口号写入到共享文件中,通过文件锁控制多进程间访问,并提供
+ DeletePortFromLockFile接口在退出时删除写入的端口号
+*/
+
+#include <fstream>
+#include <cstring>
+#include <arpa/inet.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#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
+ <http://www.gnu.org/licenses/>.
+
+ Author: Mingchuan Wu and Yancheng Li
+ Create: 2022-08-18
+ Description:
+ This file contains the implementation of the PluginInputCheck class.
+*/
+
+#include <fstream>
+#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<string, int> g_keyMap {
+ {"server_path", KEY_SERVER_PATH},
+ {"log_level", KEY_LOG_LEVEL},
+};
+void PluginInputCheck::GetInputArgs(struct plugin_name_args *pluginInfo)
+{
+ Json::Value root;
+ map<string, string> 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
+ <http://www.gnu.org/licenses/>.
+
+ Author: Mingchuan Wu and Yancheng Li
+ Create: 2022-08-18
+ Description:
+ This file contains the implementation of the PluginJson class.
+*/
+
+#include <json/json.h>
+#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<uint64_t>(type.getPluginTypeID());
+ item["id"] = std::to_string(ReTypeId);
+
+ if (auto elemTy = type.dyn_cast<PluginIR::PluginPointerType>()) {
+ auto baseTy = elemTy.getElementType().dyn_cast<PluginIR::PluginTypeBase>();
+ 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<PluginIR::PluginTypeID>(id);
+
+ if (type["signed"] && (id >= static_cast<uint64_t>(PluginIR::UIntegerTy1ID)
+ && id <= static_cast<uint64_t>(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<uint64_t>(PluginIR::FloatTyID)
+ || id == static_cast<uint64_t>(PluginIR::DoubleTyID))) {
+ uint64_t width = GetID(type["width"]);
+ baseType = PluginIR::PluginFloatType::get(&context, width);
+ } else if (id == static_cast<uint64_t>(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<FunctionOp>& 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 &region = 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<PlaceholderOp>(inst)) {
+ continue;
+ } else if (isa<SSAOp>(inst)) {
+ continue;
+ } else if (isa<MemOp>(inst)) {
+ continue;
+ } else if (isa<ConstOp>(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<AssignOp>(operation)) {
+ root = AssignOpJsonSerialize(op);
+ } else if (CallOp op = llvm::dyn_cast<CallOp>(operation)) {
+ root = CallOpJsonSerialize(op);
+ } else if (CondOp op = llvm::dyn_cast<CondOp>(operation)) {
+ root = CondOpJsonSerialize(op, bbId);
+ } else if (PhiOp op = llvm::dyn_cast<PhiOp>(operation)) {
+ root = PhiOpJsonSerialize(op);
+ } else if (FallThroughOp op = llvm::dyn_cast<FallThroughOp>(operation)) {
+ root = FallThroughOpJsonSerialize(op, bbId);
+ } else if (RetOp op = llvm::dyn_cast<RetOp>(operation)) {
+ root = RetOpJsonSerialize(op, bbId);
+ } else if (BaseOp op = llvm::dyn_cast<BaseOp>(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<LocalDeclOp>& 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<mlir::Plugin::LoopOp>& 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<uint64_t>& 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<std::pair<uint64_t, uint64_t> >& 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<uint64_t, uint64_t>& 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<PhiOp> 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<PluginIR::PluginTypeBase>();
+ 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<ConstOp>()) {
+ auto retTy = data.getType().dyn_cast<PluginIR::PluginTypeBase>();
+ root["retType"] = TypeJsonSerialize(retTy);
+ root["id"] = std::to_string(cOp.idAttr().getInt());
+ root["defCode"] = std::to_string(static_cast<int32_t>(IDefineCode::IntCST));
+ root["value"] = std::to_string(cOp.initAttr().cast<mlir::IntegerAttr>().getInt());
+ } else if (MemOp mOp = data.getDefiningOp<MemOp>()) {
+ root = MemOpJsonSerialize(mOp);
+ } else if (SSAOp sOp = data.getDefiningOp<SSAOp>()) {
+ root = SSAOpJsonSerialize(sOp);
+ } else if (PlaceholderOp phOp = data.getDefiningOp<PlaceholderOp>()) {
+ root["id"] = std::to_string(phOp.idAttr().getInt());
+ root["defCode"] = std::to_string(phOp.defCodeAttr().getInt());
+ auto retTy = phOp.getResultType().dyn_cast<PluginIR::PluginTypeBase>();
+ 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<PluginIR::PluginTypeBase>();
+ 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