mirror of
https://github.com/golang/go
synced 2024-10-04 08:21:22 -06:00
51b72d94de
benchmark old ns/op new ns/op delta BenchmarkCopyFat512 1307 329 -74.83% BenchmarkCopyFat256 666 169 -74.62% BenchmarkCopyFat1024 2617 671 -74.36% BenchmarkCopyFat128 343 89.0 -74.05% BenchmarkCopyFat64 182 48.9 -73.13% BenchmarkCopyFat32 103 28.8 -72.04% BenchmarkClearFat128 102 46.6 -54.31% BenchmarkClearFat512 344 167 -51.45% BenchmarkClearFat64 50.5 26.5 -47.52% BenchmarkClearFat256 147 87.2 -40.68% BenchmarkClearFat32 22.7 16.4 -27.75% BenchmarkClearFat1024 511 662 +29.55% Fixes #7624 LGTM=rsc R=golang-codereviews, khr, bradfitz, josharian, dave, rsc CC=golang-codereviews https://golang.org/cl/92760044
152 lines
4.9 KiB
C
152 lines
4.9 KiB
C
// Copyright 2013 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
#include <u.h>
|
|
#include <libc.h>
|
|
#include "gg.h"
|
|
#include "opt.h"
|
|
|
|
enum
|
|
{
|
|
RightRdwr = RightRead | RightWrite,
|
|
};
|
|
|
|
// This table gives the basic information about instruction
|
|
// generated by the compiler and processed in the optimizer.
|
|
// See opt.h for bit definitions.
|
|
//
|
|
// Instructions not generated need not be listed.
|
|
// As an exception to that rule, we typically write down all the
|
|
// size variants of an operation even if we just use a subset.
|
|
//
|
|
// The table is formatted for 8-space tabs.
|
|
static ProgInfo progtable[ALAST] = {
|
|
[ATYPE]= {Pseudo | Skip},
|
|
[ATEXT]= {Pseudo},
|
|
[AFUNCDATA]= {Pseudo},
|
|
[APCDATA]= {Pseudo},
|
|
[AUNDEF]= {Break},
|
|
[AUSEFIELD]= {OK},
|
|
[ACHECKNIL]= {LeftRead},
|
|
[AVARDEF]= {Pseudo | RightWrite},
|
|
[AVARKILL]= {Pseudo | RightWrite},
|
|
|
|
// NOP is an internal no-op that also stands
|
|
// for USED and SET annotations, not the Intel opcode.
|
|
[ANOP]= {LeftRead | RightWrite},
|
|
|
|
// Integer.
|
|
[AADC]= {SizeL | LeftRead | RegRead | RightWrite},
|
|
[AADD]= {SizeL | LeftRead | RegRead | RightWrite},
|
|
[AAND]= {SizeL | LeftRead | RegRead | RightWrite},
|
|
[ABIC]= {SizeL | LeftRead | RegRead | RightWrite},
|
|
[ACMN]= {SizeL | LeftRead | RightRead},
|
|
[ACMP]= {SizeL | LeftRead | RightRead},
|
|
[ADIVU]= {SizeL | LeftRead | RegRead | RightWrite},
|
|
[ADIV]= {SizeL | LeftRead | RegRead | RightWrite},
|
|
[AEOR]= {SizeL | LeftRead | RegRead | RightWrite},
|
|
[AMODU]= {SizeL | LeftRead | RegRead | RightWrite},
|
|
[AMOD]= {SizeL | LeftRead | RegRead | RightWrite},
|
|
[AMULALU]= {SizeL | LeftRead | RegRead | RightRdwr},
|
|
[AMULAL]= {SizeL | LeftRead | RegRead | RightRdwr},
|
|
[AMULA]= {SizeL | LeftRead | RegRead | RightRdwr},
|
|
[AMULU]= {SizeL | LeftRead | RegRead | RightWrite},
|
|
[AMUL]= {SizeL | LeftRead | RegRead | RightWrite},
|
|
[AMULL]= {SizeL | LeftRead | RegRead | RightWrite},
|
|
[AMULLU]= {SizeL | LeftRead | RegRead | RightWrite},
|
|
[AMVN]= {SizeL | LeftRead | RightWrite},
|
|
[AORR]= {SizeL | LeftRead | RegRead | RightWrite},
|
|
[ARSB]= {SizeL | LeftRead | RegRead | RightWrite},
|
|
[ARSC]= {SizeL | LeftRead | RegRead | RightWrite},
|
|
[ASBC]= {SizeL | LeftRead | RegRead | RightWrite},
|
|
[ASLL]= {SizeL | LeftRead | RegRead | RightWrite},
|
|
[ASRA]= {SizeL | LeftRead | RegRead | RightWrite},
|
|
[ASRL]= {SizeL | LeftRead | RegRead | RightWrite},
|
|
[ASUB]= {SizeL | LeftRead | RegRead | RightWrite},
|
|
[ATEQ]= {SizeL | LeftRead | RightRead},
|
|
[ATST]= {SizeL | LeftRead | RightRead},
|
|
|
|
// Floating point.
|
|
[AADDD]= {SizeD | LeftRead | RightRdwr},
|
|
[AADDF]= {SizeF | LeftRead | RightRdwr},
|
|
[ACMPD]= {SizeD | LeftRead | RightRead},
|
|
[ACMPF]= {SizeF | LeftRead | RightRead},
|
|
[ADIVD]= {SizeD | LeftRead | RightRdwr},
|
|
[ADIVF]= {SizeF | LeftRead | RightRdwr},
|
|
[AMULD]= {SizeD | LeftRead | RightRdwr},
|
|
[AMULF]= {SizeF | LeftRead | RightRdwr},
|
|
[ASUBD]= {SizeD | LeftRead | RightRdwr},
|
|
[ASUBF]= {SizeF | LeftRead | RightRdwr},
|
|
|
|
// Conversions.
|
|
[AMOVWD]= {SizeD | LeftRead | RightWrite | Conv},
|
|
[AMOVWF]= {SizeF | LeftRead | RightWrite | Conv},
|
|
[AMOVDF]= {SizeF | LeftRead | RightWrite | Conv},
|
|
[AMOVDW]= {SizeL | LeftRead | RightWrite | Conv},
|
|
[AMOVFD]= {SizeD | LeftRead | RightWrite | Conv},
|
|
[AMOVFW]= {SizeL | LeftRead | RightWrite | Conv},
|
|
|
|
// Moves.
|
|
[AMOVB]= {SizeB | LeftRead | RightWrite | Move},
|
|
[AMOVD]= {SizeD | LeftRead | RightWrite | Move},
|
|
[AMOVF]= {SizeF | LeftRead | RightWrite | Move},
|
|
[AMOVH]= {SizeW | LeftRead | RightWrite | Move},
|
|
[AMOVW]= {SizeL | LeftRead | RightWrite | Move},
|
|
// In addtion, duffzero reads R0,R1 and writes R1. This fact is
|
|
// encoded in peep.c
|
|
[ADUFFZERO]= {Call},
|
|
// In addtion, duffcopy reads R1,R2 and writes R0,R1,R2. This fact is
|
|
// encoded in peep.c
|
|
[ADUFFCOPY]= {Call},
|
|
|
|
// These should be split into the two different conversions instead
|
|
// of overloading the one.
|
|
[AMOVBS]= {SizeB | LeftRead | RightWrite | Conv},
|
|
[AMOVBU]= {SizeB | LeftRead | RightWrite | Conv},
|
|
[AMOVHS]= {SizeW | LeftRead | RightWrite | Conv},
|
|
[AMOVHU]= {SizeW | LeftRead | RightWrite | Conv},
|
|
|
|
// Jumps.
|
|
[AB]= {Jump | Break},
|
|
[ABL]= {Call},
|
|
[ABEQ]= {Cjmp},
|
|
[ABNE]= {Cjmp},
|
|
[ABCS]= {Cjmp},
|
|
[ABHS]= {Cjmp},
|
|
[ABCC]= {Cjmp},
|
|
[ABLO]= {Cjmp},
|
|
[ABMI]= {Cjmp},
|
|
[ABPL]= {Cjmp},
|
|
[ABVS]= {Cjmp},
|
|
[ABVC]= {Cjmp},
|
|
[ABHI]= {Cjmp},
|
|
[ABLS]= {Cjmp},
|
|
[ABGE]= {Cjmp},
|
|
[ABLT]= {Cjmp},
|
|
[ABGT]= {Cjmp},
|
|
[ABLE]= {Cjmp},
|
|
[ARET]= {Break},
|
|
};
|
|
|
|
void
|
|
proginfo(ProgInfo *info, Prog *p)
|
|
{
|
|
*info = progtable[p->as];
|
|
if(info->flags == 0)
|
|
fatal("unknown instruction %P", p);
|
|
|
|
if(p->from.type == D_CONST && p->from.sym != nil && (info->flags & LeftRead)) {
|
|
info->flags &= ~LeftRead;
|
|
info->flags |= LeftAddr;
|
|
}
|
|
|
|
if((info->flags & RegRead) && p->reg == NREG) {
|
|
info->flags &= ~RegRead;
|
|
info->flags |= CanRegRead | RightRead;
|
|
}
|
|
|
|
if(((p->scond & C_SCOND) != C_SCOND_NONE) && (info->flags & RightWrite))
|
|
info->flags |= RightRead;
|
|
}
|