本文整理匯總了Golang中cmd/compile/internal/gc.Flowend函數的典型用法代碼示例。如果您正苦於以下問題:Golang Flowend函數的具體用法?Golang Flowend怎麽用?Golang Flowend使用的例子?那麽, 這裏精選的函數代碼示例或許可以為您提供幫助。
在下文中一共展示了Flowend函數的7個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的Golang代碼示例。
示例1: peep
func peep(firstp *obj.Prog) {
g := gc.Flowstart(firstp, nil)
if g == nil {
return
}
gactive = 0
run := func(name string, pass func(r *gc.Flow) int) int {
n := pass(g.Start)
if gc.Debug['P'] != 0 {
fmt.Println(name, ":", n)
}
if gc.Debug['P'] != 0 && gc.Debug['v'] != 0 {
gc.Dumpit(name, g.Start, 0)
}
return n
}
for {
n := 0
n += run("constant propagation", constantPropagation)
n += run("copy propagation", copyPropagation)
n += run("cast propagation", castPropagation)
n += run("remove load-hit-stores", removeLoadHitStores)
n += run("dead code elimination", deadCodeElimination)
if n == 0 {
break
}
}
run("fuse op moves", fuseOpMoves)
run("fuse clears", fuseClear)
run("load pipelining", loadPipelining)
run("fuse compare branch", fuseCompareBranch)
run("simplify ops", simplifyOps)
run("dead code elimination", deadCodeElimination)
// TODO(mundaym): load/store multiple aren't currently handled by copyu
// so this pass must be last.
run("fuse multiple", fuseMultiple)
gc.Flowend(g)
}
示例2: peep
//.........這裏部分代碼省略.........
p.From.Type = obj.TYPE_REG
if p.Reg != 0 {
p.From.Reg = p.Reg
} else {
p.From.Reg = p.To.Reg
}
p.Reg = 0
}
}
}
for r := (*gc.Flow)(g.Start); r != nil; r = r.Link {
p = r.Prog
switch p.As {
case arm.AMOVW,
arm.AMOVB,
arm.AMOVBS,
arm.AMOVBU:
if p.From.Type == obj.TYPE_MEM && p.From.Offset == 0 {
xtramodes(g, r, &p.From)
} else if p.To.Type == obj.TYPE_MEM && p.To.Offset == 0 {
xtramodes(g, r, &p.To)
} else {
continue
}
}
}
// case ACMP:
// /*
// * elide CMP $0,x if calculation of x can set condition codes
// */
// if(isdconst(&p->from) || p->from.offset != 0)
// continue;
// r2 = r->s1;
// if(r2 == nil)
// continue;
// t = r2->prog->as;
// switch(t) {
// default:
// continue;
// case ABEQ:
// case ABNE:
// case ABMI:
// case ABPL:
// break;
// case ABGE:
// t = ABPL;
// break;
// case ABLT:
// t = ABMI;
// break;
// case ABHI:
// t = ABNE;
// break;
// case ABLS:
// t = ABEQ;
// break;
// }
// r1 = r;
// do
// r1 = uniqp(r1);
// while (r1 != nil && r1->prog->as == ANOP);
// if(r1 == nil)
// continue;
// p1 = r1->prog;
// if(p1->to.type != TYPE_REG)
// continue;
// if(p1->to.reg != p->reg)
// if(!(p1->as == AMOVW && p1->from.type == TYPE_REG && p1->from.reg == p->reg))
// continue;
//
// switch(p1->as) {
// default:
// continue;
// case AMOVW:
// if(p1->from.type != TYPE_REG)
// continue;
// case AAND:
// case AEOR:
// case AORR:
// case ABIC:
// case AMVN:
// case ASUB:
// case ARSB:
// case AADD:
// case AADC:
// case ASBC:
// case ARSC:
// break;
// }
// p1->scond |= C_SBIT;
// r2->prog->as = t;
// excise(r);
// continue;
// predicate(g);
gc.Flowend(g)
}
示例3: peep
//.........這裏部分代碼省略.........
if p.From.Offset == 1 {
if p.As == x86.AADDQ {
p.As = x86.AINCQ
} else if p.As == x86.AADDL {
p.As = x86.AINCL
} else {
p.As = x86.AINCW
}
p.From = obj.Addr{}
break
}
case x86.ASUBL,
x86.ASUBQ,
x86.ASUBW:
if p.From.Type != obj.TYPE_CONST || needc(p.Link) {
break
}
if p.From.Offset == -1 {
if p.As == x86.ASUBQ {
p.As = x86.AINCQ
} else if p.As == x86.ASUBL {
p.As = x86.AINCL
} else {
p.As = x86.AINCW
}
p.From = obj.Addr{}
break
}
if p.From.Offset == 1 {
if p.As == x86.ASUBQ {
p.As = x86.ADECQ
} else if p.As == x86.ASUBL {
p.As = x86.ADECL
} else {
p.As = x86.ADECW
}
p.From = obj.Addr{}
break
}
}
}
if t != 0 {
goto loop1
}
// MOVLQZX removal.
// The MOVLQZX exists to avoid being confused for a
// MOVL that is just copying 32-bit data around during
// copyprop. Now that copyprop is done, remov MOVLQZX R1, R2
// if it is dominated by an earlier ADDL/MOVL/etc into R1 that
// will have already cleared the high bits.
//
// MOVSD removal.
// We never use packed registers, so a MOVSD between registers
// can be replaced by MOVAPD, which moves the pair of float64s
// instead of just the lower one. We only use the lower one, but
// the processor can do better if we do moves using both.
for r := (*gc.Flow)(g.Start); r != nil; r = r.Link {
p = r.Prog
if p.As == x86.AMOVLQZX {
if regtyp(&p.From) {
if p.From.Type == p.To.Type && p.From.Reg == p.To.Reg {
if prevl(r, int(p.From.Reg)) {
excise(r)
}
}
}
}
if p.As == x86.AMOVSD {
if regtyp(&p.From) {
if regtyp(&p.To) {
p.As = x86.AMOVAPD
}
}
}
}
// load pipelining
// push any load from memory as early as possible
// to give it time to complete before use.
for r := (*gc.Flow)(g.Start); r != nil; r = r.Link {
p = r.Prog
switch p.As {
case x86.AMOVB,
x86.AMOVW,
x86.AMOVL,
x86.AMOVQ,
x86.AMOVLQZX:
if regtyp(&p.To) && !regconsttyp(&p.From) {
pushback(r)
}
}
}
gc.Flowend(g)
}
示例4: peep
//.........這裏部分代碼省略.........
}
gactive = 0
var p *obj.Prog
var r *gc.Flow
var t int
loop1:
if gc.Debug['P'] != 0 && gc.Debug['v'] != 0 {
gc.Dumpit("loop1", g.Start, 0)
}
t = 0
for r = g.Start; r != nil; r = r.Link {
p = r.Prog
// TODO(austin) Handle smaller moves. arm and amd64
// distinguish between moves that moves that *must*
// sign/zero extend and moves that don't care so they
// can eliminate moves that don't care without
// breaking moves that do care. This might let us
// simplify or remove the next peep loop, too.
if p.As == mips.AMOVV || p.As == mips.AMOVF || p.As == mips.AMOVD {
if regtyp(&p.To) {
// Try to eliminate reg->reg moves
if regtyp(&p.From) {
if isfreg(&p.From) == isfreg(&p.To) {
if copyprop(r) {
excise(r)
t++
} else if subprop(r) && copyprop(r) {
excise(r)
t++
}
}
}
// Convert uses to $0 to uses of R0 and
// propagate R0
if regzer(&p.From) != 0 {
if p.To.Type == obj.TYPE_REG && !isfreg(&p.To) {
p.From.Type = obj.TYPE_REG
p.From.Reg = mips.REGZERO
if copyprop(r) {
excise(r)
t++
} else if subprop(r) && copyprop(r) {
excise(r)
t++
}
}
}
}
}
}
if t != 0 {
goto loop1
}
/*
* look for MOVB x,R; MOVB R,R (for small MOVs not handled above)
*/
var p1 *obj.Prog
var r1 *gc.Flow
for r := (*gc.Flow)(g.Start); r != nil; r = r.Link {
p = r.Prog
switch p.As {
default:
continue
case mips.AMOVH,
mips.AMOVHU,
mips.AMOVB,
mips.AMOVBU,
mips.AMOVW,
mips.AMOVWU:
if p.To.Type != obj.TYPE_REG {
continue
}
}
r1 = r.Link
if r1 == nil {
continue
}
p1 = r1.Prog
if p1.As != p.As {
continue
}
if p1.From.Type != obj.TYPE_REG || p1.From.Reg != p.To.Reg {
continue
}
if p1.To.Type != obj.TYPE_REG || p1.To.Reg != p.To.Reg {
continue
}
excise(r1)
}
gc.Flowend(g)
}
示例5: peep
//.........這裏部分代碼省略.........
if regtyp(&p.From) {
if copyprop(g, r) {
excise(r)
t++
} else if subprop(r) && copyprop(g, r) {
excise(r)
t++
}
}
}
case x86.AMOVBLZX,
x86.AMOVWLZX,
x86.AMOVBLSX,
x86.AMOVWLSX:
if regtyp(&p.To) {
r1 = rnops(gc.Uniqs(r))
if r1 != nil {
p1 = r1.Prog
if p.As == p1.As && p.To.Type == p1.From.Type && p.To.Reg == p1.From.Reg {
p1.As = x86.AMOVL
t++
}
}
}
case x86.AADDL,
x86.AADDW:
if p.From.Type != obj.TYPE_CONST || needc(p.Link) {
break
}
if p.From.Offset == -1 {
if p.As == x86.AADDL {
p.As = x86.ADECL
} else {
p.As = x86.ADECW
}
p.From = obj.Addr{}
break
}
if p.From.Offset == 1 {
if p.As == x86.AADDL {
p.As = x86.AINCL
} else {
p.As = x86.AINCW
}
p.From = obj.Addr{}
break
}
case x86.ASUBL,
x86.ASUBW:
if p.From.Type != obj.TYPE_CONST || needc(p.Link) {
break
}
if p.From.Offset == -1 {
if p.As == x86.ASUBL {
p.As = x86.AINCL
} else {
p.As = x86.AINCW
}
p.From = obj.Addr{}
break
}
if p.From.Offset == 1 {
if p.As == x86.ASUBL {
p.As = x86.ADECL
} else {
p.As = x86.ADECW
}
p.From = obj.Addr{}
break
}
}
}
if t != 0 {
goto loop1
}
// MOVSD removal.
// We never use packed registers, so a MOVSD between registers
// can be replaced by MOVAPD, which moves the pair of float64s
// instead of just the lower one. We only use the lower one, but
// the processor can do better if we do moves using both.
for r := g.Start; r != nil; r = r.Link {
p = r.Prog
if p.As == x86.AMOVSD {
if regtyp(&p.From) {
if regtyp(&p.To) {
p.As = x86.AMOVAPD
}
}
}
}
gc.Flowend(g)
}
示例6: peep
//.........這裏部分代碼省略.........
}
}
}
}
if t != 0 {
goto loop1
}
/*
* look for MOVB x,R; MOVB R,R (for small MOVs not handled above)
*/
var p1 *obj.Prog
var r1 *gc.Flow
for r := g.Start; r != nil; r = r.Link {
p = r.Prog
switch p.As {
default:
continue
case arm64.AMOVH,
arm64.AMOVHU,
arm64.AMOVB,
arm64.AMOVBU,
arm64.AMOVW,
arm64.AMOVWU:
if p.To.Type != obj.TYPE_REG {
continue
}
}
r1 = r.Link
if r1 == nil {
continue
}
p1 = r1.Prog
if p1.As != p.As {
continue
}
if p1.From.Type != obj.TYPE_REG || p1.From.Reg != p.To.Reg {
continue
}
if p1.To.Type != obj.TYPE_REG || p1.To.Reg != p.To.Reg {
continue
}
excise(r1)
}
if gc.Debug['D'] > 1 {
goto ret /* allow following code improvement to be suppressed */
}
// MOVD $c, R'; ADD R', R (R' unused) -> ADD $c, R
for r := g.Start; r != nil; r = r.Link {
p = r.Prog
switch p.As {
default:
continue
case arm64.AMOVD:
if p.To.Type != obj.TYPE_REG {
continue
}
if p.From.Type != obj.TYPE_CONST {
continue
}
if p.From.Offset < 0 || 4096 <= p.From.Offset {
continue
}
}
r1 = r.Link
if r1 == nil {
continue
}
p1 = r1.Prog
if p1.As != arm64.AADD && p1.As != arm64.ASUB { // TODO(aram): also logical after we have bimm.
continue
}
if p1.From.Type != obj.TYPE_REG || p1.From.Reg != p.To.Reg {
continue
}
if p1.To.Type != obj.TYPE_REG {
continue
}
if gc.Debug['P'] != 0 {
fmt.Printf("encoding $%d directly into %v in:\n%v\n%v\n", p.From.Offset, obj.Aconv(p1.As), p, p1)
}
p1.From.Type = obj.TYPE_CONST
p1.From = p.From
excise(r)
}
/* TODO(minux):
* look for OP x,y,R; CMP R, $0 -> OP.S x,y,R
* when OP can set condition codes correctly
*/
ret:
gc.Flowend(g)
}
示例7: peep
//.........這裏部分代碼省略.........
continue
}
p1 = r1.Prog
switch p.As {
case s390x.ACMP:
switch p1.As {
case s390x.ABCL, s390x.ABC:
continue
case s390x.ABEQ:
t = s390x.ACMPBEQ
case s390x.ABGE:
t = s390x.ACMPBGE
case s390x.ABGT:
t = s390x.ACMPBGT
case s390x.ABLE:
t = s390x.ACMPBLE
case s390x.ABLT:
t = s390x.ACMPBLT
case s390x.ABNE:
t = s390x.ACMPBNE
default:
continue
}
case s390x.ACMPU:
switch p1.As {
case s390x.ABCL, s390x.ABC:
continue
case s390x.ABEQ:
t = s390x.ACMPUBEQ
case s390x.ABGE:
t = s390x.ACMPUBGE
case s390x.ABGT:
t = s390x.ACMPUBGT
case s390x.ABLE:
t = s390x.ACMPUBLE
case s390x.ABLT:
t = s390x.ACMPUBLT
case s390x.ABNE:
t = s390x.ACMPUBNE
default:
continue
}
case s390x.ACMPW, s390x.ACMPWU:
continue
default:
continue
}
if gc.Debug['D'] != 0 {
fmt.Printf("cnb %v; %v -> ", p, p1)
}
if p1.To.Sym != nil {
continue
}
if p.To.Type == obj.TYPE_REG {
p1.As = int16(t)
p1.From = p.From
p1.Reg = p.To.Reg
p1.From3 = nil
} else if p.To.Type == obj.TYPE_CONST {
switch p.As {
case s390x.ACMP, s390x.ACMPW:
if (p.To.Offset < -(1 << 7)) || (p.To.Offset >= ((1 << 7) - 1)) {
continue
}
case s390x.ACMPU, s390x.ACMPWU:
if p.To.Offset >= (1 << 8) {
continue
}
default:
}
p1.As = int16(t)
p1.From = p.From
p1.Reg = 0
p1.From3 = new(obj.Addr)
*(p1.From3) = p.To
} else {
continue
}
if gc.Debug['D'] != 0 {
fmt.Printf("%v\n", p1)
}
cnb_cnt += 1
excise(r)
}
if gc.Debug['v'] != 0 {
gc.Dumpit("compare and branch", g.Start, 0)
}
ret:
gc.Flowend(g)
}