gimple_seq gsi_split_seq_before (gimple_stmt_iterator *i) { gimple_seq_node cur, prev; gimple_seq old_seq, new_seq; cur = i->ptr; /* How can we possibly split after the end? */ gcc_assert (cur); prev = cur->prev; old_seq = i->seq; new_seq = gimple_seq_alloc (); i->seq = new_seq; /* Set the limits on NEW_SEQ. */ gimple_seq_set_first (new_seq, cur); gimple_seq_set_last (new_seq, gimple_seq_last (old_seq)); /* Cut OLD_SEQ before I. */ gimple_seq_set_last (old_seq, prev); cur->prev = NULL; if (prev) prev->next = NULL; else gimple_seq_set_first (old_seq, NULL); return new_seq; }
void add_phi_node_to_bb (gimple phi, basic_block bb) { gimple_stmt_iterator gsi; /* Add the new PHI node to the list of PHI nodes for block BB. */ if (phi_nodes (bb) == NULL) set_phi_nodes (bb, gimple_seq_alloc ()); gsi = gsi_last (phi_nodes (bb)); gsi_insert_after (&gsi, phi, GSI_NEW_STMT); /* Associate BB to the PHI node. */ gimple_set_bb (phi, bb); }
gimple_seq gsi_split_seq_after (gimple_stmt_iterator i) { gimple_seq_node cur, next; gimple_seq old_seq, new_seq; cur = i.ptr; /* How can we possibly split after the end, or before the beginning? */ gcc_assert (cur && cur->next); next = cur->next; old_seq = i.seq; new_seq = gimple_seq_alloc (); gimple_seq_set_first (new_seq, next); gimple_seq_set_last (new_seq, gimple_seq_last (old_seq)); gimple_seq_set_last (old_seq, cur); cur->next = NULL; next->prev = NULL; return new_seq; }
/* Synthesize a CALL_EXPR and a TRY_FINALLY_EXPR, for this chain of _DECLs if appropriate. Arrange to call the __mf_register function now, and the __mf_unregister function later for each. Return the gimple sequence after synthesis. */ gimple_seq mx_register_decls (tree decl, gimple_seq seq, gimple stmt, location_t location, bool func_args) { gimple_seq finally_stmts = NULL; gimple_stmt_iterator initially_stmts = gsi_start (seq); bool sframe_inserted = false; size_t front_rz_size, rear_rz_size; tree fsize, rsize, size; gimple uninit_fncall_front, uninit_fncall_rear, init_fncall_front, \ init_fncall_rear, init_assign_stmt; tree fncall_param_front, fncall_param_rear; int map_ret; while (decl != NULL_TREE) { if ((mf_decl_eligible_p (decl) || TREE_CODE(TREE_TYPE(decl)) == ARRAY_TYPE) /* Not already processed. */ && ! mf_marked_p (decl) /* Automatic variable. */ && ! DECL_EXTERNAL (decl) && ! TREE_STATIC (decl) && get_name(decl)) { DEBUGLOG("DEBUG Instrumenting %s is_complete_type %d\n", IDENTIFIER_POINTER(DECL_NAME(decl)), COMPLETE_TYPE_P(decl)); /* construct a tree corresponding to the type struct{ unsigned int rz_front[6U]; original variable unsigned int rz_rear[6U]; }; */ if (!sframe_inserted){ gimple ensure_fn_call = gimple_build_call (lbc_ensure_sframe_bitmap_fndecl, 0); gimple_set_location (ensure_fn_call, location); gsi_insert_before (&initially_stmts, ensure_fn_call, GSI_SAME_STMT); sframe_inserted = true; } // Calculate the zone sizes size_t element_size = 0, request_size = 0; if (COMPLETE_TYPE_P(decl)){ request_size = TREE_INT_CST_LOW(TYPE_SIZE_UNIT(TREE_TYPE(decl))); if (TREE_CODE(TREE_TYPE(decl)) == ARRAY_TYPE) element_size = TREE_INT_CST_LOW(TYPE_SIZE_UNIT(TREE_TYPE(TREE_TYPE(decl)))); else element_size = request_size; } calculate_zone_sizes(element_size, request_size, /*global*/ false, COMPLETE_TYPE_P(decl), &front_rz_size, &rear_rz_size); DEBUGLOG("DEBUG *SIZES* req_size %u, ele_size %u, fsize %u, rsize %u\n", request_size, element_size, front_rz_size, rear_rz_size); tree struct_type = create_struct_type(decl, front_rz_size, rear_rz_size); tree struct_var = create_struct_var(struct_type, decl, location); declare_vars(struct_var, stmt, 0); /* Inserting into hashtable */ PWord_t PV; JSLI(PV, decl_map, mf_varname_tree(decl)); gcc_assert(PV); *PV = (PWord_t) struct_var; fsize = convert (unsigned_type_node, size_int(front_rz_size)); gcc_assert (is_gimple_val (fsize)); tree rz_front = TYPE_FIELDS(struct_type); fncall_param_front = mf_mark (build1 (ADDR_EXPR, ptr_type_node, build3 (COMPONENT_REF, TREE_TYPE(rz_front), struct_var, rz_front, NULL_TREE))); uninit_fncall_front = gimple_build_call (lbc_uninit_front_rz_fndecl, 2, fncall_param_front, fsize); init_fncall_front = gimple_build_call (lbc_init_front_rz_fndecl, 2, fncall_param_front, fsize); gimple_set_location (init_fncall_front, location); gimple_set_location (uninit_fncall_front, location); // In complete types have only a front red zone if (COMPLETE_TYPE_P(decl)){ rsize = convert (unsigned_type_node, size_int(rear_rz_size)); gcc_assert (is_gimple_val (rsize)); tree rz_rear = DECL_CHAIN(DECL_CHAIN(TYPE_FIELDS (struct_type))); fncall_param_rear = mf_mark (build1 (ADDR_EXPR, ptr_type_node, build3 (COMPONENT_REF, TREE_TYPE(rz_rear), struct_var, rz_rear, NULL_TREE))); init_fncall_rear = gimple_build_call (lbc_init_rear_rz_fndecl, 2, fncall_param_rear, rsize); uninit_fncall_rear = gimple_build_call (lbc_uninit_rear_rz_fndecl, 2, fncall_param_rear, rsize); gimple_set_location (init_fncall_rear, location); gimple_set_location (uninit_fncall_rear, location); } // TODO Do I need this? #if 0 if (DECL_INITIAL(decl) != NULL_TREE){ // This code never seems to be getting executed for somehting like int i = 10; // I have no idea why? But looking at the tree dump, seems like its because // by the time it gets here, these kind of statements are split into two statements // as int i; and i = 10; respectively. I am leaving it in just in case. tree orig_var_type = DECL_CHAIN(TYPE_FIELDS (struct_type)); tree orig_var_lval = mf_mark (build3 (COMPONENT_REF, TREE_TYPE(orig_var_type), struct_var, orig_var_type, NULL_TREE)); init_assign_stmt = gimple_build_assign(orig_var_lval, DECL_INITIAL(decl)); gimple_set_location (init_assign_stmt, location); } #endif if (gsi_end_p (initially_stmts)) { // TODO handle this if (!DECL_ARTIFICIAL (decl)) warning (OPT_Wmudflap, "mudflap cannot track %qE in stub function", DECL_NAME (decl)); } else { #if 0 // Insert the declaration initializer if (DECL_INITIAL(decl) != NULL_TREE) gsi_insert_before (&initially_stmts, init_assign_stmt, GSI_SAME_STMT); #endif //gsi_insert_before (&initially_stmts, register_fncall, GSI_SAME_STMT); gsi_insert_before (&initially_stmts, init_fncall_front, GSI_SAME_STMT); if (COMPLETE_TYPE_P(decl)) gsi_insert_before (&initially_stmts, init_fncall_rear, GSI_SAME_STMT); /* Accumulate the FINALLY piece. */ //gimple_seq_add_stmt (&finally_stmts, unregister_fncall); gimple_seq_add_stmt (&finally_stmts, uninit_fncall_front); if (COMPLETE_TYPE_P(decl)) gimple_seq_add_stmt (&finally_stmts, uninit_fncall_rear); } mf_mark (decl); } decl = DECL_CHAIN (decl); } /* Actually, (initially_stmts!=NULL) <=> (finally_stmts!=NULL) */ if (finally_stmts != NULL) { gimple stmt = gimple_build_try (seq, finally_stmts, GIMPLE_TRY_FINALLY); gimple_seq new_seq = gimple_seq_alloc (); gimple_seq_add_stmt (&new_seq, stmt); return new_seq; } else return seq; }
static void gen_alloca_stmts(gimple_seq* stmts_, tree* sp_) { /* doc: tree-complex.c, c-common.c, omp-low.c */ /* create the stmt sequence so that: *sp = alloca(sizeof(type)); type: the type to be stacked stmts: the allocation sequence sp: the allocated area ptr */ gimple call; gimple_seq stmts; tree binop; tree mul; tree val; tree count; tree sizeuf; tree sp; tree ref; gimple assign; gimple_stmt_iterator gsi; /* build an empty sequence */ stmts = gimple_seq_alloc(); gsi = gsi_last(stmts); #if 0 /* fixme */ sp = create_tmp_var(ptr_type_node, NULL); #else /* from varpool.c */ sp = add_new_static_var(ptr_type_node); #endif /* sp = __builtin_alloca(count * sizeof(uintptr_t)); */ count = build_int_cst(integer_type_node, 2); sizeuf = build_int_cst(integer_type_node, sizeof(uintptr_t)); mul = build2(MULT_EXPR, integer_type_node, count, sizeuf); /* call = gimple_build_call(built_in_decls[BUILT_IN_ALLOCA], 1, mul); */ call = gimple_build_call(kaapi_pushdata_aligned_decl, 1, mul); gimple_call_set_lhs(call, sp); gsi_insert_after(&gsi, call, GSI_CONTINUE_LINKING); /* *(sp + 0) = 42; */ ref = build1(INDIRECT_REF, TREE_TYPE(sp), sp); val = build_int_cst(ptr_type_node, 0xdeadc0d3); assign = gimple_build_assign(ref, val); gsi_insert_after(&gsi, assign, GSI_CONTINUE_LINKING); /* *(sp + 8) = 24 */ binop = build_binary_op (0, PLUS_EXPR, convert(integer_type_node, sp), sizeuf, 0); ref = build1(INDIRECT_REF, TREE_TYPE(binop), binop); val = build_int_cst(ptr_type_node, 0xdeadc003); assign = gimple_build_assign(ref, val); gsi_insert_after(&gsi, assign, GSI_CONTINUE_LINKING); /* affect results */ *sp_ = sp; *stmts_ = stmts; }