Skip to content

Commit

Permalink
go/ir: add SliceToArrayPointer op
Browse files Browse the repository at this point in the history
This is a backport of golang.org/cl/333749 and golang.org/cl/348511.

Updates gh-1045
  • Loading branch information
cuonglm committed Sep 11, 2021
1 parent ff8ab87 commit e1f24e8
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 64 deletions.
2 changes: 1 addition & 1 deletion go/ir/UPSTREAM
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ The changes are too many to list here, and it is best to consider this package i
Upstream changes still get applied when they address bugs in portions of code we have inherited.

The last upstream commit we've looked at was:
640c1dea83015e5271a001c99370762fc63dc280
915f6209478fe61eb90dbe155a8a1c58655b931f

99 changes: 50 additions & 49 deletions go/ir/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,55 +49,56 @@
// concrete type which of these interfaces it implements.
//
// Value? Instruction? Member?
// *Alloc ✔ ✔
// *BinOp ✔ ✔
// *BlankStore ✔
// *Builtin ✔
// *Call ✔ ✔
// *ChangeInterface ✔ ✔
// *ChangeType ✔ ✔
// *Const ✔ ✔
// *Convert ✔ ✔
// *DebugRef ✔
// *Defer ✔ ✔
// *Extract ✔ ✔
// *Field ✔ ✔
// *FieldAddr ✔ ✔
// *FreeVar ✔
// *Function ✔ ✔ (func)
// *Global ✔ ✔ (var)
// *Go ✔ ✔
// *If ✔
// *Index ✔ ✔
// *IndexAddr ✔ ✔
// *Jump ✔
// *Load ✔ ✔
// *MakeChan ✔ ✔
// *MakeClosure ✔ ✔
// *MakeInterface ✔ ✔
// *MakeMap ✔ ✔
// *MakeSlice ✔ ✔
// *MapLookup ✔ ✔
// *MapUpdate ✔ ✔
// *NamedConst ✔ (const)
// *Next ✔ ✔
// *Panic ✔
// *Parameter ✔ ✔
// *Phi ✔ ✔
// *Range ✔ ✔
// *Recv ✔ ✔
// *Return ✔
// *RunDefers ✔
// *Select ✔ ✔
// *Send ✔ ✔
// *Sigma ✔ ✔
// *Slice ✔ ✔
// *Store ✔ ✔
// *StringLookup ✔ ✔
// *Type ✔ (type)
// *TypeAssert ✔ ✔
// *UnOp ✔ ✔
// *Unreachable ✔
// *Alloc ✔ ✔
// *BinOp ✔ ✔
// *BlankStore ✔
// *Builtin ✔
// *Call ✔ ✔
// *ChangeInterface ✔ ✔
// *ChangeType ✔ ✔
// *Const ✔ ✔
// *Convert ✔ ✔
// *DebugRef ✔
// *Defer ✔ ✔
// *Extract ✔ ✔
// *Field ✔ ✔
// *FieldAddr ✔ ✔
// *FreeVar ✔
// *Function ✔ ✔ (func)
// *Global ✔ ✔ (var)
// *Go ✔ ✔
// *If ✔
// *Index ✔ ✔
// *IndexAddr ✔ ✔
// *Jump ✔
// *Load ✔ ✔
// *MakeChan ✔ ✔
// *MakeClosure ✔ ✔
// *MakeInterface ✔ ✔
// *MakeMap ✔ ✔
// *MakeSlice ✔ ✔
// *MapLookup ✔ ✔
// *MapUpdate ✔ ✔
// *NamedConst ✔ (const)
// *Next ✔ ✔
// *Panic ✔
// *Parameter ✔ ✔
// *Phi ✔ ✔
// *Range ✔ ✔
// *Recv ✔ ✔
// *Return ✔
// *RunDefers ✔
// *Select ✔ ✔
// *Send ✔ ✔
// *Sigma ✔ ✔
// *Slice ✔ ✔
// *SliceToArrayPointer ✔ ✔
// *Store ✔ ✔
// *StringLookup ✔ ✔
// *Type ✔ (type)
// *TypeAssert ✔ ✔
// *UnOp ✔ ✔
// *Unreachable ✔
//
// Other key types in this package include: Program, Package, Function
// and BasicBlock.
Expand Down
4 changes: 2 additions & 2 deletions go/ir/emit.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,8 +239,8 @@ func emitConv(f *Function, val Value, typ types.Type, source ast.Node) Value {
// Conversion from slice to array pointer?
if slice, ok := ut_src.(*types.Slice); ok {
if ptr, ok := ut_dst.(*types.Pointer); ok {
if arr, ok := ptr.Elem().(*types.Array); ok && types.Identical(slice.Elem(), arr.Elem()) {
c := &Convert{X: val}
if arr, ok := ptr.Elem().Underlying().(*types.Array); ok && types.Identical(slice.Elem(), arr.Elem()) {
c := &SliceToArrayPointer{X: val}
c.setType(ut_dst)
return f.emit(c, source)
}
Expand Down
9 changes: 5 additions & 4 deletions go/ir/print.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,10 +162,11 @@ func printConv(prefix string, v, x Value) string {
relName(x, v.(Instruction)))
}

func (v *ChangeType) String() string { return printConv("ChangeType", v, v.X) }
func (v *Convert) String() string { return printConv("Convert", v, v.X) }
func (v *ChangeInterface) String() string { return printConv("ChangeInterface", v, v.X) }
func (v *MakeInterface) String() string { return printConv("MakeInterface", v, v.X) }
func (v *ChangeType) String() string { return printConv("ChangeType", v, v.X) }
func (v *Convert) String() string { return printConv("Convert", v, v.X) }
func (v *ChangeInterface) String() string { return printConv("ChangeInterface", v, v.X) }
func (v *SliceToArrayPointer) String() string { return printConv("slice to array pointer", v, v.X) }
func (v *MakeInterface) String() string { return printConv("MakeInterface", v, v.X) }

func (v *MakeClosure) String() string {
from := v.Parent().pkg()
Expand Down
8 changes: 1 addition & 7 deletions go/ir/sanity.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,14 +141,8 @@ func (s *sanity) checkInstr(idx int, instr Instruction) {
case *Call:
case *ChangeInterface:
case *ChangeType:
case *SliceToArrayPointer:
case *Convert:
if _, ok := instr.X.Type().Underlying().(*types.Slice); ok {
if ptr, ok := instr.Type().Underlying().(*types.Pointer); ok {
if _, ok := ptr.Elem().(*types.Array); ok {
break
}
}
}
if _, ok := instr.X.Type().Underlying().(*types.Basic); !ok {
if _, ok := instr.Type().Underlying().(*types.Basic); !ok {
s.errorf("convert %s -> %s: at least one type must be basic", instr.X.Type(), instr.Type())
Expand Down
21 changes: 20 additions & 1 deletion go/ir/ssa.go
Original file line number Diff line number Diff line change
Expand Up @@ -729,9 +729,10 @@ type ChangeType struct {
// - between pointers and unsafe.Pointer.
// - between unsafe.Pointer and uintptr.
// - from (Unicode) integer to (UTF-8) string.
// - from slice to array pointer.
// A conversion may imply a type name change also.
//
// This operation cannot fail dynamically.
//
// Conversions of untyped string/number/bool constants to a specific
// representation are eliminated during IR construction.
//
Expand Down Expand Up @@ -763,6 +764,20 @@ type ChangeInterface struct {
X Value
}

// The SliceToArrayPointer instruction yields the conversion of slice X to
// array pointer.
//
// Pos() returns the ast.CallExpr.Lparen, if the instruction arose
// from an explicit conversion in the source.
//
// Example printed form:
// t1 = slice to array pointer *[4]byte <- []byte (t0)
//
type SliceToArrayPointer struct {
register
X Value
}

// MakeInterface constructs an instance of an interface type from a
// value of a concrete type.
//
Expand Down Expand Up @@ -1731,6 +1746,10 @@ func (v *Convert) Operands(rands []*Value) []*Value {
return append(rands, &v.X)
}

func (v *SliceToArrayPointer) Operands(rands []*Value) []*Value {
return append(rands, &v.X)
}

func (s *DebugRef) Operands(rands []*Value) []*Value {
return append(rands, &s.X)
}
Expand Down

0 comments on commit e1f24e8

Please sign in to comment.