From 28574a87bc2d7719855e046ede70f66bb83c7453 Mon Sep 17 00:00:00 2001 From: Ivan Krysak Date: Wed, 15 Mar 2023 15:17:33 +0200 Subject: [PATCH] Yield: switch to `layout`'s position and size --- .../revng/Yield/ControlFlow/Configuration.h | 22 +++--- include/revng/Yield/Graph.h | 32 ++------- .../GraphLayout/SugiyamaStyle/Compute.h | 4 +- .../revng/Yield/Support/GraphLayout/Traits.h | 4 +- lib/Yield/ControlFlow/NodeSizeCalculation.cpp | 70 +++++++++---------- lib/Yield/ControlFlow/SVG.cpp | 54 +++++++------- .../GraphLayout/SugiyamaStyle/Helpers.h | 4 +- 7 files changed, 85 insertions(+), 105 deletions(-) diff --git a/include/revng/Yield/ControlFlow/Configuration.h b/include/revng/Yield/ControlFlow/Configuration.h index 081310d10..1a97946d2 100644 --- a/include/revng/Yield/ControlFlow/Configuration.h +++ b/include/revng/Yield/ControlFlow/Configuration.h @@ -11,20 +11,20 @@ namespace yield::cfg { struct Configuration { public: /// Specifies the minimum possible distance between two edges. - Graph::Dimension EdgeMarginSize; + layout::Dimension EdgeMarginSize; /// Specifies the distance between the node margin and its contents. - Graph::Dimension InternalNodeMarginSize; + layout::Dimension InternalNodeMarginSize; /// Specifies the minimum possible distance between two nodes. - Graph::Dimension ExternalNodeMarginSize; + layout::Dimension ExternalNodeMarginSize; /// Specifies the minimum possible horizontal distance between /// an instruction element and the border of its node. - Graph::Dimension HorizontalInstructionMarginSize; + layout::Dimension HorizontalInstructionMarginSize; /// Specifies the minimum possible distance between two instructions. - Graph::Dimension VerticalInstructionMarginSize; + layout::Dimension VerticalInstructionMarginSize; /// Specifies the relation between the horizontal size of a single character /// to the size of the font. @@ -38,7 +38,7 @@ public: /// let it report the final length of the said line. /// This factor is equal to the size of the line divided by the number of /// characters in it and the size of the font used. - Graph::Dimension HorizontalFontFactor; + layout::Dimension HorizontalFontFactor; /// Specifies the relation between the vertical size of a single character /// to the size of the font. @@ -51,12 +51,12 @@ public: /// all cases) let it report the final size of that paragraph. /// This factor is equal to the height of the paragraph divided by the number /// of lines in it and the size of the font used. - Graph::Dimension VerticalFontFactor; + layout::Dimension VerticalFontFactor; /// Specifies the size of the font used for instruction rendering. /// /// It's used to approximate node sizes. - Graph::Dimension InstructionFontSize; + layout::Dimension InstructionFontSize; /// Specifies the size of the font used for instruction address and raw bytes /// rendering. @@ -64,17 +64,17 @@ public: /// It's used to approximate node sizes. /// /// \note this value should be set to zero if no bytes are displayed. - Graph::Dimension AnnotationFontSize; + layout::Dimension AnnotationFontSize; /// Specifies the size of the font used for comment rendering. /// /// It's used to approximate node sizes. - Graph::Dimension CommentFontSize; + layout::Dimension CommentFontSize; /// Specifies the size of the font used for label rendering. /// /// It's used to approximate node sizes. - Graph::Dimension LabelFontSize; + layout::Dimension LabelFontSize; /// Specifies the degree to which node corners should be rounded. size_t NodeCornerRoundingFactor; diff --git a/include/revng/Yield/Graph.h b/include/revng/Yield/Graph.h index 91c06b9cf..de19850c8 100644 --- a/include/revng/Yield/Graph.h +++ b/include/revng/Yield/Graph.h @@ -8,39 +8,23 @@ #include "revng/ADT/GenericGraph.h" #include "revng/Support/BasicBlockID.h" +#include "revng/Yield/Support/GraphLayout/Traits.h" namespace yield { namespace detail { -using Coordinate = float; -using Dimension = Coordinate; - -struct Point { - Coordinate X; - Coordinate Y; - - constexpr Point(Coordinate X = 0, Coordinate Y = 0) : X(X), Y(Y) {} -}; - -struct Size { - Dimension W; - Dimension H; - - constexpr Size(Dimension W = 0, Dimension H = 0) : W(W), H(H) {} -}; - struct Node { explicit Node(const BasicBlockID &Address = BasicBlockID::invalid(), const BasicBlockID &NextAddress = BasicBlockID::invalid(), - const Point &Center = { 0, 0 }, - const Size &Size = { 0, 0 }) : + const layout::Point &Center = { 0, 0 }, + const layout::Size &Size = { 0, 0 }) : Address(Address), NextAddress(NextAddress), Center(Center), Size(Size) {} BasicBlockID Address; BasicBlockID NextAddress; - Point Center; - Size Size; + layout::Point Center; + layout::Size Size; }; enum class EdgeStatus { Unrouted, Routed, Hidden }; @@ -50,7 +34,7 @@ struct Edge { EdgeStatus Status = EdgeStatus::Unrouted; EdgeType Type = EdgeType::Unconditional; - std::vector Path = {}; + std::vector Path = {}; }; } // namespace detail @@ -62,10 +46,6 @@ public: using GenericGraph::GenericGraph; public: - using Coordinate = detail::Coordinate; - using Dimension = detail::Dimension; - using Point = detail::Point; - using Size = detail::Size; using EdgeStatus = detail::EdgeStatus; using EdgeType = detail::EdgeType; }; diff --git a/include/revng/Yield/Support/GraphLayout/SugiyamaStyle/Compute.h b/include/revng/Yield/Support/GraphLayout/SugiyamaStyle/Compute.h index a75b79c61..c83304c51 100644 --- a/include/revng/Yield/Support/GraphLayout/SugiyamaStyle/Compute.h +++ b/include/revng/Yield/Support/GraphLayout/SugiyamaStyle/Compute.h @@ -65,10 +65,10 @@ public: float VirtualNodeWeight; /// Specifies the minimum possible distance between two nodes. - Graph::Dimension NodeMarginSize; + layout::Dimension NodeMarginSize; /// Specifies the minimum possible distance between two edges. - Graph::Dimension EdgeMarginSize; + layout::Dimension EdgeMarginSize; }; /// A custom graph layering algorithm designed for pre-calculating majority of diff --git a/include/revng/Yield/Support/GraphLayout/Traits.h b/include/revng/Yield/Support/GraphLayout/Traits.h index 999664c51..b61e3b632 100644 --- a/include/revng/Yield/Support/GraphLayout/Traits.h +++ b/include/revng/Yield/Support/GraphLayout/Traits.h @@ -35,7 +35,7 @@ struct Size { template concept HasLLVMGraphTraits = requires(const GraphType &Graph) { { llvm::GraphTraits::getEntryNode(Graph) } -> - convertible_to::NodeRef>; + std::convertible_to::NodeRef>; }; template @@ -59,7 +59,7 @@ template concept HasLayoutableInputGraphTraits = HasLLVMGraphTraits && requires(typename llvm::GraphTraits::NodeRef Node) { { LayoutableGraphTraits::getNodeSize(Node) } -> - convertible_to; + std::convertible_to; }; template diff --git a/lib/Yield/ControlFlow/NodeSizeCalculation.cpp b/lib/Yield/ControlFlow/NodeSizeCalculation.cpp index f22997318..e9e696424 100644 --- a/lib/Yield/ControlFlow/NodeSizeCalculation.cpp +++ b/lib/Yield/ControlFlow/NodeSizeCalculation.cpp @@ -13,12 +13,12 @@ #include "revng/Yield/Function.h" #include "revng/Yield/Graph.h" -static yield::Graph::Size -operator+(const yield::Graph::Size &LHS, const yield::Graph::Size &RHS) { - return yield::Graph::Size(LHS.W + RHS.W, LHS.H + RHS.H); +static yield::layout::Size +operator+(const yield::layout::Size &LHS, const yield::layout::Size &RHS) { + return yield::layout::Size(LHS.W + RHS.W, LHS.H + RHS.H); } -constexpr static yield::Graph::Size textSize(std::string_view Text) { +constexpr static yield::layout::Size textSize(std::string_view Text) { size_t LineCount = 0; size_t MaximumLineLength = 0; @@ -40,7 +40,7 @@ constexpr static yield::Graph::Size textSize(std::string_view Text) { if (LastLineLength != 0) ++LineCount; - return yield::Graph::Size(MaximumLineLength, LineCount); + return yield::layout::Size(MaximumLineLength, LineCount); } constexpr static size_t firstLineSize(std::string_view Text) { @@ -51,30 +51,30 @@ constexpr static size_t firstLineSize(std::string_view Text) { return Text.size() - FirstLineEnd; } -static yield::Graph::Size -fontSize(yield::Graph::Size &&Input, - yield::Graph::Dimension FontSize, +static yield::layout::Size +fontSize(yield::layout::Size &&Input, + yield::layout::Dimension FontSize, const yield::cfg::Configuration &Configuration) { Input.W *= FontSize * Configuration.HorizontalFontFactor; Input.H *= FontSize * Configuration.VerticalFontFactor; return std::move(Input); } -static yield::Graph::Size -fontSize(yield::Graph::Size &&Input, - yield::Graph::Dimension HorizontalFontSize, - yield::Graph::Dimension VerticalFontSize, +static yield::layout::Size +fontSize(yield::layout::Size &&Input, + yield::layout::Dimension HorizontalFontSize, + yield::layout::Dimension VerticalFontSize, const yield::cfg::Configuration &Configuration) { Input.W *= HorizontalFontSize * Configuration.HorizontalFontFactor; Input.H *= VerticalFontSize * Configuration.VerticalFontFactor; return std::move(Input); } -static yield::Graph::Size +static yield::layout::Size singleLineSize(std::string_view Text, - float FontSize, + float Font, const yield::cfg::Configuration &Configuration) { - yield::Graph::Size Result = fontSize(textSize(Text), FontSize, Configuration); + yield::layout::Size Result = fontSize(textSize(Text), Font, Configuration); Result.W += Configuration.HorizontalInstructionMarginSize * 2; Result.H += Configuration.VerticalInstructionMarginSize * 2; @@ -82,13 +82,13 @@ singleLineSize(std::string_view Text, return Result; } -static yield::Graph::Size +static yield::layout::Size linkSize(const BasicBlockID &Address, const yield::Function &Function, const model::Binary &Binary, size_t IndicatorSize = 0, const BasicBlockID &NextAddress = BasicBlockID::invalid()) { - yield::Graph::Size Indicator(IndicatorSize, 0); + yield::layout::Size Indicator(IndicatorSize, 0); if (not Address.isValid()) return Indicator + textSize("an unknown location"); @@ -105,8 +105,8 @@ linkSize(const BasicBlockID &Address, } } -static yield::Graph::Size & -appendSize(yield::Graph::Size &Original, const yield::Graph::Size &AddOn) { +static yield::layout::Size & +appendSize(yield::layout::Size &Original, const yield::layout::Size &AddOn) { if (AddOn.W > Original.W) Original.W = AddOn.W; Original.H += AddOn.H; @@ -114,18 +114,18 @@ appendSize(yield::Graph::Size &Original, const yield::Graph::Size &AddOn) { return Original; } -static yield::Graph::Size +static yield::layout::Size instructionSize(const yield::Instruction &Instruction, const yield::cfg::Configuration &Configuration, size_t CommentIndicatorSize, bool IsInDelayedSlot = false) { // Instruction body. - yield::Graph::Size Result = fontSize(textSize(Instruction.Disassembled()), - Configuration.InstructionFontSize, - Configuration); + yield::layout::Size Result = fontSize(textSize(Instruction.Disassembled()), + Configuration.InstructionFontSize, + Configuration); // Comment and delayed slot notice. - yield::Graph::Size CommentSize; + yield::layout::Size CommentSize; if (!Instruction.Comment().empty()) { CommentSize = textSize(Instruction.Comment()); revng_assert(CommentSize.H == 1, "Multi line comments are not supported."); @@ -137,7 +137,7 @@ instructionSize(const yield::Instruction &Instruction, appendSize(CommentSize, DelayedSlotNoticeSize); } - auto CommentBlockSize = fontSize(yield::Graph::Size(CommentSize), + auto CommentBlockSize = fontSize(yield::layout::Size(CommentSize), Configuration.CommentFontSize, Configuration.InstructionFontSize, Configuration); @@ -145,7 +145,7 @@ instructionSize(const yield::Instruction &Instruction, Result.W = std::max(firstLineSize(Instruction.Comment()) + Result.W + CommentIndicatorSize + 1, CommentBlockSize.W); - auto OneLine = fontSize(yield::Graph::Size(1, 1), + auto OneLine = fontSize(yield::layout::Size(1, 1), Configuration.CommentFontSize, Configuration.InstructionFontSize, Configuration); @@ -158,12 +158,12 @@ instructionSize(const yield::Instruction &Instruction, if (!Instruction.Error().empty()) appendSize(Result, fontSize(textSize(Instruction.Error()) - + yield::Graph::Size(CommentIndicatorSize + 1, 0), + + yield::layout::Size(CommentIndicatorSize + 1, 0), Configuration.CommentFontSize, Configuration)); // Annotation. - yield::Graph::Size RawBytesLengthWithOffsets{ 0, 0 }; + yield::layout::Size RawBytesLengthWithOffsets{ 0, 0 }; RawBytesLengthWithOffsets.W += Instruction.RawBytes().size() * 3; RawBytesLengthWithOffsets.W += CommentIndicatorSize + 5; appendSize(Result, @@ -179,7 +179,7 @@ instructionSize(const yield::Instruction &Instruction, return Result; } -static yield::Graph::Size +static yield::layout::Size basicBlockSize(const yield::BasicBlock &BasicBlock, const yield::Function &Function, const model::Binary &Binary, @@ -187,12 +187,12 @@ basicBlockSize(const yield::BasicBlock &BasicBlock, // Account for the size of the label namespace A = model::Architecture; auto LabelIndicator = A::getAssemblyLabelIndicator(Binary.Architecture()); - yield::Graph::Size Result = fontSize(linkSize(BasicBlock.ID(), - Function, - Binary, - LabelIndicator.size()), - Configuration.LabelFontSize, - Configuration); + yield::layout::Size Result = fontSize(linkSize(BasicBlock.ID(), + Function, + Binary, + LabelIndicator.size()), + Configuration.LabelFontSize, + Configuration); namespace A = model::Architecture; auto CommentIndicator = A::getAssemblyCommentIndicator(Binary.Architecture()); diff --git a/lib/Yield/ControlFlow/SVG.cpp b/lib/Yield/ControlFlow/SVG.cpp index 7c64fbccb..14dd17676 100644 --- a/lib/Yield/ControlFlow/SVG.cpp +++ b/lib/Yield/ControlFlow/SVG.cpp @@ -59,13 +59,13 @@ static std::string_view edgeTypeAsString(yield::Graph::EdgeType Type) { // clang-format off template -static std::string cubicBend(const yield::Graph::Point &From, - const yield::Graph::Point &To, +static std::string cubicBend(const yield::layout::Point &From, + const yield::layout::Point &To, bool VerticalCurves, std::ratio &&Bend = {}) { // clang-format on - using Coordinate = yield::Graph::Coordinate; + using Coordinate = yield::layout::Coordinate; constexpr Coordinate Factor = Coordinate(Numerator) / Denominator; Coordinate XModifier = Factor * (To.X - From.X); Coordinate YModifier = Factor * (To.Y - From.Y); @@ -84,7 +84,7 @@ static std::string cubicBend(const yield::Graph::Point &From, -To.Y); } -static std::string edge(const std::vector &Path, +static std::string edge(const std::vector &Path, const yield::Graph::EdgeType &Type, bool UseOrthogonalBends = true, bool UseVerticalCurves = false) { @@ -120,9 +120,9 @@ static std::string edge(const std::vector &Path, static std::string node(const yield::Node *Node, std::string &&Content, const yield::cfg::Configuration &Configuration) { - yield::Graph::Size HalfSize{ Node->Size.W / 2, Node->Size.H / 2 }; - yield::Graph::Point TopLeft{ Node->Center.X - HalfSize.W, - -Node->Center.Y - HalfSize.H }; + yield::layout::Size HalfSize{ Node->Size.W / 2, Node->Size.H / 2 }; + yield::layout::Point TopLeft{ Node->Center.X - HalfSize.W, + -Node->Center.Y - HalfSize.H }; Tag Body("body", std::move(Content)); Body.addAttribute("xmlns", R"(http://www.w3.org/1999/xhtml)"); @@ -147,16 +147,16 @@ static std::string node(const yield::Node *Node, } struct Viewbox { - yield::Graph::Point TopLeft = { -1, -1 }; - yield::Graph::Point BottomRight = { +1, +1 }; + yield::layout::Point TopLeft = { -1, -1 }; + yield::layout::Point BottomRight = { +1, +1 }; }; static Viewbox makeViewbox(const yield::Node *Node) { - yield::Graph::Size HalfSize{ Node->Size.W / 2, Node->Size.H / 2 }; - yield::Graph::Point TopLeft{ Node->Center.X - HalfSize.W, - -Node->Center.Y - HalfSize.H }; - yield::Graph::Point BottomRight{ Node->Center.X + HalfSize.W, - -Node->Center.Y + HalfSize.H }; + yield::layout::Size HalfSize{ Node->Size.W / 2, Node->Size.H / 2 }; + yield::layout::Point TopLeft{ Node->Center.X - HalfSize.W, + -Node->Center.Y - HalfSize.H }; + yield::layout::Point BottomRight{ Node->Center.X + HalfSize.W, + -Node->Center.Y + HalfSize.H }; return Viewbox{ .TopLeft = std::move(TopLeft), .BottomRight = std::move(BottomRight) }; } @@ -172,7 +172,7 @@ static void expandViewbox(Viewbox &LHS, const Viewbox &RHS) { LHS.BottomRight.Y = RHS.BottomRight.Y; } -static void expandViewbox(Viewbox &Box, const yield::Graph::Point &Point) { +static void expandViewbox(Viewbox &Box, const yield::layout::Point &Point) { if (Box.TopLeft.X > Point.X) Box.TopLeft.X = Point.X; if (Box.TopLeft.Y > -Point.Y) @@ -376,14 +376,14 @@ struct LabelNodeHelper { size_t NameLength = FunctionIterator->name().size(); revng_assert(NameLength != 0); - Node->Size = yield::Graph::Size{ + Node->Size = yield::layout::Size{ NameLength * Configuration.LabelFontSize * Configuration.HorizontalFontFactor, 1 * Configuration.LabelFontSize * Configuration.VerticalFontFactor }; } else { // An entry node. - Node->Size = yield::Graph::Size{ 30, 30 }; + Node->Size = yield::layout::Size{ 30, 30 }; } Node->Size.W += Configuration.InternalNodeMarginSize * 2; @@ -441,19 +441,19 @@ std::string yield::svg::callGraph(const CrossRelations &Relations, return exportGraph(CalleeTree, Configuration, LeftToRight, Helper); } -static auto flipPoint(yield::Graph::Point const &Point) { - return yield::Graph::Point{ -Point.X, -Point.Y }; +static auto flipPoint(yield::layout::Point const &Point) { + return yield::layout::Point{ -Point.X, -Point.Y }; }; -static auto -calculateDelta(yield::Graph::Point const &LHS, yield::Graph::Point const &RHS) { - return yield::Graph::Point{ RHS.X - LHS.X, RHS.Y - LHS.Y }; +static auto calculateDelta(yield::layout::Point const &LHS, + yield::layout::Point const &RHS) { + return yield::layout::Point{ RHS.X - LHS.X, RHS.Y - LHS.Y }; } -static auto translatePoint(yield::Graph::Point const &Point, - yield::Graph::Point const &Delta) { - return yield::Graph::Point{ Point.X + Delta.X, Point.Y + Delta.Y }; +static auto translatePoint(yield::layout::Point const &Point, + yield::layout::Point const &Delta) { + return yield::layout::Point{ Point.X + Delta.X, Point.Y + Delta.Y }; } -static auto convertPoint(yield::Graph::Point const &Point, - yield::Graph::Point const &Delta) { +static auto convertPoint(yield::layout::Point const &Point, + yield::layout::Point const &Delta) { return translatePoint(flipPoint(Point), Delta); } diff --git a/lib/Yield/Support/GraphLayout/SugiyamaStyle/Helpers.h b/lib/Yield/Support/GraphLayout/SugiyamaStyle/Helpers.h index 3c30cb94c..541e6f38e 100644 --- a/lib/Yield/Support/GraphLayout/SugiyamaStyle/Helpers.h +++ b/lib/Yield/Support/GraphLayout/SugiyamaStyle/Helpers.h @@ -18,8 +18,8 @@ using ExternalGraph = yield::Graph; using ExternalNode = ExternalGraph::Node; using ExternalLabel = ExternalNode::Edge; -using Point = yield::Graph::Point; -using Size = yield::Graph::Size; +using Point = yield::layout::Point; +using Size = yield::layout::Size; using Index = size_t; using Rank = size_t;