#include "optimise.h" #include "blocks.h" #define DEPTH (IR->x.depth) extern BitSet liveOnEdge(EdgeSet set); static Block* sortBlocks(EdgeSet set); extern void popTemp(Block b, int temp, int depth); extern void pushTemp(Block b, int temp, int depth); static void flipArray(int* array, int size) { int i, temp; for(i = 0; i < size >> 1; i++) { temp = array[i]; array[i] = array[size-1-i]; array[size-1-i] = temp; } } static int scheduleChild(Block b, int* possibles, int* substack, int subdepth) { int i, index, depth; Node temp; if (set_empty(live)) return subdepth; depth = block_getStartDepth(b); i = subdepth; for (temp = block_firstTemp(b); temp; temp = temp->x.next) { index = getTempIndex(temp); if (getDepth(temp) + subdepth < DEPTH && set_contains(live, index)) { substack[i++] = index; } set_remove(live, index); } return i; } static void scheduleParentXStack(BLock b, int* xstack, int xdepth, BitSet live) { Node temp; for (temp = block_lastTemp(b); temp; temp = temp->x.prev) { index = getTempIndex(temp); if (getDepth(temp) + subdepth < DEPTH && set_contains(live, index)) { substack[i++] = index; } set_remove(live, index); } } static int scheduleParent(Block b, int* possibles, int* substack, int subdepth) { int i, index, depth = 0; i = subdepth; Node temp; for (temp = block_lastTemp(b); temp; temp = temp->x.prev) { index = getTempIndex(temp); if (getDepth(temp) + subdepth < DEPTH && set_contains(live, index)) { substack[i++] = index; } set_remove(live, index); } return i; } static int compare(int* i1, int* i2) { return localVariableSymbol(*i1)->ref - localVariableSymbol(*i2)->ref; } static Block* blocks; static int scheduleTemps(EdgeSet edges, int* substack) { int i, depth = 0; BitSet children = edgeset_children(edges); BitSet live = liveOnEdge(edges); int* possibles = allocate(sizeof(int), set_size(live)); int count = 0; FOR_EACH(i, live) { possibles[count++] = i; } qsort(possible, count, sizeof(int*), &compare); for (i = 0; blocks[i]; i++) { if (set_contains(children, block_id(blocks[i]))) depth = scheduleChild(blocks[i], live, substack, depth); else if (set_contains(parents, block_id(blocks[i]))) depth = scheduleParent(blocks[i], live, substack, depth); } return depth; } static char* xxxx() { blocks = sortBlocks(); EdgeSet* edge_sets = buildEdgeSets(); sortTemps(); generateConstraintsForBlocks(); int i, count, *substack; BitSet children, parents; while (*edge_sets) { BitSet live = liveOnEdge(*edge_sets); if (!set_empty(live)) { applyConstraints(); substack = allocate(sizeof(int) * set_size(live), FUNC); count = scheduleTemps(*edge_sets, substack); children = edgeset_children(*edge_sets); FOR_EACH(i, children) { popAll(flow_block(i), substack, count); } parents = edgeset_parents(*edge_sets); FOR_EACH(i, parents) { pushAll(flow_block(i), substack, count); } } edge_sets++; } // Check flowgraph is OK. verify(); return NULL; } static int compare(const void* v1, const void* v2) { Block b1 = *(Block*)v1; Block b2 = *(Block*)v2; float f1, f2; f1 = block_getPriority(b1); f2 = block_getPriority(b2); if (f1 == f2) return block_length(b1) - block_length(b2); else return f1 < f2 ? -1 : 1; } static Block* sortBlocks() { // Sort all blocks in flowgraph... // To do... return NULL; } optimiser costwise = { "costwise", "Do edge optimisation, ordering temps by front-end use count.", 0, &xxxx };