Together with teaching SSA to generate static data,
this fixes the encoding/pem and hash/adler32 tests.
Change-Id: I75f81f6c995dcb9c6d99bd3acda94a4feea8b87b
Reviewed-on: https://go-review.googlesource.com/12791
Reviewed-by: Keith Randall <khr@golang.org>
The existing backend recognizes special
assignment statements as being implementable
with static data rather than code.
Unfortunately, it assumes that it is in the middle
of codegen; it emits data and modifies the AST.
This does not play well with SSA's two-phase
bootstrapping approach, in which we attempt to
compile code but fall back to the existing backend
if something goes wrong.
To work around this:
* Add the ability to inquire about static data
without side-effects.
* Save the static data required for a function.
* Emit that static data during SSA codegen.
Change-Id: I2e8a506c866ea3e27dffb597095833c87f62d87e
Reviewed-on: https://go-review.googlesource.com/12790
Reviewed-by: Keith Randall <khr@golang.org>
For integer types less than a machine register, we have to decide
what the invariants are for the high bits of the register. We used
to set the high bits to the correct extension (sign or zero, as
determined by the type) of the low bits.
This CL makes the compiler ignore the high bits of the register
altogether (they are junk).
On this plus side, this means ops that generate subword results don't
have to worry about correctly extending them. On the minus side,
ops that consume subword arguments have to deal with the input
registers not being correctly extended.
For x86, this tradeoff is probably worth it. Almost all opcodes
have versions that use only the correct subword piece of their
inputs. (The one big exception is array indexing.) Not many opcodes
can correctly sign extend on output.
For other architectures, the tradeoff is probably not so clear, as
they don't have many subword-safe opcodes (e.g. 16-bit compare,
ignoring the high 16/48 bits). Fortunately we can decide whether
we do this per-architecture.
For the machine-independent opcodes, we pretend that the "register"
size is equal to the type width, so sign extension is immaterial.
Opcodes that care about the signedness of the input (e.g. compare,
right shift) have two different variants.
Change-Id: I465484c5734545ee697afe83bc8bf4b53bd9df8d
Reviewed-on: https://go-review.googlesource.com/12600
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
The only slice/interface comparisons that reach
the backend are comparisons to nil.
Funcs, maps, and channels are references types,
so pointer equality is enough.
Change-Id: I60a71da46a36202e9bd62ed370ab7d7f2e2800e7
Reviewed-on: https://go-review.googlesource.com/12715
Reviewed-by: Keith Randall <khr@golang.org>
Before this patch there was only partial support for ANDQconst
which was not lowered. This patch added support for AND operations
for all bit sizes and signs.
Change-Id: I3a6b2cddfac5361b27e85fcd97f7f3537ebfbcb6
Reviewed-on: https://go-review.googlesource.com/12761
Reviewed-by: Keith Randall <khr@golang.org>
This mimics the way the old backend
compiles OCALLMETH.
Change-Id: I635c8e7a48c8b5619bd837f78fa6eeba83a57b2f
Reviewed-on: https://go-review.googlesource.com/12549
Reviewed-by: Keith Randall <khr@golang.org>
Some of these were right; others weren't.
Fixes 'GOGC=off GOSSAPKG=mime go test -a mime'.
The right long term fix is probably to teach the
register allocator about in-place instructions.
In the meantime, all the tests that we can run
now pass.
Change-Id: I8e37b00a5f5e14f241b427d45d5f5cc1064883a2
Reviewed-on: https://go-review.googlesource.com/12664
Reviewed-by: Keith Randall <khr@golang.org>
Prior to this, we were smashing our own stack,
which caused the crypto/sha256 tests to fail.
Change-Id: I7dd94cf466d175b3be0cd65f9c4fe8b1223081fe
Reviewed-on: https://go-review.googlesource.com/12660
Reviewed-by: Daniel Morsing <daniel.morsing@gmail.com>
Reviewed-by: Keith Randall <khr@golang.org>
This prevents panics while attempting to generate code
for the runtime package. Now:
<unknown line number>: internal compiler error: localOffset of non-LocalSlot value: v10 = ADDQconst <*m> [256] v22
Change-Id: I20ed6ec6aae2c91183b8c826b8ebcc98e8ceebff
Reviewed-on: https://go-review.googlesource.com/12655
Reviewed-by: Keith Randall <khr@golang.org>
This generates more efficient code.
Before:
0x003a 00058 (rr.go:7) LEAQ go.string.hdr."="(SB), BX
0x0041 00065 (rr.go:7) LEAQ 16(BX), BP
0x0045 00069 (rr.go:7) MOVQ BP, 16(SP)
After:
0x003a 00058 (rr.go:7) LEAQ go.string."="(SB), BX
0x0041 00065 (rr.go:7) MOVQ BX, 16(SP)
It also matches the existing backend
and is more robust to other changes,
such as CL 11698, which I believe broke
the current code.
This CL fixes the encoding/base64 tests, as run with:
GOGC=off GOSSAPKG=base64 go test -a encoding/base64
Change-Id: I3c475bed1dd3335cc14e13309e11d23f0ed32c17
Reviewed-on: https://go-review.googlesource.com/12654
Reviewed-by: Keith Randall <khr@golang.org>
These temporary environment variables make it
possible to enable using SSA-generated code
for a particular function or package without
having to rebuild the compiler.
This makes it possible to start bulk testing
SSA generated code.
First, bump up the default stack size
(_StackMin in runtime/stack2.go) to something
large like 32768, because without stackmaps
we can't grow stacks.
Then run something like:
for pkg in `go list std`
do
GOGC=off GOSSAPKG=`basename $pkg` go test -a $pkg
done
When a test fails, you can re-run those tests,
selectively enabling one function after another,
until you find the one that is causing trouble.
Doing this right now yields some interesting results:
* There are several packages for which we generate
some code and whose tests pass. Yay!
* We can generate code for encoding/base64, but
tests there fail, so there's a bug to fix.
* Attempting to build the runtime yields a panic during codegen:
panic: interface conversion: ssa.Location is nil, not *ssa.LocalSlot
* The top unimplemented codegen items are (simplified):
59 genValue not implemented: REPMOVSB
18 genValue not implemented: REPSTOSQ
14 genValue not implemented: SUBQ
9 branch not implemented: If v -> b b. Control: XORQconst <bool> [1]
8 genValue not implemented: MOVQstoreidx8
4 branch not implemented: If v -> b b. Control: SETG <bool>
3 branch not implemented: If v -> b b. Control: SETLE <bool>
2 load flags not implemented: LoadReg8 <flags>
2 genValue not implemented: InvertFlags <flags>
1 store flags not implemented: StoreReg8 <flags>
1 branch not implemented: If v -> b b. Control: SETGE <bool>
Change-Id: Ib64809ac0c917e25bcae27829ae634c70d290c7f
Reviewed-on: https://go-review.googlesource.com/12547
Reviewed-by: Keith Randall <khr@golang.org>
Use width-and-signed-specific multiply opcodes.
Implement OMUL.
A few other cleanups.
Fixes#11467
Change-Id: Ib0fe80a1a9b7208dbb8a2b6b652a478847f5d244
Reviewed-on: https://go-review.googlesource.com/12540
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
Add label and goto checks and improve test coverage.
Implement OSWITCH and OSELECT.
Implement OBREAK and OCONTINUE.
Allow generation of code in dead blocks.
Change-Id: Ibebb7c98b4b2344f46d38db7c9dce058c56beaac
Reviewed-on: https://go-review.googlesource.com/12445
Reviewed-by: Keith Randall <khr@golang.org>
It is not clear to me what the right implementation is.
LoadReg8 and StoreReg8 are introduced during regalloc,
so after the amd64 rewrites. But implementing them
in genValue seems silly.
Change-Id: Ia708209c4604867bddcc0e5d75ecd17cf32f52c3
Reviewed-on: https://go-review.googlesource.com/12437
Reviewed-by: Keith Randall <khr@golang.org>
Bake the bit width and signedness into opcodes.
Pro: Rewrite rules become easier. Less chance for confusion.
Con: Lots more opcodes.
Let me know what you think. I'm leaning towards this, but I could be
convinced otherwise if people think this is too ugly.
Update #11467
Change-Id: Icf1b894268cdf73515877bb123839800d97b9df9
Reviewed-on: https://go-review.googlesource.com/12362
Reviewed-by: Alan Donovan <adonovan@google.com>
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
This will be used in a subsequent commit.
Change-Id: I43eca21f4692d99e164c9f6be0760597c46e6a26
Reviewed-on: https://go-review.googlesource.com/12440
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Keep track of the outargs size needed at each call.
Compute the size of the outargs section of the stack frame. It's just
the max of the outargs size at all the callsites in the function.
Change-Id: I3d0640f654f01307633b1a5f75bab16e211ea6c0
Reviewed-on: https://go-review.googlesource.com/12178
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
If we've already hit an Unimplemented, there may be important
SSA invariants that do not hold and which could cause
ssa.Compile to hang or spin.
While we're here, make detected dependency cycles stop execution.
Change-Id: Ic7d4eea659e1fe3f2c9b3e8a4eee5567494f46ad
Reviewed-on: https://go-review.googlesource.com/12310
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Implement ODOT. Similar to ArrayIndex, StructSelect selects a field
out of a larger Value.
We may need more ways to rewrite StructSelect, but StructSelect/Load
is the typical way it is used.
Change-Id: Ida7b8aab3298f4754eaf9fee733974cf8736e45d
Reviewed-on: https://go-review.googlesource.com/12265
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Joint hacking with josharian. Hints from matloob and Todd Neal.
Now with tests, and OROR.
Change-Id: Iff8826fde475691fb72a3eea7396a640b6274af9
Reviewed-on: https://go-review.googlesource.com/12041
Reviewed-by: Keith Randall <khr@golang.org>
An empty label statement can just be ignored, as it cannot
be the target of any gotos.
Tests are already in test/fixedbugs/issue7538*.go
Fixes#11589Fixes#11593
Change-Id: Iadcd639e7200ce16aa40fd7fa3eaf82522513e82
Reviewed-on: https://go-review.googlesource.com/12093
Reviewed-by: Daniel Morsing <daniel.morsing@gmail.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
And dependent fixes and misc cleanup.
Co-hacking with josharian at Gophercon.
Change-Id: Ib85dc13b303929017eb0a4d2fc2f603485f7479b
Reviewed-on: https://go-review.googlesource.com/12027
Reviewed-by: Keith Randall <khr@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
If an expression has an Ninit list, generate code for it.
Required for (at least) OANDAND.
Change-Id: I94c9e22e2a76955736f4a8e574d92711419c5e5c
Reviewed-on: https://go-review.googlesource.com/12072
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This is a prerequisite for implementing break and continue;
blocks ending in break or continue need to have
the increment block as a successor.
While we're here, implement for loops with no condition.
Change-Id: I85d8ba020628d805bfd0bd583dfd16e1be6f6fae
Reviewed-on: https://go-review.googlesource.com/11941
Reviewed-by: Keith Randall <khr@golang.org>
The removal of if false { ... } blocks in the opt
pass exposed that removePredecessor needed
to do more cleaning, on pain of failing later
consistency checks.
Change-Id: I45d4ff7e1f7f1486fdd99f867867ce6ea006a288
Reviewed-on: https://go-review.googlesource.com/11879
Reviewed-by: Keith Randall <khr@golang.org>
Loops such as
func f(c chan int) int {
for x := range c {
return x
}
return 0
}
don't loop. Remove the assumption that they must.
Partly fixes the build.
Change-Id: I766cebeec8e36d14512bea26f54c06c8eaf95e23
Reviewed-on: https://go-review.googlesource.com/11876
Reviewed-by: Keith Randall <khr@golang.org>
There is clearly work to do to fix labels and gotos.
The compiler currently hangs on ken/label.go.
For the moment, stop the bleeding.
Fixes the build.
Change-Id: Ib68360d583cf53e1a8ca4acff50644b570382728
Reviewed-on: https://go-review.googlesource.com/11877
Reviewed-by: Keith Randall <khr@golang.org>
Partly fixes the build, by punting.
Other things have broken in the meantime.
Change-Id: I1e2b8310057cbbbd9ffc501ef51e744690e00726
Reviewed-on: https://go-review.googlesource.com/11875
Reviewed-by: Keith Randall <khr@golang.org>