From 02a666961a8fa904b2d4e918a2cff2cf12962ebb Mon Sep 17 00:00:00 2001 From: benniaobufeijiushiji Date: Thu, 8 Dec 2022 21:26:02 +0800 Subject: [PATCH] [sync] Sync patch from openeuler/pin-gcc-client Sync patch from openeuler/pin-gcc-client 2022/12/08 (cherry picked from commit ca424952fd407c6158e330c8e21d67442aec4c16) --- ...upport-for-new-insertion-points-and-.patch | 79 + 0002-Pin-gcc-client-Support-LoopOp.patch | 744 ++++++++++ ...upport-build-CFG-CallOp-AssignOp-Con.patch | 1289 +++++++++++++++++ ...c-client-Support-Plugin-Pointer-type.patch | 184 +++ pin-gcc-client.spec | 19 +- 5 files changed, 2314 insertions(+), 1 deletion(-) create mode 100644 0001-Pin-gcc-client-Support-for-new-insertion-points-and-.patch create mode 100644 0002-Pin-gcc-client-Support-LoopOp.patch create mode 100644 0003-Pin-gcc-client-Support-build-CFG-CallOp-AssignOp-Con.patch create mode 100644 0004-Pin-gcc-client-Support-Plugin-Pointer-type.patch diff --git a/0001-Pin-gcc-client-Support-for-new-insertion-points-and-.patch b/0001-Pin-gcc-client-Support-for-new-insertion-points-and-.patch new file mode 100644 index 0000000..912aecc --- /dev/null +++ b/0001-Pin-gcc-client-Support-for-new-insertion-points-and-.patch @@ -0,0 +1,79 @@ +From 1b9a024e5195a6860b7e6a896e0d7afa9794c277 Mon Sep 17 00:00:00 2001 +From: dingguangya +Date: Wed, 7 Dec 2022 21:49:19 +0800 +Subject: [PATCH 1/4] [Pin-gcc-client] Support for new insertion points and new + Pass It supports the phiopt insertion point and provides a simple + arraywiden pass interface. + +--- + include/PluginClient/PluginClient.h | 1 + + lib/IRTrans/IRTransPlugin.cpp | 25 +++++++++++++++++++++++++ + 2 files changed, 26 insertions(+) + +diff --git a/include/PluginClient/PluginClient.h b/include/PluginClient/PluginClient.h +index e8adcb2..155705d 100644 +--- a/include/PluginClient/PluginClient.h ++++ b/include/PluginClient/PluginClient.h +@@ -79,6 +79,7 @@ typedef enum { + // 参考点名称 + enum RefPassName { + PASS_CFG, ++ PASS_PHIOPT, + PASS_SSA, + PASS_LOOP, + }; +diff --git a/lib/IRTrans/IRTransPlugin.cpp b/lib/IRTrans/IRTransPlugin.cpp +index ccde9b5..8e5af8c 100644 +--- a/lib/IRTrans/IRTransPlugin.cpp ++++ b/lib/IRTrans/IRTransPlugin.cpp +@@ -127,8 +127,28 @@ void ManagerSetupCallback(void) + std::shared_ptr client = PluginClient::GetInstance(); + vector userFuncs = client->GetFuncNameByInject(inject); + for (auto &userFunc : userFuncs) { ++ if (client->GetUserFuncState() == STATE_TIMEOUT) { ++ break; ++ } + string value = std::to_string(inject) + ":" + userFunc; + client->ReceiveSendMsg(key, value); ++ while (1) { ++ UserFuncStateEnum state = client->GetUserFuncState(); ++ /* server获取到client对应函数的执行结果后,向client回复已执行完,跳出循环执行下一个函数 */ ++ if (state == STATE_END) { ++ client->SetUserFuncState(STATE_WAIT_BEGIN); ++ break; ++ } else if (state == STATE_TIMEOUT) { ++ break; ++ } else if (state == STATE_BEGIN) { ++ string funcName = client->GetPluginAPIName(); ++ string param = client->GetPluginAPIParam(); ++ if (funcName != "") { ++ client->SetUserFuncState(STATE_WAIT_IR); ++ client->IRTransBegin(funcName, param); ++ } ++ } ++ } + } + } + +@@ -182,6 +202,7 @@ public: + + static std::map g_refPassName { + {PASS_CFG, "cfg"}, ++ {PASS_PHIOPT, "phiopt"}, + {PASS_SSA, "ssa"}, + {PASS_LOOP, "loop"}, + }; +@@ -213,6 +234,10 @@ int RegisterPassManagerSetup(InjectPoint inject, const ManagerSetupData& setupDa + passData.type = GIMPLE_PASS; + passInfo.pass = new GimplePass(passData); + break; ++ case PASS_PHIOPT: ++ passData.type = GIMPLE_PASS; ++ passInfo.pass = new GimplePass(passData); ++ break; + case PASS_SSA: + passData.type = RTL_PASS; + passInfo.pass = new RltPass(passData); +-- +2.27.0.windows.1 + diff --git a/0002-Pin-gcc-client-Support-LoopOp.patch b/0002-Pin-gcc-client-Support-LoopOp.patch new file mode 100644 index 0000000..c11fec0 --- /dev/null +++ b/0002-Pin-gcc-client-Support-LoopOp.patch @@ -0,0 +1,744 @@ +From f5ca57ff4a1ee37da47949abea958ba595b895d2 Mon Sep 17 00:00:00 2001 +From: benniaobufeijiushiji +Date: Mon, 5 Dec 2022 17:02:18 +0800 +Subject: [PATCH 2/4] [Pin-gcc-client] Support LoopOp Add LoopOp for Plugin + Dialect + +--- + include/Dialect/PluginOps.td | 19 ++ + include/PluginAPI/BasicPluginOpsAPI.h | 12 + + include/PluginAPI/PluginClientAPI.h | 12 + + include/PluginClient/PluginClient.h | 9 + + include/Translate/GimpleToPluginOps.h | 13 +- + include/Translate/ToPluginOpsInterface.h | 12 + + lib/Dialect/PluginOps.cpp | 13 +- + lib/IRTrans/IRTransPlugin.cpp | 1 + + lib/PluginAPI/PluginClientAPI.cpp | 58 +++++ + lib/PluginClient/PluginClient.cpp | 267 ++++++++++++++++++++++- + lib/Translate/GimpleToPluginOps.cpp | 139 +++++++++++- + 11 files changed, 549 insertions(+), 6 deletions(-) + +diff --git a/include/Dialect/PluginOps.td b/include/Dialect/PluginOps.td +index 98f5cad..8264555 100644 +--- a/include/Dialect/PluginOps.td ++++ b/include/Dialect/PluginOps.td +@@ -56,4 +56,23 @@ def LocalDeclOp : Plugin_Op<"declaration", [NoSideEffect]> { + ]; + } + ++def LoopOp : Plugin_Op<"loop", [NoSideEffect]> { ++ let summary = "loop operation"; ++ let description = [{ ++ TODO. ++ }]; ++ let arguments = (ins OptionalAttr:$id, ++ OptionalAttr:$index, ++ OptionalAttr:$innerLoopId, ++ OptionalAttr:$outerLoopId, ++ OptionalAttr:$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)> ++ ]; ++} ++ ++ + #endif // PLUGIN_OPS_TD +\ No newline at end of file +diff --git a/include/PluginAPI/BasicPluginOpsAPI.h b/include/PluginAPI/BasicPluginOpsAPI.h +index 24147e1..1037bf5 100644 +--- a/include/PluginAPI/BasicPluginOpsAPI.h ++++ b/include/PluginAPI/BasicPluginOpsAPI.h +@@ -43,6 +43,18 @@ public: + + virtual vector GetAllFunc() = 0; + virtual vector GetDecls(uint64_t funcID) = 0; ++ virtual vector GetLoopsFromFunc(uint64_t) = 0; ++ virtual LoopOp GetLoopById(uint64_t) = 0; ++ virtual bool IsBlockInside(uint64_t, uint64_t) = 0; ++ virtual vector GetBlocksInLoop(uint64_t) = 0; ++ virtual void AddLoop(uint64_t, uint64_t, uint64_t) = 0; ++ virtual uint64_t AllocateNewLoop(void) = 0; ++ virtual void DeleteLoop(uint64_t) = 0; ++ virtual uint64_t GetHeader(uint64_t) = 0; ++ virtual uint64_t GetLatch(uint64_t) = 0; ++ virtual vector > GetLoopExits(uint64_t) = 0; ++ virtual std::pair GetLoopSingleExit(uint64_t) = 0; ++ virtual LoopOp GetBlockLoopFather(uint64_t) = 0; + }; // class BasicPluginOpsAPI + } // namespace PluginAPI + +diff --git a/include/PluginAPI/PluginClientAPI.h b/include/PluginAPI/PluginClientAPI.h +index b4f1ef3..42d56ee 100644 +--- a/include/PluginAPI/PluginClientAPI.h ++++ b/include/PluginAPI/PluginClientAPI.h +@@ -35,6 +35,18 @@ public: + + vector GetAllFunc() override; + vector GetDecls(uint64_t funcID) override; ++ vector GetLoopsFromFunc(uint64_t) override; ++ LoopOp GetLoopById(uint64_t) override; ++ bool IsBlockInside(uint64_t, uint64_t) override; ++ vector GetBlocksInLoop(uint64_t) override; ++ void AddLoop(uint64_t, uint64_t, uint64_t) override; ++ uint64_t AllocateNewLoop(void) override; ++ void DeleteLoop(uint64_t) override; ++ uint64_t GetHeader(uint64_t) override; ++ uint64_t GetLatch(uint64_t) override; ++ vector > GetLoopExits(uint64_t) override; ++ std::pair GetLoopSingleExit(uint64_t) override; ++ LoopOp GetBlockLoopFather(uint64_t) override; + + private: + PluginIR::GimpleToPluginOps gimpleConversion; +diff --git a/include/PluginClient/PluginClient.h b/include/PluginClient/PluginClient.h +index 155705d..3e48c44 100644 +--- a/include/PluginClient/PluginClient.h ++++ b/include/PluginClient/PluginClient.h +@@ -43,6 +43,7 @@ using std::string; + using std::endl; + using std::vector; + using std::map; ++using std::pair; + + using plugin::PluginService; + using grpc::Channel; +@@ -107,6 +108,14 @@ public: + static std::shared_ptr GetInstance(void); + void OpJsonSerialize(vector& data, string& out); + void LocalDeclsJsonSerialize(vector& decls, string& out); ++ void LoopOpsJsonSerialize(vector& loops, string& out); ++ void LoopOpJsonSerialize(mlir::Plugin::LoopOp& loop, string& out); ++ void BoolResultJsonSerialize(bool, string&); ++ void BlockJsonSerialize(uint64_t, string&); ++ void BlocksJsonSerialize(vector&, string&); ++ void EdgesJsonSerialize(vector >&, string&); ++ void EdgeJsonSerialize(pair&, string&); ++ void NopJsonSerialize(string&); + /* 将Type类型数据序列化 */ + void TypeJsonSerialize(PluginIR::PluginTypeBase& type, string& out); + /* 获取gcc插件数据并进行IR转换,将转换后的数据序列化返回给server。param:函数入参序列化后的数据 */ +diff --git a/include/Translate/GimpleToPluginOps.h b/include/Translate/GimpleToPluginOps.h +index 2acd4a5..3f4f96a 100644 +--- a/include/Translate/GimpleToPluginOps.h ++++ b/include/Translate/GimpleToPluginOps.h +@@ -44,7 +44,18 @@ public: + /* ToPluginInterface */ + vector GetAllFunction() override; + vector GetAllDecls(uint64_t) override; +- ++ vector GetAllLoops(uint64_t) override; ++ LoopOp GetLoop(uint64_t) override; ++ bool IsBlockInside(uint64_t, uint64_t) override; ++ vector GetBlocksInLoop(uint64_t) override; ++ uint64_t AllocateNewLoop(void) override; ++ void DeleteLoop(uint64_t) override; ++ void AddLoop (uint64_t, uint64_t, uint64_t) override; ++ uint64_t GetHeader(uint64_t) override; ++ uint64_t GetLatch(uint64_t) override; ++ vector > GetLoopExits(uint64_t) override; ++ std::pair GetLoopSingleExit(uint64_t) override; ++ LoopOp GetBlockLoopFather(uint64_t) override; + private: + mlir::OpBuilder builder; + TypeFromPluginIRTranslator typeTranslator; +diff --git a/include/Translate/ToPluginOpsInterface.h b/include/Translate/ToPluginOpsInterface.h +index 881eb7f..598c176 100644 +--- a/include/Translate/ToPluginOpsInterface.h ++++ b/include/Translate/ToPluginOpsInterface.h +@@ -37,6 +37,18 @@ public: + /* Operation. */ + virtual vector GetAllFunction() = 0; + virtual vector GetAllDecls(uint64_t) = 0; ++ virtual vector GetAllLoops(uint64_t) = 0; ++ virtual LoopOp GetLoop(uint64_t) = 0; ++ virtual bool IsBlockInside(uint64_t, uint64_t) = 0; ++ virtual vector GetBlocksInLoop(uint64_t) = 0; ++ virtual uint64_t AllocateNewLoop(void) = 0; ++ virtual void DeleteLoop(uint64_t) = 0; ++ virtual void AddLoop (uint64_t, uint64_t, uint64_t) = 0; ++ virtual uint64_t GetHeader(uint64_t) = 0; ++ virtual uint64_t GetLatch(uint64_t) = 0; ++ virtual vector > GetLoopExits(uint64_t) = 0; ++ virtual std::pair GetLoopSingleExit(uint64_t) = 0; ++ virtual LoopOp GetBlockLoopFather(uint64_t) = 0; + }; + } // namespace PluginIR + +diff --git a/lib/Dialect/PluginOps.cpp b/lib/Dialect/PluginOps.cpp +index 4caa890..adf7ca6 100644 +--- a/lib/Dialect/PluginOps.cpp ++++ b/lib/Dialect/PluginOps.cpp +@@ -35,7 +35,7 @@ using namespace mlir::Plugin; + 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)); + } +@@ -50,6 +50,17 @@ 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)); ++} ++ + //===----------------------------------------------------------------------===// + // TableGen'd op method definitions + //===----------------------------------------------------------------------===// +diff --git a/lib/IRTrans/IRTransPlugin.cpp b/lib/IRTrans/IRTransPlugin.cpp +index 8e5af8c..b1cc616 100644 +--- a/lib/IRTrans/IRTransPlugin.cpp ++++ b/lib/IRTrans/IRTransPlugin.cpp +@@ -31,6 +31,7 @@ + #include "context.h" + #include "tree-pass.h" + #include "tree.h" ++#include "tree-cfg.h" + + using namespace PinClient; + +diff --git a/lib/PluginAPI/PluginClientAPI.cpp b/lib/PluginAPI/PluginClientAPI.cpp +index 028023d..d268c1e 100644 +--- a/lib/PluginAPI/PluginClientAPI.cpp ++++ b/lib/PluginAPI/PluginClientAPI.cpp +@@ -29,4 +29,62 @@ vector PluginClientAPI::GetDecls(uint64_t funcID) + return gimpleConversion.GetAllDecls(funcID); + } + ++vector PluginClientAPI::GetLoopsFromFunc(uint64_t funcID) ++{ ++ return gimpleConversion.GetAllLoops(funcID); ++} ++ ++LoopOp PluginClientAPI::GetLoopById(uint64_t loopID) ++{ ++ return gimpleConversion.GetLoop(loopID); ++} ++ ++bool PluginClientAPI::IsBlockInside(uint64_t loopID, uint64_t blockID) ++{ ++ return gimpleConversion.IsBlockInside(loopID, blockID); ++} ++ ++vector PluginClientAPI::GetBlocksInLoop(uint64_t loopID) ++{ ++ return gimpleConversion.GetBlocksInLoop(loopID); ++} ++ ++void PluginClientAPI::AddLoop (uint64_t loop, uint64_t outer, uint64_t funcId) ++{ ++ gimpleConversion.AddLoop(loop, outer, funcId); ++} ++ ++uint64_t PluginClientAPI::AllocateNewLoop(void) ++{ ++ return gimpleConversion.AllocateNewLoop(); ++} ++void PluginClientAPI::DeleteLoop(uint64_t loopId) ++{ ++ gimpleConversion.DeleteLoop(loopId); ++} ++ ++uint64_t PluginClientAPI::GetHeader(uint64_t loopId) ++{ ++ return gimpleConversion.GetHeader(loopId); ++} ++ ++uint64_t PluginClientAPI::GetLatch(uint64_t loopId) ++{ ++ return gimpleConversion.GetLatch(loopId); ++} ++ ++vector > PluginClientAPI::GetLoopExits(uint64_t loopId) ++{ ++ return gimpleConversion.GetLoopExits(loopId); ++} ++std::pair PluginClientAPI::GetLoopSingleExit(uint64_t loopId) ++{ ++ return gimpleConversion.GetLoopSingleExit(loopId); ++} ++ ++LoopOp PluginClientAPI::GetBlockLoopFather(uint64_t blockId) ++{ ++ return gimpleConversion.GetBlockLoopFather(blockId); ++} ++ + } // namespace PluginAPI +\ No newline at end of file +diff --git a/lib/PluginClient/PluginClient.cpp b/lib/PluginClient/PluginClient.cpp +index 97dfadf..c57d36c 100644 +--- a/lib/PluginClient/PluginClient.cpp ++++ b/lib/PluginClient/PluginClient.cpp +@@ -122,7 +122,7 @@ void PluginClient::OpJsonSerialize(vector& data, string& out) + item["attributes"]["declaredInline"] = "1"; + else + item["attributes"]["declaredInline"] = "0"; +- item["attributes"]["funcName"] = d.funcNameAttr().getValue().data(); ++ item["attributes"]["funcName"] = d.funcNameAttr().getValue().str(); + operation = "operation" + std::to_string(i++); + root[operation] = item; + item.clear(); +@@ -150,6 +150,101 @@ void PluginClient::LocalDeclsJsonSerialize(vector& decls, string& o + out = root.toStyledString(); + } + ++void PluginClient::LoopOpsJsonSerialize(vector& loops, string& out) ++{ ++ Json::Value root; ++ Json::Value operationObj; ++ Json::Value item; ++ int i = 0; ++ string operation; ++ ++ for (auto&loop: loops) { ++ item["id"] = std::to_string(loop.idAttr().getInt()); ++ item["index"] = std::to_string(loop.indexAttr().getInt()); ++ item["attributes"]["innerLoopId"] = std::to_string(loop.innerLoopIdAttr().getInt()); ++ item["attributes"]["outerLoopId"] = std::to_string(loop.outerLoopIdAttr().getInt()); ++ item["attributes"]["numBlock"] = std::to_string(loop.numBlockAttr().getInt()); ++ operation = "operation" + std::to_string(i++); ++ root[operation] = item; ++ item.clear(); ++ } ++ out = root.toStyledString(); ++} ++ ++void PluginClient::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 PluginClient::BlocksJsonSerialize(vector& blocks, string& out) ++{ ++ Json::Value root; ++ Json::Value item; ++ int i = 0; ++ string index; ++ ++ for(auto& block : blocks) { ++ item["id"] = std::to_string(block); ++ index = "block" + std::to_string(i++); ++ root[index] = item; ++ item.clear(); ++ } ++ out = root.toStyledString(); ++} ++ ++void PluginClient::BlockJsonSerialize(uint64_t block, string& out) ++{ ++ Json::Value root; ++ Json::Value item; ++ root["id"] = std::to_string(block); ++ out = root.toStyledString(); ++} ++ ++void PluginClient::EdgesJsonSerialize(vector >& edges, string& out) ++{ ++ Json::Value root; ++ Json::Value item; ++ int i = 0; ++ string index; ++ ++ for(auto& edge : edges) { ++ item["src"] = std::to_string(edge.first); ++ item["dest"] = std::to_string(edge.second); ++ index = "edge" + std::to_string(i++); ++ root[index] = item; ++ item.clear(); ++ } ++ out = root.toStyledString(); ++} ++ ++void PluginClient::EdgeJsonSerialize(pair& edge, string& out) ++{ ++ Json::Value root; ++ root["src"] = std::to_string(edge.first); ++ root["dest"] = std::to_string(edge.second); ++ out = root.toStyledString(); ++} ++ ++void PluginClient::BoolResultJsonSerialize(bool res, string& out) ++{ ++ Json::Value root; ++ root["result"] = std::to_string((int)res); ++ out = root.toStyledString(); ++} ++ ++// void类型的Json序列化 ++void PluginClient::NopJsonSerialize(string& out) ++{ ++ Json::Value root; ++ out = root.toStyledString(); ++} ++ + void PluginClient::IRTransBegin(const string& funcName, const string& param) + { + string result; +@@ -168,14 +263,180 @@ void PluginClient::IRTransBegin(const string& funcName, const string& param) + OpJsonSerialize(allFuncOps, result); + this->ReceiveSendMsg("FuncOpResult", result); + } else if (funcName == "GetLocalDecls") { ++ /// Json格式 ++ /// { ++ /// "funcId":"xxxx" ++ /// } + mlir::MLIRContext context; + context.getOrLoadDialect(); + PluginAPI::PluginClientAPI clientAPI(context); +- uint64_t funcID = atol(root[std::to_string(0)].asString().c_str()); ++ std::string funcIdKey = "funcId"; ++ uint64_t funcID = atol(root[funcIdKey].asString().c_str()); + vector decls = clientAPI.GetDecls(funcID); + LocalDeclsJsonSerialize(decls, result); + this->ReceiveSendMsg("LocalDeclOpResult", result); +- }else { ++ } else if (funcName == "GetLoopsFromFunc") { ++ /// Json格式 ++ /// { ++ /// "funcId":"xxxx" ++ /// } ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ std::string funcIdKey = "funcId"; ++ uint64_t funcID = atol(root[funcIdKey].asString().c_str()); ++ vector irLoops = clientAPI.GetLoopsFromFunc(funcID); ++ LoopOpsJsonSerialize(irLoops, result); ++ this->ReceiveSendMsg("LoopOpsResult", result); ++ } else if (funcName == "GetLoopById") { ++ /// Json格式 ++ /// { ++ /// "loopId":"xxxx" ++ /// } ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ std::string loopIdKey = "loopId"; ++ uint64_t loopId = atol(root[loopIdKey].asString().c_str()); ++ LoopOp irLoop = clientAPI.GetLoopById(loopId); ++ LoopOpJsonSerialize(irLoop, result); ++ this->ReceiveSendMsg("LoopOpResult", result); ++ } else if (funcName == "IsBlockInside") { ++ /// Json格式 ++ /// { ++ /// "loopId":"xxxx", ++ /// "blockId":"xxxx" ++ /// } ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ std::string loopIdKey = "loopId"; ++ std::string blockIdKey = "blockId"; ++ uint64_t loopId = atol(root[loopIdKey].asString().c_str()); ++ uint64_t blockId = atol(root[blockIdKey].asString().c_str()); ++ bool res = clientAPI.IsBlockInside(loopId, blockId); ++ BoolResultJsonSerialize(res, result); ++ this->ReceiveSendMsg("BoolResult", result); ++ } else if (funcName == "AllocateNewLoop") { ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ uint64_t newLoopId = clientAPI.AllocateNewLoop(); ++ LoopOp newLoop = clientAPI.GetLoopById(newLoopId); ++ LoopOpJsonSerialize(newLoop, result); ++ this->ReceiveSendMsg("LoopOpResult", result); ++ } else if (funcName == "DeleteLoop") { ++ /// Json格式 ++ /// { ++ /// "loopId":"xxxx", ++ /// } ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ std::string loopIdKey = "loopId"; ++ uint64_t loopId = atol(root[loopIdKey].asString().c_str()); ++ clientAPI.DeleteLoop(loopId); ++ NopJsonSerialize(result); ++ this->ReceiveSendMsg("VoidResult", result); ++ } else if (funcName == "AddLoop") { ++ /// Json格式 ++ /// { ++ /// "loopId":"xxxx", ++ /// "outerId":"xxxx" ++ /// "funcId":"xxxx" ++ /// } ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ std::string loopIdKey = "loopId"; ++ std::string outerIdKey = "outerId"; ++ std::string funcIdKey = "funcId"; ++ uint64_t loopID = atol(root[loopIdKey].asString().c_str()); ++ uint64_t outerID = atol(root[outerIdKey].asString().c_str()); ++ uint64_t funcID = atol(root[funcIdKey].asString().c_str()); ++ clientAPI.AddLoop(loopID, outerID, funcID); ++ LoopOp irLoop = clientAPI.GetLoopById(loopID); ++ LoopOpJsonSerialize(irLoop, result); ++ this->ReceiveSendMsg("LoopOpResult", result); ++ } else if (funcName == "GetBlocksInLoop") { ++ /// Json格式 ++ /// { ++ /// "loopId":"xxxx", ++ /// } ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ std::string loopIdKey = "loopId"; ++ uint64_t loopId = atol(root[loopIdKey].asString().c_str()); ++ vector blocks = clientAPI.GetBlocksInLoop(loopId); ++ BlocksJsonSerialize(blocks, result); ++ this->ReceiveSendMsg("BlockIdsResult", result); ++ } else if (funcName == "GetHeader") { ++ /// Json格式 ++ /// { ++ /// "loopId":"xxxx", ++ /// } ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ std::string loopIdKey = "loopId"; ++ uint64_t loopId = atol(root[loopIdKey].asString().c_str()); ++ uint64_t blockId = clientAPI.GetHeader(loopId); ++ BlockJsonSerialize(blockId, result); ++ this->ReceiveSendMsg("BlockIdResult", result); ++ } else if (funcName == "GetLatch") { ++ /// Json格式 ++ /// { ++ /// "loopId":"xxxx", ++ /// } ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ std::string loopIdKey = "loopId"; ++ uint64_t loopId = atol(root[loopIdKey].asString().c_str()); ++ uint64_t blockId = clientAPI.GetLatch(loopId); ++ BlockJsonSerialize(blockId, result); ++ this->ReceiveSendMsg("BlockIdResult", result); ++ } else if (funcName == "GetLoopExits") { ++ /// Json格式 ++ /// { ++ /// "loopId":"xxxx", ++ /// } ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ std::string loopIdKey = "loopId"; ++ uint64_t loopId = atol(root[loopIdKey].asString().c_str()); ++ vector > edges = clientAPI.GetLoopExits(loopId); ++ EdgesJsonSerialize(edges, result); ++ this->ReceiveSendMsg("EdgesResult", result); ++ } else if (funcName == "GetLoopSingleExit") { ++ /// Json格式 ++ /// { ++ /// "loopId":"xxxx", ++ /// } ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ std::string loopIdKey = "loopId"; ++ uint64_t loopId = atol(root[loopIdKey].asString().c_str()); ++ pair edge = clientAPI.GetLoopSingleExit(loopId); ++ EdgeJsonSerialize(edge, result); ++ this->ReceiveSendMsg("EdgeResult", result); ++ } else if (funcName == "GetBlockLoopFather") { ++ /// Json格式 ++ /// { ++ /// "blockId":"xxxx", ++ /// } ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ std::string blockIdKey = "blockId"; ++ uint64_t blockId = atol(root[blockIdKey].asString().c_str()); ++ LoopOp loopFather = clientAPI.GetBlockLoopFather(blockId); ++ LoopOpJsonSerialize(loopFather, result); ++ this->ReceiveSendMsg("LoopOpResult", result); ++ } else { + LOGW("function: %s not found!\n", funcName.c_str()); + } + +diff --git a/lib/Translate/GimpleToPluginOps.cpp b/lib/Translate/GimpleToPluginOps.cpp +index 2d021fe..273a214 100644 +--- a/lib/Translate/GimpleToPluginOps.cpp ++++ b/lib/Translate/GimpleToPluginOps.cpp +@@ -41,6 +41,8 @@ + #include "ssa.h" + #include "output.h" + #include "langhooks.h" ++#include "cfgloop.h" ++#include "tree-cfg.h" + + namespace PluginIR { + using namespace mlir::Plugin; +@@ -82,7 +84,7 @@ vector GimpleToPluginOps::GetAllDecls(uint64_t funcID) + const char* name = IDENTIFIER_POINTER(DECL_NAME (var)); + mlir::StringRef symName(name); + auto location = builder.getUnknownLoc(); +- PluginTypeBase declType = typeTranslator.translateType((intptr_t)TREE_TYPE(var)); ++ PluginTypeBase declType = typeTranslator.translateType((intptr_t)TREE_TYPE(var)); + int64_t typeID = typeTranslator.getPluginTypeId (declType); + uint64_t typeWidth = typeTranslator.getBitWidth (declType); + decl = builder.create(location, id, symName, typeID, typeWidth); +@@ -92,4 +94,139 @@ vector GimpleToPluginOps::GetAllDecls(uint64_t funcID) + return decls; + } + ++vector GimpleToPluginOps::GetAllLoops(uint64_t funcID) ++{ ++ function *fn = reinterpret_cast(funcID); ++ push_cfun(fn); ++ vector loops; ++ enum li_flags LI = LI_FROM_INNERMOST; ++ class loop *loop; ++ FOR_EACH_LOOP(loop, LI) { ++ uint64_t id = reinterpret_cast(reinterpret_cast(loop)); ++ LoopOp pluginLoop; ++ if (!id) { ++ continue; ++ } ++ auto location = builder.getUnknownLoc(); ++ uint32_t index = (uint32_t)loop->num; ++ uint64_t innerLoopId = reinterpret_cast(reinterpret_cast(loop->inner)); ++ uint64_t outerLoopId = reinterpret_cast(reinterpret_cast(loop_outer(loop))); ++ uint32_t numBlock = loop->num_nodes; ++ pluginLoop = builder.create(location, id, index, innerLoopId, outerLoopId, numBlock); ++ loops.push_back(pluginLoop); ++ } ++ pop_cfun(); ++ return loops; ++} ++ ++LoopOp GimpleToPluginOps::GetLoop(uint64_t loopID) ++{ ++ assert(loopID); ++ class loop *loop = reinterpret_cast(loopID); ++ uint64_t id = loopID; ++ LoopOp pluginLoop; ++ auto location = builder.getUnknownLoc(); ++ uint32_t index = (uint32_t)loop->num; ++ uint64_t innerLoopId = reinterpret_cast(reinterpret_cast(loop->inner)); ++ uint64_t outerLoopId = reinterpret_cast(reinterpret_cast(loop_outer(loop))); ++ uint32_t numBlock = loop->num_nodes; ++ pluginLoop = builder.create(location, id, index, innerLoopId, outerLoopId, numBlock); ++ return pluginLoop; ++} ++ ++bool GimpleToPluginOps::IsBlockInside(uint64_t loopID, uint64_t blockID) ++{ ++ assert(loopID && blockID); ++ class loop *loop = reinterpret_cast(loopID); ++ basic_block bb = reinterpret_cast(reinterpret_cast(blockID)); ++ return flow_bb_inside_loop_p(loop, bb); ++} ++ ++vector GimpleToPluginOps::GetBlocksInLoop(uint64_t loopID) ++{ ++ assert(loopID); ++ vector blocks; ++ class loop *loop = reinterpret_cast(loopID); ++ basic_block *bbs = get_loop_body_in_dom_order(loop); ++ for (unsigned i = 0; i < loop->num_nodes; i++) { ++ uint64_t blockId = reinterpret_cast(reinterpret_cast(bbs[i])); ++ blocks.push_back(blockId); ++ } ++ return blocks; ++} ++ ++uint64_t GimpleToPluginOps::AllocateNewLoop(void) ++{ ++ class loop *loop = alloc_loop(); ++ return reinterpret_cast(reinterpret_cast(loop)); ++} ++ ++void GimpleToPluginOps::DeleteLoop(uint64_t loopID) ++{ ++ class loop *loop = reinterpret_cast(reinterpret_cast(loopID)); ++ delete_loop(loop); ++} ++ ++void GimpleToPluginOps::AddLoop(uint64_t loopID, uint64_t outerID, uint64_t funcID) ++{ ++ class loop *loop = reinterpret_cast(loopID); ++ class loop *outer = reinterpret_cast(outerID); ++ function *fn = reinterpret_cast(funcID); ++ push_cfun(fn); ++ add_loop(loop, outer); ++ pop_cfun(); ++} ++ ++uint64_t GimpleToPluginOps::GetHeader(uint64_t loopID) ++{ ++ class loop *loop = reinterpret_cast(loopID); ++ basic_block header = loop->header; ++ return reinterpret_cast(reinterpret_cast(header)); ++} ++ ++uint64_t GimpleToPluginOps::GetLatch(uint64_t loopID) ++{ ++ class loop *loop = reinterpret_cast(loopID); ++ basic_block latch = loop->latch; ++ return reinterpret_cast(reinterpret_cast(latch)); ++} ++ ++vector > GimpleToPluginOps::GetLoopExits(uint64_t loopID) ++{ ++ class loop *loop = reinterpret_cast(loopID); ++ vec exit_edges = get_loop_exit_edges(loop); ++ edge e; ++ unsigned i = 0; ++ vector > res; ++ FOR_EACH_VEC_ELT(exit_edges, i, e) { ++ res.push_back(std::make_pair((uint64_t)e->src, (uint64_t)e->dest)); ++ } ++ return res; ++} ++ ++std::pair GimpleToPluginOps::GetLoopSingleExit(uint64_t loopID) ++{ ++ class loop *loop = reinterpret_cast(loopID); ++ edge e = single_exit(loop); ++ std::pair res; ++ res.first = e ? (uint64_t)e->src : 0; ++ res.second = e ? (uint64_t)e->dest : 0; ++ return res; ++} ++ ++LoopOp GimpleToPluginOps::GetBlockLoopFather(uint64_t blockID) ++{ ++ basic_block bb = reinterpret_cast(reinterpret_cast(blockID)); ++ class loop *loop = bb->loop_father; ++ LoopOp pluginLoop; ++ auto location = builder.getUnknownLoc(); ++ uint64_t id = reinterpret_cast(loop); ++ uint32_t index = (uint32_t)loop->num; ++ uint64_t innerLoopId = reinterpret_cast(reinterpret_cast(loop->inner)); ++ uint64_t outerLoopId = reinterpret_cast(reinterpret_cast(loop_outer(loop))); ++ uint32_t numBlock = loop->num_nodes; ++ pluginLoop = builder.create(location, id, index, innerLoopId, outerLoopId, numBlock); ++ return pluginLoop; ++} ++ + } // namespace PluginIR +\ No newline at end of file +-- +2.27.0.windows.1 + diff --git a/0003-Pin-gcc-client-Support-build-CFG-CallOp-AssignOp-Con.patch b/0003-Pin-gcc-client-Support-build-CFG-CallOp-AssignOp-Con.patch new file mode 100644 index 0000000..fabf19b --- /dev/null +++ b/0003-Pin-gcc-client-Support-build-CFG-CallOp-AssignOp-Con.patch @@ -0,0 +1,1289 @@ +From 02138fc424b76a664ee66d55c2bafec47ba00f4e Mon Sep 17 00:00:00 2001 +From: Mingchuan Wu +Date: Thu, 8 Dec 2022 20:06:58 +0800 +Subject: [PATCH 3/4] [Pin-gcc-client] Support build CFG, CallOp, AssignOp, + CondOp and PhiOp. Add CallOp, AssignOp, CondOp and PhiOp for PluginDialect. + Now we can support CFG. + +--- + include/Dialect/CMakeLists.txt | 3 + + include/Dialect/PluginDialect.td | 39 +++ + include/Dialect/PluginOps.h | 4 + + include/Dialect/PluginOps.td | 129 ++++++++- + include/Dialect/PluginTypes.h | 4 + + include/PluginAPI/BasicPluginOpsAPI.h | 5 + + include/PluginAPI/PluginClientAPI.h | 7 + + include/PluginClient/PluginClient.h | 13 +- + include/Translate/GimpleToPluginOps.h | 64 ++-- + lib/Dialect/PluginOps.cpp | 134 +++++++++ + lib/PluginAPI/PluginClientAPI.cpp | 25 ++ + lib/PluginClient/PluginClient.cpp | 185 +++++++++++- + lib/Translate/GimpleToPluginOps.cpp | 401 +++++++++++++++++++++++++- + 13 files changed, 978 insertions(+), 35 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 603f2fc..b6bf728 100644 +--- a/include/Dialect/PluginDialect.td ++++ b/include/Dialect/PluginDialect.td +@@ -48,4 +48,43 @@ def Plugin_Dialect : Dialect { + class Plugin_Op traits = []> : + Op; + ++//===----------------------------------------------------------------------===// ++// 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 IDefineCodeSSA : I32EnumAttrCase<"SSA", 2>; ++def IDefineCodeUNDEF : I32EnumAttrCase<"UNDEF", 3>; ++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 825310a..25089fe 100644 +--- a/include/Dialect/PluginOps.h ++++ b/include/Dialect/PluginOps.h +@@ -29,6 +29,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 8264555..6f4a399 100644 +--- a/include/Dialect/PluginOps.td ++++ b/include/Dialect/PluginOps.td +@@ -22,6 +22,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"; +@@ -29,8 +30,8 @@ def FunctionOp : Plugin_Op<"function", [NoSideEffect]> { + TODO. + }]; + +- let arguments = (ins OptionalAttr:$id, +- OptionalAttr:$funcName, ++ let arguments = (ins UI64Attr:$id, ++ StrAttr:$funcName, + OptionalAttr:$declaredInline); + let regions = (region AnyRegion:$bodyRegion); + +@@ -74,5 +75,129 @@ def LoopOp : Plugin_Op<"loop", [NoSideEffect]> { + ]; + } + ++def CallOp : Plugin_Op<"call", [ ++ DeclareOpInterfaceMethods]> { ++ 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:$inputs); ++ let results = (outs Optional:$result); ++ let builders = [ ++ OpBuilderDAG<(ins "uint64_t":$id, "StringRef":$callee, ++ "ArrayRef":$arguments)> ++ ]; ++ 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:$operands); ++ let results = (outs AnyType:$result); ++ let builders = [ ++ OpBuilderDAG<(ins "uint64_t":$id, "uint32_t":$capacity, ++ "uint32_t":$nArgs, "ArrayRef":$operands, ++ "Type":$resultType)> ++ ]; ++} ++ ++def AssignOp : Plugin_Op<"assign", [NoSideEffect]> { ++ let summary = "assign op"; ++ let description = [{TODO}]; ++ let arguments = (ins UI64Attr:$id, ++ IExprCodeAttr:$exprCode, ++ Variadic:$operands); ++ let results = (outs AnyType:$result); ++ let builders = [ ++ OpBuilderDAG<(ins "uint64_t":$id, "IExprCode":$exprCode, ++ "ArrayRef":$operands, "Type":$resultType)> ++ ]; ++ // Specify a parser and printer method. ++ // let parser = [{ return ::parseAssignOp(parser, result); }]; ++ // let printer = [{ return ::print(p, *this); }]; ++} ++ ++def PlaceholderOp : Plugin_Op<"placeholder", [NoSideEffect]> { ++ let summary = "PlaceHolder."; ++ let description = [{TODO}]; ++ let arguments = (ins UI64Attr:$id, ++ OptionalAttr:$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 traits = []> : ++ Plugin_Op; ++ ++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:$trueLabel, ++ OptionalAttr:$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)> ++ ]; ++ 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/Dialect/PluginTypes.h b/include/Dialect/PluginTypes.h +index 1b4883f..e0ef867 100644 +--- a/include/Dialect/PluginTypes.h ++++ b/include/Dialect/PluginTypes.h +@@ -141,6 +141,10 @@ public: + + }; // class PluginBooleanType + ++//===----------------------------------------------------------------------===// ++// Printing and parsing. TODO ++//===----------------------------------------------------------------------===// ++ + } // namespace PluginIR + + #endif // MLIR_DIALECT_PLUGINIR_PLUGINTYPES_H_ +\ No newline at end of file +diff --git a/include/PluginAPI/BasicPluginOpsAPI.h b/include/PluginAPI/BasicPluginOpsAPI.h +index 1037bf5..f5d7e91 100644 +--- a/include/PluginAPI/BasicPluginOpsAPI.h ++++ b/include/PluginAPI/BasicPluginOpsAPI.h +@@ -55,6 +55,11 @@ public: + virtual vector > GetLoopExits(uint64_t) = 0; + virtual std::pair GetLoopSingleExit(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/PluginClientAPI.h b/include/PluginAPI/PluginClientAPI.h +index 42d56ee..b33fdcb 100644 +--- a/include/PluginAPI/PluginClientAPI.h ++++ b/include/PluginAPI/PluginClientAPI.h +@@ -47,6 +47,13 @@ public: + vector > GetLoopExits(uint64_t) override; + std::pair GetLoopSingleExit(uint64_t) override; + LoopOp GetBlockLoopFather(uint64_t) override; ++ PhiOp GetPhiOp(uint64_t) override; ++ CallOp GetCallOp(uint64_t) override; ++ /* Plugin API for CallOp. */ ++ bool SetLhsInCallOp(uint64_t, uint64_t) override; ++ /* Plugin API for CondOp. */ ++ uint64_t CreateCondOp(IComparisonCode, uint64_t, uint64_t) override; ++ mlir::Value GetResultFromPhi(uint64_t) override; + + private: + PluginIR::GimpleToPluginOps gimpleConversion; +diff --git a/include/PluginClient/PluginClient.h b/include/PluginClient/PluginClient.h +index 3e48c44..b18ecc0 100644 +--- a/include/PluginClient/PluginClient.h ++++ b/include/PluginClient/PluginClient.h +@@ -28,6 +28,7 @@ + #include + #include + #include ++#include + + #include "Dialect/PluginOps.h" + #include "Dialect/PluginTypes.h" +@@ -107,7 +108,6 @@ public: + /* 获取client对象实例,有且只有一个实例对象 */ + static std::shared_ptr GetInstance(void); + void OpJsonSerialize(vector& data, string& out); +- void LocalDeclsJsonSerialize(vector& decls, string& out); + void LoopOpsJsonSerialize(vector& loops, string& out); + void LoopOpJsonSerialize(mlir::Plugin::LoopOp& loop, string& out); + void BoolResultJsonSerialize(bool, string&); +@@ -116,6 +116,17 @@ public: + void EdgesJsonSerialize(vector >&, string&); + void EdgeJsonSerialize(pair&, string&); + void NopJsonSerialize(string&); ++ void FunctionOpJsonSerialize(vector& data, string& out); ++ void LocalDeclsJsonSerialize(vector& decls, string& out); ++ Json::Value OperationJsonSerialize(mlir::Operation *, uint64_t&); ++ Json::Value CallOpJsonSerialize(mlir::Plugin::CallOp& data); ++ Json::Value CondOpJsonSerialize(mlir::Plugin::CondOp& data, uint64_t&); ++ Json::Value PhiOpJsonSerialize(mlir::Plugin::PhiOp& data); ++ Json::Value AssignOpJsonSerialize(mlir::Plugin::AssignOp& data); ++ Json::Value BaseOpJsonSerialize(mlir::Plugin::BaseOp data); ++ Json::Value FallThroughOpJsonSerialize(mlir::Plugin::FallThroughOp data, uint64_t&); ++ Json::Value RetOpJsonSerialize(mlir::Plugin::RetOp data, uint64_t&); ++ Json::Value ValueJsonSerialize(mlir::Value value); + /* 将Type类型数据序列化 */ + void TypeJsonSerialize(PluginIR::PluginTypeBase& type, string& out); + /* 获取gcc插件数据并进行IR转换,将转换后的数据序列化返回给server。param:函数入参序列化后的数据 */ +diff --git a/include/Translate/GimpleToPluginOps.h b/include/Translate/GimpleToPluginOps.h +index 3f4f96a..0fd2fd2 100644 +--- a/include/Translate/GimpleToPluginOps.h ++++ b/include/Translate/GimpleToPluginOps.h +@@ -23,7 +23,7 @@ + #ifndef GIMPLE_TO_PLUGINOPS_H + #define GIMPLE_TO_PLUGINOPS_H + +-#include "Translate/ToPluginOpsInterface.h" ++#include "Dialect/PluginOps.h" + #include "Translate/TypeTranslation.h" + + #include "mlir/IR/Attributes.h" +@@ -31,35 +31,59 @@ + #include "mlir/IR/BuiltinOps.h" + #include "mlir/IR/BuiltinTypes.h" + #include "mlir/IR/MLIRContext.h" ++#include "mlir/IR/Block.h" ++#include "mlir/IR/Region.h" + + namespace PluginIR { + using std::vector; ++using namespace mlir::Plugin; + +-class GimpleToPluginOps : public ToPluginOpsInterface { ++namespace detail { ++ class BlockFromGimpleTranslatorImpl; ++ // class BlockToPluginIRTranslatorImpl; ++} // namespace detail ++ ++class GimpleToPluginOps { + public: +- GimpleToPluginOps (mlir::MLIRContext &context) : builder(&context) , typeTranslator(context) {} +- GimpleToPluginOps () = default; +- ~GimpleToPluginOps () = default; ++ GimpleToPluginOps (mlir::MLIRContext &); ++ ~GimpleToPluginOps (); + + /* ToPluginInterface */ +- vector GetAllFunction() override; +- vector GetAllDecls(uint64_t) override; +- vector GetAllLoops(uint64_t) override; +- LoopOp GetLoop(uint64_t) override; +- bool IsBlockInside(uint64_t, uint64_t) override; +- vector GetBlocksInLoop(uint64_t) override; +- uint64_t AllocateNewLoop(void) override; +- void DeleteLoop(uint64_t) override; +- void AddLoop (uint64_t, uint64_t, uint64_t) override; +- uint64_t GetHeader(uint64_t) override; +- uint64_t GetLatch(uint64_t) override; +- vector > GetLoopExits(uint64_t) override; +- std::pair GetLoopSingleExit(uint64_t) override; +- LoopOp GetBlockLoopFather(uint64_t) override; ++ vector GetAllFunction(); ++ vector GetAllDecls(uint64_t); ++ vector GetAllLoops(uint64_t); ++ LoopOp GetLoop(uint64_t); ++ bool IsBlockInside(uint64_t, uint64_t); ++ vector GetBlocksInLoop(uint64_t); ++ uint64_t AllocateNewLoop(void); ++ void DeleteLoop(uint64_t); ++ void AddLoop (uint64_t, uint64_t, uint64_t); ++ uint64_t GetHeader(uint64_t); ++ uint64_t GetLatch(uint64_t); ++ vector > GetLoopExits(uint64_t); ++ std::pair GetLoopSingleExit(uint64_t); ++ LoopOp GetBlockLoopFather(uint64_t); ++ CallOp BuildCallOp(uint64_t); ++ bool SetGimpleCallLHS(uint64_t, uint64_t); ++ uint64_t CreateGcond(IComparisonCode, uint64_t, uint64_t); ++ FunctionOp BuildFunctionOp(uint64_t); ++ Operation *BuildOperation(uint64_t); ++ CondOp BuildCondOp(uint64_t, uint64_t, Block*, Block*, uint64_t, uint64_t); ++ AssignOp BuildAssignOp(uint64_t); ++ PhiOp BuildPhiOp(uint64_t); ++ mlir::Value GetGphiResult(uint64_t); ++ mlir::Value TreeToValue(uint64_t); ++ + private: ++ GimpleToPluginOps () = delete; + mlir::OpBuilder builder; + TypeFromPluginIRTranslator typeTranslator; ++ ++ // process basic_block ++ std::unique_ptr bbTranslator; ++ bool ProcessBasicBlock(intptr_t, Region&); ++ bool ProcessGimpleStmt(intptr_t, Region&); + }; + } // namespace PluginIR + +-#endif // GIMPLE_TO_PLUGINOPS_H +\ No newline at end of file ++#endif // GIMPLE_TO_PLUGINOPS_H +diff --git a/lib/Dialect/PluginOps.cpp b/lib/Dialect/PluginOps.cpp +index adf7ca6..de5cd11 100644 +--- a/lib/Dialect/PluginOps.cpp ++++ b/lib/Dialect/PluginOps.cpp +@@ -61,6 +61,140 @@ void LoopOp::build(mlir::OpBuilder &builder, mlir::OperationState &state, + builder.getI32IntegerAttr(numBlock)); + } + ++//===----------------------------------------------------------------------===// ++// PlaceholderOp ++ ++void PlaceholderOp::build(OpBuilder &builder, OperationState &state, ++ uint64_t id, IDefineCode defCode, Type retType) { ++ state.addAttribute("id", builder.getI64IntegerAttr(id)); ++ state.addAttribute("defCode", ++ builder.getI32IntegerAttr(static_cast(defCode))); ++ if (retType) state.addTypes(retType); ++} ++ ++//===----------------------------------------------------------------------===// ++// CallOp ++ ++void CallOp::build(mlir::OpBuilder &builder, mlir::OperationState &state, ++ uint64_t id, StringRef callee, ++ ArrayRef 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("callee"); ++} ++ ++/// Get the argument operands to the called function, this is required by the ++/// call interface. ++Operation::operand_range CallOp::getArgOperands() { return inputs(); } ++ ++//===----------------------------------------------------------------------===// ++// CondOp ++ ++void CondOp::build(OpBuilder &builder, OperationState &state, ++ uint64_t id, uint64_t address, IComparisonCode condCode, ++ Value lhs, Value rhs, Block* tb, Block* fb, uint64_t tbaddr, ++ uint64_t fbaddr, Value trueLabel, Value falseLabel) { ++ state.addAttribute("id", builder.getI64IntegerAttr(id)); ++ state.addAttribute("address", builder.getI64IntegerAttr(address)); ++ state.addOperands({lhs, rhs}); ++ state.addAttribute("tbaddr", builder.getI64IntegerAttr(tbaddr)); ++ state.addAttribute("fbaddr", builder.getI64IntegerAttr(fbaddr)); ++ state.addSuccessors(tb); ++ state.addSuccessors(fb); ++ state.addAttribute("condCode", ++ builder.getI32IntegerAttr(static_cast(condCode))); ++ if (trueLabel != nullptr) state.addOperands(trueLabel); ++ if (falseLabel != nullptr) state.addOperands(falseLabel); ++} ++ ++//===----------------------------------------------------------------------===// ++// PhiOp ++ ++void PhiOp::build(OpBuilder &builder, OperationState &state, ++ uint64_t id, uint32_t capacity, uint32_t nArgs, ++ ArrayRef operands, Type resultType) { ++ 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); ++} ++ ++//===----------------------------------------------------------------------===// ++// AssignOp ++ ++void AssignOp::build(OpBuilder &builder, OperationState &state, ++ uint64_t id, IExprCode exprCode, ++ ArrayRef operands, Type resultType) ++{ ++ state.addAttribute("id", builder.getI64IntegerAttr(id)); ++ state.addAttribute("exprCode", ++ builder.getI32IntegerAttr(static_cast(exprCode))); ++ state.addOperands(operands); ++ if (resultType) state.addTypes(resultType); ++} ++ ++/// The 'OpAsmParser' class provides a collection of methods for parsing ++/// various punctuation, as well as attributes, operands, types, etc. Each of ++/// these methods returns a `ParseResult`. This class is a wrapper around ++/// `LogicalResult` that can be converted to a boolean `true` value on failure, ++/// or `false` on success. This allows for easily chaining together a set of ++/// parser rules. These rules are used to populate an `mlir::OperationState` ++/// similarly to the `build` methods described above. ++static mlir::ParseResult parseAssignOp(mlir::OpAsmParser &parser, ++ mlir::OperationState &result) { ++ mlir::DenseElementsAttr value; ++ if (parser.parseOptionalAttrDict(result.attributes) || ++ parser.parseAttribute(value, "value", result.attributes)) ++ return failure(); ++ ++ result.addTypes(value.getType()); ++ return success(); ++} ++ ++/// The 'OpAsmPrinter' class is a stream that allows for formatting ++/// strings, attributes, operands, types, etc. ++static void print(mlir::OpAsmPrinter &printer, AssignOp op) { ++ printer << "assign "; ++ printer.printType(op.getType()); ++// printer << op.value(); ++} ++ ++//===----------------------------------------------------------------------===// ++// 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/PluginClientAPI.cpp b/lib/PluginAPI/PluginClientAPI.cpp +index d268c1e..ece137f 100644 +--- a/lib/PluginAPI/PluginClientAPI.cpp ++++ b/lib/PluginAPI/PluginClientAPI.cpp +@@ -86,5 +86,30 @@ LoopOp PluginClientAPI::GetBlockLoopFather(uint64_t blockId) + { + return gimpleConversion.GetBlockLoopFather(blockId); + } ++PhiOp PluginClientAPI::GetPhiOp(uint64_t id) ++{ ++ return gimpleConversion.BuildPhiOp(id); ++} ++ ++CallOp PluginClientAPI::GetCallOp(uint64_t id) ++{ ++ return gimpleConversion.BuildCallOp(id); ++} ++ ++bool PluginClientAPI::SetLhsInCallOp(uint64_t callId, uint64_t lhsId) ++{ ++ return gimpleConversion.SetGimpleCallLHS(callId, lhsId); ++} ++ ++uint64_t PluginClientAPI::CreateCondOp(IComparisonCode iCode, ++ uint64_t LHS, uint64_t RHS) ++{ ++ return gimpleConversion.CreateGcond(iCode, LHS, RHS); ++} ++ ++mlir::Value PluginClientAPI::GetResultFromPhi(uint64_t id) ++{ ++ return gimpleConversion.GetGphiResult(id); ++} + + } // namespace PluginAPI +\ No newline at end of file +diff --git a/lib/PluginClient/PluginClient.cpp b/lib/PluginClient/PluginClient.cpp +index c57d36c..e8a7d7d 100644 +--- a/lib/PluginClient/PluginClient.cpp ++++ b/lib/PluginClient/PluginClient.cpp +@@ -31,7 +31,6 @@ + #include + #include + #include +-#include + + namespace PinClient { + using namespace mlir::Plugin; +@@ -106,7 +105,7 @@ void PluginClient::TypeJsonSerialize (PluginIR::PluginTypeBase& type, string& ou + out = root.toStyledString(); + } + +-void PluginClient::OpJsonSerialize(vector& data, string& out) ++void PluginClient::FunctionOpJsonSerialize(vector& data, string& out) + { + Json::Value root; + Json::Value operationObj; +@@ -122,14 +121,77 @@ void PluginClient::OpJsonSerialize(vector& data, string& out) + item["attributes"]["declaredInline"] = "1"; + else + item["attributes"]["declaredInline"] = "0"; +- item["attributes"]["funcName"] = d.funcNameAttr().getValue().str(); +- operation = "operation" + std::to_string(i++); ++ 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 (auto phOp = llvm::dyn_cast(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 PluginClient::OperationJsonSerialize(mlir::Operation *operation, ++ uint64_t &bbId) ++{ ++ Json::Value root; ++ if (AssignOp op = llvm::dyn_cast(operation)) { ++ root = AssignOpJsonSerialize(op); ++ } else if (CallOp op = llvm::dyn_cast(operation)) { ++ root = CallOpJsonSerialize(op); ++ } else if (CondOp op = llvm::dyn_cast(operation)) { ++ root = CondOpJsonSerialize(op, bbId); ++ } else if (PhiOp op = llvm::dyn_cast(operation)) { ++ root = PhiOpJsonSerialize(op); ++ } else if (FallThroughOp op = llvm::dyn_cast(operation)) { ++ root = FallThroughOpJsonSerialize(op, bbId); ++ } else if (RetOp op = llvm::dyn_cast(operation)) { ++ root = RetOpJsonSerialize(op, bbId); ++ } else if (BaseOp op = llvm::dyn_cast(operation)) { ++ root = BaseOpJsonSerialize(op); ++ } ++ root["OperationName"] = operation->getName().getStringRef().str(); ++ return root; ++} ++ ++Json::Value PluginClient::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 PluginClient::RetOpJsonSerialize(RetOp data, uint64_t &bbId) ++{ ++ Json::Value root; ++ bbId = data.addressAttr().getInt(); ++ root["address"] = std::to_string(bbId); ++ return root; ++} ++ ++Json::Value PluginClient::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 PluginClient::LocalDeclsJsonSerialize(vector& decls, string& out) + { + Json::Value root; +@@ -245,6 +307,78 @@ void PluginClient::NopJsonSerialize(string& out) + out = root.toStyledString(); + } + ++Json::Value PluginClient::CallOpJsonSerialize(CallOp& data) ++{ ++ Json::Value item; ++ item["id"] = std::to_string(data.idAttr().getInt()); ++ item["callee"] = data.callee().str(); ++ size_t opIdx = 0; ++ for (mlir::Value v : data.getArgOperands()) { ++ PlaceholderOp phOp = v.getDefiningOp(); ++ string input = "input" + std::to_string(opIdx++); ++ item["operands"][input]["id"] = std::to_string(phOp.idAttr().getInt()); ++ item["operands"][input]["defCode"] = std::to_string(phOp.defCodeAttr().getInt()); ++ } ++ return item; ++} ++ ++Json::Value PluginClient::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 PluginClient::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()); ++ size_t opIdx = 0; ++ for (mlir::Value v : data.operands()) { ++ PlaceholderOp phOp = v.getDefiningOp(); ++ string input = "input" + std::to_string(opIdx++); ++ item["operands"][input]["id"] = std::to_string(phOp.idAttr().getInt()); ++ item["operands"][input]["defCode"] = std::to_string(phOp.defCodeAttr().getInt()); ++ } ++ return item; ++} ++ ++Json::Value PluginClient::AssignOpJsonSerialize(AssignOp& data) ++{ ++ Json::Value item; ++ item["id"] = std::to_string(data.idAttr().getInt()); ++ item["exprCode"] = std::to_string(data.exprCodeAttr().getInt()); ++ size_t opIdx = 0; ++ for (mlir::Value v : data.operands()) { ++ PlaceholderOp phOp = v.getDefiningOp(); ++ string input = "input" + std::to_string(opIdx++); ++ item["operands"][input]["id"] = std::to_string(phOp.idAttr().getInt()); ++ item["operands"][input]["defCode"] = std::to_string(phOp.defCodeAttr().getInt()); ++ } ++ return item; ++} ++ ++Json::Value PluginClient::ValueJsonSerialize(mlir::Value data) ++{ ++ Json::Value root; ++ if (PlaceholderOp phOp = data.getDefiningOp()) { ++ root["id"] = std::to_string(phOp.idAttr().getInt()); ++ root["defCode"] = std::to_string(phOp.defCodeAttr().getInt()); ++ } else { ++ LOGE("ERROR: Can't Serialize!"); ++ } ++ return root; ++} ++ + void PluginClient::IRTransBegin(const string& funcName, const string& param) + { + string result; +@@ -260,7 +394,7 @@ void PluginClient::IRTransBegin(const string& funcName, const string& param) + context.getOrLoadDialect(); + PluginAPI::PluginClientAPI clientAPI(context); + vector allFuncOps = clientAPI.GetAllFunc(); +- OpJsonSerialize(allFuncOps, result); ++ FunctionOpJsonSerialize(allFuncOps, result); + this->ReceiveSendMsg("FuncOpResult", result); + } else if (funcName == "GetLocalDecls") { + /// Json格式 +@@ -436,6 +570,47 @@ void PluginClient::IRTransBegin(const string& funcName, const string& param) + LoopOp loopFather = clientAPI.GetBlockLoopFather(blockId); + LoopOpJsonSerialize(loopFather, result); + this->ReceiveSendMsg("LoopOpResult", result); ++ } else if (funcName == "GetPhiOp") { ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ uint64_t id = atol(root[std::to_string(0)].asString().c_str()); ++ PhiOp op = clientAPI.GetPhiOp(id); ++ Json::Value result = PhiOpJsonSerialize(op); ++ this->ReceiveSendMsg("OpsResult", result.toStyledString()); ++ } else if (funcName == "GetCallOp") { ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ uint64_t id = atol(root[std::to_string(0)].asString().c_str()); ++ CallOp op = clientAPI.GetCallOp(id); ++ Json::Value result = CallOpJsonSerialize(op); ++ this->ReceiveSendMsg("OpsResult", result.toStyledString()); ++ } else if (funcName == "SetLhsInCallOp") { ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ uint64_t callId = atol(root["callId"].asString().c_str()); ++ uint64_t lhsId = atol(root["lhsId"].asString().c_str()); ++ bool ret = clientAPI.SetLhsInCallOp(callId, lhsId); ++ this->ReceiveSendMsg("BoolResult", std::to_string(ret)); ++ } else if (funcName == "CreateCondOp") { ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ int condCode = atol(root["condCode"].asString().c_str()); ++ uint64_t lhsId = atol(root["lhsId"].asString().c_str()); ++ uint64_t rhsId = atol(root["rhsId"].asString().c_str()); ++ uint64_t ret = clientAPI.CreateCondOp(IComparisonCode(condCode), ++ lhsId, rhsId); ++ this->ReceiveSendMsg("IdResult", std::to_string(ret)); ++ } else if (funcName == "GetResultFromPhi") { ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ uint64_t id = atol(root["id"].asString().c_str()); ++ mlir::Value ret = clientAPI.GetResultFromPhi(id); ++ this->ReceiveSendMsg("ValueResult", ValueJsonSerialize(ret).toStyledString()); + } else { + LOGW("function: %s not found!\n", funcName.c_str()); + } +diff --git a/lib/Translate/GimpleToPluginOps.cpp b/lib/Translate/GimpleToPluginOps.cpp +index 273a214..1f9988b 100644 +--- a/lib/Translate/GimpleToPluginOps.cpp ++++ b/lib/Translate/GimpleToPluginOps.cpp +@@ -20,6 +20,8 @@ + #include "Dialect/PluginTypes.h" + + #include ++#include "llvm/Support/Casting.h" ++#include "llvm/ADT/SmallVector.h" + + #include "gcc-plugin.h" + #include "plugin-version.h" +@@ -46,6 +48,121 @@ + + namespace PluginIR { + using namespace mlir::Plugin; ++using namespace mlir; ++ ++namespace detail { ++class BlockFromGimpleTranslatorImpl { ++public: ++ std::map blockMaps; ++ /* Constructs a class creating types in the given MLIR context. */ ++ BlockFromGimpleTranslatorImpl(mlir::MLIRContext &context) : context(context) {} ++ ++private: ++ /* The context in which MLIR types are created. */ ++ mlir::MLIRContext &context; ++}; ++ ++} // namespace detail ++ ++GimpleToPluginOps::GimpleToPluginOps (mlir::MLIRContext &context) : ++ builder(&context), typeTranslator(context), bbTranslator(new detail::BlockFromGimpleTranslatorImpl(context)) ++{} ++ ++GimpleToPluginOps::~GimpleToPluginOps () ++{} ++ ++static IComparisonCode TranslateCmpCode(enum tree_code ccode) ++{ ++ switch (ccode) { ++ case LT_EXPR: ++ return IComparisonCode::lt; ++ case LE_EXPR: ++ return IComparisonCode::le; ++ case GT_EXPR: ++ return IComparisonCode::gt; ++ case GE_EXPR: ++ return IComparisonCode::ge; ++ case LTGT_EXPR: ++ return IComparisonCode::ltgt; ++ case EQ_EXPR: ++ return IComparisonCode::eq; ++ case NE_EXPR: ++ return IComparisonCode::ne; ++ default: ++ printf("tcc_comparison: %d not suppoted!\n", ccode); ++ break; ++ } ++ return IComparisonCode::UNDEF; ++} ++ ++static enum tree_code TranslateCmpCodeToTreeCode(IComparisonCode iCode) ++{ ++ switch (iCode) { ++ case IComparisonCode::lt: ++ return LT_EXPR; ++ case IComparisonCode::le: ++ return LE_EXPR; ++ case IComparisonCode::gt: ++ return GT_EXPR; ++ case IComparisonCode::ge: ++ return GE_EXPR; ++ case IComparisonCode::ltgt: ++ return LTGT_EXPR; ++ case IComparisonCode::eq: ++ return EQ_EXPR; ++ case IComparisonCode::ne: ++ return NE_EXPR; ++ default: ++ printf("tcc_comparison not suppoted!\n"); ++ break; ++ } ++ return LT_EXPR; ++} ++ ++static IExprCode TranslateExprCode(enum tree_code ccode) ++{ ++ switch (ccode) { ++ case PLUS_EXPR: ++ return IExprCode::Plus; ++ case MINUS_EXPR: ++ return IExprCode::Minus; ++ case NOP_EXPR: ++ return IExprCode::Nop; ++ default: ++ // printf("tcc_binary: %d not suppoted!\n", ccode); ++ break; ++ } ++ return IExprCode::UNDEF; ++} ++ ++static StringRef GimpleCodeToOperationName(enum gimple_code tcode) ++{ ++ StringRef ret; ++ switch (tcode) { ++ case GIMPLE_PHI: { ++ ret = PhiOp::getOperationName(); ++ break; ++ } ++ case GIMPLE_ASSIGN: { ++ ret = AssignOp::getOperationName(); ++ break; ++ } ++ case GIMPLE_CALL: { ++ ret = CallOp::getOperationName(); ++ break; ++ } ++ case GIMPLE_COND: { ++ ret = CondOp::getOperationName(); ++ break; ++ } ++ default: { ++ ret = BaseOp::getOperationName(); ++ break; ++ } ++ } ++ return ret; ++} ++ + vector GimpleToPluginOps::GetAllFunction() + { + cgraph_node *node = NULL; +@@ -56,14 +173,9 @@ vector GimpleToPluginOps::GetAllFunction() + if (fn == NULL) + continue; + int64_t id = reinterpret_cast(reinterpret_cast(fn)); +- FunctionOp irFunc; +- mlir::StringRef funcName(function_name(fn)); +- bool declaredInline = false; +- if (DECL_DECLARED_INLINE_P(fn->decl)) +- declaredInline = true; +- auto location = builder.getUnknownLoc(); +- irFunc = builder.create(location, id, funcName, declaredInline); ++ FunctionOp irFunc = BuildFunctionOp(id); + functions.push_back(irFunc); ++ builder.setInsertionPointAfter(irFunc.getOperation()); + } + return functions; + } +@@ -229,4 +341,279 @@ LoopOp GimpleToPluginOps::GetBlockLoopFather(uint64_t blockID) + return pluginLoop; + } + ++FunctionOp GimpleToPluginOps::BuildFunctionOp(uint64_t functionId) ++{ ++ function *fn = reinterpret_cast(functionId); ++ mlir::StringRef funcName(function_name(fn)); ++ bool declaredInline = false; ++ if (DECL_DECLARED_INLINE_P(fn->decl)) ++ declaredInline = true; ++ auto location = builder.getUnknownLoc(); ++ FunctionOp retOp = builder.create(location, functionId, ++ funcName, declaredInline); ++ auto& fr = retOp.bodyRegion(); ++ if (!ProcessBasicBlock((intptr_t)ENTRY_BLOCK_PTR_FOR_FN(fn), fr)) { ++ // handle error ++ return retOp; ++ } ++ return retOp; ++} ++ ++Operation *GimpleToPluginOps::BuildOperation(uint64_t id) ++{ ++ gimple *stmt = reinterpret_cast(id); ++ Operation *ret = nullptr; ++ switch (gimple_code(stmt)) { ++ case GIMPLE_PHI: { ++ PhiOp phiOp = BuildPhiOp(id); ++ ret = phiOp.getOperation(); ++ break; ++ } ++ case GIMPLE_ASSIGN: { ++ AssignOp assignOp = BuildAssignOp(id); ++ ret = assignOp.getOperation(); ++ break; ++ } ++ case GIMPLE_CALL: { ++ CallOp callOp = BuildCallOp(id); ++ ret = callOp.getOperation(); ++ break; ++ } ++ case GIMPLE_COND: { ++ assert(EDGE_COUNT (stmt->bb->succs) == 2); ++ Block* trueBlock = bbTranslator->blockMaps[EDGE_SUCC(stmt->bb, 0)->dest]; ++ Block* falseBlock = bbTranslator->blockMaps[EDGE_SUCC(stmt->bb, 1)->dest]; ++ CondOp condOp = BuildCondOp(id, (uint64_t)stmt->bb, ++ trueBlock, falseBlock, ++ (uint64_t)EDGE_SUCC(stmt->bb, 0)->dest, ++ (uint64_t)EDGE_SUCC(stmt->bb, 1)->dest); ++ ret = condOp.getOperation(); ++ break; ++ } ++ default: { ++ BaseOp baseOp = builder.create( ++ builder.getUnknownLoc(), id, BaseOp::getOperationName()); ++ ret = baseOp.getOperation(); ++ break; ++ } ++ } ++ return ret; ++} ++ ++PhiOp GimpleToPluginOps::BuildPhiOp(uint64_t gphiId) ++{ ++ gphi *stmt = reinterpret_cast(gphiId); ++ llvm::SmallVector ops; ++ ops.reserve(gimple_phi_num_args(stmt)); ++ for (unsigned i = 0; i < gimple_phi_num_args(stmt); i++) { ++ tree *argTree = gimple_phi_arg_def_ptr(stmt, i); ++ uint64_t argId = reinterpret_cast( ++ reinterpret_cast(argTree)); ++ Value arg = TreeToValue(argId); ++ ops.push_back(arg); ++ } ++ tree returnType = TREE_TYPE(gimple_phi_result(stmt)); ++ PluginTypeBase rPluginType = typeTranslator.translateType((intptr_t)returnType); ++ uint32_t capacity = gimple_phi_capacity(stmt); ++ uint32_t nArgs = gimple_phi_num_args(stmt); ++ PhiOp ret = builder.create(builder.getUnknownLoc(), ++ gphiId, capacity, nArgs, ops, rPluginType); ++ return ret; ++} ++ ++CallOp GimpleToPluginOps::BuildCallOp(uint64_t gcallId) ++{ ++ gcall *stmt = reinterpret_cast(gcallId); ++ tree fndecl = gimple_call_fndecl(stmt); ++ if (fndecl == NULL_TREE || DECL_NAME(fndecl) == NULL_TREE) { ++ return nullptr; ++ } ++ llvm::SmallVector ops; ++ ops.reserve(gimple_call_num_args(stmt)); ++ for (unsigned i = 0; i < gimple_call_num_args(stmt); i++) { ++ tree *callArg = gimple_call_arg_ptr(stmt, i); ++ uint64_t argId = reinterpret_cast( ++ reinterpret_cast(callArg)); ++ Value arg = TreeToValue(argId); ++ ops.push_back(arg); ++ } ++ StringRef callName(IDENTIFIER_POINTER(DECL_NAME(fndecl))); ++ tree returnType = gimple_call_return_type(stmt); ++ PluginTypeBase rPluginType = typeTranslator.translateType((intptr_t)returnType); ++ CallOp ret = builder.create(builder.getUnknownLoc(), gcallId, callName, ops); ++ return ret; ++} ++ ++bool GimpleToPluginOps::SetGimpleCallLHS(uint64_t callId, uint64_t lhsId) ++{ ++ gcall *stmt = reinterpret_cast(callId); ++ tree *lhs = reinterpret_cast(callId); ++ gimple_call_set_lhs (stmt, *lhs); ++ return true; ++} ++ ++uint64_t GimpleToPluginOps::CreateGcond(IComparisonCode iCode, ++ uint64_t lhsId, uint64_t rhsId) ++{ ++ tree *lhs = reinterpret_cast(lhsId); ++ tree *rhs = reinterpret_cast(rhsId); ++ gcond *ret = gimple_build_cond (TranslateCmpCodeToTreeCode(iCode), ++ *lhs, *rhs, NULL_TREE, NULL_TREE); ++ return reinterpret_cast(reinterpret_cast(ret)); ++} ++ ++CondOp GimpleToPluginOps::BuildCondOp(uint64_t gcondId, uint64_t address, ++ Block* b1, Block* b2, uint64_t tbaddr, ++ uint64_t fbaddr) ++{ ++ gcond *stmt = reinterpret_cast(gcondId); ++ tree *lhsPtr = gimple_cond_lhs_ptr(stmt); ++ uint64_t lhsId = reinterpret_cast( ++ reinterpret_cast(lhsPtr)); ++ Value LHS = TreeToValue(lhsId); ++ tree *rhsPtr = gimple_cond_rhs_ptr(stmt); ++ uint64_t rhsId = reinterpret_cast( ++ reinterpret_cast(rhsPtr)); ++ Value RHS = TreeToValue(rhsId); ++ Value trueLabel = nullptr; ++ Value falseLabel = nullptr; ++ IComparisonCode iCode = TranslateCmpCode(gimple_cond_code(stmt)); ++ CondOp ret = builder.create(builder.getUnknownLoc(), gcondId, ++ address, iCode, LHS, RHS, b1, b2, ++ tbaddr, fbaddr, trueLabel, falseLabel); ++ return ret; ++} ++ ++AssignOp GimpleToPluginOps::BuildAssignOp(uint64_t gassignId) ++{ ++ gassign *stmt = reinterpret_cast(gassignId); ++ llvm::SmallVector ops; ++ ops.reserve(gimple_num_ops(stmt)); ++ uint64_t lhsId = reinterpret_cast( ++ reinterpret_cast(gimple_assign_lhs_ptr(stmt))); ++ ops.push_back(TreeToValue(lhsId)); ++ uint64_t rhs1Id = reinterpret_cast( ++ reinterpret_cast(gimple_assign_rhs1_ptr(stmt))); ++ ops.push_back(TreeToValue(rhs1Id)); ++ if (gimple_assign_rhs2(stmt) != NULL_TREE) { ++ uint64_t rhs2Id = reinterpret_cast( ++ reinterpret_cast(gimple_assign_rhs2_ptr(stmt))); ++ ops.push_back(TreeToValue(rhs2Id)); ++ } ++ if (gimple_assign_rhs3(stmt) != NULL_TREE) { ++ uint64_t rhs3Id = reinterpret_cast( ++ reinterpret_cast(gimple_assign_rhs3_ptr(stmt))); ++ ops.push_back(TreeToValue(rhs3Id)); ++ } ++ IExprCode iCode = TranslateExprCode(gimple_assign_rhs_code(stmt)); ++ mlir::Type returnType = nullptr; ++ AssignOp ret = builder.create( ++ builder.getUnknownLoc(), gassignId, iCode, ops, returnType); ++ return ret; ++} ++ ++Value GimpleToPluginOps::GetGphiResult(uint64_t id) ++{ ++ gphi *stmt = reinterpret_cast(id); ++ tree ret = gimple_phi_result(stmt); ++ uint64_t retId = reinterpret_cast( ++ reinterpret_cast(ret)); ++ return TreeToValue(retId); ++} ++ ++Value GimpleToPluginOps::TreeToValue(uint64_t treeId) ++{ ++ tree *t = reinterpret_cast(treeId); ++ tree treeType = TREE_TYPE(*t); ++ PluginTypeBase rPluginType = typeTranslator.translateType((intptr_t)treeType); ++ switch (TREE_CODE(*t)) { ++ case MEM_REF : { ++ break; ++ } ++ case INTEGER_CST : { ++ break; ++ } ++ case SSA_NAME : { ++ break; ++ } ++ default: ++ break; ++ } ++ mlir::Value opValue = builder.create( ++ builder.getUnknownLoc(), treeId, ++ IDefineCode::UNDEF, rPluginType); ++ return opValue; ++} ++ ++bool GimpleToPluginOps::ProcessGimpleStmt(intptr_t bbPtr, Region& rg) ++{ ++ bool putTerminator = false; ++ basic_block bb = reinterpret_cast(bbPtr); ++ for (gphi_iterator si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si)) { ++ gphi *p = si.phi (); ++ uint64_t id = reinterpret_cast(reinterpret_cast(p)); ++ BuildPhiOp(id); // FIXME: Check result. ++ } ++ ++ for (gimple_stmt_iterator si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si)) { ++ gimple *stmt = gsi_stmt (si); ++ uint64_t id = reinterpret_cast(reinterpret_cast(stmt)); ++ if (BuildOperation(id) == nullptr) { ++ printf("ERROR: BuildOperation!"); ++ } ++ if(gimple_code(stmt) == GIMPLE_COND) { ++ putTerminator = true; ++ } ++ } ++ ++ if (!putTerminator) { ++ // Process fallthrough, todo: process goto ++ if (EDGE_COUNT (bb->succs) == 1) { ++ builder.create(builder.getUnknownLoc(), (uint64_t)bb, ++ bbTranslator->blockMaps[EDGE_SUCC(bb, 0)->dest], ++ (uint64_t)(EDGE_SUCC(bb, 0)->dest)); ++ } else if (!EDGE_COUNT (bb->succs)) { ++ // Process other condition, such as return ++ builder.create(builder.getUnknownLoc(), (uint64_t)bb); ++ } else { ++ // Should unreachable; ++ assert(false); ++ } ++ } ++ ++ return true; ++} ++ ++bool GimpleToPluginOps::ProcessBasicBlock(intptr_t bbPtr, Region& rg) ++{ ++ basic_block bb = reinterpret_cast(bbPtr); ++ // handled, skip process ++ if (bbTranslator->blockMaps.find(bb) != bbTranslator->blockMaps.end()) { ++ return true; ++ } ++ // fprintf(stderr,"processing bb[%d]\n", bb->index); ++ ++ // create basic block ++ Block* block = builder.createBlock(&rg, rg.begin()); ++ bbTranslator->blockMaps.insert({bb, block}); ++ // todo process func return type ++ // todo isDeclaration ++ ++ // process succ ++ for (unsigned int i = 0; i < EDGE_COUNT (bb->succs); i++) { ++ // fprintf(stderr,"-->[%d]\n", EDGE_SUCC(bb, i)->dest->index); ++ if (!ProcessBasicBlock((intptr_t)(EDGE_SUCC(bb, i)->dest), rg)) { ++ return false; ++ } ++ } ++ // process each stmt ++ builder.setInsertionPointToStart(block); ++ if (!ProcessGimpleStmt(bbPtr, rg)) { ++ return false; ++ } ++ // block->dump(); ++ // fprintf(stderr, "[bb%d] succ: %d\n", bb->index,block->getNumSuccessors()); ++ return true; ++} ++ + } // namespace PluginIR +\ No newline at end of file +-- +2.27.0.windows.1 + diff --git a/0004-Pin-gcc-client-Support-Plugin-Pointer-type.patch b/0004-Pin-gcc-client-Support-Plugin-Pointer-type.patch new file mode 100644 index 0000000..da003d6 --- /dev/null +++ b/0004-Pin-gcc-client-Support-Plugin-Pointer-type.patch @@ -0,0 +1,184 @@ +From b8322c7f689c44ac7ca5fb4d407994308f4725ed Mon Sep 17 00:00:00 2001 +From: dingguangya +Date: Thu, 8 Dec 2022 20:41:09 +0800 +Subject: [PATCH 4/4] [Pin-gcc-client] Support Plugin Pointer type + +--- + include/Dialect/PluginTypes.h | 12 +++++++++ + include/PluginClient/PluginClient.h | 2 +- + lib/Dialect/PluginDialect.cpp | 1 + + lib/Dialect/PluginTypes.cpp | 41 +++++++++++++++++++++++++++++ + lib/PluginClient/PluginClient.cpp | 9 +++++-- + lib/Translate/TypeTranslation.cpp | 2 ++ + 6 files changed, 64 insertions(+), 3 deletions(-) + +diff --git a/include/Dialect/PluginTypes.h b/include/Dialect/PluginTypes.h +index e0ef867..b329caa 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 { +@@ -117,6 +118,17 @@ public: + unsigned getWidth() const; + }; + ++class PluginPointerType : public Type::TypeBase { ++public: ++ using Base::Base; ++ ++ PluginTypeID getPluginTypeID (); ++ ++ static PluginPointerType get(MLIRContext *context, Type pointee); ++ ++ Type getElementType(); ++}; // class PluginPointerType ++ + class PluginVoidType : public Type::TypeBase { + public: + using Base::Base; +diff --git a/include/PluginClient/PluginClient.h b/include/PluginClient/PluginClient.h +index b18ecc0..51e16c9 100644 +--- a/include/PluginClient/PluginClient.h ++++ b/include/PluginClient/PluginClient.h +@@ -128,7 +128,7 @@ public: + Json::Value RetOpJsonSerialize(mlir::Plugin::RetOp data, uint64_t&); + Json::Value ValueJsonSerialize(mlir::Value value); + /* 将Type类型数据序列化 */ +- void TypeJsonSerialize(PluginIR::PluginTypeBase& type, string& out); ++ Json::Value TypeJsonSerialize(PluginIR::PluginTypeBase& type); + /* 获取gcc插件数据并进行IR转换,将转换后的数据序列化返回给server。param:函数入参序列化后的数据 */ + void IRTransBegin(const string& funname, const string& param); + /* 从配置文件读取初始化信息 */ +diff --git a/lib/Dialect/PluginDialect.cpp b/lib/Dialect/PluginDialect.cpp +index a53861e..7071e64 100644 +--- a/lib/Dialect/PluginDialect.cpp ++++ b/lib/Dialect/PluginDialect.cpp +@@ -36,6 +36,7 @@ using namespace mlir::Plugin; + void PluginDialect::initialize() { + addTypes(); +diff --git a/lib/Dialect/PluginTypes.cpp b/lib/Dialect/PluginTypes.cpp +index bd5f145..0c0e048 100644 +--- a/lib/Dialect/PluginTypes.cpp ++++ b/lib/Dialect/PluginTypes.cpp +@@ -74,6 +74,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(key); ++ } ++ ++ bool operator==(const KeyTy &key) const { ++ return KeyTy(pointee) == key; ++ } ++ ++ Type pointee; ++ }; + } // namespace detail + } // namespace PluginIR + +@@ -96,6 +115,9 @@ PluginTypeID PluginTypeBase::getPluginTypeID () + if (auto Ty = dyn_cast()) { + return Ty.getPluginTypeID (); + } ++ if (auto Ty = dyn_cast()) { ++ return Ty.getPluginTypeID (); ++ } + return PluginTypeID::UndefTyID; + } + +@@ -254,4 +276,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/PluginClient/PluginClient.cpp b/lib/PluginClient/PluginClient.cpp +index e8a7d7d..237eccb 100644 +--- a/lib/PluginClient/PluginClient.cpp ++++ b/lib/PluginClient/PluginClient.cpp +@@ -70,7 +70,7 @@ int PluginClient::GetEvent(InjectPoint inject, plugin_event *event) + return -1; + } + +-void PluginClient::TypeJsonSerialize (PluginIR::PluginTypeBase& type, string& out) ++Json::Value PluginClient::TypeJsonSerialize (PluginIR::PluginTypeBase& type) + { + Json::Value root; + Json::Value operationObj; +@@ -82,6 +82,11 @@ void PluginClient::TypeJsonSerialize (PluginIR::PluginTypeBase& type, string& ou + ReTypeId = static_cast(type.getPluginTypeID()); + item["id"] = std::to_string(ReTypeId); + ++ if (auto elemTy = type.dyn_cast()) { ++ auto baseTy = elemTy.getElementType().dyn_cast(); ++ item["elementType"] = TypeJsonSerialize(baseTy); ++ } ++ + if (type.getPluginIntOrFloatBitWidth() != 0) { + ReTypeWidth = type.getPluginIntOrFloatBitWidth(); + item["width"] = std::to_string(ReTypeWidth); +@@ -102,7 +107,7 @@ void PluginClient::TypeJsonSerialize (PluginIR::PluginTypeBase& type, string& ou + } + + root["type"] = item; +- out = root.toStyledString(); ++ return root; + } + + void PluginClient::FunctionOpJsonSerialize(vector& data, string& out) +diff --git a/lib/Translate/TypeTranslation.cpp b/lib/Translate/TypeTranslation.cpp +index 492a895..4c390fa 100644 +--- a/lib/Translate/TypeTranslation.cpp ++++ b/lib/Translate/TypeTranslation.cpp +@@ -95,6 +95,8 @@ private: + return PluginBooleanType::get(&context); + if (TREE_CODE(type) == VOID_TYPE) + return PluginVoidType::get(&context); ++ if (TREE_CODE(type) == POINTER_TYPE) ++ return PluginPointerType::get(&context, translatePrimitiveType(TREE_TYPE(type))); + return PluginUndefType::get(&context); + } + +-- +2.27.0.windows.1 + diff --git a/pin-gcc-client.spec b/pin-gcc-client.spec index 8a3369f..14dcd95 100644 --- a/pin-gcc-client.spec +++ b/pin-gcc-client.spec @@ -1,6 +1,6 @@ Name: pin-gcc-client Version: 0.3.0 -Release: 1 +Release: 2 Summary: A Pin (Plug-IN framework) client is implemented based on GCC plugin and can execute the compiler optimization pass in GCC. License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ with exceptions and LGPLv2+ and BSD URL: https://gitee.com/src-openeuler/pin-gcc-client @@ -10,6 +10,11 @@ BuildRequires: gcc gcc-c++ gcc-plugin-devel cmake make pkgconfig grpc grpc-plug BuildRequires: llvm-mlir llvm-mlir-static llvm-mlir-devel llvm-devel Requires: gcc grpc protobuf +Patch1: 0001-Pin-gcc-client-Support-for-new-insertion-points-and-.patch +Patch2: 0002-Pin-gcc-client-Support-LoopOp.patch +Patch3: 0003-Pin-gcc-client-Support-build-CFG-CallOp-AssignOp-Con.patch +Patch4: 0004-Pin-gcc-client-Support-Plugin-Pointer-type.patch + %description A Pin (Plug-IN framework) client is implemented based on GCC plugin and can execute the compiler optimization pass in GCC. @@ -18,6 +23,12 @@ A Pin (Plug-IN framework) client is implemented based on GCC plugin and can exec %prep %setup -q + +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 + 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 @@ -41,6 +52,12 @@ cd _build %attr(0644,root,root) %{_bindir}/pin-gcc-client.json %changelog +* Thu Dec 08 2022 benniaobufeijiushiji - 0.3.0-2 +- Type:Sync +- ID:NA +- SUG:NA +- DESC:Sync patch from openEuler/pin-gcc-client + * Thu Dec 01 2022 wumingchuan - 0.3.0-1 - Type:Update - ID:NA -- Gitee