#include "blocks.h" #include "optimise.h" #define DEPTH (IR->x.depth) #include "chains.h" extern BitSet liveOnEdge(EdgeSet set); static Block* sortBlocks(EdgeSet set); float* priority = NULL; extern int reduceReloads(BitSet use, BitSet def, XStack in, XStack out, BitSet work); extern void popTemp(Block b, int temp, int depth); extern void pushTemp(Block b, int temp, int depth); extern void buildXStacks(); 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; } } void buildXStack(EdgeSet edges, BitSet work1, BitSet work2) { int i; Block* blocks = sortBlocks(edges); BitSet accepts = work1; BitSet rejects = work2; assert(accepts); assert(rejects); set_clear(accepts); set_clear(rejects); for (i = 0; blocks[i]; i++) { set_addSet(accepts, block_accept(blocks[i])); set_removeSet(accepts, rejects); set_addSet(rejects, block_reject(blocks[i])); set_removeSet(rejects, accepts); } BitSet live = liveOnEdge(edges); BitSet top = set_clone(live); BitSet lower = set_clone(live); set_intersection(live, accepts, top); set_removeSet(lower, top); set_removeSet(lower, rejects); XStack x = xstack_new(IR->x.depth - edgeset_depth(edges), top, lower); // Attach to all blocks... edgeset_setXstack(edges, x); FOR_EACH(i, edgeset_children(edges)) block_setInStack(flow_block(i), x); FOR_EACH(i, edgeset_parents(edges)) block_setOutStack(flow_block(i), x); } /* static int scheduleChild(Block b, BitSet live, 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 (getEDepth(temp) + subdepth < DEPTH && set_contains(live, index)) { substack[i++] = index; } set_remove(live, index); } return i; } static int scheduleParent(Block b, BitSet live, 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 (getEDepth(temp) + subdepth < DEPTH && set_contains(live, index)) { substack[i++] = index; } set_remove(live, index); } return i; } static int scheduleTemps(EdgeSet edges, int* substack) { int i, depth = 0; Block* blocks = sortBlocks(edges); BitSet children = edgeset_children(edges); BitSet live = set_clone(liveOnEdge(edges)); for (i = 0; blocks[i]; i++) { if (set_contains(children, block_id(blocks[i]))) depth = scheduleChild(blocks[i], live, substack, depth); else depth = scheduleParent(blocks[i], live, substack, depth); } return depth; } */ extern void accept_reject(Block b); extern void accept_reject2(Block b); extern void chainAlloc(Block b); static int compare(const void* v1, const void* v2) { Block b1 = *(Block*)v1; Block b2 = *(Block*)v2; float f1, f2; f1 = priority[block_id(b1)]; f2 = priority[block_id(b2)]; if (f1 == f2) return block_length(b2) - block_length(b1); else return f1 > f2 ? -1 : 1; } static Block* sortBlocks(EdgeSet edges) { if (priority == NULL) priority = allocate(sizeof(float)*flow_size(), FUNC); int i, size, result = 0; float f, *scores; BitSet children, parents, all; size = flow_size(); children = edgeset_children(edges); parents = edgeset_parents(edges); all = set_clone(children); set_addSet(all, parents); // set_print(stderr, all); FOR_EACH(i, all) priority[i] = 0.0f; f = 1.0f / set_size(children); FOR_EACH(i, children) priority[i] = f; f = 1.0f / set_size(parents); FOR_EACH(i, parents) { priority[i] += f; } int blockCount = set_size(all); Block* blocks = allocate(sizeof(Block) * (blockCount + 1), FUNC); blocks[blockCount] = NULL; int index = 0; FOR_EACH(i, all) { blocks[index++] = flow_block(i); } assert(index == blockCount); qsort(blocks, blockCount, sizeof(Block), &compare); return blocks; } /* static char* xxxx() { priority = allocate(sizeof(float)*flow_size(), FUNC); initialXStacks(); flow_applyToBlocks(accept_reject); buildXStacks(); return NULL; } optimiser final = { "final", "Final optimiser - maybe.", 0, &xxxx }; */