github.com/llvm-mirror/llgo@v0.0.0-20190322182713-bf6f0a60fce1/third_party/gotools/go/pointer/constraint.go (about)

     1  // Copyright 2013 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package pointer
     6  
     7  import (
     8  	"llvm.org/llgo/third_party/gotools/go/types"
     9  )
    10  
    11  type constraint interface {
    12  	// For a complex constraint, returns the nodeid of the pointer
    13  	// to which it is attached.   For addr and copy, returns dst.
    14  	ptr() nodeid
    15  
    16  	// renumber replaces each nodeid n in the constraint by mapping[n].
    17  	renumber(mapping []nodeid)
    18  
    19  	// presolve is a hook for constraint-specific behaviour during
    20  	// pre-solver optimization.  Typical implementations mark as
    21  	// indirect the set of nodes to which the solver will add copy
    22  	// edges or PTS labels.
    23  	presolve(h *hvn)
    24  
    25  	// solve is called for complex constraints when the pts for
    26  	// the node to which they are attached has changed.
    27  	solve(a *analysis, delta *nodeset)
    28  
    29  	String() string
    30  }
    31  
    32  // dst = &src
    33  // pts(dst) ⊇ {src}
    34  // A base constraint used to initialize the solver's pt sets
    35  type addrConstraint struct {
    36  	dst nodeid // (ptr)
    37  	src nodeid
    38  }
    39  
    40  func (c *addrConstraint) ptr() nodeid { return c.dst }
    41  func (c *addrConstraint) renumber(mapping []nodeid) {
    42  	c.dst = mapping[c.dst]
    43  	c.src = mapping[c.src]
    44  }
    45  
    46  // dst = src
    47  // A simple constraint represented directly as a copyTo graph edge.
    48  type copyConstraint struct {
    49  	dst nodeid // (ptr)
    50  	src nodeid
    51  }
    52  
    53  func (c *copyConstraint) ptr() nodeid { return c.dst }
    54  func (c *copyConstraint) renumber(mapping []nodeid) {
    55  	c.dst = mapping[c.dst]
    56  	c.src = mapping[c.src]
    57  }
    58  
    59  // dst = src[offset]
    60  // A complex constraint attached to src (the pointer)
    61  type loadConstraint struct {
    62  	offset uint32
    63  	dst    nodeid
    64  	src    nodeid // (ptr)
    65  }
    66  
    67  func (c *loadConstraint) ptr() nodeid { return c.src }
    68  func (c *loadConstraint) renumber(mapping []nodeid) {
    69  	c.dst = mapping[c.dst]
    70  	c.src = mapping[c.src]
    71  }
    72  
    73  // dst[offset] = src
    74  // A complex constraint attached to dst (the pointer)
    75  type storeConstraint struct {
    76  	offset uint32
    77  	dst    nodeid // (ptr)
    78  	src    nodeid
    79  }
    80  
    81  func (c *storeConstraint) ptr() nodeid { return c.dst }
    82  func (c *storeConstraint) renumber(mapping []nodeid) {
    83  	c.dst = mapping[c.dst]
    84  	c.src = mapping[c.src]
    85  }
    86  
    87  // dst = &src.f  or  dst = &src[0]
    88  // A complex constraint attached to dst (the pointer)
    89  type offsetAddrConstraint struct {
    90  	offset uint32
    91  	dst    nodeid
    92  	src    nodeid // (ptr)
    93  }
    94  
    95  func (c *offsetAddrConstraint) ptr() nodeid { return c.src }
    96  func (c *offsetAddrConstraint) renumber(mapping []nodeid) {
    97  	c.dst = mapping[c.dst]
    98  	c.src = mapping[c.src]
    99  }
   100  
   101  // dst = src.(typ)  where typ is an interface
   102  // A complex constraint attached to src (the interface).
   103  // No representation change: pts(dst) and pts(src) contains tagged objects.
   104  type typeFilterConstraint struct {
   105  	typ types.Type // an interface type
   106  	dst nodeid
   107  	src nodeid // (ptr)
   108  }
   109  
   110  func (c *typeFilterConstraint) ptr() nodeid { return c.src }
   111  func (c *typeFilterConstraint) renumber(mapping []nodeid) {
   112  	c.dst = mapping[c.dst]
   113  	c.src = mapping[c.src]
   114  }
   115  
   116  // dst = src.(typ)  where typ is a concrete type
   117  // A complex constraint attached to src (the interface).
   118  //
   119  // If exact, only tagged objects identical to typ are untagged.
   120  // If !exact, tagged objects assignable to typ are untagged too.
   121  // The latter is needed for various reflect operators, e.g. Send.
   122  //
   123  // This entails a representation change:
   124  // pts(src) contains tagged objects,
   125  // pts(dst) contains their payloads.
   126  type untagConstraint struct {
   127  	typ   types.Type // a concrete type
   128  	dst   nodeid
   129  	src   nodeid // (ptr)
   130  	exact bool
   131  }
   132  
   133  func (c *untagConstraint) ptr() nodeid { return c.src }
   134  func (c *untagConstraint) renumber(mapping []nodeid) {
   135  	c.dst = mapping[c.dst]
   136  	c.src = mapping[c.src]
   137  }
   138  
   139  // src.method(params...)
   140  // A complex constraint attached to iface.
   141  type invokeConstraint struct {
   142  	method *types.Func // the abstract method
   143  	iface  nodeid      // (ptr) the interface
   144  	params nodeid      // the start of the identity/params/results block
   145  }
   146  
   147  func (c *invokeConstraint) ptr() nodeid { return c.iface }
   148  func (c *invokeConstraint) renumber(mapping []nodeid) {
   149  	c.iface = mapping[c.iface]
   150  	c.params = mapping[c.params]
   151  }