diff --git a/0001-Refactoring-Code-refactoring-of-Communication-Subsys.patch b/0001-Refactoring-Code-refactoring-of-Communication-Subsys.patch new file mode 100644 index 0000000000000000000000000000000000000000..3913cb1ff333837f1abd61908f7154161b5b9b62 --- /dev/null +++ b/0001-Refactoring-Code-refactoring-of-Communication-Subsys.patch @@ -0,0 +1,1971 @@ +From 7ec62344dcd95cb321647f495d12303c94286ec5 Mon Sep 17 00:00:00 2001 +From: wangding16 +Date: Wed, 8 Feb 2023 15:05:33 +0800 +Subject: [PATCH 1/9] [Refactoring] Code refactoring of Communication Subsystem + [1/3]. Code refactoring of PluginLog and PluginServer. Add PluginJson. + + +diff --git a/include/user.h b/include/user.h +deleted file mode 100755 +index 1fb7a30..0000000 +--- a/include/user.h ++++ /dev/null +@@ -1,27 +0,0 @@ +-/* Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. +- +- Licensed under the Apache License, Version 2.0 (the "License"); you may +- not use this file except in compliance with the License. You may obtain +- a copy of the License at +- +- http://www.apache.org/licenses/LICENSE-2.0 +- +- Unless required by applicable law or agreed to in writing, software +- distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +- WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +- License for the specific language governing permissions and limitations +- under the License. +- +- Author: Mingchuan Wu and Yancheng Li +- Create: 2022-08-18 +- Description: +- This file contains the declaration of the User Init. +-*/ +- +-#ifndef PLUGIN_USER_H +-#define PLUGIN_USER_H +- +-/* 将注册点及用户函数注册给server, server初始化时调用 */ +-void RegisterCallbacks(void); +- +-#endif +diff --git a/lib/PluginServer/PluginJson.cpp b/lib/PluginServer/PluginJson.cpp +new file mode 100755 +index 0000000..c399aad +--- /dev/null ++++ b/lib/PluginServer/PluginJson.cpp +@@ -0,0 +1,612 @@ ++/* Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. ++ ++ Licensed under the Apache License, Version 2.0 (the "License"); you may ++ not use this file except in compliance with the License. You may obtain ++ a copy of the License at ++ ++ http://www.apache.org/licenses/LICENSE-2.0 ++ ++ Unless required by applicable law or agreed to in writing, software ++ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT ++ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the ++ License for the specific language governing permissions and limitations ++ under the License. ++ ++ Author: Mingchuan Wu and Yancheng Li ++ Create: 2022-08-18 ++ Description: ++ This file contains the implementation of the PluginJson class. ++*/ ++ ++#include "PluginServer/PluginJson.h" ++#include "PluginServer/PluginServer.h" ++ ++namespace PinJson { ++using namespace PinServer; ++using namespace mlir::Plugin; ++ ++static uintptr_t GetID(Json::Value node) ++{ ++ string id = node.asString(); ++ return atol(id.c_str()); ++} ++ ++static void JsonGetAttributes(Json::Value node, map& attributes) ++{ ++ Json::Value::Members attMember = node.getMemberNames(); ++ for (unsigned int i = 0; i < attMember.size(); i++) { ++ string key = attMember[i]; ++ string value = node[key.c_str()].asString(); ++ attributes[key] = value; ++ } ++} ++ ++Json::Value PluginJson::TypeJsonSerialize (PluginIR::PluginTypeBase& type) ++{ ++ Json::Value root; ++ Json::Value operationObj; ++ Json::Value item; ++ ++ uint64_t ReTypeId; ++ uint64_t ReTypeWidth; ++ ++ ReTypeId = static_cast(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 (elemTy.isReadOnlyElem()) { ++ item["elemConst"] = "1"; ++ } else { ++ item["elemConst"] = "0"; ++ } ++ } ++ ++ if (type.getPluginIntOrFloatBitWidth() != 0) { ++ ReTypeWidth = type.getPluginIntOrFloatBitWidth(); ++ item["width"] = std::to_string(ReTypeWidth); ++ } ++ ++ if (type.isSignedPluginInteger()) { ++ item["signed"] = "1"; ++ } ++ ++ if (type.isUnsignedPluginInteger()) { ++ item["signed"] = "0"; ++ } ++ ++ root["type"] = item; ++ return root; ++} ++ ++mlir::Value PluginJson::ValueJsonDeSerialize(Json::Value valueJson) ++{ ++ uint64_t opId = GetID(valueJson["id"]); ++ if (PluginServer::GetInstance()->HaveValue(opId)) ++ return PluginServer::GetInstance()->GetValue(opId); ++ ++ IDefineCode defCode = IDefineCode(atoi(valueJson["defCode"].asString().c_str())); ++ mlir::Type retType = TypeJsonDeSerialize(valueJson["retType"].toStyledString()); ++ bool readOnly = GetID(valueJson["readOnly"]); ++ mlir::Value opValue; ++ mlir::OpBuilder *opBuilder = PluginServer::GetInstance()->GetOpBuilder(); ++ switch (defCode) { ++ case IDefineCode::MemRef : { ++ opValue = MemRefDeSerialize(valueJson.toStyledString()); ++ break; ++ } ++ case IDefineCode::IntCST : { ++ uint64_t init = GetID(valueJson["value"]); ++ // FIXME : AnyAttr! ++ mlir::Attribute initAttr = opBuilder->getI64IntegerAttr(init); ++ opValue = opBuilder->create( ++ opBuilder->getUnknownLoc(), opId, IDefineCode::IntCST, ++ readOnly, initAttr, retType); ++ break; ++ } ++ case IDefineCode::SSA : { ++ opValue = SSAOpJsonDeSerialize(valueJson.toStyledString()); ++ break; ++ } ++ default: { ++ opValue = opBuilder->create( ++ opBuilder->getUnknownLoc(), opId, defCode, readOnly, retType); ++ break; ++ } ++ } ++ PluginServer::GetInstance()->InsertValue(opId, opValue); ++ return opValue; ++} ++ ++mlir::Value PluginJson::MemRefDeSerialize(const string& data) ++{ ++ Json::Value root; ++ Json::Reader reader; ++ reader.parse(data, root); ++ uint64_t id = GetID(root["id"]); ++ bool readOnly = (bool)atoi(root["readOnly"].asString().c_str()); ++ mlir::Value base = ValueJsonDeSerialize(root["base"]); ++ mlir::Value offset = ValueJsonDeSerialize(root["offset"]); ++ mlir::Type retType = TypeJsonDeSerialize(root["retType"].toStyledString().c_str()); ++ mlir::OpBuilder *opBuilder = PluginServer::GetInstance()->GetOpBuilder(); ++ mlir::Value memRef = opBuilder->create( ++ opBuilder->getUnknownLoc(), id, IDefineCode::MemRef, ++ readOnly, base, offset, retType); ++ return memRef; ++} ++ ++mlir::Value PluginJson::SSAOpJsonDeSerialize(const string& data) ++{ ++ Json::Value node; ++ Json::Reader reader; ++ reader.parse(data, node); ++ ++ uint64_t id = GetID(node["id"]); ++ bool readOnly = (bool)atoi(node["readOnly"].asString().c_str()); ++ uint64_t nameVarId = GetID(node["nameVarId"]); ++ uint64_t ssaParmDecl = GetID(node["ssaParmDecl"]); ++ uint64_t version = GetID(node["version"]); ++ uint64_t definingId = GetID(node["definingId"]); ++ mlir::Type retType = TypeJsonDeSerialize(node["retType"].toStyledString().c_str()); ++ mlir::OpBuilder *opBuilder = PluginServer::GetInstance()->GetOpBuilder(); ++ mlir::Value ret = opBuilder->create(opBuilder->getUnknownLoc(), ++ id, IDefineCode::SSA, readOnly, ++ nameVarId, ssaParmDecl, version, ++ definingId, retType); ++ return ret; ++} ++ ++void PluginJson::GetAttributes(Json::Value node, map& attributes) ++{ ++ Json::Value::Members attMember = node.getMemberNames(); ++ for (unsigned int i = 0; i < attMember.size(); i++) { ++ string key = attMember[i]; ++ string value = node[key.c_str()].asString(); ++ attributes[key] = value; ++ } ++} ++ ++bool PluginJson::ProcessBlock(mlir::Block* block, mlir::Region& rg, const Json::Value& blockJson) ++{ ++ if (blockJson.isNull()) { ++ return false; ++ } ++ // todo process func return type ++ // todo isDeclaration ++ ++ // process each stmt ++ mlir::OpBuilder *opBuilder = PluginServer::GetInstance()->GetOpBuilder(); ++ opBuilder->setInsertionPointToStart(block); ++ Json::Value::Members opMember = blockJson.getMemberNames(); ++ for (size_t opIdx = 0; opIdx < opMember.size(); opIdx++) { ++ string baseOpKey = "Operation" + std::to_string(opIdx); ++ Json::Value opJson = blockJson[baseOpKey]; ++ if (opJson.isNull()) continue; ++ string opCode = opJson["OperationName"].asString(); ++ if (opCode == PhiOp::getOperationName().str()) { ++ PhiOpJsonDeSerialize(opJson.toStyledString()); ++ } else if (opCode == CallOp::getOperationName().str()) { ++ CallOpJsonDeSerialize(opJson.toStyledString()); ++ } else if (opCode == AssignOp::getOperationName().str()) { ++ AssignOpJsonDeSerialize(opJson.toStyledString()); ++ } else if (opCode == CondOp::getOperationName().str()) { ++ CondOpJsonDeSerialize(opJson.toStyledString()); ++ } else if (opCode == RetOp::getOperationName().str()) { ++ RetOpJsonDeSerialize(opJson.toStyledString()); ++ } else if (opCode == FallThroughOp::getOperationName().str()) { ++ FallThroughOpJsonDeSerialize(opJson.toStyledString()); ++ } else if (opCode == BaseOp::getOperationName().str()) { ++ uint64_t opID = GetID(opJson["id"]); ++ opBuilder->create(opBuilder->getUnknownLoc(), opID, opCode); ++ } ++ } ++ return true; ++} ++ ++void PluginJson::IntegerDeSerialize(const string& data, int64_t& result) ++{ ++ Json::Value root; ++ Json::Reader reader; ++ reader.parse(data, root); ++ ++ result = root["integerData"].asInt64(); ++} ++ ++void PluginJson::StringDeSerialize(const string& data, string& result) ++{ ++ Json::Value root; ++ Json::Reader reader; ++ reader.parse(data, root); ++ ++ result = root["stringData"].asString(); ++} ++ ++void PluginJson::FuncOpJsonDeSerialize( ++ const string& data, vector& funcOpData) ++{ ++ Json::Value root; ++ Json::Reader reader; ++ Json::Value node; ++ reader.parse(data, root); ++ ++ Json::Value::Members operation = root.getMemberNames(); ++ ++ mlir::OpBuilder opBuilder(PluginServer::GetInstance()->GetContext()); ++ ++ for (size_t iter = 0; iter < operation.size(); iter++) { ++ string operationKey = "FunctionOp" + std::to_string(iter); ++ node = root[operationKey]; ++ int64_t id = GetID(node["id"]); ++ Json::Value attributes = node["attributes"]; ++ map funcAttributes; ++ JsonGetAttributes(attributes, funcAttributes); ++ bool declaredInline = false; ++ if (funcAttributes["declaredInline"] == "1") declaredInline = true; ++ auto location = opBuilder.getUnknownLoc(); ++ FunctionOp fOp = opBuilder.create( ++ location, id, funcAttributes["funcName"], declaredInline); ++ mlir::Region &bodyRegion = fOp.bodyRegion(); ++ Json::Value regionJson = node["region"]; ++ Json::Value::Members bbMember = regionJson.getMemberNames(); ++ // We must create Blocks before process ops ++ for (size_t bbIdx = 0; bbIdx < bbMember.size(); bbIdx++) { ++ string blockKey = "block" + std::to_string(bbIdx); ++ Json::Value blockJson = regionJson[blockKey]; ++ mlir::Block* block = opBuilder.createBlock(&bodyRegion); ++ PluginServer::GetInstance()->InsertCreatedBlock( ++ GetID(blockJson["address"]), block); ++ } ++ ++ for (size_t bbIdx = 0; bbIdx < bbMember.size(); bbIdx++) { ++ string blockKey = "block" + std::to_string(bbIdx); ++ Json::Value blockJson = regionJson[blockKey]; ++ uint64_t bbAddress = GetID(blockJson["address"]); ++ mlir::Block* block = PluginServer::GetInstance()->FindBlock(bbAddress); ++ ProcessBlock(block, bodyRegion, blockJson["ops"]); ++ } ++ funcOpData.push_back(fOp); ++ opBuilder.setInsertionPointAfter(fOp.getOperation()); ++ } ++} ++ ++PluginIR::PluginTypeBase PluginJson::TypeJsonDeSerialize(const string& data) ++{ ++ Json::Value root; ++ Json::Reader reader; ++ Json::Value node; ++ reader.parse(data, root); ++ PluginIR::PluginTypeBase baseType; ++ Json::Value type = root["type"]; ++ uint64_t id = GetID(type["id"]); ++ PluginIR::PluginTypeID PluginTypeId = static_cast(id); ++ if (type["signed"] && (id >= static_cast(PluginIR::UIntegerTy1ID) && ++ id <= static_cast(PluginIR::IntegerTy64ID))) { ++ string s = type["signed"].asString(); ++ uint64_t width = GetID(type["width"]); ++ if (s == "1") { ++ baseType = PluginIR::PluginIntegerType::get( ++ PluginServer::GetInstance()->GetContext(), width, PluginIR::PluginIntegerType::Signed); ++ } else { ++ baseType = PluginIR::PluginIntegerType::get( ++ PluginServer::GetInstance()->GetContext(), width, PluginIR::PluginIntegerType::Unsigned); ++ } ++ } else if (type["width"] && (id == static_cast(PluginIR::FloatTyID) || ++ id == static_cast(PluginIR::DoubleTyID))) { ++ uint64_t width = GetID(type["width"]); ++ baseType = PluginIR::PluginFloatType::get(PluginServer::GetInstance()->GetContext(), width); ++ } else if (id == static_cast(PluginIR::PointerTyID)) { ++ mlir::Type elemTy = TypeJsonDeSerialize(type["elementType"].toStyledString()); ++ baseType = PluginIR::PluginPointerType::get( ++ PluginServer::GetInstance()->GetContext(), elemTy, type["elemConst"].asString() == "1" ? 1 : 0); ++ } else { ++ if (PluginTypeId == PluginIR::VoidTyID) { ++ baseType = PluginIR::PluginVoidType::get(PluginServer::GetInstance()->GetContext()); ++ } ++ if (PluginTypeId == PluginIR::BooleanTyID) { ++ baseType = PluginIR::PluginBooleanType::get(PluginServer::GetInstance()->GetContext()); ++ } ++ if (PluginTypeId == PluginIR::UndefTyID) { ++ baseType = PluginIR::PluginUndefType::get(PluginServer::GetInstance()->GetContext()); ++ } ++ } ++ return baseType; ++} ++ ++void PluginJson::LocalDeclOpJsonDeSerialize( ++ const string& data, vector& decls) ++{ ++ Json::Value root; ++ Json::Reader reader; ++ Json::Value node; ++ reader.parse(data, root); ++ Json::Value::Members operation = root.getMemberNames(); ++ mlir::OpBuilder opBuilder(PluginServer::GetInstance()->GetContext()); ++ for (size_t iter = 0; iter < operation.size(); iter++) { ++ string operationKey = "localDecl" + std::to_string(iter); ++ node = root[operationKey]; ++ int64_t id = GetID(node["id"]); ++ Json::Value attributes = node["attributes"]; ++ map declAttributes; ++ JsonGetAttributes(attributes, declAttributes); ++ string symName = declAttributes["symName"]; ++ uint64_t typeID = atol(declAttributes["typeID"].c_str()); ++ uint64_t typeWidth = atol(declAttributes["typeWidth"].c_str()); ++ auto location = opBuilder.getUnknownLoc(); ++ LocalDeclOp op = opBuilder.create( ++ location, id, symName, typeID, typeWidth); ++ decls.push_back(op); ++ } ++} ++ ++void PluginJson::LoopOpsJsonDeSerialize( ++ const string& data, vector& loops) ++{ ++ Json::Value root; ++ Json::Reader reader; ++ Json::Value node; ++ reader.parse(data, root); ++ Json::Value::Members operation = root.getMemberNames(); ++ mlir::OpBuilder builder(PluginServer::GetInstance()->GetContext()); ++ for (size_t iter = 0; iter < operation.size(); iter++) { ++ string operationKey = "loopOp" + std::to_string(iter); ++ node = root[operationKey]; ++ int64_t id = GetID(node["id"]); ++ Json::Value attributes = node["attributes"]; ++ map loopAttributes; ++ JsonGetAttributes(attributes, loopAttributes); ++ uint32_t index = GetID(attributes["index"]); ++ uint64_t innerId = atol(loopAttributes["innerLoopId"].c_str()); ++ uint64_t outerId = atol(loopAttributes["outerLoopId"].c_str()); ++ uint32_t numBlock = atoi(loopAttributes["numBlock"].c_str()); ++ auto location = builder.getUnknownLoc(); ++ LoopOp op = builder.create( ++ location, id, index, innerId, outerId, numBlock); ++ loops.push_back(op); ++ } ++} ++ ++LoopOp PluginJson::LoopOpJsonDeSerialize(const string& data) ++{ ++ Json::Value root; ++ Json::Reader reader; ++ reader.parse(data, root); ++ mlir::OpBuilder builder(PluginServer::GetInstance()->GetContext()); ++ uint64_t id = GetID(root["id"]); ++ Json::Value attributes = root["attributes"]; ++ uint32_t index = GetID(attributes["index"]); ++ uint64_t innerLoopId = GetID(attributes["innerLoopId"]); ++ uint64_t outerLoopId = GetID(attributes["outerLoopId"]); ++ uint32_t numBlock = GetID(attributes["numBlock"]); ++ auto location = builder.getUnknownLoc(); ++ return builder.create( ++ location, id, index, innerLoopId, outerLoopId, numBlock); ++} ++ ++void PluginJson::EdgesJsonDeSerialize( ++ const string& data, vector>& edges) ++{ ++ Json::Value root; ++ Json::Reader reader; ++ Json::Value node; ++ reader.parse(data, root); ++ Json::Value::Members operation = root.getMemberNames(); ++ for (size_t iter = 0; iter < operation.size(); iter++) { ++ string operationKey = "edge" + std::to_string(iter); ++ node = root[operationKey]; ++ uint64_t src = GetID(node["src"]); ++ uint64_t dest = GetID(node["dest"]); ++ std::pair e; ++ if (PluginServer::GetInstance()->HaveBlock(src)) { ++ e.first = PluginServer::GetInstance()->FindBlock(src); ++ } else { ++ e.first = nullptr; ++ } ++ ++ if (PluginServer::GetInstance()->HaveBlock(dest)) { ++ e.second = PluginServer::GetInstance()->FindBlock(dest); ++ } else { ++ e.second = nullptr; ++ } ++ ++ edges.push_back(e); ++ } ++} ++ ++void PluginJson::EdgeJsonDeSerialize( ++ const string& data, std::pair& edge) ++{ ++ Json::Value root; ++ Json::Reader reader; ++ reader.parse(data, root); ++ uint64_t src = GetID(root["src"]); ++ uint64_t dest = GetID(root["dest"]); ++ if (PluginServer::GetInstance()->HaveBlock(src)) { ++ edge.first = PluginServer::GetInstance()->FindBlock(src); ++ } else { ++ edge.first = nullptr; ++ } ++ ++ if (PluginServer::GetInstance()->HaveBlock(dest)) { ++ edge.second = PluginServer::GetInstance()->FindBlock(dest); ++ } else { ++ edge.second = nullptr; ++ } ++} ++ ++void PluginJson::IdsJsonDeSerialize( ++ const string& data, vector& idsResult) ++{ ++ Json::Value root; ++ Json::Reader reader; ++ Json::Value node; ++ reader.parse(data, root); ++ Json::Value::Members operation = root.getMemberNames(); ++ for (size_t iter = 0; iter < operation.size(); iter++) { ++ string operationKey = "block" + std::to_string(iter); ++ node = root[operationKey]; ++ uint64_t id = GetID(node["id"]); ++ idsResult.push_back(id); ++ } ++} ++ ++mlir::Operation *PluginJson::CallOpJsonDeSerialize(const string& data) ++{ ++ Json::Value node; ++ Json::Reader reader; ++ reader.parse(data, node); ++ Json::Value operandJson = node["operands"]; ++ Json::Value::Members operandMember = operandJson.getMemberNames(); ++ llvm::SmallVector ops; ++ for (size_t opIter = 0; opIter < operandMember.size(); opIter++) { ++ string key = "input" + std::to_string(opIter); ++ mlir::Value opValue = ValueJsonDeSerialize(operandJson[key.c_str()]); ++ ops.push_back(opValue); ++ } ++ int64_t id = GetID(node["id"]); ++ mlir::StringRef callName(node["callee"].asString()); ++ mlir::OpBuilder *opBuilder = PluginServer::GetInstance()->GetOpBuilder(); ++ CallOp op = opBuilder->create(opBuilder->getUnknownLoc(), ++ id, callName, ops); ++ return op.getOperation(); ++} ++ ++mlir::Operation *PluginJson::CondOpJsonDeSerialize(const string& data) ++{ ++ Json::Value node; ++ Json::Reader reader; ++ reader.parse(data, node); ++ mlir::Value LHS = ValueJsonDeSerialize(node["lhs"]); ++ mlir::Value RHS = ValueJsonDeSerialize(node["rhs"]); ++ mlir::Value trueLabel = nullptr; ++ mlir::Value falseLabel = nullptr; ++ int64_t id = GetID(node["id"]); ++ int64_t address = GetID(node["address"]); ++ int64_t tbaddr = GetID(node["tbaddr"]); ++ int64_t fbaddr = GetID(node["fbaddr"]); ++ mlir::Block* tb = PluginServer::GetInstance()->FindBlock(tbaddr); ++ mlir::Block* fb = PluginServer::GetInstance()->FindBlock(fbaddr); ++ IComparisonCode iCode = IComparisonCode( ++ atoi(node["condCode"].asString().c_str())); ++ mlir::OpBuilder *opBuilder = PluginServer::GetInstance()->GetOpBuilder(); ++ CondOp op = opBuilder->create( ++ opBuilder->getUnknownLoc(), id, address, iCode, LHS, ++ RHS, tb, fb, tbaddr, fbaddr, trueLabel, falseLabel); ++ return op.getOperation(); ++} ++ ++mlir::Operation *PluginJson::RetOpJsonDeSerialize(const string& data) ++{ ++ Json::Value node; ++ Json::Reader reader; ++ reader.parse(data, node); ++ int64_t address = GetID(node["address"]); ++ mlir::OpBuilder *opBuilder = PluginServer::GetInstance()->GetOpBuilder(); ++ RetOp op = opBuilder->create(opBuilder->getUnknownLoc(), address); ++ return op.getOperation(); ++} ++ ++mlir::Operation *PluginJson::FallThroughOpJsonDeSerialize(const string& data) ++{ ++ Json::Value node; ++ Json::Reader reader; ++ reader.parse(data, node); ++ int64_t address = GetID(node["address"]); ++ int64_t destaddr = GetID(node["destaddr"]); ++ mlir::Block* succ = PluginServer::GetInstance()->FindBlock(destaddr); ++ mlir::OpBuilder *opBuilder = PluginServer::GetInstance()->GetOpBuilder(); ++ FallThroughOp op = opBuilder->create(opBuilder->getUnknownLoc(), ++ address, succ, destaddr); ++ return op.getOperation(); ++} ++ ++mlir::Operation *PluginJson::AssignOpJsonDeSerialize(const string& data) ++{ ++ Json::Value node; ++ Json::Reader reader; ++ reader.parse(data, node); ++ Json::Value operandJson = node["operands"]; ++ Json::Value::Members operandMember = operandJson.getMemberNames(); ++ llvm::SmallVector ops; ++ for (size_t opIter = 0; opIter < operandMember.size(); opIter++) { ++ string key = "input" + std::to_string(opIter); ++ mlir::Value opValue = ValueJsonDeSerialize(operandJson[key.c_str()]); ++ ops.push_back(opValue); ++ } ++ uint64_t id = GetID(node["id"]); ++ IExprCode iCode = IExprCode(atoi(node["exprCode"].asString().c_str())); ++ mlir::OpBuilder *opBuilder = PluginServer::GetInstance()->GetOpBuilder(); ++ AssignOp op = opBuilder->create(opBuilder->getUnknownLoc(), ++ ops, id, iCode); ++ PluginServer::GetInstance()->InsertDefOperation(id, op.getOperation()); ++ return op.getOperation(); ++} ++ ++mlir::Operation *PluginJson::PhiOpJsonDeSerialize(const string& data) ++{ ++ Json::Value node; ++ Json::Reader reader; ++ reader.parse(data, node); ++ Json::Value operandJson = node["operands"]; ++ Json::Value::Members operandMember = operandJson.getMemberNames(); ++ llvm::SmallVector ops; ++ for (size_t opIter = 0; opIter < operandMember.size(); opIter++) { ++ string key = "input" + std::to_string(opIter); ++ mlir::Value opValue = ValueJsonDeSerialize(operandJson[key.c_str()]); ++ ops.push_back(opValue); ++ } ++ uint64_t id = GetID(node["id"]); ++ uint32_t capacity = GetID(node["capacity"]); ++ uint32_t nArgs = GetID(node["nArgs"]); ++ mlir::OpBuilder *opBuilder = PluginServer::GetInstance()->GetOpBuilder(); ++ PhiOp op = opBuilder->create(opBuilder->getUnknownLoc(), ++ ops, id, capacity, nArgs); ++ ++ PluginServer::GetInstance()->InsertDefOperation(id, op.getOperation()); ++ return op.getOperation(); ++} ++ ++void PluginJson::GetPhiOpsJsonDeSerialize( ++ const string& data, vector& opData) ++{ ++ opData.clear(); ++ Json::Value root; ++ Json::Reader reader; ++ Json::Value node; ++ reader.parse(data, root); ++ ++ Json::Value::Members operation = root.getMemberNames(); ++ for (size_t iter = 0; iter < operation.size(); iter++) { ++ string operationKey = "operation" + std::to_string(iter); ++ node = root[operationKey]; ++ opData.push_back(PhiOpJsonDeSerialize(node.toStyledString())); ++ } ++} ++ ++void PluginJson::OpJsonDeSerialize( ++ const string& data, vector& opData) ++{ ++ Json::Value opJson; ++ Json::Reader reader; ++ Json::Value node; ++ reader.parse(data, opJson); ++ string opCode = opJson["OperationName"].asString(); ++ if (opCode == PhiOp::getOperationName().str()) { ++ opData.push_back(PhiOpJsonDeSerialize(opJson.toStyledString())); ++ } else if (opCode == CallOp::getOperationName().str()) { ++ opData.push_back(CallOpJsonDeSerialize(opJson.toStyledString())); ++ } else if (opCode == AssignOp::getOperationName().str()) { ++ opData.push_back(AssignOpJsonDeSerialize(opJson.toStyledString())); ++ } else if (opCode == CondOp::getOperationName().str()) { ++ opData.push_back(CondOpJsonDeSerialize(opJson.toStyledString())); ++ } else if (opCode == RetOp::getOperationName().str()) { ++ opData.push_back(RetOpJsonDeSerialize(opJson.toStyledString())); ++ } else if (opCode == FallThroughOp::getOperationName().str()) { ++ opData.push_back(FallThroughOpJsonDeSerialize(opJson.toStyledString())); ++ } else if (opCode == BaseOp::getOperationName().str()) { ++ uint64_t opID = GetID(opJson["id"]); ++ mlir::OpBuilder *opBuilder = PluginServer::GetInstance()->GetOpBuilder(); ++ opBuilder->create(opBuilder->getUnknownLoc(), opID, opCode); ++ } ++} ++} // namespace PinJson +\ No newline at end of file +diff --git a/lib/PluginServer/PluginLog.cpp b/lib/PluginServer/PluginLog.cpp +index 970fca2..9c0a08f 100644 +--- a/lib/PluginServer/PluginLog.cpp ++++ b/lib/PluginServer/PluginLog.cpp +@@ -18,108 +18,160 @@ + This file contains the implementation of the Plugin_Log class. + */ + ++#include + #include + #include + #include + #include +-#include + #include + #include + #include "PluginServer/PluginLog.h" + +-namespace PinServer { +-using namespace std; +-using std::string; +-constexpr int LOG_BUF_SIZE = 102400; +-constexpr int BASE_DATE = 1900; +-static LogPriority g_priority = PRIORITY_WARN; // log打印的级别控制 ++namespace PinLog { + static std::mutex g_mutex; // 线程锁 +-static char g_buf[LOG_BUF_SIZE]; ++PluginLog g_pluginLog; ++const int LOG_DEFAULT_SIZE = 10 * 1024 * 1024; + +-shared_ptr g_fs; +-static void LogWriteInit(const string& data); +-static void (*g_writeToLog)(const string& data) = LogWriteInit; ++PluginLog::PluginLog() ++{ ++ priority = PRIORITY_WARN; ++ logFileSize = LOG_DEFAULT_SIZE; ++} ++ ++PluginLog *PluginLog::GetInstance() ++{ ++ return &g_pluginLog; ++} + +-static void GetLogFileName(string& fileName) ++void PluginLog::GetLogFileName(string& fileName) + { + time_t nowTime = time(nullptr); ++ if (nowTime == -1) { ++ printf("%s fail\n", __func__); ++ } + struct tm *t = localtime(&nowTime); + char buf[100]; +- sprintf(buf, "/tmp/pin_server%d_%4d%02d%02d_%02d_%02d_%02d.log", getppid(), ++ int ret = sprintf(buf, "/tmp/pin_server%d_%4d%02d%02d_%02d_%02d_%02d.log", getppid(), + t->tm_year + BASE_DATE, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec); ++ if (ret < 0) { ++ printf("%s sprintf fail\n", __func__); ++ } + fileName = buf; + } + +-static void LogWriteFile(const string& data) ++void PluginLog::LogWriteFile(const string& data) + { +- if (g_fs->tellg() > LOG_FILE_SIZE) { +- g_fs->close(); +- string fileName; ++ string fileName; ++ if (logFs == nullptr) { ++ logFs = std::make_shared(); + GetLogFileName(fileName); +- g_fs->open(fileName.c_str(), ios::app); ++ logFs->open(fileName.c_str(), std::ios::app); + } + +- g_fs->write(data.c_str(), data.size()); +-} +- +-static void LogWriteInit(const string& data) +-{ +- if (g_writeToLog == LogWriteInit) { +- g_fs = std::make_shared(); +- string fileName; ++ if (logFs->tellg() > logFileSize) { ++ logFs->close(); + GetLogFileName(fileName); +- g_fs->open(fileName.c_str(), ios::app); +- g_writeToLog = LogWriteFile; ++ logFs->open(fileName.c_str(), std::ios::app); + } +- g_writeToLog(data); ++ ++ logFs->write(data.c_str(), data.size()); + } + +-void CloseLog(void) ++void PluginLog::CloseLog() + { +- if (g_fs) { +- if (g_fs->is_open()) { +- g_fs->close(); ++ if (logFs) { ++ if (logFs->is_open()) { ++ logFs->close(); ++ logFs = nullptr; + } + } + } + +-static void LogWrite(const char *tag, const char *msg) ++void PluginLog::LogWrite(const char *tag, const char *msg) + { + time_t nowTime = time(nullptr); ++ if (nowTime == -1) { ++ printf("%s fail\n", __func__); ++ } + struct tm *t = localtime(&nowTime); + char buf[30]; +- sprintf(buf, "%4d-%02d-%02d %02d:%02d:%02d ", t->tm_year + BASE_DATE, t->tm_mon + 1, t->tm_mday, ++ int ret = sprintf(buf, "%4d-%02d-%02d %02d:%02d:%02d ", t->tm_year + BASE_DATE, t->tm_mon + 1, t->tm_mday, + t->tm_hour, t->tm_min, t->tm_sec); +- ++ if (ret < 0) { ++ printf("%s sprintf fail\n", __func__); ++ } + string stag = tag; + string smsg = msg; + string data = buf + stag + smsg; +- g_writeToLog(data); ++ LogWriteFile(data); ++} ++ ++void PluginLog::LogPrint(LogPriority pri, const char *tag, const char *buf) ++{ ++ if (pri <= priority) { ++ printf("%s%s", tag, buf); ++ } ++ ++ g_mutex.lock(); ++ LogWrite(tag, buf); ++ g_mutex.unlock(); + } + +-void LogPrint(LogPriority priority, const char *tag, const char *fmt, ...) ++void PluginLog::LOGE(const char *fmt, ...) + { + va_list ap; ++ va_start(ap, fmt); ++ int ret = vsnprintf(logBuf, LOG_BUF_SIZE, fmt, ap); ++ if (ret < 0) { ++ printf("%s vsnprintf fail\n", __func__); ++ } ++ va_end(ap); ++ ++ LogPrint(PRIORITY_ERROR, "ERROR:", logBuf); ++} + ++void PluginLog::LOGW(const char *fmt, ...) ++{ ++ va_list ap; + va_start(ap, fmt); +- vsnprintf(g_buf, LOG_BUF_SIZE, fmt, ap); ++ int ret = vsnprintf(logBuf, LOG_BUF_SIZE, fmt, ap); ++ if (ret < 0) { ++ printf("%s vsnprintf fail\n", __func__); ++ } + va_end(ap); ++ LogPrint(PRIORITY_WARN, "WARN:", logBuf); ++} + +- if (priority <= g_priority) { +- printf("%s%s", tag, g_buf); ++void PluginLog::LOGI(const char *fmt, ...) ++{ ++ va_list ap; ++ va_start(ap, fmt); ++ int ret = vsnprintf(logBuf, LOG_BUF_SIZE, fmt, ap); ++ if (ret < 0) { ++ printf("%s vsnprintf fail\n", __func__); + } ++ va_end(ap); ++ LogPrint(PRIORITY_INFO, "INFO:", logBuf); ++} + +- g_mutex.lock(); +- LogWrite(tag, g_buf); +- g_mutex.unlock(); ++void PluginLog::LOGD(const char *fmt, ...) ++{ ++ va_list ap; ++ va_start(ap, fmt); ++ int ret = vsnprintf(logBuf, LOG_BUF_SIZE, fmt, ap); ++ if (ret < 0) { ++ printf("%s vsnprintf fail\n", __func__); ++ } ++ va_end(ap); ++ LogPrint(PRIORITY_DEBUG, "DEBUG:", logBuf); + } + +-bool SetLogPriority(LogPriority priority) ++bool PluginLog::SetPriority(LogPriority pri) + { +- if (priority > PRIORITY_DEBUG) { ++ if (pri > PRIORITY_DEBUG) { + return false; + } +- g_priority = priority; ++ priority = pri; + return true; + } +-} // namespace PinServer ++} // namespace PinLog +diff --git a/lib/PluginServer/PluginServer.cpp b/lib/PluginServer/PluginServer.cpp +index 7ebc15d..05d0d3d 100644 +--- a/lib/PluginServer/PluginServer.cpp ++++ b/lib/PluginServer/PluginServer.cpp +@@ -18,94 +18,56 @@ + This file contains the implementation of the client PluginServer class. + */ + +-#include +-#include + #include + #include + #include ++#include ++#include + +-#include "Dialect/PluginDialect.h" + #include "PluginAPI/PluginServerAPI.h" +-#include "mlir/IR/Attributes.h" +-#include "mlir/IR/BuiltinOps.h" +-#include "mlir/IR/BuiltinTypes.h" +-#include "user.h" +-#include "PluginServer/PluginLog.h" ++#include "user/user.h" + #include "PluginServer/PluginServer.h" +-#include "Dialect/PluginTypes.h" + + namespace PinServer { + using namespace mlir::Plugin; ++using namespace PluginOpt; + using std::cout; + using std::endl; + using std::pair; +-static std::unique_ptr g_server; // grpc对象指针 +-static PluginServer g_service; // 插件server对象 +- +-PluginServer *PluginServer::GetInstance(void) ++PluginServer *PluginServer::pluginServerPtr = nullptr; ++PluginServer *PluginServer::GetInstance() + { +- return &g_service; ++ return pluginServerPtr; + } + +-int PluginServer::RegisterUserFunc(InjectPoint inject, UserFunc func) ++bool PluginServer::RegisterOpt(std::shared_ptr optBase) + { +- if ((inject >= HANDLE_MAX) || (func == nullptr)) { +- return -1; ++ InjectPoint inject = optBase->GetInject(); ++ if ((inject >= HANDLE_MAX) || (optBase == nullptr)) { ++ return false; + } +- string name = "funcname" + std::to_string((uint64_t)&func); +- userFunc[inject].push_back(RecordedUserFunc(name, func)); +- return 0; ++ ++ string name = "funcname" + std::to_string((uintptr_t)optBase.get()); ++ userOpts[inject].push_back(RecordedOpt(name, optBase)); ++ this->context = optBase->GetContext(); ++ mlir::OpBuilder opBuilder_temp = mlir::OpBuilder(context); ++ opBuilder = &opBuilder_temp; ++ return true; + } + +-int PluginServer::RegisterPassManagerSetup(InjectPoint inject, const ManagerSetupData& setupData, UserFunc func) ++bool PluginServer::RegisterPassManagerOpt(ManagerSetup& setupData, std::shared_ptr optBase) + { +- if (inject != HANDLE_MANAGER_SETUP) { +- return -1; +- } +- + Json::Value root; +- root["refPassName"] = setupData.refPassName; +- root["passNum"] = setupData.passNum; +- root["passPosition"] = setupData.passPosition; ++ root["refPassName"] = setupData.GetPassName(); ++ root["passNum"] = setupData.GetPassNum(); ++ root["passPosition"] = setupData.GetPassPosition(); + string params = root.toStyledString(); +- +- userFunc[inject].push_back(RecordedUserFunc(params, func)); +- return 0; +-} +- +-vector PluginServer::GetOpResult(void) +-{ +- vector retOps = opData; +- opData.clear(); +- return retOps; +-} +- +-vector PluginServer::GetFunctionOpResult(void) +-{ +- vector retOps = funcOpData; +- funcOpData.clear(); +- opData.clear(); +- return retOps; +-} +- +-vector PluginServer::GetLocalDeclResult() +-{ +- vector retOps = decls; +- decls.clear(); +- return retOps; +-} +- +-vector PluginServer::LoopOpsResult() +-{ +- vector retLoops = loops; +- loops.clear(); +- return retLoops; +-} +- +-LoopOp PluginServer::LoopOpResult() +-{ +- mlir::Plugin::LoopOp retLoop = loop; +- return retLoop; ++ string name = "funcname" + std::to_string((uintptr_t)optBase.get()); ++ userOpts[HANDLE_MANAGER_SETUP].push_back(RecordedOpt(name, params, optBase)); ++ this->context = optBase->GetContext(); ++ static mlir::OpBuilder opBuilder_temp = mlir::OpBuilder(context); ++ opBuilder = &opBuilder_temp; ++ return true; + } + + void PluginServer::EraseBlock(mlir::Block* b) +@@ -113,7 +75,6 @@ void PluginServer::EraseBlock(mlir::Block* b) + if (auto bbit = basicblockMaps.find(b); bbit != basicblockMaps.end()) { + uint64_t addr = bbit->second; + basicblockMaps[b] = 0; +- // basicblockMaps.erase(bbit); + if (auto bit = blockMaps.find(addr); bit != blockMaps.end()) { + blockMaps.erase(bit); + } +@@ -134,13 +95,23 @@ mlir::Operation* PluginServer::FindDefOperation(uint64_t id) + return iter->second; + } + ++bool PluginServer::InsertDefOperation(uint64_t id, mlir::Operation* op) ++{ ++ auto iter = this->defOpMaps.find(id); ++ this->defOpMaps.insert({id, op}); ++ return true; ++} ++ + void PluginServer::InsertCreatedBlock(uint64_t id, mlir::Block* block) + { + this->blockMaps.insert({id, block}); ++ this->basicblockMaps.insert({block, id}); + } ++ + uint64_t PluginServer::GetBlockResult(mlir::Block* b) + { +- uint64_t newAddr = GetIdResult(); ++ uint64_t newAddr = pluginCom.GetIdResult(); ++ mlir::OpBuilder opBuilder = mlir::OpBuilder(this->context); + mlir::Block* block = opBuilder.createBlock(b); + this->blockMaps.insert({newAddr, block}); + this->basicblockMaps.insert({block, newAddr}); +@@ -162,693 +133,84 @@ bool PluginServer::InsertValue(uint64_t id, mlir::Value v) + return true; + } + +-pair PluginServer::EdgeResult() +-{ +- pair e; +- e.first = edge.first; +- e.second = edge.second; +- return e; +-} +- +-vector > PluginServer::EdgesResult() +-{ +- vector > retEdges; +- retEdges = edges; +- edges.clear(); +- return retEdges; +-} +- +-bool PluginServer::GetBoolResult() +-{ +- return this->boolResult; +-} +- +-uint64_t PluginServer::GetIdResult() +-{ +- return this->idResult; +-} +- +-vector PluginServer::GetIdsResult() +-{ +- vector retIds = idsResult; +- idsResult.clear(); +- return retIds; +-} +- +-mlir::Value PluginServer::GetValueResult() ++bool PluginServer::HaveValue(uint64_t id) + { +- return this->valueResult; ++ return this->valueMaps.find(id) != this->valueMaps.end(); + } + +-vector PluginServer::GetPhiOpsResult() ++mlir::Value PluginServer::GetValue(uint64_t id) + { +- vector retOps; +- for (auto item : opData) { +- PhiOp p = llvm::dyn_cast(item); +- retOps.push_back(p); +- } +- opData.clear(); +- return retOps; ++ auto iter = this->valueMaps.find(id); ++ assert(iter != this->valueMaps.end()); ++ return iter->second; + } + +-void PluginServer::JsonGetAttributes(Json::Value node, map& attributes) ++void PluginServer::RemoteCallClientWithAPI(const string& api, const string& params) + { +- Json::Value::Members attMember = node.getMemberNames(); +- for (unsigned int i = 0; i < attMember.size(); i++) { +- string key = attMember[i]; +- string value = node[key.c_str()].asString(); +- attributes[key] = value; ++ if (api == "") { ++ return; + } +-} + +-static uintptr_t GetID(Json::Value node) +-{ +- string id = node.asString(); +- return atol(id.c_str()); +-} +- +-mlir::Value PluginServer::ValueJsonDeSerialize(Json::Value valueJson) +-{ +- uint64_t opId = GetID(valueJson["id"]); +- auto iter = this->valueMaps.find(opId); +- if (iter != this->valueMaps.end()) { +- return iter->second; +- } +- IDefineCode defCode = IDefineCode( +- atoi(valueJson["defCode"].asString().c_str())); +- mlir::Type retType = TypeJsonDeSerialize( +- valueJson["retType"].toStyledString()); +- bool readOnly = GetID(valueJson["readOnly"]); +- mlir::Value opValue; +- switch (defCode) { +- case IDefineCode::MemRef : { +- opValue = MemRefDeSerialize(valueJson.toStyledString()); +- break; +- } +- case IDefineCode::IntCST : { +- uint64_t init = GetID(valueJson["value"]); +- // FIXME : AnyAttr! +- mlir::Attribute initAttr = opBuilder.getI64IntegerAttr(init); +- opValue = opBuilder.create( +- opBuilder.getUnknownLoc(), opId, IDefineCode::IntCST, +- readOnly, initAttr, retType); +- break; +- } +- case IDefineCode::SSA : { +- opValue = SSAOpJsonDeSerialize(valueJson.toStyledString()); +- break; +- } +- default: { +- opValue = opBuilder.create( +- opBuilder.getUnknownLoc(), opId, defCode, readOnly, retType); ++ apiFuncName = api; ++ apiFuncParams = params; ++ userFunState = STATE_BEGIN; ++ sem_post(&clientWaitSem); ++ while (1) { ++ sem_wait(&clientReturnSem); ++ if (userFunState == STATE_RETURN) { // wait client result ++ userFunState = STATE_WAIT_BEGIN; + break; + } + } +- this->valueMaps.insert({opId, opValue}); +- return opValue; +-} +- +-mlir::Value PluginServer::MemRefDeSerialize(const string& data) +-{ +- Json::Value root; +- Json::Reader reader; +- reader.parse(data, root); +- uint64_t id = GetID(root["id"]); +- bool readOnly = (bool)atoi(root["readOnly"].asString().c_str()); +- mlir::Value base = ValueJsonDeSerialize(root["base"]); +- mlir::Value offset = ValueJsonDeSerialize(root["offset"]); +- mlir::Type retType = TypeJsonDeSerialize(root["retType"].toStyledString().c_str()); +- mlir::Value memRef = opBuilder.create(opBuilder.getUnknownLoc(), id, +- IDefineCode::MemRef, readOnly, base, offset, retType); +- return memRef; +-} +- +-void PluginServer::JsonDeSerialize(const string& key, const string& data) +-{ +- if (key == "FuncOpResult") { +- FuncOpJsonDeSerialize(data); +- } else if (key == "LocalDeclOpResult") { +- LocalDeclOpJsonDeSerialize(data); +- } else if (key == "LoopOpResult") { +- LoopOpJsonDeSerialize (data); +- } else if (key == "LoopOpsResult") { +- LoopOpsJsonDeSerialize (data); +- } else if (key == "BoolResult") { +- this->boolResult = (bool)atol(data.c_str()); +- } else if (key == "VoidResult") { +- ; +- } else if (key == "EdgeResult") { +- EdgeJsonDeSerialize(data); +- } else if (key == "EdgesResult") { +- EdgesJsonDeSerialize(data); +- } else if (key == "IdsResult") { +- IdsJsonDeSerialize(data); +- } else if (key == "IdResult") { +- this->idResult = atol(data.c_str()); +- } else if (key == "OpsResult") { +- OpJsonDeSerialize(data.c_str()); +- } else if (key == "ValueResult") { +- Json::Value node; +- Json::Reader reader; +- reader.parse(data, node); +- this->valueResult = ValueJsonDeSerialize(node); +- } else if (key == "GetPhiOps") { +- GetPhiOpsJsonDeSerialize(data); +- } else { +- cout << "not Json,key:" << key << ",value:" << data << endl; +- } +-} +- +-Json::Value PluginServer::TypeJsonSerialize (PluginIR::PluginTypeBase& type) +-{ +- Json::Value root; +- Json::Value operationObj; +- Json::Value item; +- +- uint64_t ReTypeId; +- uint64_t ReTypeWidth; +- +- 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 (elemTy.isReadOnlyElem()) { +- item["elemConst"] = "1"; +- }else { +- item["elemConst"] = "0"; +- } +- } +- +- if (type.getPluginIntOrFloatBitWidth() != 0) { +- ReTypeWidth = type.getPluginIntOrFloatBitWidth(); +- item["width"] = std::to_string(ReTypeWidth); +- } +- +- if (type.isSignedPluginInteger()) { +- item["signed"] = "1"; +- } +- +- if (type.isUnsignedPluginInteger()) { +- item["signed"] = "0"; +- } +- +- root["type"] = item; +- return root; +-} +- +-PluginIR::PluginTypeBase PluginServer::TypeJsonDeSerialize(const string& data) +-{ +- Json::Value root; +- Json::Reader reader; +- Json::Value node; +- reader.parse(data, root); +- +- PluginIR::PluginTypeBase baseType; +- +- Json::Value type = root["type"]; +- uint64_t id = GetID(type["id"]); +- PluginIR::PluginTypeID PluginTypeId = static_cast(id); +- +- if (type["signed"] && (id >= static_cast(PluginIR::UIntegerTy1ID) && id <= static_cast(PluginIR::IntegerTy64ID))) { +- string s = type["signed"].asString(); +- uint64_t width = GetID(type["width"]); +- if (s == "1") { +- baseType = PluginIR::PluginIntegerType::get(&context, width, PluginIR::PluginIntegerType::Signed); +- } +- else { +- baseType = PluginIR::PluginIntegerType::get(&context, width, PluginIR::PluginIntegerType::Unsigned); +- } +- } +- else if (type["width"] && (id == static_cast(PluginIR::FloatTyID) || id == static_cast(PluginIR::DoubleTyID)) ) { +- uint64_t width = GetID(type["width"]); +- baseType = PluginIR::PluginFloatType::get(&context, width); +- }else if (id == static_cast(PluginIR::PointerTyID)) { +- mlir::Type elemTy = TypeJsonDeSerialize(type["elementType"].toStyledString()); +- baseType = PluginIR::PluginPointerType::get(&context, elemTy, type["elemConst"].asString() == "1" ? 1 : 0); +- }else { +- if (PluginTypeId == PluginIR::VoidTyID) +- baseType = PluginIR::PluginVoidType::get(&context); +- if (PluginTypeId == PluginIR::BooleanTyID) +- baseType = PluginIR::PluginBooleanType::get(&context); +- if (PluginTypeId == PluginIR::UndefTyID) +- baseType = PluginIR::PluginUndefType::get(&context); +- } +- +- pluginType = baseType; +- return baseType; +-} +- +-bool PluginServer::ProcessBlock(mlir::Block* block, mlir::Region& rg, +- const Json::Value& blockJson) +-{ +- if (blockJson.isNull()) { +- return false; +- } +- // todo process func return type +- // todo isDeclaration +- +- // process each stmt +- opBuilder.setInsertionPointToStart(block); +- Json::Value::Members opMember = blockJson.getMemberNames(); +- for (size_t opIdx = 0; opIdx < opMember.size(); opIdx++) { +- string baseOpKey = "Operation" + std::to_string(opIdx); +- Json::Value opJson = blockJson[baseOpKey]; +- if (opJson.isNull()) continue; +- string opCode = opJson["OperationName"].asString(); +- if (opCode == PhiOp::getOperationName().str()) { +- PhiOpJsonDeSerialize(opJson.toStyledString()); +- } else if (opCode == CallOp::getOperationName().str()) { +- CallOpJsonDeSerialize(opJson.toStyledString()); +- } else if (opCode == AssignOp::getOperationName().str()) { +- AssignOpJsonDeSerialize(opJson.toStyledString()); +- } else if (opCode == CondOp::getOperationName().str()) { +- CondOpJsonDeSerialize(opJson.toStyledString()); +- } else if (opCode == RetOp::getOperationName().str()) { +- RetOpJsonDeSerialize(opJson.toStyledString()); +- } else if (opCode == FallThroughOp::getOperationName().str()) { +- FallThroughOpJsonDeSerialize(opJson.toStyledString()); +- } else if (opCode == BaseOp::getOperationName().str()) { +- uint64_t opID = GetID(opJson["id"]); +- opBuilder.create(opBuilder.getUnknownLoc(), opID, opCode); +- } +- } +- // fprintf(stderr, "[bb] op:%ld, succ: %d\n", block->getOperations().size(), block->getNumSuccessors()); +- return true; +-} +- +-void PluginServer::OpJsonDeSerialize(const string& data) +-{ +- Json::Value opJson; +- Json::Reader reader; +- Json::Value node; +- reader.parse(data, opJson); +- string opCode = opJson["OperationName"].asString(); +- if (opCode == PhiOp::getOperationName().str()) { +- PhiOpJsonDeSerialize(opJson.toStyledString()); +- } else if (opCode == CallOp::getOperationName().str()) { +- CallOpJsonDeSerialize(opJson.toStyledString()); +- } else if (opCode == AssignOp::getOperationName().str()) { +- AssignOpJsonDeSerialize(opJson.toStyledString()); +- } else if (opCode == CondOp::getOperationName().str()) { +- CondOpJsonDeSerialize(opJson.toStyledString()); +- } else if (opCode == RetOp::getOperationName().str()) { +- RetOpJsonDeSerialize(opJson.toStyledString()); +- } else if (opCode == FallThroughOp::getOperationName().str()) { +- FallThroughOpJsonDeSerialize(opJson.toStyledString()); +- } else if (opCode == BaseOp::getOperationName().str()) { +- uint64_t opID = GetID(opJson["id"]); +- opBuilder.create(opBuilder.getUnknownLoc(), opID, opCode); +- } +-} +- +-void PluginServer::FuncOpJsonDeSerialize(const string& data) +-{ +- Json::Value root; +- Json::Reader reader; +- Json::Value node; +- reader.parse(data, root); +- +- Json::Value::Members operation = root.getMemberNames(); +- +- context.getOrLoadDialect(); +- opBuilder = mlir::OpBuilder(&context); +- for (size_t iter = 0; iter < operation.size(); iter++) { +- string operationKey = "FunctionOp" + std::to_string(iter); +- node = root[operationKey]; +- int64_t id = GetID(node["id"]); +- Json::Value attributes = node["attributes"]; +- map funcAttributes; +- JsonGetAttributes(attributes, funcAttributes); +- bool declaredInline = false; +- if (funcAttributes["declaredInline"] == "1") declaredInline = true; +- auto location = opBuilder.getUnknownLoc(); +- FunctionOp fOp = opBuilder.create( +- location, id, funcAttributes["funcName"], declaredInline); +- mlir::Region &bodyRegion = fOp.bodyRegion(); +- Json::Value regionJson = node["region"]; +- Json::Value::Members bbMember = regionJson.getMemberNames(); +- // We must create Blocks before process ops +- for (size_t bbIdx = 0; bbIdx < bbMember.size(); bbIdx++) { +- string blockKey = "block" + std::to_string(bbIdx); +- Json::Value blockJson = regionJson[blockKey]; +- mlir::Block* block = opBuilder.createBlock(&bodyRegion); +- this->blockMaps.insert({GetID(blockJson["address"]), block}); +- this->basicblockMaps.insert({block, GetID(blockJson["address"])}); +- } +- +- for (size_t bbIdx = 0; bbIdx < bbMember.size(); bbIdx++) { +- string blockKey = "block" + std::to_string(bbIdx); +- Json::Value blockJson = regionJson[blockKey]; +- uint64_t bbAddress = GetID(blockJson["address"]); +- ProcessBlock(this->blockMaps[bbAddress], bodyRegion, blockJson["ops"]); +- } +- funcOpData.push_back(fOp); +- opBuilder.setInsertionPointAfter(fOp.getOperation()); +- } +-} +- +-void PluginServer::LocalDeclOpJsonDeSerialize(const string& data) +-{ +- Json::Value root; +- Json::Reader reader; +- Json::Value node; +- reader.parse(data, root); +- +- Json::Value::Members operation = root.getMemberNames(); +- +- context.getOrLoadDialect(); +- opBuilder = mlir::OpBuilder(&context); +- for (size_t iter = 0; iter < operation.size(); iter++) { +- string operationKey = "localDecl" + std::to_string(iter); +- node = root[operationKey]; +- int64_t id = GetID(node["id"]); +- Json::Value attributes = node["attributes"]; +- map declAttributes; +- JsonGetAttributes(attributes, declAttributes); +- string symName = declAttributes["symName"]; +- uint64_t typeID = atol(declAttributes["typeID"].c_str()); +- uint64_t typeWidth = atol(declAttributes["typeWidth"].c_str()); +- auto location = opBuilder.getUnknownLoc(); +- LocalDeclOp op = opBuilder.create(location, id, symName, typeID, typeWidth); +- decls.push_back(op); +- } +-} +-void PluginServer::LoopOpsJsonDeSerialize(const string& data) +-{ +- Json::Value root; +- Json::Reader reader; +- Json::Value node; +- reader.parse(data, root); +- +- Json::Value::Members operation = root.getMemberNames(); +- context.getOrLoadDialect(); +- mlir::OpBuilder builder(&context); +- for (size_t iter = 0; iter < operation.size(); iter++) { +- string operationKey = "loopOp" + std::to_string(iter); +- node = root[operationKey]; +- int64_t id = GetID(node["id"]); +- Json::Value attributes = node["attributes"]; +- map loopAttributes; +- JsonGetAttributes(attributes, loopAttributes); +- uint32_t index = GetID(attributes["index"]); +- uint64_t innerId = atol(loopAttributes["innerLoopId"].c_str()); +- uint64_t outerId = atol(loopAttributes["outerLoopId"].c_str()); +- uint32_t numBlock = atoi(loopAttributes["numBlock"].c_str()); +- auto location = builder.getUnknownLoc(); +- LoopOp op = builder.create(location, id, index, innerId, outerId, numBlock); +- loops.push_back(op); +- } +-} +- +-void PluginServer::LoopOpJsonDeSerialize(const string& data) +-{ +- Json::Value root; +- Json::Reader reader; +- reader.parse(data, root); +- +- context.getOrLoadDialect(); +- mlir::OpBuilder builder(&context); +- +- uint64_t id = GetID(root["id"]); +- Json::Value attributes = root["attributes"]; +- uint32_t index = GetID(attributes["index"]); +- uint64_t innerLoopId = GetID(attributes["innerLoopId"]); +- uint64_t outerLoopId = GetID(attributes["outerLoopId"]); +- uint32_t numBlock = GetID(attributes["numBlock"]); +- auto location = builder.getUnknownLoc(); +- loop = builder.create(location, id, index, innerLoopId, outerLoopId, numBlock); +-} +- +-void PluginServer::EdgesJsonDeSerialize(const string& data) +-{ +- Json::Value root; +- Json::Reader reader; +- Json::Value node; +- reader.parse(data, root); +- +- Json::Value::Members operation = root.getMemberNames(); +- context.getOrLoadDialect(); +- mlir::OpBuilder builder(&context); +- for (size_t iter = 0; iter < operation.size(); iter++) { +- string operationKey = "edge" + std::to_string(iter); +- node = root[operationKey]; +- uint64_t src = GetID(node["src"]); +- uint64_t dest = GetID(node["dest"]); +- pair e; +- auto iterSrc = this->blockMaps.find(src); +- if(iterSrc != blockMaps.end()) +- e.first = iterSrc->second; +- else +- e.first = nullptr; +- +- auto iterDest = this->blockMaps.find(dest); +- if(iterDest != blockMaps.end()) +- e.second = iterDest->second; +- else +- e.second = nullptr; +- +- edges.push_back(e); +- } +-} +- +-void PluginServer::EdgeJsonDeSerialize(const string& data) +-{ +- Json::Value root; +- Json::Reader reader; +- reader.parse(data, root); +- uint64_t src = GetID(root["src"]); +- uint64_t dest = GetID(root["dest"]); +- auto iterSrc = this->blockMaps.find(src); +- if(iterSrc != blockMaps.end()) +- edge.first = iterSrc->second; +- else +- edge.first = nullptr; +- +- auto iterDest = this->blockMaps.find(dest); +- if(iterDest != blockMaps.end()) +- edge.second = iterDest->second; +- else +- edge.second = nullptr; +-} +- +-void PluginServer::IdsJsonDeSerialize(const string& data) +-{ +- Json::Value root; +- Json::Reader reader; +- Json::Value node; +- reader.parse(data, root); +- +- Json::Value::Members operation = root.getMemberNames(); +- context.getOrLoadDialect(); +- mlir::OpBuilder builder(&context); +- for (size_t iter = 0; iter < operation.size(); iter++) { +- string operationKey = "block" + std::to_string(iter); +- node = root[operationKey]; +- uint64_t id = GetID(node["id"]); +- idsResult.push_back(id); +- } +-} +- +-void PluginServer::CallOpJsonDeSerialize(const string& data) +-{ +- Json::Value node; +- Json::Reader reader; +- reader.parse(data, node); +- Json::Value operandJson = node["operands"]; +- Json::Value::Members operandMember = operandJson.getMemberNames(); +- llvm::SmallVector ops; +- for (size_t opIter = 0; opIter < operandMember.size(); opIter++) { +- string key = "input" + std::to_string(opIter); +- mlir::Value opValue = ValueJsonDeSerialize(operandJson[key.c_str()]); +- ops.push_back(opValue); +- } +- int64_t id = GetID(node["id"]); +- mlir::StringRef callName(node["callee"].asString()); +- CallOp op = opBuilder.create(opBuilder.getUnknownLoc(), +- id, callName, ops); +- opData.push_back(op.getOperation()); +-} +- +-void PluginServer::CondOpJsonDeSerialize(const string& data) +-{ +- Json::Value node; +- Json::Reader reader; +- reader.parse(data, node); +- mlir::Value LHS = ValueJsonDeSerialize(node["lhs"]); +- mlir::Value RHS = ValueJsonDeSerialize(node["rhs"]); +- mlir::Value trueLabel = nullptr; +- mlir::Value falseLabel = nullptr; +- int64_t id = GetID(node["id"]); +- int64_t address = GetID(node["address"]); +- int64_t tbaddr = GetID(node["tbaddr"]); +- int64_t fbaddr = GetID(node["fbaddr"]); +- assert (this->blockMaps.find(tbaddr) != this->blockMaps.end()); +- assert (this->blockMaps.find(fbaddr) != this->blockMaps.end()); +- mlir::Block* tb = this->blockMaps[tbaddr]; +- mlir::Block* fb = this->blockMaps[fbaddr]; +- IComparisonCode iCode = IComparisonCode( +- atoi(node["condCode"].asString().c_str())); +- CondOp op = opBuilder.create(opBuilder.getUnknownLoc(), id, +- address, iCode, LHS, RHS, tb, fb, tbaddr, fbaddr, +- trueLabel, falseLabel); +- opData.push_back(op.getOperation()); +-} +- +-void PluginServer::RetOpJsonDeSerialize(const string& data) +-{ +- Json::Value node; +- Json::Reader reader; +- reader.parse(data, node); +- int64_t address = GetID(node["address"]); +- RetOp op = opBuilder.create(opBuilder.getUnknownLoc(), address); +- opData.push_back(op.getOperation()); +-} +- +-void PluginServer::FallThroughOpJsonDeSerialize(const string& data) +-{ +- Json::Value node; +- Json::Reader reader; +- reader.parse(data, node); +- int64_t address = GetID(node["address"]); +- int64_t destaddr = GetID(node["destaddr"]); +- assert (this->blockMaps.find(destaddr) != this->blockMaps.end()); +- mlir::Block* succ = this->blockMaps[destaddr]; +- FallThroughOp op = opBuilder.create(opBuilder.getUnknownLoc(), +- address, succ, destaddr); +- opData.push_back(op.getOperation()); +-} +- +-void PluginServer::PhiOpJsonDeSerialize(const string& data) +-{ +- Json::Value node; +- Json::Reader reader; +- reader.parse(data, node); +- Json::Value operandJson = node["operands"]; +- Json::Value::Members operandMember = operandJson.getMemberNames(); +- llvm::SmallVector ops; +- for (size_t opIter = 0; opIter < operandMember.size(); opIter++) { +- string key = "input" + std::to_string(opIter); +- mlir::Value opValue = ValueJsonDeSerialize(operandJson[key.c_str()]); +- ops.push_back(opValue); +- } +- uint64_t id = GetID(node["id"]); +- uint32_t capacity = GetID(node["capacity"]); +- uint32_t nArgs = GetID(node["nArgs"]); +- PhiOp op = opBuilder.create(opBuilder.getUnknownLoc(), +- ops, id, capacity, nArgs); +- +- defOpMaps.insert({id, op.getOperation()}); +- opData.push_back(op.getOperation()); +-} +- +-mlir::Value PluginServer::SSAOpJsonDeSerialize(const string& data) +-{ +- Json::Value node; +- Json::Reader reader; +- reader.parse(data, node); +- +- uint64_t id = GetID(node["id"]); +- bool readOnly = (bool)atoi(node["readOnly"].asString().c_str()); +- uint64_t nameVarId = GetID(node["nameVarId"]); +- uint64_t ssaParmDecl = GetID(node["ssaParmDecl"]); +- uint64_t version = GetID(node["version"]); +- uint64_t definingId = GetID(node["definingId"]); +- mlir::Type retType = TypeJsonDeSerialize(node["retType"].toStyledString().c_str()); +- mlir::Value ret = opBuilder.create(opBuilder.getUnknownLoc(), +- id, IDefineCode::SSA, readOnly, nameVarId, +- ssaParmDecl, version, +- definingId, retType); +- return ret; +-} +- +-void PluginServer::AssignOpJsonDeSerialize(const string& data) +-{ +- Json::Value node; +- Json::Reader reader; +- reader.parse(data, node); +- Json::Value operandJson = node["operands"]; +- Json::Value::Members operandMember = operandJson.getMemberNames(); +- llvm::SmallVector ops; +- for (size_t opIter = 0; opIter < operandMember.size(); opIter++) { +- string key = "input" + std::to_string(opIter); +- mlir::Value opValue = ValueJsonDeSerialize(operandJson[key.c_str()]); +- ops.push_back(opValue); +- } +- uint64_t id = GetID(node["id"]); +- IExprCode iCode = IExprCode(atoi(node["exprCode"].asString().c_str())); +- AssignOp op = opBuilder.create(opBuilder.getUnknownLoc(), +- ops, id, iCode); +- defOpMaps.insert({id, op.getOperation()}); +- opData.push_back(op.getOperation()); +-} +- +-void PluginServer::GetPhiOpsJsonDeSerialize(const string& data) +-{ +- opData.clear(); +- Json::Value root; +- Json::Reader reader; +- Json::Value node; +- reader.parse(data, root); +- +- Json::Value::Members operation = root.getMemberNames(); +- context.getOrLoadDialect(); +- mlir::OpBuilder builder(&context); +- for (size_t iter = 0; iter < operation.size(); iter++) { +- string operationKey = "operation" + std::to_string(iter); +- node = root[operationKey]; +- PhiOpJsonDeSerialize(node.toStyledString()); +- } + } + + /* 线程函数,执行用户注册函数,客户端返回数据后退出 */ +-static void ExecCallbacks(const string& name) +-{ +- PluginServer::GetInstance()->ExecFunc(name); +-} +- +-void PluginServer::ServerSend(ServerReaderWriter* stream, const string& key, +- const string& value) ++void PluginServer::ExecCallbacks(const string& name) + { +- ServerMsg serverMsg; +- serverMsg.set_attribute(key); +- serverMsg.set_value(value); +- stream->Write(serverMsg); ++ ExecFunc(name); + } + + /* 处理从client接收到的消息 */ +-int PluginServer::ClientMsgProc(ServerReaderWriter* stream, const string& attribute, +- const string& value) ++int PluginServer::ClientMsgProc(const string& key, const string& value) + { +- if ((attribute != "injectPoint") && (attribute != apiFuncName)) { +- JsonDeSerialize(attribute, value); ++ log->LOGD("rec from client:%s,%s\n", key.c_str(), value.c_str()); ++ if (key == "start") { ++ ParseArgv(value); ++ pluginCom.ServerSend("start", "ok"); ++ SendRegisteredUserOpts(); ++ return 0; ++ } else if (key == "stop") { ++ pluginCom.ServerSend("stop", "ok"); ++ pluginCom.ShutDown(); ++ return 0; ++ } ++ if ((key != "injectPoint") && (key != apiFuncName)) { ++ pluginCom.JsonDeSerialize(key, value); + return 0; + } +- if (attribute == "injectPoint") { +- std::thread userfunc(ExecCallbacks, value); ++ if (key == "injectPoint") { ++ std::thread userfunc(&PluginServer::ExecCallbacks, this, value); + userfunc.detach(); + } +- if ((attribute == apiFuncName) && (value == "done")) { +- SemPost(); ++ if ((key == apiFuncName) && (value == "done")) { ++ sem_post(&clientWaitSem); + } + + while (1) { +- SemWait(); +- UserFunStateEnum state = GetUserFunState(); +- if (state == STATE_END) { +- ServerSend(stream, "userFunc", "execution completed"); +- SetUserFunState(STATE_WAIT_BEGIN); ++ sem_wait(&clientWaitSem); ++ if (userFunState == STATE_END) { ++ pluginCom.ServerSend("userFunc", "execution completed"); ++ userFunState = STATE_WAIT_BEGIN; + break; +- } else if (state == STATE_BEGIN) { +- ServerSend(stream, apiFuncName, apiFuncParams); +- SetUserFunState(STATE_WAIT_RETURN); ++ } else if (userFunState == STATE_BEGIN) { ++ pluginCom.ServerSend(apiFuncName, apiFuncParams); ++ userFunState = STATE_WAIT_RETURN; + break; +- } else if (state == STATE_WAIT_RETURN) { +- if ((attribute == apiFuncName) && (value == "done")) { +- SetUserFunState(STATE_RETURN); +- SetApiFuncName(""); // 已通知,清空 +- ClientReturnSemPost(); ++ } else if (userFunState == STATE_WAIT_RETURN) { ++ if ((key == apiFuncName) && (value == "done")) { ++ userFunState = STATE_RETURN; ++ apiFuncName = ""; // 已通知,清空 ++ sem_post(&clientReturnSem); + } + } + } +@@ -865,16 +227,28 @@ void PluginServer::ExecFunc(const string& value) + return; + } + +- auto it = userFunc.find(inject); +- if (it != userFunc.end()) { +- for (auto& funcSet : it->second) { +- if (funcSet.GetName() == name) { +- UserFunc func = funcSet.GetFunc(); +- func(); // 执行用户注册函数 +- SetUserFunState(STATE_END); +- ClearMaps(); +- SemPost(); ++ uint64_t param = 0; ++ if (inject == HANDLE_MANAGER_SETUP) { ++ param = atol(name.substr(name.find_first_of(":") + 1, -1).c_str()); ++ name = name.substr(0, name.find_first_of(",")); ++ } ++ ++ auto it = userOpts.find(inject); ++ if (it != userOpts.end()) { ++ for (auto& userOpt : it->second) { ++ if (userOpt.GetName() != name) { ++ continue; ++ } ++ ++ if (userOpt.GetOpt()->Gate()) { ++ if (it->first == HANDLE_MANAGER_SETUP) { ++ userOpt.GetOpt()->SetFuncAddr(param); ++ } ++ userOpt.GetOpt()->DoOptimize(); + } ++ ClearMaps(); ++ userFunState = STATE_END; ++ sem_post(&clientWaitSem); + } + } + } +@@ -893,129 +267,45 @@ void PluginServer::ParseArgv(const string& data) + } + } + +-void PluginServer::SendRegisteredUserFunc(ServerReaderWriter* stream) ++void PluginServer::SendRegisteredUserOpts() + { +- for (auto it = userFunc.begin(); it != userFunc.end(); it++) { ++ for (auto it = userOpts.begin(); it != userOpts.end(); it++) { + string key = "injectPoint"; +- for (auto& funcSet : it->second) { ++ for (auto& userOpt : it->second) { + string value = std::to_string(it->first) + ":"; +- value += funcSet.GetName(); +- ServerSend(stream, key, value); +- } +- } +- ServerSend(stream, "injectPoint", "finished"); +-} +- +-Status PluginServer::ReceiveSendMsg(ServerContext* context, ServerReaderWriter* stream) +-{ +- ClientMsg clientMsg; +- ServerMsg serverMsg; +- +- while (stream->Read(&clientMsg)) { +- LOGD("rec from client:%s,%s\n", clientMsg.attribute().c_str(), clientMsg.value().c_str()); +- string attribute = clientMsg.attribute(); +- if (attribute == "start") { +- string arg = clientMsg.value(); +- ParseArgv(arg); +- +- ServerSend(stream, "start", "ok"); +- SendRegisteredUserFunc(stream); +- } else if (attribute == "stop") { +- ServerSend(stream, "stop", "ok"); +- SetShutdownFlag(true); // 关闭标志 +- } else { +- ClientMsgProc(stream, attribute, clientMsg.value()); +- } +- } +- return Status::OK; +-} +- +-static void ServerExitThread(void) +-{ +- int delay = 100000; +- pid_t initPid = 1; +- while (1) { +- if (g_service.GetShutdownFlag() || (getppid() == initPid)) { +- g_server->Shutdown(); +- break; ++ if (it->first == HANDLE_MANAGER_SETUP) { ++ value += userOpt.GetName() + ",params:" + userOpt.GetParam(); ++ } else { ++ value += userOpt.GetName(); ++ } ++ pluginCom.ServerSend(key, value); + } +- +- usleep(delay); + } ++ pluginCom.ServerSend("injectPoint", "finished"); + } + +-static void TimeoutFunc(union sigval sig) +-{ +- int delay = 1; // server延时1秒等待client发指令关闭,若client异常,没收到关闭指令,延时1秒自动关闭 +- LOGW("server ppid:%d timeout!\n", getppid()); +- PluginServer::GetInstance()->SetUserFunState(STATE_TIMEOUT); +- sleep(delay); +- PluginServer::GetInstance()->SetShutdownFlag(true); +-} +- +-void PluginServer::TimerStart(int interval) // interval:单位ms ++void PluginServer::ServerSemPost(const string& port) + { +- int msTons = 1000000; // ms转ns倍数 +- int msTos = 1000; // s转ms倍数 +- struct itimerspec time_value; +- time_value.it_value.tv_sec = (interval / msTos); +- time_value.it_value.tv_nsec = (interval % msTos) * msTons; +- time_value.it_interval.tv_sec = 0; +- time_value.it_interval.tv_nsec = 0; +- +- timer_settime(timerId, 0, &time_value, NULL); ++ 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); ++ umask(mask); ++ sem_post(sem); ++ sem_close(sem); + } + +-void PluginServer::TimerInit(void) ++void PluginServer::RunServer() + { +- struct sigevent evp; +- int sival = 123; // 传递整型参数,可以自定义 +- memset(&evp, 0, sizeof(struct sigevent)); +- evp.sigev_value.sival_ptr = timerId; +- evp.sigev_value.sival_int = sival; +- evp.sigev_notify = SIGEV_THREAD; +- evp.sigev_notify_function = TimeoutFunc; +- +- if (timer_create(CLOCK_REALTIME, &evp, &timerId) == -1) { +- LOGE("timer create fail\n"); +- } +-} +- +-void RunServer(int timeout, string& port) // port由client启动server时传入 +-{ +- string serverAddress = "0.0.0.0:" + port; +- +- ServerBuilder builder; +- int serverPort = 0; +- // Listen on the given address without any authentication mechanism. +- builder.AddListeningPort(serverAddress, grpc::InsecureServerCredentials(), &serverPort); +- +- // Register "service" as the instance through which we'll communicate with +- // clients. In this case, it corresponds to an *synchronous* service. +- builder.RegisterService(&g_service); +- // Finally assemble the server. +- g_server = std::unique_ptr(builder.BuildAndStart()); +- LOGI("Server ppid:%d listening on %s\n", getppid(), serverAddress.c_str()); +- if (serverPort != atoi(port.c_str())) { +- LOGW("server start fail\n"); ++ if (!pluginCom.RegisterServer(port)) { ++ log->LOGE("server start fail,port:%s\n", port.c_str()); + return; + } +- +- g_service.SetShutdownFlag(false); +- g_service.SetTimeout(timeout); +- g_service.TimerInit(); +- g_service.SetUserFunState(STATE_WAIT_BEGIN); +- g_service.SemInit(); ++ log->LOGI("Server ppid:%d listening on port:%s\n", getppid(), port.c_str()); ++ ServerSemPost(port); + + RegisterCallbacks(); +- +- std::thread serverExtiThread(ServerExitThread); +- serverExtiThread.join(); +- +- // Wait for the server to shutdown. Note that some other thread must be +- // responsible for shutting down the server for this call to ever return. +- g_server->Wait(); +- g_service.SemDestroy(); +- LOGI("server ppid:%d quit!\n", getppid()); ++ printf("RunServer: RegisterCallbacks Done.\n"); ++ pluginCom.Run(); + } + } // namespace PinServer +-- +2.27.0.windows.1 + diff --git a/0002-Refactoring-Code-refactoring-of-Communication-Subsys.patch b/0002-Refactoring-Code-refactoring-of-Communication-Subsys.patch new file mode 100644 index 0000000000000000000000000000000000000000..8abb0a35ef7ab0b429509b5224ba8c69f7f2c32a --- /dev/null +++ b/0002-Refactoring-Code-refactoring-of-Communication-Subsys.patch @@ -0,0 +1,2595 @@ +From c1301cbec8465ef4c9c4df597ee46774b6da5715 Mon Sep 17 00:00:00 2001 +From: wangding16 +Date: Wed, 8 Feb 2023 15:13:54 +0800 +Subject: [PATCH 2/9] [Refactoring] Code refactoring of Communication Subsystem + [2/3]. Code refactoring of PluginServer. + + +diff --git a/include/PluginServer/PluginLog.h b/include/PluginServer/PluginLog.h +index 716e08a..ece7067 100644 +--- a/include/PluginServer/PluginLog.h ++++ b/include/PluginServer/PluginLog.h +@@ -16,13 +16,18 @@ + Create: 2022-08-18 + Description: + This file contains the declaration of the Plugin_Log class. ++ 主要完成功能:提供LOGE、LOGW、LOGI、LOGD四个log保存接口,并提供SetLogPriority接口 ++ 设置log级别 + */ + + #ifndef PLUGIN_LOG_H + #define PLUGIN_LOG_H + +-namespace PinServer { +-#define LOG_FILE_SIZE (10 * 1024 * 1024) ++#include ++#include ++ ++namespace PinLog { ++using std::string; + + enum LogPriority : uint8_t { + PRIORITY_ERROR = 0, +@@ -30,14 +35,38 @@ enum LogPriority : uint8_t { + PRIORITY_INFO, + PRIORITY_DEBUG + }; +-void LogPrint(LogPriority priority, const char *tag, const char *fmt, ...); +-void CloseLog(void); +-bool SetLogPriority(LogPriority priority); +- +-#define LOGE(...) LogPrint(PRIORITY_ERROR, "ERROR:", __VA_ARGS__) +-#define LOGW(...) LogPrint(PRIORITY_WARN, "WARN:", __VA_ARGS__) +-#define LOGI(...) LogPrint(PRIORITY_INFO, "", __VA_ARGS__) +-#define LOGD(...) LogPrint(PRIORITY_DEBUG, "DEBUG:", __VA_ARGS__) +-} // namespace PinServer ++ ++constexpr int LOG_BUF_SIZE = 102400; ++constexpr int BASE_DATE = 1900; ++class PluginLog { ++public: ++ PluginLog(); ++ ~PluginLog() ++ { ++ CloseLog(); ++ } ++ void CloseLog(); ++ bool SetPriority(LogPriority pri); ++ void SetFileSize(unsigned int size) ++ { ++ logFileSize = size; ++ } ++ void LOGE(const char *fmt, ...); ++ void LOGW(const char *fmt, ...); ++ void LOGI(const char *fmt, ...); ++ void LOGD(const char *fmt, ...); ++ static PluginLog *GetInstance(); ++ ++private: ++ void LogPrint(LogPriority priority, const char *tag, const char *fmt); ++ void LogWrite(const char *tag, const char *msg); ++ void LogWriteFile(const string& data); ++ void GetLogFileName(string& fileName); ++ LogPriority priority; ++ unsigned int logFileSize; ++ std::shared_ptr logFs; ++ char logBuf[LOG_BUF_SIZE]; ++}; ++} // namespace PinLog + + #endif +diff --git a/include/PluginServer/PluginOptBase.h b/include/PluginServer/PluginOptBase.h +new file mode 100755 +index 0000000..474d072 +--- /dev/null ++++ b/include/PluginServer/PluginOptBase.h +@@ -0,0 +1,82 @@ ++/* Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. ++ ++ Licensed under the Apache License, Version 2.0 (the "License"); you may ++ not use this file except in compliance with the License. You may obtain ++ a copy of the License at ++ ++ http://www.apache.org/licenses/LICENSE-2.0 ++ ++ Unless required by applicable law or agreed to in writing, software ++ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT ++ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the ++ License for the specific language governing permissions and limitations ++ under the License. ++ ++ Author: Mingchuan Wu and Yancheng Li ++ Create: 2022-08-18 ++ Description: ++ This file contains the declaration of the PluginOptBase class. ++ 主要完成功能:提供优化基类,gate为进入条件,DoOptimize为执行函数,RegisterCallbacks为注册函数 ++*/ ++ ++#ifndef PLUGIN_OPTBASE_H ++#define PLUGIN_OPTBASE_H ++ ++#include "PluginServer/ManagerSetup.h" ++#include "Dialect/PluginDialect.h" ++#include "Dialect/PluginOps.h" ++#include "mlir/IR/MLIRContext.h" ++#include "mlir/IR/Builders.h" ++ ++namespace PluginOpt { ++enum InjectPoint : uint8_t { ++ HANDLE_PARSE_TYPE = 0, ++ HANDLE_PARSE_DECL, ++ HANDLE_PRAGMAS, ++ HANDLE_PARSE_FUNCTION, ++ HANDLE_BEFORE_IPA, ++ HANDLE_AFTER_IPA, ++ HANDLE_BEFORE_EVERY_PASS, ++ HANDLE_AFTER_EVERY_PASS, ++ HANDLE_BEFORE_ALL_PASS, ++ HANDLE_AFTER_ALL_PASS, ++ HANDLE_COMPILE_END, ++ HANDLE_MANAGER_SETUP, ++ HANDLE_INCLUDE_FILE, ++ HANDLE_MAX, ++}; ++ ++class PluginOptBase { ++public: ++ PluginOptBase(InjectPoint inject) ++ { ++ this->inject = inject; ++ context.getOrLoadDialect(); ++ } ++ virtual ~PluginOptBase() = default; ++ virtual bool Gate() = 0; ++ virtual int DoOptimize() = 0; ++ InjectPoint GetInject() ++ { ++ return inject; ++ } ++ void SetFuncAddr(uint64_t add) ++ { ++ func = add; ++ } ++ uint64_t GetFuncAddr(void) ++ { ++ return func; ++ } ++ mlir::MLIRContext *GetContext() ++ { ++ return &(this->context); ++ } ++ ++private: ++ mlir::MLIRContext context; ++ InjectPoint inject; ++ uint64_t func; // 保存managerSetup fun参数指针 ++}; ++} // namespace PluginOpt ++#endif +diff --git a/include/PluginServer/PluginServer.h b/include/PluginServer/PluginServer.h +index ba659be..b651140 100644 +--- a/include/PluginServer/PluginServer.h ++++ b/include/PluginServer/PluginServer.h +@@ -16,6 +16,8 @@ + Create: 2022-08-18 + Description: + This file contains the declaration of the PluginServer class. ++ 主要完成功能:完成和server之间grpc数据解析,提供接口函数获取client数据,提供注册 ++ 函数完成用户事件注册,并在对应事件触发时回调用户函数 + */ + + #ifndef PLUGIN_SERVER_H +@@ -30,22 +32,25 @@ + + #include + #include +-#include "Dialect/PluginOps.h" + #include "plugin.grpc.pb.h" ++#include "Dialect/PluginOps.h" + #include "mlir/IR/MLIRContext.h" + #include "mlir/IR/Builders.h" + #include "Dialect/PluginTypes.h" + +-namespace PinServer { +-using grpc::Server; +-using grpc::ServerBuilder; +-using grpc::ServerContext; +-using grpc::ServerReaderWriter; +-using grpc::Status; ++#include "PluginServer/PluginLog.h" ++#include "PluginServer/PluginCom.h" ++#include "PluginServer/PluginOptBase.h" + +-using plugin::PluginService; ++namespace PinServer { ++using PinLog::PluginLog; ++using PinLog::LogPriority; ++using PinCom::PluginCom; + using plugin::ClientMsg; + using plugin::ServerMsg; ++using PluginOpt::InjectPoint; ++using PluginOpt::ManagerSetup; ++using PluginOpt::PluginOptBase; + + using std::vector; + using std::string; +@@ -60,250 +65,211 @@ typedef enum { + STATE_TIMEOUT, + } UserFunStateEnum; + +-typedef std::function UserFunc; +-enum InjectPoint : uint8_t { +- HANDLE_PARSE_TYPE = 0, +- HANDLE_PARSE_DECL, +- HANDLE_PRAGMAS, +- HANDLE_PARSE_FUNCTION, +- HANDLE_BEFORE_IPA, +- HANDLE_AFTER_IPA, +- HANDLE_BEFORE_EVERY_PASS, +- HANDLE_AFTER_EVERY_PASS, +- HANDLE_BEFORE_ALL_PASS, +- HANDLE_AFTER_ALL_PASS, +- HANDLE_COMPILE_END, +- HANDLE_MANAGER_SETUP, +- HANDLE_MAX, +-}; +- +-// 参考点名称 +-enum RefPassName { +- PASS_CFG, +- PASS_PHIOPT, +- PASS_SSA, +- PASS_LOOP, +-}; +- +-enum PassPosition { +- PASS_INSERT_AFTER, +- PASS_INSERT_BEFORE, +- PASS_REPLACE, +-}; +- +-struct ManagerSetupData { +- RefPassName refPassName; +- int passNum; // 指定passName的第几次执行作为参考点 +- PassPosition passPosition; // 指定pass是添加在参考点之前还是之后 +-}; +- +-class RecordedUserFunc { ++class RecordedOpt { + public: +- RecordedUserFunc () = default; +- ~RecordedUserFunc () = default; +- RecordedUserFunc (const string& name, UserFunc func) ++ RecordedOpt() = default; ++ ~RecordedOpt() = default; ++ RecordedOpt(const string& name, std::shared_ptr opt) + { + this->name = name; +- this->func = func; ++ this->opt = opt; + } +- string GetName(void) ++ RecordedOpt(const string& name, const string& param, std::shared_ptr opt) ++ { ++ this->name = name; ++ this->param = param; ++ this->opt = opt; ++ } ++ string GetName() + { + return name; + } +- UserFunc GetFunc(void) ++ string GetParam() + { +- return func; ++ return param; ++ } ++ std::shared_ptr GetOpt() ++ { ++ return opt; + } + private: + string name; +- UserFunc func; ++ string param; ++ std::shared_ptr opt; + }; + +-class PluginServer final : public PluginService::Service { ++class PluginServer { + public: +- PluginServer() : opBuilder(&context){} +- /* 定义的grpc服务端和客户端通信的接口函数 */ +- Status ReceiveSendMsg(ServerContext* context, ServerReaderWriter* stream) override; +- /* 服务端发送数据给client接口 */ +- void ServerSend(ServerReaderWriter* stream, const string& key, const string& value); ++ PluginServer(LogPriority priority, const string& port) ++ { ++ userFunState = STATE_WAIT_BEGIN; ++ sem_init(&clientWaitSem, 0, 0); ++ sem_init(&clientReturnSem, 0, 0); ++ log = PluginLog::GetInstance(); ++ log->SetPriority(priority); ++ this->port = port; ++ pluginServerPtr = this; ++ } ++ ~PluginServer() ++ { ++ sem_destroy(&clientWaitSem); ++ sem_destroy(&clientReturnSem); ++ log->LOGI("server ppid:%d quit!\n", getppid()); ++ } + /* 处理从client接收到的消息 */ +- int ClientMsgProc(ServerReaderWriter* stream, const string& attribute, const string& value); +- /* 获取server对象实例,有且只有一个实例对象 */ +- static PluginServer *GetInstance(void); +- vector GetFunctionOpResult(void); +- vector GetLocalDeclResult(void); +- mlir::Plugin::LoopOp LoopOpResult(void); +- vector LoopOpsResult(void); +- vector > EdgesResult(void); +- std::pair EdgeResult(void); +- vector GetOpResult(void); +- bool GetBoolResult(void); +- void EraseBlock(mlir::Block*); +- uint64_t GetBlockResult(mlir::Block*); +- uint64_t GetIdResult(void); +- vector GetIdsResult(void); +- mlir::Value GetValueResult(void); +- vector GetPhiOpsResult(void); +- mlir::Block* FindBlock(uint64_t); +- uint64_t FindBasicBlock(mlir::Block*); +- bool InsertValue(uint64_t, mlir::Value); +- mlir::Operation* FindDefOperation(uint64_t); +- void InsertCreatedBlock(uint64_t, mlir::Block*); ++ int ClientMsgProc(const string& attribute, const string& value); ++ mlir::MLIRContext *GetContext() ++ { ++ return this->context; ++ } ++ void SetOpBuilder(mlir::OpBuilder *builder) ++ { ++ this->opBuilder = builder; ++ } ++ mlir::OpBuilder *GetOpBuilder() ++ { ++ return this->opBuilder; ++ } + /* 回调函数接口,用于向server注册用户需要执行的函数 */ +- int RegisterUserFunc(InjectPoint inject, UserFunc func); +- int RegisterPassManagerSetup(InjectPoint inject, const ManagerSetupData& passData, UserFunc func); +- /* 执行用户注册的回调函数,根据value查找对应的函数,value格式 InjectPoint:funName */ +- void ExecFunc(const string& value); +- /* 将注册点和函数名发到客户端, stream为grpc当前数据流指针 */ +- void SendRegisteredUserFunc(ServerReaderWriter* stream); +- bool GetShutdownFlag(void) ++ bool RegisterOpt(std::shared_ptr optBase); ++ bool RegisterPassManagerOpt(ManagerSetup& passData, std::shared_ptr optBase); ++ map& GetArgs() + { +- return shutdown; ++ return args; + } +- void SetShutdownFlag(bool flag) ++ /* 执行用户注册的回调函数,根据value查找对应的函数,value格式 InjectPoint:funName */ ++ void ExecFunc(const string& value); ++ void RunServer(); ++ /* 获取server对象实例,有且只有一个实例对象 */ ++ static PluginServer *GetInstance(void); ++ ++ int64_t GetIntegerDataResult(const string& funName, const string& params) + { +- shutdown = flag; ++ RemoteCallClientWithAPI(funName, params); ++ return pluginCom.GetIntegerDataResult(); + } +- void SetApiFuncName(const string& name) ++ string GetStringDataResult(const string& funName, const string& params) + { +- apiFuncName = name; ++ RemoteCallClientWithAPI(funName, params); ++ return pluginCom.GetStringDataResult(); + } +- void SetApiFuncParams(const string& params) ++ vector GetFunctionOpResult(const string& funName, const string& params) + { +- apiFuncParams = params; ++ RemoteCallClientWithAPI(funName, params); ++ return pluginCom.GetFunctionOpResult(); + } +- string &GetApiFuncName(void) ++ vector GetLocalDeclResult(const string& funName, const string& params) + { +- return apiFuncName; ++ RemoteCallClientWithAPI(funName, params); ++ return pluginCom.GetLocalDeclResult(); + } +- string &GetApiFuncParams(void) ++ mlir::Plugin::LoopOp LoopOpResult(const string& funName, const string& params) + { +- return apiFuncParams; ++ RemoteCallClientWithAPI(funName, params); ++ return pluginCom.LoopOpResult(); + } +- void SetUserFunState(UserFunStateEnum state) ++ vector LoopOpsResult(const string& funName, const string& params) + { +- userFunState = state; ++ RemoteCallClientWithAPI(funName, params); ++ return pluginCom.LoopOpsResult(); + } +- UserFunStateEnum GetUserFunState(void) ++ vector > EdgesResult(const string& funName, const string& params) + { +- return userFunState; ++ RemoteCallClientWithAPI(funName, params); ++ return pluginCom.EdgesResult(); + } +- void SetTimeout(int time) ++ std::pair EdgeResult(const string& funName, const string& params) + { +- timeout = time; ++ RemoteCallClientWithAPI(funName, params); ++ return pluginCom.EdgeResult(); + } +- void FuncOpJsonDeSerialize(const string& data); +- Json::Value TypeJsonSerialize(PluginIR::PluginTypeBase& type); +- PluginIR::PluginTypeBase TypeJsonDeSerialize(const string& data); +- void LocalDeclOpJsonDeSerialize(const string& data); +- void LoopOpsJsonDeSerialize(const string& data); +- void LoopOpJsonDeSerialize(const string& data); +- void EdgesJsonDeSerialize(const string& data); +- void EdgeJsonDeSerialize(const string& data); +- void IdsJsonDeSerialize(const string& data); +- void CallOpJsonDeSerialize(const string& data); +- void CondOpJsonDeSerialize(const string& data); +- void RetOpJsonDeSerialize(const string& data); +- mlir::Value SSAOpJsonDeSerialize(const string& data); +- void FallThroughOpJsonDeSerialize(const string& data); +- void PhiOpJsonDeSerialize(const string& data); +- void AssignOpJsonDeSerialize(const string& data); +- void GetPhiOpsJsonDeSerialize(const string& data); +- void OpJsonDeSerialize(const string& data); +- mlir::Value ValueJsonDeSerialize(Json::Value valueJson); +- mlir::Value MemRefDeSerialize(const string& data); +- /* json反序列化,根据key值分别调用Operation/Decl/Type反序列化接口函数 */ +- void JsonDeSerialize(const string& key, const string& data); +- /* 解析客户端发送过来的-fplugin-arg参数,并保存在私有变量args中 */ +- void ParseArgv(const string& data); +- void TimerInit(void); // 超时定时器初始化 +- void TimerStart(int interval); // 启动定时器,interval为0表示关闭定时器 +- map& GetArgs(void) ++ vector GetOpResult(const string& funName, const string& params) + { +- return args; ++ RemoteCallClientWithAPI(funName, params); ++ return pluginCom.GetOpResult(); + } +- /* 将json格式数据解析成map格式 */ +- void JsonGetAttributes(Json::Value node, map& attributes); +- void SemInit(void) ++ bool GetBoolResult(const string& funName, const string& params) + { +- sem_init(&sem[0], 0, 0); +- sem_init(&sem[1], 0, 0); ++ RemoteCallClientWithAPI(funName, params); ++ return pluginCom.GetBoolResult(); + } +- void SemPost(void) // 开始执行用户函数或者用户函数结束触发该信号量 ++ uint64_t GetIdResult(const string& funName, const string& params) + { +- sem_post(&sem[0]); ++ RemoteCallClientWithAPI(funName, params); ++ return pluginCom.GetIdResult(); + } +- void SemWait(void) ++ vector GetIdsResult(const string& funName, const string& params) + { +- sem_wait(&sem[0]); ++ RemoteCallClientWithAPI(funName, params); ++ return pluginCom.GetIdsResult(); + } +- void ClientReturnSemPost(void) // client返回数据后触发该信号量 ++ mlir::Value GetValueResult(const string& funName, const string& params) + { +- sem_post(&sem[1]); ++ RemoteCallClientWithAPI(funName, params); ++ return pluginCom.GetValueResult(); + } +- void ClientReturnSemWait(void) ++ vector GetPhiOpsResult(const string& funName, const string& params) + { +- sem_wait(&sem[1]); ++ RemoteCallClientWithAPI(funName, params); ++ return pluginCom.GetPhiOpsResult(); + } +- void SemDestroy(void) ++ ++ uint64_t GetBlockResult(mlir::Block*); ++ void EraseBlock(mlir::Block*); ++ mlir::Block* FindBlock(uint64_t); ++ void InsertCreatedBlock(uint64_t, mlir::Block*); ++ bool HaveBlock(uint64_t id) + { +- sem_destroy(&sem[0]); +- sem_destroy(&sem[1]); ++ return this->blockMaps.find(id) != this->blockMaps.end(); + } + +- void SetOpBuilder(mlir::OpBuilder builder) { this->opBuilder = builder; } + void ClearMaps() + { + valueMaps.clear(); + blockMaps.clear(); + basicblockMaps.clear(); + defOpMaps.clear(); +- idsResult.clear(); +- opData.clear(); +- edges.clear(); +- loops.clear(); +- decls.clear(); +- funcOpData.clear(); +- opBuilder = mlir::OpBuilder(&context); + } + ++ uint64_t FindBasicBlock(mlir::Block*); ++ bool InsertValue(uint64_t, mlir::Value); ++ bool HaveValue(uint64_t); ++ mlir::Value GetValue(uint64_t); ++ mlir::Operation* FindDefOperation(uint64_t); ++ bool InsertDefOperation(uint64_t, mlir::Operation*); ++ void RemoteCallClientWithAPI(const string& api, const string& params); ++ + private: +- bool shutdown; // 是否关闭server + /* 用户函数执行状态,client返回结果后为STATE_RETURN,开始执行下一个函数 */ + volatile UserFunStateEnum userFunState; +- mlir::MLIRContext context; +- mlir::OpBuilder opBuilder; +- vector funcOpData; +- PluginIR::PluginTypeBase pluginType; +- vector decls; +- vector loops; +- mlir::Plugin::LoopOp loop; +- vector > edges; +- std::pair edge; +- vector opData; +- bool boolResult; +- uint64_t idResult; +- vector idsResult; +- mlir::Value valueResult; ++ mlir::MLIRContext *context; ++ mlir::OpBuilder* opBuilder = nullptr; ++ + /* 保存用户注册的回调函数,它们将在注入点事件触发后调用 */ +- map> userFunc; ++ map> userOpts; + string apiFuncName; // 保存用户调用PluginAPI的函数名 + string apiFuncParams; // 保存用户调用PluginAPI函数的参数 +- int timeout; +- timer_t timerId; +- map args; // 保存gcc编译时用户传入参数 +- sem_t sem[2]; ++ string port; // server使用的端口号 ++ map args; // 保存client编译时用户传入参数 ++ sem_t clientWaitSem; // 等待client结果信号量 ++ sem_t clientReturnSem; // client返回结果信号量 ++ PluginCom pluginCom; ++ PluginLog *log; + + std::map valueMaps; + // process Block. + std::map blockMaps; + std::map basicblockMaps; + std::map defOpMaps; +- bool ProcessBlock(mlir::Block*, mlir::Region&, const Json::Value&); + ++ /* 解析客户端发送过来的-fplugin-arg参数,并保存在私有变量args中 */ ++ void ParseArgv(const string& data); ++ void ServerSemPost(const string& port); // server服务起来后通知client ++ /* 将注册点和函数名发到客户端, stream为grpc当前数据流指针 */ ++ void SendRegisteredUserOpts(); ++ void ExecCallbacks(const string& name); ++ static PluginServer *pluginServerPtr; + }; // class PluginServer +- +-void RunServer(int timeout, string& port); + } // namespace PinServer + + #endif +diff --git a/lib/PluginServer/PluginCom.cpp b/lib/PluginServer/PluginCom.cpp +new file mode 100755 +index 0000000..ab171c7 +--- /dev/null ++++ b/lib/PluginServer/PluginCom.cpp +@@ -0,0 +1,164 @@ ++/* Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. ++ ++ Licensed under the Apache License, Version 2.0 (the "License"); you may ++ not use this file except in compliance with the License. You may obtain ++ a copy of the License at ++ ++ http://www.apache.org/licenses/LICENSE-2.0 ++ ++ Unless required by applicable law or agreed to in writing, software ++ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT ++ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the ++ License for the specific language governing permissions and limitations ++ under the License. ++ ++ Author: Mingchuan Wu and Yancheng Li ++ Create: 2022-08-18 ++ Description: ++ This file contains the implementation of the PluginCom class. ++ 主要完成功能:和client之间通信、数据解析、数据反序列化 ++*/ ++ ++#include "PluginServer/PluginCom.h" ++#include "PluginServer/PluginLog.h" ++ ++namespace PinCom { ++int64_t PluginCom::GetIntegerDataResult(void) ++{ ++ int64_t result = integerResult; ++ integerResult = 0; // clear ++ return result; ++} ++ ++string PluginCom::GetStringDataResult(void) ++{ ++ string result = stringResult; ++ stringResult.clear(); // clear ++ return result; ++} ++ ++vector PluginCom::GetFunctionOpResult(void) ++{ ++ vector retOps = this->funcOpData; ++ this->funcOpData.clear(); ++ this->opData.clear(); ++ return retOps; ++} ++ ++vector PluginCom::GetOpResult(void) ++{ ++ vector retOps = opData; ++ opData.clear(); ++ return retOps; ++} ++ ++vector PluginCom::GetLocalDeclResult(void) ++{ ++ vector retOps = decls; ++ decls.clear(); ++ return retOps; ++} ++ ++vector PluginCom::LoopOpsResult(void) ++{ ++ vector retLoops = loops; ++ loops.clear(); ++ return retLoops; ++} ++ ++mlir::Plugin::LoopOp PluginCom::LoopOpResult(void) ++{ ++ mlir::Plugin::LoopOp retLoop = loop; ++ return retLoop; ++} ++ ++std::pair PluginCom::EdgeResult() ++{ ++ std::pair e; ++ e.first = edge.first; ++ e.second = edge.second; ++ return e; ++} ++ ++vector > PluginCom::EdgesResult() ++{ ++ vector > retEdges; ++ retEdges = edges; ++ edges.clear(); ++ return retEdges; ++} ++ ++bool PluginCom::GetBoolResult() ++{ ++ return this->boolResult; ++} ++ ++uint64_t PluginCom::GetIdResult() ++{ ++ return this->idResult; ++} ++ ++vector PluginCom::GetIdsResult() ++{ ++ vector retIds = idsResult; ++ idsResult.clear(); ++ return retIds; ++} ++ ++mlir::Value PluginCom::GetValueResult() ++{ ++ return this->valueResult; ++} ++ ++vector PluginCom::GetPhiOpsResult() ++{ ++ vector retOps; ++ for (auto item : opData) { ++ mlir::Plugin::PhiOp p = llvm::dyn_cast(item); ++ retOps.push_back(p); ++ } ++ opData.clear(); ++ return retOps; ++} ++ ++void PluginCom::JsonDeSerialize(const string& key, const string& data) ++{ ++ if (key == "FuncOpResult") { ++ json.FuncOpJsonDeSerialize(data, this->funcOpData); ++ } else if (key == "LocalDeclOpResult") { ++ json.LocalDeclOpJsonDeSerialize(data, this->decls); ++ } else if (key == "LoopOpResult") { ++ this->loop = json.LoopOpJsonDeSerialize (data); ++ } else if (key == "LoopOpsResult") { ++ json.LoopOpsJsonDeSerialize (data, this->loops); ++ } else if (key == "BoolResult") { ++ this->boolResult = (bool)atol(data.c_str()); ++ } else if (key == "VoidResult") { ++ ; ++ } else if (key == "EdgeResult") { ++ json.EdgeJsonDeSerialize(data, this->edge); ++ } else if (key == "EdgesResult") { ++ json.EdgesJsonDeSerialize(data, this->edges); ++ } else if (key == "IdsResult") { ++ json.IdsJsonDeSerialize(data, this->idsResult); ++ } else if (key == "IdResult") { ++ this->idResult = atol(data.c_str()); ++ } else if (key == "OpsResult") { ++ json.OpJsonDeSerialize(data.c_str(), this->opData); ++ } else if (key == "ValueResult") { ++ Json::Value node; ++ Json::Reader reader; ++ reader.parse(data, node); ++ this->valueResult = json.ValueJsonDeSerialize(node); ++ } else if (key == "GetPhiOps") { ++ json.GetPhiOpsJsonDeSerialize(data, this->opData); ++ } else if (key == "IntegerResult") { ++ json.IntegerDeSerialize(data, integerResult); ++ } else if (key == "StringResult") { ++ json.StringDeSerialize(data, stringResult); ++ } else { ++ PinLog::PluginLog::GetInstance()->LOGE("not Json,key:%s,value:%s\n", key.c_str(), data.c_str()); ++ } ++} ++} // namespace PinCom ++ +diff --git a/lib/PluginServer/PluginGrpc.cpp b/lib/PluginServer/PluginGrpc.cpp +new file mode 100755 +index 0000000..659b3ef +--- /dev/null ++++ b/lib/PluginServer/PluginGrpc.cpp +@@ -0,0 +1,82 @@ ++/* Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. ++ ++ Licensed under the Apache License, Version 2.0 (the "License"); you may ++ not use this file except in compliance with the License. You may obtain ++ a copy of the License at ++ ++ http://www.apache.org/licenses/LICENSE-2.0 ++ ++ Unless required by applicable law or agreed to in writing, software ++ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT ++ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the ++ License for the specific language governing permissions and limitations ++ under the License. ++ ++ Author: Mingchuan Wu and Yancheng Li ++ Create: 2022-08-18 ++ Description: ++ This file contains the implementation of the PluginGrpc class. ++ 主要完成功能:完成grpc server服务的注册,提供server和client之间grpc收发接口 ++*/ ++ ++#include ++#include "PluginServer/PluginServer.h" ++ ++namespace PinGrpc { ++void PluginGrpc::ServerSend(const string& key, const string& value) ++{ ++ ServerMsg serverMsg; ++ serverMsg.set_attribute(key); ++ serverMsg.set_value(value); ++ grpcStream->Write(serverMsg); ++} ++ ++Status PluginGrpc::ReceiveSendMsg(ServerContext* context, ServerReaderWriter* stream) ++{ ++ ClientMsg clientMsg; ++ grpcStream = stream; ++ ++ while (stream->Read(&clientMsg)) { ++ PinServer::PluginServer::GetInstance()->ClientMsgProc(clientMsg.attribute(), clientMsg.value()); ++ } ++ return Status::OK; ++} ++ ++void PluginGrpc::ServerMonitorThread() ++{ ++ int delay = 100000; // 100ms ++ pid_t initPid = 1; ++ while (1) { ++ if (shutdown || (getppid() == initPid)) { ++ grpcServer->Shutdown(); ++ break; ++ } ++ usleep(delay); ++ } ++} ++ ++bool PluginGrpc::RegisterServer(const string& port) ++{ ++ string serverAddress = "0.0.0.0:" + port; ++ ServerBuilder builder; ++ int serverPort = 0; ++ // Listen on the given address without any authentication mechanism. ++ builder.AddListeningPort(serverAddress, grpc::InsecureServerCredentials(), &serverPort); ++ builder.RegisterService(this); ++ grpcServer = std::unique_ptr(builder.BuildAndStart()); ++ if (serverPort != atoi(port.c_str())) { ++ return false; ++ } ++ return true; ++} ++ ++void PluginGrpc::Run() ++{ ++ std::thread serverExtiThread(&PluginGrpc::ServerMonitorThread, this); ++ serverExtiThread.join(); ++ ++ // Wait for the server to shutdown. Note that some other thread must be ++ // responsible for shutting down the server for this call to ever return. ++ grpcServer->Wait(); ++} ++} // namespace PinGrpc +diff --git a/lib/PluginServer/main.cpp b/lib/PluginServer/main.cpp +index 5ec007b..fac574e 100644 +--- a/lib/PluginServer/main.cpp ++++ b/lib/PluginServer/main.cpp +@@ -19,15 +19,20 @@ + */ + + #include "PluginServer/PluginServer.h" +-#include "PluginServer/PluginLog.h" ++ ++using namespace PinServer; + + int main(int argc, char** argv) + { +- int timeout = atoi(argv[0]); +- std::string port = argv[1]; +- PinServer::LogPriority priority = (PinServer::LogPriority)atoi(argv[2]); +- PinServer::SetLogPriority(priority); +- PinServer::RunServer(timeout, port); +- PinServer::CloseLog(); ++ const int argcNum = 2; // 参数只有2个,argv[0]:port argv[1]:log级别 ++ if (argc != argcNum) { ++ printf("param num:%d, should be:%d\n", argc, argcNum); ++ return -1; ++ } ++ printf("main arg: %s, %s\n", argv[0], argv[1]); ++ std::string port = argv[0]; ++ LogPriority priority = (LogPriority)atoi(argv[1]); ++ PluginServer server(priority, port); ++ server.RunServer(); + return 0; + } +\ No newline at end of file +diff --git a/user.cpp b/user.cpp +index cdb0b99..a6fe555 100644 +--- a/user.cpp ++++ b/user.cpp +@@ -27,7 +27,9 @@ + #include "PluginAPI/PluginServerAPI.h" + #include "PluginServer/PluginLog.h" + #include "PluginAPI/ControlFlowAPI.h" ++#include "PluginServer/PluginOptBase.h" + ++namespace PluginOpt { + using std::string; + using std::vector; + using std::cout; +@@ -83,15 +85,13 @@ static void PassManagerSetupFunc(void) + printf("PassManagerSetupFunc in\n"); + } + +-enum EDGE_FLAG +-{ ++enum EDGE_FLAG { + EDGE_FALLTHRU, + EDGE_TRUE_VALUE, + EDGE_FALSE_VALUE + }; + +-struct edgeDef +-{ ++struct edgeDef { + Block *src; + Block *dest; + unsigned destIdx; +@@ -100,84 +100,74 @@ struct edgeDef + typedef struct edgeDef edge; + typedef struct edgeDef *edgePtr; + +-static vector +-getPredecessors (Block *bb) ++static vector getPredecessors(Block *bb) + { + vector preds; +- for (auto it = bb->pred_begin(); it != bb->pred_end(); ++it) +- { ++ for (auto it = bb->pred_begin(); it != bb->pred_end(); ++it) { + Block *pred = *it; + preds.push_back(pred); + } + return preds; + } + +-static unsigned +-getNumPredecessor (Block *bb) ++static unsigned getNumPredecessor(Block *bb) + { + vector preds = getPredecessors(bb); + return preds.size(); + } + +-static unsigned +-getIndexPredecessor (Block *bb, Block *pred) ++static unsigned getIndexPredecessor(Block *bb, Block *pred) + { + unsigned i; + vector preds = getPredecessors(bb); +- for (i = 0; i < getNumPredecessor(bb); i++) +- { +- if (preds[i] == pred) +- break; ++ for (i = 0; i < getNumPredecessor(bb); i++) { ++ if (preds[i] == pred) { ++ break; ++ } + } + return i; + } + +-static enum EDGE_FLAG +-getEdgeFlag (Block *src, Block *dest) ++static enum EDGE_FLAG GetEdgeFlag(Block *src, Block *dest) + { + Operation *op = src->getTerminator(); + enum EDGE_FLAG flag; +- if (isa(op)) +- { ++ if (isa(op)) { + flag = EDGE_FALLTHRU; + } +- if (isa(op)) +- { +- if (op->getSuccessor(0) == dest) ++ if (isa(op)) { ++ if (op->getSuccessor(0) == dest) { + flag = EDGE_TRUE_VALUE; +- else ++ } else { + flag = EDGE_FALSE_VALUE; ++ } + } + return flag; + } + + +-static vector +-getPredEdges (Block *bb) ++static vector GetPredEdges(Block *bb) + { + unsigned i = 0; + vector edges; +- for (auto it = bb->pred_begin(); it != bb->pred_end(); ++it) +- { ++ for (auto it = bb->pred_begin(); it != bb->pred_end(); ++it) { + Block *pred = *it; + edge e; + e.src = pred; + e.dest = bb; + e.destIdx = i; +- e.flag = getEdgeFlag(bb, pred); ++ e.flag = GetEdgeFlag(bb, pred); + edges.push_back(e); + i++; + } + return edges; + } + +-static edge +-getEdge (Block *src, Block *dest) ++static edge GetEdge(Block *src, Block *dest) + { +- vector edges = getPredEdges (dest); ++ vector edges = GetPredEdges(dest); + edge e; +- for (auto elm : edges) +- { ++ for (auto elm : edges) { + if (elm.src == src) { + e = elm; + break; +@@ -186,24 +176,21 @@ getEdge (Block *src, Block *dest) + return e; + } + +-static unsigned +-getEdgeDestIdx (Block *src, Block *dest) ++static unsigned GetEdgeDestIdx(Block *src, Block *dest) + { +- edge e = getEdge(src, dest); ++ edge e = GetEdge(src, dest); + return e.destIdx; + } + +-static bool +-isEqualEdge (edge e1, edge e2) ++static bool IsEqualEdge(edge e1, edge e2) + { +- if (e1.src == e2.src && e1.dest == e2.dest && e1.destIdx == e2.destIdx +- && e1.flag == e2.flag) ++ if (e1.src == e2.src && e1.dest == e2.dest && e1.destIdx == e2.destIdx && e1.flag == e2.flag) { + return true; ++ } + return false; + } + +-static IDefineCode +-getValueDefCode (Value v) ++static IDefineCode getValueDefCode(Value v) + { + IDefineCode rescode; + if (auto ssaop = dyn_cast(v.getDefiningOp())) { +@@ -212,16 +199,14 @@ getValueDefCode (Value v) + rescode = memop.defCode().getValue(); + } else if (auto constop = dyn_cast(v.getDefiningOp())) { + rescode = constop.defCode().getValue(); +- }else { ++ } else { + auto holderop = dyn_cast(v.getDefiningOp()); + rescode = holderop.defCode().getValue(); + } +- // assert(rescode == IDefineCode::UNDEF); + return rescode; + } + +-static uint64_t +-getValueId (Value v) ++static uint64_t getValueId(Value v) + { + uint64_t resid; + if (auto ssaop = dyn_cast(v.getDefiningOp())) { +@@ -230,15 +215,14 @@ getValueId (Value v) + resid = memop.id(); + } else if (auto constop = dyn_cast(v.getDefiningOp())) { + resid = constop.id(); +- }else { ++ } else { + auto holderop = dyn_cast(v.getDefiningOp()); + resid = holderop.id(); + } + return resid; + } + +-static PluginIR::PluginTypeBase +-getPluginTypeofValue (Value v) ++static PluginIR::PluginTypeBase getPluginTypeofValue(Value v) + { + PluginIR::PluginTypeBase type; + if (auto ssaop = dyn_cast(v.getDefiningOp())) { +@@ -247,15 +231,14 @@ getPluginTypeofValue (Value v) + type = memop.getResultType().dyn_cast(); + } else if (auto constop = dyn_cast(v.getDefiningOp())) { + type = constop.getResultType().dyn_cast(); +- }else { ++ } else { + auto holderop = dyn_cast(v.getDefiningOp()); + type = holderop.getResultType().dyn_cast(); + } + return type; + } + +-static bool +-isValueExist (Value v) ++static bool isValueExist(Value v) + { + uint64_t vid = getValueId(v); + if (vid != 0) { +@@ -264,60 +247,58 @@ isValueExist (Value v) + return false; + } + +-static bool +-isEqualValue (Value v1, Value v2) ++static bool isEqualValue(Value v1, Value v2) + { + uint64_t v1id = getValueId(v1); + uint64_t v2id = getValueId(v2); +- if (v1id != 0 && v2id != 0 && v1id == v2id) ++ if (v1id != 0 && v2id != 0 && v1id == v2id) { + return true; ++ } + return false; + } + +-static bool +-isSingleRhsAssignOp (Operation *op) ++static bool isSingleRhsAssignOp(Operation *op) + { +- if (!isa(op)) ++ if (!isa(op)) { + return false; +- if (op->getNumOperands() == 2) ++ } ++ if (op->getNumOperands() == 2) { + return true; ++ } + return false; + } + +-static bool +-isBinaryRhsAssignOp (Operation *op) ++static bool isBinaryRhsAssignOp(Operation *op) + { +- if (!isa(op)) ++ if (!isa(op)) { + return false; +- if (op->getNumOperands() == 3) ++ } ++ if (op->getNumOperands() == 3) { + return true; ++ } + return false; + } + +-static IDefineCode +-getSingleRhsAssignOpCode (Operation *op) ++static IDefineCode getSingleRhsAssignOpCode(Operation *op) + { + auto assignOp = dyn_cast(op); + Value v = assignOp.GetRHS1(); + return getValueDefCode(v); + } + +-static IExprCode +-getBinaryRhsAssignOpCode (Operation *op) ++static IExprCode getBinaryRhsAssignOpCode(Operation *op) + { + auto assignOp = dyn_cast(op); + return assignOp.exprCode(); + } + +-static int64_t +-getRealValueIntCST (Value v) ++static int64_t getRealValueIntCST(Value v) + { + auto constOp = dyn_cast(v.getDefiningOp()); + return constOp.initAttr().cast().getInt(); + } + +-static Operation * +-getSSADefStmtofValue (Value v) ++static Operation *getSSADefStmtofValue(Value v) + { + if (!isa(v.getDefiningOp())) { + return NULL; +@@ -330,17 +311,16 @@ getSSADefStmtofValue (Value v) + return op; + } + +-struct originLoopInfo +-{ +- Value base; /* The initial index of the array in the old loop. */ ++struct originLoopInfo { ++ Value base; /* The initial index of the array in the old loop. */ + Value *baseptr; +- Value limit; /* The limit index of the array in the old loop. */ ++ Value limit; /* The limit index of the array in the old loop. */ + Value *limitptr; +- Value arr1; /* Array 1 in the old loop. */ ++ Value arr1; /* Array 1 in the old loop. */ + Value *arr1ptr; +- Value arr2; /* Array 2 in the old loop. */ ++ Value arr2; /* Array 2 in the old loop. */ + Value *arr2ptr; +- edge entryEdge; /* The edge into the old loop. */ ++ edge entryEdge; /* The edge into the old loop. */ + edgePtr entryEdgePtr; + Block *exitBB1; + Block *exitBB2; +@@ -352,10 +332,9 @@ struct originLoopInfo + Operation *condOp2; + Operation *updateStmt; + bool existPrologAssgin; +- /* Whether the marker has an initial value assigned +- to the array index. */ ++ /* Whether the marker has an initial value assigned to the array index. */ + uint64_t step; +- /* The growth step of the loop induction variable. */ ++ /* The growth step of the loop induction variable. */ + }; + + typedef struct originLoopInfo originLoopInfo; +@@ -363,32 +342,31 @@ typedef struct originLoopInfo originLoopInfo; + static originLoopInfo originLoop; + + /* Return true if the loop has precisely one backedge. */ +- +-static bool +-isLoopSingleBackedge (LoopOp loop) ++static bool isLoopSingleBackedge(LoopOp loop) + { + Block *latch = loop.GetLatch(); + unsigned numSucc = latch->getNumSuccessors(); +- if (numSucc != 1) ++ if (numSucc != 1) { + return false; ++ } + + Block *header = loop.GetHeader(); + Block *latchSuccBB = latch->getSuccessor(numSucc-1); + +- if (latchSuccBB != header) ++ if (latchSuccBB != header) { + return false; ++ } + + return true; + } + + /* Return true if the loop has precisely one preheader BB. */ +- +-static bool +-isLoopSinglePreheaderBB (LoopOp loop) ++static bool isLoopSinglePreheaderBB(LoopOp loop) + { + Block *header = loop.GetHeader(); +- if (getNumPredecessor(header) != 2) ++ if (getNumPredecessor(header) != 2) { + return false; ++ } + + vector preds = getPredecessors(header); + Block *headerPred1 = preds[0]; +@@ -396,39 +374,37 @@ isLoopSinglePreheaderBB (LoopOp loop) + + Block *latch = loop.GetLatch(); + if ((headerPred1 == latch && !loop.IsLoopFather(headerPred2)) +- || (headerPred2 == latch && !loop.IsLoopFather(headerPred1))) ++ || (headerPred2 == latch && !loop.IsLoopFather(headerPred1))) { + return true; ++ } + return false; + } + + /* Initialize the originLoop structure. */ +-static void +-initOriginLoopStructure () ++static void InitOriginLoopStructure() + { +- originLoop.baseptr = nullptr; +- originLoop.limitptr = nullptr; +- originLoop.arr1ptr = nullptr; +- originLoop.arr2ptr = nullptr; +- originLoop.exitE1Ptr = nullptr; +- originLoop.exitE2Ptr = nullptr; +- originLoop.exitBB1 = nullptr; +- originLoop.exitBB2 =nullptr; +- originLoop.entryEdgePtr = nullptr; +- originLoop.condOp1 = nullptr; +- originLoop.condOp2 = nullptr; +- originLoop.updateStmt = nullptr; +- originLoop.existPrologAssgin = false; +- originLoop.step = 0; ++ originLoop.baseptr = nullptr; ++ originLoop.limitptr = nullptr; ++ originLoop.arr1ptr = nullptr; ++ originLoop.arr2ptr = nullptr; ++ originLoop.exitE1Ptr = nullptr; ++ originLoop.exitE2Ptr = nullptr; ++ originLoop.exitBB1 = nullptr; ++ originLoop.exitBB2 =nullptr; ++ originLoop.entryEdgePtr = nullptr; ++ originLoop.condOp1 = nullptr; ++ originLoop.condOp2 = nullptr; ++ originLoop.updateStmt = nullptr; ++ originLoop.existPrologAssgin = false; ++ originLoop.step = 0; + } + +-static vector +-getLoopExitEdges (LoopOp loop) ++static vector getLoopExitEdges(LoopOp loop) + { + vector> bbPairInfo = loop.GetExitEdges(); + vector edges; + for (auto elm : bbPairInfo) { +- edge e; +- e = getEdge(elm.first, elm.second); ++ edge e = GetEdge(elm.first, elm.second); + edges.push_back(e); + } + return edges; +@@ -436,51 +412,53 @@ getLoopExitEdges (LoopOp loop) + + /* Make sure the exit condition stmt satisfies a specific form. */ + +-static bool +-checkCondOp (Operation *op) ++static bool checkCondOp(Operation *op) + { +- if (!op) ++ if (!op) { + return false; +- if (!isa(op)) ++ } ++ if (!isa(op)) { + return false; ++ } + + auto cond = dyn_cast(op); + +- if (cond.condCode() != IComparisonCode::ne +- && cond.condCode() != IComparisonCode::eq) ++ if (cond.condCode() != IComparisonCode::ne && cond.condCode() != IComparisonCode::eq) { + return false; ++ } + + Value lhs = cond.GetLHS(); + Value rhs = cond.GetRHS(); +- +- if (getValueDefCode(lhs) != IDefineCode::SSA +- || getValueDefCode(rhs) != IDefineCode::SSA) ++ if (getValueDefCode(lhs) != IDefineCode::SSA || getValueDefCode(rhs) != IDefineCode::SSA) { + return false; ++ } + +- return true; ++ return true; + } + + /* Record the exit information in the original loop including exit edge, + exit bb block, exit condition stmt, +- eg: exit_eX origin_exit_bbX cond_stmtX. */ ++ eg: exitEX originLoop.exitBBX condOpX. */ + +-static bool +-recordOriginLoopExitInfo (LoopOp loop) ++static bool recordOriginLoopExitInfo(LoopOp loop) + { + bool found = false; + Operation *op; + + if (originLoop.exitE1Ptr != nullptr || originLoop.exitBB1 != nullptr + || originLoop.exitE2Ptr != nullptr || originLoop.exitBB2 != nullptr +- || originLoop.condOp1 != nullptr || originLoop.condOp2 != nullptr) ++ || originLoop.condOp1 != nullptr || originLoop.condOp2 != nullptr) { + return false; ++ } + + vector exitEdges = getLoopExitEdges (loop); +- if (exitEdges.empty()) ++ if (exitEdges.empty()) { + return false; ++ } + +- if (exitEdges.size() != 2) ++ if (exitEdges.size() != 2) { + return false; ++ } + for (auto e : exitEdges) { + if (e.src == loop.GetHeader()) { + originLoop.exitE1 = e; +@@ -502,21 +480,19 @@ recordOriginLoopExitInfo (LoopOp loop) + } + } + } +- +- + +- if (originLoop.exitE1Ptr != nullptr && originLoop.exitBB1 != nullptr ++ if (originLoop.exitE1Ptr != nullptr && originLoop.exitBB1 != nullptr + && originLoop.exitE2Ptr != nullptr && originLoop.exitBB2 != nullptr +- && originLoop.condOp1 != nullptr && originLoop.condOp2 != nullptr) +- found = true; ++ && originLoop.condOp1 != nullptr && originLoop.condOp2 != nullptr) { ++ found = true; ++ } + +- return found; ++ return found; + } + + /* Get the edge that first entered the loop. */ + +-static edge +-getLoopPreheaderEdge (LoopOp loop) ++static edge getLoopPreheaderEdge(LoopOp loop) + { + Block *header = loop.GetHeader(); + vector preds = getPredecessors(header); +@@ -529,54 +505,56 @@ getLoopPreheaderEdge (LoopOp loop) + } + } + +- edge e = getEdge(src, header); ++ edge e = GetEdge(src, header); + + return e; + } + +-/* Returns true if t is SSA_NAME and user variable exists. */ ++/* Returns true if t is SSAOp and user variable exists. */ + +-static bool +-isSSANameVar (Value v) ++static bool isSSANameVar(Value v) + { +- if (!isValueExist(v) || getValueDefCode(v) != IDefineCode::SSA) ++ if (!isValueExist(v) || getValueDefCode(v) != IDefineCode::SSA) { + return false; ++ } + auto ssaOp = dyn_cast(v.getDefiningOp()); + uint64_t varid = ssaOp.nameVarId(); +- if (varid != 0) ++ if (varid != 0) { + return true; ++ } + return false; + } + +-/* Returns true if t1 and t2 are SSA_NAME and belong to the same variable. */ ++/* Returns true if t1 and t2 are SSAOp and belong to the same variable. */ + +-static bool +-isSameSSANameVar (Value v1, Value v2) ++static bool isSameSSANameVar(Value v1, Value v2) + { +- if (!isSSANameVar (v1) || !isSSANameVar (v2)) ++ if (!isSSANameVar (v1) || !isSSANameVar (v2)) { + return false; ++ } + auto ssaOp1 = dyn_cast(v1.getDefiningOp()); + auto ssaOp2 = dyn_cast(v2.getDefiningOp()); + uint64_t varid1 = ssaOp1.nameVarId(); + uint64_t varid2 = ssaOp2.nameVarId(); +- if (varid1 == varid2) ++ if (varid1 == varid2) { + return true; ++ } + return false; + } + + /* Get origin loop induction variable upper bound. */ +- +-static bool +-getIvUpperBound (CondOp cond) ++static bool getIvUpperBound(CondOp cond) + { +- if (originLoop.limitptr != nullptr) ++ if (originLoop.limitptr != nullptr) { + return false; ++ } + + Value lhs = cond.GetLHS(); + Value rhs = cond.GetRHS(); +- +- if (!getPluginTypeofValue(lhs).isa() || !getPluginTypeofValue(rhs).isa()) ++ if (!getPluginTypeofValue(lhs).isa() ++ || !getPluginTypeofValue(rhs).isa()) { + return false; ++ } + + originLoop.limit = rhs; + originLoop.limitptr = &originLoop.limit; +@@ -587,18 +565,16 @@ getIvUpperBound (CondOp cond) + return false; + } + +-/* Returns true only when the expression on the rhs code of stmt is PLUS_EXPR, +- rhs1 is SSA_NAME with the same var as originLoop base, and rhs2 is +- INTEGER_CST. */ +- +-static bool +-checkUpdateStmt (Operation *op) ++/* Returns true only when the expression on the rhs code of stmt is PLUS, ++ rhs1 is SSAOp with the same var as originLoop base, and rhs2 is ++ ConstOp. */ ++static bool checkUpdateStmt(Operation *op) + { +- if (!op || !isa(op)) ++ if (!op || !isa(op)) { + return false; ++ } + auto assignOp = dyn_cast(op); + if (assignOp.exprCode() == IExprCode::Plus) { +- + Value rhs1 = assignOp.GetRHS1(); + Value rhs2 = assignOp.GetRHS2(); + if (getValueDefCode(rhs1) == IDefineCode::SSA +@@ -615,42 +591,43 @@ checkUpdateStmt (Operation *op) + } + + /* Get origin loop induction variable initial value. */ +- +-static bool +-getIvBase (CondOp cond) ++static bool getIvBase(CondOp cond) + { +- if (originLoop.baseptr != nullptr || originLoop.updateStmt != nullptr) ++ if (originLoop.baseptr != nullptr || originLoop.updateStmt != nullptr) { + return false; ++ } + + Value lhs = cond.GetLHS(); +- + Block *header = cond.getOperation()->getBlock(); +- + auto &opList = header->getOperations(); + for (auto it = opList.begin(); it != opList.end(); ++it) { + Operation *op = &(*it); +- if (!isa(op)) ++ if (!isa(op)) { + continue; ++ } + auto phi = dyn_cast(op); + Value result = phi.GetResult(); +- if (!isSameSSANameVar (result, lhs)) ++ if (!isSameSSANameVar (result, lhs)) { + continue; ++ } + Value base = phi.GetArgDef(originLoop.entryEdge.destIdx); +- if (!isSameSSANameVar (base, lhs)) ++ if (!isSameSSANameVar (base, lhs)) { + return false; ++ } + + originLoop.base = base; + originLoop.baseptr = &originLoop.base; +- vector edges = getPredEdges(header); ++ vector edges = GetPredEdges(header); + for (auto e : edges) { +- +- if (!isEqualEdge(e, originLoop.entryEdge)) { ++ if (!IsEqualEdge(e, originLoop.entryEdge)) { + Value ivAfter = phi.GetArgDef(e.destIdx); +- if (!isa(ivAfter.getDefiningOp())) ++ if (!isa(ivAfter.getDefiningOp())) { + return false; ++ } + Operation *op = getSSADefStmtofValue(ivAfter); +- if (!checkUpdateStmt (op)) ++ if (!checkUpdateStmt (op)) { + return false; ++ } + originLoop.updateStmt = op; + if (op->getBlock() == header && isEqualValue(ivAfter, lhs)) { + originLoop.existPrologAssgin = true; +@@ -672,60 +649,58 @@ getIvBase (CondOp cond) + ...... + For such a loop, ++len will be processed before entering header_bb, and the + assign is regarded as the prolog_assign of the loop. */ +- +-static bool +-recordOriginLoopHeader (LoopOp loop) ++static bool recordOriginLoopHeader(LoopOp loop) + { + Block *header = loop.GetHeader(); +- + if (originLoop.entryEdgePtr != nullptr || originLoop.baseptr != nullptr +- || originLoop.updateStmt != nullptr || originLoop.limitptr != nullptr) ++ || originLoop.updateStmt != nullptr || originLoop.limitptr != nullptr) { + return false; ++ } + originLoop.entryEdge = getLoopPreheaderEdge (loop); + originLoop.entryEdgePtr = &originLoop.entryEdge; + auto &opList = header->getOperations(); + for (auto it = opList.rbegin(); it != opList.rend(); ++it) { + Operation *op = &(*it); +- if (isa(op)) ++ if (isa(op)) { + continue; ++ } + + if (auto cond = dyn_cast(op)) { +- if (!getIvUpperBound (cond)) ++ if (!getIvUpperBound(cond)) { + return false; +- if (!getIvBase (cond)) ++ } ++ if (!getIvBase(cond)) { + return false; ++ } + } else if (auto assign = dyn_cast(op)) { +- + if (op != originLoop.updateStmt || !originLoop.existPrologAssgin) { + return false; + } +- } +- else { ++ } else { + return false; + } + } + +- if (originLoop.entryEdgePtr != nullptr && originLoop.baseptr != nullptr ++ if (originLoop.entryEdgePtr != nullptr && originLoop.baseptr != nullptr + && originLoop.updateStmt != nullptr && originLoop.limitptr != nullptr) { + return true; + } + +- return false; ++ return false; + } + + /* When prolog_assign does not exist, make sure that updateStmt exists in the + loop latch, and its form is a specific form, eg: + len_2 = len_1 + 1. */ +- +-static bool +-recordOriginLoopLatch (LoopOp loop) ++static bool recordOriginLoopLatch(LoopOp loop) + { + Block *latch = loop.GetLatch(); + Operation *op = latch->getTerminator(); + + if (originLoop.existPrologAssgin) { +- if (isa(op)) ++ if (isa(op)) { + return true; ++ } + } + + // Todo: else分支处理别的场景,待添加 +@@ -733,14 +708,13 @@ recordOriginLoopLatch (LoopOp loop) + return false; + } + +-/* Returns true when the DEF_STMT corresponding to arg0 of the mem_ref tree +- satisfies the POINTER_PLUS_EXPR type. */ +- +-static bool +-checkBodyMemRef (Value memRef) ++/* Returns true when the define STMT corresponding to arg0 of the MemOp ++ satisfies the PtrPlus type. */ ++static bool checkBodyMemRef(Value memRef) + { +- if(getValueDefCode(memRef) != IDefineCode::MemRef) ++ if (getValueDefCode(memRef) != IDefineCode::MemRef) { + return false; ++ } + + auto memOp = dyn_cast(memRef.getDefiningOp()); + Value realarg0 = memOp.GetBase(); +@@ -748,7 +722,6 @@ checkBodyMemRef (Value memRef) + PluginServerAPI pluginapi; + Value arg0 = pluginapi.ConfirmValue(realarg0); + Value arg1 = pluginapi.ConfirmValue(realarg1); +- + if (getPluginTypeofValue(arg0).isa() + && getValueDefCode(arg1) == IDefineCode::IntCST + && getRealValueIntCST(arg1) == 0) { +@@ -762,9 +735,7 @@ checkBodyMemRef (Value memRef) + + /* Returns true if the rh2 of the current stmt comes from the base in the + original loop. */ +- +-static bool +-checkBodyPointerPlus (Operation *op, Value &tmpIndex) ++static bool checkBodyPointerPlus(Operation *op, Value &tmpIndex) + { + auto assignOp = dyn_cast(op); + Value rhs1 = assignOp.GetRHS1(); +@@ -775,17 +746,17 @@ checkBodyPointerPlus (Operation *op, Value &tmpIndex) + if (g && isSingleRhsAssignOp(g) && getBinaryRhsAssignOpCode(g) == IExprCode::Nop) { + auto nopOp = dyn_cast(g); + Value nopRhs = nopOp.GetRHS1(); +- + if (isSameSSANameVar(nopRhs, originLoop.base)) { + if (!originLoop.arr1ptr) { + originLoop.arr1 = rhs1; + originLoop.arr1ptr = &originLoop.arr1; + tmpIndex = rhs2; +- } else if(!originLoop.arr2ptr) { +- originLoop.arr2 = rhs1; +- originLoop.arr2ptr = &originLoop.arr2; +- if (!isEqualValue(tmpIndex, rhs2)) +- return false; ++ } else if (!originLoop.arr2ptr) { ++ originLoop.arr2 = rhs1; ++ originLoop.arr2ptr = &originLoop.arr2; ++ if (!isEqualValue(tmpIndex, rhs2)) { ++ return false; ++ } + } else { + return false; + } +@@ -796,15 +767,11 @@ checkBodyPointerPlus (Operation *op, Value &tmpIndex) + return false; + } + +- + /* Record the array comparison information in the original loop, while ensuring +- that there are only statements related to cont_stmt in the loop body. */ +- +-static bool +-recordOriginLoopBody (LoopOp loop) ++ that there are only statements related to cont stmt in the loop body. */ ++static bool recordOriginLoopBody(LoopOp loop) + { + Block *body = originLoop.condOp2->getBlock(); +- + map visited; + for (auto &op : *body) { + visited[&op] = false; +@@ -813,8 +780,9 @@ recordOriginLoopBody (LoopOp loop) + Value condLhs = dyn_cast(originLoop.condOp2).GetLHS(); + Value condRhs = dyn_cast(originLoop.condOp2).GetRHS(); + if (!(getPluginTypeofValue(condLhs).isa()) +- || !(getPluginTypeofValue(condRhs).isa())) ++ || !(getPluginTypeofValue(condRhs).isa())) { + return false; ++ } + + vector worklist; + worklist.push_back(condLhs); +@@ -822,63 +790,68 @@ recordOriginLoopBody (LoopOp loop) + Value tmpIndex; + visited[originLoop.condOp2] = true; + +- while (!worklist.empty()) +- { ++ while (!worklist.empty()) { + Value v = worklist.back(); + worklist.pop_back(); + Operation *op = getSSADefStmtofValue(v); + +- if (!op || op->getBlock() != body || !isa(op)) ++ if (!op || op->getBlock() != body || !isa(op)) { + continue; ++ } + visited[op] = true; + if (isSingleRhsAssignOp(op) && getSingleRhsAssignOpCode(op) == IDefineCode::MemRef) { + auto assignopmem = dyn_cast(op); + Value memRef = assignopmem.GetRHS1(); +- if (!checkBodyMemRef(memRef)) ++ if (!checkBodyMemRef(memRef)) { + return false; ++ } + auto memOp = dyn_cast(memRef.getDefiningOp()); + Value arg0 = memOp.GetBase(); +- worklist.push_back(arg0);//memref arg0 +- }else if (isBinaryRhsAssignOp(op) && getBinaryRhsAssignOpCode(op) == IExprCode::PtrPlus) { ++ worklist.push_back(arg0); // memref arg0 ++ } else if (isBinaryRhsAssignOp(op) && getBinaryRhsAssignOpCode(op) == IExprCode::PtrPlus) { + auto assignop2 = dyn_cast(op); + Value rhs2 = assignop2.GetRHS2(); +- if (!checkBodyPointerPlus(op, tmpIndex)) ++ if (!checkBodyPointerPlus(op, tmpIndex)) { + return false; ++ } + worklist.push_back(rhs2); +- }else if (isSingleRhsAssignOp(op) && getBinaryRhsAssignOpCode(op) == IExprCode::Nop){ ++ } else if (isSingleRhsAssignOp(op) && getBinaryRhsAssignOpCode(op) == IExprCode::Nop) { + auto assignop = dyn_cast(op); + Value rhs = assignop.GetRHS1(); +- if (!isSameSSANameVar(rhs, originLoop.base)) ++ if (!isSameSSANameVar(rhs, originLoop.base)) { + return false; ++ } + worklist.push_back(rhs); +- }else { ++ } else { + return false; + } + } + bool allvisited = true; +- if (allvisited) ++ if (allvisited) { + return true; ++ } + + return false; + } + + /* Returns true only if the exit bb of the original loop is unique and its phi + node parameter comes from the same variable. */ +- +-static bool +-checkExitBB (LoopOp loop) ++static bool checkExitBB(LoopOp loop) + { +- if (originLoop.exitBB1 != originLoop.exitBB2 +- || loop.IsBlockInside (originLoop.exitBB1)) +- return false; ++ if (originLoop.exitBB1 != originLoop.exitBB2 ++ || loop.IsBlockInside (originLoop.exitBB1)) { ++ return false; ++ } + + for (auto &op : *originLoop.exitBB1) { +- if (!isa(op)) ++ if (!isa(op)) { + continue; ++ } + auto phi = dyn_cast(op); + Value result = phi.GetResult(); +- if (!isSameSSANameVar(result, originLoop.base)) ++ if (!isSameSSANameVar(result, originLoop.base)) { + continue; ++ } + if (phi.nArgs() == 2) { + Value arg0 = phi.GetArgDef(0); + Value arg1 = phi.GetArgDef(1); +@@ -892,131 +865,122 @@ checkExitBB (LoopOp loop) + + /* Make sure that the recorded originLoop information meets the + relative requirements. */ +- +-static bool +-checkOriginLoopInfo (LoopOp loop) ++static bool checkOriginLoopInfo(LoopOp loop) + { +- if (!checkExitBB (loop)) ++ if (!checkExitBB (loop)) { + return false; ++ } + +- if (getValueDefCode(originLoop.base) != IDefineCode::SSA) ++ if (getValueDefCode(originLoop.base) != IDefineCode::SSA) { + return false; ++ } + +- if (getValueDefCode(originLoop.limit) != IDefineCode::SSA) ++ if (getValueDefCode(originLoop.limit) != IDefineCode::SSA) { + return false; ++ } + + auto limitssaop = dyn_cast(originLoop.limit.getDefiningOp()); +- +- if (!limitssaop.readOnly().getValue()) ++ if (!limitssaop.readOnly().getValue()) { + return false; ++ } + + if (!getPluginTypeofValue(originLoop.arr1).isa() +- || !getPluginTypeofValue(originLoop.arr2).isa()) ++ || !getPluginTypeofValue(originLoop.arr2).isa()) { + return false; ++ } + + auto arr1type = getPluginTypeofValue(originLoop.arr1).dyn_cast(); + auto arr2type = getPluginTypeofValue(originLoop.arr2).dyn_cast(); +- +- if (!arr1type.isReadOnlyElem() || !arr2type.isReadOnlyElem()) ++ if (!arr1type.isReadOnlyElem() || !arr2type.isReadOnlyElem()) { + return false; ++ } + + if (!arr1type.getElementType().isa() +- || !arr2type.getElementType().isa()) ++ || !arr2type.getElementType().isa()) { + return false; ++ } + + auto elemTy1 = arr1type.getElementType().dyn_cast(); + auto elemTy2 = arr2type.getElementType().dyn_cast(); +- +- if (elemTy1.getWidth() != 8 || elemTy2.getWidth() != 8) ++ if (elemTy1.getWidth() != 8 || elemTy2.getWidth() != 8) { + return false; ++ } + + return true; + } + + // /* Record the useful information of the original loop and judge whether the + // information meets the specified conditions. */ +- +-static bool +-checkRecordLoopForm (LoopOp loop) ++static bool checkRecordLoopForm(LoopOp loop) + { +- if (!recordOriginLoopExitInfo (loop)) +- { ++ if (!recordOriginLoopExitInfo (loop)) { + printf ("\nFailed to record loop exit information.\n"); + return false; + } + +- if (!recordOriginLoopHeader (loop)) +- { ++ if (!recordOriginLoopHeader (loop)) { + printf ("\nFailed to record loop header information.\n"); + return false; + } + +- if (!recordOriginLoopLatch (loop)) +- { ++ if (!recordOriginLoopLatch (loop)) { + printf ("\nFailed to record loop latch information.\n"); + return false; + } + +- if (!recordOriginLoopBody (loop)) +- { ++ if (!recordOriginLoopBody (loop)) { + printf ("\nFailed to record loop body information.\n"); + return false; + } + +- if (!checkOriginLoopInfo (loop)) +- { ++ if (!checkOriginLoopInfo (loop)) { + printf ("\nFailed to check origin loop information.\n"); + return false; + } + +- return true; ++ return true; + } + +-static bool +-determineLoopForm(LoopOp loop) ++static bool determineLoopForm(LoopOp loop) + { +- if (loop.innerLoopIdAttr().getInt() != 0 && loop.numBlockAttr().getInt() != 3) +- { ++ if (loop.innerLoopIdAttr().getInt() != 0 && loop.numBlockAttr().getInt() != 3) { + printf ("\nWrong loop form, there is inner loop or redundant bb.\n"); + return false; + } + +- if (loop.GetSingleExit().first || !loop.GetLatch()) +- { ++ if (loop.GetSingleExit().first || !loop.GetLatch()) { + printf ("\nWrong loop form, only one exit or loop_latch does not exist.\n"); + return false; + } + +- if (!isLoopSingleBackedge(loop)) +- { ++ if (!isLoopSingleBackedge(loop)) { + printf ("\nWrong loop form, loop back edges are not unique.\n"); + return false; + } + +- if (!isLoopSinglePreheaderBB(loop)) +- { ++ if (!isLoopSinglePreheaderBB(loop)) { + printf ("\nWrong loop form, loop preheader bb are not unique.\n"); + return false; + } + +- initOriginLoopStructure(); +- if (!checkRecordLoopForm(loop)) ++ InitOriginLoopStructure(); ++ if (!checkRecordLoopForm(loop)) { + return false; ++ } + return true; + } + +- +-static void +-update_loop_dominator(uint64_t dir, FunctionOp* funcOp) ++static void update_loop_dominator(uint64_t dir, FunctionOp* funcOp) + { + ControlFlowAPI cfAPI; + mlir::Region ®ion = funcOp->bodyRegion(); + PluginServerAPI pluginAPI; + +- for (auto &bb : region.getBlocks()) +- { ++ for (auto &bb : region.getBlocks()) { + uint64_t bbAddr = pluginAPI.FindBasicBlock(&bb); +- if (bbAddr == 0) continue; ++ if (bbAddr == 0) { ++ continue; ++ } + uint64_t i_bbAddr = cfAPI.GetImmediateDominator(dir, bbAddr); + if (!i_bbAddr || &bb == originLoop.exitBB1) { + cfAPI.SetImmediateDominator(1, pluginAPI.FindBasicBlock(&bb), \ +@@ -1026,8 +990,7 @@ update_loop_dominator(uint64_t dir, FunctionOp* funcOp) + } + } + +-static void +-remove_originLoop(LoopOp *loop, FunctionOp* funcOp) ++static void remove_originLoop(LoopOp *loop, FunctionOp* funcOp) + { + vector body; + ControlFlowAPI controlapi; +@@ -1035,15 +998,13 @@ remove_originLoop(LoopOp *loop, FunctionOp* funcOp) + body = loop->GetLoopBody(); + unsigned n = loop->numBlockAttr().getInt(); + for (unsigned i = 0; i < n; i++) { +- // body[i]->erase(); + controlapi.DeleteBlock(body[i], funcOp->idAttr().getInt(), pluginAPI.FindBasicBlock(body[i])); + } + loop->Delete(); + } + +-static void +-create_prolog_bb( +- Block *prolog_bb, Block *after_bb, Block *dominator_bb, LoopOp *outer, edge entryEdge, FunctionOp *funcOp, Block *ftBB) ++static void create_prolog_bb(Block *prolog_bb, Block *after_bb, Block *dominator_bb, ++ LoopOp *outer, edge entryEdge, FunctionOp *funcOp, Block *ftBB) + { + mlir::Value lhs1; + +@@ -1052,14 +1013,14 @@ create_prolog_bb( + + pluginAPI.AddBlockToLoop(pluginAPI.FindBasicBlock(prolog_bb), outer->idAttr().getInt()); + +- FallThroughOp fp =llvm::dyn_cast(entryEdge.src->back()); +- pluginAPI.RedirectFallthroughTarget(fp, pluginAPI.FindBasicBlock(entryEdge.src), pluginAPI.FindBasicBlock(prolog_bb)); ++ FallThroughOp fp = llvm::dyn_cast(entryEdge.src->back()); ++ pluginAPI.RedirectFallthroughTarget(fp, pluginAPI.FindBasicBlock(entryEdge.src), ++ pluginAPI.FindBasicBlock(prolog_bb)); + cfAPI.SetImmediateDominator(1, pluginAPI.FindBasicBlock(prolog_bb), pluginAPI.FindBasicBlock(dominator_bb)); + + SSAOp baseSsa = dyn_cast(originLoop.base.getDefiningOp()); + lhs1 = baseSsa.Copy(); + +- + opBuilder->setInsertionPointToStart(prolog_bb); + llvm::SmallVector ops; + if (originLoop.existPrologAssgin) { +@@ -1069,8 +1030,7 @@ create_prolog_bb( + mlir::Value step = ConstOp::CreateConst(*opBuilder, attr, originLoop.base.getType()); + ops.push_back(step); + AssignOp opa = opBuilder->create(opBuilder->getUnknownLoc(), ops, IExprCode::Plus, prolog_bb); +- } +- else { ++ } else { + ops.push_back(lhs1); + ops.push_back(originLoop.base); + AssignOp op = opBuilder->create(opBuilder->getUnknownLoc(), ops, IExprCode::Nop, prolog_bb); +@@ -1080,8 +1040,7 @@ create_prolog_bb( + defs_map.emplace(prolog_bb, lhs1); + } + +-static void +-create_loop_pred_bb( ++static void create_loop_pred_bb( + Block *loop_pred_bb, Block* after_bb, Block* dominator_bb, LoopOp *outer, FunctionOp *funcOp, Block *ftBB) + { + ControlFlowAPI cfAPI; +@@ -1095,8 +1054,7 @@ create_loop_pred_bb( + defs_map.emplace(loop_pred_bb, baseSsa.GetCurrentDef()); + } + +-static void +-create_align_loop_header(Block *align_loop_header, Block* after_bb, ++static void create_align_loop_header(Block *align_loop_header, Block* after_bb, + Block* dominator_bb, LoopOp *outer, FunctionOp *funcOp, Block* tb, Block* fb) + { + CondOp cond_stmt; +@@ -1114,11 +1072,11 @@ create_align_loop_header(Block *align_loop_header, Block* after_bb, + cfAPI.CreateNewDef(entry_node, phi.getOperation()); + res = phi.GetResult(); + +- + opBuilder->setInsertionPointToStart(align_loop_header); + llvm::SmallVector ops; + +- PluginIR::PluginTypeBase baseType = PluginIR::PluginIntegerType::get(context, 64, PluginIR::PluginIntegerType::Unsigned); ++ PluginIR::PluginTypeBase baseType = PluginIR::PluginIntegerType::get(context, 64, ++ PluginIR::PluginIntegerType::Unsigned); + ops.push_back(SSAOp::MakeSSA(*opBuilder, baseType)); + ops.push_back(res); + AssignOp op1 = opBuilder->create(opBuilder->getUnknownLoc(), ops, IExprCode::Nop, (align_loop_header)); +@@ -1138,25 +1096,25 @@ create_align_loop_header(Block *align_loop_header, Block* after_bb, + ops.push_back(lhs2); + ops.push_back(lhs3); + +- cond_stmt = opBuilder->create(opBuilder->getUnknownLoc(), IComparisonCode::le, lhs2, lhs3, tb, fb, (align_loop_header)); ++ cond_stmt = opBuilder->create(opBuilder->getUnknownLoc(), IComparisonCode::le, ++ lhs2, lhs3, tb, fb, (align_loop_header)); + + baseSsa.SetCurrentDef(res); + defs_map.emplace(align_loop_header, res); + } + +-static void +-rewrite_add_phi_arg(Block* bb) ++static void rewrite_add_phi_arg(Block* bb) + { + ControlFlowAPI cf; + PluginServerAPI pluginAPI; + vector phis = cf.GetAllPhiOpInsideBlock(bb); + for (auto phi : phis) { + Value res = phi.GetResult(); +- vector bv = getPredecessors (bb); ++ vector bv = getPredecessors (bb); + int j = 0; + for (int i = bv.size()-1; i>=0; i--) { + if (phi.GetArgDef(j++)) { +- continue; ++ continue; + } + + Value var = (defs_map[bv[i]]); +@@ -1181,9 +1139,8 @@ static LoopOp *init_new_loop(LoopOp *outer_loop, Block* header, Block* latch, Fu + return new_loop; + } + +-static void +-create_align_loop_body_bb(Block *align_loop_body_bb, Block* after_bb, Block* dominator_bb, LoopOp *outer, FunctionOp *funcOp, +- Block* tb, Block* fb) ++static void create_align_loop_body_bb(Block *align_loop_body_bb, Block* after_bb, Block* dominator_bb, ++ LoopOp *outer, FunctionOp *funcOp, Block* tb, Block* fb) + { + CondOp cond_stmt; + Value lhs1, lhs2; +@@ -1192,27 +1149,32 @@ create_align_loop_body_bb(Block *align_loop_body_bb, Block* after_bb, Block* dom + + pluginAPI.AddBlockToLoop(pluginAPI.FindBasicBlock(align_loop_body_bb), outer->idAttr().getInt()); + +- cfAPI.SetImmediateDominator(1, pluginAPI.FindBasicBlock(align_loop_body_bb), pluginAPI.FindBasicBlock(dominator_bb)); ++ cfAPI.SetImmediateDominator(1, pluginAPI.FindBasicBlock(align_loop_body_bb), ++ pluginAPI.FindBasicBlock(dominator_bb)); + + opBuilder->setInsertionPointToStart(align_loop_body_bb); + llvm::SmallVector ops; + + SSAOp baseSsa = dyn_cast(originLoop.base.getDefiningOp()); +- PluginIR::PluginTypeBase sizeType = PluginIR::PluginIntegerType::get(context, 64, PluginIR::PluginIntegerType::Unsigned); ++ PluginIR::PluginTypeBase sizeType = PluginIR::PluginIntegerType::get(context, 64, ++ PluginIR::PluginIntegerType::Unsigned); + + ops.push_back(SSAOp::MakeSSA(*opBuilder, sizeType)); + + ops.push_back(baseSsa.GetCurrentDef()); +- AssignOp op1 = opBuilder->create(opBuilder->getUnknownLoc(), ops, IExprCode::Nop, (align_loop_body_bb)); ++ AssignOp op1 = opBuilder->create(opBuilder->getUnknownLoc(), ops, ++ IExprCode::Nop, (align_loop_body_bb)); + Value var = op1.GetLHS(); + ops.clear(); + ops.push_back(SSAOp::MakeSSA(*opBuilder, originLoop.arr2.getType())); + ops.push_back(originLoop.arr2); + ops.push_back(var); +- AssignOp op2 = opBuilder->create(opBuilder->getUnknownLoc(), ops, IExprCode::PtrPlus, (align_loop_body_bb)); ++ AssignOp op2 = opBuilder->create(opBuilder->getUnknownLoc(), ops, ++ IExprCode::PtrPlus, (align_loop_body_bb)); + lhs1 = op2.GetLHS(); + ops.clear(); +- PluginIR::PluginTypeBase baseType = PluginIR::PluginIntegerType::get(context, 64, PluginIR::PluginIntegerType::Unsigned); ++ PluginIR::PluginTypeBase baseType = PluginIR::PluginIntegerType::get(context, 64, ++ PluginIR::PluginIntegerType::Unsigned); + PluginIR::PluginTypeBase pointerTy = PluginIR::PluginPointerType::get(context, baseType, 0); + ops.push_back(SSAOp::MakeSSA(*opBuilder, baseType)); + mlir::Attribute asdada = opBuilder->getI64IntegerAttr(0); +@@ -1224,7 +1186,8 @@ create_align_loop_body_bb(Block *align_loop_body_bb, Block* after_bb, Block* dom + ops.push_back(SSAOp::MakeSSA(*opBuilder, originLoop.arr1.getType())); + ops.push_back(originLoop.arr1); + ops.push_back(var); +- AssignOp op4 = opBuilder->create(opBuilder->getUnknownLoc(), ops, IExprCode::PtrPlus, (align_loop_body_bb)); ++ AssignOp op4 = opBuilder->create(opBuilder->getUnknownLoc(), ops, ++ IExprCode::PtrPlus, (align_loop_body_bb)); + lhs2 = op4.GetLHS(); + ops.clear(); + +@@ -1232,15 +1195,16 @@ create_align_loop_body_bb(Block *align_loop_body_bb, Block* after_bb, Block* dom + ops.push_back(pluginAPI.BuildMemRef( + baseType, lhs2, ConstOp::CreateConst(*opBuilder, opBuilder->getI64IntegerAttr(0), pointerTy))); + +- AssignOp op5 = opBuilder->create(opBuilder->getUnknownLoc(), ops, IExprCode::UNDEF, (align_loop_body_bb)); ++ AssignOp op5 = opBuilder->create(opBuilder->getUnknownLoc(), ops, ++ IExprCode::UNDEF, (align_loop_body_bb)); + lhs2 = op5.GetLHS(); + +- cond_stmt = opBuilder->create(opBuilder->getUnknownLoc(), ++ cond_stmt = opBuilder->create(opBuilder->getUnknownLoc(), + llvm::dyn_cast(originLoop.condOp2).condCode(), lhs1, lhs2, tb, fb, (align_loop_body_bb)); + } + +-static void +-create_align_loop_latch(Block *align_loop_latch, Block* after_bb, Block* dominator_bb, LoopOp *outer, FunctionOp *funcOp, Block *ftBB) ++static void create_align_loop_latch(Block *align_loop_latch, Block* after_bb, Block* dominator_bb, ++ LoopOp *outer, FunctionOp *funcOp, Block *ftBB) + { + Value res; + ControlFlowAPI cfAPI; +@@ -1251,7 +1215,8 @@ create_align_loop_latch(Block *align_loop_latch, Block* after_bb, Block* dominat + + pluginAPI.AddBlockToLoop(pluginAPI.FindBasicBlock(align_loop_latch), outer->idAttr().getInt()); + +- cfAPI.SetImmediateDominator(1, pluginAPI.FindBasicBlock(align_loop_latch), pluginAPI.FindBasicBlock(dominator_bb)); ++ cfAPI.SetImmediateDominator(1, pluginAPI.FindBasicBlock(align_loop_latch), ++ pluginAPI.FindBasicBlock(dominator_bb)); + + res = baseSsa.Copy(); + +@@ -1265,8 +1230,8 @@ create_align_loop_latch(Block *align_loop_latch, Block* after_bb, Block* dominat + defs_map.emplace(align_loop_latch, res); + } + +-static void +-create_align_loop_exit_bb(Block *align_loop_exit_bb, Block* after_bb, Block* dominator_bb, LoopOp *outer, FunctionOp *funcOp, Block *ftBB) ++static void create_align_loop_exit_bb(Block *align_loop_exit_bb, Block* after_bb, Block* dominator_bb, ++ LoopOp *outer, FunctionOp *funcOp, Block *ftBB) + { + CondOp cond_stmt; + Value lhs1, lhs2; +@@ -1279,7 +1244,8 @@ create_align_loop_exit_bb(Block *align_loop_exit_bb, Block* after_bb, Block* dom + + pluginAPI.AddBlockToLoop(pluginAPI.FindBasicBlock(align_loop_exit_bb), outer->idAttr().getInt()); + +- cfAPI.SetImmediateDominator(1, pluginAPI.FindBasicBlock(align_loop_exit_bb), pluginAPI.FindBasicBlock(dominator_bb)); ++ cfAPI.SetImmediateDominator(1, pluginAPI.FindBasicBlock(align_loop_exit_bb), ++ pluginAPI.FindBasicBlock(dominator_bb)); + + cond_stmt = llvm::dyn_cast(after_bb->back()); + cond_lhs = cond_stmt.GetLHS(); +@@ -1290,12 +1256,14 @@ create_align_loop_exit_bb(Block *align_loop_exit_bb, Block* after_bb, Block* dom + ops.push_back((SSAOp::MakeSSA(*opBuilder, cond_lhs.getType()))); + ops.push_back(cond_lhs); + ops.push_back(cond_rhs); +- AssignOp op1 = opBuilder->create(opBuilder->getUnknownLoc(), ops, IExprCode::BitXOR, (align_loop_exit_bb)); ++ AssignOp op1 = opBuilder->create(opBuilder->getUnknownLoc(), ops, ++ IExprCode::BitXOR, (align_loop_exit_bb)); + lhs1 = op1.GetLHS(); + ops.clear(); + ops.push_back(lhs1); + build_ctzll = opBuilder->create(opBuilder->getUnknownLoc(), ops, (align_loop_exit_bb)); +- PluginIR::PluginTypeBase intType = PluginIR::PluginIntegerType::get(context, 32, PluginIR::PluginIntegerType::Signed); ++ PluginIR::PluginTypeBase intType = ++ PluginIR::PluginIntegerType::get(context, 32, PluginIR::PluginIntegerType::Signed); + lhs1 = SSAOp::MakeSSA(*opBuilder, intType); + build_ctzll.SetLHS(lhs1); + +@@ -1325,8 +1293,8 @@ create_align_loop_exit_bb(Block *align_loop_exit_bb, Block* after_bb, Block* dom + defs_map.emplace(align_loop_exit_bb, lhs2); + } + +-static void +-create_epilogue_loop_header(Block *epilogue_loop_header, Block* after_bb, Block* dominator_bb, LoopOp *outer, FunctionOp *funcOp, Block* tb, Block* fb) ++static void create_epilogue_loop_header(Block *epilogue_loop_header, Block* after_bb, Block* dominator_bb, ++ LoopOp *outer, FunctionOp *funcOp, Block* tb, Block* fb) + { + CondOp cond_stmt; + Value res; +@@ -1337,10 +1305,10 @@ create_epilogue_loop_header(Block *epilogue_loop_header, Block* after_bb, Block* + SSAOp baseSsa = dyn_cast(originLoop.base.getDefiningOp()); + Value entry_node = baseSsa.GetCurrentDef(); + +- + pluginAPI.AddBlockToLoop(pluginAPI.FindBasicBlock(epilogue_loop_header), outer->idAttr().getInt()); + +- cfAPI.SetImmediateDominator(1, pluginAPI.FindBasicBlock(epilogue_loop_header), pluginAPI.FindBasicBlock(dominator_bb)); ++ cfAPI.SetImmediateDominator(1, pluginAPI.FindBasicBlock(epilogue_loop_header), ++ pluginAPI.FindBasicBlock(dominator_bb)); + + phi = PhiOp::CreatePhi(nullptr, epilogue_loop_header); + cfAPI.CreateNewDef(entry_node, phi.getOperation()); +@@ -1348,17 +1316,16 @@ create_epilogue_loop_header(Block *epilogue_loop_header, Block* after_bb, Block* + + opBuilder->setInsertionPointToStart(epilogue_loop_header); + +- cond_stmt = +- opBuilder->create(opBuilder->getUnknownLoc(), llvm::dyn_cast(originLoop.condOp1).condCode(), res, originLoop.limit, tb, fb, (epilogue_loop_header)); ++ cond_stmt = opBuilder->create(opBuilder->getUnknownLoc(), ++ llvm::dyn_cast(originLoop.condOp1).condCode(), res, originLoop.limit, tb, fb, (epilogue_loop_header)); + + baseSsa.SetCurrentDef(res); + defs_map.emplace(epilogue_loop_header, res); + } + +-static void +-create_epilogue_loop_body_bb(Block *epilogue_loop_body_bb, Block* after_bb, Block* dominator_bb, LoopOp *outer, FunctionOp *funcOp, Block* tb, Block* fb) ++static void create_epilogue_loop_body_bb(Block *epilogue_loop_body_bb, Block* after_bb, Block* dominator_bb, ++ LoopOp *outer, FunctionOp *funcOp, Block* tb, Block* fb) + { +- + AssignOp g; + CondOp cond_stmt; + Value lhs1, lhs2, lhs3; +@@ -1368,30 +1335,35 @@ create_epilogue_loop_body_bb(Block *epilogue_loop_body_bb, Block* after_bb, Bloc + SSAOp baseSsa = dyn_cast(originLoop.base.getDefiningOp()); + Value entry_node = baseSsa.GetCurrentDef(); + +- + pluginAPI.AddBlockToLoop(pluginAPI.FindBasicBlock(epilogue_loop_body_bb), outer->idAttr().getInt()); + +- cfAPI.SetImmediateDominator(1, pluginAPI.FindBasicBlock(epilogue_loop_body_bb), pluginAPI.FindBasicBlock(dominator_bb)); ++ cfAPI.SetImmediateDominator(1, pluginAPI.FindBasicBlock(epilogue_loop_body_bb), ++ pluginAPI.FindBasicBlock(dominator_bb)); + + opBuilder->setInsertionPointToStart(epilogue_loop_body_bb); + llvm::SmallVector ops; + +- PluginIR::PluginTypeBase sizeType = PluginIR::PluginIntegerType::get(context, 64, PluginIR::PluginIntegerType::Unsigned); ++ PluginIR::PluginTypeBase sizeType = PluginIR::PluginIntegerType::get(context, 64, ++ PluginIR::PluginIntegerType::Unsigned); + ops.push_back(SSAOp::MakeSSA(*opBuilder, sizeType)); + ops.push_back(entry_node); +- AssignOp op1 = opBuilder->create(opBuilder->getUnknownLoc(), ops, IExprCode::Nop, (epilogue_loop_body_bb)); ++ AssignOp op1 = opBuilder->create(opBuilder->getUnknownLoc(), ops, ++ IExprCode::Nop, (epilogue_loop_body_bb)); + lhs1 = op1.GetLHS(); + ops.clear(); + ops.push_back(SSAOp::MakeSSA(*opBuilder, originLoop.arr1.getType())); + ops.push_back(originLoop.arr1); + ops.push_back(lhs1); +- AssignOp op2 = opBuilder->create(opBuilder->getUnknownLoc(), ops, IExprCode::PtrPlus, (epilogue_loop_body_bb)); ++ AssignOp op2 = opBuilder->create(opBuilder->getUnknownLoc(), ops, ++ IExprCode::PtrPlus, (epilogue_loop_body_bb)); + lhs2 = op2.GetLHS(); + + ops.clear(); +- PluginIR::PluginTypeBase charType = PluginIR::PluginIntegerType::get(context, 8, PluginIR::PluginIntegerType::Unsigned); ++ PluginIR::PluginTypeBase charType = PluginIR::PluginIntegerType::get(context, 8, ++ PluginIR::PluginIntegerType::Unsigned); + ops.push_back(SSAOp::MakeSSA(*opBuilder, charType)); +- ops.push_back(pluginAPI.BuildMemRef(charType, lhs2, ConstOp::CreateConst(*opBuilder, opBuilder->getI64IntegerAttr(0), lhs2.getType()))); ++ ops.push_back(pluginAPI.BuildMemRef(charType, lhs2, ++ ConstOp::CreateConst(*opBuilder, opBuilder->getI64IntegerAttr(0), lhs2.getType()))); + g = opBuilder->create(opBuilder->getUnknownLoc(), ops, IExprCode::UNDEF, (epilogue_loop_body_bb)); + + lhs2 = g.GetLHS(); +@@ -1400,37 +1372,37 @@ create_epilogue_loop_body_bb(Block *epilogue_loop_body_bb, Block* after_bb, Bloc + ops.push_back(SSAOp::MakeSSA(*opBuilder, originLoop.arr2.getType())); + ops.push_back(originLoop.arr2); + ops.push_back(lhs1); +- AssignOp op3 = opBuilder->create(opBuilder->getUnknownLoc(), ops, IExprCode::PtrPlus, (epilogue_loop_body_bb)); ++ AssignOp op3 = opBuilder->create(opBuilder->getUnknownLoc(), ops, ++ IExprCode::PtrPlus, (epilogue_loop_body_bb)); + lhs3 = op3.GetLHS(); + + ops.clear(); + + ops.push_back(SSAOp::MakeSSA(*opBuilder, charType)); +- ops.push_back(pluginAPI.BuildMemRef(charType, lhs3, ConstOp::CreateConst(*opBuilder, opBuilder->getI64IntegerAttr(0), lhs3.getType()))); ++ ops.push_back(pluginAPI.BuildMemRef(charType, lhs3, ConstOp::CreateConst(*opBuilder, ++ opBuilder->getI64IntegerAttr(0), lhs3.getType()))); + g = opBuilder->create(opBuilder->getUnknownLoc(), ops, IExprCode::UNDEF, (epilogue_loop_body_bb)); + + Value res = g.GetLHS(); +- cond_stmt = opBuilder->create(opBuilder->getUnknownLoc(), llvm::dyn_cast(originLoop.condOp1).condCode(), res, originLoop.limit, tb, fb, (epilogue_loop_body_bb)); ++ cond_stmt = opBuilder->create(opBuilder->getUnknownLoc(), ++ llvm::dyn_cast(originLoop.condOp1).condCode(), res, originLoop.limit, tb, fb, (epilogue_loop_body_bb)); + + defs_map.emplace(epilogue_loop_body_bb, baseSsa.GetCurrentDef()); + } + +-static void +-create_epilogue_loop_latch(Block *epilogue_loop_latch, +- Block *after_bb, Block *dominator_bb, +- LoopOp *outer, FunctionOp *funcOp, Block *ftBB) ++static void create_epilogue_loop_latch(Block *epilogue_loop_latch, ++ Block *after_bb, Block *dominator_bb, LoopOp *outer, FunctionOp *funcOp, Block *ftBB) + { +- + Value res; + ControlFlowAPI cfAPI; + PluginServerAPI pluginAPI; + SSAOp baseSsa = dyn_cast(originLoop.base.getDefiningOp()); + Value entry_node = baseSsa.GetCurrentDef(); + +- + pluginAPI.AddBlockToLoop(pluginAPI.FindBasicBlock(epilogue_loop_latch), outer->idAttr().getInt()); + +- cfAPI.SetImmediateDominator(1, pluginAPI.FindBasicBlock(epilogue_loop_latch), pluginAPI.FindBasicBlock(dominator_bb)); ++ cfAPI.SetImmediateDominator(1, pluginAPI.FindBasicBlock(epilogue_loop_latch), ++ pluginAPI.FindBasicBlock(dominator_bb)); + + SSAOp entrySsa = dyn_cast(entry_node.getDefiningOp()); + res = entrySsa.Copy(); +@@ -1439,7 +1411,8 @@ create_epilogue_loop_latch(Block *epilogue_loop_latch, + llvm::SmallVector ops; + ops.push_back(res); + ops.push_back(entry_node); +- ops.push_back(ConstOp::CreateConst(*opBuilder, opBuilder->getI64IntegerAttr(originLoop.step), entry_node.getType())); ++ ops.push_back(ConstOp::CreateConst(*opBuilder, ++ opBuilder->getI64IntegerAttr(originLoop.step), entry_node.getType())); + opBuilder->create(opBuilder->getUnknownLoc(), ops, IExprCode::Plus, (epilogue_loop_latch)); + + opBuilder->create(opBuilder->getUnknownLoc(), pluginAPI.FindBasicBlock(epilogue_loop_latch), ftBB); +@@ -1447,8 +1420,7 @@ create_epilogue_loop_latch(Block *epilogue_loop_latch, + defs_map.emplace(epilogue_loop_latch, res); + } + +-static void +-create_new_loops(edge entryEdge, FunctionOp *funcOp) ++static void create_new_loops(edge entryEdge, FunctionOp *funcOp) + { + Block* prolog_bb; + Block* align_loop_header, *align_loop_latch, *align_loop_body_bb; +@@ -1461,78 +1433,97 @@ create_new_loops(edge entryEdge, FunctionOp *funcOp) + ControlFlowAPI cfAPI; + LoopOp outer = pluginAPI.GetBlockLoopFather(pluginAPI.FindBasicBlock(entryEdge.src)); + +- uint64_t bbAddr = cfAPI.CreateBlock(entryEdge.src, funcOp->idAttr().getInt(), pluginAPI.FindBasicBlock(entryEdge.src)); ++ uint64_t bbAddr = cfAPI.CreateBlock(entryEdge.src, funcOp->idAttr().getInt(), ++ pluginAPI.FindBasicBlock(entryEdge.src)); + prolog_bb = pluginAPI.FindBlock(bbAddr); + +- bbAddr = cfAPI.CreateBlock(prolog_bb, funcOp->idAttr().getInt(), pluginAPI.FindBasicBlock(prolog_bb)); +- // pluginAPI.InsertCreatedBlock(bbAddr, prolog_bb); ++ bbAddr = cfAPI.CreateBlock(prolog_bb, funcOp->idAttr().getInt(), ++ pluginAPI.FindBasicBlock(prolog_bb)); + align_pred_bb = pluginAPI.FindBlock(bbAddr); + +- bbAddr = cfAPI.CreateBlock(align_pred_bb, funcOp->idAttr().getInt(), pluginAPI.FindBasicBlock(align_pred_bb)); ++ bbAddr = cfAPI.CreateBlock(align_pred_bb, funcOp->idAttr().getInt(), ++ pluginAPI.FindBasicBlock(align_pred_bb)); + align_loop_header = pluginAPI.FindBlock(bbAddr); + +- bbAddr = cfAPI.CreateBlock(align_loop_header, funcOp->idAttr().getInt(), pluginAPI.FindBasicBlock(align_loop_header)); ++ bbAddr = cfAPI.CreateBlock(align_loop_header, funcOp->idAttr().getInt(), ++ pluginAPI.FindBasicBlock(align_loop_header)); + align_loop_body_bb = pluginAPI.FindBlock(bbAddr); + +- bbAddr = cfAPI.CreateBlock(align_loop_body_bb, funcOp->idAttr().getInt(), pluginAPI.FindBasicBlock(align_loop_body_bb)); ++ bbAddr = cfAPI.CreateBlock(align_loop_body_bb, funcOp->idAttr().getInt(), ++ pluginAPI.FindBasicBlock(align_loop_body_bb)); + align_loop_latch = pluginAPI.FindBlock(bbAddr); + +- bbAddr = cfAPI.CreateBlock(align_loop_body_bb, funcOp->idAttr().getInt(), pluginAPI.FindBasicBlock(align_loop_body_bb)); ++ bbAddr = cfAPI.CreateBlock(align_loop_body_bb, funcOp->idAttr().getInt(), ++ pluginAPI.FindBasicBlock(align_loop_body_bb)); + align_loop_exit_bb = pluginAPI.FindBlock(bbAddr); + +- bbAddr = cfAPI.CreateBlock(align_loop_header, funcOp->idAttr().getInt(), pluginAPI.FindBasicBlock(align_loop_header)); ++ bbAddr = cfAPI.CreateBlock(align_loop_header, funcOp->idAttr().getInt(), ++ pluginAPI.FindBasicBlock(align_loop_header)); + epilogue_loop_pred_bb = pluginAPI.FindBlock(bbAddr); + +- bbAddr = cfAPI.CreateBlock(epilogue_loop_pred_bb, funcOp->idAttr().getInt(), pluginAPI.FindBasicBlock(epilogue_loop_pred_bb)); ++ bbAddr = cfAPI.CreateBlock(epilogue_loop_pred_bb, funcOp->idAttr().getInt(), ++ pluginAPI.FindBasicBlock(epilogue_loop_pred_bb)); + epilogue_loop_header = pluginAPI.FindBlock(bbAddr); + +- bbAddr = cfAPI.CreateBlock(epilogue_loop_header, funcOp->idAttr().getInt(), pluginAPI.FindBasicBlock(epilogue_loop_header)); ++ bbAddr = cfAPI.CreateBlock(epilogue_loop_header, funcOp->idAttr().getInt(), ++ pluginAPI.FindBasicBlock(epilogue_loop_header)); + epilogue_loop_body_bb = pluginAPI.FindBlock(bbAddr); + +- bbAddr = cfAPI.CreateBlock(epilogue_loop_body_bb, funcOp->idAttr().getInt(), pluginAPI.FindBasicBlock(epilogue_loop_body_bb)); ++ bbAddr = cfAPI.CreateBlock(epilogue_loop_body_bb, funcOp->idAttr().getInt(), ++ pluginAPI.FindBasicBlock(epilogue_loop_body_bb)); + epilogue_loop_latch = pluginAPI.FindBlock(bbAddr); + + create_prolog_bb(prolog_bb, entryEdge.src, entryEdge.src, &outer, entryEdge, funcOp, align_pred_bb); + + create_loop_pred_bb(align_pred_bb, prolog_bb, prolog_bb, &outer, funcOp, align_loop_header); + +- create_align_loop_header(align_loop_header, align_pred_bb, align_pred_bb, &outer, funcOp, align_loop_body_bb, epilogue_loop_pred_bb); ++ create_align_loop_header(align_loop_header, align_pred_bb, align_pred_bb, &outer, ++ funcOp, align_loop_body_bb, epilogue_loop_pred_bb); + +- create_align_loop_body_bb(align_loop_body_bb, align_loop_header, align_loop_header, &outer, funcOp, align_loop_exit_bb, align_loop_latch); ++ create_align_loop_body_bb(align_loop_body_bb, align_loop_header, align_loop_header, &outer, ++ funcOp, align_loop_exit_bb, align_loop_latch); + +- create_align_loop_latch(align_loop_latch, align_loop_body_bb, align_loop_body_bb, &outer, funcOp, align_loop_header); ++ create_align_loop_latch(align_loop_latch, align_loop_body_bb, align_loop_body_bb, &outer, ++ funcOp, align_loop_header); + + rewrite_add_phi_arg(align_loop_header); + + align_loop = init_new_loop(&outer, align_loop_header, align_loop_latch, funcOp); + +- create_align_loop_exit_bb(align_loop_exit_bb, align_loop_body_bb, align_loop_body_bb, &outer, funcOp, originLoop.exitBB1); ++ create_align_loop_exit_bb(align_loop_exit_bb, align_loop_body_bb, align_loop_body_bb, &outer, ++ funcOp, originLoop.exitBB1); + +- create_loop_pred_bb(epilogue_loop_pred_bb, align_loop_header, align_loop_header, &outer, funcOp, epilogue_loop_header); ++ create_loop_pred_bb(epilogue_loop_pred_bb, align_loop_header, align_loop_header, &outer, ++ funcOp, epilogue_loop_header); + +- create_epilogue_loop_header(epilogue_loop_header, epilogue_loop_pred_bb, epilogue_loop_pred_bb, &outer, funcOp, epilogue_loop_body_bb, originLoop.exitBB1); ++ create_epilogue_loop_header(epilogue_loop_header, epilogue_loop_pred_bb, epilogue_loop_pred_bb, &outer, ++ funcOp, epilogue_loop_body_bb, originLoop.exitBB1); + +- create_epilogue_loop_body_bb(epilogue_loop_body_bb, epilogue_loop_header, epilogue_loop_header, &outer, funcOp, originLoop.exitBB1 , epilogue_loop_latch); ++ create_epilogue_loop_body_bb(epilogue_loop_body_bb, epilogue_loop_header, epilogue_loop_header, &outer, ++ funcOp, originLoop.exitBB1, epilogue_loop_latch); + +- create_epilogue_loop_latch(epilogue_loop_latch, epilogue_loop_body_bb, epilogue_loop_body_bb, &outer, funcOp, epilogue_loop_header); ++ create_epilogue_loop_latch(epilogue_loop_latch, epilogue_loop_body_bb, epilogue_loop_body_bb, &outer, ++ funcOp, epilogue_loop_header); + + rewrite_add_phi_arg(epilogue_loop_header); + + epilogue_loop = init_new_loop(&outer, epilogue_loop_header, epilogue_loop_latch, funcOp); + +- cfAPI.SetImmediateDominator(1, pluginAPI.FindBasicBlock(originLoop.exitBB1), pluginAPI.FindBasicBlock(entryEdge.src)); +- cfAPI.SetImmediateDominator(1, pluginAPI.FindBasicBlock(originLoop.exitBB2), pluginAPI.FindBasicBlock(entryEdge.src)); ++ cfAPI.SetImmediateDominator(1, pluginAPI.FindBasicBlock(originLoop.exitBB1), ++ pluginAPI.FindBasicBlock(entryEdge.src)); ++ cfAPI.SetImmediateDominator(1, pluginAPI.FindBasicBlock(originLoop.exitBB2), ++ pluginAPI.FindBasicBlock(entryEdge.src)); + + rewrite_add_phi_arg(originLoop.exitBB1); + rewrite_add_phi_arg(originLoop.exitBB2); + +- cfAPI.RemoveEdge(pluginAPI.FindBasicBlock(originLoop.exitE1.src), pluginAPI.FindBasicBlock(originLoop.exitE1.dest)); +- cfAPI.RemoveEdge(pluginAPI.FindBasicBlock(originLoop.exitE2.src), pluginAPI.FindBasicBlock(originLoop.exitE2.dest)); ++ cfAPI.RemoveEdge(pluginAPI.FindBasicBlock(originLoop.exitE1.src), ++ pluginAPI.FindBasicBlock(originLoop.exitE1.dest)); ++ cfAPI.RemoveEdge(pluginAPI.FindBasicBlock(originLoop.exitE2.src), ++ pluginAPI.FindBasicBlock(originLoop.exitE2.dest)); + } + +- +-static void +-convertToNewLoop(LoopOp* loop, FunctionOp* funcOp) ++static void convertToNewLoop(LoopOp* loop, FunctionOp* funcOp) + { + ControlFlowAPI cfAPI; + create_new_loops(originLoop.entryEdge, funcOp); +@@ -1542,9 +1533,7 @@ convertToNewLoop(LoopOp* loop, FunctionOp* funcOp) + return; + } + +- +-static void +-ProcessArrayWiden(void) ++static void ProcessArrayWiden(void) + { + std::cout << "Running first pass, awiden\n"; + +@@ -1567,13 +1556,33 @@ ProcessArrayWiden(void) + } + } + ++class ArrayWidenPass : public PluginOptBase { ++public: ++ ArrayWidenPass() : PluginOptBase(HANDLE_MANAGER_SETUP) ++ { ++ } ++ bool Gate() ++ { ++ return true; ++ } ++ int DoOptimize() ++ { ++ uint64_t *fun = (uint64_t *)GetFuncAddr(); ++ return DoOptimize(fun); ++ } ++ int DoOptimize(uint64_t *fun); ++}; ++ ++int ArrayWidenPass::DoOptimize(uint64_t *fun) ++{ ++ ProcessArrayWiden(); ++ return 0; ++} ++} ++ + void RegisterCallbacks(void) + { +- PluginServer::GetInstance()->RegisterUserFunc(HANDLE_BEFORE_IPA, UserOptimizeFunc); +- PluginServer::GetInstance()->RegisterUserFunc(HANDLE_BEFORE_IPA, LocalVarSummery); +- // ManagerSetupData setupData; +- // setupData.refPassName = PASS_PHIOPT; +- // setupData.passNum = 1; +- // setupData.passPosition = PASS_INSERT_AFTER; +- // PluginServer::GetInstance()->RegisterPassManagerSetup(HANDLE_MANAGER_SETUP, setupData, ProcessArrayWiden); ++ PinServer::PluginServer *pluginServer = PinServer::PluginServer::GetInstance(); ++ PluginOpt::ManagerSetup setupData(PluginOpt::PASS_PHIOPT, 1, PluginOpt::PASS_INSERT_AFTER); ++ pluginServer->RegisterPassManagerOpt(setupData, std::make_shared()); + } +-- +2.27.0.windows.1 + diff --git a/0003-Refactoring-Code-refactoring-of-Communication-Subsys.patch b/0003-Refactoring-Code-refactoring-of-Communication-Subsys.patch new file mode 100644 index 0000000000000000000000000000000000000000..56b7993abe299efe75b84426b0ee0f9c94297ff6 --- /dev/null +++ b/0003-Refactoring-Code-refactoring-of-Communication-Subsys.patch @@ -0,0 +1,1715 @@ +From d395986acddf59c379a107fbe6d1b69c74ff2d3b Mon Sep 17 00:00:00 2001 +From: wangding16 +Date: Wed, 8 Feb 2023 15:16:49 +0800 +Subject: [PATCH 3/9] [Refactoring] Code refactoring of Communication Subsystem + [3/3]. Code refactoring of Communication subsystem. + + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index f1373e8..3a784df 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -92,6 +92,9 @@ add_custom_command(TARGET pin_user COMMAND sha256sum libpin_user.so > libpin_use + add_executable(pin_server + "lib/PluginServer/PluginServer.cpp" + "lib/PluginAPI/ControlFlowAPI.cpp" ++ "lib/PluginServer/PluginGrpc.cpp" ++ "lib/PluginServer/PluginJson.cpp" ++ "lib/PluginServer/PluginCom.cpp" + "lib/PluginServer/PluginLog.cpp" + "lib/PluginServer/main.cpp") + target_link_libraries(pin_server +diff --git a/README.md b/README.md +index f948f51..3513a24 100644 +--- a/README.md ++++ b/README.md +@@ -6,10 +6,8 @@ Pin (Plug-IN framework) server provides plugin APIs for compiler optimization de + + #### 软件架构 + Pin(Plug-IN framework, 插件框架)为生态伙伴提供基于插件IR的编译器优化开发能力,允许开发者使用插件API开发编译器优化pass,并以插件形式向主流编译器(如GCC)提供优化能力。 +-本框架采用插件服务端组件(Pin-Server)和插件客户端模块(Pin-gcc-client)组成代理模式。 ++本框架采用插件服务端组件(Pin-Server)和插件客户端模块组成代理模式。 + Pin-Server为开发者提供插件API进行编译器优化pass的开发。 +-Pin-gcc-client基于GCC插件实现,可以在GCC场景执行优化pass。 +- + + #### 安装教程 + +diff --git a/include/Dialect/PluginDialect.h b/include/Dialect/PluginDialect.h +index 0affbc2..65e03c0 100644 +--- a/include/Dialect/PluginDialect.h ++++ b/include/Dialect/PluginDialect.h +@@ -13,11 +13,11 @@ + under the License. + + */ +-//===----------------------------------------------------------------------===// +-// ++// ===----------------------------------------------------------------------===// ++// + // This is the header file for the Plugin dialect. + // +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + + #ifndef PLUGIN_DIALECT_H + #define PLUGIN_DIALECT_H +diff --git a/include/Dialect/PluginOps.h b/include/Dialect/PluginOps.h +index 8bab877..3c7bd64 100644 +--- a/include/Dialect/PluginOps.h ++++ b/include/Dialect/PluginOps.h +@@ -14,11 +14,11 @@ + + + */ +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // +-// This is the header file for operations in Plugin dialect. ++// This is the header file for operations in Plugin dialect. + // +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + + #ifndef Plugin_OPS_H + #define Plugin_OPS_H +diff --git a/include/Dialect/PluginTypes.h b/include/Dialect/PluginTypes.h +index 0b1f4f4..7fb1ff9 100644 +--- a/include/Dialect/PluginTypes.h ++++ b/include/Dialect/PluginTypes.h +@@ -131,25 +131,19 @@ public: + class PluginVoidType : public Type::TypeBase { + public: + using Base::Base; +- + PluginTypeID getPluginTypeID (); +- + }; // class PluginVoidType + + class PluginUndefType : public Type::TypeBase { + public: + using Base::Base; +- + PluginTypeID getPluginTypeID (); +- + }; // class PluginUndefType + + class PluginBooleanType : public Type::TypeBase { + public: + using Base::Base; +- + PluginTypeID getPluginTypeID (); +- + }; // class PluginBooleanType + + } // namespace PluginIR +diff --git a/include/PluginAPI/BasicPluginOpsAPI.h b/include/PluginAPI/BasicPluginOpsAPI.h +index 68abaef..0ca0ac4 100644 +--- a/include/PluginAPI/BasicPluginOpsAPI.h ++++ b/include/PluginAPI/BasicPluginOpsAPI.h +@@ -37,6 +37,14 @@ public: + BasicPluginOpsAPI() = default; + virtual ~BasicPluginOpsAPI() = default; + ++ virtual int64_t GetInjectDataAddress() = 0; ++ virtual string GetDeclSourceFile(int64_t) = 0; ++ virtual string VariableName(int64_t) = 0; ++ virtual string FuncName(int64_t) = 0; ++ virtual string GetIncludeFile() = 0; ++ virtual int GetDeclSourceLine(int64_t) = 0; ++ virtual int GetDeclSourceColumn(int64_t) = 0; ++ + virtual vector GetAllFunc() = 0; + virtual vector GetDecls(uint64_t) = 0; + virtual LoopOp AllocateNewLoop(uint64_t) = 0; +@@ -74,4 +82,4 @@ public: + }; // class BasicPluginOpsAPI + } // namespace PluginAPI + +-#endif // BASIC_PLUGIN_OPS_FRAMEWORK_API_H +\ No newline at end of file ++#endif // BASIC_PLUGIN_OPS_FRAMEWORK_API_H +diff --git a/include/PluginAPI/PluginServerAPI.h b/include/PluginAPI/PluginServerAPI.h +index 360ffbd..0655d80 100644 +--- a/include/PluginAPI/PluginServerAPI.h ++++ b/include/PluginAPI/PluginServerAPI.h +@@ -52,8 +52,8 @@ public: + vector > GetLoopExitEdges(uint64_t loopID); + mlir::Block* GetHeader(uint64_t loopID); + mlir::Block* GetLatch(uint64_t loopID); +- void SetHeader(uint64_t loopID, uint64_t blockID); +- void SetLatch(uint64_t loopID, uint64_t blockID); ++ void SetHeader(uint64_t loopID, uint64_t blockID); ++ void SetLatch(uint64_t loopID, uint64_t blockID); + vector GetLoopBody(uint64_t loopID); + LoopOp GetBlockLoopFather(uint64_t blockID); + mlir::Block* FindBlock(uint64_t); +@@ -73,7 +73,7 @@ public: + PhiOp CreatePhiOp(uint64_t, uint64_t) override; + /* Plugin API for ConstOp. */ + mlir::Value CreateConstOp(mlir::Attribute, mlir::Type) override; +- void DebugValue(uint64_t) override; ++ void DebugValue(uint64_t) override; + + mlir::Value GetCurrentDefFromSSA(uint64_t) override; + bool SetCurrentDefInSSA(uint64_t, uint64_t) override; +@@ -84,16 +84,15 @@ public: + bool RedirectFallthroughTarget(FallThroughOp&, uint64_t, uint64_t) override; + mlir::Operation* GetSSADefOperation(uint64_t) override; + void InsertCreatedBlock(uint64_t id, mlir::Block* block); +- void WaitClientResult(const string& funName, const string& params); + ++ int64_t GetInjectDataAddress() override; // 获取注入点返回数据的地址 ++ string GetDeclSourceFile(int64_t) override; ++ string VariableName(int64_t) override; ++ string FuncName(int64_t) override; ++ string GetIncludeFile() override; ++ int GetDeclSourceLine(int64_t) override; ++ int GetDeclSourceColumn(int64_t) override; + private: +- vector GetFunctionOpResult(const string& funName, const string& params); +- vector GetDeclOperationResult(const string& funName, const string& params); +- LoopOp GetLoopResult(const string&funName, const string& params); +- vector GetLoopsResult(const string& funName, const string& params); +- bool GetBoolResult(const string& funName, const string& params); +- pair EdgeResult(const string& funName, const string& params); +- vector > EdgesResult(const string& funName, const string& params); + mlir::Block* BlockResult(const string& funName, const string& params); + vector BlocksResult(const string& funName, const string& params); + bool GetDomInfoAvaiResult(const string& funName); +diff --git a/include/PluginServer/ManagerSetup.h b/include/PluginServer/ManagerSetup.h +new file mode 100755 +index 0000000..27ba930 +--- /dev/null ++++ b/include/PluginServer/ManagerSetup.h +@@ -0,0 +1,67 @@ ++/* Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. ++ ++ Licensed under the Apache License, Version 2.0 (the "License"); you may ++ not use this file except in compliance with the License. You may obtain ++ a copy of the License at ++ ++ http://www.apache.org/licenses/LICENSE-2.0 ++ ++ Unless required by applicable law or agreed to in writing, software ++ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT ++ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the ++ License for the specific language governing permissions and limitations ++ under the License. ++ ++ Author: Mingchuan Wu and Yancheng Li ++ Create: 2022-08-18 ++ Description: ++ This file contains the declaration of the ManagerSetup class. ++ 主要完成功能:提供managerSetup注册方法 ++*/ ++ ++#ifndef MANAGER_SETUP_H ++#define MANAGER_SETUP_H ++ ++namespace PluginOpt { ++enum RefPassName { ++ PASS_CFG, ++ PASS_PHIOPT, ++ PASS_SSA, ++ PASS_LOOP, ++}; ++ ++enum PassPosition { ++ PASS_INSERT_AFTER, ++ PASS_INSERT_BEFORE, ++ PASS_REPLACE, ++}; ++ ++class ManagerSetup { ++public: ++ ManagerSetup(RefPassName name, int num, PassPosition position) ++ { ++ refPassName = name; ++ passNum = num; ++ passPosition = position; ++ } ++ RefPassName GetPassName() ++ { ++ return refPassName; ++ } ++ int GetPassNum() ++ { ++ return passNum; ++ } ++ PassPosition GetPassPosition() ++ { ++ return passPosition; ++ } ++ ++private: ++ RefPassName refPassName; ++ int passNum; // 指定passName的第几次执行作为参考点 ++ PassPosition passPosition; // 指定pass是添加在参考点之前还是之后 ++}; ++} // namespace PinOpt ++ ++#endif +\ No newline at end of file +diff --git a/include/PluginServer/PluginCom.h b/include/PluginServer/PluginCom.h +new file mode 100755 +index 0000000..6535362 +--- /dev/null ++++ b/include/PluginServer/PluginCom.h +@@ -0,0 +1,90 @@ ++/* Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. ++ ++ Licensed under the Apache License, Version 2.0 (the "License"); you may ++ not use this file except in compliance with the License. You may obtain ++ a copy of the License at ++ ++ http://www.apache.org/licenses/LICENSE-2.0 ++ ++ Unless required by applicable law or agreed to in writing, software ++ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT ++ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the ++ License for the specific language governing permissions and limitations ++ under the License. ++ ++ Author: Mingchuan Wu and Yancheng Li ++ Create: 2022-08-18 ++ Description: ++ This file contains the declaration of the PluginCom class. ++ 主要完成功能:和client之间通信、数据解析、数据反序列化 ++*/ ++ ++#ifndef PLUGIN_COM_H ++#define PLUGIN_COM_H ++ ++#include "Dialect/PluginOps.h" ++#include "Dialect/PluginTypes.h" ++#include "PluginServer/PluginJson.h" ++#include "PluginServer/PluginGrpc.h" ++ ++namespace PinCom { ++using PinGrpc::PluginGrpc; ++using PinJson::PluginJson; ++using std::vector; ++using std::string; ++ ++class PluginCom { ++public: ++ bool RegisterServer(const string& port) ++ { ++ return pluginGrpc.RegisterServer(port); ++ } ++ void Run() ++ { ++ pluginGrpc.Run(); ++ } ++ void ShutDown() ++ { ++ pluginGrpc.ShutDown(); ++ } ++ void ServerSend(const string& key, const string& value) ++ { ++ pluginGrpc.ServerSend(key, value); ++ } ++ /* json反序列化,根据key值分别调用Operation/Decl/Type反序列化接口函数 */ ++ void JsonDeSerialize(const string& key, const string& data); ++ int64_t GetIntegerDataResult(void); ++ string GetStringDataResult(void); ++ vector GetFunctionOpResult(void); ++ vector GetLocalDeclResult(void); ++ mlir::Plugin::LoopOp LoopOpResult(void); ++ vector LoopOpsResult(void); ++ vector > EdgesResult(void); ++ std::pair EdgeResult(void); ++ vector GetOpResult(void); ++ bool GetBoolResult(void); ++ uint64_t GetIdResult(void); ++ vector GetIdsResult(void); ++ mlir::Value GetValueResult(void); ++ vector GetPhiOpsResult(void); ++ ++private: ++ PluginGrpc pluginGrpc; ++ PluginJson json; ++ int64_t integerResult; ++ string stringResult; ++ vector funcOpData; ++ vector decls; ++ vector loops; ++ mlir::Plugin::LoopOp loop; ++ vector > edges; ++ std::pair edge; ++ vector opData; ++ bool boolResult; ++ uint64_t idResult; ++ vector idsResult; ++ mlir::Value valueResult; ++}; ++} // namespace PinCom ++ ++#endif +\ No newline at end of file +diff --git a/include/PluginServer/PluginGrpc.h b/include/PluginServer/PluginGrpc.h +new file mode 100755 +index 0000000..9d30dce +--- /dev/null ++++ b/include/PluginServer/PluginGrpc.h +@@ -0,0 +1,65 @@ ++/* Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. ++ ++ Licensed under the Apache License, Version 2.0 (the "License"); you may ++ not use this file except in compliance with the License. You may obtain ++ a copy of the License at ++ ++ http://www.apache.org/licenses/LICENSE-2.0 ++ ++ Unless required by applicable law or agreed to in writing, software ++ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT ++ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the ++ License for the specific language governing permissions and limitations ++ under the License. ++ ++ Author: Mingchuan Wu and Yancheng Li ++ Create: 2022-08-18 ++ Description: ++ This file contains the declaration of the GrpcService class. ++ 主要完成功能:完成grpc server服务的注册,提供server和client之间grpc收发接口 ++*/ ++ ++#ifndef PLUGIN_GRPC_H ++#define PLUGIN_GRPC_H ++ ++#include ++#include "plugin.grpc.pb.h" ++ ++namespace PinGrpc { ++using grpc::Server; ++using grpc::ServerBuilder; ++using grpc::ServerContext; ++using grpc::ServerReaderWriter; ++using grpc::Status; ++ ++using plugin::PluginService; ++using plugin::ClientMsg; ++using plugin::ServerMsg; ++using std::string; ++ ++class PluginGrpc final : public PluginService::Service { ++public: ++ PluginGrpc() ++ { ++ shutdown = false; ++ } ++ /* 定义的grpc服务端和客户端通信的接口函数 */ ++ Status ReceiveSendMsg(ServerContext* context, ServerReaderWriter* stream) override; ++ /* 服务端发送数据给client接口 */ ++ void ServerSend(const string& key, const string& value); ++ bool RegisterServer(const string& port); ++ void Run(); ++ void ShutDown() ++ { ++ shutdown = true; ++ } ++ ++private: ++ void ServerMonitorThread(); // 监听线程,shutdown为true时,grpc server退出 ++ bool shutdown; // 是否关闭grpc server ++ ServerReaderWriter *grpcStream; // 保存server和client通信的grpc stream指针 ++ std::unique_ptr grpcServer; ++}; ++} // namespace PinGrpc ++ ++#endif +diff --git a/include/PluginServer/PluginJson.h b/include/PluginServer/PluginJson.h +new file mode 100755 +index 0000000..6f46187 +--- /dev/null ++++ b/include/PluginServer/PluginJson.h +@@ -0,0 +1,68 @@ ++/* Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. ++ ++ Licensed under the Apache License, Version 2.0 (the "License"); you may ++ not use this file except in compliance with the License. You may obtain ++ a copy of the License at ++ ++ http://www.apache.org/licenses/LICENSE-2.0 ++ ++ Unless required by applicable law or agreed to in writing, software ++ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT ++ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the ++ License for the specific language governing permissions and limitations ++ under the License. ++ ++ Author: Mingchuan Wu and Yancheng Li ++ Create: 2022-08-18 ++ Description: ++ This file contains the declaration of the PluginJson class. ++ 主要完成功能:将序列化数据进行反序列化 ++*/ ++ ++#ifndef PLUGIN_JSON_H ++#define PLUGIN_JSON_H ++ ++#include ++#include "Dialect/PluginOps.h" ++#include "Dialect/PluginTypes.h" ++ ++using std::string; ++using std::map; ++using std::vector; ++ ++namespace PinJson { ++class PluginJson { ++public: ++ void FuncOpJsonDeSerialize(const string&, vector&); ++ void LocalDeclOpJsonDeSerialize(const string&, ++ vector&); ++ void LoopOpsJsonDeSerialize(const string&, vector&); ++ void EdgesJsonDeSerialize(const string&, ++ vector>&); ++ void EdgeJsonDeSerialize(const string&, std::pair&); ++ void IdsJsonDeSerialize(const string&, vector&); ++ mlir::Operation *CallOpJsonDeSerialize(const string&); ++ mlir::Operation *CondOpJsonDeSerialize(const string&); ++ mlir::Operation *RetOpJsonDeSerialize(const string&); ++ mlir::Operation *FallThroughOpJsonDeSerialize(const string&); ++ mlir::Operation *PhiOpJsonDeSerialize(const string&); ++ mlir::Operation *AssignOpJsonDeSerialize(const string&); ++ void GetPhiOpsJsonDeSerialize(const string&, vector&); ++ mlir::Value SSAOpJsonDeSerialize(const string& data); ++ mlir::Plugin::LoopOp LoopOpJsonDeSerialize(const string& data); ++ PluginIR::PluginTypeBase TypeJsonDeSerialize(const string& data); ++ void OpJsonDeSerialize(const string&, vector&); ++ /* 将整形数据反序列化 */ ++ void IntegerDeSerialize(const string& data, int64_t& result); ++ /* 将字符串数据反序列化 */ ++ void StringDeSerialize(const string& data, string& result); ++ /* 将json格式数据解析成map格式 */ ++ void GetAttributes(Json::Value node, map& attributes); ++ mlir::Value ValueJsonDeSerialize(Json::Value valueJson); ++ Json::Value TypeJsonSerialize(PluginIR::PluginTypeBase& type); ++ mlir::Value MemRefDeSerialize(const string& data); ++ bool ProcessBlock(mlir::Block*, mlir::Region&, const Json::Value&); ++}; ++} // namespace PinJson ++ ++#endif +diff --git a/include/user/user.h b/include/user/user.h +new file mode 100755 +index 0000000..1fb7a30 +--- /dev/null ++++ b/include/user/user.h +@@ -0,0 +1,27 @@ ++/* Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. ++ ++ Licensed under the Apache License, Version 2.0 (the "License"); you may ++ not use this file except in compliance with the License. You may obtain ++ a copy of the License at ++ ++ http://www.apache.org/licenses/LICENSE-2.0 ++ ++ Unless required by applicable law or agreed to in writing, software ++ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT ++ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the ++ License for the specific language governing permissions and limitations ++ under the License. ++ ++ Author: Mingchuan Wu and Yancheng Li ++ Create: 2022-08-18 ++ Description: ++ This file contains the declaration of the User Init. ++*/ ++ ++#ifndef PLUGIN_USER_H ++#define PLUGIN_USER_H ++ ++/* 将注册点及用户函数注册给server, server初始化时调用 */ ++void RegisterCallbacks(void); ++ ++#endif +diff --git a/lib/Dialect/PluginDialect.cpp b/lib/Dialect/PluginDialect.cpp +index 001fdab..95b38cf 100644 +--- a/lib/Dialect/PluginDialect.cpp ++++ b/lib/Dialect/PluginDialect.cpp +@@ -14,11 +14,11 @@ + + + */ +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // + // This file defines Plugin dialect. + // +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + + #include "Dialect/PluginDialect.h" + #include "Dialect/PluginOps.h" +@@ -27,21 +27,22 @@ + using namespace mlir; + using namespace mlir::Plugin; + +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // Plugin dialect. +-//===----------------------------------------------------------------------===// +- +-void PluginDialect::initialize() { +- addTypes< +- PluginIR::PluginIntegerType, +- PluginIR::PluginFloatType, +- PluginIR::PluginPointerType, +- PluginIR::PluginBooleanType, +- PluginIR::PluginVoidType, +- PluginIR::PluginUndefType>(); +- +- addOperations< ++// ===----------------------------------------------------------------------===// ++ ++void PluginDialect::initialize() ++{ ++ addTypes< ++ PluginIR::PluginIntegerType, ++ PluginIR::PluginFloatType, ++ PluginIR::PluginPointerType, ++ PluginIR::PluginBooleanType, ++ PluginIR::PluginVoidType, ++ PluginIR::PluginUndefType>(); ++ ++ addOperations< + #define GET_OP_LIST + #include "Dialect/PluginOps.cpp.inc" +- >(); ++ >(); + } +\ No newline at end of file +diff --git a/lib/Dialect/PluginOps.cpp b/lib/Dialect/PluginOps.cpp +index 4d8974a..a0591b5 100644 +--- a/lib/Dialect/PluginOps.cpp ++++ b/lib/Dialect/PluginOps.cpp +@@ -14,11 +14,11 @@ + + + */ +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // + // This file defines operations in the Plugin dialect. + // +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + + #include "PluginAPI/PluginServerAPI.h" + #include "PluginAPI/ControlFlowAPI.h" +@@ -105,7 +105,8 @@ void LocalDeclOp::build(OpBuilder &builder, OperationState &state, + + void LoopOp::build(mlir::OpBuilder &builder, mlir::OperationState &state, + uint64_t id, uint32_t index, uint64_t innerLoopId, +- uint64_t outerLoopId, uint32_t numBlock) { ++ uint64_t outerLoopId, uint32_t numBlock) ++{ + LoopOp::build(builder, state, + builder.getI64IntegerAttr(id), + builder.getI32IntegerAttr(index), +@@ -219,7 +220,7 @@ void LoopOp::AddBlock(mlir::Block* block) + pluginAPI.AddBlockToLoop(blockId, loopId); + } + +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // PlaceholderOp + + void PlaceholderOp::build(OpBuilder &builder, OperationState &state, +@@ -233,7 +234,7 @@ void PlaceholderOp::build(OpBuilder &builder, OperationState &state, + state.addTypes(retType); + } + +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // MemOp + + void MemOp::build(OpBuilder &builder, OperationState &state, +@@ -248,7 +249,7 @@ void MemOp::build(OpBuilder &builder, OperationState &state, + if (retType) state.addTypes(retType); + } + +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // SSAOp + + void SSAOp::build(OpBuilder &builder, OperationState &state, uint64_t id, +@@ -270,23 +271,23 @@ void SSAOp::build(OpBuilder &builder, OperationState &state, uint64_t id, + Value SSAOp::MakeSSA(OpBuilder &builder, Type t) + { + PluginAPI::PluginServerAPI pluginAPI; +- PinServer::PluginServer::GetInstance()->SetOpBuilder(builder); ++ PinServer::PluginServer::GetInstance()->SetOpBuilder(&builder); + return pluginAPI.CreateSSAOp(t); + } + + Value SSAOp::Copy() + { + PluginAPI::PluginServerAPI pluginAPI; +- OpBuilder builder(this->getOperation()); +- PinServer::PluginServer::GetInstance()->SetOpBuilder(builder); ++ static OpBuilder builder(this->getOperation()); ++ PinServer::PluginServer::GetInstance()->SetOpBuilder(&builder); + return pluginAPI.CopySSAOp(this->idAttr().getInt()); + } + + Value SSAOp::GetCurrentDef() + { + PluginAPI::PluginServerAPI pluginAPI; +- OpBuilder builder(this->getOperation()); +- PinServer::PluginServer::GetInstance()->SetOpBuilder(builder); ++ static OpBuilder builder(this->getOperation()); ++ PinServer::PluginServer::GetInstance()->SetOpBuilder(&builder); + return pluginAPI.GetCurrentDefFromSSA(this->idAttr().getInt()); + } + +@@ -307,7 +308,7 @@ Operation* SSAOp::GetSSADefOperation() + return pluginAPI.GetSSADefOperation(definingId); + } + +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // ConstOp + + void ConstOp::build(OpBuilder &builder, OperationState &state, uint64_t id, +@@ -325,11 +326,11 @@ void ConstOp::build(OpBuilder &builder, OperationState &state, uint64_t id, + Value ConstOp::CreateConst(OpBuilder &builder, Attribute value, Type retType) + { + PluginAPI::PluginServerAPI pluginAPI; +- PinServer::PluginServer::GetInstance()->SetOpBuilder(builder); ++ PinServer::PluginServer::GetInstance()->SetOpBuilder(&builder); + return pluginAPI.CreateConstOp(value, retType); + } + +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // PointerOp + + void PointerOp::build(OpBuilder &builder, OperationState &state, uint64_t id, +@@ -344,7 +345,7 @@ void PointerOp::build(OpBuilder &builder, OperationState &state, uint64_t id, + state.addAttribute("pointeeReadOnly", builder.getBoolAttr(pointeeReadOnly)); + } + +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // CallOp + + void CallOp::build(OpBuilder &builder, OperationState &state, +@@ -414,13 +415,14 @@ void CallOp::build(OpBuilder &builder, OperationState &state, + state.addAttribute("callee", builder.getSymbolRefAttr("ctzll")); + } + +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // 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) { ++ uint64_t fbaddr, Value trueLabel, Value falseLabel) ++{ + state.addAttribute("id", builder.getI64IntegerAttr(id)); + state.addAttribute("address", builder.getI64IntegerAttr(address)); + state.addAttribute("tbaddr", builder.getI64IntegerAttr(tbaddr)); +@@ -449,19 +451,18 @@ void CondOp::build(OpBuilder &builder, OperationState &state, + state.addAttribute("id", builder.getI64IntegerAttr(id)); + state.addOperands({lhs, rhs}); + state.addAttribute("condCode", +- builder.getI32IntegerAttr(static_cast(condCode))); ++ builder.getI32IntegerAttr(static_cast(condCode))); + state.addSuccessors(tb); + state.addSuccessors(fb); + state.addAttribute("tbaddr", builder.getI64IntegerAttr(tbaddr)); + state.addAttribute("fbaddr", builder.getI64IntegerAttr(fbaddr)); + } + +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // PhiOp + + void PhiOp::build(OpBuilder &builder, OperationState &state, +- ArrayRef operands, uint64_t id, +- uint32_t capacity, uint32_t nArgs) ++ ArrayRef operands, uint64_t id, uint32_t capacity, uint32_t nArgs) + { + state.addAttribute("id", builder.getI64IntegerAttr(id)); + state.addAttribute("capacity", builder.getI32IntegerAttr(capacity)); +@@ -472,8 +473,8 @@ void PhiOp::build(OpBuilder &builder, OperationState &state, + Value PhiOp::GetResult() + { + PluginAPI::PluginServerAPI pluginAPI; +- OpBuilder builder(this->getOperation()); +- PinServer::PluginServer::GetInstance()->SetOpBuilder(builder); ++ static OpBuilder builder(this->getOperation()); ++ PinServer::PluginServer::GetInstance()->SetOpBuilder(&builder); + return pluginAPI.GetResultFromPhi(this->idAttr().getInt()); + } + +@@ -507,7 +508,7 @@ Value PhiOp::GetArgDef(int i) + } + return getOperand(i); + } +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // AssignOp + + void AssignOp::build(OpBuilder &builder, OperationState &state, +@@ -538,7 +539,7 @@ void AssignOp::build(OpBuilder &builder, OperationState &state, + state.addOperands(operands); + } + +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // BaseOp + + void BaseOp::build(OpBuilder &builder, OperationState &state, +@@ -548,7 +549,7 @@ void BaseOp::build(OpBuilder &builder, OperationState &state, + state.addAttribute("opCode", builder.getStringAttr(opCode)); + } + +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // FallThroughOp + + void FallThroughOp::build(OpBuilder &builder, OperationState &state, +@@ -572,7 +573,7 @@ void FallThroughOp::build(OpBuilder &builder, OperationState &state, + state.addSuccessors(dest); + } + +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // RetOp + + void RetOp::build(OpBuilder &builder, OperationState &state, uint64_t address) +@@ -580,9 +581,9 @@ void RetOp::build(OpBuilder &builder, OperationState &state, uint64_t address) + state.addAttribute("address", builder.getI64IntegerAttr(address)); + } + +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // TableGen'd op method definitions +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + + #define GET_OP_CLASSES + #include "Dialect/PluginOps.cpp.inc" +\ No newline at end of file +diff --git a/lib/Dialect/PluginTypes.cpp b/lib/Dialect/PluginTypes.cpp +index c33d9e0..c0a58c2 100644 +--- a/lib/Dialect/PluginTypes.cpp ++++ b/lib/Dialect/PluginTypes.cpp +@@ -36,16 +36,19 @@ namespace detail { + /// The hash key used for uniquing. + using KeyTy = std::pair; + +- static llvm::hash_code hashKey(const KeyTy &key) { ++ static llvm::hash_code hashKey(const KeyTy &key) ++ { + return llvm::hash_value(key); + } + +- bool operator==(const KeyTy &key) const { ++ bool operator==(const KeyTy &key) const ++ { + return KeyTy(width, signedness) == key; + } + + static PluginIntegerTypeStorage *construct(TypeStorageAllocator &allocator, +- KeyTy key) { ++ KeyTy key) ++ { + return new (allocator.allocate()) + PluginIntegerTypeStorage(key.first, key.second); + } +@@ -60,12 +63,13 @@ namespace detail { + /// The hash key used for uniquing. + using KeyTy = unsigned; + +- bool operator==(const KeyTy &key) const { ++ bool operator==(const KeyTy &key) const ++ { + return KeyTy(width) == key; + } + +- static PluginFloatTypeStorage *construct(TypeStorageAllocator &allocator, +- KeyTy key) { ++ static PluginFloatTypeStorage *construct(TypeStorageAllocator &allocator, KeyTy key) ++ { + return new (allocator.allocate()) + PluginFloatTypeStorage(key); + } +@@ -79,13 +83,14 @@ namespace detail { + PluginPointerTypeStorage(const KeyTy &key) + : pointee(std::get<0>(key)), readOnlyPointee(std::get<1>(key)) {} + +- static PluginPointerTypeStorage *construct(TypeStorageAllocator &allocator, +- KeyTy key) { ++ static PluginPointerTypeStorage *construct(TypeStorageAllocator &allocator, KeyTy key) ++ { + return new (allocator.allocate()) + PluginPointerTypeStorage(key); + } + +- bool operator==(const KeyTy &key) const { ++ bool operator==(const KeyTy &key) const ++ { + return std::make_tuple(pointee, readOnlyPointee) == key; + } + +@@ -96,9 +101,9 @@ namespace detail { + } + + +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // Plugin TypeBase +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + + PluginTypeID PluginTypeBase::getPluginTypeID () + { +@@ -117,7 +122,7 @@ PluginTypeID PluginTypeBase::getPluginTypeID () + if (auto Ty = dyn_cast()) { + return Ty.getPluginTypeID (); + } +- return PluginTypeID::UndefTyID; ++ return PluginTypeID::UndefTyID; + } + + unsigned PluginTypeBase::getPluginIntOrFloatBitWidth () +@@ -157,9 +162,9 @@ unsigned PluginTypeBase::getTypeSize () + return size; + } + +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // Plugin Integer Type +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + + unsigned PluginIntegerType::getWidth() const + { +@@ -173,10 +178,8 @@ PluginIntegerType::SignednessSemantics PluginIntegerType::getSignedness() const + + PluginTypeID PluginIntegerType::getPluginTypeID() + { +- if (isSigned()) +- { +- switch (getWidth()) +- { ++ if (isSigned()) { ++ switch (getWidth()) { + case 1: + return PluginTypeID::IntegerTy1ID; + case 8: +@@ -191,10 +194,8 @@ PluginTypeID PluginIntegerType::getPluginTypeID() + return PluginTypeID::UndefTyID; + } + } +- if (isUnsigned()) +- { +- switch (getWidth()) +- { ++ if (isUnsigned()) { ++ switch (getWidth()) { + case 1: + return PluginTypeID::UIntegerTy1ID; + case 8: +@@ -212,15 +213,15 @@ PluginTypeID PluginIntegerType::getPluginTypeID() + return PluginTypeID::UndefTyID; + } + +-PluginIntegerType PluginIntegerType::get (MLIRContext *context, unsigned width, PluginIntegerType::SignednessSemantics signedness) ++PluginIntegerType PluginIntegerType::get (MLIRContext *context, unsigned width, ++ PluginIntegerType::SignednessSemantics signedness) + { + return Base::get(context, width, signedness); + } + +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // Plugin Float Type +-//===----------------------------------------------------------------------===// +- ++// ===----------------------------------------------------------------------===// + unsigned PluginFloatType::getWidth () const + { + return getImpl()->width; +@@ -228,10 +229,12 @@ unsigned PluginFloatType::getWidth () const + + PluginTypeID PluginFloatType::getPluginTypeID() + { +- if (getWidth() == 32) ++ if (getWidth() == 32) { + return PluginTypeID::FloatTyID; +- if (getWidth() == 64) ++ } ++ if (getWidth() == 64) { + return PluginTypeID::DoubleTyID; ++ } + return PluginTypeID::UndefTyID; + } + +@@ -240,36 +243,36 @@ PluginFloatType PluginFloatType::get (MLIRContext *context, unsigned width) + return Base::get(context, width); + } + +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // Plugin Boolean Type +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + + PluginTypeID PluginBooleanType::getPluginTypeID() + { + return PluginTypeID::BooleanTyID; + } + +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // Plugin Void Type +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + + PluginTypeID PluginVoidType::getPluginTypeID() + { + return PluginTypeID::VoidTyID; + } + +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // Plugin Undef Type +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + + PluginTypeID PluginUndefType::getPluginTypeID() + { + return PluginTypeID::UndefTyID; + } + +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + // Plugin Pointer Type +-//===----------------------------------------------------------------------===// ++// ===----------------------------------------------------------------------===// + + PluginTypeID PluginPointerType::getPluginTypeID() + { +diff --git a/lib/PluginAPI/ControlFlowAPI.cpp b/lib/PluginAPI/ControlFlowAPI.cpp +index b598f57..92c0dd3 100644 +--- a/lib/PluginAPI/ControlFlowAPI.cpp ++++ b/lib/PluginAPI/ControlFlowAPI.cpp +@@ -15,7 +15,6 @@ + */ + + #include "PluginAPI/ControlFlowAPI.h" +-#include "PluginServer/PluginLog.h" + + namespace PluginAPI { + using namespace PinServer; +@@ -60,20 +59,18 @@ bool ControlFlowAPI::UpdateSSA(void) + bool ControlFlowAPI::GetUpdateOperationResult(const string &funName) + { + Json::Value root; +- pluginAPI.WaitClientResult(funName, root.toStyledString()); +- return PluginServer::GetInstance()->GetBoolResult(); ++ return PluginServer::GetInstance()->GetBoolResult(funName, root.toStyledString()); + } + + vector ControlFlowAPI::GetPhiOperationResult(const string &funName, const string& params) + { +- pluginAPI.WaitClientResult(funName, params);; +- vector retOps = PluginServer::GetInstance()->GetPhiOpsResult(); ++ vector retOps = PluginServer::GetInstance()->GetPhiOpsResult(funName, params); + return retOps; + } + + void ControlFlowAPI::GetDominatorSetOperationResult(const string &funName, const string& params) + { +- pluginAPI.WaitClientResult(funName, params);; ++ PluginServer::GetInstance()->RemoteCallClientWithAPI(funName, params); + return; + } + +@@ -97,12 +94,11 @@ uint64_t ControlFlowAPI::CreateBlock(mlir::Block* b, uint64_t funcAddr, uint64_t + root["funcaddr"] = std::to_string(funcAddr); + root["bbaddr"] = std::to_string(bbAddr); + string params = root.toStyledString(); +- pluginAPI.WaitClientResult(funName, params);; ++ PluginServer::GetInstance()->RemoteCallClientWithAPI(funName, params); + return PluginServer::GetInstance()->GetBlockResult(b); + } + +-void ControlFlowAPI::DeleteBlock(mlir::Block* b, uint64_t funcAddr, +- uint64_t bbAddr) ++void ControlFlowAPI::DeleteBlock(mlir::Block* b, uint64_t funcAddr, uint64_t bbAddr) + { + Json::Value root; + string funName = __func__; +@@ -111,14 +107,12 @@ void ControlFlowAPI::DeleteBlock(mlir::Block* b, uint64_t funcAddr, + root["funcaddr"] = std::to_string(funcAddr); + root["bbaddr"] = std::to_string(bbAddr); + string params = root.toStyledString(); +- pluginAPI.WaitClientResult(funName, params);; ++ PluginServer::GetInstance()->RemoteCallClientWithAPI(funName, params); + PluginServer::GetInstance()->EraseBlock(b); +- // b->erase(); + } + + /* dir: 1 or 2 */ +-void ControlFlowAPI::SetImmediateDominator(uint64_t dir, uint64_t bbAddr, +- uint64_t domiAddr) ++void ControlFlowAPI::SetImmediateDominator(uint64_t dir, uint64_t bbAddr, uint64_t domiAddr) + { + Json::Value root; + string funName = __func__; +@@ -128,7 +122,7 @@ void ControlFlowAPI::SetImmediateDominator(uint64_t dir, uint64_t bbAddr, + root["bbaddr"] = std::to_string(bbAddr); + root["domiaddr"] = std::to_string(domiAddr); + string params = root.toStyledString(); +- pluginAPI.WaitClientResult(funName, params);; ++ PluginServer::GetInstance()->RemoteCallClientWithAPI(funName, params); + } + + /* dir: 1 or 2 */ +@@ -140,8 +134,7 @@ uint64_t ControlFlowAPI::GetImmediateDominator(uint64_t dir, uint64_t bbAddr) + root["dir"] = std::to_string(dir); + root["bbaddr"] = std::to_string(bbAddr); + string params = root.toStyledString(); +- pluginAPI.WaitClientResult(funName, params);; +- return PluginServer::GetInstance()->GetIdResult(); ++ return PluginServer::GetInstance()->GetIdResult(funName, params); + } + + /* dir: 1 or 2 */ +@@ -153,8 +146,7 @@ uint64_t ControlFlowAPI::RecomputeDominator(uint64_t dir, uint64_t bbAddr) + root["dir"] = std::to_string(dir); + root["bbaddr"] = std::to_string(bbAddr); + string params = root.toStyledString(); +- pluginAPI.WaitClientResult(funName, params);; +- return PluginServer::GetInstance()->GetIdResult(); ++ return PluginServer::GetInstance()->GetIdResult(funName, params); + } + + mlir::Value ControlFlowAPI::CreateNewDef(mlir::Value oldValue, +@@ -170,8 +162,7 @@ mlir::Value ControlFlowAPI::CreateNewDef(mlir::Value oldValue, + uint64_t defId = 0; + root["defId"] = std::to_string(defId); + string params = root.toStyledString(); +- pluginAPI.WaitClientResult(funName, params); +- return PluginServer::GetInstance()->GetValueResult(); ++ return PluginServer::GetInstance()->GetValueResult(funName, params); + } + + void ControlFlowAPI::CreateFallthroughOp( +@@ -182,7 +173,7 @@ void ControlFlowAPI::CreateFallthroughOp( + root["address"] = std::to_string(address); + root["destaddr"] = std::to_string(destaddr); + string params = root.toStyledString(); +- pluginAPI.WaitClientResult(funName, params); ++ PluginServer::GetInstance()->RemoteCallClientWithAPI(funName, params); + } + + void ControlFlowAPI::RemoveEdge(uint64_t src, uint64_t dest) +@@ -192,7 +183,7 @@ void ControlFlowAPI::RemoveEdge(uint64_t src, uint64_t dest) + root["src"] = std::to_string(src); + root["dest"] = std::to_string(dest); + string params = root.toStyledString(); +- pluginAPI.WaitClientResult(funName, params); ++ PluginServer::GetInstance()->RemoteCallClientWithAPI(funName, params); + } + + } // namespace PluginAPI +diff --git a/lib/PluginAPI/PluginServerAPI.cpp b/lib/PluginAPI/PluginServerAPI.cpp +index 5ab27d7..523e08d 100644 +--- a/lib/PluginAPI/PluginServerAPI.cpp ++++ b/lib/PluginAPI/PluginServerAPI.cpp +@@ -18,24 +18,27 @@ + */ + + #include "PluginAPI/PluginServerAPI.h" +-#include "PluginServer/PluginLog.h" ++#include "PluginServer/PluginJson.h" + + namespace PluginAPI { + using namespace PinServer; + using namespace mlir::Plugin; + +-int CheckAttribute(string &attribute) ++static bool CheckAttribute(string &attribute) + { +- /* if (attribute == "") { ++ if (attribute == "NULL") { + printf("param attribute is NULL,check fail!\n"); +- return -1; +- } */ +- return 0; ++ return false; ++ } ++ return true; + } + +-int CheckID(uintptr_t id) ++static bool CheckID(uintptr_t id) + { +- return 0; ++ if (id == 0) { ++ return false; ++ } ++ return true; + } + + static uint64_t GetValueId(mlir::Value v) +@@ -52,21 +55,60 @@ static uint64_t GetValueId(mlir::Value v) + } + return 0; + } ++int64_t PluginServerAPI::GetInjectDataAddress() ++{ ++ string funName = __func__; ++ string params = ""; + +-void PluginServerAPI::WaitClientResult(const string& funName, const string& params) ++ return PluginServer::GetInstance()->GetIntegerDataResult(funName, params); ++} ++ ++string PluginServerAPI::GetDeclSourceFile(int64_t clientDataAddr) + { +- PluginServer *server = PluginServer::GetInstance(); +- server->SetApiFuncName(funName); +- server->SetApiFuncParams(params); +- server->SetUserFunState(STATE_BEGIN); +- server->SemPost(); +- while (1) { +- server->ClientReturnSemWait(); +- if (server->GetUserFunState() == STATE_RETURN) { // wait client result +- server->SetUserFunState(STATE_WAIT_BEGIN); +- break; +- } +- } ++ string funName = __func__; ++ string params = std::to_string(clientDataAddr); ++ ++ return PluginServer::GetInstance()->GetStringDataResult(funName, params); ++} ++ ++string PluginServerAPI::VariableName(int64_t clientDataAddr) ++{ ++ string funName = __func__; ++ string params = std::to_string(clientDataAddr); ++ ++ return PluginServer::GetInstance()->GetStringDataResult(funName, params); ++} ++ ++string PluginServerAPI::FuncName(int64_t clientDataAddr) ++{ ++ string funName = __func__; ++ string params = std::to_string(clientDataAddr); ++ ++ return PluginServer::GetInstance()->GetStringDataResult(funName, params); ++} ++ ++string PluginServerAPI::GetIncludeFile() ++{ ++ string funName = __func__; ++ string params = ""; ++ ++ return PluginServer::GetInstance()->GetStringDataResult(funName, params); ++} ++ ++int PluginServerAPI::GetDeclSourceLine(int64_t clientDataAddr) ++{ ++ string funName = __func__; ++ string params = std::to_string(clientDataAddr); ++ ++ return PluginServer::GetInstance()->GetIntegerDataResult(funName, params); ++} ++ ++int PluginServerAPI::GetDeclSourceColumn(int64_t clientDataAddr) ++{ ++ string funName = __func__; ++ string params = std::to_string(clientDataAddr); ++ ++ return PluginServer::GetInstance()->GetIntegerDataResult(funName, params); + } + + bool PluginServerAPI::SetCurrentDefInSSA(uint64_t varId, uint64_t defId) +@@ -76,8 +118,7 @@ bool PluginServerAPI::SetCurrentDefInSSA(uint64_t varId, uint64_t defId) + root["varId"] = std::to_string(varId); + root["defId"] = std::to_string(defId); + string params = root.toStyledString(); +- WaitClientResult(funName, params); +- return PluginServer::GetInstance()->GetBoolResult(); ++ return PluginServer::GetInstance()->GetBoolResult(funName, params); + } + + mlir::Value PluginServerAPI::GetCurrentDefFromSSA(uint64_t varId) +@@ -86,8 +127,7 @@ mlir::Value PluginServerAPI::GetCurrentDefFromSSA(uint64_t varId) + string funName = __func__; + root["varId"] = std::to_string(varId); + string params = root.toStyledString(); +- WaitClientResult(funName, params); +- return PluginServer::GetInstance()->GetValueResult(); ++ return PluginServer::GetInstance()->GetValueResult(funName, params); + } + + mlir::Value PluginServerAPI::CopySSAOp(uint64_t id) +@@ -96,8 +136,7 @@ mlir::Value PluginServerAPI::CopySSAOp(uint64_t id) + string funName = __func__; + root["id"] = std::to_string(id); + string params = root.toStyledString(); +- WaitClientResult(funName, params); +- return PluginServer::GetInstance()->GetValueResult(); ++ return PluginServer::GetInstance()->GetValueResult(funName, params); + } + + mlir::Value PluginServerAPI::CreateSSAOp(mlir::Type t) +@@ -105,17 +144,10 @@ mlir::Value PluginServerAPI::CreateSSAOp(mlir::Type t) + Json::Value root; + string funName = __func__; + auto baseTy = t.dyn_cast(); +- root = PluginServer::GetInstance()->TypeJsonSerialize(baseTy); ++ PinJson::PluginJson json; ++ root = json.TypeJsonSerialize(baseTy); + string params = root.toStyledString(); +- WaitClientResult(funName, params); +- return PluginServer::GetInstance()->GetValueResult(); +-} +- +-vector PluginServerAPI::GetFunctionOpResult(const string& funName, const string& params) +-{ +- WaitClientResult(funName, params); +- vector retOps = PluginServer::GetInstance()->GetFunctionOpResult(); +- return retOps; ++ return PluginServer::GetInstance()->GetValueResult(funName, params); + } + + vector PluginServerAPI::GetAllFunc() +@@ -124,7 +156,7 @@ vector PluginServerAPI::GetAllFunc() + string funName = __func__; + string params = root.toStyledString(); + +- return GetFunctionOpResult(funName, params); ++ return PluginServer::GetInstance()->GetFunctionOpResult(funName, params); + } + + PhiOp PluginServerAPI::GetPhiOp(uint64_t id) +@@ -133,8 +165,7 @@ PhiOp PluginServerAPI::GetPhiOp(uint64_t id) + string funName = __func__; + root["id"] = std::to_string(id); + string params = root.toStyledString(); +- WaitClientResult(funName, params); +- vector opRet = PluginServer::GetInstance()->GetOpResult(); ++ vector opRet = PluginServer::GetInstance()->GetOpResult(funName, params); + return llvm::dyn_cast(opRet[0]); + } + +@@ -144,8 +175,7 @@ CallOp PluginServerAPI::GetCallOp(uint64_t id) + string funName = __func__; + root["id"] = std::to_string(id); + string params = root.toStyledString(); +- WaitClientResult(funName, params); +- vector opRet = PluginServer::GetInstance()->GetOpResult(); ++ vector opRet = PluginServer::GetInstance()->GetOpResult(funName, params); + return llvm::dyn_cast(opRet[0]); + } + +@@ -156,14 +186,10 @@ bool PluginServerAPI::SetLhsInCallOp(uint64_t callId, uint64_t lhsId) + root["callId"] = std::to_string(callId); + root["lhsId"] = std::to_string(lhsId); + string params = root.toStyledString(); +- WaitClientResult(funName, params); +- return PluginServer::GetInstance()->GetBoolResult(); ++ return PluginServer::GetInstance()->GetBoolResult(funName, params); + } + +-uint32_t PluginServerAPI::AddArgInPhiOp(uint64_t phiId, +- uint64_t argId, +- uint64_t predId, +- uint64_t succId) ++uint32_t PluginServerAPI::AddArgInPhiOp(uint64_t phiId, uint64_t argId, uint64_t predId, uint64_t succId) + { + Json::Value root; + string funName = __func__; +@@ -172,8 +198,7 @@ uint32_t PluginServerAPI::AddArgInPhiOp(uint64_t phiId, + root["predId"] = std::to_string(predId); + root["succId"] = std::to_string(succId); + string params = root.toStyledString(); +- WaitClientResult(funName, params); +- return PluginServer::GetInstance()->GetIdResult(); ++ return PluginServer::GetInstance()->GetIdResult(funName, params); + } + + uint64_t PluginServerAPI::CreateCondOp(uint64_t blockId, IComparisonCode iCode, +@@ -189,8 +214,7 @@ uint64_t PluginServerAPI::CreateCondOp(uint64_t blockId, IComparisonCode iCode, + root["tbaddr"] = std::to_string(tbaddr); + root["fbaddr"] = std::to_string(fbaddr); + string params = root.toStyledString(); +- WaitClientResult(funName, params); +- return PluginServer::GetInstance()->GetIdResult(); ++ return PluginServer::GetInstance()->GetIdResult(funName, params); + } + + uint64_t PluginServerAPI::CreateAssignOp(uint64_t blockId, IExprCode iCode, vector &argIds) +@@ -207,8 +231,7 @@ uint64_t PluginServerAPI::CreateAssignOp(uint64_t blockId, IExprCode iCode, vect + } + root["argIds"] = item; + string params = root.toStyledString(); +- WaitClientResult(funName, params); +- return PluginServer::GetInstance()->GetIdResult(); ++ return PluginServer::GetInstance()->GetIdResult(funName, params); + } + + uint64_t PluginServerAPI::CreateCallOp(uint64_t blockId, uint64_t funcId, +@@ -226,8 +249,7 @@ uint64_t PluginServerAPI::CreateCallOp(uint64_t blockId, uint64_t funcId, + } + root["argIds"] = item; + string params = root.toStyledString(); +- WaitClientResult(funName, params); +- return PluginServer::GetInstance()->GetIdResult(); ++ return PluginServer::GetInstance()->GetIdResult(funName, params); + } + + mlir::Value PluginServerAPI::CreateConstOp(mlir::Attribute attr, mlir::Type type) +@@ -235,15 +257,15 @@ mlir::Value PluginServerAPI::CreateConstOp(mlir::Attribute attr, mlir::Type type + Json::Value root; + string funName = __func__; + auto baseTy = type.dyn_cast(); +- root = PluginServer::GetInstance()->TypeJsonSerialize(baseTy); ++ PinJson::PluginJson json; ++ root = json.TypeJsonSerialize(baseTy); + string valueStr; + if (type.isa()) { + valueStr = std::to_string(attr.cast().getInt()); + } + root["value"] = valueStr; + string params = root.toStyledString(); +- WaitClientResult(funName, params); +- return PluginServer::GetInstance()->GetValueResult(); ++ return PluginServer::GetInstance()->GetValueResult(funName, params); + } + + mlir::Value PluginServerAPI::GetResultFromPhi(uint64_t phiId) +@@ -252,8 +274,7 @@ mlir::Value PluginServerAPI::GetResultFromPhi(uint64_t phiId) + string funName = __func__; + root["id"] = std::to_string(phiId); + string params = root.toStyledString(); +- WaitClientResult(funName, params); +- return PluginServer::GetInstance()->GetValueResult(); ++ return PluginServer::GetInstance()->GetValueResult(funName, params); + } + + PhiOp PluginServerAPI::CreatePhiOp(uint64_t argId, uint64_t blockId) +@@ -263,8 +284,7 @@ PhiOp PluginServerAPI::CreatePhiOp(uint64_t argId, uint64_t blockId) + root["blockId"] = std::to_string(blockId); + root["argId"] = std::to_string(argId); + string params = root.toStyledString(); +- WaitClientResult(funName, params); +- vector opRet = PluginServer::GetInstance()->GetOpResult(); ++ vector opRet = PluginServer::GetInstance()->GetOpResult(funName, params); + return llvm::dyn_cast(opRet[0]); + } + +@@ -275,8 +295,7 @@ mlir::Value PluginServerAPI::ConfirmValue(mlir::Value v) + uint64_t valId = GetValueId(v); + root["valId"] = std::to_string(valId); + string params = root.toStyledString(); +- WaitClientResult(funName, params); +- return PluginServer::GetInstance()->GetValueResult(); ++ return PluginServer::GetInstance()->GetValueResult(funName, params); + } + + mlir::Value PluginServerAPI::BuildMemRef(PluginIR::PluginTypeBase type, +@@ -288,55 +307,47 @@ mlir::Value PluginServerAPI::BuildMemRef(PluginIR::PluginTypeBase type, + uint64_t offsetId = GetValueId(offset); + root["baseId"] = baseId; + root["offsetId"] = offsetId; +- root["type"] = PluginServer::GetInstance()->TypeJsonSerialize(type); ++ PinJson::PluginJson json; ++ root["type"] = json.TypeJsonSerialize(type); + string params = root.toStyledString(); +- WaitClientResult(funName, params); +- return PluginServer::GetInstance()->GetValueResult(); ++ return PluginServer::GetInstance()->GetValueResult(funName, params); + } + + PluginIR::PluginTypeID PluginServerAPI::GetTypeCodeFromString(string type) + { + if (type == "VoidTy") { + return PluginIR::PluginTypeID::VoidTyID; +- }else if (type == "UIntegerTy1") { ++ } else if (type == "UIntegerTy1") { + return PluginIR::PluginTypeID::UIntegerTy1ID; +- }else if (type == "UIntegerTy8") { ++ } else if (type == "UIntegerTy8") { + return PluginIR::PluginTypeID::UIntegerTy8ID; +- }else if (type == "UIntegerTy16") { ++ } else if (type == "UIntegerTy16") { + return PluginIR::PluginTypeID::UIntegerTy16ID; +- }else if (type == "UIntegerTy32") { ++ } else if (type == "UIntegerTy32") { + return PluginIR::PluginTypeID::UIntegerTy32ID; +- }else if (type == "UIntegerTy64") { ++ } else if (type == "UIntegerTy64") { + return PluginIR::PluginTypeID::UIntegerTy64ID; +- }else if (type == "IntegerTy1") { ++ } else if (type == "IntegerTy1") { + return PluginIR::PluginTypeID::IntegerTy1ID; +- }else if (type == "IntegerTy8") { ++ } else if (type == "IntegerTy8") { + return PluginIR::PluginTypeID::IntegerTy8ID; +- }else if (type == "IntegerTy16") { ++ } else if (type == "IntegerTy16") { + return PluginIR::PluginTypeID::IntegerTy16ID; +- }else if (type == "IntegerTy32") { ++ } else if (type == "IntegerTy32") { + return PluginIR::PluginTypeID::IntegerTy32ID; +- }else if (type == "IntegerTy64") { ++ } else if (type == "IntegerTy64") { + return PluginIR::PluginTypeID::IntegerTy64ID; +- }else if (type == "BooleanTy") { ++ } else if (type == "BooleanTy") { + return PluginIR::PluginTypeID::BooleanTyID; +- }else if (type == "FloatTy") { ++ } else if (type == "FloatTy") { + return PluginIR::PluginTypeID::FloatTyID; +- }else if (type == "DoubleTy") { ++ } else if (type == "DoubleTy") { + return PluginIR::PluginTypeID::DoubleTyID; + } + + return PluginIR::PluginTypeID::UndefTyID; + } + +-vector PluginServerAPI::GetDeclOperationResult(const string&funName, +- const string& params) +-{ +- WaitClientResult(funName, params); +- vector retDecls = PluginServer::GetInstance()->GetLocalDeclResult(); +- return retDecls; +-} +- + vector PluginServerAPI::GetDecls(uint64_t funcID) + { + Json::Value root; +@@ -344,48 +355,12 @@ vector PluginServerAPI::GetDecls(uint64_t funcID) + root["funcId"] = std::to_string(funcID); + string params = root.toStyledString(); + +- return GetDeclOperationResult(funName, params); +-} +- +-vector PluginServerAPI::GetLoopsResult(const string& funName, +- const string& params) +-{ +- WaitClientResult(funName, params); +- vector loops = PluginServer::GetInstance()->LoopOpsResult(); +- return loops; +-} +- +-LoopOp PluginServerAPI::GetLoopResult(const string& funName, const string& params) +-{ +- WaitClientResult(funName, params); +- LoopOp loop = PluginServer::GetInstance()->LoopOpResult(); +- return loop; +-} +- +-bool PluginServerAPI::GetBoolResult(const string& funName, const string& params) +-{ +- WaitClientResult(funName, params); +- return PluginServer::GetInstance()->GetBoolResult(); +-} +- +-pair PluginServerAPI::EdgeResult(const string& funName, const string& params) +-{ +- WaitClientResult(funName, params); +- pair e = PluginServer::GetInstance()->EdgeResult(); +- return e; +-} +- +-vector > PluginServerAPI::EdgesResult(const string& funName, const string& params) +-{ +- WaitClientResult(funName, params); +- vector > retEdges = PluginServer::GetInstance()->EdgesResult(); +- return retEdges; ++ return PluginServer::GetInstance()->GetLocalDeclResult(funName, params); + } + + mlir::Block* PluginServerAPI::BlockResult(const string& funName, const string& params) + { +- WaitClientResult(funName, params); +- uint64_t blockId = PluginServer::GetInstance()->GetIdResult(); ++ uint64_t blockId = PluginServer::GetInstance()->GetIdResult(funName, params); + return PluginServer::GetInstance()->FindBlock(blockId); + } + +@@ -393,9 +368,8 @@ vector PluginServerAPI::BlocksResult(const string& funName, const + { + vector res; + PluginServer *server = PluginServer::GetInstance(); +- WaitClientResult(funName, params); +- vector blockIds = server->GetIdsResult(); +- for(auto b : blockIds) { ++ vector blockIds = server->GetIdsResult(funName, params); ++ for (auto b : blockIds) { + res.push_back(server->FindBlock(b)); + } + return res; +@@ -408,7 +382,7 @@ vector PluginServerAPI::GetLoopsFromFunc(uint64_t funcID) + root["funcId"] = std::to_string(funcID); + string params = root.toStyledString(); + +- return GetLoopsResult(funName, params); ++ return PluginServer::GetInstance()->LoopOpsResult(funName, params); + } + + bool PluginServerAPI::IsDomInfoAvailable() +@@ -421,8 +395,7 @@ bool PluginServerAPI::IsDomInfoAvailable() + bool PluginServerAPI::GetDomInfoAvaiResult(const string& funName) + { + Json::Value root; +- WaitClientResult(funName, root.toStyledString()); +- return PluginServer::GetInstance()->GetBoolResult(); ++ return PluginServer::GetInstance()->GetBoolResult(funName, root.toStyledString()); + } + + LoopOp PluginServerAPI::AllocateNewLoop(uint64_t funcID) +@@ -432,7 +405,7 @@ LoopOp PluginServerAPI::AllocateNewLoop(uint64_t funcID) + root["funcId"] = std::to_string(funcID); + string params = root.toStyledString(); + +- return GetLoopResult(funName, params); ++ return PluginServer::GetInstance()->LoopOpResult(funName, params); + } + + LoopOp PluginServerAPI::GetLoopById(uint64_t loopID) +@@ -442,7 +415,7 @@ LoopOp PluginServerAPI::GetLoopById(uint64_t loopID) + root["loopId"] = std::to_string(loopID); + string params = root.toStyledString(); + +- return GetLoopResult(funName, params); ++ return PluginServer::GetInstance()->LoopOpResult(funName, params); + } + + void PluginServerAPI::DeleteLoop(uint64_t loopID) +@@ -451,7 +424,7 @@ void PluginServerAPI::DeleteLoop(uint64_t loopID) + string funName("DeleteLoop"); + root["loopId"] = std::to_string(loopID); + string params = root.toStyledString(); +- WaitClientResult(funName, params); ++ PluginServer::GetInstance()->RemoteCallClientWithAPI(funName, params); + } + + void PluginServerAPI::AddLoop(uint64_t loopID, uint64_t outerID, uint64_t funcID) +@@ -462,7 +435,7 @@ void PluginServerAPI::AddLoop(uint64_t loopID, uint64_t outerID, uint64_t funcID + root["outerId"] = outerID; + root["funcId"] = funcID; + string params = root.toStyledString(); +- WaitClientResult(funName, params); ++ PluginServer::GetInstance()->RemoteCallClientWithAPI(funName, params); + } + + void PluginServerAPI::AddBlockToLoop(uint64_t blockID, uint64_t loopID) +@@ -472,7 +445,7 @@ void PluginServerAPI::AddBlockToLoop(uint64_t blockID, uint64_t loopID) + root["blockId"] = blockID; + root["loopId"] = loopID; + string params = root.toStyledString(); +- WaitClientResult(funName, params); ++ PluginServer::GetInstance()->RemoteCallClientWithAPI(funName, params); + } + + bool PluginServerAPI::IsBlockInLoop(uint64_t loopID, uint64_t blockID) +@@ -483,7 +456,7 @@ bool PluginServerAPI::IsBlockInLoop(uint64_t loopID, uint64_t blockID) + root["blockId"] = std::to_string(blockID); + string params = root.toStyledString(); + +- return GetBoolResult(funName, params); ++ return PluginServer::GetInstance()->GetBoolResult(funName, params); + } + + mlir::Block* PluginServerAPI::GetHeader(uint64_t loopID) +@@ -513,8 +486,7 @@ void PluginServerAPI::SetHeader(uint64_t loopID, uint64_t blockID) + root["loopId"] = std::to_string(loopID); + root["blockId"] = std::to_string(blockID); + string params = root.toStyledString(); +- +- WaitClientResult(funName, params); ++ PluginServer::GetInstance()->RemoteCallClientWithAPI(funName, params); + } + + void PluginServerAPI::SetLatch(uint64_t loopID, uint64_t blockID) +@@ -524,8 +496,7 @@ void PluginServerAPI::SetLatch(uint64_t loopID, uint64_t blockID) + root["loopId"] = std::to_string(loopID); + root["blockId"] = std::to_string(blockID); + string params = root.toStyledString(); +- +- WaitClientResult(funName, params); ++ PluginServer::GetInstance()->RemoteCallClientWithAPI(funName, params); + } + + pair PluginServerAPI::LoopSingleExit(uint64_t loopID) +@@ -534,8 +505,7 @@ pair PluginServerAPI::LoopSingleExit(uint64_t loopID + string funName("GetLoopSingleExit"); + root["loopId"] = std::to_string(loopID); + string params = root.toStyledString(); +- +- return EdgeResult(funName, params); ++ return PluginServer::GetInstance()->EdgeResult(funName, params); + } + + vector > PluginServerAPI::GetLoopExitEdges(uint64_t loopID) +@@ -544,8 +514,7 @@ vector > PluginServerAPI::GetLoopExitEdges(uint + string funName("GetLoopExits"); + root["loopId"] = std::to_string(loopID); + string params = root.toStyledString(); +- +- return EdgesResult(funName, params); ++ return PluginServer::GetInstance()->EdgesResult(funName, params); + } + + vector PluginServerAPI::GetLoopBody(uint64_t loopID) +@@ -554,7 +523,6 @@ vector PluginServerAPI::GetLoopBody(uint64_t loopID) + string funName("GetBlocksInLoop"); + root["loopId"] = std::to_string(loopID); + string params = root.toStyledString(); +- + return BlocksResult(funName, params); + } + +@@ -564,8 +532,7 @@ LoopOp PluginServerAPI::GetBlockLoopFather(uint64_t blockID) + string funName("GetBlockLoopFather"); + root["blockId"] = std::to_string(blockID); + string params = root.toStyledString(); +- +- return GetLoopResult(funName, params); ++ return PluginServer::GetInstance()->LoopOpResult(funName, params); + } + + mlir::Block* PluginServerAPI::FindBlock(uint64_t b) +@@ -594,8 +561,8 @@ bool PluginServerAPI::RedirectFallthroughTarget(FallThroughOp& fop, + root["src"] = src; + root["dest"] = dest; + string params = root.toStyledString(); +- WaitClientResult(funName, params); +- //update server ++ PluginServer::GetInstance()->RemoteCallClientWithAPI(funName, params); ++ // update server + PluginServer *server = PluginServer::GetInstance(); + fop->setSuccessor(server->FindBlock(dest), 0); + return true; +@@ -617,7 +584,7 @@ void PluginServerAPI::DebugValue(uint64_t valId) + string funName = __func__; + root["valId"] = valId; + string params = root.toStyledString(); +- WaitClientResult(funName, params); ++ PluginServer::GetInstance()->RemoteCallClientWithAPI(funName, params); + } + + } // namespace Plugin_IR +-- +2.27.0.windows.1 + diff --git a/0004-Pin-server-Add-DebugOp.patch b/0004-Pin-server-Add-DebugOp.patch new file mode 100644 index 0000000000000000000000000000000000000000..b3466a6ba301326a27a4d74b41092735f03f4cce --- /dev/null +++ b/0004-Pin-server-Add-DebugOp.patch @@ -0,0 +1,127 @@ +From b14803116c8488a4c765799fd31966991f2031d7 Mon Sep 17 00:00:00 2001 +From: benniaobufeijiushiji +Date: Sun, 19 Feb 2023 11:43:57 +0800 +Subject: [PATCH 4/9] [Pin-server] Add DebugOp + + +diff --git a/include/Dialect/PluginOps.td b/include/Dialect/PluginOps.td +index 2af4a33..f4062ad 100644 +--- a/include/Dialect/PluginOps.td ++++ b/include/Dialect/PluginOps.td +@@ -82,8 +82,8 @@ def LoopOp : Plugin_Op<"loop", [NoSideEffect]> { + let extraClassDeclaration = [{ + mlir::Block* GetHeader(); + mlir::Block* GetLatch(); +- void SetHeader(mlir::Block*); +- void SetLatch(mlir::Block*); ++ void SetHeader(mlir::Block*); ++ void SetLatch(mlir::Block*); + std::pair GetSingleExit(); + void Delete(); + LoopOp GetInnerLoop(); +@@ -247,7 +247,7 @@ def SSAOp : SSA<"SSA"> { + Value Copy(); + Value GetCurrentDef(); + bool SetCurrentDef(Value def); +- Operation* GetSSADefOperation(); ++ Operation* GetSSADefOperation(); + }]; + } + +@@ -274,6 +274,16 @@ def BaseOp : Plugin_Op<"statement_base", [NoSideEffect]> { + ]; + } + ++def DebugOp : Plugin_Op<"debug", [NoSideEffect]> { ++ let summary = "DebugOp."; ++ let description = [{TODO}]; ++ let arguments = (ins UI64Attr:$id); ++ let results = (outs AnyType); ++ let builders = [ ++ OpBuilderDAG<(ins "uint64_t":$id)> ++ ]; ++} ++ + // Terminators + // Opaque builder used for terminator operations that contain successors. + +diff --git a/lib/Dialect/PluginOps.cpp b/lib/Dialect/PluginOps.cpp +index a0591b5..a49ce16 100644 +--- a/lib/Dialect/PluginOps.cpp ++++ b/lib/Dialect/PluginOps.cpp +@@ -549,6 +549,15 @@ void BaseOp::build(OpBuilder &builder, OperationState &state, + state.addAttribute("opCode", builder.getStringAttr(opCode)); + } + ++//===----------------------------------------------------------------------===// ++// DebugOp ++ ++void DebugOp::build(OpBuilder &builder, OperationState &state, ++ uint64_t id) ++{ ++ state.addAttribute("id", builder.getI64IntegerAttr(id)); ++} ++ + // ===----------------------------------------------------------------------===// + // FallThroughOp + +diff --git a/lib/PluginServer/PluginJson.cpp b/lib/PluginServer/PluginJson.cpp +index c399aad..d89945c 100755 +--- a/lib/PluginServer/PluginJson.cpp ++++ b/lib/PluginServer/PluginJson.cpp +@@ -196,6 +196,9 @@ bool PluginJson::ProcessBlock(mlir::Block* block, mlir::Region& rg, const Json:: + RetOpJsonDeSerialize(opJson.toStyledString()); + } else if (opCode == FallThroughOp::getOperationName().str()) { + FallThroughOpJsonDeSerialize(opJson.toStyledString()); ++ } else if (opCode == DebugOp::getOperationName().str()) { ++ uint64_t opID = GetID(opJson["id"]); ++ opBuilder->create(opBuilder->getUnknownLoc(), opID); + } else if (opCode == BaseOp::getOperationName().str()) { + uint64_t opID = GetID(opJson["id"]); + opBuilder->create(opBuilder->getUnknownLoc(), opID, opCode); +@@ -603,6 +606,10 @@ void PluginJson::OpJsonDeSerialize( + opData.push_back(RetOpJsonDeSerialize(opJson.toStyledString())); + } else if (opCode == FallThroughOp::getOperationName().str()) { + opData.push_back(FallThroughOpJsonDeSerialize(opJson.toStyledString())); ++ } else if (opCode == DebugOp::getOperationName().str()) { ++ uint64_t opID = GetID(opJson["id"]); ++ mlir::OpBuilder *opBuilder = PluginServer::GetInstance()->GetOpBuilder(); ++ opBuilder->create(opBuilder->getUnknownLoc(), opID); + } else if (opCode == BaseOp::getOperationName().str()) { + uint64_t opID = GetID(opJson["id"]); + mlir::OpBuilder *opBuilder = PluginServer::GetInstance()->GetOpBuilder(); +diff --git a/user.cpp b/user.cpp +index a6fe555..8163cec 100644 +--- a/user.cpp ++++ b/user.cpp +@@ -318,7 +318,7 @@ struct originLoopInfo { + Value *limitptr; + Value arr1; /* Array 1 in the old loop. */ + Value *arr1ptr; +- Value arr2; /* Array 2 in the old loop. */ ++ Value arr2; /* Array 2 in the old loop. */ + Value *arr2ptr; + edge entryEdge; /* The edge into the old loop. */ + edgePtr entryEdgePtr; +@@ -646,7 +646,7 @@ static bool getIvBase(CondOp cond) + original loop; When prolog_assign is present, make sure loop header is in + simple form; And the interpretation of prolog_assign is as follows: + eg: while (++len != limit) +- ...... ++ ...... + For such a loop, ++len will be processed before entering header_bb, and the + assign is regarded as the prolog_assign of the loop. */ + static bool recordOriginLoopHeader(LoopOp loop) +@@ -665,6 +665,9 @@ static bool recordOriginLoopHeader(LoopOp loop) + continue; + } + ++ if (auto debugOp = dyn_cast(op)) ++ continue; ++ + if (auto cond = dyn_cast(op)) { + if (!getIvUpperBound(cond)) { + return false; +-- +2.27.0.windows.1 + diff --git a/0005-Pin-server-Add-API-for-LTO-judgement.patch b/0005-Pin-server-Add-API-for-LTO-judgement.patch new file mode 100644 index 0000000000000000000000000000000000000000..c6b102a526e2485e528bd9b3eb0ea040052cca8f --- /dev/null +++ b/0005-Pin-server-Add-API-for-LTO-judgement.patch @@ -0,0 +1,60 @@ +From 47f1208aab2acb3e1a8442d830125ad3b54149c5 Mon Sep 17 00:00:00 2001 +From: benniaobufeijiushiji +Date: Sun, 19 Feb 2023 14:40:09 +0800 +Subject: [PATCH 5/9] [Pin-server] Add API for LTO judgement + + +diff --git a/include/PluginAPI/BasicPluginOpsAPI.h b/include/PluginAPI/BasicPluginOpsAPI.h +index 0ca0ac4..f83b888 100644 +--- a/include/PluginAPI/BasicPluginOpsAPI.h ++++ b/include/PluginAPI/BasicPluginOpsAPI.h +@@ -70,6 +70,8 @@ public: + virtual uint32_t AddArgInPhiOp(uint64_t, uint64_t, uint64_t, uint64_t) = 0; + virtual PhiOp CreatePhiOp(uint64_t, uint64_t) = 0; + virtual void DebugValue(uint64_t) = 0; ++ virtual bool IsLtoOptimize() = 0; ++ virtual bool IsWholeProgram() = 0; + + virtual mlir::Value GetCurrentDefFromSSA(uint64_t) = 0; + virtual bool SetCurrentDefInSSA(uint64_t, uint64_t) = 0; +diff --git a/include/PluginAPI/PluginServerAPI.h b/include/PluginAPI/PluginServerAPI.h +index 0655d80..b2f8fbf 100644 +--- a/include/PluginAPI/PluginServerAPI.h ++++ b/include/PluginAPI/PluginServerAPI.h +@@ -74,6 +74,8 @@ public: + /* Plugin API for ConstOp. */ + mlir::Value CreateConstOp(mlir::Attribute, mlir::Type) override; + void DebugValue(uint64_t) override; ++ bool IsLtoOptimize() override; ++ bool IsWholeProgram() override; + + mlir::Value GetCurrentDefFromSSA(uint64_t) override; + bool SetCurrentDefInSSA(uint64_t, uint64_t) override; +diff --git a/lib/PluginAPI/PluginServerAPI.cpp b/lib/PluginAPI/PluginServerAPI.cpp +index 523e08d..f81a3ad 100644 +--- a/lib/PluginAPI/PluginServerAPI.cpp ++++ b/lib/PluginAPI/PluginServerAPI.cpp +@@ -587,4 +587,20 @@ void PluginServerAPI::DebugValue(uint64_t valId) + PluginServer::GetInstance()->RemoteCallClientWithAPI(funName, params); + } + ++bool PluginServerAPI::IsLtoOptimize() ++{ ++ Json::Value root; ++ string funName = __func__; ++ string params = root.toStyledString(); ++ return PluginServer::GetInstance()->GetBoolResult(funName, params); ++} ++ ++bool PluginServerAPI::IsWholeProgram() ++{ ++ Json::Value root; ++ string funName = __func__; ++ string params = root.toStyledString(); ++ return PluginServer::GetInstance()->GetBoolResult(funName, params); ++} ++ + } // namespace Plugin_IR +-- +2.27.0.windows.1 + diff --git a/0006-Pin-server-Fix-bug-for-BuildCallOp.patch b/0006-Pin-server-Fix-bug-for-BuildCallOp.patch new file mode 100644 index 0000000000000000000000000000000000000000..35f3e0a7d0eddfcff041ff8be6d9b5faa8addda1 --- /dev/null +++ b/0006-Pin-server-Fix-bug-for-BuildCallOp.patch @@ -0,0 +1,105 @@ +From 5be0d63fe19decadaebb012efeb03b75aa868228 Mon Sep 17 00:00:00 2001 +From: Mingchuan Wu +Date: Tue, 21 Feb 2023 16:52:39 +0800 +Subject: [PATCH 6/9] [Pin-server] Fix bug for BuildCallOp. Now we can convert + the function pointer. + + +diff --git a/include/Dialect/PluginOps.td b/include/Dialect/PluginOps.td +index f4062ad..3a88846 100644 +--- a/include/Dialect/PluginOps.td ++++ b/include/Dialect/PluginOps.td +@@ -107,11 +107,13 @@ def CallOp : Plugin_Op<"call", [ + The arguments list must match the arguments expected by the callee. + }]; + let arguments = (ins UI64Attr:$id, +- FlatSymbolRefAttr:$callee, ++ OptionalAttr:$callee, + Variadic:$inputs); + let builders = [ + OpBuilderDAG<(ins "int64_t":$id, "StringRef":$callee, + "ArrayRef":$arguments)>, ++ OpBuilderDAG<(ins "int64_t":$id, ++ "ArrayRef":$arguments)>, + // Only for server. + OpBuilderDAG<(ins "Value":$func, + "ArrayRef":$arguments, "Block *":$block)>, +diff --git a/lib/Dialect/PluginOps.cpp b/lib/Dialect/PluginOps.cpp +index a49ce16..a30e9ed 100644 +--- a/lib/Dialect/PluginOps.cpp ++++ b/lib/Dialect/PluginOps.cpp +@@ -357,6 +357,13 @@ void CallOp::build(OpBuilder &builder, OperationState &state, + state.addAttribute("callee", builder.getSymbolRefAttr(callee)); + } + ++void CallOp::build(OpBuilder &builder, OperationState &state, ++ int64_t id, ArrayRef arguments) ++{ ++ state.addAttribute("id", builder.getI64IntegerAttr(id)); ++ state.addOperands(arguments); ++} ++ + /// Return the callee of the generic call operation, this is required by the + /// call interface. + CallInterfaceCallable CallOp::getCallableForCallee() +diff --git a/lib/PluginServer/PluginJson.cpp b/lib/PluginServer/PluginJson.cpp +index d89945c..7bbf681 100755 +--- a/lib/PluginServer/PluginJson.cpp ++++ b/lib/PluginServer/PluginJson.cpp +@@ -467,10 +467,16 @@ mlir::Operation *PluginJson::CallOpJsonDeSerialize(const string& data) + ops.push_back(opValue); + } + int64_t id = GetID(node["id"]); +- mlir::StringRef callName(node["callee"].asString()); + mlir::OpBuilder *opBuilder = PluginServer::GetInstance()->GetOpBuilder(); +- CallOp op = opBuilder->create(opBuilder->getUnknownLoc(), +- id, callName, ops); ++ Json::Value calleeJson = node["callee"]; ++ CallOp op; ++ if (calleeJson.isNull()) { ++ op = opBuilder->create(opBuilder->getUnknownLoc(), id, ops); ++ } else { ++ mlir::StringRef callName(calleeJson.asString()); ++ op = opBuilder->create(opBuilder->getUnknownLoc(), ++ id, callName, ops); ++ } + return op.getOperation(); + } + +diff --git a/lib/PluginServer/PluginServer.cpp b/lib/PluginServer/PluginServer.cpp +index 05d0d3d..d2a1736 100644 +--- a/lib/PluginServer/PluginServer.cpp ++++ b/lib/PluginServer/PluginServer.cpp +@@ -50,7 +50,7 @@ bool PluginServer::RegisterOpt(std::shared_ptr optBase) + string name = "funcname" + std::to_string((uintptr_t)optBase.get()); + userOpts[inject].push_back(RecordedOpt(name, optBase)); + this->context = optBase->GetContext(); +- mlir::OpBuilder opBuilder_temp = mlir::OpBuilder(context); ++ static mlir::OpBuilder opBuilder_temp = mlir::OpBuilder(context); + opBuilder = &opBuilder_temp; + return true; + } +@@ -305,7 +305,7 @@ void PluginServer::RunServer() + ServerSemPost(port); + + RegisterCallbacks(); +- printf("RunServer: RegisterCallbacks Done.\n"); ++ log->LOGI("RunServer: RegisterCallbacks Done.\n"); + pluginCom.Run(); + } + } // namespace PinServer +diff --git a/lib/PluginServer/main.cpp b/lib/PluginServer/main.cpp +index fac574e..333d55e 100644 +--- a/lib/PluginServer/main.cpp ++++ b/lib/PluginServer/main.cpp +@@ -29,7 +29,6 @@ int main(int argc, char** argv) + printf("param num:%d, should be:%d\n", argc, argcNum); + return -1; + } +- printf("main arg: %s, %s\n", argv[0], argv[1]); + std::string port = argv[0]; + LogPriority priority = (LogPriority)atoi(argv[1]); + PluginServer server(priority, port); +-- +2.27.0.windows.1 + diff --git a/0007-Pin-server-Refactoring-array-widen-compare-into-a-cl.patch b/0007-Pin-server-Refactoring-array-widen-compare-into-a-cl.patch new file mode 100644 index 0000000000000000000000000000000000000000..aa04376908e0c9cf5e99a5a358e3f9ff58e668eb --- /dev/null +++ b/0007-Pin-server-Refactoring-array-widen-compare-into-a-cl.patch @@ -0,0 +1,93 @@ +From 1f800efcb93e2868f609c70584966b706ba13031 Mon Sep 17 00:00:00 2001 +From: Mingchuan Wu +Date: Tue, 21 Feb 2023 17:37:23 +0800 +Subject: [PATCH 7/9] [Pin-server] Refactoring array-widen-compare into a + class. + + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 3a784df..4b2ab67 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -82,7 +82,7 @@ target_link_libraries(plg_grpc_proto + + add_subdirectory(include) + add_subdirectory(lib) +-add_library(pin_user SHARED "user.cpp") ++add_library(pin_user SHARED "user/ArrayWidenPass.cpp") + target_link_libraries(pin_user + MLIRServerAPI + ) +diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt +index 7b0c8c4..6bc2859 100644 +--- a/lib/CMakeLists.txt ++++ b/lib/CMakeLists.txt +@@ -5,9 +5,9 @@ add_mlir_library(MLIRServerAPI + + DEPENDS + MLIRPluginOpsIncGen +- MLIRPlugin ++ MLIRPluginServer + + LINK_LIBS PUBLIC + MLIRIR +- MLIRPlugin ++ MLIRPluginServer + ) +\ No newline at end of file +diff --git a/lib/Dialect/CMakeLists.txt b/lib/Dialect/CMakeLists.txt +index ca912e9..8627cdd 100644 +--- a/lib/Dialect/CMakeLists.txt ++++ b/lib/Dialect/CMakeLists.txt +@@ -1,4 +1,4 @@ +-add_mlir_dialect_library(MLIRPlugin ++add_mlir_dialect_library(MLIRPluginServer + PluginTypes.cpp + PluginDialect.cpp + PluginOps.cpp +diff --git a/user.cpp b/user/ArrayWidenPass.cpp +similarity index 100% +rename from user.cpp +rename to user/ArrayWidenPass.cpp +diff --git a/user/user.cpp b/user/user.cpp +new file mode 100644 +index 0000000..bee70bb +--- /dev/null ++++ b/user/user.cpp +@@ -0,0 +1,33 @@ ++/* Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. ++ ++ Licensed under the Apache License, Version 2.0 (the "License"); you may ++ not use this file except in compliance with the License. You may obtain ++ a copy of the License at ++ ++ http://www.apache.org/licenses/LICENSE-2.0 ++ ++ Unless required by applicable law or agreed to in writing, software ++ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT ++ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the ++ License for the specific language governing permissions and limitations ++ under the License. ++ ++ Author: Mingchuan Wu and Yancheng Li ++ Create: 2022-08-18 ++ Description: ++ This file contains the implementation of the User Init. ++*/ ++ ++#include "PluginAPI/PluginServerAPI.h" ++#include "user/ArrayWidenPass.h" ++#include "user/InlineFunctionPass.h" ++#include "user/LocalVarSummeryPass.h" ++ ++void RegisterCallbacks(void) ++{ ++ PinServer::PluginServer *pluginServer = PinServer::PluginServer::GetInstance(); ++ pluginServer->RegisterOpt(std::make_shared(PluginOpt::HANDLE_BEFORE_IPA)); ++ pluginServer->RegisterOpt(std::make_shared(PluginOpt::HANDLE_AFTER_IPA)); ++ PluginOpt::ManagerSetup setupData(PluginOpt::PASS_PHIOPT, 1, PluginOpt::PASS_INSERT_AFTER); ++ pluginServer->RegisterPassManagerOpt(setupData, std::make_shared()); ++} +-- +2.27.0.windows.1 + diff --git a/0008-Pin-server-Refactoring-DEMOs-into-PluginOpt-classes.patch b/0008-Pin-server-Refactoring-DEMOs-into-PluginOpt-classes.patch new file mode 100644 index 0000000000000000000000000000000000000000..60cb4564a8ed7cd67c38af47af540bc9f18f7251 --- /dev/null +++ b/0008-Pin-server-Refactoring-DEMOs-into-PluginOpt-classes.patch @@ -0,0 +1,442 @@ +From 2942cf7b6cdbea40735d5574e21d34d9f665a1fd Mon Sep 17 00:00:00 2001 +From: Mingchuan Wu +Date: Tue, 21 Feb 2023 17:45:30 +0800 +Subject: [PATCH 8/9] [Pin-server] Refactoring DEMOs into PluginOpt classes. + + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 4b2ab67..1cfb776 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -82,7 +82,12 @@ target_link_libraries(plg_grpc_proto + + add_subdirectory(include) + add_subdirectory(lib) +-add_library(pin_user SHARED "user/ArrayWidenPass.cpp") ++add_library(pin_user SHARED ++ "user/ArrayWidenPass.cpp" ++ "user/InlineFunctionPass.cpp" ++ "user/LocalVarSummeryPass.cpp" ++ "user/user.cpp") ++ + target_link_libraries(pin_user + MLIRServerAPI + ) +diff --git a/include/user/ArrayWidenPass.h b/include/user/ArrayWidenPass.h +new file mode 100755 +index 0000000..38c692d +--- /dev/null ++++ b/include/user/ArrayWidenPass.h +@@ -0,0 +1,45 @@ ++/* Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. ++ ++ Licensed under the Apache License, Version 2.0 (the "License"); you may ++ not use this file except in compliance with the License. You may obtain ++ a copy of the License at ++ ++ http://www.apache.org/licenses/LICENSE-2.0 ++ ++ Unless required by applicable law or agreed to in writing, software ++ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT ++ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the ++ License for the specific language governing permissions and limitations ++ under the License. ++ ++ Author: Mingchuan Wu and Yancheng Li ++ Create: 2022-08-18 ++ Description: ++ This file contains the declaration of the ArrayWidenPass class. ++*/ ++ ++#ifndef ARRAYWIDEN_PASS_H ++#define ARRAYWIDEN_PASS_H ++ ++#include "PluginServer/PluginOptBase.h" ++ ++namespace PluginOpt { ++class ArrayWidenPass : public PluginOptBase { ++public: ++ ArrayWidenPass() : PluginOptBase(HANDLE_MANAGER_SETUP) ++ { ++ } ++ bool Gate() ++ { ++ return true; ++ } ++ int DoOptimize() ++ { ++ uint64_t *fun = (uint64_t *)GetFuncAddr(); ++ return DoOptimize(fun); ++ } ++ int DoOptimize(uint64_t *fun); ++}; ++} ++ ++#endif +diff --git a/include/user/InlineFunctionPass.h b/include/user/InlineFunctionPass.h +new file mode 100755 +index 0000000..b2dad9f +--- /dev/null ++++ b/include/user/InlineFunctionPass.h +@@ -0,0 +1,40 @@ ++/* Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. ++ ++ Licensed under the Apache License, Version 2.0 (the "License"); you may ++ not use this file except in compliance with the License. You may obtain ++ a copy of the License at ++ ++ http://www.apache.org/licenses/LICENSE-2.0 ++ ++ Unless required by applicable law or agreed to in writing, software ++ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT ++ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the ++ License for the specific language governing permissions and limitations ++ under the License. ++ ++ Author: Mingchuan Wu and Yancheng Li ++ Create: 2022-08-18 ++ Description: ++ This file contains the declaration of the InlineFunctionPass class. ++*/ ++ ++#ifndef INLINEFUNCTION_PASS_H ++#define INLINEFUNCTION_PASS_H ++ ++#include "PluginServer/PluginOptBase.h" ++ ++namespace PluginOpt { ++class InlineFunctionPass : public PluginOptBase { ++public: ++ InlineFunctionPass(InjectPoint inject) : PluginOptBase(inject) ++ { ++ } ++ bool Gate() ++ { ++ return true; ++ } ++ int DoOptimize(); ++}; ++} ++ ++#endif +diff --git a/include/user/LocalVarSummeryPass.h b/include/user/LocalVarSummeryPass.h +new file mode 100755 +index 0000000..760cb25 +--- /dev/null ++++ b/include/user/LocalVarSummeryPass.h +@@ -0,0 +1,40 @@ ++/* Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. ++ ++ Licensed under the Apache License, Version 2.0 (the "License"); you may ++ not use this file except in compliance with the License. You may obtain ++ a copy of the License at ++ ++ http://www.apache.org/licenses/LICENSE-2.0 ++ ++ Unless required by applicable law or agreed to in writing, software ++ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT ++ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the ++ License for the specific language governing permissions and limitations ++ under the License. ++ ++ Author: Mingchuan Wu and Yancheng Li ++ Create: 2022-08-18 ++ Description: ++ This file contains the declaration of the LocalVarSummeryPass pass. ++*/ ++ ++#ifndef LOCALVAR_SUMMERY_H ++#define LOCALVAR_SUMMERY_H ++ ++#include "PluginServer/PluginOptBase.h" ++ ++namespace PluginOpt { ++class LocalVarSummeryPass : public PluginOptBase { ++public: ++ LocalVarSummeryPass(InjectPoint inject) : PluginOptBase(inject) ++ { ++ } ++ bool Gate() ++ { ++ return true; ++ } ++ int DoOptimize(); ++}; ++} ++ ++#endif +diff --git a/user/ArrayWidenPass.cpp b/user/ArrayWidenPass.cpp +index 8163cec..162fdc9 100644 +--- a/user/ArrayWidenPass.cpp ++++ b/user/ArrayWidenPass.cpp +@@ -15,7 +15,7 @@ + Author: Mingchuan Wu and Yancheng Li + Create: 2022-08-18 + Description: +- This file contains the implementation of the User Init. ++ This file contains the implementation of the ArrayWidenPass class. + */ + + #include +@@ -27,7 +27,7 @@ + #include "PluginAPI/PluginServerAPI.h" + #include "PluginServer/PluginLog.h" + #include "PluginAPI/ControlFlowAPI.h" +-#include "PluginServer/PluginOptBase.h" ++#include "user/ArrayWidenPass.h" + + namespace PluginOpt { + using std::string; +@@ -318,7 +318,7 @@ struct originLoopInfo { + Value *limitptr; + Value arr1; /* Array 1 in the old loop. */ + Value *arr1ptr; +- Value arr2; /* Array 2 in the old loop. */ ++ Value arr2; /* Array 2 in the old loop. */ + Value *arr2ptr; + edge entryEdge; /* The edge into the old loop. */ + edgePtr entryEdgePtr; +@@ -438,7 +438,7 @@ static bool checkCondOp(Operation *op) + + /* Record the exit information in the original loop including exit edge, + exit bb block, exit condition stmt, +- eg: exitEX originLoop.exitBBX condOpX. */ ++ eg: exit_eX origin_exit_bbX cond_stmtX. */ + + static bool recordOriginLoopExitInfo(LoopOp loop) + { +@@ -510,7 +510,7 @@ static edge getLoopPreheaderEdge(LoopOp loop) + return e; + } + +-/* Returns true if t is SSAOp and user variable exists. */ ++/* Returns true if t is SSA_NAME and user variable exists. */ + + static bool isSSANameVar(Value v) + { +@@ -525,7 +525,7 @@ static bool isSSANameVar(Value v) + return false; + } + +-/* Returns true if t1 and t2 are SSAOp and belong to the same variable. */ ++/* Returns true if t1 and t2 are SSA_NAME and belong to the same variable. */ + + static bool isSameSSANameVar(Value v1, Value v2) + { +@@ -565,9 +565,9 @@ static bool getIvUpperBound(CondOp cond) + return false; + } + +-/* Returns true only when the expression on the rhs code of stmt is PLUS, +- rhs1 is SSAOp with the same var as originLoop base, and rhs2 is +- ConstOp. */ ++/* Returns true only when the expression on the rhs code of stmt is PLUS_EXPR, ++ rhs1 is SSA_NAME with the same var as originLoop base, and rhs2 is ++ INTEGER_CST. */ + static bool checkUpdateStmt(Operation *op) + { + if (!op || !isa(op)) { +@@ -646,7 +646,7 @@ static bool getIvBase(CondOp cond) + original loop; When prolog_assign is present, make sure loop header is in + simple form; And the interpretation of prolog_assign is as follows: + eg: while (++len != limit) +- ...... ++ ...... + For such a loop, ++len will be processed before entering header_bb, and the + assign is regarded as the prolog_assign of the loop. */ + static bool recordOriginLoopHeader(LoopOp loop) +@@ -665,9 +665,6 @@ static bool recordOriginLoopHeader(LoopOp loop) + continue; + } + +- if (auto debugOp = dyn_cast(op)) +- continue; +- + if (auto cond = dyn_cast(op)) { + if (!getIvUpperBound(cond)) { + return false; +@@ -711,8 +708,8 @@ static bool recordOriginLoopLatch(LoopOp loop) + return false; + } + +-/* Returns true when the define STMT corresponding to arg0 of the MemOp +- satisfies the PtrPlus type. */ ++/* Returns true when the DEF_STMT corresponding to arg0 of the mem_ref tree ++ satisfies the POINTER_PLUS_EXPR type. */ + static bool checkBodyMemRef(Value memRef) + { + if (getValueDefCode(memRef) != IDefineCode::MemRef) { +@@ -771,7 +768,7 @@ static bool checkBodyPointerPlus(Operation *op, Value &tmpIndex) + } + + /* Record the array comparison information in the original loop, while ensuring +- that there are only statements related to cont stmt in the loop body. */ ++ that there are only statements related to cont_stmt in the loop body. */ + static bool recordOriginLoopBody(LoopOp loop) + { + Block *body = originLoop.condOp2->getBlock(); +@@ -1559,33 +1556,9 @@ static void ProcessArrayWiden(void) + } + } + +-class ArrayWidenPass : public PluginOptBase { +-public: +- ArrayWidenPass() : PluginOptBase(HANDLE_MANAGER_SETUP) +- { +- } +- bool Gate() +- { +- return true; +- } +- int DoOptimize() +- { +- uint64_t *fun = (uint64_t *)GetFuncAddr(); +- return DoOptimize(fun); +- } +- int DoOptimize(uint64_t *fun); +-}; +- + int ArrayWidenPass::DoOptimize(uint64_t *fun) + { + ProcessArrayWiden(); + return 0; + } + } +- +-void RegisterCallbacks(void) +-{ +- PinServer::PluginServer *pluginServer = PinServer::PluginServer::GetInstance(); +- PluginOpt::ManagerSetup setupData(PluginOpt::PASS_PHIOPT, 1, PluginOpt::PASS_INSERT_AFTER); +- pluginServer->RegisterPassManagerOpt(setupData, std::make_shared()); +-} +diff --git a/user/InlineFunctionPass.cpp b/user/InlineFunctionPass.cpp +new file mode 100755 +index 0000000..d982d44 +--- /dev/null ++++ b/user/InlineFunctionPass.cpp +@@ -0,0 +1,44 @@ ++/* Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. ++ ++ Licensed under the Apache License, Version 2.0 (the "License"); you may ++ not use this file except in compliance with the License. You may obtain ++ a copy of the License at ++ ++ http://www.apache.org/licenses/LICENSE-2.0 ++ ++ Unless required by applicable law or agreed to in writing, software ++ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT ++ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the ++ License for the specific language governing permissions and limitations ++ under the License. ++ ++ Author: Mingchuan Wu and Yancheng Li ++ Create: 2022-08-18 ++ Description: ++ This file contains the implementation of the inlineFunctionPass class. ++*/ ++ ++#include "PluginAPI/PluginServerAPI.h" ++#include "user/InlineFunctionPass.h" ++ ++namespace PluginOpt { ++using namespace PluginAPI; ++ ++static void UserOptimizeFunc(void) ++{ ++ PluginServerAPI pluginAPI; ++ vector allFunction = pluginAPI.GetAllFunc(); ++ int count = 0; ++ for (size_t i = 0; i < allFunction.size(); i++) { ++ if (allFunction[i].declaredInlineAttr().getValue()) ++ count++; ++ } ++ printf("declaredInline have %d functions were declared.\n", count); ++} ++ ++int InlineFunctionPass::DoOptimize() ++{ ++ UserOptimizeFunc(); ++ return 0; ++} ++} +diff --git a/user/LocalVarSummeryPass.cpp b/user/LocalVarSummeryPass.cpp +new file mode 100755 +index 0000000..4fc4985 +--- /dev/null ++++ b/user/LocalVarSummeryPass.cpp +@@ -0,0 +1,57 @@ ++/* Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. ++ ++ Licensed under the Apache License, Version 2.0 (the "License"); you may ++ not use this file except in compliance with the License. You may obtain ++ a copy of the License at ++ ++ http://www.apache.org/licenses/LICENSE-2.0 ++ ++ Unless required by applicable law or agreed to in writing, software ++ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT ++ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the ++ License for the specific language governing permissions and limitations ++ under the License. ++ ++ Author: Mingchuan Wu and Yancheng Li ++ Create: 2022-08-18 ++ Description: ++ This file contains the implementation of the LocalVarSummeryPass pass. ++*/ ++ ++#include "PluginAPI/ControlFlowAPI.h" ++#include "PluginAPI/PluginServerAPI.h" ++#include "user/LocalVarSummeryPass.h" ++ ++namespace PluginOpt { ++using namespace PluginAPI; ++ ++static void LocalVarSummery(void) ++{ ++ PluginServerAPI pluginAPI; ++ vector allFunction = pluginAPI.GetAllFunc(); ++ map args = PluginServer::GetInstance()->GetArgs(); ++ for (size_t i = 0; i < allFunction.size(); i++) { ++ uint64_t funcID = allFunction[i].idAttr().getValue().getZExtValue(); ++ printf("In the %ldth function:\n", i); ++ vector decls = pluginAPI.GetDecls(funcID); ++ int64_t typeFilter = -1u; ++ if (args.find("type_code") != args.end()) { ++ typeFilter = (int64_t)pluginAPI.GetTypeCodeFromString(args["type_code"]); ++ } ++ for (size_t j = 0; j < decls.size(); j++) { ++ auto decl = decls[j]; ++ string name = decl.symNameAttr().getValue().str(); ++ int64_t declTypeID = decl.typeIDAttr().getValue().getZExtValue(); ++ if (declTypeID == typeFilter) { ++ printf("\tFind %ldth target type %s\n", j, name.c_str()); ++ } ++ } ++ } ++} ++ ++int LocalVarSummeryPass::DoOptimize() ++{ ++ LocalVarSummery(); ++ return 0; ++} ++} +diff --git a/user/user.cpp b/user/user.cpp +index bee70bb..16f0687 100644 +--- a/user/user.cpp ++++ b/user/user.cpp +@@ -27,7 +27,7 @@ void RegisterCallbacks(void) + { + PinServer::PluginServer *pluginServer = PinServer::PluginServer::GetInstance(); + pluginServer->RegisterOpt(std::make_shared(PluginOpt::HANDLE_BEFORE_IPA)); +- pluginServer->RegisterOpt(std::make_shared(PluginOpt::HANDLE_AFTER_IPA)); +- PluginOpt::ManagerSetup setupData(PluginOpt::PASS_PHIOPT, 1, PluginOpt::PASS_INSERT_AFTER); +- pluginServer->RegisterPassManagerOpt(setupData, std::make_shared()); ++ pluginServer->RegisterOpt(std::make_shared(PluginOpt::HANDLE_BEFORE_IPA)); ++ // PluginOpt::ManagerSetup setupData(PluginOpt::PASS_PHIOPT, 1, PluginOpt::PASS_INSERT_AFTER); ++ // pluginServer->RegisterPassManagerOpt(setupData, std::make_shared()); + } +-- +2.27.0.windows.1 + diff --git a/0009-Pin-server-Support-functiontype-structtype.eg.patch b/0009-Pin-server-Support-functiontype-structtype.eg.patch new file mode 100644 index 0000000000000000000000000000000000000000..01e239836b016fb8da70499995af24b5a1cc0458 --- /dev/null +++ b/0009-Pin-server-Support-functiontype-structtype.eg.patch @@ -0,0 +1,566 @@ +From e2a6f729f4ce40542fccec997529b43d25a6d5ae Mon Sep 17 00:00:00 2001 +From: d00573793 +Date: Tue, 21 Feb 2023 21:53:44 +0800 +Subject: [PATCH 9/9] [Pin-server] Support functiontype structtype.eg. + + +diff --git a/include/Dialect/PluginOps.td b/include/Dialect/PluginOps.td +index 3a88846..1083141 100644 +--- a/include/Dialect/PluginOps.td ++++ b/include/Dialect/PluginOps.td +@@ -30,7 +30,8 @@ def FunctionOp : Plugin_Op<"function", [NoSideEffect]> { + + let arguments = (ins UI64Attr:$id, + StrAttr:$funcName, +- OptionalAttr:$declaredInline); ++ OptionalAttr:$declaredInline, ++ TypeAttr:$type); + let regions = (region AnyRegion:$bodyRegion); + + // Add custom build methods for the operation. These method populates +@@ -39,13 +40,15 @@ def FunctionOp : Plugin_Op<"function", [NoSideEffect]> { + let builders = [ + OpBuilderDAG<(ins "uint64_t":$id, + "StringRef":$funcName, +- "bool":$declaredInline)> ++ "bool":$declaredInline, ++ "Type":$type)> + ]; + + let extraClassDeclaration = [{ + std::vector GetAllLoops(); + LoopOp AllocateNewLoop(); + bool IsDomInfoAvailable(); ++ Type getResultType(); + }]; + } + +diff --git a/include/Dialect/PluginTypes.h b/include/Dialect/PluginTypes.h +index 7fb1ff9..3f7f14b 100644 +--- a/include/Dialect/PluginTypes.h ++++ b/include/Dialect/PluginTypes.h +@@ -78,6 +78,9 @@ namespace detail { + struct PluginIntegerTypeStorage; + struct PluginFloatTypeStorage; + struct PluginPointerTypeStorage; ++ struct PluginTypeAndSizeStorage; ++ struct PluginFunctionTypeStorage; ++ struct PluginStructTypeStorage; + } + + class PluginIntegerType : public Type::TypeBase { +@@ -128,6 +131,61 @@ public: + unsigned isReadOnlyElem(); + }; // class PluginPointerType + ++class PluginArrayType : public Type::TypeBase { ++public: ++ using Base::Base; ++ ++ PluginTypeID getPluginTypeID (); ++ ++ static bool isValidElementType(Type type); ++ ++ static PluginArrayType get(MLIRContext *context, Type elementType, unsigned numElements); ++ ++ Type getElementType(); ++ ++ unsigned getNumElements(); ++}; // class PluginArrayType ++ ++class PluginFunctionType : public Type::TypeBase { ++public: ++ using Base::Base; ++ ++ PluginTypeID getPluginTypeID (); ++ ++ static bool isValidArgumentType(Type type); ++ ++ static bool isValidResultType(Type type); ++ ++ static PluginFunctionType get(MLIRContext *context, Type result, ArrayRef arguments); ++ ++ Type getReturnType(); ++ ++ unsigned getNumParams(); ++ ++ Type getParamType(unsigned i); ++ ++ ArrayRef getParams(); ++ ++}; // class PluginFunctionType ++ ++class PluginStructType : public Type::TypeBase { ++public: ++ using Base::Base; ++ ++ PluginTypeID getPluginTypeID (); ++ ++ static bool isValidElementType(Type type); ++ ++ static PluginStructType get(MLIRContext *context, std::string name, ArrayRef elements, ArrayRef elemNames); ++ ++ std::string getName(); ++ ++ ArrayRef getBody(); ++ ++ ArrayRef getElementNames(); ++ ++}; // class PluginStructType ++ + class PluginVoidType : public Type::TypeBase { + public: + using Base::Base; +diff --git a/include/PluginServer/PluginJson.h b/include/PluginServer/PluginJson.h +index 6f46187..fd2f05b 100755 +--- a/include/PluginServer/PluginJson.h ++++ b/include/PluginServer/PluginJson.h +@@ -59,7 +59,7 @@ public: + /* 将json格式数据解析成map格式 */ + void GetAttributes(Json::Value node, map& attributes); + mlir::Value ValueJsonDeSerialize(Json::Value valueJson); +- Json::Value TypeJsonSerialize(PluginIR::PluginTypeBase& type); ++ Json::Value TypeJsonSerialize(PluginIR::PluginTypeBase type); + mlir::Value MemRefDeSerialize(const string& data); + bool ProcessBlock(mlir::Block*, mlir::Region&, const Json::Value&); + }; +diff --git a/lib/Dialect/PluginDialect.cpp b/lib/Dialect/PluginDialect.cpp +index 95b38cf..ba8e4fe 100644 +--- a/lib/Dialect/PluginDialect.cpp ++++ b/lib/Dialect/PluginDialect.cpp +@@ -37,6 +37,9 @@ void PluginDialect::initialize() + PluginIR::PluginIntegerType, + PluginIR::PluginFloatType, + PluginIR::PluginPointerType, ++ PluginIR::PluginArrayType, ++ PluginIR::PluginFunctionType, ++ PluginIR::PluginStructType, + PluginIR::PluginBooleanType, + PluginIR::PluginVoidType, + PluginIR::PluginUndefType>(); +diff --git a/lib/Dialect/PluginOps.cpp b/lib/Dialect/PluginOps.cpp +index a30e9ed..1c4fb2d 100644 +--- a/lib/Dialect/PluginOps.cpp ++++ b/lib/Dialect/PluginOps.cpp +@@ -64,12 +64,19 @@ static uint64_t getBlockAddress(mlir::Block* b) + } + + void FunctionOp::build(OpBuilder &builder, OperationState &state, +- uint64_t id, StringRef funcName, bool declaredInline) ++ uint64_t id, StringRef funcName, bool declaredInline, Type type) + { +- FunctionOp::build(builder, state, +- builder.getI64IntegerAttr(id), +- builder.getStringAttr(funcName), +- builder.getBoolAttr(declaredInline)); ++ state.addRegion(); ++ state.addAttribute("id", builder.getI64IntegerAttr(id)); ++ state.addAttribute("funcName", builder.getStringAttr(funcName)); ++ state.addAttribute("declaredInline", builder.getBoolAttr(declaredInline)); ++ if (type) state.addAttribute("type", TypeAttr::get(type)); ++} ++ ++Type FunctionOp::getResultType() ++{ ++ PluginIR::PluginFunctionType resultType = type().dyn_cast(); ++ return resultType; + } + + vector FunctionOp::GetAllLoops() +diff --git a/lib/Dialect/PluginTypes.cpp b/lib/Dialect/PluginTypes.cpp +index c0a58c2..337fc49 100644 +--- a/lib/Dialect/PluginTypes.cpp ++++ b/lib/Dialect/PluginTypes.cpp +@@ -97,6 +97,80 @@ namespace detail { + Type pointee; + unsigned readOnlyPointee; + }; ++ ++ struct PluginTypeAndSizeStorage : public TypeStorage { ++ using KeyTy = std::tuple; ++ ++ PluginTypeAndSizeStorage(const KeyTy &key) ++ : elementType(std::get<0>(key)), numElements(std::get<1>(key)) {} ++ ++ static PluginTypeAndSizeStorage *construct(TypeStorageAllocator &allocator, KeyTy key) ++ { ++ return new (allocator.allocate()) ++ PluginTypeAndSizeStorage(key); ++ } ++ ++ bool operator==(const KeyTy &key) const ++ { ++ return std::make_tuple(elementType, numElements) == key; ++ } ++ ++ Type elementType; ++ unsigned numElements; ++ }; ++ ++ struct PluginFunctionTypeStorage : public TypeStorage { ++ using KeyTy = std::tuple>; ++ ++ PluginFunctionTypeStorage(Type resultType, ArrayRef argumentTypes) ++ : resultType(resultType), argumentTypes(argumentTypes) {} ++ ++ static PluginFunctionTypeStorage *construct(TypeStorageAllocator &allocator, KeyTy key) ++ { ++ return new (allocator.allocate()) ++ PluginFunctionTypeStorage(std::get<0>(key), allocator.copyInto(std::get<1>(key))); ++ } ++ ++ static unsigned hashKey(const KeyTy &key) { ++ // LLVM doesn't like hashing bools in tuples. ++ return llvm::hash_combine(std::get<0>(key), std::get<1>(key)); ++ } ++ ++ bool operator==(const KeyTy &key) const ++ { ++ return std::make_tuple(resultType, argumentTypes) == key; ++ } ++ ++ Type resultType; ++ ArrayRef argumentTypes; ++ }; ++ ++ struct PluginStructTypeStorage : public TypeStorage { ++ using KeyTy = std::tuple, ArrayRef>; ++ ++ PluginStructTypeStorage(std::string name, ArrayRef elements, ArrayRef elemNames) ++ : name(name), elements(elements), elemNames(elemNames) {} ++ ++ static PluginStructTypeStorage *construct(TypeStorageAllocator &allocator, KeyTy key) ++ { ++ return new (allocator.allocate()) ++ PluginStructTypeStorage(std::get<0>(key), allocator.copyInto(std::get<1>(key)), allocator.copyInto(std::get<2>(key))); ++ } ++ ++ static unsigned hashKey(const KeyTy &key) { ++ // LLVM doesn't like hashing bools in tuples. ++ return llvm::hash_combine(std::get<0>(key), std::get<1>(key), std::get<2>(key)); ++ } ++ ++ bool operator==(const KeyTy &key) const ++ { ++ return std::make_tuple(name, elements, elemNames) == key; ++ } ++ ++ std::string name; ++ ArrayRef elements; ++ ArrayRef elemNames; ++ }; + } + } + +@@ -122,6 +196,15 @@ PluginTypeID PluginTypeBase::getPluginTypeID () + if (auto Ty = dyn_cast()) { + return Ty.getPluginTypeID (); + } ++ if (auto Ty = dyn_cast()) { ++ return Ty.getPluginTypeID (); ++ } ++ if (auto Ty = dyn_cast()) { ++ return Ty.getPluginTypeID (); ++ } ++ if (auto Ty = dyn_cast()) { ++ return Ty.getPluginTypeID (); ++ } + return PluginTypeID::UndefTyID; + } + +@@ -292,4 +375,108 @@ unsigned PluginPointerType::isReadOnlyElem() + PluginPointerType PluginPointerType::get (MLIRContext *context, Type pointee, unsigned readOnlyPointee) + { + return Base::get(context, pointee, readOnlyPointee); ++} ++ ++// ===----------------------------------------------------------------------===// ++// Plugin Array Type ++// ===----------------------------------------------------------------------===// ++ ++PluginTypeID PluginArrayType::getPluginTypeID() ++{ ++ return PluginTypeID::ArrayTyID; ++} ++ ++bool PluginArrayType::isValidElementType(Type type) ++{ ++ return !type.isa(); ++} ++ ++PluginArrayType PluginArrayType::get(MLIRContext *context, Type elementType, unsigned numElements) ++{ ++ return Base::get(context, elementType, numElements); ++} ++ ++Type PluginArrayType::getElementType() ++{ ++ return getImpl()->elementType; ++} ++ ++unsigned PluginArrayType::getNumElements() ++{ ++ return getImpl()->numElements; ++} ++ ++// ===----------------------------------------------------------------------===// ++// Plugin Function Type ++// ===----------------------------------------------------------------------===// ++ ++PluginTypeID PluginFunctionType::getPluginTypeID() ++{ ++ return PluginTypeID::FunctionTyID; ++} ++ ++bool PluginFunctionType::isValidArgumentType(Type type) ++{ ++ return !type.isa(); ++} ++ ++bool PluginFunctionType::isValidResultType(Type type) { ++ return !type.isa(); ++} ++ ++PluginFunctionType PluginFunctionType::get(MLIRContext *context, Type result, ArrayRef arguments) ++{ ++ return Base::get(context, result, arguments); ++} ++ ++Type PluginFunctionType::getReturnType() ++{ ++ return getImpl()->resultType; ++} ++ ++unsigned PluginFunctionType::getNumParams() ++{ ++ return getImpl()->argumentTypes.size(); ++} ++ ++Type PluginFunctionType::getParamType(unsigned i) { ++ return getImpl()->argumentTypes[i]; ++} ++ ++ArrayRef PluginFunctionType::getParams() ++{ ++ return getImpl()->argumentTypes; ++} ++ ++// ===----------------------------------------------------------------------===// ++// Plugin Struct Type ++// ===----------------------------------------------------------------------===// ++ ++PluginTypeID PluginStructType::getPluginTypeID() ++{ ++ return PluginTypeID::StructTyID; ++} ++ ++bool PluginStructType::isValidElementType(Type type) { ++ return !type.isa(); ++} ++ ++PluginStructType PluginStructType::get(MLIRContext *context, std::string name, ArrayRef elements, ArrayRef elemNames) ++{ ++ return Base::get(context, name, elements, elemNames); ++} ++ ++std::string PluginStructType::getName() ++{ ++ return getImpl()->name; ++} ++ ++ArrayRef PluginStructType::getBody() ++{ ++ return getImpl()->elements; ++} ++ ++ArrayRef PluginStructType::getElementNames() ++{ ++ return getImpl()->elemNames; + } +\ No newline at end of file +diff --git a/lib/PluginAPI/PluginServerAPI.cpp b/lib/PluginAPI/PluginServerAPI.cpp +index f81a3ad..e3435b0 100644 +--- a/lib/PluginAPI/PluginServerAPI.cpp ++++ b/lib/PluginAPI/PluginServerAPI.cpp +@@ -343,6 +343,14 @@ PluginIR::PluginTypeID PluginServerAPI::GetTypeCodeFromString(string type) + return PluginIR::PluginTypeID::FloatTyID; + } else if (type == "DoubleTy") { + return PluginIR::PluginTypeID::DoubleTyID; ++ } else if (type == "PointerTy") { ++ return PluginIR::PluginTypeID::PointerTyID; ++ } else if (type == "ArrayTy") { ++ return PluginIR::PluginTypeID::ArrayTyID; ++ } else if (type == "FunctionTy") { ++ return PluginIR::PluginTypeID::FunctionTyID; ++ } else if (type == "StructTy") { ++ return PluginIR::PluginTypeID::StructTyID; + } + + return PluginIR::PluginTypeID::UndefTyID; +diff --git a/lib/PluginServer/PluginJson.cpp b/lib/PluginServer/PluginJson.cpp +index 7bbf681..e1beddf 100755 +--- a/lib/PluginServer/PluginJson.cpp ++++ b/lib/PluginServer/PluginJson.cpp +@@ -23,6 +23,7 @@ + + namespace PinJson { + using namespace PinServer; ++using namespace mlir; + using namespace mlir::Plugin; + + static uintptr_t GetID(Json::Value node) +@@ -41,7 +42,7 @@ static void JsonGetAttributes(Json::Value node, map& attributes) + } + } + +-Json::Value PluginJson::TypeJsonSerialize (PluginIR::PluginTypeBase& type) ++Json::Value PluginJson::TypeJsonSerialize (PluginIR::PluginTypeBase type) + { + Json::Value root; + Json::Value operationObj; +@@ -53,6 +54,41 @@ Json::Value PluginJson::TypeJsonSerialize (PluginIR::PluginTypeBase& type) + ReTypeId = static_cast(type.getPluginTypeID()); + item["id"] = std::to_string(ReTypeId); + ++ if (auto Ty = type.dyn_cast()) { ++ std::string tyName = Ty.getName(); ++ item["structtype"] = tyName; ++ size_t paramIndex = 0; ++ ArrayRef paramsType = Ty.getBody(); ++ for (auto ty :paramsType) { ++ std::string paramStr = "elemType" + std::to_string(paramIndex++); ++ item["structelemType"][paramStr] = TypeJsonSerialize(ty.dyn_cast()); ++ } ++ paramIndex = 0; ++ ArrayRef paramsNames = Ty.getElementNames(); ++ for (auto name :paramsNames) { ++ std::string paramStr = "elemName" + std::to_string(paramIndex++); ++ item["structelemName"][paramStr] = name; ++ } ++ } ++ ++ if (auto Ty = type.dyn_cast()) { ++ auto fnrestype = Ty.getReturnType().dyn_cast(); ++ item["fnreturntype"] = TypeJsonSerialize(fnrestype); ++ size_t paramIndex = 0; ++ ArrayRef paramsType = Ty.getParams(); ++ for (auto ty : Ty.getParams()) { ++ string paramStr = "argType" + std::to_string(paramIndex++); ++ item["fnargsType"][paramStr] = TypeJsonSerialize(ty.dyn_cast()); ++ } ++ } ++ ++ if (auto Ty = type.dyn_cast()) { ++ auto elemTy = Ty.getElementType().dyn_cast(); ++ item["elementType"] = TypeJsonSerialize(elemTy); ++ uint64_t elemNum = Ty.getNumElements(); ++ item["arraysize"] = std::to_string(elemNum); ++ } ++ + if (auto elemTy = type.dyn_cast()) { + auto baseTy = elemTy.getElementType().dyn_cast(); + item["elementType"] = TypeJsonSerialize(baseTy); +@@ -247,8 +283,9 @@ void PluginJson::FuncOpJsonDeSerialize( + bool declaredInline = false; + if (funcAttributes["declaredInline"] == "1") declaredInline = true; + auto location = opBuilder.getUnknownLoc(); ++ PluginIR::PluginTypeBase retType = TypeJsonDeSerialize(node["retType"].toStyledString()); + FunctionOp fOp = opBuilder.create( +- location, id, funcAttributes["funcName"], declaredInline); ++ location, id, funcAttributes["funcName"], declaredInline, retType); + mlir::Region &bodyRegion = fOp.bodyRegion(); + Json::Value regionJson = node["region"]; + Json::Value::Members bbMember = regionJson.getMemberNames(); +@@ -302,7 +339,40 @@ PluginIR::PluginTypeBase PluginJson::TypeJsonDeSerialize(const string& data) + mlir::Type elemTy = TypeJsonDeSerialize(type["elementType"].toStyledString()); + baseType = PluginIR::PluginPointerType::get( + PluginServer::GetInstance()->GetContext(), elemTy, type["elemConst"].asString() == "1" ? 1 : 0); +- } else { ++ } else if (id == static_cast(PluginIR::ArrayTyID)) { ++ mlir::Type elemTy = TypeJsonDeSerialize(type["elementType"].toStyledString()); ++ uint64_t elemNum = GetID(type["arraysize"]); ++ baseType = PluginIR::PluginArrayType::get(PluginServer::GetInstance()->GetContext(), elemTy, elemNum); ++ } else if (id == static_cast(PluginIR::FunctionTyID)) { ++ mlir::Type returnTy = TypeJsonDeSerialize(type["fnreturntype"].toStyledString()); ++ llvm::SmallVector typelist; ++ Json::Value::Members fnTypeNum = type["fnargsType"].getMemberNames(); ++ uint64_t argsNum = fnTypeNum.size(); ++ for (size_t paramIndex = 0; paramIndex < argsNum; paramIndex++) { ++ string Key = "argType" + std::to_string(paramIndex); ++ mlir::Type paramTy = TypeJsonDeSerialize(type["fnargsType"][Key].toStyledString()); ++ typelist.push_back(paramTy); ++ } ++ baseType = PluginIR::PluginFunctionType::get(PluginServer::GetInstance()->GetContext(), returnTy, typelist); ++ } else if (id == static_cast(PluginIR::StructTyID)) { ++ std::string tyName = type["structtype"].asString(); ++ llvm::SmallVector typelist; ++ Json::Value::Members elemTypeNum = type["structelemType"].getMemberNames(); ++ for (size_t paramIndex = 0; paramIndex < elemTypeNum.size(); paramIndex++) { ++ string Key = "elemType" + std::to_string(paramIndex); ++ mlir::Type paramTy = TypeJsonDeSerialize(type["structelemType"][Key].toStyledString()); ++ typelist.push_back(paramTy); ++ } ++ llvm::SmallVector names; ++ Json::Value::Members elemNameNum = type["structelemName"].getMemberNames(); ++ for (size_t paramIndex = 0; paramIndex < elemTypeNum.size(); paramIndex++) { ++ std::string Key = "elemName" + std::to_string(paramIndex); ++ std::string elemName = type["structelemName"][Key].asString(); ++ names.push_back(elemName); ++ } ++ baseType = PluginIR::PluginStructType::get(PluginServer::GetInstance()->GetContext(), tyName, typelist, names); ++ } ++ else { + if (PluginTypeId == PluginIR::VoidTyID) { + baseType = PluginIR::PluginVoidType::get(PluginServer::GetInstance()->GetContext()); + } +diff --git a/user/LocalVarSummeryPass.cpp b/user/LocalVarSummeryPass.cpp +index 4fc4985..2e157e3 100755 +--- a/user/LocalVarSummeryPass.cpp ++++ b/user/LocalVarSummeryPass.cpp +@@ -23,6 +23,10 @@ + #include "user/LocalVarSummeryPass.h" + + namespace PluginOpt { ++using std::string; ++using std::vector; ++using std::cout; ++using namespace mlir; + using namespace PluginAPI; + + static void LocalVarSummery(void) +@@ -38,6 +42,32 @@ static void LocalVarSummery(void) + if (args.find("type_code") != args.end()) { + typeFilter = (int64_t)pluginAPI.GetTypeCodeFromString(args["type_code"]); + } ++ mlir::Plugin::FunctionOp funcOp = allFunction[i]; ++ printf("func name is :%s\n", funcOp.funcNameAttr().getValue().str().c_str()); ++ mlir::Type dgyty = funcOp.type(); ++ if (auto ty = dgyty.dyn_cast()) { ++ if(auto stTy = ty.getReturnType().dyn_cast()) { ++ printf("func return type is PluginStructType\n"); ++ std::string tyName = stTy.getName(); ++ printf(" struct name is : %s\n", tyName.c_str()); ++ ++ llvm::ArrayRef paramsType = stTy.getBody(); ++ for (auto tty :paramsType) { ++ printf("\n struct arg id : %d\n", tty.dyn_cast().getPluginTypeID()); ++ } ++ llvm::ArrayRef paramsNames = stTy.getElementNames(); ++ for (auto name :paramsNames) { ++ std::string pName = name; ++ printf("\n struct argname is : %s\n", pName.c_str()); ++ } ++ } ++ size_t paramIndex = 0; ++ llvm::ArrayRef paramsType = ty.getParams(); ++ for (auto ty : ty.getParams()) { ++ printf("\n Param index : %d\n", paramIndex++); ++ printf("\n Param type id : %d\n", ty.dyn_cast().getPluginTypeID()); ++ } ++ } + for (size_t j = 0; j < decls.size(); j++) { + auto decl = decls[j]; + string name = decl.symNameAttr().getValue().str(); +-- +2.27.0.windows.1 + diff --git a/pin-server.spec b/pin-server.spec index 085eaecb714672b07a8e250ec5d67f45cfa0fbf3..a7e46689ac5b22e91e917732f38686848d9ffb46 100644 --- a/pin-server.spec +++ b/pin-server.spec @@ -1,6 +1,6 @@ Name: pin-server Version: 0.4.0 -Release: 1 +Release: 2 Summary: Pin (Plug-IN framework) server provides plugin APIs for compiler optimization developers to develop optimization pass. License: Apache 2.0 URL: https://gitee.com/openeuler/pin-server @@ -10,6 +10,16 @@ BuildRequires: gcc gcc-c++ cmake make pkgconfig grpc grpc-plugins grpc-devel pr BuildRequires: llvm-mlir llvm-mlir-static llvm-mlir-devel llvm-devel Requires: grpc protobuf +Patch1: 0001-Refactoring-Code-refactoring-of-Communication-Subsys.patch +Patch2: 0002-Refactoring-Code-refactoring-of-Communication-Subsys.patch +Patch3: 0003-Refactoring-Code-refactoring-of-Communication-Subsys.patch +Patch4: 0004-Pin-server-Add-DebugOp.patch +Patch5: 0005-Pin-server-Add-API-for-LTO-judgement.patch +Patch6: 0006-Pin-server-Fix-bug-for-BuildCallOp.patch +Patch7: 0007-Pin-server-Refactoring-array-widen-compare-into-a-cl.patch +Patch8: 0008-Pin-server-Refactoring-DEMOs-into-PluginOpt-classes.patch +Patch9: 0009-Pin-server-Support-functiontype-structtype.eg.patch + %description Pin (Plug-IN framework) server provides plugin APIs for compiler optimization developers to develop optimization pass. @@ -27,6 +37,16 @@ A demo for pin-server %prep %setup -q +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 +%patch6 -p1 +%patch7 -p1 +%patch8 -p1 +%patch9 -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 @@ -45,13 +65,19 @@ cd _build %files demo %attr(0755,root,root) %{_libdir}/libpin_user.so -%attr(0755,root,root) %{_libdir}/libMLIRPlugin.so -%attr(0755,root,root) %{_libdir}/libMLIRPlugin.so.12 +%attr(0755,root,root) %{_libdir}/libMLIRPluginServer.so +%attr(0755,root,root) %{_libdir}/libMLIRPluginServer.so.12 %attr(0755,root,root) %{_libdir}/libMLIRServerAPI.so %attr(0755,root,root) %{_libdir}/libMLIRServerAPI.so.12 %attr(0644,root,root) %{_libdir}/libpin_user.sha256 %changelog +* Wed Feb 22 2023 dingguangya - 0.4.0-2 +- Type:Update +- ID:NA +- SUG:NA +- DESC:Sync patch from openEuler/pin-server + * Tue Dec 20 2022 zhaowenyu <804544223@qq.com> - 0.4.0-1 - Type:Update - ID:NA