Mercurial > lcfOS
comparison 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 |
comparison
equal
deleted
inserted
replaced
299:674789d9ff37 | 300:158068af716c |
---|---|
1 import logging | |
2 from transform import FunctionPass | |
3 from ir import * | |
4 | |
5 def isAllocPromotable(allocinst): | |
6 # Check if alloc value is only used by load and store operations. | |
7 assert type(allocinst) is Alloc | |
8 return all(type(use) in [Load, Store] for use in allocinst.value.used_by) | |
9 | |
10 | |
11 class Mem2RegPromotor(FunctionPass): | |
12 def promoteSingleBlock(self, ai): | |
13 v = ai.value | |
14 bb = ai.Block | |
15 | |
16 # Replace all loads with the value: | |
17 loads = [i for i in v.used_by if isinstance(i, Load)] | |
18 stores = [i for i in v.used_by if isinstance(i, Store)] | |
19 stores.sort(key=lambda s: s.Position) | |
20 stores.reverse() | |
21 | |
22 for load in loads: | |
23 idx = load.Position | |
24 # Search upwards: | |
25 for store in stores: | |
26 if store.Position < load.Position: | |
27 break | |
28 load.value.replaceby(store.value) | |
29 logging.debug('replaced {} with {}'.format(load, store.value)) | |
30 bb.removeInstruction(load) | |
31 | |
32 # Remove store instructions: | |
33 for store in stores: | |
34 sv = store.value | |
35 logging.debug('removing {}'.format(store)) | |
36 bb.removeInstruction(store) | |
37 #assert sv.Used | |
38 | |
39 # Remove alloca instruction: | |
40 assert not ai.value.Used, ai.value.used_by | |
41 bb.removeInstruction(ai) | |
42 | |
43 def promote(self, ai): | |
44 # Find load operations and replace them with assignments | |
45 v = ai.value | |
46 if len(ai.value.UsedInBlocks) == 1: | |
47 self.promoteSingleBlock(ai) | |
48 return | |
49 | |
50 loads = [i for i in v.used_by if isinstance(i, Load)] | |
51 stores = [i for i in v.used_by if isinstance(i, Store)] | |
52 | |
53 # Each store instruction can be removed (later). | |
54 # Instead of storing the value, we use it | |
55 # where the load would have been! | |
56 replMap = {} | |
57 for store in stores: | |
58 replMap[store] = store.value | |
59 | |
60 # for each load, track back what the defining store | |
61 # was. | |
62 for load in loads: | |
63 pass | |
64 | |
65 def onFunction(self, f): | |
66 for bb in f.BasicBlocks: | |
67 allocs = [i for i in bb.Instructions if isinstance(i, Alloc)] | |
68 for i in allocs: | |
69 if isAllocPromotable(i): | |
70 self.promote(i) |