diff --git a/__init__.py b/__init__.py
index 8e21541ca74e622cf6ae7420c5b339fcde2a4610..2f6f6bf2f64761f6127ce91e7c4c0c28e1e73ee2 100644
--- a/__init__.py
+++ b/__init__.py
@@ -1,2 +1,3 @@
 from pystencils.field import Field, extractCommonSubexpressions
-
+from pystencils.typedsymbol import TypedSymbol
+from pystencils.slicing import makeSlice
diff --git a/ast.py b/ast.py
index 301bf81cff3b11280c566a33d1c3c2880ada1190..7600e946f0195a6d30722970d9b0030182c598c8 100644
--- a/ast.py
+++ b/ast.py
@@ -118,6 +118,10 @@ class Block(Node):
         node.parent = self
         self._nodes.insert(0, node)
 
+    def insertBefore(self, newNode, insertBefore):
+        idx = self._nodes.index(insertBefore)
+        self._nodes.insert(idx, newNode)
+
     def append(self, node):
         node.parent = self
         self._nodes.append(node)
@@ -162,30 +166,26 @@ class PragmaBlock(Block):
 class LoopOverCoordinate(Node):
     LOOP_COUNTER_NAME_PREFIX = "ctr"
 
-    def __init__(self, body, coordinateToLoopOver, shape, increment=1, ghostLayers=1,
-                 isInnermostLoop=False, isOutermostLoop=False):
+    def __init__(self, body, coordinateToLoopOver, start, stop, step=1):
         self._body = body
         self._coordinateToLoopOver = coordinateToLoopOver
-        self._shape = shape
-        self._increment = increment
-        self._ghostLayers = ghostLayers
+        self._begin = start
+        self._end = stop
+        self._increment = step
         self._body.parent = self
         self.prefixLines = []
-        self._isInnermostLoop = isInnermostLoop
-        self._isOutermostLoop = isOutermostLoop
 
     def newLoopWithDifferentBody(self, newBody):
-        result = LoopOverCoordinate(newBody, self._coordinateToLoopOver, self._shape, self._increment,
-                                    self._ghostLayers, self._isInnermostLoop, self._isOutermostLoop)
+        result = LoopOverCoordinate(newBody, self._coordinateToLoopOver, self._begin, self._end, self._increment)
         result.prefixLines = self.prefixLines
         return result
 
     @property
     def args(self):
         result = [self._body]
-        limit = self._shape[self._coordinateToLoopOver]
-        if isinstance(limit, Node) or isinstance(limit, sp.Basic):
-            result.append(limit)
+        for e in [self._begin, self._end, self._increment]:
+            if hasattr(e, "args"):
+                result.append(e)
         return result
 
     @property
@@ -193,8 +193,16 @@ class LoopOverCoordinate(Node):
         return self._body
 
     @property
-    def iterationEnd(self):
-        return self._shape[self.coordinateToLoopOver] - self.ghostLayers
+    def start(self):
+        return self._begin
+
+    @property
+    def stop(self):
+        return self._end
+
+    @property
+    def step(self):
+        return self._increment
 
     @property
     def coordinateToLoopOver(self):
@@ -206,42 +214,44 @@ class LoopOverCoordinate(Node):
         result.add(self.loopCounterSymbol)
         return result
 
+    @staticmethod
+    def getLoopCounterName(coordinateToLoopOver):
+        return "%s_%s" % (LoopOverCoordinate.LOOP_COUNTER_NAME_PREFIX, coordinateToLoopOver)
+
     @property
     def loopCounterName(self):
-        return "%s_%s" % (LoopOverCoordinate.LOOP_COUNTER_NAME_PREFIX, self._coordinateToLoopOver)
+        return LoopOverCoordinate.getLoopCounterName(self.coordinateToLoopOver)
+
+    @staticmethod
+    def getLoopCounterSymbol(coordinateToLoopOver):
+        return TypedSymbol(LoopOverCoordinate.getLoopCounterName(coordinateToLoopOver), "int")
 
     @property
     def loopCounterSymbol(self):
-        return TypedSymbol(self.loopCounterName, "int")
+        return LoopOverCoordinate.getLoopCounterSymbol(self.coordinateToLoopOver)
 
     @property
     def symbolsRead(self):
-        result = self._body.symbolsRead
-        limit = self._shape[self._coordinateToLoopOver]
-        if isinstance(limit, sp.Basic):
-            result.update(limit.atoms(sp.Symbol))
+        loopBoundSymbols = set()
+        for possibleSymbol in [self._begin, self._end, self._increment]:
+            if isinstance(possibleSymbol, Node) or isinstance(possibleSymbol, sp.Basic):
+                loopBoundSymbols.update(possibleSymbol.atoms(sp.Symbol))
+        result = self._body.symbolsRead.union(loopBoundSymbols)
         return result
 
     @property
     def isOutermostLoop(self):
-        return self._isOutermostLoop
+        from pystencils.transformations import getNextParentOfType
+        return getNextParentOfType(self, LoopOverCoordinate) is None
 
     @property
     def isInnermostLoop(self):
-        return self._isInnermostLoop
+        return len(self.atoms(LoopOverCoordinate)) == 0
 
     @property
     def coordinateToLoopOver(self):
         return self._coordinateToLoopOver
 
-    @property
-    def iterationRegionWithGhostLayer(self):
-        return self._shape[self._coordinateToLoopOver]
-
-    @property
-    def ghostLayers(self):
-        return self._ghostLayers
-
 
 class SympyAssignment(Node):
 
diff --git a/backends/cbackend.py b/backends/cbackend.py
index ef24a39fb3b389f08ba62e6c2685de5122b25720..bf5f92a06e24dc55025d49a3165e6a7380fa47b7 100644
--- a/backends/cbackend.py
+++ b/backends/cbackend.py
@@ -105,9 +105,9 @@ class CBackend:
                     yield e
 
         counterVar = node.loopCounterName
-        start = "int %s = %d" % (counterVar, node.ghostLayers)
-        condition = "%s < %s" % (counterVar, self.sympyPrinter.doprint(node.iterationEnd))
-        update = "++%s" % (counterVar,)
+        start = "int %s = %s" % (counterVar, self.sympyPrinter.doprint(node.start))
+        condition = "%s < %s" % (counterVar, self.sympyPrinter.doprint(node.stop))
+        update = "%s += %s" % (counterVar, self.sympyPrinter.doprint(node.step),)
         loopStr = "for (%s; %s; %s)" % (start, condition, update)
         return LoopWithOptionalPrefix(loopStr, self._print(node.body), prefixLines=node.prefixLines)
 
diff --git a/cpu/kernelcreation.py b/cpu/kernelcreation.py
index 185ebaa3c759a50c9fb230d1cee3f50b236d5a7e..6407382bae6f7ef64af77a354f009eccc8f8c6bb 100644
--- a/cpu/kernelcreation.py
+++ b/cpu/kernelcreation.py
@@ -6,7 +6,7 @@ from pystencils.field import Field
 import pystencils.ast as ast
 
 
-def createKernel(listOfEquations, functionName="kernel", typeForSymbol=None, splitGroups=()):
+def createKernel(listOfEquations, functionName="kernel", typeForSymbol=None, splitGroups=(), iterationSlice=None):
     """
     Creates an abstract syntax tree for a kernel function, by taking a list of update rules.
 
@@ -20,6 +20,7 @@ def createKernel(listOfEquations, functionName="kernel", typeForSymbol=None, spl
            right hand side is a sympy Boolean which are assumed to be 'bool' .
     :param splitGroups: Specification on how to split up inner loop into multiple loops. For details see
            transformation :func:`pystencils.transformation.splitInnerLoop`
+    :param iterationSlice: if not None, iteration is done only over this slice of the field
     :return: :class:`pystencils.ast.KernelFunction` node
     """
     if not typeForSymbol:
@@ -42,7 +43,7 @@ def createKernel(listOfEquations, functionName="kernel", typeForSymbol=None, spl
         field.setReadOnly()
 
     body = ast.Block(assignments)
-    code = makeLoopOverDomain(body, functionName)
+    code = makeLoopOverDomain(body, functionName, iterationSlice=iterationSlice)
 
     if splitGroups:
         typedSplitGroups = [[typeSymbol(s) for s in splitGroup] for splitGroup in splitGroups]
diff --git a/slicing.py b/slicing.py
new file mode 100644
index 0000000000000000000000000000000000000000..c9b45a6592531921b8d3522a68ac22528a73418a
--- /dev/null
+++ b/slicing.py
@@ -0,0 +1,45 @@
+import sympy as sp
+
+class SliceMaker(object):
+    def __getitem__(self, item):
+        return item
+makeSlice = SliceMaker()
+
+
+def normalizeSlice(slices, sizes):
+    """Converts slices with floating point and/or negative entries to integer slices"""
+
+    if len(slices) != len(sizes):
+        raise ValueError("Slice dimension does not match sizes")
+
+    result = []
+
+    for s, size in zip(slices, sizes):
+        if type(s) is int:
+            result.append(s)
+            continue
+        if type(s) is float:
+            result.append(int(s * size))
+            continue
+
+        assert (type(s) is slice)
+
+        if s.start is None:
+            newStart = 0
+        elif type(s.start) is float:
+            newStart = int(s.start * size)
+        else:
+            newStart = s.start
+
+        if s.stop is None:
+            newStop = size
+        elif type(s.stop) is float:
+            newStop = int(s.stop * size)
+        elif not isinstance(s.stop, sp.Basic) and s.stop < 0:
+            newStop = size + s.stop
+        else:
+            newStop = s.stop
+
+        result.append(slice(newStart, newStop, s.step if s.step is not None else 1))
+
+    return tuple(result)
diff --git a/transformations.py b/transformations.py
index 6ea7014fb98c5e00dfe0f55621cc2280de89ffdc..1443908037d4b025d201bdd3893e487a11c50032 100644
--- a/transformations.py
+++ b/transformations.py
@@ -2,16 +2,19 @@ from collections import defaultdict
 import sympy as sp
 from sympy.logic.boolalg import Boolean
 from sympy.tensor import IndexedBase
+
 from pystencils.field import Field, offsetComponentToDirectionString
 from pystencils.typedsymbol import TypedSymbol
+from pystencils.slicing import normalizeSlice
 import pystencils.ast as ast
 
 
-def makeLoopOverDomain(body, functionName):
+def makeLoopOverDomain(body, functionName, iterationSlice=None):
     """
     Uses :class:`pystencils.field.Field.Access` to create (multiple) loops around given AST.
     :param body: list of nodes
     :param functionName: name of generated C function
+    :param iterationSlice: if not None, iteration is done only over this slice of the field
     :return: :class:`LoopOverCoordinate` instance with nested loops, ordered according to field layouts
     """
     # find correct ordering by inspecting participating FieldAccesses
@@ -33,13 +36,29 @@ def makeLoopOverDomain(body, functionName):
         assert nrOfFixedSizedFields <= 1, "Differently sized field accesses in loop body: " + str(shapes)
     shape = list(shapes)[0]
 
+    if iterationSlice is not None:
+        iterationSlice = normalizeSlice(iterationSlice, shape)
+
     currentBody = body
     lastLoop = None
     for i, loopCoordinate in enumerate(loopOrder):
-        newLoop = ast.LoopOverCoordinate(currentBody, loopCoordinate, shape, 1, requiredGhostLayers,
-                                         isInnermostLoop=(i == 0), isOutermostLoop=(i == len(loopOrder) - 1))
-        lastLoop = newLoop
-        currentBody = ast.Block([lastLoop])
+        if iterationSlice is None:
+            begin = requiredGhostLayers
+            end = shape[loopCoordinate] - requiredGhostLayers
+            newLoop = ast.LoopOverCoordinate(currentBody, loopCoordinate, begin, end, 1)
+            lastLoop = newLoop
+            currentBody = ast.Block([lastLoop])
+        else:
+            sliceComponent = iterationSlice[loopCoordinate]
+            if type(sliceComponent) is slice:
+                sc = sliceComponent
+                newLoop = ast.LoopOverCoordinate(currentBody, loopCoordinate, sc.start, sc.stop, sc.step)
+                lastLoop = newLoop
+                currentBody = ast.Block([lastLoop])
+            else:
+                assignment = ast.SympyAssignment(ast.LoopOverCoordinate.getLoopCounterSymbol(loopCoordinate),
+                                                 sp.sympify(sliceComponent))
+                currentBody.insertFront(assignment)
     return ast.KernelFunction(currentBody, functionName)
 
 
@@ -236,21 +255,28 @@ def moveConstantsBeforeLoop(astNode):
     :return:
     """
     def findBlockToMoveTo(node):
-        """Traverses parents of node as long as the symbols are independent and returns a (parent) block
+        """
+        Traverses parents of node as long as the symbols are independent and returns a (parent) block
         the assignment can be safely moved to
-        :param node: SympyAssignment inside a Block"""
+        :param node: SympyAssignment inside a Block
+        :return blockToInsertTo, childOfBlockToInsertBefore
+        """
         assert isinstance(node, ast.SympyAssignment)
         assert isinstance(node.parent, ast.Block)
 
         lastBlock = node.parent
+        lastBlockChild = node
         element = node.parent
+        prevElement = node
         while element:
             if isinstance(element, ast.Block):
                 lastBlock = element
+                lastBlockChild = prevElement
             if node.symbolsRead.intersection(element.symbolsDefined):
                 break
+            prevElement = element
             element = element.parent
-        return lastBlock
+        return lastBlock, lastBlockChild
 
     def checkIfAssignmentAlreadyInBlock(assignment, targetBlock):
         for arg in targetBlock.args:
@@ -266,13 +292,13 @@ def moveConstantsBeforeLoop(astNode):
             if not isinstance(child, ast.SympyAssignment):
                 block.append(child)
             else:
-                target = findBlockToMoveTo(child)
+                target, childToInsertBefore = findBlockToMoveTo(child)
                 if target == block:     # movement not possible
                     target.append(child)
                 else:
                     existingAssignment = checkIfAssignmentAlreadyInBlock(child, target)
                     if not existingAssignment:
-                        target.insertFront(child)
+                        target.insertBefore(child, childToInsertBefore)
                     else:
                         assert existingAssignment.rhs == child.rhs, "Symbol with same name exists already"
 
@@ -335,7 +361,7 @@ def splitInnerLoop(astNode, symbolGroups):
     innerLoop.parent.replace(innerLoop, newLoops)
 
     for tmpArray in symbolsWithTemporaryArray:
-        outerLoop.parent.insertFront(ast.TemporaryMemoryAllocation(tmpArray, innerLoop.iterationRegionWithGhostLayer))
+        outerLoop.parent.insertFront(ast.TemporaryMemoryAllocation(tmpArray, innerLoop.stop))
         outerLoop.parent.append(ast.TemporaryMemoryFree(tmpArray))