void print_node (tree node)
{
if (node == NULL_TREE) {
return;
}
switch (TREE_CODE (node)) {
case IDENTIFIER_NODE: printf("%s", IDENTIFIER_POINTER (node)); break;
case CONST_DECL: printf("%s", IDENTIFIER_POINTER (DECL_NAME (node))); break;
case VAR_DECL: printf("%s", IDENTIFIER_POINTER (DECL_NAME (node))); break;
case INTEGER_CST: printf("%d", TREE_INT_CST_LOW (node)); break;
case SSA_NAME: {
if (SSA_NAME_IDENTIFIER (node)) {
print_node (SSA_NAME_IDENTIFIER (node));
}
printf("_%d", SSA_NAME_VERSION (node));
break;
}
case ARRAY_REF: {
print_node (TREE_OPERAND (node, 0));
printf("[");
print_node (TREE_OPERAND (node, 1));
printf("]");
break;
}
case MEM_REF: {
printf("*");
printPart (TREE_OPERAND (node, 0));
break;
}
case ADDR_EXPR: {
printf("&");
printPart ( TREE_OPERAND(node, 0));
break;
}
}
}
const char* get_operation_str (enum tree_code code)
{
switch (code) {
case TRUTH_OR_EXPR:
case TRUTH_ORIF_EXPR: return "||";
case TRUTH_AND_EXPR:
case TRUTH_ANDIF_EXPR: return "&&";
case LT_EXPR: return "<";
case GT_EXPR: return ">";
case LE_EXPR: return "<=";
case GE_EXPR: return ">=";
case EQ_EXPR: return "==";
case NE_EXPR: return "!=";
case PLUS_EXPR: return "+";
case MINUS_EXPR: return "-";
case MULT_EXPR: return "*";
case DIV_EXPR: return "/";
default: return " ";
}
}
void print_statement (gimple stmt)
{
switch (gimple_code(stmt))
{
case GIMPLE_COND: {
printf(" GIMPLE_COND:\n\t");
printf("if (");
print_node (gimple_assign_lhs (stmt));
printf(" %s ", op_symbol_code (gimple_cond_code (stmt)));
print_node (gimple_assign_rhs1 (stmt));
printf(") \n");
break;
}
case GIMPLE_ASSIGN: {
printf(" ASSIGN: %d args\n\t", gimple_num_ops (stmt));
switch (gimple_num_ops (stmt))
{
case 2: {
print_node(gimple_assign_lhs (stmt));
printf(" = ");
print_node(gimple_assign_rhs1 (stmt));
break;
}
case 3: {
print_node (gimple_assign_lhs (stmt));
printf(" = ");
print_node (gimple_assign_rhs1 (stmt));
printf("%s ", get_operation_str (gimple_assign_rhs_code (stmt)));
print_node (gimple_assign_rhs2 (stmt));
break;
}
}
break;
}
case GIMPLE_CALL: {
printf(" GIMPLE_CALL:\n\t");
tree lhs = gimple_call_lhs (stmt);
if (lhs) {
print_node (lhs);
printf(" = ");
}
print_node (DECL_NAME (TREE_OPERAND(gimple_call_fn (stmt), 0)));
printf("(");
for (int i = 0; i < gimple_call_num_args (stmt); i++)
{
print_node (gimple_call_arg (stmt, i));
if (i < gimple_call_num_args (stmt) - 1) {
printf(", ");
}
}
printf(")\n");
break;
}
case GIMPLE_RETURN: {
printf(" GIMPLE_RETURN\n\t");
print_node (gimple_return_retval (stmt));
printf("\n");
break;
}
}
}
void print_tree ()
{
printf("Function: %s\n", function_name(cfun));
basic_block bb;
FOR_EACH_BB_FN (bb, cfun)
{
printf("Base block:\n");
gimple_stmt_iterator stmt_iter;
for (stmt_iter = gsi_start_bb (bb); !gsi_end_p (stmt_iter); gsi_next (&stmt_iter))
{
printf("Statement:\n");
print_statement ( gsi_stmt (stmt_iter) )
}
}
}