diff --git a/0013-pin-gcc-client-Add-DataFlow-APIs.patch b/0013-pin-gcc-client-Add-DataFlow-APIs.patch new file mode 100644 index 0000000..7e69481 --- /dev/null +++ b/0013-pin-gcc-client-Add-DataFlow-APIs.patch @@ -0,0 +1,927 @@ +From 6fdbb193b91f3deae430ae6ad0fc17aec40dd720 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=E9=83=91=E6=99=A8=E5=8D=89?= +Date: Fri, 22 Dec 2023 16:06:33 +0800 +Subject: [PATCH 4/5] [pin-gcc-client] Add DataFlow APIs. + +--- + include/PluginAPI/BasicPluginOpsAPI.h | 18 +++ + include/PluginAPI/PluginClientAPI.h | 18 +++ + include/PluginClient/PluginClient.h | 1 + + include/PluginClient/PluginJson.h | 4 +- + include/Translate/GimpleToPluginOps.h | 18 +++ + lib/PluginAPI/PluginClientAPI.cpp | 80 ++++++++++ + lib/PluginClient/PluginClient.cpp | 216 ++++++++++++++++++++++++- + lib/PluginClient/PluginJson.cpp | 32 ++++ + lib/Translate/GimpleToPluginOps.cpp | 217 +++++++++++++++++++++++++- + lib/gccPlugin/gccPlugin.cpp | 5 + + 10 files changed, 602 insertions(+), 7 deletions(-) + +diff --git a/include/PluginAPI/BasicPluginOpsAPI.h b/include/PluginAPI/BasicPluginOpsAPI.h +index 22da8df..647c498 100644 +--- a/include/PluginAPI/BasicPluginOpsAPI.h ++++ b/include/PluginAPI/BasicPluginOpsAPI.h +@@ -100,6 +100,7 @@ public: + virtual vector > GetLoopExits(uint64_t) = 0; + virtual std::pair GetLoopSingleExit(uint64_t) = 0; + virtual LoopOp GetBlockLoopFather(uint64_t) = 0; ++ virtual LoopOp FindCommonLoop(uint64_t, uint64_t) = 0; + virtual PhiOp GetPhiOp(uint64_t) = 0; + virtual CallOp GetCallOp(uint64_t) = 0; + virtual bool SetLhsInCallOp(uint64_t, uint64_t) = 0; +@@ -118,15 +119,32 @@ public: + virtual PhiOp CreatePhiOp(uint64_t, uint64_t) = 0; + virtual bool UpdateSSA() = 0; + virtual vector GetPhiOpsInsideBlock(uint64_t bb) = 0; ++ virtual vector GetOpsInsideBlock(uint64_t bb) = 0; + virtual bool IsDomInfoAvailable() = 0; + virtual mlir::Value GetValue(uint64_t) = 0; + virtual void DebugValue(uint64_t) = 0; ++ virtual void DebugOperation(uint64_t) = 0; ++ virtual void DebugBlock(uint64_t) = 0; + virtual mlir::Value BuildMemRef(PluginTypeBase, uint64_t, uint64_t) = 0; + virtual void RedirectFallthroughTarget(uint64_t, uint64_t) = 0; + virtual void RemoveEdge(uint64_t, uint64_t) = 0; + + virtual bool IsLtoOptimize() = 0; + virtual bool IsWholeProgram() = 0; ++ ++ virtual bool IsVirtualOperand(uint64_t) = 0; ++ ++ virtual void CalDominanceInfo(uint64_t, uint64_t) = 0; ++ virtual vector GetImmUseStmts(uint64_t) = 0; ++ virtual mlir::Value GetGimpleVuse(uint64_t) = 0; ++ virtual mlir::Value GetGimpleVdef(uint64_t) = 0; ++ virtual vector GetSsaUseOperand(uint64_t) = 0; ++ virtual vector GetSsaDefOperand(uint64_t) = 0; ++ virtual vector GetPhiOrStmtUse(uint64_t) = 0; ++ virtual vector GetPhiOrStmtDef(uint64_t) = 0; ++ virtual bool RefsMayAlias(uint64_t, uint64_t, uint64_t) = 0; ++ virtual bool PTIncludesDecl(uint64_t, uint64_t) = 0; ++ virtual bool PTsIntersect(uint64_t, uint64_t) = 0; + }; // class BasicPluginOpsAPI + } // namespace PluginAPI + +diff --git a/include/PluginAPI/PluginClientAPI.h b/include/PluginAPI/PluginClientAPI.h +index 26ef71d..23fa523 100644 +--- a/include/PluginAPI/PluginClientAPI.h ++++ b/include/PluginAPI/PluginClientAPI.h +@@ -92,6 +92,7 @@ public: + vector > GetLoopExits(uint64_t) override; + std::pair GetLoopSingleExit(uint64_t) override; + LoopOp GetBlockLoopFather(uint64_t) override; ++ LoopOp FindCommonLoop(uint64_t, uint64_t) override; + PhiOp GetPhiOp(uint64_t) override; + CallOp GetCallOp(uint64_t) override; + /* Plugin API for CallOp. */ +@@ -110,9 +111,12 @@ public: + mlir::Value CreateConstOp(mlir::Attribute, mlir::Type) override; + bool UpdateSSA() override; + vector GetPhiOpsInsideBlock(uint64_t bb) override; ++ vector GetOpsInsideBlock(uint64_t bb) override; + bool IsDomInfoAvailable() override; + mlir::Value GetValue(uint64_t) override; + void DebugValue(uint64_t) override; ++ void DebugOperation(uint64_t) override; ++ void DebugBlock(uint64_t) override; + mlir::Value BuildMemRef(PluginIR::PluginTypeBase, uint64_t, uint64_t) override; + + mlir::Value GetCurrentDefFromSSA(uint64_t) override; +@@ -128,6 +132,20 @@ public: + + bool IsLtoOptimize() override; + bool IsWholeProgram() override; ++ ++ bool IsVirtualOperand(uint64_t) override; ++ /* Plugin API for Data Flow*/ ++ void CalDominanceInfo(uint64_t, uint64_t) override; ++ virtual vector GetImmUseStmts(uint64_t) override; ++ virtual mlir::Value GetGimpleVuse(uint64_t) override; ++ virtual mlir::Value GetGimpleVdef(uint64_t) override; ++ virtual vector GetSsaUseOperand(uint64_t) override; ++ virtual vector GetSsaDefOperand(uint64_t) override; ++ virtual vector GetPhiOrStmtUse(uint64_t) override; ++ virtual vector GetPhiOrStmtDef(uint64_t) override; ++ virtual bool RefsMayAlias(uint64_t, uint64_t, uint64_t) override; ++ virtual bool PTIncludesDecl(uint64_t, uint64_t) override; ++ virtual bool PTsIntersect(uint64_t, uint64_t) override; + private: + PluginIR::GimpleToPluginOps gimpleConversion; + }; // class PluginClientAPI +diff --git a/include/PluginClient/PluginClient.h b/include/PluginClient/PluginClient.h +index 2b5648c..0b90970 100644 +--- a/include/PluginClient/PluginClient.h ++++ b/include/PluginClient/PluginClient.h +@@ -117,6 +117,7 @@ enum RefPassName { + PASS_PHIOPT, + PASS_SSA, + PASS_LOOP, ++ PASS_LAD, + PASS_MAC, + }; + +diff --git a/include/PluginClient/PluginJson.h b/include/PluginClient/PluginJson.h +index f8df011..a45a9b7 100755 +--- a/include/PluginClient/PluginJson.h ++++ b/include/PluginClient/PluginJson.h +@@ -52,7 +52,9 @@ public: + void FunctionDeclsJsonSerialize(vector& decls, string& out); + void FiledOpsJsonSerialize(vector& decls, string& out); + void GetPhiOpsJsonSerialize(vector phiOps, string& out); +- Json::Value OperationJsonSerialize(mlir::Operation *, uint64_t&); ++ void OpsJsonSerialize(vector>& ops, string& out); ++ void ValuesJsonSerialize(vector& values, 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); +diff --git a/include/Translate/GimpleToPluginOps.h b/include/Translate/GimpleToPluginOps.h +index 1332219..0423f15 100644 +--- a/include/Translate/GimpleToPluginOps.h ++++ b/include/Translate/GimpleToPluginOps.h +@@ -109,6 +109,7 @@ public: + vector > GetLoopExits(uint64_t); + std::pair GetLoopSingleExit(uint64_t); + LoopOp GetBlockLoopFather(uint64_t); ++ LoopOp FindCommonLoop(uint64_t, uint64_t); + CallOp BuildCallOp(uint64_t); + bool SetGimpleCallLHS(uint64_t, uint64_t); + uint32_t AddPhiArg(uint64_t, uint64_t, uint64_t, uint64_t); +@@ -140,9 +141,12 @@ public: + void GetTreeAttr(uint64_t, bool&, PluginTypeBase&); + mlir::Value TreeToValue(uint64_t); + void DebugValue(uint64_t); ++ void DebugOperation(uint64_t); ++ void DebugBlock(uint64_t); + mlir::Value BuildMemRef(PluginIR::PluginTypeBase, uint64_t, uint64_t); + bool UpdateSSA(); + vector GetPhiOpsInsideBlock(uint64_t); ++ vector GetOpsInsideBlock(uint64_t); + bool IsDomInfoAvailable(); + mlir::Value CreateNewDefFor(uint64_t, uint64_t, uint64_t); + bool SetCurrentDefFor(uint64_t, uint64_t); +@@ -156,6 +160,20 @@ public: + bool IsLtoOptimize(); + bool IsWholeProgram(); + ++ bool IsVirtualOperand(uint64_t); ++ ++ void CalDominanceInfo(uint64_t, uint64_t); ++ vector GetImmUseStmts(uint64_t); ++ mlir::Value GetGimpleVuse(uint64_t); ++ mlir::Value GetGimpleVdef(uint64_t); ++ vector GetSsaUseOperand(uint64_t); ++ vector GetSsaDefOperand(uint64_t); ++ vector GetPhiOrStmtUse(uint64_t); ++ vector GetPhiOrStmtDef(uint64_t); ++ bool RefsMayAlias(uint64_t, uint64_t, uint64_t); ++ bool PTIncludesDecl(uint64_t, uint64_t); ++ bool PTsIntersect(uint64_t, uint64_t); ++ + private: + GimpleToPluginOps () = delete; + mlir::OpBuilder builder; +diff --git a/lib/PluginAPI/PluginClientAPI.cpp b/lib/PluginAPI/PluginClientAPI.cpp +index 95e9ab3..b908ba1 100644 +--- a/lib/PluginAPI/PluginClientAPI.cpp ++++ b/lib/PluginAPI/PluginClientAPI.cpp +@@ -274,6 +274,12 @@ LoopOp PluginClientAPI::GetBlockLoopFather(uint64_t blockId) + { + return gimpleConversion.GetBlockLoopFather(blockId); + } ++ ++LoopOp PluginClientAPI::FindCommonLoop(uint64_t opId_1, uint64_t opId_2) ++{ ++ return gimpleConversion.FindCommonLoop(opId_1, opId_2); ++} ++ + PhiOp PluginClientAPI::GetPhiOp(uint64_t id) + { + return gimpleConversion.BuildPhiOp(id); +@@ -345,6 +351,11 @@ vector PluginClientAPI::GetPhiOpsInsideBlock(uint64_t bb) + return gimpleConversion.GetPhiOpsInsideBlock(bb); + } + ++vector PluginClientAPI::GetOpsInsideBlock(uint64_t bb) ++{ ++ return gimpleConversion.GetOpsInsideBlock(bb); ++} ++ + bool PluginClientAPI::IsDomInfoAvailable() + { + return gimpleConversion.IsDomInfoAvailable(); +@@ -380,11 +391,26 @@ mlir::Value PluginClientAPI::GetValue(uint64_t valId) + return gimpleConversion.TreeToValue(valId); + } + ++bool PluginClientAPI::IsVirtualOperand(uint64_t id) ++{ ++ return gimpleConversion.IsVirtualOperand(id); ++} ++ + void PluginClientAPI::DebugValue(uint64_t valId) + { + gimpleConversion.DebugValue(valId); + } + ++void PluginClientAPI::DebugOperation(uint64_t opId) ++{ ++ gimpleConversion.DebugOperation(opId); ++} ++ ++void PluginClientAPI::DebugBlock(uint64_t bb) ++{ ++ gimpleConversion.DebugBlock(bb); ++} ++ + mlir::Value PluginClientAPI::BuildMemRef(PluginIR::PluginTypeBase type, + uint64_t baseId, uint64_t offsetId) + { +@@ -411,4 +437,58 @@ bool PluginClientAPI::IsWholeProgram() + return gimpleConversion.IsWholeProgram(); + } + ++void PluginClientAPI::CalDominanceInfo(uint64_t dir, uint64_t funcID) ++{ ++ return gimpleConversion.CalDominanceInfo(dir, funcID); ++} ++ ++vector PluginClientAPI::GetImmUseStmts(uint64_t varId) ++{ ++ return gimpleConversion.GetImmUseStmts(varId); ++} ++ ++mlir::Value PluginClientAPI::GetGimpleVuse(uint64_t opId) ++{ ++ return gimpleConversion.GetGimpleVuse(opId); ++} ++ ++mlir::Value PluginClientAPI::GetGimpleVdef(uint64_t opId) ++{ ++ return gimpleConversion.GetGimpleVdef(opId); ++} ++ ++vector PluginClientAPI::GetSsaUseOperand(uint64_t opId) ++{ ++ return gimpleConversion.GetSsaUseOperand(opId); ++} ++ ++vector PluginClientAPI::GetSsaDefOperand(uint64_t opId) ++{ ++ return gimpleConversion.GetSsaDefOperand(opId); ++} ++ ++vector PluginClientAPI::GetPhiOrStmtUse(uint64_t opId) ++{ ++ return gimpleConversion.GetPhiOrStmtUse(opId); ++} ++ ++vector PluginClientAPI::GetPhiOrStmtDef(uint64_t opId) ++{ ++ return gimpleConversion.GetPhiOrStmtDef(opId); ++} ++ ++bool PluginClientAPI::RefsMayAlias(uint64_t id1, uint64_t id2, uint64_t flag) ++{ ++ return gimpleConversion.RefsMayAlias(id1, id2, flag); ++} ++ ++bool PluginClientAPI::PTIncludesDecl(uint64_t ptrId, uint64_t declId) ++{ ++ return gimpleConversion.PTIncludesDecl(ptrId, declId); ++} ++ ++bool PluginClientAPI::PTsIntersect(uint64_t ptrId_1, uint64_t ptrId_2) ++{ ++ return gimpleConversion.PTsIntersect(ptrId_1, ptrId_2); ++} + } // namespace PluginAPI +\ No newline at end of file +diff --git a/lib/PluginClient/PluginClient.cpp b/lib/PluginClient/PluginClient.cpp +index c9f3cb7..fba0de4 100644 +--- a/lib/PluginClient/PluginClient.cpp ++++ b/lib/PluginClient/PluginClient.cpp +@@ -839,6 +839,19 @@ void GetBlockLoopFatherResult(PluginClient *client, Json::Value& root, string& r + client->ReceiveSendMsg("LoopOpResult", result); + } + ++void FindCommonLoopResult(PluginClient *client, Json::Value& root, string& result) ++{ ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ uint64_t loopId_1 = atol(root["loopId_1"].asString().c_str()); ++ uint64_t loopId_2 = atol(root["loopId_2"].asString().c_str()); ++ LoopOp commonLoop = clientAPI.FindCommonLoop(loopId_1, loopId_2); ++ PluginJson json = client->GetJson(); ++ json.LoopOpJsonSerialize(commonLoop, result); ++ client->ReceiveSendMsg("LoopOpResult", result); ++} ++ + void CreateBlockResult(PluginClient *client, Json::Value& root, string& result) + { + /// Json格式 +@@ -942,7 +955,7 @@ void GetPhiOpResult(PluginClient *client, Json::Value& root, string& result) + PhiOp op = clientAPI.GetPhiOp(id); + PluginJson json = client->GetJson(); + Json::Value phiOpResult = json.PhiOpJsonSerialize(op); +- client->ReceiveSendMsg("OpsResult", phiOpResult.toStyledString()); ++ client->ReceiveSendMsg("OpResult", phiOpResult.toStyledString()); + } + + void GetCallOpResult(PluginClient *client, Json::Value& root, string& result) +@@ -954,7 +967,7 @@ void GetCallOpResult(PluginClient *client, Json::Value& root, string& result) + CallOp op = clientAPI.GetCallOp(id); + PluginJson json = client->GetJson(); + Json::Value opResult = json.CallOpJsonSerialize(op); +- client->ReceiveSendMsg("OpsResult", opResult.toStyledString()); ++ client->ReceiveSendMsg("OpResult", opResult.toStyledString()); + } + + void SetLhsInCallOpResult(PluginClient *client, Json::Value& root, string& result) +@@ -1068,7 +1081,7 @@ void CreatePhiOpResult(PluginClient *client, Json::Value& root, string& result) + PhiOp op = clientAPI.CreatePhiOp(argId, blockId); + PluginJson json = client->GetJson(); + Json::Value opResult = json.PhiOpJsonSerialize(op); +- client->ReceiveSendMsg("OpsResult", opResult.toStyledString()); ++ client->ReceiveSendMsg("OpResult", opResult.toStyledString()); + } + + void CreateConstOpResult(PluginClient *client, Json::Value& root, string& result) +@@ -1106,6 +1119,18 @@ void GetAllPhiOpInsideBlockResult(PluginClient *client, Json::Value& root, strin + client->ReceiveSendMsg("GetPhiOps", result); + } + ++void GetAllOpsInsideBlockResult(PluginClient *client, Json::Value& root, string& result) ++{ ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ uint64_t bb = atol(root["bbAddr"].asString().c_str()); ++ vector opsId = clientAPI.GetOpsInsideBlock(bb); ++ PluginJson json = client->GetJson(); ++ json.IDsJsonSerialize(opsId, result); ++ client->ReceiveSendMsg("IdsResult", result); ++} ++ + void IsDomInfoAvailableResult(PluginClient *client, Json::Value& root, string& result) + { + mlir::MLIRContext context; +@@ -1172,6 +1197,136 @@ void CreateNewDefResult(PluginClient *client, Json::Value& root, string& result) + client->ReceiveSendMsg("ValueResult", json.ValueJsonSerialize(ret).toStyledString()); + } + ++void CalDominanceInfoResult(PluginClient *client, Json::Value& root, string& result) ++{ ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ std::string dirIdKey = "dir"; ++ uint64_t dir = atol(root[dirIdKey].asString().c_str()); ++ uint64_t funcId = atol(root["funcId"].asString().c_str()); ++ clientAPI.CalDominanceInfo(dir, funcId); ++ PluginJson json = client->GetJson(); ++ json.NopJsonSerialize(result); ++ client->ReceiveSendMsg("VoidResult", result); ++} ++ ++void GetImmUseStmtsResult(PluginClient *client, Json::Value& root, string& result) ++{ ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ uint64_t varId = atol(root["varId"].asString().c_str()); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ vector opsId = clientAPI.GetImmUseStmts(varId); ++ PluginJson json = client->GetJson(); ++ json.IDsJsonSerialize(opsId, result); ++ client->ReceiveSendMsg("IdsResult", result); ++} ++ ++void GetGimpleVuseResult(PluginClient *client, Json::Value& root, string& result) ++{ ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ uint64_t opId = atol(root["opId"].asString().c_str()); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ mlir::Value vuse = clientAPI.GetGimpleVuse(opId); ++ PluginJson json = client->GetJson(); ++ client->ReceiveSendMsg("ValueResult", json.ValueJsonSerialize(vuse).toStyledString()); ++} ++ ++void GetGimpleVdefResult(PluginClient *client, Json::Value& root, string& result) ++{ ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ uint64_t opId = atol(root["opId"].asString().c_str()); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ mlir::Value vdef = clientAPI.GetGimpleVdef(opId); ++ PluginJson json = client->GetJson(); ++ client->ReceiveSendMsg("ValueResult", json.ValueJsonSerialize(vdef).toStyledString()); ++} ++ ++void GetSsaUseOperandResult(PluginClient *client, Json::Value& root, string& result) ++{ ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ uint64_t opId = atol(root["opId"].asString().c_str()); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ vector ret = clientAPI.GetSsaUseOperand(opId); ++ PluginJson json = client->GetJson(); ++ json.ValuesJsonSerialize(ret, result); ++ client->ReceiveSendMsg("ValuesResult", result); ++} ++ ++void GetSsaDefOperandResult(PluginClient *client, Json::Value& root, string& result) ++{ ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ uint64_t opId = atol(root["opId"].asString().c_str()); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ vector ret = clientAPI.GetSsaDefOperand(opId); ++ PluginJson json = client->GetJson(); ++ json.ValuesJsonSerialize(ret, result); ++ client->ReceiveSendMsg("ValuesResult", result); ++} ++ ++void GetPhiOrStmtUseResult(PluginClient *client, Json::Value& root, string& result) ++{ ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ uint64_t opId = atol(root["opId"].asString().c_str()); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ vector ret = clientAPI.GetPhiOrStmtUse(opId); ++ PluginJson json = client->GetJson(); ++ json.ValuesJsonSerialize(ret, result); ++ client->ReceiveSendMsg("ValuesResult", result); ++} ++ ++void GetPhiOrStmtDefResult(PluginClient *client, Json::Value& root, string& result) ++{ ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ uint64_t opId = atol(root["opId"].asString().c_str()); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ vector ret = clientAPI.GetPhiOrStmtDef(opId); ++ PluginJson json = client->GetJson(); ++ json.ValuesJsonSerialize(ret, result); ++ client->ReceiveSendMsg("ValuesResult", result); ++} ++ ++void RefsMayAliasResult(PluginClient *client, Json::Value& root, string& result) ++{ ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ uint64_t id1 = atol(root["id1"].asString().c_str()); ++ uint64_t id2 = atol(root["id2"].asString().c_str()); ++ uint64_t flag = atol(root["flag"].asString().c_str()); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ bool ret = clientAPI.RefsMayAlias(id1, id2, flag); ++ client->ReceiveSendMsg("BoolResult", std::to_string(ret)); ++} ++ ++void PTIncludesDeclResult(PluginClient *client, Json::Value& root, string& result) ++{ ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ uint64_t ptrId = atol(root["ptrId"].asString().c_str()); ++ uint64_t declId = atol(root["declId"].asString().c_str()); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ bool ret = clientAPI.PTIncludesDecl(ptrId, declId); ++ client->ReceiveSendMsg("BoolResult", std::to_string(ret)); ++} ++ ++void PTsIntersectResult(PluginClient *client, Json::Value& root, string& result) ++{ ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ uint64_t ptrId_1 = atol(root["ptrId_1"].asString().c_str()); ++ uint64_t ptrId_2 = atol(root["ptrId_2"].asString().c_str()); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ bool ret = clientAPI.PTsIntersect(ptrId_1, ptrId_2); ++ client->ReceiveSendMsg("BoolResult", std::to_string(ret)); ++} ++ + void RemoveEdgeResult(PluginClient *client, Json::Value& root, string& result) + { + /// Json格式 +@@ -1235,6 +1390,16 @@ void BuildMemRefResult(PluginClient *client, Json::Value& root, string& result) + client->ReceiveSendMsg("ValueResult", result); + } + ++void IsVirtualOperandResult(PluginClient *client, Json::Value& root, string& result) ++{ ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ uint64_t id = atol(root["id"].asString().c_str()); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ bool ret = clientAPI.IsVirtualOperand(id); ++ client->ReceiveSendMsg("BoolResult", std::to_string(ret)); ++} ++ + void DebugValueResult(PluginClient *client, Json::Value& root, string& result) + { + /// Json格式 +@@ -1252,6 +1417,31 @@ void DebugValueResult(PluginClient *client, Json::Value& root, string& result) + client->ReceiveSendMsg("ValueResult", result); + } + ++void DebugOperationResult(PluginClient *client, Json::Value& root, string& result) ++{ ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ std::string opIdKey = "opId"; ++ uint64_t opId = atol(root[opIdKey].asString().c_str()); ++ clientAPI.DebugOperation(opId); ++ PluginJson json = client->GetJson(); ++ json.NopJsonSerialize(result); ++ client->ReceiveSendMsg("VoidResult", result); ++} ++ ++void DebugBlockResult(PluginClient *client, Json::Value& root, string& result) ++{ ++ mlir::MLIRContext context; ++ context.getOrLoadDialect(); ++ PluginAPI::PluginClientAPI clientAPI(context); ++ uint64_t bb = atol(root["bbAddr"].asString().c_str()); ++ clientAPI.DebugBlock(bb); ++ PluginJson json = client->GetJson(); ++ json.NopJsonSerialize(result); ++ client->ReceiveSendMsg("VoidResult", result); ++} ++ + void IsLtoOptimizeResult(PluginClient *client, Json::Value& root, string& result) + { + mlir::MLIRContext context; +@@ -1314,6 +1504,7 @@ std::map g_getResultFunc = { + {"GetLoopExits", GetLoopExitsResult}, + {"GetLoopSingleExit", GetLoopSingleExitResult}, + {"GetBlockLoopFather", GetBlockLoopFatherResult}, ++ {"FindCommonLoop", FindCommonLoopResult}, + {"CreateBlock", CreateBlockResult}, + {"DeleteBlock", DeleteBlockResult}, + {"SetImmediateDominator", SetImmediateDominatorResult}, +@@ -1332,6 +1523,7 @@ std::map g_getResultFunc = { + {"CreateConstOp", CreateConstOpResult}, + {"UpdateSSA", UpdateSSAResult}, + {"GetAllPhiOpInsideBlock", GetAllPhiOpInsideBlockResult}, ++ {"GetAllOpsInsideBlock", GetAllOpsInsideBlockResult}, + {"IsDomInfoAvailable", IsDomInfoAvailableResult}, + {"GetCurrentDefFromSSA", GetCurrentDefFromSSAResult}, + {"SetCurrentDefInSSA", SetCurrentDefInSSAResult}, +@@ -1341,9 +1533,23 @@ std::map g_getResultFunc = { + {"RemoveEdge", RemoveEdgeResult}, + {"ConfirmValue", ConfirmValueResult}, + {"BuildMemRef", BuildMemRefResult}, ++ {"IsVirtualOperand", IsVirtualOperandResult}, + {"DebugValue", DebugValueResult}, +- {"IsLtoOptimize",IsLtoOptimizeResult}, +- {"IsWholeProgram",IsWholeProgramResult}, ++ {"DebugOperation", DebugOperationResult}, ++ {"DebugBlock", DebugBlockResult}, ++ {"IsLtoOptimize", IsLtoOptimizeResult}, ++ {"IsWholeProgram", IsWholeProgramResult}, ++ {"CalDominanceInfo", CalDominanceInfoResult}, ++ {"GetImmUseStmts", GetImmUseStmtsResult}, ++ {"GetGimpleVuse", GetGimpleVuseResult}, ++ {"GetGimpleVdef", GetGimpleVdefResult}, ++ {"GetSsaUseOperand", GetSsaUseOperandResult}, ++ {"GetSsaDefOperand", GetSsaDefOperandResult}, ++ {"GetPhiOrStmtUse", GetPhiOrStmtUseResult}, ++ {"GetPhiOrStmtDef", GetPhiOrStmtDefResult}, ++ {"RefsMayAlias", RefsMayAliasResult}, ++ {"PTIncludesDecl", PTIncludesDeclResult}, ++ {"PTsIntersect", PTsIntersectResult} + }; + + void PluginClient::GetIRTransResult(void *gccData, const string& funcName, const string& param) +diff --git a/lib/PluginClient/PluginJson.cpp b/lib/PluginClient/PluginJson.cpp +index 7384a49..70532df 100755 +--- a/lib/PluginClient/PluginJson.cpp ++++ b/lib/PluginClient/PluginJson.cpp +@@ -444,6 +444,38 @@ void PluginJson::LoopOpJsonSerialize(mlir::Plugin::LoopOp& loop, string& out) + out = root.toStyledString(); + } + ++void PluginJson::OpsJsonSerialize(vector>& ops, string& out) ++{ ++ Json::Value root; ++ Json::Value item; ++ int i = 0; ++ string index; ++ ++ for (auto& op : ops) { ++ item = OperationJsonSerialize(op.first, op.second); ++ index = "Op" + std::to_string(i++); ++ root[index] = item; ++ item.clear(); ++ } ++ out = root.toStyledString(); ++} ++ ++void PluginJson::ValuesJsonSerialize(vector& values, string& out) ++{ ++ Json::Value root; ++ Json::Value item; ++ int i = 0; ++ string index; ++ ++ for (auto& v : values) { ++ item = ValueJsonSerialize(v); ++ index = "Value" + std::to_string(i++); ++ root[index] = item; ++ item.clear(); ++ } ++ out = root.toStyledString(); ++} ++ + void PluginJson::IDsJsonSerialize(vector& ids, string& out) + { + Json::Value root; +diff --git a/lib/Translate/GimpleToPluginOps.cpp b/lib/Translate/GimpleToPluginOps.cpp +index c358d17..342ef3d 100644 +--- a/lib/Translate/GimpleToPluginOps.cpp ++++ b/lib/Translate/GimpleToPluginOps.cpp +@@ -49,6 +49,8 @@ + #include "dominance.h" + #include "print-tree.h" + #include "stor-layout.h" ++#include "ssa-iterators.h" ++#include + + namespace PluginIR { + using namespace mlir::Plugin; +@@ -754,7 +756,7 @@ void GimpleToPluginOps::SetLatch(uint64_t loopID, uint64_t blockID) + vector > GimpleToPluginOps::GetLoopExits(uint64_t loopID) + { + class loop *loop = reinterpret_cast(loopID); +- vec exit_edges = get_loop_exit_edges(loop); ++ auto_vec exit_edges = get_loop_exit_edges(loop); + edge e; + unsigned i = 0; + vector > res; +@@ -789,6 +791,22 @@ LoopOp GimpleToPluginOps::GetBlockLoopFather(uint64_t blockID) + return pluginLoop; + } + ++LoopOp GimpleToPluginOps::FindCommonLoop(uint64_t loopId_1, uint64_t loopId_2) ++{ ++ class loop *loop_s = reinterpret_cast(loopId_1); ++ class loop *loop_d = reinterpret_cast(loopId_2); ++ class loop *loop = find_common_loop(loop_s, loop_d); ++ 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; ++} ++ + void GimpleToPluginOps::RedirectFallthroughTarget(uint64_t src, uint64_t dest) + { + basic_block srcbb = reinterpret_cast(reinterpret_cast(src)); +@@ -1721,6 +1739,19 @@ Value GimpleToPluginOps::TreeToValue(uint64_t treeId) + void GimpleToPluginOps::DebugValue(uint64_t valId) + { + tree t = reinterpret_cast(valId); ++ debug_tree(t); ++} ++ ++void GimpleToPluginOps::DebugOperation(uint64_t opId) ++{ ++ gimple *stmt = reinterpret_cast(opId); ++ debug_gimple_stmt(stmt); ++} ++ ++void GimpleToPluginOps::DebugBlock(uint64_t bb) ++{ ++ basic_block BB = reinterpret_cast(bb); ++ debug_bb(BB); + } + + mlir::Value GimpleToPluginOps::BuildMemRef(PluginIR::PluginTypeBase type, uint64_t baseId, uint64_t offsetId) +@@ -1828,6 +1859,27 @@ vector GimpleToPluginOps::GetPhiOpsInsideBlock(uint64_t bb) + return phiOps; + } + ++vector GimpleToPluginOps::GetOpsInsideBlock(uint64_t bb) ++{ ++ basic_block header = reinterpret_cast(bb); ++ vector ops; ++ gimple_stmt_iterator gsi; ++ int i = 0; ++ for (gsi = gsi_start_bb (header); ++ !gsi_end_p (gsi); ++ gsi_next (&gsi)) ++ { ++ gimple *s = gsi_stmt(gsi); ++ if (gimple_code(s) == GIMPLE_DEBUG) continue; ++ uint64_t id = reinterpret_cast(reinterpret_cast(s)); ++ if (gimple_code(s) == GIMPLE_ASSIGN) { ++ BuildAssignOp(id); ++ } ++ ops.push_back(id); ++ } ++ return ops; ++} ++ + bool GimpleToPluginOps::IsDomInfoAvailable() + { + return dom_info_available_p (CDI_DOMINATORS); +@@ -1887,4 +1939,167 @@ Value GimpleToPluginOps::MakeSsaName(mlir::Type type) + return TreeToValue(retId); + } + ++bool GimpleToPluginOps::IsVirtualOperand(uint64_t id) ++{ ++ tree op = reinterpret_cast(id); ++ return virtual_operand_p (op); ++} ++ ++void GimpleToPluginOps::CalDominanceInfo(uint64_t dir, uint64_t funcID) ++{ ++ function *fn = reinterpret_cast(funcID); ++ push_cfun(fn); ++ if (dir == 1) { ++ calculate_dominance_info(CDI_DOMINATORS); ++ } else if (dir == 2) { ++ calculate_dominance_info(CDI_POST_DOMINATORS); ++ } else { ++ abort(); ++ } ++ pop_cfun(); ++} ++ ++vector GimpleToPluginOps::GetImmUseStmts(uint64_t varId) ++{ ++ vector opsId; ++ tree var = reinterpret_cast(varId); ++ imm_use_iterator imm_iter; ++ gimple *stmt; ++ FOR_EACH_IMM_USE_STMT (stmt, imm_iter, var) { ++ uint64_t id = reinterpret_cast(reinterpret_cast(stmt)); ++ opsId.push_back(id); ++ } ++ return opsId; ++} ++ ++ ++mlir::Value GimpleToPluginOps::GetGimpleVuse(uint64_t opId) ++{ ++ gimple *stmt = reinterpret_cast(opId); ++ tree vuse = gimple_vuse(stmt); ++ mlir::Value v = TreeToValue(reinterpret_cast(reinterpret_cast(vuse))); ++ return v; ++} ++ ++mlir::Value GimpleToPluginOps::GetGimpleVdef(uint64_t opId) ++{ ++ gimple *stmt = reinterpret_cast(opId); ++ tree vdef = gimple_vdef(stmt); ++ mlir::Value v = TreeToValue(reinterpret_cast(reinterpret_cast(vdef))); ++ return v; ++} ++ ++vector GimpleToPluginOps::GetSsaUseOperand(uint64_t opId) ++{ ++ vector ret; ++ gimple *stmt = reinterpret_cast(opId); ++ use_operand_p use_p; ++ ssa_op_iter oi; ++ FOR_EACH_SSA_USE_OPERAND (use_p, stmt, oi, SSA_OP_USE) { ++ tree op = USE_FROM_PTR (use_p); ++ if (TREE_CODE (op) != SSA_NAME) { ++ continue; ++ } ++ mlir::Value v = TreeToValue(reinterpret_cast(reinterpret_cast(op))); ++ ret.push_back(v); ++ } ++ return ret; ++} ++ ++vector GimpleToPluginOps::GetSsaDefOperand(uint64_t opId) ++{ ++ vector ret; ++ gimple *stmt = reinterpret_cast(opId); ++ def_operand_p def_p; ++ ssa_op_iter oi; ++ FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, oi, SSA_OP_DEF) { ++ tree op = DEF_FROM_PTR (def_p); ++ if (TREE_CODE (op) != SSA_NAME) { ++ continue; ++ } ++ mlir::Value v = TreeToValue(reinterpret_cast(reinterpret_cast(op))); ++ ret.push_back(v); ++ } ++ return ret; ++} ++ ++vector GimpleToPluginOps::GetPhiOrStmtUse(uint64_t opId) ++{ ++ vector ret; ++ gimple *stmt = reinterpret_cast(opId); ++ use_operand_p use_p; ++ ssa_op_iter oi; ++ FOR_EACH_PHI_OR_STMT_USE (use_p, stmt, oi, SSA_OP_USE) { ++ tree op = USE_FROM_PTR (use_p); ++ mlir::Value v = TreeToValue(reinterpret_cast(reinterpret_cast(op))); ++ ret.push_back(v); ++ } ++ return ret; ++} ++ ++vector GimpleToPluginOps::GetPhiOrStmtDef(uint64_t opId) ++{ ++ vector ret; ++ gimple *stmt = reinterpret_cast(opId); ++ def_operand_p def_p; ++ ssa_op_iter oi; ++ FOR_EACH_PHI_OR_STMT_DEF (def_p, stmt, oi, SSA_OP_DEF) { ++ tree op = DEF_FROM_PTR (def_p); ++ mlir::Value v = TreeToValue(reinterpret_cast(reinterpret_cast(op))); ++ ret.push_back(v); ++ } ++ return ret; ++} ++ ++string parser_generic_tree_node(tree node) ++{ ++ FILE *fp = tmpfile(); ++ if(fp==nullptr){ ++ return ""; ++ } ++ pretty_printer buffer; ++ pp_needs_newline(&buffer)=true; ++ buffer.buffer->stream = fp; ++ dump_generic_node(&buffer, node, 0, TDF_SLIM, false); ++ std::string str(pp_formatted_text(&buffer)); ++ pp_newline_and_flush(&buffer); ++ fclose(fp); ++ return str; ++} ++ ++bool GimpleToPluginOps::RefsMayAlias(uint64_t id1, uint64_t id2, uint64_t flag) ++{ ++ tree ref1 = reinterpret_cast(id1); ++ tree ref2 = reinterpret_cast(id2); ++ bool tbaa_p = false; ++ if (flag) tbaa_p = true; ++ return refs_may_alias_p (ref1, ref2, tbaa_p); ++} ++ ++bool GimpleToPluginOps::PTIncludesDecl(uint64_t ptrId, uint64_t declId) ++{ ++ tree ptr = reinterpret_cast(ptrId); ++ tree decl = reinterpret_cast(declId); ++ struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr); ++ if(!pi) return false; ++ if(!decl){ ++ std::cout<<"this decl is invalid!"; ++ return false; ++ } ++ if(is_global_var(decl)){ ++ std::cout<<"decl is global var!"<pt, decl); ++} ++ ++bool GimpleToPluginOps::PTsIntersect(uint64_t ptrId_1, uint64_t ptrId_2) ++{ ++ tree ptr_1 = reinterpret_cast(ptrId_1); ++ tree ptr_2 = reinterpret_cast(ptrId_2); ++ struct ptr_info_def *pi_1 = SSA_NAME_PTR_INFO (ptr_1); ++ struct ptr_info_def *pi_2 = SSA_NAME_PTR_INFO (ptr_2); ++ if(!pi_1 || !pi_2) return false; ++ return pt_solutions_intersect(&pi_1->pt, &pi_2->pt); ++} ++ + } // namespace PluginIR +\ No newline at end of file +diff --git a/lib/gccPlugin/gccPlugin.cpp b/lib/gccPlugin/gccPlugin.cpp +index 1877651..3e10023 100755 +--- a/lib/gccPlugin/gccPlugin.cpp ++++ b/lib/gccPlugin/gccPlugin.cpp +@@ -193,6 +193,7 @@ static std::map g_refPassName { + {PASS_PHIOPT, "phiopt"}, + {PASS_SSA, "ssa"}, + {PASS_LOOP, "loop"}, ++ {PASS_LAD, "laddress"}, + {PASS_MAC, "materialize-all-clones"}, + }; + +@@ -232,6 +233,10 @@ void RegisterPassManagerSetup(unsigned int index, const ManagerSetupData& setupD + passData.type = GIMPLE_PASS; + passInfo.pass = new GimplePass(passData, index); + break; ++ case PASS_LAD: ++ passData.type = GIMPLE_PASS; ++ passInfo.pass = new GimplePass(passData, index); ++ break; + case PASS_MAC: + passData.type = SIMPLE_IPA_PASS; + passInfo.pass = new SimpleIPAPass(passData, index); +-- +2.33.0 + diff --git a/0014-PluginClient-Bugfix-for-semaphore-exception-and-port.patch b/0014-PluginClient-Bugfix-for-semaphore-exception-and-port.patch new file mode 100644 index 0000000..4045e30 --- /dev/null +++ b/0014-PluginClient-Bugfix-for-semaphore-exception-and-port.patch @@ -0,0 +1,66 @@ +From 954c37acbb0a9a790d07b567ad99c952e150e6da Mon Sep 17 00:00:00 2001 +From: Mingchuan Wu +Date: Tue, 27 Feb 2024 16:05:13 +0800 +Subject: [PATCH 5/5] [PluginClient] Bugfix for semaphore exception and port + number release. + +--- + lib/PluginClient/PluginClient.cpp | 16 +++++++++++++--- + lib/Translate/GimpleToPluginOps.cpp | 7 ++++++- + 2 files changed, 19 insertions(+), 4 deletions(-) + +diff --git a/lib/PluginClient/PluginClient.cpp b/lib/PluginClient/PluginClient.cpp +index fba0de4..6bc6401 100644 +--- a/lib/PluginClient/PluginClient.cpp ++++ b/lib/PluginClient/PluginClient.cpp +@@ -1749,7 +1749,12 @@ static bool WaitServer(const string& port) + mode_t mask = umask(0); + mode_t mode = 0666; // 权限是rwrwrw,跨进程时,其他用户也要可以访问 + string semFile = "wait_server_startup" + port; +- sem_t *sem = sem_open(semFile.c_str(), O_CREAT, mode, 0); ++ sem_t *sem = sem_open(semFile.c_str(), O_CREAT | O_EXCL, mode, 0); ++ // Semaphore exception handling. ++ if (sem == SEM_FAILED) { ++ sem_unlink(semFile.c_str()); ++ sem = sem_open(semFile.c_str(), O_CREAT, mode, 0); ++ } + umask(mask); + int i = 0; + for (; i < cnt; i++) { +@@ -1770,8 +1775,13 @@ static bool WaitServer(const string& port) + int PluginClient::ServerStart(pid_t& pid) + { + if (!grpcPort.FindUnusedPort()) { +- LOGE("cannot find port for grpc,port 40001-65535 all used!\n"); +- return -1; ++ // Rectify the fault that the port number is not released ++ // because the client is abnormal. ++ LOGW("cannot find port for grpc, try again!\n"); ++ if (!grpcPort.FindUnusedPort()) { ++ LOGE("cannot find port for grpc,port 40001-65534 all used!\n"); ++ return -1; ++ } + } + + int ret = 0; +diff --git a/lib/Translate/GimpleToPluginOps.cpp b/lib/Translate/GimpleToPluginOps.cpp +index 342ef3d..76c5e31 100644 +--- a/lib/Translate/GimpleToPluginOps.cpp ++++ b/lib/Translate/GimpleToPluginOps.cpp +@@ -1523,7 +1523,12 @@ Value GimpleToPluginOps::TreeToValue(uint64_t treeId) + unsigned HOST_WIDE_INT uinit = tree_to_uhwi(t); + initAttr = builder.getI64IntegerAttr(uinit); + } else { +- abort(); ++ wide_int val = wi::to_wide(t); ++ if (wi::neg_p(val, TYPE_SIGN(TREE_TYPE(t)))) { ++ val = -val; ++ } ++ signed HOST_WIDE_INT init = val.to_shwi(); ++ initAttr = builder.getI64IntegerAttr(init); + } + GetTreeAttr(treeId, readOnly, rPluginType); + opValue = builder.create( +-- +2.33.0 + diff --git a/pin-gcc-client.spec b/pin-gcc-client.spec index dd2ea3e..9f568b3 100644 --- a/pin-gcc-client.spec +++ b/pin-gcc-client.spec @@ -1,6 +1,6 @@ Name: pin-gcc-client Version: 0.4.1 -Release: 12 +Release: 13 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 @@ -22,6 +22,8 @@ Patch9: 0009-Pin-gcc-client-Fix-TreeToValue-VAR_DECL-and-ARRAY_TY.patch Patch10: 0010-PluginClient-Fix-the-bug-during-multi-process-compil.patch Patch11: 0011-Pin-gcc-client-Adaptation-to-llvm15-mlir15-only-solv.patch Patch12: 0012-Pin-gcc-client-Adaptation-to-gcc12-only-solves-the-b.patch +Patch13: 0013-pin-gcc-client-Add-DataFlow-APIs.patch +Patch14: 0014-PluginClient-Bugfix-for-semaphore-exception-and-port.patch %description A Pin (Plug-IN framework) client is implemented based on GCC plugin and can execute the compiler optimization pass in GCC. @@ -61,6 +63,12 @@ find %{buildroot} -type f -name "*.so" -exec strip "{}" ";" %config(noreplace) /etc/ld.so.conf.d/%{name}-%{_arch}.conf %changelog +* Wed Apr 10 2024 wumingchuan - 0.4.1-13 +- Type:Update +- ID:NA +- SUG:NA +- DESC:Sync patch from openEuler/pin-gcc-client + * Tue Aug 22 2023 liyunfei - 0.4.1-12 - Type:FIX - ID:NA