Skip to content

Commit b72bbae

Browse files
committed
cmd/compile: expand calls cleanup
Convert expand calls into a smaller number of focused recursive rewrites, and rely on an enhanced version of "decompose" to clean up afterwards. Debugging information seems to emerge intact. Change-Id: Ic46da4207e3a4da5c8e2c47b637b0e35abbe56bb Reviewed-on: https://go-review.googlesource.com/c/go/+/507295 Run-TryBot: David Chase <[email protected]> Reviewed-by: Cherry Mui <[email protected]> Reviewed-by: Keith Randall <[email protected]> TryBot-Result: Gopher Robot <[email protected]>
1 parent 8b6e0e6 commit b72bbae

File tree

10 files changed

+1639
-1608
lines changed

10 files changed

+1639
-1608
lines changed

src/cmd/compile/internal/ssa/_gen/dec.rules

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,109 @@
9191
(OffPtr <typ.BytePtrPtr> [config.PtrSize] dst)
9292
data
9393
(Store {typ.Uintptr} dst itab mem))
94+
95+
// Helpers for expand calls
96+
// Some of these are copied from generic.rules
97+
98+
(IMake _typ (StructMake1 val)) => (IMake _typ val)
99+
(StructSelect [0] (IData x)) => (IData x)
100+
101+
(StructSelect (StructMake1 x)) => x
102+
(StructSelect [0] (StructMake2 x _)) => x
103+
(StructSelect [1] (StructMake2 _ x)) => x
104+
(StructSelect [0] (StructMake3 x _ _)) => x
105+
(StructSelect [1] (StructMake3 _ x _)) => x
106+
(StructSelect [2] (StructMake3 _ _ x)) => x
107+
(StructSelect [0] (StructMake4 x _ _ _)) => x
108+
(StructSelect [1] (StructMake4 _ x _ _)) => x
109+
(StructSelect [2] (StructMake4 _ _ x _)) => x
110+
(StructSelect [3] (StructMake4 _ _ _ x)) => x
111+
112+
// Special case coming from immediate interface rewriting
113+
// Typical case: (StructSelect [0] (IData (IMake typ dat)) rewrites to (StructSelect [0] dat)
114+
// but because the interface is immediate, the type of "IData" is a one-element struct containing
115+
// a pointer that is not the pointer type of dat (can be a *uint8).
116+
// More annoying case: (ArraySelect[0] (StructSelect[0] isAPtr))
117+
// There, result of the StructSelect is an Array (not a pointer) and
118+
// the pre-rewrite input to the ArraySelect is a struct, not a pointer.
119+
(StructSelect [0] x) && x.Type.IsPtr() => x
120+
(ArraySelect [0] x) && x.Type.IsPtr() => x
121+
122+
// These, too. Bits is bits.
123+
(ArrayMake1 x) && x.Type.IsPtr() => x
124+
(StructMake1 x) && x.Type.IsPtr() => x
125+
126+
(Store dst (StructMake1 <t> f0) mem) =>
127+
(Store {t.FieldType(0)} (OffPtr <t.FieldType(0).PtrTo()> [0] dst) f0 mem)
128+
(Store dst (StructMake2 <t> f0 f1) mem) =>
129+
(Store {t.FieldType(1)}
130+
(OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] dst)
131+
f1
132+
(Store {t.FieldType(0)}
133+
(OffPtr <t.FieldType(0).PtrTo()> [0] dst)
134+
f0 mem))
135+
(Store dst (StructMake3 <t> f0 f1 f2) mem) =>
136+
(Store {t.FieldType(2)}
137+
(OffPtr <t.FieldType(2).PtrTo()> [t.FieldOff(2)] dst)
138+
f2
139+
(Store {t.FieldType(1)}
140+
(OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] dst)
141+
f1
142+
(Store {t.FieldType(0)}
143+
(OffPtr <t.FieldType(0).PtrTo()> [0] dst)
144+
f0 mem)))
145+
(Store dst (StructMake4 <t> f0 f1 f2 f3) mem) =>
146+
(Store {t.FieldType(3)}
147+
(OffPtr <t.FieldType(3).PtrTo()> [t.FieldOff(3)] dst)
148+
f3
149+
(Store {t.FieldType(2)}
150+
(OffPtr <t.FieldType(2).PtrTo()> [t.FieldOff(2)] dst)
151+
f2
152+
(Store {t.FieldType(1)}
153+
(OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] dst)
154+
f1
155+
(Store {t.FieldType(0)}
156+
(OffPtr <t.FieldType(0).PtrTo()> [0] dst)
157+
f0 mem))))
158+
159+
(ArraySelect (ArrayMake1 x)) => x
160+
(ArraySelect [0] (IData x)) => (IData x)
161+
162+
(Store dst (ArrayMake1 e) mem) => (Store {e.Type} dst e mem)
163+
164+
// NOTE removed must-not-be-SSA condition.
165+
(ArraySelect [i] x:(Load <t> ptr mem)) =>
166+
@x.Block (Load <v.Type> (OffPtr <v.Type.PtrTo()> [t.Elem().Size()*i] ptr) mem)
167+
168+
(StringPtr x:(Load <t> ptr mem)) && t.IsString() => @x.Block (Load <typ.BytePtr> ptr mem)
169+
(StringLen x:(Load <t> ptr mem)) && t.IsString() => @x.Block (Load <typ.Int>
170+
(OffPtr <typ.IntPtr> [config.PtrSize] ptr)
171+
mem)
172+
173+
// NOTE removed must-not-be-SSA condition.
174+
(StructSelect [i] x:(Load <t> ptr mem)) =>
175+
@x.Block (Load <v.Type> (OffPtr <v.Type.PtrTo()> [t.FieldOff(int(i))] ptr) mem)
176+
177+
(ITab x:(Load <t> ptr mem)) && t.IsInterface() => @x.Block (Load <typ.Uintptr> ptr mem)
178+
179+
(IData x:(Load <t> ptr mem)) && t.IsInterface() => @x.Block (Load <typ.BytePtr>
180+
(OffPtr <typ.BytePtrPtr> [config.PtrSize] ptr)
181+
mem)
182+
183+
(SlicePtr x:(Load <t> ptr mem)) && t.IsSlice() => @x.Block (Load <t.Elem().PtrTo()> ptr mem)
184+
(SliceLen x:(Load <t> ptr mem)) && t.IsSlice() => @x.Block (Load <typ.Int>
185+
(OffPtr <typ.IntPtr> [config.PtrSize] ptr)
186+
mem)
187+
(SliceCap x:(Load <t> ptr mem)) && t.IsSlice() => @x.Block (Load <typ.Int>
188+
(OffPtr <typ.IntPtr> [2*config.PtrSize] ptr)
189+
mem)
190+
191+
(ComplexReal x:(Load <t> ptr mem)) && t.IsComplex() && t.Size() == 8 => @x.Block (Load <typ.Float32> ptr mem)
192+
(ComplexImag x:(Load <t> ptr mem)) && t.IsComplex() && t.Size() == 8 => @x.Block (Load <typ.Float32>
193+
(OffPtr <typ.Float32Ptr> [4] ptr)
194+
mem)
195+
196+
(ComplexReal x:(Load <t> ptr mem)) && t.IsComplex() && t.Size() == 16 => @x.Block (Load <typ.Float64> ptr mem)
197+
(ComplexImag x:(Load <t> ptr mem)) && t.IsComplex() && t.Size() == 16 => @x.Block (Load <typ.Float64>
198+
(OffPtr <typ.Float64Ptr> [8] ptr)
199+
mem)

src/cmd/compile/internal/ssa/compile.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -472,8 +472,8 @@ var passes = [...]pass{
472472
{name: "nilcheckelim", fn: nilcheckelim},
473473
{name: "prove", fn: prove},
474474
{name: "early fuse", fn: fuseEarly},
475-
{name: "decompose builtin", fn: decomposeBuiltIn, required: true},
476475
{name: "expand calls", fn: expandCalls, required: true},
476+
{name: "decompose builtin", fn: postExpandCallsDecompose, required: true},
477477
{name: "softfloat", fn: softfloat, required: true},
478478
{name: "late opt", fn: opt, required: true}, // TODO: split required rules and optimizing rules
479479
{name: "dead auto elim", fn: elimDeadAutosGeneric},
@@ -547,6 +547,8 @@ var passOrder = [...]constraint{
547547
{"generic cse", "tighten"},
548548
// checkbce needs the values removed
549549
{"generic deadcode", "check bce"},
550+
// decompose builtin now also cleans up after expand calls
551+
{"expand calls", "decompose builtin"},
550552
// don't run optimization pass until we've decomposed builtin objects
551553
{"decompose builtin", "late opt"},
552554
// decompose builtin is the last pass that may introduce new float ops, so run softfloat after it

0 commit comments

Comments
 (0)