move rr_graph back to vpr because the reader and writer requires too much dependency on the core engine

This commit is contained in:
tangxifan 2020-01-31 15:42:44 -07:00
parent fb0bcd7a48
commit 9269d7106d
17 changed files with 234 additions and 756 deletions

View File

@ -5,7 +5,6 @@ add_subdirectory(EXTERNAL)
# Only add warn flags for VPR internal libraries.
#add_compile_options(${WARN_FLAGS})
add_subdirectory(libarchfpga)
add_subdirectory(librrgraph)
add_subdirectory(libvtrutil)
add_subdirectory(liblog)
add_subdirectory(libpugiutil)

View File

@ -1,35 +0,0 @@
cmake_minimum_required(VERSION 3.9)
project("librrgraph")
file(GLOB_RECURSE EXEC_SOURCE test/test_rr_graph.cpp)
file(GLOB_RECURSE LIB_SOURCES src/*.cpp)
file(GLOB_RECURSE LIB_HEADERS src/*.h)
files_to_dirs(LIB_HEADERS LIB_INCLUDE_DIRS)
#Remove test executable from library
list(REMOVE_ITEM LIB_SOURCES ${EXEC_SOURCE})
#Create the library
add_library(librrgraph STATIC
${LIB_HEADERS}
${LIB_SOURCES})
target_include_directories(librrgraph PUBLIC ${LIB_INCLUDE_DIRS})
set_target_properties(librrgraph PROPERTIES PREFIX "") #Avoid extra 'lib' prefix
#Specify link-time dependancies
target_link_libraries(librrgraph
libarchfpga
libvtrutil)
#Create the test executable
add_executable(test_rr_graph ${EXEC_SOURCE})
target_link_libraries(test_rr_graph librrgraph)
#Supress IPO link warnings if IPO is enabled
#get_target_property(READ_ARCH_USES_IPO read_arch_openfpga INTERPROCEDURAL_OPTIMIZATION)
#if (READ_ARCH_USES_IPO)
# set_target_properties(read_arch_openfpga PROPERTIES LINK_FLAGS ${IPO_LINK_WARN_SUPRESS_FLAGS})
#endif()
#install(TARGETS libarchopenfpga read_arch_openfpga DESTINATION bin)

View File

@ -1,8 +0,0 @@
#include "vtr_geometry.h"
#include "rr_graph_obj.h"
int main(int argc, char** argv) {
RRGraph rr_graph_obj;
return 0;
}

View File

@ -58,7 +58,6 @@ set_target_properties(libvpr8 PROPERTIES PREFIX "") #Avoid extra 'lib' prefix
target_link_libraries(libvpr8
libvtrutil
libarchfpga
librrgraph
libsdcparse
libblifparse
libtatum

View File

@ -0,0 +1,222 @@
/*********************************************************************
* This file defines the writing rr graph function in XML format.
* The rr graph is separated into channels, nodes, switches,
* grids, edges, block types, and segments. Each tag has several
* children tags such as timing, location, or some general
* details. Each tag has attributes to describe them
********************************************************************/
#include <fstream>
#include <iostream>
#include <string.h>
#include <iomanip>
#include <limits>
#include "vpr_error.h"
#include "globals.h"
#include "read_xml_arch_file.h"
#include "vtr_version.h"
#include "rr_graph_obj.h"
#include "write_xml_rr_graph_obj.h"
using namespace std;
/* All values are printed with this precision value. The higher the
* value, the more accurate the read in rr graph is. Using numeric_limits
* max_digits10 guarentees that no values change during a sequence of
* float -> string -> float conversions */
constexpr int FLOAT_PRECISION = std::numeric_limits<float>::max_digits10;
/*********************** External Subroutines to this module *******************/
void add_metadata_to_xml(fstream &fp, const char *tab_prefix, const t_metadata_dict & meta);
void write_rr_channel(fstream &fp);
void write_rr_grid(fstream &fp);
void write_rr_block_types(fstream &fp);
/*********************** Subroutines local to this module *******************/
void write_rr_graph_node(fstream &fp, const RRGraph& rr_graph);
void write_rr_graph_switches(fstream &fp, const RRGraph& rr_graph);
void write_rr_graph_edges(fstream &fp, const RRGraph& rr_graph);
void write_rr_graph_segments(fstream &fp, const RRGraph& rr_graph);
/************************ Subroutine definitions ****************************/
/* This function is used to write the rr_graph into xml format into a a file with name: file_name */
void write_xml_rr_graph_obj(const char *file_name, const RRGraph& rr_graph) {
fstream fp;
fp.open(file_name, fstream::out | fstream::trunc);
/* Prints out general info for easy error checking*/
if (!fp.is_open() || !fp.good()) {
vpr_throw(VPR_ERROR_OTHER, __FILE__, __LINE__,
"couldn't open file \"%s\" for generating RR graph file\n", file_name);
}
cout << "Writing RR graph" << endl;
fp << "<rr_graph tool_name=\"vpr\" tool_version=\"" << vtr::VERSION <<
"\" tool_comment=\"Generated from arch file "
<< get_arch_file_name() << "\">" << endl;
/* Write out each individual component
* Use existing write_rr_* functions as much as possible
* 1. For those using external data structures outside RRGraph,
* leave as it is.
* 2. For those using RRGraph internal data,
* write new functions
*/
write_rr_channel(fp);
write_rr_graph_switches(fp, rr_graph);
write_rr_graph_segments(fp, rr_graph);
write_rr_block_types(fp);
write_rr_grid(fp);
write_rr_graph_node(fp, rr_graph);
write_rr_graph_edges(fp, rr_graph);
fp << "</rr_graph>";
fp.close();
cout << "Finished generating RR graph file named " << file_name << endl << endl;
}
/* All relevant rr node info is written out to the graph.
* This includes location, timing, and segment info
*/
void write_rr_graph_node(fstream &fp, const RRGraph& rr_graph) {
/* TODO: we should make it function full independent from device_ctx !!! */
auto& device_ctx = g_vpr_ctx.device();
fp << "\t<rr_nodes>" << endl;
for (auto node : rr_graph.nodes()) {
fp << "\t\t<node";
fp << " id=\"" << rr_graph.node_index(node);
fp << "\" type=\"" << rr_node_typename[rr_graph.node_type(node)];
if (CHANX == rr_graph.node_type(node) || CHANY == rr_graph.node_type(node)) {
fp << "\" direction=\"" << DIRECTION_STRING[rr_graph.node_direction(node)];
}
fp << "\" capacity=\"" << rr_graph.node_capacity(node);
fp << "\">" << endl;
fp << "\t\t\t<loc";
fp << " xlow=\"" << rr_graph.node_xlow(node);
fp << "\" ylow=\"" << rr_graph.node_ylow(node);
fp << "\" xhigh=\"" << rr_graph.node_xhigh(node);
fp << "\" yhigh=\"" << rr_graph.node_yhigh(node);
if (IPIN == rr_graph.node_type(node) || OPIN == rr_graph.node_type(node)) {
fp << "\" side=\"" << SIDE_STRING[rr_graph.node_side(node)];
}
fp << "\" ptc=\"" << rr_graph.node_ptc_num(node) ;
fp << "\"/>" << endl;
fp << "\t\t\t<timing R=\"" << setprecision(FLOAT_PRECISION) << rr_graph.node_R(node)
<< "\" C=\"" << setprecision(FLOAT_PRECISION) << rr_graph.node_C(node) << "\"/>" << endl;
if (RRSegmentId::INVALID() != rr_graph.node_segment(node)) {
fp << "\t\t\t<segment segment_id=\"" << size_t(rr_graph.node_segment(node)) << "\"/>" << endl;
}
const auto iter = device_ctx.rr_node_metadata.find(rr_graph.node_index(node));
if(iter != device_ctx.rr_node_metadata.end()) {
const t_metadata_dict & meta = iter->second;
add_metadata_to_xml(fp, "\t\t\t", meta);
}
fp << "\t\t</node>" << endl;
}
fp << "\t</rr_nodes>" << endl << endl;
return;
}
/* Segment information in the t_segment_inf data structure is written out.
* Information includes segment id, name, and optional timing parameters
*/
void write_rr_graph_segments(fstream &fp, const RRGraph& rr_graph) {
fp << "\t<segments>" << endl;
for (auto seg : rr_graph.segments()) {
fp << "\t\t<segment id=\"" << rr_graph.segment_index(seg) <<
"\" name=\"" << rr_graph.get_segment(seg).name << "\">" << endl;
fp << "\t\t\t<timing R_per_meter=\"" << setprecision(FLOAT_PRECISION) << rr_graph.get_segment(seg).Rmetal <<
"\" C_per_meter=\"" <<setprecision(FLOAT_PRECISION) << rr_graph.get_segment(seg).Cmetal << "\"/>" << endl;
fp << "\t\t</segment>" << endl;
}
fp << "\t</segments>" << endl << endl;
return;
}
/* Switch info is written out into xml format. This includes
* general, sizing, and optional timing information
*/
void write_rr_graph_switches(fstream &fp, const RRGraph& rr_graph) {
fp << "\t<switches>" << endl;
for (auto rr_switch : rr_graph.switches()) {
fp << "\t\t<switch id=\"" << rr_graph.switch_index(rr_switch);
t_rr_switch_inf cur_switch = rr_graph.get_switch(rr_switch);
if (cur_switch.type() == SwitchType::TRISTATE) {
fp << "\" type=\"tristate";
} else if (cur_switch.type() == SwitchType::MUX) {
fp << "\" type=\"mux";
} else if (cur_switch.type() == SwitchType::PASS_GATE) {
fp << "\" type=\"pass_gate";
} else if (cur_switch.type() == SwitchType::SHORT) {
fp << "\" type=\"short";
} else if (cur_switch.type() == SwitchType::BUFFER) {
fp << "\" type=\"buffer";
} else {
VPR_THROW(VPR_ERROR_ROUTE, "Invalid switch type %d\n", cur_switch.type());
}
fp << "\"";
if (cur_switch.name) {
fp << " name=\"" << cur_switch.name << "\"";
}
fp << ">" << endl;
fp << "\t\t\t<timing R=\"" << setprecision(FLOAT_PRECISION) << cur_switch.R <<
"\" Cin=\"" << setprecision(FLOAT_PRECISION) << cur_switch.Cin <<
"\" Cout=\"" << setprecision(FLOAT_PRECISION) << cur_switch.Cout <<
"\" Tdel=\"" << setprecision(FLOAT_PRECISION) << cur_switch.Tdel << "\"/>" << endl;
fp << "\t\t\t<sizing mux_trans_size=\"" << setprecision(FLOAT_PRECISION) << cur_switch.mux_trans_size <<
"\" buf_size=\"" << setprecision(FLOAT_PRECISION) << cur_switch.buf_size << "\"/>" << endl;
fp << "\t\t</switch>" << endl;
}
fp << "\t</switches>" << endl << endl;
return;
}
/* Edges connecting to each rr node is printed out. The two nodes
* it connects to are also printed
*/
void write_rr_graph_edges(fstream &fp, const RRGraph& rr_graph) {
auto& device_ctx = g_vpr_ctx.device();
fp << "\t<rr_edges>" << endl;
for (auto node : rr_graph.nodes()) {
for (auto edge: rr_graph.node_out_edges(node)) {
fp << "\t\t<edge src_node=\"" << rr_graph.node_index(node) <<
"\" sink_node=\"" << rr_graph.node_index(rr_graph.edge_sink_node(edge)) <<
"\" switch_id=\"" << rr_graph.switch_index(rr_graph.edge_switch(edge)) << "\"";
bool wrote_edge_metadata = false;
const auto iter = device_ctx.rr_edge_metadata.find( std::make_tuple(rr_graph.node_index(node),
rr_graph.node_index(rr_graph.edge_sink_node(edge)),
rr_graph.switch_index(rr_graph.edge_switch(edge))) );
if(iter != device_ctx.rr_edge_metadata.end()) {
fp << ">" << endl;
const t_metadata_dict & meta = iter->second;
add_metadata_to_xml(fp, "\t\t\t", meta);
wrote_edge_metadata = true;
}
if(wrote_edge_metadata == false) {
fp << "/>" << endl;
} else {
fp << "\t\t</edge>" << endl;
}
}
}
fp << "\t</rr_edges>" << endl << endl;
}

View File

@ -0,0 +1,12 @@
/*********************************************************************
* This function writes the RR_graph generated by VPR into a file in XML format
* Information included in the file includes rr nodes, rr switches,
* the grid, block info, node indices
********************************************************************/
#ifndef WRITE_XML_RR_GRAPH_OBJ_H
#define WRITE_XML_RR_GRAPH_OBJ_H
void write_xml_rr_graph_obj(const char *file_name, const RRGraph& rr_graph);
#endif

View File

@ -1,711 +0,0 @@
#
# Valgrind suppression file for EZGL
#
#pango
{
libpango
Memcheck:Leak
...
obj:/usr/lib*/libpango*
}
#GTK
{
g_type_register
Memcheck:Leak
fun:*alloc
...
fun:g_type_register_*
...
fun:_dl_init
...
}
{
g_quark_from_static_string
Memcheck:Leak
fun:*alloc
...
fun:g_quark_from_static_string
...
fun:_dl_init
...
}
{
g_main_thread
Memcheck:Leak
fun:*alloc
...
fun:g_main*
...
fun:start_thread
fun:clone
}
{
g_closure
Memcheck:Leak
match-leak-kinds:possible
fun:*alloc
...
fun:g_cclosure_new
fun:g_signal_connect_data
...
}
#
{
g_object
Memcheck:Leak
match-leak-kinds:possible
...
fun:g_object_new
...
}
{
g_type_register_static
Memcheck:Leak
match-leak-kinds:possible
...
fun:g_type_register_static
...
}
{
g_signal_connect_closure
Memcheck:Leak
match-leak-kinds:possible
...
fun:g_signal_connect_closure
fun:gtk_*group*
...
}
{
gtk_module_init
Memcheck:Leak
fun:*alloc
...
fun:gtk_module_init
...
}
{
g_closure_invoke
Memcheck:Leak
fun:*alloc
...
fun:g_closure_invoke
...
}
{
gtk_style_context_set_state
Memcheck:Leak
fun:*alloc
...
fun:gtk_style_context_set_state
...
}
#
{
call_init
Memcheck:Leak
fun:*alloc
...
fun:call_init
fun:_dl_init
...
}
{
XML_ParseBuffer
Memcheck:Leak
fun:*alloc
...
fun:XML_ParseBuffer
...
}
{
FcConfigParseAndLoad
Memcheck:Leak
fun:*alloc
...
fun:FcConfigParseAndLoad
...
}
#
{
g_objectv
Memcheck:Leak
...
fun:g_object_newv
...
}
{
g_type_add_interface_static
Memcheck:Leak
match-leak-kinds:possible
...
fun:g_type_add_interface_static
...
}
{
gtk_container_get_children
Memcheck:Leak
fun:*alloc
...
fun:gtk_container_get_children
...
}
{
cairo_select_font_face
Memcheck:Leak
fun:*alloc
...
fun:cairo_select_font_face
...
}
{
libfontconfig
Memcheck:Leak
fun:*alloc
...
obj:*libfontconfig.so.*
...
}
{
X11_XGetDefault
Memcheck:Leak
fun:realloc
obj:*libX11.so.6.3.0
obj:*libX11.so.6.3.0
obj:*libX11.so.6.3.0
fun:_XlcCreateLC
fun:_XlcDefaultLoader
fun:_XOpenLC
fun:_XrmInitParseInfo
obj:*libX11.so.6.3.0
fun:XrmGetStringDatabase
obj:*libX11.so.6.3.0
fun:XGetDefault
}
{
XInternAtom_via_event_loop
Memcheck:Leak
fun:*alloc
fun:_XEnq
obj:*libX11.so.6.3.0
fun:_XReply
fun:XInternAtom
...
}
{
cairo_deep_*alloc
Memcheck:Leak
fun:*alloc
obj:*libcairo.*
...
}
#openmp
{
GOMP_parallel
Memcheck:Leak
fun:*alloc
fun:allocate_dtv
fun:_dl_allocate_tls
fun:allocate_stack
fun:pthread_create@@GLIBC_2.2.5
...
}
#GTK engines
{
engines
Memcheck:Leak
fun:*alloc
...
obj:/usr/lib*/gtk*/*/engines*
...
obj:/usr/lib*/libgtk*
}
#nvidia
{
libGL
Memcheck:Leak
...
obj:/usr/lib*/libGL.so*
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
fun:*alloc
...
fun:g_socket_create_source
...
fun:g_main_context_dispatch
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
fun:*alloc
...
fun:g_type_class_ref
...
fun:gtk_init_check
fun:gtk_init
obj:*libgtk-3*
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
fun:*alloc
...
fun:g_markup_parse_context_parse
obj:*libgtk-3*
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
fun:*alloc
...
fun:g_socket_new
obj:*libgio-2*
fun:g_socket_client_connect
obj:*libgio-2*
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
fun:*alloc
...
fun:atk_add_focus_tracker
obj:*libgtk-3*
...
fun:gtk_parse_args
fun:gtk_init_check
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
fun:m*alloc
...
fun:g_bus_get_sync
...
fun:g_application_register
obj:*libgio-2*
fun:g_application_run
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
fun:*alloc
...
obj:*libgtk-3*
fun:g_closure_invoke
...
fun:g_signal_emit_valist
fun:g_signal_emit
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
fun:*alloc
...
fun:g_simple_async_result_complete
...
fun:g_main_context_dispatch
...
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
fun:*alloc
...
fun:g_type_class_ref
...
fun:atk_add_focus_tracker
obj:*libgtk-3*
...
fun:g_option_context_parse
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
fun:*alloc
...
fun:g_type_class_ref
obj:*libgtk-3*
fun:atk_add_focus_tracker
obj:*libgtk-3*
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
fun:*alloc
...
fun:g_type_class_ref
obj:*libgtk-3*
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
fun:*alloc
...
fun:g_dbus_proxy_new_sync
obj:*libgtk-3*
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
fun:*alloc
...
fun:g_signal_new
...
obj:*libgobject-2*
fun:g_type_class_ref
fun:g_object_new_valist
fun:g_initable_new_valist
fun:g_initable_new
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
fun:*alloc
...
fun:g_signal_new
obj:*libgtk-3*
fun:g_type_class_ref
obj:*libgtk-3*
...
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
fun:*alloc
...
fun:g_signal_new
obj:*libgtk-3*
...
fun:g_type_class_ref
obj:*libgtk-3*
...
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
fun:*alloc
...
fun:g_type_class_ref
obj:*libgtk-3*
fun:atk_add_focus_tracker
obj:*libgtk-3*
...
fun:g_option_context_parse
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
fun:*alloc
...
fun:g_signal_new_class_handler
obj:*libgtk-3*
...
fun:g_type_class_ref
obj:*libgtk-3*
...
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
fun:*alloc
...
fun:g_signal_connect_data
obj:*libgtk-3*
...
fun:gtk_widget_show
obj:*libgtk-3*
...
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
fun:*alloc
...
fun:g_type_class_ref
fun:g_object_new_valist
fun:g_initable_new_valist
fun:g_initable_new
fun:gvfs_dbus_mount_tracker_proxy_new_for_bus_sync
...
fun:g_type_create_instance
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
fun:*alloc
fun:g_*alloc
...
fun:g_type_class_ref
obj:*libgtk-3*
...
fun:g_markup_parse_context_parse
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
fun:*alloc
...
fun:g_type_class_ref
obj:*libgtk-3*
...
fun:g_option_context_parse
fun:gtk_parse_args
fun:gtk_init_check
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
fun:*alloc
...
fun:g_type_class_ref
fun:atk_bridge_adaptor_init
obj:*libgtk-3*
...
fun:g_option_context_parse
fun:gtk_parse_args
fun:gtk_init_check
fun:gtk_init
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
fun:*alloc
...
fun:g_signal_new
...
fun:g_type_class_ref
obj:*libgtk-3*
fun:atk_add_focus_tracker
obj:*libgtk-3*
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
fun:*alloc
...
fun:g_signal_new
...
fun:g_type_class_ref
obj:*libgtk-3*
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
fun:*alloc
...
fun:g_signal_new
...
fun:g_initable_new
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
fun:*alloc
...
fun:g_signal_new
obj:*libgtk-3*
fun:g_type_class_ref
obj:*libgtk-3*
...
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
fun:*alloc
...
fun:g_signal_new
...
fun:g_type_class_ref
obj:*libgtk-3*
...
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
fun:*alloc
...
fun:g_signal_new
...
fun:g_type_class_ref
obj:*libgtk-3*
...
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
fun:*alloc
...
fun:g_signal_new
...
fun:g_type_class_ref
obj:*libgtk-3*
...
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
fun:*alloc
...
fun:g_signal_new
...
fun:g_type_class_ref
obj:*libgio-2.0.so.0.4002.0
...
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
fun:*alloc
...
fun:g_signal_new_class_handler
...
fun:g_type_class_ref
obj:*libgtk-3*
...
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
fun:*alloc
...
fun:g_signal_connect_data
...
fun:gtk_widget_show
obj:*libgtk-3*
...
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
fun:*alloc
...
fun:g_initable_new
...
fun:g_type_create_instance
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
fun:*alloc
...
fun:g_type_class_ref
obj:*libgtk-3*
...
fun:g_markup_parse_context_parse
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
fun:malloc
...
fun:g_type_class_ref
obj:*libgtk-3*
...
fun:gtk_init_check
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
fun:malloc
...
fun:atk_bridge_adaptor_init
obj:*libgtk-3*
...
fun:gtk_init
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
fun:*alloc
...
fun:g_application_register
obj:*libgio-2*
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
fun:*alloc
...
fun:g_thread_new
obj:*libgio-2*
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
fun:*alloc
...
fun:g_thread_pool_push
...
fun:g_bus_get
fun:g_bus_watch_name
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
match-leak-kinds: possible
fun:*alloc
...
fun:g_param_spec_enum
...
fun:g_bus_get_sync
obj:*libgio-*
fun:g_application_register
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
match-leak-kinds: possible
fun:*alloc
fun:g_realloc
...
fun:gtk_button_set_image_position
fun:g_object_setv
...
obj:*libgtk-3*
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
match-leak-kinds: possible
fun:*alloc
...
fun:gtk_cell_renderer_render
...
obj:*libgtk-3*
}