Mercurial > lcfOS
diff python/ppci/mem2reg.py @ 300:158068af716c
yafm
author | Windel Bouwman |
---|---|
date | Tue, 03 Dec 2013 18:00:22 +0100 |
parents | python/mem2reg.py@9417caea2eb3 |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/python/ppci/mem2reg.py Tue Dec 03 18:00:22 2013 +0100 @@ -0,0 +1,70 @@ +import logging +from transform import FunctionPass +from ir import * + +def isAllocPromotable(allocinst): + # Check if alloc value is only used by load and store operations. + assert type(allocinst) is Alloc + return all(type(use) in [Load, Store] for use in allocinst.value.used_by) + + +class Mem2RegPromotor(FunctionPass): + def promoteSingleBlock(self, ai): + v = ai.value + bb = ai.Block + + # Replace all loads with the value: + loads = [i for i in v.used_by if isinstance(i, Load)] + stores = [i for i in v.used_by if isinstance(i, Store)] + stores.sort(key=lambda s: s.Position) + stores.reverse() + + for load in loads: + idx = load.Position + # Search upwards: + for store in stores: + if store.Position < load.Position: + break + load.value.replaceby(store.value) + logging.debug('replaced {} with {}'.format(load, store.value)) + bb.removeInstruction(load) + + # Remove store instructions: + for store in stores: + sv = store.value + logging.debug('removing {}'.format(store)) + bb.removeInstruction(store) + #assert sv.Used + + # Remove alloca instruction: + assert not ai.value.Used, ai.value.used_by + bb.removeInstruction(ai) + + def promote(self, ai): + # Find load operations and replace them with assignments + v = ai.value + if len(ai.value.UsedInBlocks) == 1: + self.promoteSingleBlock(ai) + return + + loads = [i for i in v.used_by if isinstance(i, Load)] + stores = [i for i in v.used_by if isinstance(i, Store)] + + # Each store instruction can be removed (later). + # Instead of storing the value, we use it + # where the load would have been! + replMap = {} + for store in stores: + replMap[store] = store.value + + # for each load, track back what the defining store + # was. + for load in loads: + pass + + def onFunction(self, f): + for bb in f.BasicBlocks: + allocs = [i for i in bb.Instructions if isinstance(i, Alloc)] + for i in allocs: + if isAllocPromotable(i): + self.promote(i)