Generate manifest constants from constant data

Bug #599192 reported by Matt Giuca
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Mars
Triaged
Low
Matt Giuca

Bug Description

Currently, if some Mars code mentions a constant, such as a string literal or a large term with only constant subexpressions, that value will be recreated upon each execution.

Add a pass which transforms code such that any "significant constant" is moved to a CGC and therefore cached. For example, the code:

def f() :: Int:
    return print_string("Hello, world!\n")

is transformed to

def f__const_0 :: Array(Int) = "Hello, world!\n"

def f() :: Int:
    return print_string(f__const_0)

Do this by applying the following rules:

A "constant expression" is any expression which is an int literal, global variable name, constructor name, (array literal, field ref or field replace) with only constant subexpressions, or an apply or partial-apply expression where the function is a constructor name and all arguments are constant expressions. Note that this definition is not context sensitive (it can be applied to a single expression, and doesn't know how to do constant propagation). Expressions which are not constant expressions are those containing local variable names, and calls to non-constructor functions.

A "significant constant expression" (SCE) is a constant expression which is a non-empty array literal, field ref or replace, or apply expression. These are the constant expressions which are worth converting into manifest constants (the others are just atomic anyway).

For each expression in a function (from the outside in), if the expression is a SCE, create a new computable global constant (CGC) which returns the SCE and replace the expression with a reference to the CGC. Do not recursively apply this algorithm to the newly-generated CGC (any further significant constant subexpressions will not be moved into separate CGCs). If an expression is not a SCE, recursively apply the algorithm to its subexpressions (so any significant constant subexpressions could potentially be moved out).

This algorithm can be extended (later) such that:
- Any local variable assigned a SCE is removed, and all references to the local are replaced with references to the CGC (this would actually eliminate the computation dynamically if the local was never referenced -- careful),
- Any local variable assigned a non-significant CE is removed, and all references to the local are replaced with the atomic value,
- (Hence, there are no local variables with a constant value),
- Track which functions are pure (possibly with an annotation), and consider apply expressions to those functions to be constant expressions. (Can't do this without purity annotation, because otherwise IO functions will be considered constants and optimised away.)
- Apply compound-statement-level constant propagation.

Revision history for this message
Peter Schachte (schachte) wrote :

What about for this code:

def f() :: String:
    return "Hello, world!\n"

That transformation would make that code effectively equivalent to

def f :: String:
    return "Hello, world!\n"

(note no empty parens), which you wanted to distinguish.

But I still think that transformation is a good idea.

Revision history for this message
Matt Giuca (mgiuca) wrote :

> def f() :: String:
> return "Hello, world!\n"
>
> That transformation would make that code effectively equivalent to
>
> def f :: String:
> return "Hello, world!\n"

Well it wouldn't change the function f() though. It would create a new CGC, like this:

def f__const_0 :: String:
    return "Hello, world!\n"

def f() :: String:
    return f__const_0

So f would still have type () -> String, but calling it repeatedly would just result in returning a constant pointer.

Matt Giuca (mgiuca)
Changed in mars:
milestone: 0.3.1 → 0.4
Matt Giuca (mgiuca)
Changed in mars:
milestone: 1.0 → 1.1
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.