diff --git a/include/revng/Model/CABIFunctionType.h b/include/revng/Model/CABIFunctionType.h index 7c0926a70..fe8cee7ef 100644 --- a/include/revng/Model/CABIFunctionType.h +++ b/include/revng/Model/CABIFunctionType.h @@ -48,6 +48,17 @@ public: using generated::CABIFunctionType::CABIFunctionType; CABIFunctionType() : generated::CABIFunctionType() { Kind = AssociatedKind; } +public: + llvm::SmallVector edges() { + llvm::SmallVector Result; + + for (model::Argument &Argument : Arguments) + Result.push_back(Argument.Type); + Result.push_back(ReturnType); + + return Result; + } + public: Identifier name() const; static bool classof(const Type *T) { return classof(T->key()); } diff --git a/include/revng/Model/EnumType.h b/include/revng/Model/EnumType.h index 27e38763c..67bc61422 100644 --- a/include/revng/Model/EnumType.h +++ b/include/revng/Model/EnumType.h @@ -42,6 +42,13 @@ public: public: Identifier name() const; + +public: + llvm::SmallVector edges() { + return { model::QualifiedType(UnderlyingType, {}) }; + } + +public: static bool classof(const Type *T) { return classof(T->key()); } static bool classof(const Key &K) { return std::get<0>(K) == AssociatedKind; } }; diff --git a/include/revng/Model/PrimitiveType.h b/include/revng/Model/PrimitiveType.h index 1abe65ee3..976c1265d 100644 --- a/include/revng/Model/PrimitiveType.h +++ b/include/revng/Model/PrimitiveType.h @@ -37,6 +37,9 @@ public: public: Identifier name() const; +public: + llvm::SmallVector edges() { return {}; } + public: static bool classof(const Type *T) { return classof(T->key()); } static bool classof(const Key &K) { return std::get<0>(K) == AssociatedKind; } diff --git a/include/revng/Model/RawFunctionType.h b/include/revng/Model/RawFunctionType.h index bb754c5a7..095d2148c 100644 --- a/include/revng/Model/RawFunctionType.h +++ b/include/revng/Model/RawFunctionType.h @@ -53,6 +53,20 @@ public: public: Identifier name() const; + +public: + llvm::SmallVector edges() { + llvm::SmallVector Result; + + for (auto &Argument : Arguments) + Result.push_back(Argument.Type); + for (auto &RV : ReturnValues) + Result.push_back(RV.Type); + + return Result; + } + +public: static bool classof(const Type *T) { return classof(T->key()); } static bool classof(const Key &K) { return std::get<0>(K) == AssociatedKind; } }; diff --git a/include/revng/Model/StructType.h b/include/revng/Model/StructType.h index 347ea1234..42bc7b7f5 100644 --- a/include/revng/Model/StructType.h +++ b/include/revng/Model/StructType.h @@ -43,6 +43,18 @@ public: public: Identifier name() const; + +public: + llvm::SmallVector edges() { + llvm::SmallVector Result; + + for (auto &Field : Fields) + Result.push_back(Field.Type); + + return Result; + } + +public: static bool classof(const Type *T) { return classof(T->key()); } static bool classof(const Key &K) { return std::get<0>(K) == AssociatedKind; } }; diff --git a/include/revng/Model/Type.h b/include/revng/Model/Type.h index 3706c38d6..b01177eaa 100644 --- a/include/revng/Model/Type.h +++ b/include/revng/Model/Type.h @@ -60,6 +60,9 @@ public: std::optional size() const debug_function; RecursiveCoroutine> size(VerifyHelper &VH) const; +public: + llvm::SmallVector edges(); + public: bool verify() const debug_function; bool verify(bool Assert) const debug_function; diff --git a/include/revng/Model/TypedefType.h b/include/revng/Model/TypedefType.h index a9fa3d2d5..7d0ae2fe8 100644 --- a/include/revng/Model/TypedefType.h +++ b/include/revng/Model/TypedefType.h @@ -36,6 +36,13 @@ public: public: Identifier name() const; + +public: + llvm::SmallVector edges() { + return { UnderlyingType }; + } + +public: static bool classof(const Type *T) { return classof(T->key()); } static bool classof(const Key &K) { return std::get<0>(K) == AssociatedKind; } }; diff --git a/include/revng/Model/UnionType.h b/include/revng/Model/UnionType.h index e8073c4c3..ad4c8f821 100644 --- a/include/revng/Model/UnionType.h +++ b/include/revng/Model/UnionType.h @@ -40,6 +40,18 @@ public: public: Identifier name() const; + +public: + llvm::SmallVector edges() { + llvm::SmallVector Result; + + for (auto &Field : Fields) + Result.push_back(Field.Type); + + return Result; + } + +public: static bool classof(const Type *T) { return classof(T->key()); } static bool classof(const Key &K) { return std::get<0>(K) == AssociatedKind; } }; diff --git a/lib/Model/Processing.cpp b/lib/Model/Processing.cpp index b4aff93db..5d51e22a0 100644 --- a/lib/Model/Processing.cpp +++ b/lib/Model/Processing.cpp @@ -31,42 +31,15 @@ unsigned dropTypesDependingOnTypes(TupleTree &Model, for (UpcastablePointer &T : Model->Types) TypeToNode[T.get()] = ReverseDependencyGraph.addNode(TypeNode{ T.get() }); - auto RegisterDependency = [&](UpcastablePointer &T, - const model::QualifiedType &QT) { - auto *DependantType = QT.UnqualifiedType.get(); - TypeToNode.at(DependantType)->addSuccessor(TypeToNode.at(T.get())); - }; - - // Populate the graph + // Register edges for (UpcastablePointer &T : Model->Types) { - - // Ignore dependencies of + // Ignore dependencies of types we need to drop if (Types.count(T.get()) != 0) continue; - if (auto *Primitive = dyn_cast(T.get())) { - // Nothing to do here - } else if (auto *Struct = dyn_cast(T.get())) { - for (const model::StructField &Field : Struct->Fields) - RegisterDependency(T, Field.Type); - } else if (auto *Union = dyn_cast(T.get())) { - for (const model::UnionField &Field : Union->Fields) - RegisterDependency(T, Field.Type); - } else if (auto *Enum = dyn_cast(T.get())) { - RegisterDependency(T, model::QualifiedType(Enum->UnderlyingType, {})); - } else if (auto *Typedef = dyn_cast(T.get())) { - RegisterDependency(T, Typedef->UnderlyingType); - } else if (auto *RFT = dyn_cast(T.get())) { - for (const model::NamedTypedRegister &Argument : RFT->Arguments) - RegisterDependency(T, Argument.Type); - for (const model::TypedRegister &RV : RFT->ReturnValues) - RegisterDependency(T, RV.Type); - } else if (auto *CAFT = dyn_cast(T.get())) { - for (const model::Argument &Argument : CAFT->Arguments) - RegisterDependency(T, Argument.Type); - RegisterDependency(T, CAFT->ReturnType); - } else { - revng_abort(); + for (model::QualifiedType &QT : T->edges()) { + auto *DependantType = QT.UnqualifiedType.get(); + TypeToNode.at(DependantType)->addSuccessor(TypeToNode.at(T.get())); } } diff --git a/lib/Model/Type.cpp b/lib/Model/Type.cpp index 9f59b93ef..32eb2bfcb 100644 --- a/lib/Model/Type.cpp +++ b/lib/Model/Type.cpp @@ -187,6 +187,13 @@ model::Type::Type(TypeKind::Values TK) : model::Type::Type(TK, IDGenerator->get()) { } +llvm::SmallVector model::Type::edges() { + llvm::SmallVector Empty; + auto *This = this; + auto GetEdges = [](auto &Upcasted) { return Upcasted.edges(); }; + return upcast(This, GetEdges, Empty); +} + template model::UpcastableType makeTypeWithIDImpl(model::TypeKind::Values Kind, uint64_t ID) {