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