#include "c.h" #include "collections.h" #include "x_stack.h" struct x_stack { int top_size; BitSet upper; BitSet lower; Symbol top_items[1]; // item 0 is TOS... }; void xstack_order(XStack x, Symbol temp) { int id = temp->x.uniqueID; if (set_contains(x->upper, id)) { set_remove(x->upper, id); x->top_items[x->top_size++] = temp; x->top_items[x->top_size] = NULL; } } Symbol* xstack_top(XStack x) { return x->top_items; } void xstack_print(XStack stack, FILE* out) { int i; if (stack == NULL) { fprintf(out, "None"); return; } fprintf(out, "{"); FOR_EACH(i, stack->lower) { fprintf(out, "%s, ", localVariableSymbol(i)->name); } fprintf(out, "}"); if (!set_empty(stack->upper)) { fprintf(out, "{"); FOR_EACH(i, stack->upper) { fprintf(out, "%s, ", localVariableSymbol(i)->name); } fprintf(out, "}"); } if (stack->top_size) { fprintf(out, "["); for (i = 0; i < stack->top_size; i++) { fprintf(out, "%s, ", stack->top_items[i]->name); } fprintf(out, "]"); } } XStack xstack_new(BitSet upper, BitSet lower) { assert(upper); assert(lower); int size = set_size(upper); assert(size <= (IR->x.depth)); XStack new = allocate(sizeof(int) * size + sizeof(struct x_stack), FUNC); new->top_size = 0; new->top_items[0] = NULL; new->upper = upper; new->lower = lower; return new; } void ensurePopOrPush(XStack x1, XStack x2, BitSet work1, BitSet work2) { assert(work1); assert(work2); set_intersection(x1->lower, x2->upper, work1); set_intersection(x2->lower, x1->upper, work2); if (set_empty(work1)) return; if (set_empty(work2)) return; // Neither is empty... int i; float cost1, cost2; cost1 = cost2 = 0; FOR_EACH(i, work1) { cost1 += localVariableSymbol(i)->ref; } FOR_EACH(i, work2) { cost2 += localVariableSymbol(i)->ref; } if (cost1 > cost2) { set_removeSet(x2->lower, work2); } else { set_removeSet(x1->lower, work1); } } int correctLowerStacks(XStack x1, XStack x2, BitSet work1, BitSet work2) { assert(work1); assert(work2); set_clear(work1); set_addSet(work1, x1->lower); set_removeSet(work1, x2->upper); set_clear(work2); set_addSet(work2, x2->lower); set_removeSet(work2, x1->upper); if (set_equals(work1, work2)) return 0; set_intersection(work1, work2, work1); set_removeSet(x1->lower, work1); set_removeSet(x2->lower, work1); return 1; } void ensureOrder(XStack x1, XStack x2, BitSet work1, BitSet work2) { assert(work1); assert(work2); int i; float max_lower_ref = 0; set_intersection(x1->lower, x2->lower, work1); set_intersection(x1->lower, x2->upper, work2); if (set_empty(work2)) { set_intersection(x2->lower, x1->upper, work2); } if (set_empty(work2)) return; FOR_EACH(i, work1) { float f = localVariableSymbol(i)->ref; max_lower_ref = max_lower_ref > f ? max_lower_ref : f; } FOR_EACH(i, work2) { if (localVariableSymbol(i)->ref < max_lower_ref) { set_remove(x1->lower, i); set_remove(x2->lower, i); } } }