!12 [sync] PR-10: [Sync] Sync patch from openeuler/pin-server

From: @openeuler-sync-bot 
Reviewed-by: @li-yancheng 
Signed-off-by: @li-yancheng
This commit is contained in:
openeuler-ci-bot 2022-12-09 07:10:24 +00:00 committed by Gitee
commit 9d31f4e14a
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
5 changed files with 2060 additions and 1 deletions

View File

@ -0,0 +1,85 @@
From 192ac2d7c8568fa5c8f02039707bc951747c877b Mon Sep 17 00:00:00 2001
From: dingguangya <dingguangya1@huawei.com>
Date: Wed, 7 Dec 2022 21:59:02 +0800
Subject: [PATCH 1/4] [Pin-server] Support for new insertion points and new
Pass It supports the phiopt insertion point and provides a simple
arraywiden pass interface.
---
include/PluginServer/PluginServer.h | 1 +
user.cpp | 42 +++++++++++++++++++++++++++--
2 files changed, 41 insertions(+), 2 deletions(-)
diff --git a/include/PluginServer/PluginServer.h b/include/PluginServer/PluginServer.h
index 667cedc..2cb314c 100644
--- a/include/PluginServer/PluginServer.h
+++ b/include/PluginServer/PluginServer.h
@@ -79,6 +79,7 @@ enum InjectPoint : uint8_t {
// 参考点名称
enum RefPassName {
PASS_CFG,
+ PASS_PHIOPT,
PASS_SSA,
PASS_LOOP,
};
diff --git a/user.cpp b/user.cpp
index 50fc3bb..81958c0 100644
--- a/user.cpp
+++ b/user.cpp
@@ -77,13 +77,51 @@ static void PassManagerSetupFunc(void)
printf("PassManagerSetupFunc in\n");
}
+static bool
+determineLoopForm(LoopOp loop)
+{
+ if (loop.innerLoopIdAttr().getUInt() != 0 || loop.numBlockAttr().getUInt() != 3)
+ {
+ printf ("\nWrong loop form, there is inner loop or redundant bb.\n");
+ return false;
+ }
+
+ if (loop.GetSingleExit().first != 0 || !loop.GetLatch())
+ {
+ printf ("\nWrong loop form, only one exit or loop_latch does not exist.\n");
+ return false;
+ }
+ return true;
+}
+
+static void
+ProcessArrayWiden(void)
+{
+ std::cout << "Running first pass, OMG\n";
+
+ PluginServerAPI pluginAPI;
+ vector<FunctionOp> allFunction = pluginAPI.GetAllFunc();
+
+ for (auto &funcOp : allFunction) {
+ string name = funcOp.funcNameAttr().getValue().str();
+ printf("Now process func : %s \n", name.c_str());
+ vector<LoopOp> allLoop = funcOp.GetAllLoops();
+ for (auto &loop : allLoop) {
+ if (determineLoopForm(loop)) {
+ printf("The %dth loop form is success matched, and the loop can be optimized.\n", loop.indexAttr().getUInt());
+ return;
+ }
+ }
+ }
+}
+
void RegisterCallbacks(void)
{
PluginServer::GetInstance()->RegisterUserFunc(HANDLE_BEFORE_IPA, UserOptimizeFunc);
PluginServer::GetInstance()->RegisterUserFunc(HANDLE_BEFORE_IPA, LocalVarSummery);
ManagerSetupData setupData;
- setupData.refPassName = PASS_CFG;
+ setupData.refPassName = PASS_PHIOPT;
setupData.passNum = 1;
setupData.passPosition = PASS_INSERT_AFTER;
- PluginServer::GetInstance()->RegisterPassManagerSetup(HANDLE_MANAGER_SETUP, setupData, PassManagerSetupFunc);
+ PluginServer::GetInstance()->RegisterPassManagerSetup(HANDLE_MANAGER_SETUP, setupData, ProcessArrayWiden);
}
--
2.27.0.windows.1

View File

@ -0,0 +1,772 @@
From c51ee872abc92b72fa35f7ff52c2d9e506dde40a Mon Sep 17 00:00:00 2001
From: benniaobufeijiushiji <linda7@huawei.com>
Date: Wed, 7 Dec 2022 14:52:19 +0800
Subject: [PATCH 2/4] [Pin-server] support LoopOp Add LoopOp for Plugin Dialect
---
include/Dialect/PluginOps.td | 35 +++++
include/PluginAPI/BasicPluginOpsAPI.h | 11 ++
include/PluginAPI/PluginServerAPI.h | 20 +++
include/PluginServer/PluginServer.h | 21 +++
lib/Dialect/PluginOps.cpp | 96 ++++++++++++-
lib/PluginAPI/PluginServerAPI.cpp | 171 +++++++++++++++++++++++-
lib/PluginServer/PluginServer.cpp | 185 +++++++++++++++++++++++++-
user.cpp | 16 +--
8 files changed, 541 insertions(+), 14 deletions(-)
diff --git a/include/Dialect/PluginOps.td b/include/Dialect/PluginOps.td
index 374340c..02d9bdd 100644
--- a/include/Dialect/PluginOps.td
+++ b/include/Dialect/PluginOps.td
@@ -20,6 +20,7 @@
include "PluginDialect.td"
include "mlir/Interfaces/SideEffectInterfaces.td"
+include "mlir/Interfaces/CallInterfaces.td"
def FunctionOp : Plugin_Op<"function", [NoSideEffect]> {
let summary = "function with a region";
@@ -38,6 +39,10 @@ def FunctionOp : Plugin_Op<"function", [NoSideEffect]> {
let builders = [
OpBuilderDAG<(ins "uint64_t":$id, "StringRef":$funcName, "bool":$declaredInline)>
];
+
+ let extraClassDeclaration = [{
+ std::vector<LoopOp> GetAllLoops();
+ }];
}
def LocalDeclOp : Plugin_Op<"declaration", [NoSideEffect]> {
@@ -54,4 +59,34 @@ def LocalDeclOp : Plugin_Op<"declaration", [NoSideEffect]> {
];
}
+def LoopOp : Plugin_Op<"loop", [NoSideEffect]> {
+ let summary = "loop operation";
+ let description = [{
+ TODO.
+ }];
+ let arguments = (ins OptionalAttr<UI64Attr>:$id,
+ OptionalAttr<UI32Attr>:$index,
+ OptionalAttr<UI64Attr>:$innerLoopId,
+ OptionalAttr<UI64Attr>:$outerLoopId,
+ OptionalAttr<UI32Attr>:$numBlock);
+ let regions = (region AnyRegion:$bodyRegion);
+ let builders = [
+ OpBuilderDAG<(ins "uint64_t":$id, "uint32_t":$index,
+ "uint64_t":$innerLoopId, "uint64_t":$outerLoopId,
+ "uint32_t":$numBlock)>
+ ];
+ let extraClassDeclaration = [{
+ uint64_t GetHeader();
+ uint64_t GetLatch();
+ std::pair<uint64_t, uint64_t> GetSingleExit();
+ void Delete();
+ LoopOp GetInnerLoop();
+ LoopOp GetOuterLoop();
+ bool IsBlockInside(uint64_t);
+ std::vector<std::pair<uint64_t, uint64_t> > GetExitEdges();
+ std::vector<uint64_t> GetLoopBody();
+ void AddLoop(uint64_t, uint64_t);
+ }];
+}
+
#endif // PLUGIN_OPS_TD
\ No newline at end of file
diff --git a/include/PluginAPI/BasicPluginOpsAPI.h b/include/PluginAPI/BasicPluginOpsAPI.h
index b6f2b4f..fde5f63 100644
--- a/include/PluginAPI/BasicPluginOpsAPI.h
+++ b/include/PluginAPI/BasicPluginOpsAPI.h
@@ -25,6 +25,7 @@
namespace PluginAPI {
using std::vector;
using std::string;
+using std::pair;
using namespace mlir::Plugin;
/* The BasicPluginOpsAPI class defines the basic plugin API, both the plugin
@@ -37,6 +38,16 @@ public:
virtual vector<FunctionOp> GetAllFunc() = 0;
virtual vector<LocalDeclOp> GetDecls(uint64_t) = 0;
+ virtual LoopOp AllocateNewLoop(uint64_t) = 0;
+ virtual vector<LoopOp> GetLoopsFromFunc(uint64_t) = 0;
+ virtual LoopOp GetLoopById(uint64_t) = 0;
+ virtual void AddLoop(uint64_t, uint64_t, uint64_t) = 0;
+ virtual void DeleteLoop(uint64_t) = 0;
+ virtual vector<uint64_t> GetLoopBody(uint64_t) = 0;
+ virtual bool IsBlockInLoop(uint64_t, uint64_t) = 0;
+ virtual pair<uint64_t, uint64_t> LoopSingleExit(uint64_t) = 0;
+ virtual vector<pair<uint64_t, uint64_t> > GetLoopExitEdges(uint64_t) = 0;
+ virtual LoopOp GetBlockLoopFather(uint64_t) = 0;
}; // class BasicPluginOpsAPI
} // namespace PluginAPI
diff --git a/include/PluginAPI/PluginServerAPI.h b/include/PluginAPI/PluginServerAPI.h
index 7cb4fa7..5b14f2e 100644
--- a/include/PluginAPI/PluginServerAPI.h
+++ b/include/PluginAPI/PluginServerAPI.h
@@ -29,6 +29,7 @@ namespace PluginAPI {
using std::vector;
using std::string;
+using std::pair;
using namespace mlir::Plugin;
class PluginServerAPI : public BasicPluginOpsAPI {
public:
@@ -38,9 +39,28 @@ public:
vector<FunctionOp> GetAllFunc() override;
vector<LocalDeclOp> GetDecls(uint64_t) override;
PluginIR::PluginTypeID GetTypeCodeFromString(string type);
+ LoopOp AllocateNewLoop(uint64_t funcID);
+ LoopOp GetLoopById(uint64_t loopID);
+ vector<LoopOp> GetLoopsFromFunc(uint64_t funcID);
+ bool IsBlockInLoop(uint64_t loopID, uint64_t blockID);
+ void DeleteLoop(uint64_t loopID);
+ void AddLoop(uint64_t loopID, uint64_t outerID, uint64_t funcID);
+ pair<uint64_t, uint64_t> LoopSingleExit(uint64_t loopID);
+ vector<pair<uint64_t, uint64_t> > GetLoopExitEdges(uint64_t loopID);
+ uint64_t GetHeader(uint64_t loopID);
+ uint64_t GetLatch(uint64_t loopID);
+ vector<uint64_t> GetLoopBody(uint64_t loopID);
+ LoopOp GetBlockLoopFather(uint64_t blockID);
private:
vector<FunctionOp> GetOperationResult(const string& funName, const string& params);
vector<LocalDeclOp> GetDeclOperationResult(const string& funName, const string& params);
+ LoopOp GetLoopResult(const string&funName, const string& params);
+ vector<LoopOp> GetLoopsResult(const string& funName, const string& params);
+ bool GetBoolResult(const string& funName, const string& params);
+ pair<uint64_t, uint64_t> EdgeResult(const string& funName, const string& params);
+ vector<pair<uint64_t, uint64_t> > EdgesResult(const string& funName, const string& params);
+ uint64_t BlockResult(const string& funName, const string& params);
+ vector<uint64_t> BlocksResult(const string& funName, const string& params);
void WaitClientResult(const string& funName, const string& params);
}; // class PluginServerAPI
} // namespace PluginAPI
diff --git a/include/PluginServer/PluginServer.h b/include/PluginServer/PluginServer.h
index 2cb314c..610ecb9 100644
--- a/include/PluginServer/PluginServer.h
+++ b/include/PluginServer/PluginServer.h
@@ -130,6 +130,13 @@ public:
static PluginServer *GetInstance(void);
vector<mlir::Plugin::FunctionOp> GetFunctionOpResult(void);
vector<mlir::Plugin::LocalDeclOp> GetLocalDeclResult(void);
+ mlir::Plugin::LoopOp LoopOpResult(void);
+ vector<mlir::Plugin::LoopOp> LoopOpsResult(void);
+ vector<uint64_t> BlockIdsResult(void);
+ uint64_t BlockIdResult(void);
+ vector<std::pair<uint64_t, uint64_t> > EdgesResult(void);
+ std::pair<uint64_t, uint64_t> EdgeResult(void);
+ bool BoolResult(void);
/* 回调函数接口用于向server注册用户需要执行的函数 */
int RegisterUserFunc(InjectPoint inject, UserFunc func);
int RegisterPassManagerSetup(InjectPoint inject, const ManagerSetupData& passData, UserFunc func);
@@ -176,6 +183,13 @@ public:
void FuncOpJsonDeSerialize(const string& data);
void TypeJsonDeSerialize(const string& data);
void LocalDeclOpJsonDeSerialize(const string& data);
+ void LoopOpsJsonDeSerialize(const string& data);
+ void LoopOpJsonDeSerialize(const string& data);
+ void BoolResJsonDeSerialize(const string& data);
+ void EdgesJsonDeSerialize(const string& data);
+ void EdgeJsonDeSerialize(const string& data);
+ void BlocksJsonDeSerialize(const string& data);
+ void BlockJsonDeSerialize(const string& data);
/* json反序列化根据key值分别调用Operation/Decl/Type反序列化接口函数 */
void JsonDeSerialize(const string& key, const string& data);
/* 解析客户端发送过来的-fplugin-arg参数并保存在私有变量args中 */
@@ -223,6 +237,13 @@ private:
vector<mlir::Plugin::FunctionOp> funcOpData;
PluginIR::PluginTypeBase pluginType;
vector<mlir::Plugin::LocalDeclOp> decls;
+ vector<mlir::Plugin::LoopOp> loops;
+ mlir::Plugin::LoopOp loop;
+ vector<std::pair<uint64_t, uint64_t> > edges;
+ std::pair<uint64_t, uint64_t> edge;
+ vector<uint64_t> blockIds;
+ uint64_t blockId;
+ bool boolRes;
/* 保存用户注册的回调函数,它们将在注入点事件触发后调用 */
map<InjectPoint, vector<RecordedUserFunc>> userFunc;
string apiFuncName; // 保存用户调用PluginAPI的函数名
diff --git a/lib/Dialect/PluginOps.cpp b/lib/Dialect/PluginOps.cpp
index 2377875..481d51a 100644
--- a/lib/Dialect/PluginOps.cpp
+++ b/lib/Dialect/PluginOps.cpp
@@ -20,6 +20,7 @@
//
//===----------------------------------------------------------------------===//
+#include "PluginAPI/PluginServerAPI.h"
#include "Dialect/PluginDialect.h"
#include "Dialect/PluginOps.h"
@@ -29,15 +30,24 @@
using namespace mlir;
using namespace mlir::Plugin;
+using std::vector;
+using std::pair;
void FunctionOp::build(mlir::OpBuilder &builder, mlir::OperationState &state,
uint64_t id, StringRef funcName, bool declaredInline) {
FunctionOp::build(builder, state,
- builder.getI64IntegerAttr(id),
+ builder.getI64IntegerAttr(id),
builder.getStringAttr(funcName),
builder.getBoolAttr(declaredInline));
}
+vector<LoopOp> FunctionOp::GetAllLoops()
+{
+ PluginAPI::PluginServerAPI pluginAPI;
+ uint64_t funcId = idAttr().getInt();
+ return pluginAPI.GetLoopsFromFunc(funcId);
+}
+
void LocalDeclOp::build(mlir::OpBuilder &builder, mlir::OperationState &state,
uint64_t id, StringRef symName,
int64_t typeID, uint64_t typeWidth) {
@@ -48,6 +58,90 @@ void LocalDeclOp::build(mlir::OpBuilder &builder, mlir::OperationState &state,
builder.getI64IntegerAttr(typeWidth));
}
+void LoopOp::build(mlir::OpBuilder &builder, mlir::OperationState &state,
+ 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),
+ builder.getI64IntegerAttr(innerLoopId),
+ builder.getI64IntegerAttr(outerLoopId),
+ builder.getI32IntegerAttr(numBlock));
+}
+
+// FIXME: use Block instead of uint64_t
+uint64_t LoopOp::GetHeader()
+{
+ PluginAPI::PluginServerAPI pluginAPI;
+ uint64_t loopId = idAttr().getInt();
+ return pluginAPI.GetHeader(loopId);
+}
+
+// FIXME: use Block instead of uint64_t
+uint64_t LoopOp::GetLatch()
+{
+ PluginAPI::PluginServerAPI pluginAPI;
+ uint64_t loopId = idAttr().getInt();
+ return pluginAPI.GetLatch(loopId);
+}
+
+vector<uint64_t> LoopOp::GetLoopBody()
+{
+ PluginAPI::PluginServerAPI pluginAPI;
+ uint64_t loopId = idAttr().getInt();
+ return pluginAPI.GetLoopBody(loopId);
+}
+
+pair<uint64_t, uint64_t> LoopOp::GetSingleExit()
+{
+ PluginAPI::PluginServerAPI pluginAPI;
+ uint64_t loopId = idAttr().getInt();
+ return pluginAPI.LoopSingleExit(loopId);
+}
+
+void LoopOp::Delete()
+{
+ PluginAPI::PluginServerAPI pluginAPI;
+ uint64_t loopId = idAttr().getInt();
+ pluginAPI.DeleteLoop(loopId);
+}
+
+LoopOp LoopOp::GetInnerLoop()
+{
+ PluginAPI::PluginServerAPI pluginAPI;
+ uint64_t loopId = innerLoopIdAttr().getInt();
+ return pluginAPI.GetLoopById(loopId);
+}
+
+LoopOp LoopOp::GetOuterLoop()
+{
+ PluginAPI::PluginServerAPI pluginAPI;
+ uint64_t loopId = outerLoopIdAttr().getInt();
+ return pluginAPI.GetLoopById(loopId);
+}
+
+// FIXME: 用Block替换uint64_t
+bool LoopOp::IsBlockInside(uint64_t b)
+{
+ PluginAPI::PluginServerAPI pluginAPI;
+ uint64_t loopId = idAttr().getInt();
+ return pluginAPI.IsBlockInLoop(loopId, b);
+}
+
+vector<pair<uint64_t, uint64_t> > LoopOp::GetExitEdges()
+{
+ PluginAPI::PluginServerAPI pluginAPI;
+ uint64_t loopId = idAttr().getInt();
+ return pluginAPI.GetLoopExitEdges(loopId);
+}
+
+void LoopOp::AddLoop(uint64_t outerId, uint64_t funcId)
+{
+ PluginAPI::PluginServerAPI pluginAPI;
+ uint64_t loopId = idAttr().getInt();
+ return pluginAPI.AddLoop(loopId, outerId, funcId);
+}
+
//===----------------------------------------------------------------------===//
// TableGen'd op method definitions
//===----------------------------------------------------------------------===//
diff --git a/lib/PluginAPI/PluginServerAPI.cpp b/lib/PluginAPI/PluginServerAPI.cpp
index b6ed53f..41626f9 100644
--- a/lib/PluginAPI/PluginServerAPI.cpp
+++ b/lib/PluginAPI/PluginServerAPI.cpp
@@ -116,10 +116,179 @@ vector<LocalDeclOp> PluginServerAPI::GetDecls(uint64_t funcID)
{
Json::Value root;
string funName("GetLocalDecls");
- root[std::to_string(0)] = std::to_string(funcID);
+ root["funcId"] = std::to_string(funcID);
string params = root.toStyledString();
return GetDeclOperationResult(funName, params);
}
+vector<LoopOp> PluginServerAPI::GetLoopsResult(const string& funName, const string& params)
+{
+ WaitClientResult(funName, params);
+ vector<LoopOp> loops = PluginServer::GetInstance()->LoopOpsResult();
+ return loops;
+}
+
+LoopOp PluginServerAPI::GetLoopResult(const string& funName, const string& params)
+{
+ WaitClientResult(funName, params);
+ LoopOp loop = PluginServer::GetInstance()->LoopOpResult();
+ return loop;
+}
+
+bool PluginServerAPI::GetBoolResult(const string& funName, const string& params)
+{
+ WaitClientResult(funName, params);
+ return PluginServer::GetInstance()->BoolResult();
+}
+
+pair<uint64_t, uint64_t> PluginServerAPI::EdgeResult(const string& funName, const string& params)
+{
+ WaitClientResult(funName, params);
+ pair<uint64_t, uint64_t> e = PluginServer::GetInstance()->EdgeResult();
+ return e;
+}
+
+vector<pair<uint64_t, uint64_t> > PluginServerAPI::EdgesResult(const string& funName, const string& params)
+{
+ WaitClientResult(funName, params);
+ vector<pair<uint64_t, uint64_t> > retEdges = PluginServer::GetInstance()->EdgesResult();
+ return retEdges;
+}
+
+uint64_t PluginServerAPI::BlockResult(const string& funName, const string& params)
+{
+ WaitClientResult(funName, params);
+ return PluginServer::GetInstance()->BlockIdResult();
+}
+
+vector<uint64_t> PluginServerAPI::BlocksResult(const string& funName, const string& params)
+{
+ WaitClientResult(funName, params);
+ vector<uint64_t> retBlocks = PluginServer::GetInstance()->BlockIdsResult();
+ return retBlocks;
+}
+
+vector<LoopOp> PluginServerAPI::GetLoopsFromFunc(uint64_t funcID)
+{
+ Json::Value root;
+ string funName("GetLoopsFromFunc");
+ root["funcId"] = std::to_string(funcID);
+ string params = root.toStyledString();
+
+ return GetLoopsResult(funName, params);
+}
+
+// FIXME: 入参void
+LoopOp PluginServerAPI::AllocateNewLoop(uint64_t funcID)
+{
+ Json::Value root;
+ string funName("AllocateNewLoop");
+ root["funcId"] = std::to_string(funcID);
+ string params = root.toStyledString();
+
+ return GetLoopResult(funName, params);
+}
+
+LoopOp PluginServerAPI::GetLoopById(uint64_t loopID)
+{
+ Json::Value root;
+ string funName("GetLoopById");
+ root["loopId"] = std::to_string(loopID);
+ string params = root.toStyledString();
+
+ return GetLoopResult(funName, params);
+}
+
+void PluginServerAPI::DeleteLoop(uint64_t loopID)
+{
+ Json::Value root;
+ string funName("DeleteLoop");
+ root["loopId"] = std::to_string(loopID);
+ string params = root.toStyledString();
+ WaitClientResult(funName, params);
+}
+
+void PluginServerAPI::AddLoop(uint64_t loopID, uint64_t outerID, uint64_t funcID)
+{
+ Json::Value root;
+ string funName("AddLoop");
+ root["loopId"] = loopID;
+ root["outerId"] = outerID;
+ root["funcId"] = funcID;
+ string params = root.toStyledString();
+ WaitClientResult(funName, params);
+}
+
+bool PluginServerAPI::IsBlockInLoop(uint64_t loopID, uint64_t blockID)
+{
+ Json::Value root;
+ string funName("IsBlockInside");
+ root["loopId"] = std::to_string(loopID);
+ root["blockId"] = std::to_string(blockID);
+ string params = root.toStyledString();
+
+ return GetBoolResult(funName, params);
+}
+
+uint64_t PluginServerAPI::GetHeader(uint64_t loopID)
+{
+ Json::Value root;
+ string funName("GetHeader");
+ root["loopId"] = std::to_string(loopID);
+ string params = root.toStyledString();
+
+ return BlockResult(funName, params);
+}
+
+uint64_t PluginServerAPI::GetLatch(uint64_t loopID)
+{
+ Json::Value root;
+ string funName("GetLatch");
+ root["loopId"] = std::to_string(loopID);
+ string params = root.toStyledString();
+
+ return BlockResult(funName, params);
+}
+
+pair<uint64_t, uint64_t> PluginServerAPI::LoopSingleExit(uint64_t loopID)
+{
+ Json::Value root;
+ string funName("GetLoopSingleExit");
+ root["loopId"] = std::to_string(loopID);
+ string params = root.toStyledString();
+
+ return EdgeResult(funName, params);
+}
+
+vector<pair<uint64_t, uint64_t> > PluginServerAPI::GetLoopExitEdges(uint64_t loopID)
+{
+ Json::Value root;
+ string funName("GetExitEdges");
+ root["loopId"] = std::to_string(loopID);
+ string params = root.toStyledString();
+
+ return EdgesResult(funName, params);
+}
+
+vector<uint64_t> PluginServerAPI::GetLoopBody(uint64_t loopID)
+{
+ Json::Value root;
+ string funName("GetBlocksInLoop");
+ root["loopId"] = std::to_string(loopID);
+ string params = root.toStyledString();
+
+ return BlocksResult(funName, params);
+}
+
+LoopOp PluginServerAPI::GetBlockLoopFather(uint64_t blockID)
+{
+ Json::Value root;
+ string funName("GetBlockLoopFather");
+ root["blockId"] = std::to_string(blockID);
+ string params = root.toStyledString();
+
+ return GetLoopResult(funName, params);
+}
+
} // namespace Plugin_IR
diff --git a/lib/PluginServer/PluginServer.cpp b/lib/PluginServer/PluginServer.cpp
index 1ec47ae..92159e8 100644
--- a/lib/PluginServer/PluginServer.cpp
+++ b/lib/PluginServer/PluginServer.cpp
@@ -40,6 +40,7 @@ using namespace mlir::Plugin;
using std::cout;
using std::endl;
+using std::pair;
static std::unique_ptr<Server> g_server; // grpc对象指针
static PluginServer g_service; // 插件server对象
@@ -88,6 +89,52 @@ vector<mlir::Plugin::LocalDeclOp> PluginServer::GetLocalDeclResult()
return retOps;
}
+vector<mlir::Plugin::LoopOp> PluginServer::LoopOpsResult()
+{
+ vector<mlir::Plugin::LoopOp> retLoops = loops;
+ loops.clear();
+ return retLoops;
+}
+
+LoopOp PluginServer::LoopOpResult()
+{
+ mlir::Plugin::LoopOp retLoop = loop;
+ return retLoop;
+}
+
+bool PluginServer::BoolResult()
+{
+ return boolRes;
+}
+
+uint64_t PluginServer::BlockIdResult()
+{
+ return blockId;
+}
+
+vector<uint64_t> PluginServer::BlockIdsResult()
+{
+ vector<uint64_t> retIds = blockIds;
+ blockIds.clear();
+ return retIds;
+}
+
+pair<uint64_t, uint64_t> PluginServer::EdgeResult()
+{
+ pair<uint64_t, uint64_t> e;
+ e.first = edge.first;
+ e.second = edge.second;
+ return e;
+}
+
+vector<pair<uint64_t, uint64_t> > PluginServer::EdgesResult()
+{
+ vector<pair<uint64_t, uint64_t> > retEdges;
+ retEdges = edges;
+ edges.clear();
+ return retEdges;
+}
+
void PluginServer::JsonGetAttributes(Json::Value node, map<string, string>& attributes)
{
Json::Value::Members attMember = node.getMemberNames();
@@ -110,7 +157,23 @@ void PluginServer::JsonDeSerialize(const string& key, const string& data)
FuncOpJsonDeSerialize(data);
} else if (key == "LocalDeclOpResult") {
LocalDeclOpJsonDeSerialize(data);
- }else {
+ } else if (key == "LoopOpResult") {
+ LoopOpJsonDeSerialize (data);
+ } else if (key == "LoopOpsResult") {
+ LoopOpsJsonDeSerialize (data);
+ } else if (key == "BoolResult") {
+ BoolResJsonDeSerialize(data);
+ } else if (key == "VoidResult") {
+ ;
+ } else if (key == "BlockIdResult") {
+ BlockJsonDeSerialize(data);
+ } else if (key == "EdgeResult") {
+ EdgeJsonDeSerialize(data);
+ } else if (key == "EdgesResult") {
+ EdgesJsonDeSerialize(data);
+ } else if (key == "BlockIdsResult") {
+ BlocksJsonDeSerialize(data);
+ } else {
cout << "not Json,key:" << key << ",value:" << data << endl;
}
}
@@ -198,14 +261,128 @@ void PluginServer::LocalDeclOpJsonDeSerialize(const string& data)
Json::Value attributes = node["attributes"];
map<string, string> declAttributes;
JsonGetAttributes(attributes, declAttributes);
- string symName = declAttributes["symName"];
- uint64_t typeID = atol(declAttributes["typeID"].c_str());
- uint64_t typeWidth = atol(declAttributes["typeWidth"].c_str());
+ string symName = declAttributes["symName"];
+ uint64_t typeID = atol(declAttributes["typeID"].c_str());
+ uint64_t typeWidth = atol(declAttributes["typeWidth"].c_str());
auto location = builder.getUnknownLoc();
LocalDeclOp op = builder.create<LocalDeclOp>(location, id, symName, typeID, typeWidth);
decls.push_back(op);
}
}
+void PluginServer::LoopOpsJsonDeSerialize(const string& data)
+{
+ Json::Value root;
+ Json::Reader reader;
+ Json::Value node;
+ reader.parse(data, root);
+
+ Json::Value::Members operation = root.getMemberNames();
+ context.getOrLoadDialect<PluginDialect>();
+ mlir::OpBuilder builder(&context);
+ for (Json::Value::Members::iterator iter = operation.begin(); iter != operation.end(); iter++) {
+ string operationKey = *iter;
+ node = root[operationKey];
+ int64_t id = GetID(node["id"]);
+ Json::Value attributes = node["attributes"];
+ map<string, string> loopAttributes;
+ JsonGetAttributes(attributes, loopAttributes);
+ uint32_t index = atoi(attributes["index"].asString().c_str());
+ uint64_t innerId = atol(loopAttributes["innerLoopId"].c_str());
+ uint64_t outerId = atol(loopAttributes["outerLoopId"].c_str());
+ uint32_t numBlock = atoi(loopAttributes["numBlock"].c_str());
+ auto location = builder.getUnknownLoc();
+ LoopOp op = builder.create<LoopOp>(location, id, index, innerId, outerId, numBlock);
+ loops.push_back(op);
+ }
+}
+
+void PluginServer::LoopOpJsonDeSerialize(const string& data)
+{
+ Json::Value root;
+ Json::Reader reader;
+ reader.parse(data, root);
+
+ context.getOrLoadDialect<PluginDialect>();
+ mlir::OpBuilder builder(&context);
+
+ uint64_t id = GetID(root["id"]);
+ Json::Value attributes = root["attributes"];
+ uint32_t index = atoi(attributes["index"].asString().c_str());
+ uint64_t innerLoopId = atol(attributes["innerLoopId"].asString().c_str());
+ uint64_t outerLoopId = atol(attributes["outerLoopId"].asString().c_str());
+ uint32_t numBlock = atoi(attributes["numBlock"].asString().c_str());
+ auto location = builder.getUnknownLoc();
+ loop = builder.create<LoopOp>(location, id, index, innerLoopId, outerLoopId, numBlock);
+}
+
+void PluginServer::BoolResJsonDeSerialize(const string& data)
+{
+ Json::Value root;
+ Json::Reader reader;
+ reader.parse(data, root);
+
+ boolRes = (bool)atoi(root["result"].asString().c_str());
+}
+
+void PluginServer::EdgesJsonDeSerialize(const string& data)
+{
+ Json::Value root;
+ Json::Reader reader;
+ Json::Value node;
+ reader.parse(data, root);
+
+ Json::Value::Members operation = root.getMemberNames();
+ context.getOrLoadDialect<PluginDialect>();
+ mlir::OpBuilder builder(&context);
+ for (Json::Value::Members::iterator iter = operation.begin(); iter != operation.end(); iter++) {
+ string operationKey = *iter;
+ node = root[operationKey];
+ uint64_t src = atol(node["src"].asString().c_str());
+ uint64_t dest = atol(node["dest"].asString().c_str());
+ pair<uint64_t, uint64_t> e;
+ e.first = src;
+ e.second = dest;
+ edges.push_back(e);
+ }
+}
+
+void PluginServer::EdgeJsonDeSerialize(const string& data)
+{
+ Json::Value root;
+ Json::Reader reader;
+ reader.parse(data, root);
+ uint64_t src = atol(root["src"].asString().c_str());
+ uint64_t dest = atol(root["dest"].asString().c_str());
+ edge.first = src;
+ edge.second = dest;
+}
+
+void PluginServer::BlocksJsonDeSerialize(const string& data)
+{
+ Json::Value root;
+ Json::Reader reader;
+ Json::Value node;
+ reader.parse(data, root);
+
+ Json::Value::Members operation = root.getMemberNames();
+ context.getOrLoadDialect<PluginDialect>();
+ mlir::OpBuilder builder(&context);
+ for (Json::Value::Members::iterator iter = operation.begin(); iter != operation.end(); iter++) {
+ string operationKey = *iter;
+ node = root[operationKey];
+ uint64_t id = atol(node["id"].asString().c_str());
+ blockIds.push_back(id);
+ }
+}
+
+void PluginServer::BlockJsonDeSerialize(const string& data)
+{
+ Json::Value root;
+ Json::Reader reader;
+ reader.parse(data, root);
+
+ blockId = (uint64_t)atol(root["id"].asString().c_str());
+}
/* 线程函数,执行用户注册函数,客户端返回数据后退出 */
static void ExecCallbacks(const string& name)
diff --git a/user.cpp b/user.cpp
index 81958c0..efc4158 100644
--- a/user.cpp
+++ b/user.cpp
@@ -80,7 +80,7 @@ static void PassManagerSetupFunc(void)
static bool
determineLoopForm(LoopOp loop)
{
- if (loop.innerLoopIdAttr().getUInt() != 0 || loop.numBlockAttr().getUInt() != 3)
+ if (loop.innerLoopIdAttr().getInt() != 0 || loop.numBlockAttr().getInt() != 3)
{
printf ("\nWrong loop form, there is inner loop or redundant bb.\n");
return false;
@@ -97,21 +97,21 @@ determineLoopForm(LoopOp loop)
static void
ProcessArrayWiden(void)
{
- std::cout << "Running first pass, OMG\n";
+ std::cout << "Running first pass, awiden\n";
PluginServerAPI pluginAPI;
vector<FunctionOp> allFunction = pluginAPI.GetAllFunc();
-
+
for (auto &funcOp : allFunction) {
string name = funcOp.funcNameAttr().getValue().str();
printf("Now process func : %s \n", name.c_str());
vector<LoopOp> allLoop = funcOp.GetAllLoops();
- for (auto &loop : allLoop) {
- if (determineLoopForm(loop)) {
- printf("The %dth loop form is success matched, and the loop can be optimized.\n", loop.indexAttr().getUInt());
- return;
- }
+ for (auto &loop : allLoop) {
+ if (determineLoopForm(loop)) {
+ printf("The %ldth loop form is success matched, and the loop can be optimized.\n", loop.indexAttr().getInt());
+ return;
}
+ }
}
}
--
2.27.0.windows.1

View File

@ -0,0 +1,984 @@
From b721e3a4292503115329d6380b590b3bab1cd856 Mon Sep 17 00:00:00 2001
From: Mingchuan Wu <wumingchuan1992@foxmail.com>
Date: Thu, 8 Dec 2022 20:14:09 +0800
Subject: [PATCH 3/4] [Pin-server] Support build CFG, CondOp, CallOp, PhiOp and
AssignOp. Add CondOp, CallOp, PhiOp and AssignOp for PluginDialect. Now we
can support CFG.
---
include/Dialect/CMakeLists.txt | 3 +
include/Dialect/PluginDialect.td | 38 ++++
include/Dialect/PluginOps.h | 4 +
include/Dialect/PluginOps.td | 142 ++++++++++++++-
include/PluginAPI/BasicPluginOpsAPI.h | 5 +
include/PluginAPI/PluginServerAPI.h | 10 +-
include/PluginServer/PluginServer.h | 22 +++
lib/Dialect/PluginOps.cpp | 150 +++++++++++++++-
lib/PluginAPI/PluginServerAPI.cpp | 60 ++++++-
lib/PluginServer/PluginServer.cpp | 250 ++++++++++++++++++++++++--
user.cpp | 2 +-
11 files changed, 663 insertions(+), 23 deletions(-)
diff --git a/include/Dialect/CMakeLists.txt b/include/Dialect/CMakeLists.txt
index f0dfc58..f44e77c 100644
--- a/include/Dialect/CMakeLists.txt
+++ b/include/Dialect/CMakeLists.txt
@@ -1,5 +1,8 @@
# Add for the dialect operations. arg:(dialect dialect_namespace)
file(COPY /usr/bin/mlir-tblgen DESTINATION ./)
+set(LLVM_TARGET_DEFINITIONS PluginOps.td)
+mlir_tablegen(PluginOpsEnums.h.inc -gen-enum-decls)
+mlir_tablegen(PluginOpsEnums.cpp.inc -gen-enum-defs)
add_mlir_dialect(PluginOps Plugin)
# Necessary to generate documentation. arg:(doc_filename command output_file output_directory)
diff --git a/include/Dialect/PluginDialect.td b/include/Dialect/PluginDialect.td
index 362a5c8..31b338d 100644
--- a/include/Dialect/PluginDialect.td
+++ b/include/Dialect/PluginDialect.td
@@ -46,4 +46,42 @@ def Plugin_Dialect : Dialect {
class Plugin_Op<string mnemonic, list<OpTrait> traits = []> :
Op<Plugin_Dialect, mnemonic, traits>;
+//===----------------------------------------------------------------------===//
+// PluginDialect enum definitions
+//===----------------------------------------------------------------------===//
+
+def IComparisonLT : I32EnumAttrCase<"lt", 0>;
+def IComparisonLE : I32EnumAttrCase<"le", 1>;
+def IComparisonGT : I32EnumAttrCase<"gt", 2>;
+def IComparisonGE : I32EnumAttrCase<"ge", 3>;
+def IComparisonLTGT : I32EnumAttrCase<"ltgt", 4>;
+def IComparisonEQ : I32EnumAttrCase<"eq", 5>;
+def IComparisonNE : I32EnumAttrCase<"ne", 6>;
+def IComparisonUNDEF : I32EnumAttrCase<"UNDEF", 7>;
+def IComparisonAttr : I32EnumAttr<
+ "IComparisonCode", "plugin comparison code",
+ [IComparisonLT, IComparisonLE, IComparisonGT, IComparisonGE,
+ IComparisonLTGT, IComparisonEQ, IComparisonNE, IComparisonUNDEF]>{
+ let cppNamespace = "::mlir::Plugin";
+}
+
+def IDefineCodeMemRef : I32EnumAttrCase<"MemRef", 0>;
+def IDefineCodeIntCST : I32EnumAttrCase<"IntCST", 1>;
+def IDefineCodeUNDEF : I32EnumAttrCase<"UNDEF", 2>;
+def IDefineCodeAttr : I32EnumAttr<
+ "IDefineCode", "plugin define code",
+ [IDefineCodeMemRef, IDefineCodeIntCST, IDefineCodeUNDEF]>{
+ let cppNamespace = "::mlir::Plugin";
+}
+
+def IExprCodePlus : I32EnumAttrCase<"Plus", 0>;
+def IExprCodeMinus : I32EnumAttrCase<"Minus", 1>;
+def IExprCodeNop : I32EnumAttrCase<"Nop", 2>;
+def IExprCodeUNDEF : I32EnumAttrCase<"UNDEF", 3>;
+def IExprCodeAttr : I32EnumAttr<
+ "IExprCode", "plugin expr code",
+ [IExprCodePlus, IExprCodeMinus, IExprCodeNop, IExprCodeUNDEF]>{
+ let cppNamespace = "::mlir::Plugin";
+}
+
#endif // PLUGIN_DIALECT_TD
\ No newline at end of file
diff --git a/include/Dialect/PluginOps.h b/include/Dialect/PluginOps.h
index be2a3ef..8bab877 100644
--- a/include/Dialect/PluginOps.h
+++ b/include/Dialect/PluginOps.h
@@ -27,6 +27,10 @@
#include "mlir/IR/Dialect.h"
#include "mlir/IR/OpDefinition.h"
#include "mlir/Interfaces/SideEffectInterfaces.h"
+#include "mlir/Interfaces/CallInterfaces.h"
+
+// Pull in all enum type definitions and utility function declarations.
+#include "Dialect/PluginOpsEnums.h.inc"
#define GET_OP_CLASSES
#include "Dialect/PluginOps.h.inc"
diff --git a/include/Dialect/PluginOps.td b/include/Dialect/PluginOps.td
index 02d9bdd..e91cd84 100644
--- a/include/Dialect/PluginOps.td
+++ b/include/Dialect/PluginOps.td
@@ -28,8 +28,8 @@ def FunctionOp : Plugin_Op<"function", [NoSideEffect]> {
TODO.
}];
- let arguments = (ins OptionalAttr<UI64Attr>:$id,
- OptionalAttr<StrAttr>:$funcName,
+ let arguments = (ins UI64Attr:$id,
+ StrAttr:$funcName,
OptionalAttr<BoolAttr>:$declaredInline);
let regions = (region AnyRegion:$bodyRegion);
@@ -89,4 +89,142 @@ def LoopOp : Plugin_Op<"loop", [NoSideEffect]> {
}];
}
+def CallOp : Plugin_Op<"call", [
+ DeclareOpInterfaceMethods<CallOpInterface>]> {
+ let summary = "call operation";
+ let description = [{
+ CallOp represent calls to a user defined function that needs to
+ be specialized for the shape of its arguments.
+ The callee name is attached as a symbol reference via an attribute.
+ The arguments list must match the arguments expected by the callee.
+ }];
+ let arguments = (ins UI64Attr:$id,
+ FlatSymbolRefAttr:$callee,
+ Variadic<AnyType>:$inputs);
+ let results = (outs Optional<AnyType>:$result);
+ let builders = [
+ OpBuilderDAG<(ins "uint64_t":$id, "StringRef":$callee,
+ "ArrayRef<Value>":$arguments)>
+ ];
+ let extraClassDeclaration = [{
+ bool SetLHS(Value lhs);
+ }];
+ let assemblyFormat = [{
+ $callee `(` $inputs `)` attr-dict `:` functional-type($inputs, results)
+ }];
+}
+
+def PhiOp : Plugin_Op<"phi", [NoSideEffect]> {
+ let summary = "phi op";
+ let description = [{TODO}];
+ let arguments = (ins UI64Attr:$id,
+ UI32Attr:$capacity,
+ UI32Attr:$nArgs,
+ Variadic<AnyType>:$operands);
+ let results = (outs AnyType:$result);
+ let builders = [
+ OpBuilderDAG<(ins "uint64_t":$id, "uint32_t":$capacity,
+ "uint32_t":$nArgs, "ArrayRef<Value>":$operands,
+ "Type":$resultType)>
+ ];
+ let extraClassDeclaration = [{
+ Value GetResult();
+ Value GetArgDef(int i) { return getOperand(i); }
+ }];
+}
+
+def AssignOp : Plugin_Op<"assign", [NoSideEffect]> {
+ let summary = "assign op";
+ let description = [{TODO}];
+ let arguments = (ins UI64Attr:$id,
+ IExprCodeAttr:$exprCode,
+ Variadic<AnyType>:$operands);
+ let results = (outs AnyType:$result);
+ let builders = [
+ OpBuilderDAG<(ins "uint64_t":$id, "IExprCode":$exprCode,
+ "ArrayRef<Value>":$operands, "Type":$resultType)>
+ ];
+ let extraClassDeclaration = [{
+ Value GetLHS() { return getOperand(0); }
+ Value GetRHS1() { return getOperand(1); }
+ Value GetRHS2() { return getOperand(2); }
+ }];
+}
+
+def PlaceholderOp : Plugin_Op<"placeholder", [NoSideEffect]> {
+ let summary = "PlaceHolder.";
+ let description = [{TODO}];
+ let arguments = (ins UI64Attr:$id,
+ OptionalAttr<IDefineCodeAttr>:$defCode);
+ let results = (outs AnyType);
+ let builders = [
+ OpBuilderDAG<(ins "uint64_t":$id, "IDefineCode":$defCode, "Type":$retType)>
+ ];
+}
+
+def BaseOp : Plugin_Op<"statement_base", [NoSideEffect]> {
+ let summary = "Base operation, just like placeholder for statement.";
+ let description = [{TODO}];
+ let arguments = (ins UI64Attr:$id, StrAttr:$opCode);
+ let results = (outs AnyType);
+ let builders = [
+ OpBuilderDAG<(ins "uint64_t":$id, "StringRef":$opCode)>
+ ];
+}
+
+// Terminators
+// Opaque builder used for terminator operations that contain successors.
+
+class Plugin_TerminatorOp<string mnemonic, list<OpTrait> traits = []> :
+ Plugin_Op<mnemonic, !listconcat(traits, [Terminator])>;
+
+def FallThroughOp : Plugin_TerminatorOp<"fallthrough", [NoSideEffect]> {
+ let summary = "FallThroughOp";
+ let description = [{TODO}];
+ let successors = (successor AnySuccessor:$dest);
+ // for bb address
+ let arguments = (ins UI64Attr:$address, UI64Attr:$destaddr);
+ let results = (outs AnyType);
+ let builders = [
+ OpBuilderDAG<(ins "uint64_t":$address, "Block*":$dest, "uint64_t":$destaddr)>
+ ];
+}
+
+def CondOp : Plugin_TerminatorOp<"condition", [NoSideEffect]> {
+ let summary = "condition op";
+ let description = [{TODO}];
+ let arguments = (ins UI64Attr:$id, UI64Attr:$address,
+ IComparisonAttr:$condCode,
+ AnyType:$LHS, AnyType:$RHS,
+ UI64Attr:$tbaddr,
+ UI64Attr:$fbaddr,
+ OptionalAttr<TypeAttr>:$trueLabel,
+ OptionalAttr<TypeAttr>:$falseLabel);
+ let successors = (successor AnySuccessor:$tb, AnySuccessor:$fb);
+ let builders = [
+ OpBuilderDAG<(ins "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)>,
+ // Only for server.
+ OpBuilderDAG<(ins "IComparisonCode":$condCode,
+ "Value":$lhs, "Value":$rhs)>
+ ];
+ let extraClassDeclaration = [{
+ Value GetLHS() { return getOperand(0); }
+ Value GetRHS() { return getOperand(1); }
+ }];
+}
+
+// todo: currently RetOp do not have a correct assemblyFormat
+def RetOp : Plugin_TerminatorOp<"ret", [NoSideEffect]> {
+ let summary = "RetOp";
+ let description = [{TODO}];
+ let arguments = (ins UI64Attr:$address); // for bb address
+ let results = (outs AnyType);
+ let builders = [
+ OpBuilderDAG<(ins "uint64_t":$address)>
+ ];
+}
+
#endif // PLUGIN_OPS_TD
\ No newline at end of file
diff --git a/include/PluginAPI/BasicPluginOpsAPI.h b/include/PluginAPI/BasicPluginOpsAPI.h
index fde5f63..6f5fbb0 100644
--- a/include/PluginAPI/BasicPluginOpsAPI.h
+++ b/include/PluginAPI/BasicPluginOpsAPI.h
@@ -48,6 +48,11 @@ public:
virtual pair<uint64_t, uint64_t> LoopSingleExit(uint64_t) = 0;
virtual vector<pair<uint64_t, uint64_t> > GetLoopExitEdges(uint64_t) = 0;
virtual LoopOp GetBlockLoopFather(uint64_t) = 0;
+ virtual PhiOp GetPhiOp(uint64_t) = 0;
+ virtual CallOp GetCallOp(uint64_t) = 0;
+ virtual bool SetLhsInCallOp(uint64_t, uint64_t) = 0;
+ virtual uint64_t CreateCondOp(IComparisonCode, uint64_t, uint64_t) = 0;
+ virtual mlir::Value GetResultFromPhi(uint64_t) = 0;
}; // class BasicPluginOpsAPI
} // namespace PluginAPI
diff --git a/include/PluginAPI/PluginServerAPI.h b/include/PluginAPI/PluginServerAPI.h
index 5b14f2e..425b946 100644
--- a/include/PluginAPI/PluginServerAPI.h
+++ b/include/PluginAPI/PluginServerAPI.h
@@ -38,6 +38,8 @@ public:
vector<FunctionOp> GetAllFunc() override;
vector<LocalDeclOp> GetDecls(uint64_t) override;
+ PhiOp GetPhiOp(uint64_t) override;
+ CallOp GetCallOp(uint64_t) override;
PluginIR::PluginTypeID GetTypeCodeFromString(string type);
LoopOp AllocateNewLoop(uint64_t funcID);
LoopOp GetLoopById(uint64_t loopID);
@@ -51,8 +53,14 @@ public:
uint64_t GetLatch(uint64_t loopID);
vector<uint64_t> GetLoopBody(uint64_t loopID);
LoopOp GetBlockLoopFather(uint64_t blockID);
+ /* Plugin API for CallOp. */
+ bool SetLhsInCallOp(uint64_t, uint64_t);
+ /* Plugin API for CondOp. */
+ uint64_t CreateCondOp(IComparisonCode, uint64_t, uint64_t) override;
+ mlir::Value GetResultFromPhi(uint64_t) override;
+
private:
- vector<FunctionOp> GetOperationResult(const string& funName, const string& params);
+ vector<FunctionOp> GetFunctionOpResult(const string& funName, const string& params);
vector<LocalDeclOp> GetDeclOperationResult(const string& funName, const string& params);
LoopOp GetLoopResult(const string&funName, const string& params);
vector<LoopOp> GetLoopsResult(const string& funName, const string& params);
diff --git a/include/PluginServer/PluginServer.h b/include/PluginServer/PluginServer.h
index 610ecb9..b28c6d0 100644
--- a/include/PluginServer/PluginServer.h
+++ b/include/PluginServer/PluginServer.h
@@ -33,6 +33,7 @@
#include "Dialect/PluginOps.h"
#include "plugin.grpc.pb.h"
#include "mlir/IR/MLIRContext.h"
+#include "mlir/IR/Builders.h"
#include "Dialect/PluginTypes.h"
namespace PinServer {
@@ -120,6 +121,7 @@ private:
class PluginServer final : public PluginService::Service {
public:
+ PluginServer() : opBuilder(&context){}
/* 定义的grpc服务端和客户端通信的接口函数 */
Status ReceiveSendMsg(ServerContext* context, ServerReaderWriter<ServerMsg, ClientMsg>* stream) override;
/* 服务端发送数据给client接口 */
@@ -137,6 +139,10 @@ public:
vector<std::pair<uint64_t, uint64_t> > EdgesResult(void);
std::pair<uint64_t, uint64_t> EdgeResult(void);
bool BoolResult(void);
+ vector<mlir::Operation *> GetOpResult(void);
+ bool GetBoolResult(void);
+ uint64_t GetIdResult(void);
+ mlir::Value GetValueResult(void);
/* 回调函数接口用于向server注册用户需要执行的函数 */
int RegisterUserFunc(InjectPoint inject, UserFunc func);
int RegisterPassManagerSetup(InjectPoint inject, const ManagerSetupData& passData, UserFunc func);
@@ -190,6 +196,13 @@ public:
void EdgeJsonDeSerialize(const string& data);
void BlocksJsonDeSerialize(const string& data);
void BlockJsonDeSerialize(const string& data);
+ void CallOpJsonDeSerialize(const string& data);
+ void CondOpJsonDeSerialize(const string& data);
+ void RetOpJsonDeSerialize(const string& data);
+ void FallThroughOpJsonDeSerialize(const string& data);
+ void PhiOpJsonDeSerialize(const string& data);
+ void AssignOpJsonDeSerialize(const string& data);
+ mlir::Value ValueJsonDeSerialize(Json::Value valueJson);
/* json反序列化根据key值分别调用Operation/Decl/Type反序列化接口函数 */
void JsonDeSerialize(const string& key, const string& data);
/* 解析客户端发送过来的-fplugin-arg参数并保存在私有变量args中 */
@@ -234,6 +247,7 @@ private:
/* 用户函数执行状态client返回结果后为STATE_RETURN,开始执行下一个函数 */
volatile UserFunStateEnum userFunState;
mlir::MLIRContext context;
+ mlir::OpBuilder opBuilder;
vector<mlir::Plugin::FunctionOp> funcOpData;
PluginIR::PluginTypeBase pluginType;
vector<mlir::Plugin::LocalDeclOp> decls;
@@ -244,6 +258,10 @@ private:
vector<uint64_t> blockIds;
uint64_t blockId;
bool boolRes;
+ vector<mlir::Operation *> opData;
+ bool boolResult;
+ bool idResult;
+ mlir::Value valueResult;
/* 保存用户注册的回调函数,它们将在注入点事件触发后调用 */
map<InjectPoint, vector<RecordedUserFunc>> userFunc;
string apiFuncName; // 保存用户调用PluginAPI的函数名
@@ -252,6 +270,10 @@ private:
timer_t timerId;
map<string, string> args; // 保存gcc编译时用户传入参数
sem_t sem[2];
+
+ // process Block.
+ std::map<uint64_t, mlir::Block*> blockMaps;
+ bool ProcessBlock(mlir::Block*, mlir::Region&, const Json::Value&);
}; // class PluginServer
void RunServer(int timeout, string& port);
diff --git a/lib/Dialect/PluginOps.cpp b/lib/Dialect/PluginOps.cpp
index 481d51a..d647fc4 100644
--- a/lib/Dialect/PluginOps.cpp
+++ b/lib/Dialect/PluginOps.cpp
@@ -33,8 +33,9 @@ using namespace mlir::Plugin;
using std::vector;
using std::pair;
-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)
+{
FunctionOp::build(builder, state,
builder.getI64IntegerAttr(id),
builder.getStringAttr(funcName),
@@ -48,9 +49,10 @@ vector<LoopOp> FunctionOp::GetAllLoops()
return pluginAPI.GetLoopsFromFunc(funcId);
}
-void LocalDeclOp::build(mlir::OpBuilder &builder, mlir::OperationState &state,
+void LocalDeclOp::build(OpBuilder &builder, OperationState &state,
uint64_t id, StringRef symName,
- int64_t typeID, uint64_t typeWidth) {
+ int64_t typeID, uint64_t typeWidth)
+{
LocalDeclOp::build(builder, state,
builder.getI64IntegerAttr(id),
builder.getStringAttr(symName),
@@ -142,6 +144,146 @@ void LoopOp::AddLoop(uint64_t outerId, uint64_t funcId)
return pluginAPI.AddLoop(loopId, outerId, funcId);
}
+//===----------------------------------------------------------------------===//
+// PlaceholderOp
+
+void PlaceholderOp::build(OpBuilder &builder, OperationState &state,
+ uint64_t id, IDefineCode defCode, Type retType) {
+ state.addAttribute("id", builder.getI64IntegerAttr(id));
+ state.addAttribute("defCode",
+ builder.getI32IntegerAttr(static_cast<int32_t>(defCode)));
+ if (retType) state.addTypes(retType);
+}
+
+//===----------------------------------------------------------------------===//
+// CallOp
+
+void CallOp::build(OpBuilder &builder, OperationState &state,
+ uint64_t id, StringRef callee,
+ ArrayRef<Value> arguments)
+{
+ state.addAttribute("id", builder.getI64IntegerAttr(id));
+ state.addOperands(arguments);
+ state.addAttribute("callee", builder.getSymbolRefAttr(callee));
+}
+
+/// Return the callee of the generic call operation, this is required by the
+/// call interface.
+CallInterfaceCallable CallOp::getCallableForCallee()
+{
+ return (*this)->getAttrOfType<SymbolRefAttr>("callee");
+}
+
+/// Get the argument operands to the called function, this is required by the
+/// call interface.
+Operation::operand_range CallOp::getArgOperands() { return inputs(); }
+
+bool CallOp::SetLHS(Value lhs)
+{
+ PlaceholderOp phOp = lhs.getDefiningOp<PlaceholderOp>();
+ uint64_t lhsId = phOp.idAttr().getInt();
+ PluginAPI::PluginServerAPI pluginAPI;
+ return pluginAPI.SetLhsInCallOp(this->idAttr().getInt(), lhsId);
+}
+
+//===----------------------------------------------------------------------===//
+// 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) {
+ state.addAttribute("id", builder.getI64IntegerAttr(id));
+ state.addAttribute("address", builder.getI64IntegerAttr(address));
+ state.addAttribute("tbaddr", builder.getI64IntegerAttr(tbaddr));
+ state.addAttribute("fbaddr", builder.getI64IntegerAttr(fbaddr));
+ state.addOperands({lhs, rhs});
+ state.addSuccessors(tb);
+ state.addSuccessors(fb);
+ state.addAttribute("condCode",
+ builder.getI32IntegerAttr(static_cast<int32_t>(condCode)));
+ if (trueLabel != nullptr) state.addOperands(trueLabel);
+ if (falseLabel != nullptr) state.addOperands(falseLabel);
+}
+
+void CondOp::build(OpBuilder &builder, OperationState &state,
+ IComparisonCode condCode, Value lhs, Value rhs)
+{
+ PluginAPI::PluginServerAPI pluginAPI;
+ PlaceholderOp lhsOp = lhs.getDefiningOp<PlaceholderOp>();
+ uint64_t lhsId = lhsOp.idAttr().getInt();
+ PlaceholderOp rhsOp = rhs.getDefiningOp<PlaceholderOp>();
+ uint64_t rhsId = rhsOp.idAttr().getInt();
+ uint64_t id = pluginAPI.CreateCondOp(condCode, lhsId, rhsId);
+ state.addAttribute("id", builder.getI64IntegerAttr(id));
+ state.addOperands({lhs, rhs});
+ state.addAttribute("condCode",
+ builder.getI32IntegerAttr(static_cast<int32_t>(condCode)));
+}
+
+//===----------------------------------------------------------------------===//
+// PhiOp
+
+void PhiOp::build(OpBuilder &builder, OperationState &state,
+ uint64_t id, uint32_t capacity, uint32_t nArgs,
+ ArrayRef<Value> 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) state.addTypes(resultType);
+}
+
+Value PhiOp::GetResult()
+{
+ PluginAPI::PluginServerAPI pluginAPI;
+ return pluginAPI.GetResultFromPhi(this->idAttr().getInt());
+}
+
+//===----------------------------------------------------------------------===//
+// AssignOp
+
+void AssignOp::build(OpBuilder &builder, OperationState &state,
+ uint64_t id, IExprCode exprCode,
+ ArrayRef<Value> operands, Type resultType)
+{
+ state.addAttribute("id", builder.getI64IntegerAttr(id));
+ state.addAttribute("exprCode",
+ builder.getI32IntegerAttr(static_cast<int32_t>(exprCode)));
+ state.addOperands(operands);
+ if (resultType) state.addTypes(resultType);
+}
+
+//===----------------------------------------------------------------------===//
+// BaseOp
+
+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)
+{
+ 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)
+{
+ state.addAttribute("address", builder.getI64IntegerAttr(address));
+}
+
//===----------------------------------------------------------------------===//
// TableGen'd op method definitions
//===----------------------------------------------------------------------===//
diff --git a/lib/PluginAPI/PluginServerAPI.cpp b/lib/PluginAPI/PluginServerAPI.cpp
index 41626f9..65eafa7 100644
--- a/lib/PluginAPI/PluginServerAPI.cpp
+++ b/lib/PluginAPI/PluginServerAPI.cpp
@@ -54,7 +54,7 @@ void PluginServerAPI::WaitClientResult(const string& funName, const string& para
}
}
-vector<FunctionOp> PluginServerAPI::GetOperationResult(const string& funName, const string& params)
+vector<FunctionOp> PluginServerAPI::GetFunctionOpResult(const string& funName, const string& params)
{
WaitClientResult(funName, params);
vector<FunctionOp> retOps = PluginServer::GetInstance()->GetFunctionOpResult();
@@ -67,7 +67,63 @@ vector<FunctionOp> PluginServerAPI::GetAllFunc()
string funName = __func__;
string params = root.toStyledString();
- return GetOperationResult(funName, params);
+ return GetFunctionOpResult(funName, params);
+}
+
+PhiOp PluginServerAPI::GetPhiOp(uint64_t id)
+{
+ Json::Value root;
+ string funName = __func__;
+ root["id"] = std::to_string(id);
+ string params = root.toStyledString();
+ WaitClientResult(funName, params);
+ vector<mlir::Operation*> opRet = PluginServer::GetInstance()->GetOpResult();
+ return llvm::dyn_cast<PhiOp>(opRet[0]);
+}
+
+CallOp PluginServerAPI::GetCallOp(uint64_t id)
+{
+ Json::Value root;
+ string funName = __func__;
+ root["id"] = std::to_string(id);
+ string params = root.toStyledString();
+ WaitClientResult(funName, params);
+ vector<mlir::Operation*> opRet = PluginServer::GetInstance()->GetOpResult();
+ return llvm::dyn_cast<CallOp>(opRet[0]);
+}
+
+bool PluginServerAPI::SetLhsInCallOp(uint64_t callId, uint64_t lhsId)
+{
+ Json::Value root;
+ string funName = __func__;
+ root["callId"] = std::to_string(callId);
+ root["lhsId"] = std::to_string(lhsId);
+ string params = root.toStyledString();
+ WaitClientResult(funName, params);
+ return PluginServer::GetInstance()->GetBoolResult();
+}
+
+uint64_t PluginServerAPI::CreateCondOp(IComparisonCode iCode,
+ uint64_t lhs, uint64_t rhs)
+{
+ Json::Value root;
+ string funName = __func__;
+ root["condCode"] = std::to_string(static_cast<int32_t>(iCode));
+ root["lhsId"] = std::to_string(lhs);
+ root["rhsId"] = std::to_string(rhs);
+ string params = root.toStyledString();
+ WaitClientResult(funName, params);
+ return PluginServer::GetInstance()->GetIdResult();
+}
+
+mlir::Value PluginServerAPI::GetResultFromPhi(uint64_t phiId)
+{
+ Json::Value root;
+ string funName = __func__;
+ root["id"] = std::to_string(phiId);
+ string params = root.toStyledString();
+ WaitClientResult(funName, params);
+ return PluginServer::GetInstance()->GetValueResult();
}
PluginIR::PluginTypeID PluginServerAPI::GetTypeCodeFromString(string type)
diff --git a/lib/PluginServer/PluginServer.cpp b/lib/PluginServer/PluginServer.cpp
index 92159e8..2eac906 100644
--- a/lib/PluginServer/PluginServer.cpp
+++ b/lib/PluginServer/PluginServer.cpp
@@ -27,7 +27,6 @@
#include "Dialect/PluginDialect.h"
#include "PluginAPI/PluginServerAPI.h"
#include "mlir/IR/Attributes.h"
-#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/BuiltinTypes.h"
#include "user.h"
@@ -37,7 +36,6 @@
namespace PinServer {
using namespace mlir::Plugin;
-
using std::cout;
using std::endl;
using std::pair;
@@ -75,6 +73,13 @@ int PluginServer::RegisterPassManagerSetup(InjectPoint inject, const ManagerSetu
return 0;
}
+vector<mlir::Operation *> PluginServer::GetOpResult(void)
+{
+ vector<mlir::Operation *> retOps = opData;
+ opData.clear();
+ return retOps;
+}
+
vector<mlir::Plugin::FunctionOp> PluginServer::GetFunctionOpResult(void)
{
vector<mlir::Plugin::FunctionOp> retOps = funcOpData;
@@ -135,6 +140,21 @@ vector<pair<uint64_t, uint64_t> > PluginServer::EdgesResult()
return retEdges;
}
+bool PluginServer::GetBoolResult()
+{
+ return this->boolResult;
+}
+
+uint64_t PluginServer::GetIdResult()
+{
+ return this->idResult;
+}
+
+mlir::Value PluginServer::GetValueResult()
+{
+ return this->valueResult;
+}
+
void PluginServer::JsonGetAttributes(Json::Value node, map<string, string>& attributes)
{
Json::Value::Members attMember = node.getMemberNames();
@@ -151,6 +171,27 @@ static uintptr_t GetID(Json::Value node)
return atol(id.c_str());
}
+mlir::Value PluginServer::ValueJsonDeSerialize(Json::Value valueJson)
+{
+ uint64_t opId = GetID(valueJson["id"]);
+ IDefineCode defCode = IDefineCode(
+ atoi(valueJson["defCode"].asString().c_str()));
+ switch (defCode) {
+ case IDefineCode::MemRef : {
+ break;
+ }
+ case IDefineCode::IntCST : {
+ break;
+ }
+ default:
+ break;
+ }
+ mlir::Type retType = PluginIR::PluginUndefType::get(&context); // FIXME!
+ mlir::Value opValue = opBuilder.create<PlaceholderOp>(
+ opBuilder.getUnknownLoc(), opId, defCode, retType);
+ return opValue;
+}
+
void PluginServer::JsonDeSerialize(const string& key, const string& data)
{
if (key == "FuncOpResult") {
@@ -173,6 +214,12 @@ void PluginServer::JsonDeSerialize(const string& key, const string& data)
EdgesJsonDeSerialize(data);
} else if (key == "BlockIdsResult") {
BlocksJsonDeSerialize(data);
+ } else if (key == "IdResult") {
+ this->idResult = atol(data.c_str());
+ } else if (key == "ValueResult") {
+ context.getOrLoadDialect<PluginDialect>();
+ opBuilder = mlir::OpBuilder(&context);
+ this->valueResult = ValueJsonDeSerialize(data.c_str());
} else {
cout << "not Json,key:" << key << ",value:" << data << endl;
}
@@ -217,6 +264,46 @@ void PluginServer::TypeJsonDeSerialize(const string& data)
return;
}
+bool PluginServer::ProcessBlock(mlir::Block* block, mlir::Region& rg,
+ const Json::Value& blockJson)
+{
+ if (blockJson.isNull()) {
+ return false;
+ }
+ // todo process func return type
+ // todo isDeclaration
+
+ // process each stmt
+ opBuilder.setInsertionPointToStart(block);
+ Json::Value::Members opMember = blockJson.getMemberNames();
+ for (Json::Value::Members::iterator opIdx = opMember.begin();
+ opIdx != opMember.end(); opIdx++) {
+ string baseOpKey = *opIdx;
+ Json::Value opJson = blockJson[baseOpKey];
+ if (opJson.isNull()) continue;
+ // llvm::StringRef opCode(opJson["OperationName"].asString().c_str());
+ string opCode = opJson["OperationName"].asString();
+ if (opCode == PhiOp::getOperationName().str()) {
+ PhiOpJsonDeSerialize(opJson.toStyledString());
+ } else if (opCode == CallOp::getOperationName().str()) {
+ CallOpJsonDeSerialize(opJson.toStyledString());
+ } else if (opCode == AssignOp::getOperationName().str()) {
+ AssignOpJsonDeSerialize(opJson.toStyledString());
+ } else if (opCode == CondOp::getOperationName().str()) {
+ CondOpJsonDeSerialize(opJson.toStyledString());
+ } else if (opCode == RetOp::getOperationName().str()) {
+ RetOpJsonDeSerialize(opJson.toStyledString());
+ } else if (opCode == FallThroughOp::getOperationName().str()) {
+ FallThroughOpJsonDeSerialize(opJson.toStyledString());
+ } else if (opCode == BaseOp::getOperationName().str()) {
+ uint64_t opID = GetID(opJson["id"]);
+ opBuilder.create<BaseOp>(opBuilder.getUnknownLoc(), opID, opCode);
+ }
+ }
+ // fprintf(stderr, "[bb] op:%ld, succ: %d\n", block->getOperations().size(), block->getNumSuccessors());
+ return true;
+}
+
void PluginServer::FuncOpJsonDeSerialize(const string& data)
{
Json::Value root;
@@ -227,8 +314,9 @@ void PluginServer::FuncOpJsonDeSerialize(const string& data)
Json::Value::Members operation = root.getMemberNames();
context.getOrLoadDialect<PluginDialect>();
- mlir::OpBuilder builder(&context);
- for (Json::Value::Members::iterator iter = operation.begin(); iter != operation.end(); iter++) {
+ opBuilder = mlir::OpBuilder(&context);
+ for (Json::Value::Members::iterator iter = operation.begin();
+ iter != operation.end(); iter++) {
string operationKey = *iter;
node = root[operationKey];
int64_t id = GetID(node["id"]);
@@ -237,9 +325,30 @@ void PluginServer::FuncOpJsonDeSerialize(const string& data)
JsonGetAttributes(attributes, funcAttributes);
bool declaredInline = false;
if (funcAttributes["declaredInline"] == "1") declaredInline = true;
- auto location = builder.getUnknownLoc();
- FunctionOp op = builder.create<FunctionOp>(location, id, funcAttributes["funcName"], declaredInline);
- funcOpData.push_back(op);
+ auto location = opBuilder.getUnknownLoc();
+ FunctionOp fOp = opBuilder.create<FunctionOp>(
+ location, id, funcAttributes["funcName"], declaredInline);
+ mlir::Region &bodyRegion = fOp.bodyRegion();
+ Json::Value regionJson = node["region"];
+ Json::Value::Members bbMember = regionJson.getMemberNames();
+ // We must create Blocks before process ops
+ for (Json::Value::Members::iterator bbIdx = bbMember.begin();
+ bbIdx != bbMember.end(); bbIdx++) {
+ string blockKey = *bbIdx;
+ Json::Value blockJson = regionJson[blockKey];
+ mlir::Block* block = opBuilder.createBlock(&bodyRegion);
+ this->blockMaps.insert({GetID(blockJson["address"]), block});
+ }
+
+ for (Json::Value::Members::iterator bbIdx = bbMember.begin();
+ bbIdx != bbMember.end(); bbIdx++) {
+ string blockKey = *bbIdx;
+ Json::Value blockJson = regionJson[blockKey];
+ uint64_t bbAddress = GetID(blockJson["address"]);
+ ProcessBlock(this->blockMaps[bbAddress], bodyRegion, blockJson["ops"]);
+ }
+ funcOpData.push_back(fOp);
+ opBuilder.setInsertionPointAfter(fOp.getOperation());
}
}
@@ -253,7 +362,7 @@ void PluginServer::LocalDeclOpJsonDeSerialize(const string& data)
Json::Value::Members operation = root.getMemberNames();
context.getOrLoadDialect<PluginDialect>();
- mlir::OpBuilder builder(&context);
+ opBuilder = mlir::OpBuilder(&context);
for (Json::Value::Members::iterator iter = operation.begin(); iter != operation.end(); iter++) {
string operationKey = *iter;
node = root[operationKey];
@@ -261,11 +370,11 @@ void PluginServer::LocalDeclOpJsonDeSerialize(const string& data)
Json::Value attributes = node["attributes"];
map<string, string> declAttributes;
JsonGetAttributes(attributes, declAttributes);
- string symName = declAttributes["symName"];
- uint64_t typeID = atol(declAttributes["typeID"].c_str());
- uint64_t typeWidth = atol(declAttributes["typeWidth"].c_str());
- auto location = builder.getUnknownLoc();
- LocalDeclOp op = builder.create<LocalDeclOp>(location, id, symName, typeID, typeWidth);
+ string symName = declAttributes["symName"];
+ uint64_t typeID = atol(declAttributes["typeID"].c_str());
+ uint64_t typeWidth = atol(declAttributes["typeWidth"].c_str());
+ auto location = opBuilder.getUnknownLoc();
+ LocalDeclOp op = opBuilder.create<LocalDeclOp>(location, id, symName, typeID, typeWidth);
decls.push_back(op);
}
}
@@ -384,6 +493,121 @@ void PluginServer::BlockJsonDeSerialize(const string& data)
blockId = (uint64_t)atol(root["id"].asString().c_str());
}
+void PluginServer::CallOpJsonDeSerialize(const string& data)
+{
+ Json::Value node;
+ Json::Reader reader;
+ reader.parse(data, node);
+ Json::Value operandJson = node["operands"];
+ Json::Value::Members operandMember = operandJson.getMemberNames();
+ llvm::SmallVector<mlir::Value, 4> ops;
+ for (Json::Value::Members::iterator opIter = operandMember.begin();
+ opIter != operandMember.end(); opIter++) {
+ string key = *opIter;
+ mlir::Value opValue = ValueJsonDeSerialize(operandJson[key.c_str()]);
+ ops.push_back(opValue);
+ }
+ int64_t id = GetID(node["id"]);
+ mlir::StringRef callName(node["callee"].asString());
+ CallOp op = opBuilder.create<CallOp>(opBuilder.getUnknownLoc(),
+ id, callName, ops);
+ opData.push_back(op.getOperation());
+}
+
+void PluginServer::CondOpJsonDeSerialize(const string& data)
+{
+ Json::Value node;
+ Json::Reader reader;
+ reader.parse(data, node);
+ mlir::Value LHS = ValueJsonDeSerialize(node["lhs"]);
+ mlir::Value RHS = ValueJsonDeSerialize(node["rhs"]);
+ mlir::Value trueLabel = nullptr;
+ mlir::Value falseLabel = nullptr;
+ int64_t id = GetID(node["id"]);
+ int64_t address = GetID(node["address"]);
+ int64_t tbaddr = GetID(node["tbaddr"]);
+ int64_t fbaddr = GetID(node["fbaddr"]);
+ assert (this->blockMaps.find(tbaddr) != this->blockMaps.end());
+ assert (this->blockMaps.find(fbaddr) != this->blockMaps.end());
+ mlir::Block* tb = this->blockMaps[tbaddr];
+ mlir::Block* fb = this->blockMaps[fbaddr];
+ IComparisonCode iCode = IComparisonCode(
+ atoi(node["condCode"].asString().c_str()));
+ CondOp op = opBuilder.create<CondOp>(opBuilder.getUnknownLoc(), id,
+ address, iCode, LHS, RHS, tb, fb, tbaddr, fbaddr,
+ trueLabel, falseLabel);
+ opData.push_back(op.getOperation());
+}
+
+void PluginServer::RetOpJsonDeSerialize(const string& data)
+{
+ Json::Value node;
+ Json::Reader reader;
+ reader.parse(data, node);
+ int64_t address = GetID(node["address"]);
+ RetOp op = opBuilder.create<RetOp>(opBuilder.getUnknownLoc(), address);
+ opData.push_back(op.getOperation());
+}
+
+void PluginServer::FallThroughOpJsonDeSerialize(const string& data)
+{
+ Json::Value node;
+ Json::Reader reader;
+ reader.parse(data, node);
+ int64_t address = GetID(node["address"]);
+ int64_t destaddr = GetID(node["destaddr"]);
+ assert (this->blockMaps.find(destaddr) != this->blockMaps.end());
+ mlir::Block* succ = this->blockMaps[destaddr];
+ FallThroughOp op = opBuilder.create<FallThroughOp>(opBuilder.getUnknownLoc(),
+ address, succ, destaddr);
+ opData.push_back(op.getOperation());
+}
+
+void PluginServer::PhiOpJsonDeSerialize(const string& data)
+{
+ Json::Value node;
+ Json::Reader reader;
+ reader.parse(data, node);
+ Json::Value operandJson = node["operands"];
+ Json::Value::Members operandMember = operandJson.getMemberNames();
+ llvm::SmallVector<mlir::Value, 4> ops;
+ for (Json::Value::Members::iterator opIter = operandMember.begin();
+ opIter != operandMember.end(); opIter++) {
+ string key = *opIter;
+ mlir::Value opValue = ValueJsonDeSerialize(operandJson[key.c_str()]);
+ ops.push_back(opValue);
+ }
+ int64_t id = GetID(node["id"]);
+ uint32_t capacity = atoi(node["capacity"].asString().c_str());
+ uint32_t nArgs = atoi(node["nArgs"].asString().c_str());
+ mlir::Type retType = nullptr;
+ PhiOp op = opBuilder.create<PhiOp>(opBuilder.getUnknownLoc(),
+ id, capacity, nArgs, ops, retType);
+ opData.push_back(op.getOperation());
+}
+
+void PluginServer::AssignOpJsonDeSerialize(const string& data)
+{
+ Json::Value node;
+ Json::Reader reader;
+ reader.parse(data, node);
+ Json::Value operandJson = node["operands"];
+ Json::Value::Members operandMember = operandJson.getMemberNames();
+ llvm::SmallVector<mlir::Value, 4> ops;
+ for (Json::Value::Members::iterator opIter = operandMember.begin();
+ opIter != operandMember.end(); opIter++) {
+ string key = *opIter;
+ mlir::Value opValue = ValueJsonDeSerialize(operandJson[key.c_str()]);
+ ops.push_back(opValue);
+ }
+ int64_t id = GetID(node["id"]);
+ IExprCode iCode = IExprCode(atoi(node["exprCode"].asString().c_str()));
+ mlir::Type retType = nullptr;
+ AssignOp op = opBuilder.create<AssignOp>(opBuilder.getUnknownLoc(),
+ id, iCode, ops, retType);
+ opData.push_back(op.getOperation());
+}
+
/* 线程函数,执行用户注册函数,客户端返回数据后退出 */
static void ExecCallbacks(const string& name)
{
diff --git a/user.cpp b/user.cpp
index efc4158..605e6f8 100644
--- a/user.cpp
+++ b/user.cpp
@@ -117,7 +117,7 @@ ProcessArrayWiden(void)
void RegisterCallbacks(void)
{
- PluginServer::GetInstance()->RegisterUserFunc(HANDLE_BEFORE_IPA, UserOptimizeFunc);
+ // PluginServer::GetInstance()->RegisterUserFunc(HANDLE_BEFORE_IPA, UserOptimizeFunc);
PluginServer::GetInstance()->RegisterUserFunc(HANDLE_BEFORE_IPA, LocalVarSummery);
ManagerSetupData setupData;
setupData.refPassName = PASS_PHIOPT;
--
2.27.0.windows.1

View File

@ -0,0 +1,201 @@
From 7e56b74990e5f6ccb9a2896eeea0d60e1e2b1f21 Mon Sep 17 00:00:00 2001
From: dingguangya <dingguangya1@huawei.com>
Date: Thu, 8 Dec 2022 20:50:23 +0800
Subject: [PATCH 4/4] [Pin-server] Support Plugin Pointer Type
---
include/Dialect/PluginTypes.h | 12 +++++++++
include/PluginServer/PluginServer.h | 2 +-
lib/Dialect/PluginDialect.cpp | 1 +
lib/Dialect/PluginTypes.cpp | 41 +++++++++++++++++++++++++++++
lib/PluginServer/PluginServer.cpp | 28 +++++++++++++-------
5 files changed, 73 insertions(+), 11 deletions(-)
diff --git a/include/Dialect/PluginTypes.h b/include/Dialect/PluginTypes.h
index bb8d81a..1329b8d 100644
--- a/include/Dialect/PluginTypes.h
+++ b/include/Dialect/PluginTypes.h
@@ -80,6 +80,7 @@ private:
namespace detail {
struct PluginIntegerTypeStorage;
struct PluginFloatTypeStorage;
+ struct PluginPointerTypeStorage;
}
class PluginIntegerType : public Type::TypeBase<PluginIntegerType, PluginTypeBase, detail::PluginIntegerTypeStorage> {
@@ -117,6 +118,17 @@ public:
unsigned getWidth() const;
};
+class PluginPointerType : public Type::TypeBase<PluginPointerType, PluginTypeBase, detail::PluginPointerTypeStorage> {
+public:
+ using Base::Base;
+
+ PluginTypeID getPluginTypeID ();
+
+ static PluginPointerType get(MLIRContext *context, Type pointee);
+
+ Type getElementType();
+}; // class PluginPointerType
+
class PluginVoidType : public Type::TypeBase<PluginVoidType, PluginTypeBase, TypeStorage> {
public:
using Base::Base;
diff --git a/include/PluginServer/PluginServer.h b/include/PluginServer/PluginServer.h
index b28c6d0..207c018 100644
--- a/include/PluginServer/PluginServer.h
+++ b/include/PluginServer/PluginServer.h
@@ -187,7 +187,7 @@ public:
timeout = time;
}
void FuncOpJsonDeSerialize(const string& data);
- void TypeJsonDeSerialize(const string& data);
+ PluginIR::PluginTypeBase TypeJsonDeSerialize(const string& data);
void LocalDeclOpJsonDeSerialize(const string& data);
void LoopOpsJsonDeSerialize(const string& data);
void LoopOpJsonDeSerialize(const string& data);
diff --git a/lib/Dialect/PluginDialect.cpp b/lib/Dialect/PluginDialect.cpp
index 63ba167..001fdab 100644
--- a/lib/Dialect/PluginDialect.cpp
+++ b/lib/Dialect/PluginDialect.cpp
@@ -35,6 +35,7 @@ void PluginDialect::initialize() {
addTypes<
PluginIR::PluginIntegerType,
PluginIR::PluginFloatType,
+ PluginIR::PluginPointerType,
PluginIR::PluginBooleanType,
PluginIR::PluginVoidType,
PluginIR::PluginUndefType>();
diff --git a/lib/Dialect/PluginTypes.cpp b/lib/Dialect/PluginTypes.cpp
index def302b..0fa003a 100644
--- a/lib/Dialect/PluginTypes.cpp
+++ b/lib/Dialect/PluginTypes.cpp
@@ -72,6 +72,25 @@ namespace detail {
unsigned width : 30;
};
+
+ struct PluginPointerTypeStorage : public TypeStorage {
+ using KeyTy = Type;
+
+ PluginPointerTypeStorage(const KeyTy &key)
+ : pointee(key) {}
+
+ static PluginPointerTypeStorage *construct(TypeStorageAllocator &allocator,
+ KeyTy key) {
+ return new (allocator.allocate<PluginPointerTypeStorage>())
+ PluginPointerTypeStorage(key);
+ }
+
+ bool operator==(const KeyTy &key) const {
+ return KeyTy(pointee) == key;
+ }
+
+ Type pointee;
+ };
}
}
@@ -94,6 +113,9 @@ PluginTypeID PluginTypeBase::getPluginTypeID ()
if (auto Ty = dyn_cast<PluginIR::PluginVoidType>()) {
return Ty.getPluginTypeID ();
}
+ if (auto Ty = dyn_cast<PluginIR::PluginPointerType>()) {
+ return Ty.getPluginTypeID ();
+ }
return PluginTypeID::UndefTyID;
}
@@ -252,4 +274,23 @@ PluginTypeID PluginVoidType::getPluginTypeID()
PluginTypeID PluginUndefType::getPluginTypeID()
{
return PluginTypeID::UndefTyID;
+}
+
+//===----------------------------------------------------------------------===//
+// Plugin Pointer Type
+//===----------------------------------------------------------------------===//
+
+PluginTypeID PluginPointerType::getPluginTypeID()
+{
+ return PluginTypeID::PointerTyID;
+}
+
+Type PluginPointerType::getElementType()
+{
+ return getImpl()->pointee;
+}
+
+PluginPointerType PluginPointerType::get (MLIRContext *context, Type pointee)
+{
+ return Base::get(context, pointee);
}
\ No newline at end of file
diff --git a/lib/PluginServer/PluginServer.cpp b/lib/PluginServer/PluginServer.cpp
index 2eac906..74974dc 100644
--- a/lib/PluginServer/PluginServer.cpp
+++ b/lib/PluginServer/PluginServer.cpp
@@ -225,13 +225,15 @@ void PluginServer::JsonDeSerialize(const string& key, const string& data)
}
}
-void PluginServer::TypeJsonDeSerialize(const string& data)
+PluginIR::PluginTypeBase PluginServer::TypeJsonDeSerialize(const string& data)
{
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);
@@ -240,28 +242,34 @@ void PluginServer::TypeJsonDeSerialize(const string& data)
string s = type["signed"].asString();
uint64_t width = GetID(type["width"]);
if (s == "1") {
- pluginType = PluginIR::PluginIntegerType::get(&context, width, PluginIR::PluginIntegerType::Signed);
+ baseType = PluginIR::PluginIntegerType::get(&context, width, PluginIR::PluginIntegerType::Signed);
}
else {
- pluginType = PluginIR::PluginIntegerType::get(&context, width, PluginIR::PluginIntegerType::Unsigned);
+ 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"]);
- pluginType = PluginIR::PluginFloatType::get(&context, width);
+ baseType = PluginIR::PluginFloatType::get(&context, width);
+ }else if (id == static_cast<uint64_t>(PluginIR::PointerTyID)) {
+ mlir::Type elemTy = TypeJsonDeSerialize(type["elementType"].toStyledString());
+ auto ty = elemTy.dyn_cast<PluginIR::PluginTypeBase>();
+ baseType = PluginIR::PluginPointerType::get(&context, elemTy);
}else {
if (PluginTypeId == PluginIR::VoidTyID)
- pluginType = PluginIR::PluginVoidType::get(&context);
+ baseType = PluginIR::PluginVoidType::get(&context);
if (PluginTypeId == PluginIR::BooleanTyID)
- pluginType = PluginIR::PluginBooleanType::get(&context);
+ baseType = PluginIR::PluginBooleanType::get(&context);
if (PluginTypeId == PluginIR::UndefTyID)
- pluginType = PluginIR::PluginUndefType::get(&context);
+ baseType = PluginIR::PluginUndefType::get(&context);
}
if (type["readonly"] == "1")
- pluginType.setReadOnlyFlag(1);
+ baseType.setReadOnlyFlag(1);
else
- pluginType.setReadOnlyFlag(0);
- return;
+ baseType.setReadOnlyFlag(0);
+
+ pluginType = baseType;
+ return baseType;
}
bool PluginServer::ProcessBlock(mlir::Block* block, mlir::Region& rg,
--
2.27.0.windows.1

View File

@ -1,6 +1,6 @@
Name: pin-server
Version: 0.3.0
Release: 1
Release: 2
Summary: Pin (Plug-IN framework) server provides plugin APIs for compiler optimization developers to develop optimization pass.
License: Apache 2.0
URL: https://gitee.com/openeuler/pin-server
@ -10,6 +10,11 @@ BuildRequires: gcc gcc-c++ cmake make pkgconfig grpc grpc-plugins grpc-devel pr
BuildRequires: llvm-mlir llvm-mlir-static llvm-mlir-devel llvm-devel
Requires: grpc protobuf
Patch1: 0001-Pin-server-Support-for-new-insertion-points-and-new-.patch
Patch2: 0002-Pin-server-support-LoopOp.patch
Patch3: 0003-Pin-server-Support-build-CFG-CondOp-CallOp-PhiOp-and.patch
Patch4: 0004-Pin-server-Support-Plugin-Pointer-Type.patch
%description
Pin (Plug-IN framework) server provides plugin APIs for compiler optimization developers to develop optimization pass.
@ -26,6 +31,12 @@ A demo for pin-server
%prep
%setup -q
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch4 -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
@ -51,6 +62,12 @@ cd _build
%attr(0644,root,root) %{_libdir}/libpin_user.sha256
%changelog
* Thu Dec 08 2022 benniaobufeijiushiji <linda7@huawei.com> - 0.3.0-2
- Type:Sync
- ID:NA
- SUG:NA
- DESC:Sync patch from openEuler/pin-server
* Thu Dec 01 2022 wumingchuan <wumingchuan1992@foxmail.com> - 0.3.0-1
- Type:Update
- ID:NA