69 const DesignFlowManagerConstRef _design_flow_manager)
81 switch(relationship_type)
85 if(
parameters->getOption<
bool>(OPT_parse_pragma))
87 relationships.insert(std::make_pair(EXTRACT_OMP_ATOMIC,
SAME_FUNCTION));
89 relationships.insert(std::make_pair(BB_FEEDBACK_EDGES_IDENTIFICATION,
SAME_FUNCTION));
90 relationships.insert(std::make_pair(LUT_TRANSFORMATION,
SAME_FUNCTION));
91 relationships.insert(std::make_pair(BASIC_BLOCKS_CFG_COMPUTATION,
SAME_FUNCTION));
100 if(!
parameters->getOption<
int>(OPT_gcc_openmp_simd))
102 relationships.insert(std::make_pair(BITVALUE_RANGE,
SAME_FUNCTION));
104 relationships.insert(std::make_pair(BUILD_VIRTUAL_PHI,
SAME_FUNCTION));
105 relationships.insert(std::make_pair(COND_EXPR_RESTRUCTURING,
SAME_FUNCTION));
106 relationships.insert(std::make_pair(VECTORIZE,
SAME_FUNCTION));
114 return relationships;
123 if(boost::num_vertices(*basic_block_graph) != 0)
126 for(boost::tie(basic_block, basic_block_end) = boost::vertices(*basic_block_graph);
127 basic_block != basic_block_end; basic_block++)
129 basic_block_graph->
GetBBNodeInfo(*basic_block)->statements_list.clear();
143 const auto root_functions =
AppM->CGetCallGraphManager()->GetRootFunctions();
152 bbgc->add_operation_to_bb(ogc->getIndex(
EXIT),
BB_EXIT);
160 for(boost::tie(v_iter, v_iter_end) = boost::vertices(*fbb); v_iter != v_iter_end; ++v_iter)
169 const auto block = bb_node_info->block;
174 std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> gimple_nop_schema;
179 auto gn = GetPointer<gimple_nop>(TM->
GetTreeNode(new_tree_node_id));
180 gn->bb_index =
block->number;
185 if(
block->CGetStmtList().size())
187 auto front =
block->CGetStmtList().front();
188 if(
GET_NODE(front)->get_kind() == gimple_label_K)
190 auto* le = GetPointer<gimple_label>(
GET_NODE(front));
195 else if(
block->CGetPhiList().empty())
204 else if(
block->CGetPhiList().size())
223 for(boost::tie(v_iter, v_iter_end) = boost::vertices(*fbb); v_iter != v_iter_end; ++v_iter)
230 const auto block = bb_node_info->block;
232 "-->Building operation of basic block BB" +
STR(
block->number));
233 bool skip_first_stmt =
false;
234 if(
block->CGetStmtList().size())
236 const auto front =
block->CGetStmtList().front();
237 if(
GET_NODE(front)->get_kind() == gimple_label_K)
241 "the name of the first vertice has to be the same of the label expression vertex");
249 skip_first_stmt =
true;
252 for(
const auto&
phi :
block->CGetPhiList())
266 "---List of operations size " +
STR(
block->CGetStmtList().size()));
267 auto s_end =
block->CGetStmtList().end();
268 auto s =
block->CGetStmtList().begin();
274 for(; s != s_end; s++)
288 if(
block->CGetStmtList().empty())
290 if(!
block->CGetPhiList().empty())
292 last_instruction =
block->CGetPhiList().back();
299 else if(
block->CGetStmtList().size() == 1 && skip_first_stmt)
301 if(
block->CGetPhiList().size())
303 last_instruction =
block->CGetPhiList().back();
307 last_instruction =
block->CGetStmtList().back();
312 last_instruction =
block->CGetStmtList().back();
314 if(last_instruction &&
GET_NODE(last_instruction)->get_kind() != gimple_switch_K)
318 else if(!last_instruction)
322 if(
block->list_of_succ.size() == 0 and root_functions.find(
function_id) != root_functions.end())
325 for(operation =
start_nodes.begin(); operation != operation_end; ++operation)
332 for(
const auto successor :
block->list_of_succ)
338 if(root_functions.find(
function_id) != root_functions.end())
341 for(operation =
start_nodes.begin(); operation != operation_end; ++operation)
349 if(successor ==
block->true_edge)
353 else if(successor ==
block->false_edge)
357 "First statement of successor BB" +
STR(successor) +
" not found");
360 else if(last_instruction && GetPointer<gimple_goto>(
GET_NODE(last_instruction)) &&
361 block->list_of_succ.size() > 1)
380 if(
parameters->getOption<
bool>(OPT_print_dot))
390 if(tn->
get_kind() == tree_reindex_K)
400 src = f_name +
"_" +
STR(ind);
406 case case_label_expr_K:
408 auto* cle = GetPointer<case_label_expr>(curr_tn);
417 case aggr_init_expr_K:
418 case identifier_node_K:
420 case statement_list_K:
422 case target_mem_ref_K:
423 case target_mem_ref461_K:
467 bool true_edge,
bool false_edge,
unsigned int nodeid)
469 const auto root_functions =
AppM->CGetCallGraphManager()->GetRootFunctions();
478 ogc->AddEdge(ogc->getIndex(Start_node), ogc->getIndex(next),
CFG_SELECTOR);
479 if(true_edge && false_edge)
482 ogc->add_edge_info(ogc->getIndex(Start_node), ogc->getIndex(next),
CFG_SELECTOR, nodeid);
484 if(true_edge && !false_edge)
486 ogc->add_edge_info(ogc->getIndex(Start_node), ogc->getIndex(next),
CFG_SELECTOR,
T_COND);
488 if(false_edge && !true_edge)
490 ogc->add_edge_info(ogc->getIndex(Start_node), ogc->getIndex(next),
CFG_SELECTOR,
F_COND);
496 const operations_graph_constructorRef ogc,
498 unsigned int bb_index)
503 "-->Building CFG of node " +
STR(ind) +
" of type " + curr_tn->get_kind_text());
504 switch(curr_tn->get_kind())
506 case gimple_return_K:
508 ogc->AddOperation(TM,
actual_name, curr_tn->get_kind_text(), bb_index, curr_tn->index);
512 case gimple_assign_K:
514 const auto me = GetPointerS<const gimple_assign>(curr_tn);
515 const auto op0_kind =
GET_NODE(me->op0)->get_kind();
516 const auto op1_kind =
GET_NODE(me->op1)->get_kind();
526 op1_kind == constructor_K)))
529 (((op1_kind == constructor_K || (op1_kind == var_decl_K && GetPointerS<const var_decl>(me->op1)->init) ||
530 op1_kind == string_cst_K)) &&
531 (GetPointer<const decl_node>(me->op0) || op0_kind == ssa_name_K)))
533 function_behavior->GetBehavioralHelper()->add_initialization(me->op0->index, me->op1->index);
538 if(me->init_assignment || me->clobber)
543 else if(op1_kind == float_expr_K)
546 const auto fe = GetPointerS<const float_expr>(
GET_CONST_NODE(me->op1));
553 else if(size_from > 32 && size_from < 64)
558 bb_index, me->index);
561 else if(op1_kind == fix_trunc_expr_K)
564 const auto fte = GetPointerS<const fix_trunc_expr>(
GET_CONST_NODE(me->op1));
572 else if(size_dest > 32 && size_dest < 64)
579 bb_index, me->index);
585 const auto co = GetPointerS<const constructor>(
GET_CONST_NODE(me->op1));
587 const auto n_byte = size_obj / 8;
590 bb_index, me->index);
593 else if(op1_kind == complex_expr_K)
598 else if(!store_candidate && (op0_kind == realpart_expr_K || op0_kind == imagpart_expr_K))
603 else if(op0_type && op1_type &&
GET_CONST_NODE(me->op1)->get_kind() != insertvalue_expr_K &&
606 GET_CONST_NODE(op1_type)->get_kind() == record_type_K && op1_kind != view_convert_expr_K) ||
608 GET_CONST_NODE(op1_type)->get_kind() == union_type_K && op1_kind != view_convert_expr_K) ||
611 (fun_mem_data.count(
GET_INDEX_NODE(me->op0)) && load_candidate) ||
612 (store_candidate && fun_mem_data.count(
GET_INDEX_NODE(me->op1)))))
614 if(op1_kind == constructor_K && GetPointer<const constructor>(
GET_CONST_NODE(me->op1)) &&
615 GetPointer<const constructor>(
GET_CONST_NODE(me->op1))->list_of_idx_valu.empty())
628 else if(store_candidate || fun_mem_data.count(
GET_INDEX_NODE(me->op0)))
631 ogc->AddOperation(TM,
actual_name,
"STORE", bb_index, me->index);
634 else if(load_candidate || fun_mem_data.count(
GET_INDEX_NODE(me->op1)))
637 ogc->AddOperation(TM,
actual_name,
"LOAD", bb_index, me->index);
652 case gimple_pragma_K:
655 ogc->AddOperation(TM,
actual_name, curr_tn->get_kind_text(), bb_index, curr_tn->index);
660 case aggr_init_expr_K:
662 const auto ce = GetPointerS<const call_expr>(curr_tn);
667 const auto ue = GetPointerS<const unary_expr>(
GET_CONST_NODE(ce->fn));
684 ogc->AddOperation(TM,
actual_name, fun_name, bb_index, 0);
686 if(fd->writing_memory || fd->reading_memory)
688 type_external = type_external |
TYPE_RW;
692 if(fun_name ==
"exit" || fun_name ==
"abort" || fun_name ==
"__builtin_exit" ||
693 fun_name ==
"__builtin_abort")
697 #if HAVE_FROM_PRAGMA_BUILT 710 ogc->AddOperation(TM,
actual_name, curr_tn->get_kind_text(), bb_index, 0);
716 const auto ce = GetPointerS<const gimple_call>(curr_tn);
721 const auto ue = GetPointerS<const unary_expr>(
GET_CONST_NODE(ce->fn));
745 ogc->AddOperation(TM,
actual_name, fun_name, bb_index, ce->index);
747 if(fd->writing_memory || fd->reading_memory)
749 type_external = type_external |
TYPE_RW;
752 if(fun_name ==
"exit" || fun_name ==
"abort" || fun_name ==
"__builtin_exit" ||
753 fun_name ==
"__builtin_abort")
757 #if HAVE_FROM_PRAGMA_BUILT 771 ogc->AddOperation(TM,
actual_name, curr_tn->get_kind_text(), bb_index, ce->index);
777 ogc->AddOperation(TM,
actual_name, curr_tn->get_kind_text(), bb_index, curr_tn->index);
783 ogc->AddOperation(TM,
actual_name, curr_tn->get_kind_text(), bb_index, curr_tn->index);
784 const auto le = GetPointerS<const gimple_label>(curr_tn);
785 THROW_ASSERT(le->op,
"expected a gimple_label operand");
786 const auto ld = GetPointerS<const label_decl>(
GET_CONST_NODE(le->op));
787 if(ld->artificial_flag)
799 const auto gc = GetPointerS<const gimple_cond>(curr_tn);
805 case gimple_multi_way_if_K:
813 const auto we = GetPointerS<const gimple_while>(curr_tn);
825 case gimple_switch_K:
827 const auto se = GetPointerS<const gimple_switch>(curr_tn);
841 std::string(
"op2 in gimple_switch not yet supported (") +
STR(ind) + std::string(
")"));
843 if(case_label_exprs->
get_kind() == tree_vec_K)
845 const auto tv = GetPointerS<const tree_vec>(case_label_exprs);
846 for(
const auto& i : tv->list_of_op)
852 const auto cl = GetPointerS<const case_label_expr>(
GET_CONST_NODE(i));
870 THROW_ERROR(std::string(
"expected tree_vec in op1 in gimple_switch (") +
STR(ind) + std::string(
")"));
876 const auto ue = GetPointerS<const unary_expr>(curr_tn);
878 ogc->AddOperation(TM,
actual_name, curr_tn->get_kind_text(), bb_index, 0);
884 const auto be = GetPointerS<const binary_expr>(curr_tn);
887 ogc->AddOperation(TM,
actual_name, curr_tn->get_kind_text(), bb_index, 0);
893 const auto te = GetPointerS<const ternary_expr>(curr_tn);
903 ogc->AddOperation(TM,
actual_name, curr_tn->get_kind_text(), bb_index, 0);
909 const auto qe = GetPointerS<const quaternary_expr>(curr_tn);
923 ogc->AddOperation(TM,
actual_name, curr_tn->get_kind_text(), bb_index, 0);
929 const auto le = GetPointerS<const lut_expr>(curr_tn);
960 ogc->AddOperation(TM,
actual_name, curr_tn->get_kind_text(), bb_index, 0);
972 case target_mem_ref_K:
973 case target_mem_ref461_K:
980 const auto ae = GetPointerS<const gimple_asm>(curr_tn);
981 if(!ae->volatile_flag && (ae->in && ae->out))
989 ogc->AddOperation(TM,
actual_name, curr_tn->get_kind_text(), bb_index, curr_tn->index);
994 const auto phi = GetPointerS<const gimple_phi>(curr_tn);
995 ogc->AddOperation(TM,
actual_name, curr_tn->get_kind_text(), bb_index, curr_tn->index);
1002 ogc->AddOperation(TM,
actual_name, curr_tn->get_kind_text(), bb_index, curr_tn->index);
1008 case case_label_expr_K:
1010 case gimple_predict_K:
1012 case identifier_node_K:
1013 case statement_list_K:
#define GET_NODE(t)
Macro used to hide implementation details when accessing a tree_node from another tree_node...
static bool IsStore(const tree_nodeConstRef &tn, const CustomOrderedSet< unsigned int > &fun_mem_data)
Return true if the tree node is a gimple_assign writing something which will be allocated in memory...
#define TYPE_SWITCH
constant identifying the node type of a SWITCH operation.
#define TYPE_NOP
constant string identifying a type for a no operation.
#define DEBUG_LEVEL_VERY_PEDANTIC
extremely verbose debugging print is performed.
static bool is_a_nop_function_decl(const function_decl *fd)
#define INDENT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
#define MEMCPY
constant string identifying the operation performed when two objects are memcopied.
Basic block control flow graph.
File containing functions and utilities to support the printing of debug messagges.
#define PRINT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
DesignFlowStep_Status InternalExec() override
Computes the operations CFG graph data structure.
#define FLOAT_EXPR
constant string identifying integer to float conversions
std::string ToString() const
Print this node as string in gimple format.
#define TYPE_PREDICATED
Constant identifying a predicated operation.
#define CASE_BINARY_EXPRESSION
This macro collects all case labels for binary_expr objects.
#define TYPE_MULTIIF
constant identifying the a multi-way if
#define TYPE_VPHI
constant string identifying an operation node of type virtual phi-nodes
#define GET_CLASS(obj)
Macro returning the actual type of an object.
std::string get_function_name() const
Return the name of the function.
#define BB_EXIT
constant identifying the basic block node of type exit
#define TYPE_IF
constant identifying the node type of an IF operation.
Definition of the class representing a generic C application.
static bool IsArrayEquivType(const tree_nodeConstRef &type)
Return true if treenode is an array or it is equivalent to an array (record recursively having a sing...
#define CASE_DECL_NODES
NOTE that cast_expr is a unary expression but it could not be included in the CASE_UNARY_EXPRESSION b...
RelationshipType
The relationship type.
struct definition of the function_decl tree node.
Source must be executed to satisfy target.
const BBGraphInfoConstRef CGetBBGraphInfo() const
Returns the property associated with the graph.
static std::string GetString(const enum kind k)
Given a kind, return the corresponding string.
~operations_cfg_computation() override
Destructor.
Class specification of the graph structures.
Analysis step creating the control flow graph for the operations.
#define READ_COND
constant string identifying the operation performed by a READ_COND.
std::map< unsigned int, std::string > label_decl_map
relation between label declaration and first statement id
A simple interface to token object of the raw files.
void connect_start_nodes(const operations_graph_constructorRef ogc, const std::string &next, bool true_edge=false, bool false_edge=false, unsigned int nodeid=0)
Connect start_node with the next node.
static const unsigned int EXIT_BLOCK_ID
constant identifying the exit basic block
void build_operation_recursive(const tree_managerRef TM, const operations_graph_constructorRef ogc, const tree_nodeRef tn, const std::string &f_name, unsigned int bb_index)
Builds recursively the operation for a given tree node.
#define GET_INDEX_NODE(t)
Macro used to hide implementation details when accessing a tree_node from another tree_node...
static std::string print_function_name(const tree_managerConstRef &TM, const function_decl *fd)
Return the name of the function in a string.
#define TYPE_INIT
Constant string identifying an operation that is a variable initialization.
This class provides methods to build a basic blocks graph.
#define TYPE_FIRST_OP
A vertex of type FIRST_OP if it is the first operation of the application.
Data structure describing a basic block at tree level.
unsigned int bb_version
The version of the basic block intermediate representation on which this step has been applied...
void clean_start_nodes()
Clean the list of start nodes.
#define VECT_CONCATENATION
constant string identifying the operation performed when a vector concatenation is considered...
#define TOK(token)
Macro used to convert a token symbol into a treeVocabularyTokenTypes.
#define TYPE_LOAD
Constant string identifying a memory load operation.
#define TYPE_PHI
constant string identifying an operation node of type PHI
virtual enum kind get_kind() const =0
Virtual function returning the type of the actual class.
#define STR(s)
Macro which performs a lexical_cast to a string.
Auxiliary methods for manipulating string.
static bool IsUnsignedIntegerType(const tree_nodeConstRef &type)
Return true if the treenode is of unsigned integer type.
#define MEMSET
constant string identifying the operation performed when two objects are memsetted.
const tree_nodeRef get_tree_node_const(unsigned int i) const
Return the reference to the i-th tree_node Constant version of get_tree_node.
#define TYPE_LABEL
A vertex is of type TYPE_LABEL when it is a target of a goto expression.
#define TYPE_EXIT
constant identifying the node type of an exit node.
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached
virtual std::string get_kind_text() const =0
Virtual function returning the name of the actual class.
void Initialize() override
Initialize the step (i.e., like a constructor, but executed just before exec.
operations_cfg_computation(const ParameterConstRef _parameters, const application_managerRef AppM, unsigned int function_id, const DesignFlowManagerConstRef design_flow_manager)
Constructor.
static unsigned long long Size(const tree_nodeConstRef &tn)
Return the size of a tree object.
#define TYPE_GOTO
A vertex is of type TYPE_GOTO when it is associated with a goto expression.
This class specifies the characteristic of a particular operation working on a given functional unit...
#define ENTRY
Superclass include.
#define CASE_QUATERNARY_EXPRESSION
This macro collects all case labels for quaternary_expr objects.
#define CASE_UNARY_EXPRESSION
This macro collects all case labels for unary_expr objects.
unsigned int new_tree_node_id(const unsigned int ask=0)
Return a new node id in the intermediate representation.
#define TYPE_ATOMIC
Constant identifying an atomic operation.
#define TYPE_EXTERNAL
constant identifying the node type of a EXTERNAL operation (a function call)
#define default_COND
constant used to represent label "default" of a switch construct
void create_tree_node(const unsigned int node_id, enum kind tree_node_type, std::map< TreeVocabularyTokenTypes_TokenEnum, std::string > &tree_node_schema)
Factory method.
Classes to describe design flow graph.
Basic block control flow graph with feedback.
Target must be reexecuted.
tree_nodeRef GetTreeReindex(const unsigned int i)
Return a tree_reindex wrapping the i-th tree_node.
std::string actual_name
store the name of the current vertex
std::map< unsigned int, std::string > first_statement
relation between basic block and first statement id
#define TYPE_STORE
Constant string identifying a memory store operation.
#define BB_ENTRY
constant identifying the basic block node of type entry
static bool IsVectorType(const tree_nodeConstRef &type)
Return true if the treenode is a vector.
#define TYPE_FOR
constant string identifying the node type of an WHILE operation.
#define T_COND
constant used to represent control edges representing a true edge of a conditional statement...
#define TYPE_RW
Constant identifying if a TYPE_EXTERNAL write or read memory.
#define GET_CONST_NODE(t)
boost::graph_traits< graph >::vertex_iterator VertexIterator
vertex_iterator definition.
Classes specification of the tree_node data structures.
static std::string NormalizeTypename(const std::string &id)
Return normalized name of types and variables.
const ParameterConstRef parameters
Set of input parameters.
DesignFlowStep_Status
The status of a step.
#define DEBUG_LEVEL_NONE
no debugging print is performed.
#define THROW_ERROR(str_expr)
helper function used to throw an error in a standard way
#define FIX_TRUNC_EXPR
constant string identifying float to integer conversions
This struct specifies the block node.
bool empty_start_nodes() const
Return true if start_node is empty.
#define TYPE_ASSIGN
constant string identifying the node type of an ASSIGN operation.
#define CASE_TYPE_NODES
This macro collects all case labels for type objects.
This file collects some utility functions.
#define SWITCH_COND
constant string identifying the operation performed by a SWITCH_COND.
tree_nodeRef GetTreeNode(const unsigned int index) const
Return the index-th tree_node (modifiable version)
static tree_nodeRef find_obj_type_ref_function(const tree_nodeConstRef &tn)
Given the tree_node of an obj_type_ref return the tree_node of the called function.
BBNodeInfoRef GetBBNodeInfo(const vertex node)
Return the info associated with a basic block.
const unsigned int function_id
The index of the function to be analyzed.
#define TYPE_MEMCPY
A vertex is of type TYPE_MEMCPY when it is associated with a assignment between struct/union.
#define CASE_CST_NODES
This macro collects all case labels for cast nodes.
void insert_start_node(const std::string &start_node)
Insert a start node to the list of start nodes.
const application_managerRef AppM
The application manager.
Class specification of the tree_reindex support class.
#define ASSIGN
constant string identifying the operation performed by an assignment.
#define CASE_FAKE_NODES
This macro collects all case labels for fake or empty nodes.
Class specification of the basic_block structure.
#define NOP
constant string identifying a no operation.
const BBNodeInfoConstRef CGetBBNodeInfo(const vertex node) const
Return the info associated with a basic block.
Data structures used in operations graph.
Template borrowed from the ANTLR library by Terence Parr (http://www.jGuru.com - Software rights: htt...
static tree_nodeConstRef CGetType(const tree_nodeConstRef &node)
Return the treenode of the type of node.
#define THROW_ERROR_CODE(code, str_expr)
helper function used to throw an error with a code error
#define TYPE_WHILE
constant string identifying the node type of an WHILE operation.
Classes specification of the tree_node data structures not present in the gcc.
this class is used to manage the command-line or XML options.
#define CASE_CPP_NODES
This macro collects all case labels for cpp nodes.
std::string get_first_node(const tree_nodeRef &tn, const std::string &f_name) const
Return the name of the first node given a tree node.
refcount< tree_node > tree_nodeRef
RefCount type definition of the tree_node class structure.
#define F_COND
constant used to represent control edges representing a false edge of a conditional statement...
#define TYPE_ENTRY
constant identifying the node type of an entry node.
#define CASE_GIMPLE_NODES
This macro collects all cases labels for gimple nodes.
int debug_level
The debug level.
This class provides methods to build an operations graph.
#define TYPE_GENERIC
constant identifying the node type of a GENERIC operation.
#define TYPE_RET
constant string identifying an operation node of type return expr
#define GET_INDEX_CONST_NODE(t)
void init_start_nodes(const std::string &start_node)
Initialize the list of start nodes.
static bool IsPointerType(const tree_nodeConstRef &type)
Return true if treenode index is a pointer.
#define CFG_SELECTOR
Control flow graph edge selector.
#define TYPE_OPAQUE
constant identifying a node of opaque type
static bool IsLoad(const tree_nodeConstRef &tn, const CustomOrderedSet< unsigned int > &fun_mem_data)
Return true if the tree node is a gimple_assign reading something which will be allocated in memory...
const CustomUnorderedSet< std::pair< FrontendFlowStepType, FunctionRelationship > > ComputeFrontendRelationships(const DesignFlowStep::RelationshipType relationship_type) const override
Return the set of analyses in relationship with this design step.
#define MULTI_READ_COND
constant string identifying the operation performed by a MULTI_READ_COND.
#define CASE_TERNARY_EXPRESSION
This macro collects all case labels for ternary_expr objects.
Class specification of the manager of the tree structures extracted from the raw file.
std::list< std::string > start_nodes
store the name of the nodes at which the next node should be attached.
A brief description of the C++ Header File.
const FunctionBehaviorRef function_behavior
The function behavior of the function to be analyzed.
#define CASE_PRAGMA_NODES
This macro collects all case labels for pragma objects.
#define TYPE_LAST_OP
A vertex of type LAST_OP if it is the last operation of the application.
#define THROW_ASSERT(cond, str_expr)
helper function used to check an assert and if needed to throw an error in a standard way ...