view python/ir/instruction.py @ 171:3eb9b9e2958d

Improved IR code
author Windel Bouwman
date Wed, 03 Apr 2013 22:20:20 +0200
parents 4348da5ca307
children c1d2b6b9f9a7
line wrap: on
line source

from .basicblock import BasicBlock

class Value:
   """ Temporary SSA value (value that is assigned only once! """
   def __init__(self, name):
      # TODO: add typing? for now only handle integers
      self.name = name
      self.interferes = set()
      self.reg = None
   def __repr__(self):
      if self.reg:
         n = self.reg
      else:
         n = self.name
      return '{0}'.format(n)

class Instruction:
   """ Base class for all instructions. """
   def __init__(self):
      # successors:
      self.succ = set()
      # predecessors:
      self.pred = set()
      # live variables at this node:
      self.live_in = set()
      self.live_out = set()
      # What variables this instruction uses and defines:
      self.defs = set()
      self.uses = set()

# Function calling:
class Call(Instruction):
   def __init__(self, callee, arguments):
      super().__init__()
      self.callee = callee
      self.arguments = arguments
   def __repr__(self):
      return 'CALL {0}'.format(self.callee)

class Return(Instruction):
   def __repr__(self):
      return 'RET'

class ImmLoad(Instruction):
   def __init__(self, target, value):
      super().__init__()
      self.target = target
      self.value = value
      self.defs.add(target)
   def __repr__(self):
      return '{0} = {1}'.format(self.target, self.value)

# Data operations
class BinaryOperator(Instruction):
   def __init__(self, result, operation, value1, value2):
      super().__init__()
      #print('operation is in binops:', operation in BinOps)
      # Check types of the two operands:
      self.result = result
      self.defs.add(result)
      self.value1 = value1
      self.value2 = value2
      self.uses.add(value1)
      self.uses.add(value2)
      self.operation = operation
   def __repr__(self):
      return '{0} = {2} {1} {3}'.format(self.result, self.operation, self.value1, self.value2)

# Memory functions:
class Load(Instruction):
   def __init__(self, name, value):
      super().__init__()
      self.value = value
      self.defs.add(value)
      self.name = name
   def __repr__(self):
      return '{1} = [{0}]'.format(self.name, self.value)

class Store(Instruction):
   def __init__(self, name, value):
      super().__init__()
      self.name = name
      self.value = value
      self.uses.add(value)
   def __repr__(self):
      return '[{0}] = {1}'.format(self.name, self.value)

# Branching:
class Branch(Instruction):
   def __init__(self, target):
      super().__init__()
      assert type(target) is BasicBlock
      self.target = target
   def __repr__(self):
      return 'BRANCH {0}'.format(self.target)

class ConditionalBranch(Instruction):
   def __init__(self, a, cond, b, lab1, lab2):
      super().__init__()
      self.a = a
      assert type(a) is Value
      self.cond = cond
      self.b = b
      self.uses.add(a)
      self.uses.add(b)
      assert type(b) is Value
      assert type(lab1) is BasicBlock
      self.lab1 = lab1
      assert type(lab2) is BasicBlock
      self.lab2 = lab2
   def __repr__(self):
      return 'IF {0} {1} {2} THEN {3} ELSE {4}'.format(self.a, self.cond, self.b, self.lab1, self.lab2)

class PhiNode(Instruction):
   def __init__(self):
      super().__init__()
      self.incBB = []
   def addIncoming(self, bb):
      self.incBB.append(bb)