368 lines
17 KiB
Diff
368 lines
17 KiB
Diff
From 7879456e9645e34cf1bcc61ad340834ba1ac716a Mon Sep 17 00:00:00 2001
|
|
From: d00573793 <dingguangya1@huawei.com>
|
|
Date: Fri, 17 Mar 2023 10:27:41 +0800
|
|
Subject: [PATCH] [Pin-gcc-client] Fix struct self-contained CallOp TreeTOValue
|
|
|
|
|
|
diff --git a/include/Dialect/PluginOps.td b/include/Dialect/PluginOps.td
|
|
index 143a856..ba29f7e 100644
|
|
--- a/include/Dialect/PluginOps.td
|
|
+++ b/include/Dialect/PluginOps.td
|
|
@@ -56,14 +56,16 @@ def FunctionOp : Plugin_Op<"function", [NoSideEffect]> {
|
|
let arguments = (ins UI64Attr:$id,
|
|
StrAttr:$funcName,
|
|
OptionalAttr<BoolAttr>:$declaredInline,
|
|
- TypeAttr:$type);
|
|
+ TypeAttr:$type,
|
|
+ OptionalAttr<BoolAttr>:$validType);
|
|
let regions = (region AnyRegion:$bodyRegion);
|
|
|
|
// Add custom build methods for the operation. These method populates
|
|
// the `state` that MLIR uses to create operations, i.e. these are used when
|
|
// using `builder.create<Op>(...)`.
|
|
let builders = [
|
|
- OpBuilderDAG<(ins "uint64_t":$id, "StringRef":$funcName, "bool":$declaredInline, "Type":$type)>
|
|
+ OpBuilderDAG<(ins "uint64_t":$id, "StringRef":$funcName, "bool":$declaredInline, "Type":$type, "bool":$validType)>,
|
|
+ OpBuilderDAG<(ins "uint64_t":$id, "StringRef":$funcName, "bool":$declaredInline, "bool":$validType)>
|
|
];
|
|
let extraClassDeclaration = [{
|
|
Type getResultType();
|
|
diff --git a/include/Dialect/PluginTypes.h b/include/Dialect/PluginTypes.h
|
|
index 983d7ca..081b35b 100644
|
|
--- a/include/Dialect/PluginTypes.h
|
|
+++ b/include/Dialect/PluginTypes.h
|
|
@@ -191,12 +191,10 @@ public:
|
|
|
|
static bool isValidElementType(Type type);
|
|
|
|
- static PluginStructType get(MLIRContext *context, StringRef name, ArrayRef<Type> elements, ArrayRef<StringRef> elemNames);
|
|
+ static PluginStructType get(MLIRContext *context, StringRef name, ArrayRef<StringRef> elemNames);
|
|
|
|
StringRef getName();
|
|
|
|
- ArrayRef<Type> getBody();
|
|
-
|
|
ArrayRef<StringRef> getElementNames();
|
|
|
|
}; // class PluginStructType
|
|
diff --git a/lib/Dialect/PluginOps.cpp b/lib/Dialect/PluginOps.cpp
|
|
index cf1dbbe..ec8286a 100644
|
|
--- a/lib/Dialect/PluginOps.cpp
|
|
+++ b/lib/Dialect/PluginOps.cpp
|
|
@@ -49,15 +49,26 @@ void CGnodeOp::build(OpBuilder &builder, OperationState &state,
|
|
// ============================
|
|
|
|
void FunctionOp::build(OpBuilder &builder, OperationState &state,
|
|
- uint64_t id, StringRef funcName, bool declaredInline, Type type)
|
|
+ uint64_t id, StringRef funcName, bool declaredInline, Type type, bool validType)
|
|
{
|
|
state.addRegion();
|
|
state.addAttribute("id", builder.getI64IntegerAttr(id));
|
|
state.addAttribute("funcName", builder.getStringAttr(funcName));
|
|
state.addAttribute("declaredInline", builder.getBoolAttr(declaredInline));
|
|
+ state.addAttribute("validType", builder.getBoolAttr(validType));
|
|
if (type) state.addAttribute("type", TypeAttr::get(type));
|
|
}
|
|
|
|
+void FunctionOp::build(OpBuilder &builder, OperationState &state,
|
|
+ uint64_t id, StringRef funcName, bool declaredInline, bool validType)
|
|
+{
|
|
+ state.addRegion();
|
|
+ state.addAttribute("id", builder.getI64IntegerAttr(id));
|
|
+ state.addAttribute("funcName", builder.getStringAttr(funcName));
|
|
+ state.addAttribute("declaredInline", builder.getBoolAttr(declaredInline));
|
|
+ state.addAttribute("validType", builder.getBoolAttr(validType));
|
|
+}
|
|
+
|
|
Type FunctionOp::getResultType()
|
|
{
|
|
PluginIR::PluginFunctionType resultType = type().dyn_cast<PluginIR::PluginFunctionType>();
|
|
diff --git a/lib/Dialect/PluginTypes.cpp b/lib/Dialect/PluginTypes.cpp
|
|
index 1b3e09a..6c5cb0c 100644
|
|
--- a/lib/Dialect/PluginTypes.cpp
|
|
+++ b/lib/Dialect/PluginTypes.cpp
|
|
@@ -147,29 +147,28 @@ namespace Detail {
|
|
};
|
|
|
|
struct PluginStructTypeStorage : public TypeStorage {
|
|
- using KeyTy = std::tuple<StringRef, ArrayRef<Type>, ArrayRef<StringRef>>;
|
|
+ using KeyTy = std::tuple<StringRef, ArrayRef<StringRef>>;
|
|
|
|
- PluginStructTypeStorage(StringRef name, ArrayRef<Type> elements, ArrayRef<StringRef> elemNames)
|
|
- : name(name), elements(elements), elemNames(elemNames) {}
|
|
+ PluginStructTypeStorage(StringRef name, ArrayRef<StringRef> elemNames)
|
|
+ : name(name), elemNames(elemNames) {}
|
|
|
|
static PluginStructTypeStorage *construct(TypeStorageAllocator &allocator, KeyTy key)
|
|
{
|
|
return new (allocator.allocate<PluginStructTypeStorage>())
|
|
- PluginStructTypeStorage(std::get<0>(key), allocator.copyInto(std::get<1>(key)), allocator.copyInto(std::get<2>(key)));
|
|
+ PluginStructTypeStorage(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), std::get<2>(key));
|
|
+ return llvm::hash_combine(std::get<0>(key), std::get<1>(key));
|
|
}
|
|
|
|
bool operator==(const KeyTy &key) const
|
|
{
|
|
- return std::make_tuple(name, elements, elemNames) == key;
|
|
+ return std::make_tuple(name, elemNames) == key;
|
|
}
|
|
|
|
StringRef name;
|
|
- ArrayRef<Type> elements;
|
|
ArrayRef<StringRef> elemNames;
|
|
};
|
|
} // namespace Detail
|
|
@@ -496,9 +495,9 @@ bool PluginStructType::isValidElementType(Type type) {
|
|
return !type.isa<PluginVoidType, PluginFunctionType>();
|
|
}
|
|
|
|
-PluginStructType PluginStructType::get(MLIRContext *context, StringRef name, ArrayRef<Type> elements, ArrayRef<StringRef> elemNames)
|
|
+PluginStructType PluginStructType::get(MLIRContext *context, StringRef name, ArrayRef<StringRef> elemNames)
|
|
{
|
|
- return Base::get(context, name, elements, elemNames);
|
|
+ return Base::get(context, name, elemNames);
|
|
}
|
|
|
|
StringRef PluginStructType::getName()
|
|
@@ -506,11 +505,6 @@ StringRef PluginStructType::getName()
|
|
return getImpl()->name;
|
|
}
|
|
|
|
-ArrayRef<Type> PluginStructType::getBody()
|
|
-{
|
|
- return getImpl()->elements;
|
|
-}
|
|
-
|
|
ArrayRef<StringRef> PluginStructType::getElementNames()
|
|
{
|
|
return getImpl()->elemNames;
|
|
diff --git a/lib/PluginClient/PluginJson.cpp b/lib/PluginClient/PluginJson.cpp
|
|
index be0ee8d..7384a49 100755
|
|
--- a/lib/PluginClient/PluginJson.cpp
|
|
+++ b/lib/PluginClient/PluginJson.cpp
|
|
@@ -53,12 +53,6 @@ Json::Value PluginJson::TypeJsonSerialize(PluginIR::PluginTypeBase type)
|
|
std::string tyName = Ty.getName().str();
|
|
item["structtype"] = tyName;
|
|
size_t paramIndex = 0;
|
|
- ArrayRef<Type> paramsType = Ty.getBody();
|
|
- for (auto ty :paramsType) {
|
|
- string paramStr = "elemType" + std::to_string(paramIndex++);
|
|
- item["structelemType"][paramStr] = TypeJsonSerialize(ty.dyn_cast<PluginIR::PluginTypeBase>());
|
|
- }
|
|
- paramIndex = 0;
|
|
ArrayRef<StringRef> paramsNames = Ty.getElementNames();
|
|
for (auto name :paramsNames) {
|
|
string paramStr = "elemName" + std::to_string(paramIndex++);
|
|
@@ -164,21 +158,14 @@ PluginIR::PluginTypeBase PluginJson::TypeJsonDeSerialize(const string& data, mli
|
|
baseType = PluginIR::PluginFunctionType::get(&context, returnTy, typelist);
|
|
} else if (id == static_cast<uint64_t>(PluginIR::StructTyID)) {
|
|
StringRef tyName = type["structtype"].toStyledString();
|
|
- llvm::SmallVector<Type> 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(), context);
|
|
- typelist.push_back(paramTy);
|
|
- }
|
|
llvm::SmallVector<StringRef> names;
|
|
Json::Value::Members elemNameNum = type["structelemName"].getMemberNames();
|
|
- for (size_t paramIndex = 0; paramIndex < elemTypeNum.size(); paramIndex++) {
|
|
+ for (size_t paramIndex = 0; paramIndex < elemNameNum.size(); paramIndex++) {
|
|
string Key = "elemName" + std::to_string(paramIndex);
|
|
StringRef elemName = type["structelemName"][Key].toStyledString();
|
|
names.push_back(elemName);
|
|
}
|
|
- baseType = PluginIR::PluginStructType::get(&context, tyName, typelist, names);
|
|
+ baseType = PluginIR::PluginStructType::get(&context, tyName, names);
|
|
}
|
|
else {
|
|
if (PluginTypeId == PluginIR::VoidTyID) {
|
|
@@ -229,11 +216,16 @@ void PluginJson::FunctionOpJsonSerialize(vector<FunctionOp>& data, string& out)
|
|
}
|
|
item["attributes"]["funcName"] = d.funcNameAttr().getValue().str().c_str();
|
|
|
|
- mlir::Type fnty = d.type();
|
|
- if (auto ty = fnty.dyn_cast<PluginIR::PluginFunctionType>()) {
|
|
- if (auto retTy = ty.dyn_cast<PluginIR::PluginTypeBase>()) {
|
|
- item["retType"] = TypeJsonSerialize(retTy);
|
|
+ if (d.validTypeAttr().getValue()) {
|
|
+ item["attributes"]["validType"] = "1";
|
|
+ mlir::Type fnty = d.type();
|
|
+ if (auto ty = fnty.dyn_cast<PluginIR::PluginFunctionType>()) {
|
|
+ if (auto retTy = ty.dyn_cast<PluginIR::PluginTypeBase>()) {
|
|
+ item["retType"] = TypeJsonSerialize(retTy);
|
|
+ }
|
|
}
|
|
+ } else {
|
|
+ item["attributes"]["validType"] = "0";
|
|
}
|
|
|
|
auto ®ion = d.getRegion();
|
|
diff --git a/lib/Translate/GimpleToPluginOps.cpp b/lib/Translate/GimpleToPluginOps.cpp
|
|
index 930b430..d1b8319 100644
|
|
--- a/lib/Translate/GimpleToPluginOps.cpp
|
|
+++ b/lib/Translate/GimpleToPluginOps.cpp
|
|
@@ -379,6 +379,9 @@ vector<uint64_t> GimpleToPluginOps::GetFunctionIDs()
|
|
function *fn = NULL;
|
|
vector<uint64_t> functions;
|
|
FOR_EACH_FUNCTION (node) {
|
|
+ if (!node->real_symbol_p ())
|
|
+ continue;
|
|
+ if(!node->definition) continue;
|
|
fn = DECL_STRUCT_FUNCTION(node->decl);
|
|
if (fn == NULL)
|
|
continue;
|
|
@@ -820,12 +823,20 @@ FunctionOp GimpleToPluginOps::BuildFunctionOp(uint64_t functionId)
|
|
bool declaredInline = false;
|
|
if (DECL_DECLARED_INLINE_P(fn->decl))
|
|
declaredInline = true;
|
|
- tree returnType = TREE_TYPE(fn->decl);
|
|
- PluginTypeBase rPluginType = typeTranslator.translateType((intptr_t)returnType);
|
|
auto location = builder.getUnknownLoc();
|
|
- auto Ty = rPluginType.dyn_cast<PluginFunctionType>();
|
|
- FunctionOp retOp = builder.create<FunctionOp>(location, functionId,
|
|
- funcName, declaredInline, Ty);
|
|
+ bool validType = false;
|
|
+ tree returnType = TREE_TYPE(fn->decl);
|
|
+ FunctionOp retOp;
|
|
+ if (TREE_CODE(returnType) != FUNCTION_TYPE) {
|
|
+ retOp = builder.create<FunctionOp>(location, functionId,
|
|
+ funcName, declaredInline, validType);
|
|
+ } else {
|
|
+ validType = true;
|
|
+ PluginTypeBase rPluginType = typeTranslator.translateType((intptr_t)returnType);
|
|
+ auto Ty = rPluginType.dyn_cast<PluginFunctionType>();
|
|
+ retOp = builder.create<FunctionOp>(location, functionId,
|
|
+ funcName, declaredInline, Ty, validType);
|
|
+ }
|
|
auto& fr = retOp.bodyRegion();
|
|
if (fn->cfg == nullptr) return retOp;
|
|
if (!ProcessBasicBlock((intptr_t)ENTRY_BLOCK_PTR_FOR_FN(fn), fr)) {
|
|
@@ -1000,8 +1011,13 @@ CallOp GimpleToPluginOps::BuildCallOp(uint64_t gcallId)
|
|
Value arg = TreeToValue(argId);
|
|
ops.push_back(arg);
|
|
}
|
|
- tree returnType = gimple_call_return_type(stmt);
|
|
- PluginTypeBase rPluginType = typeTranslator.translateType((intptr_t)returnType);
|
|
+ // tree returnType = gimple_call_return_type(stmt);
|
|
+ // PluginTypeBase rPluginType = typeTranslator.translateType((intptr_t)returnType);
|
|
+ PluginTypeBase rPluginType = nullptr;
|
|
+ if (gimple_call_fntype (stmt) != NULL_TREE || gimple_call_lhs (stmt) != NULL_TREE) {
|
|
+ tree returnType = gimple_call_return_type(stmt);
|
|
+ rPluginType = typeTranslator.translateType((intptr_t)returnType);
|
|
+ }
|
|
tree fndecl = gimple_call_fndecl(stmt);
|
|
CallOp ret;
|
|
if (fndecl == NULL_TREE || DECL_NAME(fndecl) == NULL_TREE) {
|
|
@@ -1665,6 +1681,12 @@ Value GimpleToPluginOps::TreeToValue(uint64_t treeId)
|
|
break;
|
|
}
|
|
case BLOCK : {
|
|
+ if (BLOCK_VARS(t) == NULL_TREE) {
|
|
+ GetTreeAttr(treeId, readOnly, rPluginType);
|
|
+ opValue = builder.create<PlaceholderOp>(builder.getUnknownLoc(),
|
|
+ treeId, IDefineCode::UNDEF, readOnly, rPluginType);
|
|
+ break;
|
|
+ }
|
|
llvm::Optional<mlir::Value> vars = TreeToValue((uint64_t)BLOCK_VARS(t));
|
|
llvm::Optional<uint64_t> supercontext = (uint64_t)BLOCK_SUPERCONTEXT(t);
|
|
llvm::Optional<mlir::Value> subblocks = TreeToValue((uint64_t)BLOCK_SUBBLOCKS(t));
|
|
@@ -1746,7 +1768,9 @@ bool GimpleToPluginOps::ProcessGimpleStmt(intptr_t bbPtr, Region& rg)
|
|
// Process other condition, such as return
|
|
builder.create<RetOp>(builder.getUnknownLoc(), (uint64_t)bb);
|
|
} else {
|
|
- assert(false);
|
|
+ builder.create<FallThroughOp>(builder.getUnknownLoc(), (uint64_t)bb,
|
|
+ bbTranslator->blockMaps[EDGE_SUCC(bb, 0)->dest],
|
|
+ (uint64_t)(EDGE_SUCC(bb, 0)->dest));
|
|
}
|
|
}
|
|
|
|
diff --git a/lib/Translate/TypeTranslation.cpp b/lib/Translate/TypeTranslation.cpp
|
|
index 354a8b9..8a0a674 100644
|
|
--- a/lib/Translate/TypeTranslation.cpp
|
|
+++ b/lib/Translate/TypeTranslation.cpp
|
|
@@ -130,6 +130,8 @@ private:
|
|
llvm::SmallVector<Type> getElemType(tree type)
|
|
{
|
|
llvm::SmallVector<Type> typelist;
|
|
+ if (!type)
|
|
+ return typelist;
|
|
tree parmtype;
|
|
for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
|
|
{
|
|
@@ -145,6 +147,8 @@ private:
|
|
llvm::SmallVector<StringRef> getElemNames(tree type)
|
|
{
|
|
llvm::SmallVector<StringRef> names;
|
|
+ if (!type)
|
|
+ return names;
|
|
StringRef name;
|
|
for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
|
|
{
|
|
@@ -161,6 +165,8 @@ private:
|
|
type. */
|
|
PluginTypeBase translatePrimitiveType (tree type)
|
|
{
|
|
+ if (!type)
|
|
+ return PluginUndefType::get(&context);
|
|
if (TREE_CODE(type) == INTEGER_TYPE)
|
|
return PluginIntegerType::get(&context, getBitWidth(type),
|
|
isUnsigned(type) ? PluginIntegerType::Unsigned : PluginIntegerType::Signed);
|
|
@@ -170,9 +176,10 @@ private:
|
|
return PluginBooleanType::get(&context);
|
|
if (TREE_CODE(type) == VOID_TYPE)
|
|
return PluginVoidType::get(&context);
|
|
- if (TREE_CODE(type) == POINTER_TYPE)
|
|
+ if (TREE_CODE(type) == POINTER_TYPE) {
|
|
return PluginPointerType::get(&context, translatePrimitiveType(TREE_TYPE(type)),
|
|
TYPE_READONLY(TREE_TYPE(type)) ? 1 : 0);
|
|
+ }
|
|
if (TREE_CODE(type) == ARRAY_TYPE)
|
|
return PluginArrayType::get(&context,translatePrimitiveType(TREE_TYPE(type)), getDomainIndex(type));
|
|
if (TREE_CODE(type) == VECTOR_TYPE)
|
|
@@ -182,7 +189,7 @@ private:
|
|
return PluginFunctionType::get(&context, translatePrimitiveType(TREE_TYPE(type)),argsType);
|
|
}
|
|
if (TREE_CODE(type) == RECORD_TYPE) {
|
|
- return PluginStructType::get(&context, getTypeName(type), getElemType(type), getElemNames(type));
|
|
+ return PluginStructType::get(&context, getTypeName(type), getElemNames(type));
|
|
}
|
|
return PluginUndefType::get(&context);
|
|
}
|
|
@@ -295,7 +302,6 @@ private:
|
|
return build_function_type_array(returnType, paramTypes.length (), paramTypes.address ());
|
|
}
|
|
if (auto Ty = type.dyn_cast<PluginStructType>()) {
|
|
- ArrayRef<Type> elemTypes = Ty.getBody();
|
|
ArrayRef<StringRef> elemNames = Ty.getElementNames();
|
|
StringRef tyName = Ty.getName();
|
|
unsigned fieldSize = elemNames.size();
|
|
@@ -305,18 +311,8 @@ private:
|
|
unsigned i;
|
|
|
|
ret = make_node (RECORD_TYPE);
|
|
- for (i = 0; i < fieldSize; i++)
|
|
- {
|
|
- mlir::Type elemTy = elemTypes[i];
|
|
- auto ty = elemTy.dyn_cast<PluginTypeBase>();
|
|
- tree elmType = translatePrimitiveType(ty);
|
|
- fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, get_identifier (elemNames[i].str().c_str()), elmType);
|
|
- DECL_CONTEXT (fields[i]) = ret;
|
|
- if (i) DECL_CHAIN (fields[i - 1]) = fields[i];
|
|
- }
|
|
tree typeDecl = build_decl (input_location, TYPE_DECL, get_identifier (tyName.str().c_str()), ret);
|
|
DECL_ARTIFICIAL (typeDecl) = 1;
|
|
- TYPE_FIELDS (ret) = fields[0];
|
|
TYPE_NAME (ret) = typeDecl;
|
|
layout_type (ret);
|
|
return ret;
|
|
--
|
|
2.33.0
|
|
|