summaryrefslogtreecommitdiff
path: root/src/main/java/com/seaofnodes/simple/node/ConstantNode.java
blob: 47a7bbf6be8c574ced89005bd572c575792b86c1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package com.seaofnodes.simple.node;

import com.seaofnodes.print.ExprPrinter;

import com.seaofnodes.simple.codegen.CodeGen;
import com.seaofnodes.simple.type.Type;
import com.seaofnodes.simple.type.TypeFunPtr;
import com.seaofnodes.simple.util.BAOS;

import java.util.HashMap;
import java.util.IdentityHashMap;

/**
 * A Constant node represents a constant value.
 * <p>
 * Constants have no semantic inputs. However, we set Start as an input to
 * Constants to enable a forward graph walk.  This edge carries no semantic
 * meaning, and it is present <em>solely</em> to allow visitation.
 * <p>
 * The Constant's value is the value stored in it.
 */

public class ConstantNode extends TypeNode {
    public ConstantNode( Type type ) {
        this(type,false);
    }
    protected ConstantNode( Type type, boolean raw ) {
        super(type,new Node[]{CodeGen.CODE._start});
        assert raw || !(type instanceof TypeFunPtr tfp && tfp.isConstant()) :
            "Unique function identities require a Return-linked FunPtrNode";
        _type = type;
    }
    public ConstantNode( ConstantNode con ) { super(con); }
    @Override public Tag serialTag() { return Tag.Con; }
    @Override public void packed( BAOS baos, HashMap<String,Integer> strs, HashMap<Type,Integer> types, IdentityHashMap<Node, Integer> anodes ) {
        baos.packed2(types.get(_con)); // NPE if fails lookup
    }
    static Node make( BAOS bais, Type[] types)  { return raw(types[bais.packed2()]); }

    // Semantic constant construction through Opto.  A unique internal
    // function identity carries a lifetime edge to the function's Return.
    public static Node make( Type type ) {
        if( type==Type. CONTROL ) return new CtrlNode();
        if( type==Type.XCONTROL ) return new XCtrlNode();
        if( CodeGen.CODE._phase != null &&
            CodeGen.CODE._phase.ordinal() > CodeGen.Phase.Opto.ordinal() )
            return raw(type);
        if( type instanceof TypeFunPtr tfp && tfp.isConstant() ) {
            FunNode fun = CodeGen.CODE._link(tfp);
            if( fun != null )
                return new FunPtrNode(tfp,CodeGen.CODE._start,fun.ret()).init();
            // TODO: A singleton FIDX can also emerge after merging and
            // guarding several function pointers.  Preserve that identity
            // even if its internal Return is no longer available.
            return raw(type);
        }
        return new ConstantNode(type);
    }

    // Exact construction for deserialization and graph-incomplete machine
    // selection.  No semantic classification, compute, idealize, or GVN.
    public static ConstantNode raw( Type type ) { return new ConstantNode(type,true); }
    public static ConstantNode raw( ConstantNode con ) { return new ConstantNode(con); }

    // Analysis input created from whole cloth, rather than a first-class
    // runtime value.  In particular, a constructor call descriptor does not
    // own the constructor function; the class FunPtr does.
    public static ConstantNode seed( Type type ) { return new ConstantNode(type,true); }

    @Override protected String repeatName() {
        return _con==null || _con.toString().length()<=32 ? null : uniqueName();
    }

    @Override public String label() { return "Con"; }
    @Override public Node copy() { return raw(this); }


    @Override
    protected ExprPrinter<Node> _print1(ExprPrinter<Node> p) {
        if( _con instanceof TypeFunPtr tfp && tfp._isConstant() && tfp.notNull() ) {
            FunNode fun = CodeGen.CODE._link(tfp);
            if( fun!=null && fun._name != null )
                return p.p("{ ").p(fun._name).p("}");
        }
        return p.p(_con==null ? "---" : _con.toString());
    }

    @Override public boolean isConst() { return true; }
    @Override public Type compute() { return _con; }
    @Override public Node idealize() { return null; }
}