comparison python/ppci/ir.py @ 307:e609d5296ee9

Massive rewrite of codegenerator
author Windel Bouwman
date Thu, 12 Dec 2013 20:42:56 +0100
parents 0615b5308710
children 68b01c8abf8a
comparison
equal deleted inserted replaced
306:b145f8e6050b 307:e609d5296ee9
1 """ 1 """
2 Intermediate representation (IR) code classes. 2 Intermediate representation (IR) code classes.
3 """ 3 """
4
5
6 def dumpgv(m, outf):
7 print('digraph G ', file=outf)
8 print('{', file=outf)
9 for f in m.Functions:
10 print('{} [label="{}" shape=box3d]'.format(id(f), f), file=outf)
11 for bb in f.Blocks:
12 contents = str(bb) + '\n'
13 contents += '\n'.join([str(i) for i in bb.Instructions])
14 print('{0} [shape=note label="{1}"];'
15 .format(id(bb), contents), file=outf)
16 for successor in bb.Successors:
17 print('"{}" -> "{}"'.format(id(bb), id(successor)), file=outf)
18
19 print('"{}" -> "{}" [label="entry"]'
20 .format(id(f), id(f.entry)), file=outf)
21 print('}', file=outf)
22
23 4
24 class Module: 5 class Module:
25 """ Container unit for variables and functions. """ 6 """ Container unit for variables and functions. """
26 def __init__(self, name): 7 def __init__(self, name):
27 self.name = name 8 self.name = name
420 lab_no = property(lambda s: s.Targets[1]) 401 lab_no = property(lambda s: s.Targets[1])
421 402
422 def __repr__(self): 403 def __repr__(self):
423 return 'IF {} {} {} THEN {} ELSE {}'\ 404 return 'IF {} {} {} THEN {} ELSE {}'\
424 .format(self.a, self.cond, self.b, self.lab_yes, self.lab_no) 405 .format(self.a, self.cond, self.b, self.lab_yes, self.lab_no)
425
426
427 # Constructing IR:
428
429 class NamedClassGenerator:
430 def __init__(self, prefix, cls):
431 self.prefix = prefix
432 self.cls = cls
433
434 def NumGen():
435 a = 0
436 while True:
437 yield a
438 a = a + 1
439 self.nums = NumGen()
440
441 def gen(self, prefix=None):
442 if not prefix:
443 prefix = self.prefix
444 return self.cls('{0}{1}'.format(prefix, self.nums.__next__()))
445
446
447 class Builder:
448 """ Base class for ir code generators """
449 def __init__(self):
450 self.prepare()
451
452 def prepare(self):
453 self.newTemp = NamedClassGenerator('reg', Temp).gen
454 self.newBlock2 = NamedClassGenerator('block', Block).gen
455 self.bb = None
456 self.m = None
457 self.fn = None
458 self.loc = None
459
460 # Helpers:
461 def setModule(self, m):
462 self.m = m
463
464 def newFunction(self, name):
465 f = Function(name)
466 self.m.addFunc(f)
467 return f
468
469 def newBlock(self):
470 assert self.fn
471 b = self.newBlock2()
472 b.function = self.fn
473 return b
474
475 def setFunction(self, f):
476 self.fn = f
477 self.bb = f.entry if f else None
478
479 def setBlock(self, b):
480 self.bb = b
481
482 def setLoc(self, l):
483 self.loc = l
484
485 def emit(self, i):
486 assert isinstance(i, Statement)
487 i.debugLoc = self.loc
488 if not self.bb:
489 raise Exception('No basic block')
490 self.bb.addInstruction(i)