static void AddExtensionFields (FGraph graph) { Node ptr; Arc arc; struct Ext *ext; int change; Set all; FreeExtensionFields (); if (graph->nodes == 0) return; if (graph->root == 0) Punt ("no root node"); all = 0; for (ptr = graph->nodes; ptr != 0; ptr = nextNode (ptr)) { nodeExt (ptr) = (others + n_others); others[n_others].dominator = 0; others[n_others].level = -1; others[n_others].order = n_others; all = Set_add (all, n_others); n_others += 1; } ext = (struct Ext *) nodeExt (graph->root); ext->level = 0; ext->dominator = Set_add (0, ext->order); for (ptr = graph->nodes; ptr != 0; ptr = nextNode (ptr)) { if (ptr == graph->root) continue; ext = (struct Ext *) nodeExt (ptr); ext->dominator = Set_union (0, all); } /* * compute dominators. */ change = 1; while (change != 0) { change = 0; for (ptr = graph->nodes; ptr != 0; ptr = nextNode (ptr)) { Set dom, temp; if (ptr == graph->root) continue; arc = sourceArcs (ptr); if (arc == 0) { dom = 0; } else { dom = Set_union (all, 0); for (; arc != 0; arc = nextArc (arc)) { ext = (struct Ext *) nodeExt (sourceNode (arc)); temp = Set_intersect (dom, ext->dominator); Set_dispose (dom); dom = temp; temp = 0; } ext = (struct Ext *) nodeExt (ptr); dom = Set_add (dom, ext->order); if (Set_same (dom, ext->dominator)) { Set_dispose (dom); } else { Set_dispose (ext->dominator); ext->dominator = dom; change += 1; } } } } all = Set_dispose (all); /* * compute level. */ change = 1; while (change != 0) { change = 0; for (ptr = graph->nodes; ptr != 0; ptr = nextNode (ptr)) { int max; ext = (struct Ext *) nodeExt (ptr); if (ext->level >= 0) continue; max = -1; for (arc = sourceArcs (ptr); arc != 0; arc = arc->next) { Node src; struct Ext *ex; src = sourceNode (arc); ex = (struct Ext *) nodeExt (src); /* ignore back-edges */ if (ex->order >= ext->order) continue; if (ex->level < 0) break; if (ex->level > max) max = ex->level; } if (arc == 0) { /* all source have been visited */ ext->level = max + 1; change += 1; } } } #ifdef DEBUG printf ("--------------------------------------------------\n"); for (ptr = graph->nodes; ptr != 0; ptr = nextNode (ptr)) { ext = nodeExt (ptr); printf ("# id=%d, order=%d, level=%d, ", ptr->id, ext->order, ext->level); PrintSet (stdout, "dominator", ext->dominator); } #endif }
int L_global_memflow_multiloadstore_load (L_Func * fn, L_Cb * cb, L_Oper * oper) { return 0; #if 0 int change = 0; Set RAMB_ST, RAMB_JSR; Set RDEF_ST, RDEF_LD; if (!L_general_load_opcode (oper)) return 0; /* 02/07/03 REK Adding a check to make sure we don't touch a volatile * oper. */ if (L_EXTRACT_BIT_VAL (oper->flags, L_OPER_VOLATILE)) return 0; RDEF_ST = NULL; RDEF_LD = NULL; RAMB_ST = NULL; RAMB_JSR = NULL; /* Get all reaching stores */ RDEF_ST = L_get_mem_oper_RIN_defining_opers (oper, (MDF_RET_DEP | MDF_RET_STORES)); /* Get all reaching loads */ RDEF_LD = L_get_mem_oper_RIN_defining_opers (oper, (MDF_RET_DEP | MDF_RET_LOADS)); if (!Set_size (RDEF_LD) || !Set_size (RDEF_ST)) return change; fprintf (stderr, "\n\nMFMLSL: Examining load %d\n", oper->id); /* Are there any reaching, ambiguous stores */ RAMB_ST = L_get_mem_oper_RIN_defining_opers (oper, (MDF_RET_AMB | MDF_RET_STORES)); /* Are there any reaching, unsafe jsrs */ RAMB_JSR = L_get_mem_oper_RIN_defining_opers (oper, (MDF_RET_AMB | MDF_RET_JSRS)); fprintf (stderr, "MFMLSL: Dep Stores reach load %d ", oper->id); Set_print (stderr, "MSMLSL: ", RDEF_ST); fprintf (stderr, "MFMLSL: Dep Loads reach load %d ", oper->id); Set_print (stderr, "MSMLSL: ", RDEF_LD); fprintf (stderr, "MFMLSL: Amb Stores reach load %d ", oper->id); Set_print (stderr, "MSMLSL: ", RAMB_ST); fprintf (stderr, "MFMLSL: Unsafe jsrs reach load %d ", oper->id); Set_print (stderr, "MSMLSL: ", RAMB_JSR); if (!L_load_compatible_each_store (fn, oper, RDEF_ST)) { fprintf (stderr, "MFMLSL: Load is incompatible with a store\n"); Set_dispose (RDEF); Set_dispose (RDEF_LD); Set_dispose (RAMB_ST); Set_dispose (RAMB_JSR); return change; } if (!L_load_compatible_each_load (fn, oper, RDEF_LD)) { fprintf (stderr, "MFMLSL: Load is incompatible with a store\n"); Set_dispose (RDEF); Set_dispose (RDEF_LD); Set_dispose (RAMB_ST); Set_dispose (RAMB_JSR); return change; } if (!L_store_union_dominates_load (fn, cb, oper, Set_union (RDEF_LD, RDEF_ST))) { fprintf (stderr, "MFMLSL: Path to load exists not through a store/load\n"); Set_dispose (RDEF); Set_dispose (RDEF_LD); Set_dispose (RAMB_ST); Set_dispose (RAMB_JSR); return change; } if (!L_loadstore_union_postdominates_amb (fn, cb, oper, Set_union (RDEF_LD, RDEF_ST), Set_union (RAMB_ST, RAMB_JSR))) { fprintf (stderr, "MFMLSL: A amb st/jsr lies between ld/st and load \n"); Set_dispose (RDEF); Set_dispose (RDEF_LD); Set_dispose (RAMB_ST); Set_dispose (RAMB_JSR); return change; } /* Load can be removed, moves added */ fprintf (stderr, "MFMLSL: red Load %d can be converted\n", oper->id); Set_dispose (RDEF); Set_dispose (RDEF_LD); Set_dispose (RAMB_ST); Set_dispose (RAMB_JSR); return change; #endif }
int main() { //Set console default size. system(CONSOLE_SIZE); //Testing fields int testSize = 10; Set_T * mainSet = Set_new(testSize); //Fill the set Set_fill(mainSet); //Print it out puts("**********"); printf("Creating a new set...\n" "Filling it with non-repeatable numbers...\n"); Set_print(mainSet); puts("**********"); //Get some elements printf("Getting element on the index 4...\n"); int test_a = Set_getValueAt(mainSet,4); printf("Element with the index 4 is %d\n", test_a); printf("Getting element on the index 10...\n"); int test_b = Set_getValueAt(mainSet,10); printf("Element with the index 10 is %d\n", test_b); //Set some elements printf("Setting element with index 3 to \"123\"\n"); Set_setValueAt(mainSet, 3, 123); printf("Setting element with index 10 to \"123\"\n"); Set_setValueAt(mainSet, 10, 123); //Print set again puts("**********"); Set_print(mainSet); //Delete some elements printf("Deleting element index 3\n"); Set_removeValueAt(mainSet, 3); //Print the set again puts("**********"); Set_print(mainSet); //In the end - free allocated memory puts("----------------------------------------------------------------------"); printf("Creating two more sets.\n"); Set_T * first = Set_new(testSize+1); Set_T * second = Set_new(testSize+4); //15 Set_fill(first); Set_fill(second); puts("**********"); printf("First set:\n"); Set_print(first); printf("Second set:\n"); Set_print(second); puts("**********"); printf("Union with the first set and the second set.\n"); Set_T * test_unionSet = Set_union(first, second); printf("The 'union' set:\n"); Set_print(test_unionSet); puts("**********"); printf("Intersection with the first and the second set.\n"); Set_T * test_intersectionSet = Set_intersection(first, second); printf("The 'intersection' set:\n"); Set_print(test_intersectionSet); puts("**********"); printf("Difference between the first and the second set.\n"); for(int i = 0; i < Set_getSize(first); i++) { Set_setValueAt(first, i, 8+i); } printf("Changed first set:\n"); Set_print(first); Set_T * test_differenceSet = Set_difference(first, second); printf("The 'difference' set:\n"); Set_print(test_differenceSet); puts("**********"); //free allocated memory Set_delete(first); Set_delete(second); Set_delete(mainSet); Set_delete(test_unionSet); Set_delete(test_intersectionSet); Set_delete(test_differenceSet); puts("allocated memory was deleted."); return (0); }
/*! \brief Finds loops in the CFG. Builds lp hdr, body and exit bb sets, and * puts this lp info in a PC_Loop struct, which is appended to the CFG lp list. * * \param cfg * control flow graph for the func being processed * * Multiple back edges coming into the same loop header are considered as one * loop. The loop body is a union of the bodies of the loops corresponding to * each one of these back edges. * * \return void */ void PC_FindLoops (PC_Graph cfg) { PC_Block h_bb; /* build dominator sets for each bb in the cfg */ PC_BuildDomSets (cfg); /* check each cfg bb in turn to see if it's a lp header bb */ for (h_bb = cfg->first_bb; h_bb; h_bb = h_bb->next) { PC_Flow be; PC_Loop *loop; int num_back_edge; int num_exit; int s_lp_head = -1; Set s_lp_body = Set_new (), s_lp_exits = Set_new (); /* check all edges coming into h_bb to see if they are back edges */ num_back_edge = 0; for (be = h_bb->p_flow; be; be = be->p_next_flow) { /* check to see if be is indeed a back edge */ if (PC_BB1DominatesBB2 (be->dest_bb, be->src_bb)) { PC_Block bb; Stack *st = New_Stack (); Set lp_body = Set_new (); num_back_edge++; s_lp_head = be->dest_bb->ID; if (be->src_bb->ID == be->dest_bb->ID) P_warn ("PC_FindNaturalLoop: back edge head & tail are same."); /* Build the set of all bbs in the lp body. */ lp_body = Set_add (lp_body, s_lp_head); if (!Set_in (lp_body, be->src_bb->ID)) { lp_body = Set_add (lp_body, be->src_bb->ID); Push_Top (st, be->src_bb); } while ((bb = Pop (st)) != ((void*)-1)) { PC_Flow fl; for (fl = bb->p_flow; fl; fl = fl->p_next_flow) { if (!Set_in (lp_body, fl->src_bb->ID)) { lp_body = Set_add (lp_body, fl->src_bb->ID); Push_Top (st, fl->src_bb); } } } /* the s_lp body is a union of all of these 'inner' lp bodies */ s_lp_body = Set_union (s_lp_body, lp_body); Clear_Stack (st); Set_dispose (lp_body); } } /* If a loop was found, build its set of exits bbs, and append it to the list of loops in the cfg. */ if (s_lp_head != -1) { int *s_lp_bod; int lp_size = 0, i; /* Build the set of all bbs that are exits out of the lp. */ s_lp_bod = (int *) calloc (Set_size (s_lp_body), sizeof (int)); lp_size = Set_2array (s_lp_body, s_lp_bod); num_exit = 0; for (i = 0; i < lp_size; i++) { PC_Block bb; PC_Flow fl; bb = PC_FindBlock (cfg, s_lp_bod[i]); for (fl = bb->s_flow; fl; fl = fl->s_next_flow) if (!Set_in (s_lp_body, fl->dest_bb->ID)) { num_exit++; s_lp_exits = Set_add (s_lp_exits, fl->dest_bb->ID); } } free (s_lp_bod); /* check for redundant loops */ { PC_Loop lp = NULL; int same = 0; for (lp = cfg->lp; lp; lp = lp->next) if (Set_same (s_lp_body, lp->body)) { same = 1; break; } if (same) { Set_dispose (s_lp_body); Set_dispose (s_lp_exits); continue; } } /* Create a new PC_Loop and append it to the current CFG loop list. */ loop = &cfg->lp; while (*loop) loop = &(*loop)->next; *loop = PC_NewLoop (s_lp_head, s_lp_body, s_lp_exits, num_back_edge, num_exit); cfg->lp_tree = PC_LoopTreeInsert (cfg->lp_tree, *loop, 1); } Set_dispose (s_lp_body); Set_dispose (s_lp_exits); } PC_SetBlockLoops (cfg); return; }