840 lines
28 KiB
Diff
840 lines
28 KiB
Diff
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 ®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<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
|
||
|