Mercurial > lcfOS
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) |