當前位置: 首頁>>代碼示例>>Golang>>正文


Golang gc.Uniqp函數代碼示例

本文整理匯總了Golang中cmd/compile/internal/gc.Uniqp函數的典型用法代碼示例。如果您正苦於以下問題:Golang Uniqp函數的具體用法?Golang Uniqp怎麽用?Golang Uniqp使用的例子?那麽, 這裏精選的函數代碼示例或許可以為您提供幫助。


在下文中一共展示了Uniqp函數的15個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的Golang代碼示例。

示例1: copyprop

// The idea is to remove redundant copies.
//     v1->v2  F=0
//     (use v2 s/v2/v1/)*
//     set v1  F=1
//     use v2  return fail (v1->v2 move must remain)
//     -----------------
//     v1->v2  F=0
//     (use v2 s/v2/v1/)*
//     set v1  F=1
//     set v2  return success (caller can remove v1->v2 move)
func copyprop(r *gc.Flow) bool {
	p := r.Prog

	canSub := false
	switch p.As {
	case s390x.AFMOVS, s390x.AFMOVD, s390x.AMOVD:
		canSub = true
	default:
		for rr := gc.Uniqp(r); rr != nil; rr = gc.Uniqp(rr) {
			if gc.Uniqs(rr) == nil {
				break
			}
			switch copyu(rr.Prog, &p.From, nil) {
			case _Read, _None:
				continue
			}
			// write
			if rr.Prog.As == p.As {
				canSub = true
			}
			break
		}
	}
	if !canSub {
		return false
	}
	if copyas(&p.From, &p.To) {
		return true
	}

	gactive++
	return copy1(&p.From, &p.To, r.S1, 0)
}
開發者ID:hurkgu,項目名稱:go,代碼行數:43,代碼來源:peep.go

示例2: subprop

// the idea is to substitute
// one register for another
// from one MOV to another
//	MOV	a, R1
//	ADD	b, R1	/ no use of R2
//	MOV	R1, R2
// would be converted to
//	MOV	a, R2
//	ADD	b, R2
//	MOV	R2, R1
// hopefully, then the former or latter MOV
// will be eliminated by copy propagation.
//
// r0 (the argument, not the register) is the MOV at the end of the
// above sequences. subprop returns true if it modified any instructions.
func subprop(r0 *gc.Flow) bool {
	p := r0.Prog
	v1 := &p.From
	if !isReg(v1) {
		return false
	}
	v2 := &p.To
	if !isReg(v2) {
		return false
	}
	cast := false
	switch p.As {
	case s390x.AMOVW, s390x.AMOVWZ,
		s390x.AMOVH, s390x.AMOVHZ,
		s390x.AMOVB, s390x.AMOVBZ:
		cast = true
	}
	for r := gc.Uniqp(r0); r != nil; r = gc.Uniqp(r) {
		if gc.Uniqs(r) == nil {
			break
		}
		p = r.Prog
		switch copyu(p, v1, nil) {
		case _Write, _ReadWriteDiff:
			if p.As == obj.ACALL {
				return false
			}
			if (!cast || p.As == r0.Prog.As) && p.To.Type == v1.Type && p.To.Reg == v1.Reg {
				copysub(&p.To, v1, v2)
				for r = gc.Uniqs(r); r != r0; r = gc.Uniqs(r) {
					p = r.Prog
					copysub(&p.From, v1, v2)
					copysub1(p, v1, v2)
					copysub(&p.To, v1, v2)
				}
				v1.Reg, v2.Reg = v2.Reg, v1.Reg
				return true
			}
			if cast {
				return false
			}
		case _ReadWriteSame:
			if cast {
				return false
			}
		}
		if copyu(p, v2, nil) != _None {
			return false
		}
	}
	return false
}
開發者ID:hurkgu,項目名稱:go,代碼行數:67,代碼來源:peep.go

示例3: prevl

// is reg guaranteed to be truncated by a previous L instruction?
func prevl(r0 *gc.Flow, reg int16) bool {
	for r := gc.Uniqp(r0); r != nil; r = gc.Uniqp(r) {
		p := r.Prog
		if p.To.Type == obj.TYPE_REG && p.To.Reg == reg {
			flags := progflags(p)
			if flags&gc.RightWrite != 0 {
				if flags&gc.SizeL != 0 {
					return true
				}
				return false
			}
		}
	}
	return false
}
開發者ID:2thetop,項目名稱:go,代碼行數:16,代碼來源:peep.go

示例4: removeLoadHitStores

// removeLoadHitStores trys to remove loads that take place
// immediately after a store to the same location. Returns
// true if load-hit-stores were removed.
//
// For example:
// 	MOVD	R1, 0(R15)
// 	MOVD	0(R15), R2
// Would become:
// 	MOVD	R1, 0(R15)
// 	MOVD	R1, R2
func removeLoadHitStores(r *gc.Flow) int {
	n := 0
	for ; r != nil; r = r.Link {
		p := r.Prog
		if !isStore(p) {
			continue
		}
		for rr := gc.Uniqs(r); rr != nil; rr = gc.Uniqs(rr) {
			pp := rr.Prog
			if gc.Uniqp(rr) == nil {
				break
			}
			if pp.As == obj.ANOP {
				continue
			}
			if isLoad(pp) && sameStackMem(&p.To, &pp.From) {
				if size(p.As) >= size(pp.As) && isGPR(&p.From) == isGPR(&pp.To) {
					pp.From = p.From
				}
			}
			if !isMove(pp) || isStore(pp) {
				break
			}
			if copyau(&p.From, &pp.To) {
				break
			}
		}
	}
	return n
}
開發者ID:hurkgu,項目名稱:go,代碼行數:40,代碼來源:peep.go

示例5: findinc

/*
 * findinc finds ADD instructions with a constant
 * argument which falls within the immed_12 range.
 */
func findinc(r *gc.Flow, r2 *gc.Flow, v *obj.Addr) *gc.Flow {
	var r1 *gc.Flow
	var p *obj.Prog

	for r1 = gc.Uniqs(r); r1 != nil && r1 != r2; r, r1 = r1, gc.Uniqs(r1) {
		if gc.Uniqp(r1) != r {
			return nil
		}
		switch copyu(r1.Prog, v, nil) {
		case 0: /* not touched */
			continue

		case 4: /* set and used */
			p = r1.Prog

			if p.As == arm.AADD {
				if isdconst(&p.From) {
					if p.From.Offset > -4096 && p.From.Offset < 4096 {
						return r1
					}
				}
			}
			fallthrough

		default:
			return nil
		}
	}

	return nil
}
開發者ID:xiezerozero,項目名稱:go,代碼行數:35,代碼來源:peep.go

示例6: findpre

/*
 * findpre returns the last instruction mentioning v
 * before r. It must be a set, and there must be
 * a unique path from that instruction to r.
 */
func findpre(r *gc.Flow, v *obj.Addr) *gc.Flow {
	var r1 *gc.Flow

	for r1 = gc.Uniqp(r); r1 != nil; r, r1 = r1, gc.Uniqp(r1) {
		if gc.Uniqs(r1) != r {
			return nil
		}
		switch copyu(r1.Prog, v, nil) {
		case 1, /* used */
			2: /* read-alter-rewrite */
			return nil

		case 3, /* set */
			4: /* set and used */
			return r1
		}
	}

	return nil
}
開發者ID:xiezerozero,項目名稱:go,代碼行數:25,代碼來源:peep.go

示例7: conprop

func conprop(r0 *gc.Flow) {
	var p *obj.Prog
	var t int

	p0 := (*obj.Prog)(r0.Prog)
	v0 := (*obj.Addr)(&p0.To)
	r := (*gc.Flow)(r0)

loop:
	r = gc.Uniqs(r)
	if r == nil || r == r0 {
		return
	}
	if gc.Uniqp(r) == nil {
		return
	}

	p = r.Prog
	t = copyu(p, v0, nil)
	switch t {
	case 0, // miss
		1: // use
		goto loop

	case 2, // rar
		4: // use and set
		break

	case 3: // set
		if p.As == p0.As {
			if p.From.Type == p0.From.Type {
				if p.From.Reg == p0.From.Reg {
					if p.From.Node == p0.From.Node {
						if p.From.Offset == p0.From.Offset {
							if p.From.Scale == p0.From.Scale {
								if p.From.Type == obj.TYPE_FCONST && p.From.Val.(float64) == p0.From.Val.(float64) {
									if p.From.Index == p0.From.Index {
										excise(r)
										goto loop
									}
								}
							}
						}
					}
				}
			}
		}
	}
}
開發者ID:danny8002,項目名稱:go,代碼行數:49,代碼來源:peep.go

示例8: copy1

// copy1 replaces uses of v2 with v1 starting at r and returns true if
// all uses were rewritten.
func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool {
	if uint32(r.Active) == gactive {
		return true
	}
	r.Active = int32(gactive)
	for ; r != nil; r = r.S1 {
		p := r.Prog
		if f == 0 && gc.Uniqp(r) == nil {
			// Multiple predecessors; conservatively
			// assume v1 was set on other path
			f = 1
		}
		t := copyu(p, v2, nil)
		switch t {
		case _ReadWriteSame:
			return false
		case _Write:
			return true
		case _Read, _ReadWriteDiff:
			if f != 0 {
				return false
			}
			if copyu(p, v2, v1) != 0 {
				return false
			}
			if t == _ReadWriteDiff {
				return true
			}
		}
		if f == 0 {
			switch copyu(p, v1, nil) {
			case _ReadWriteSame, _ReadWriteDiff, _Write:
				f = 1
			}
		}
		if r.S2 != nil {
			if !copy1(v1, v2, r.S2, f) {
				return false
			}
		}
	}
	return true
}
開發者ID:hurkgu,項目名稱:go,代碼行數:45,代碼來源:peep.go

示例9: constprop

/*
 * The idea is to remove redundant constants.
 *	$c1->v1
 *	($c1->v2 s/$c1/v1)*
 *	set v1  return
 * The v1->v2 should be eliminated by copy propagation.
 */
func constprop(c1 *obj.Addr, v1 *obj.Addr, r *gc.Flow) {
	if gc.Debug['P'] != 0 {
		fmt.Printf("constprop %v->%v\n", gc.Ctxt.Dconv(c1), gc.Ctxt.Dconv(v1))
	}
	var p *obj.Prog
	for ; r != nil; r = r.S1 {
		p = r.Prog
		if gc.Debug['P'] != 0 {
			fmt.Printf("%v", p)
		}
		if gc.Uniqp(r) == nil {
			if gc.Debug['P'] != 0 {
				fmt.Printf("; merge; return\n")
			}
			return
		}

		if p.As == arm.AMOVW && copyas(&p.From, c1) {
			if gc.Debug['P'] != 0 {
				fmt.Printf("; sub%v/%v", gc.Ctxt.Dconv(&p.From), gc.Ctxt.Dconv(v1))
			}
			p.From = *v1
		} else if copyu(p, v1, nil) > 1 {
			if gc.Debug['P'] != 0 {
				fmt.Printf("; %vset; return\n", gc.Ctxt.Dconv(v1))
			}
			return
		}

		if gc.Debug['P'] != 0 {
			fmt.Printf("\n")
		}
		if r.S2 != nil {
			constprop(c1, v1, r.S2)
		}
	}
}
開發者ID:xiezerozero,項目名稱:go,代碼行數:44,代碼來源:peep.go

示例10: subprop

/*
 * the idea is to substitute
 * one register for another
 * from one MOV to another
 *	MOV	a, R0
 *	ADD	b, R0	/ no use of R1
 *	MOV	R0, R1
 * would be converted to
 *	MOV	a, R1
 *	ADD	b, R1
 *	MOV	R1, R0
 * hopefully, then the former or latter MOV
 * will be eliminated by copy propagation.
 */
func subprop(r0 *gc.Flow) bool {
	p := r0.Prog
	v1 := &p.From
	if !regtyp(v1) {
		return false
	}
	v2 := &p.To
	if !regtyp(v2) {
		return false
	}
	for r := gc.Uniqp(r0); r != nil; r = gc.Uniqp(r) {
		if gc.Debug['P'] != 0 && gc.Debug['v'] != 0 {
			fmt.Printf("\t? %v\n", r.Prog)
		}
		if gc.Uniqs(r) == nil {
			break
		}
		p = r.Prog
		if p.As == obj.AVARDEF || p.As == obj.AVARKILL {
			continue
		}
		if p.Info.Flags&gc.Call != 0 {
			return false
		}

		if p.Info.Reguse|p.Info.Regset != 0 {
			return false
		}

		if (p.Info.Flags&gc.Move != 0) && (p.Info.Flags&(gc.SizeL|gc.SizeQ|gc.SizeF|gc.SizeD) != 0) && p.To.Type == v1.Type && p.To.Reg == v1.Reg {
			copysub(&p.To, v1, v2, 1)
			if gc.Debug['P'] != 0 {
				fmt.Printf("gotit: %v->%v\n%v", gc.Ctxt.Dconv(v1), gc.Ctxt.Dconv(v2), r.Prog)
				if p.From.Type == v2.Type && p.From.Reg == v2.Reg {
					fmt.Printf(" excise")
				}
				fmt.Printf("\n")
			}

			for r = gc.Uniqs(r); r != r0; r = gc.Uniqs(r) {
				p = r.Prog
				copysub(&p.From, v1, v2, 1)
				copysub(&p.To, v1, v2, 1)
				if gc.Debug['P'] != 0 {
					fmt.Printf("%v\n", r.Prog)
				}
			}

			t := int(v1.Reg)
			v1.Reg = v2.Reg
			v2.Reg = int16(t)
			if gc.Debug['P'] != 0 {
				fmt.Printf("%v last\n", r.Prog)
			}
			return true
		}

		if copyau(&p.From, v2) || copyau(&p.To, v2) {
			break
		}
		if copysub(&p.From, v1, v2, 0) != 0 || copysub(&p.To, v1, v2, 0) != 0 {
			break
		}
	}

	return false
}
開發者ID:sreis,項目名稱:go,代碼行數:81,代碼來源:peep.go

示例11: shiftprop

/*
 * ASLL x,y,w
 * .. (not use w, not set x y w)
 * AXXX w,a,b (a != w)
 * .. (not use w)
 * (set w)
 * ----------- changed to
 * ..
 * AXXX (x<<y),a,b
 * ..
 */
func shiftprop(r *gc.Flow) bool {
	p := (*obj.Prog)(r.Prog)
	if p.To.Type != obj.TYPE_REG {
		if gc.Debug['P'] != 0 {
			fmt.Printf("\tBOTCH: result not reg; FAILURE\n")
		}
		return false
	}

	n := int(int(p.To.Reg))
	a := obj.Addr(obj.Addr{})
	if p.Reg != 0 && p.Reg != p.To.Reg {
		a.Type = obj.TYPE_REG
		a.Reg = p.Reg
	}

	if gc.Debug['P'] != 0 {
		fmt.Printf("shiftprop\n%v", p)
	}
	r1 := (*gc.Flow)(r)
	var p1 *obj.Prog
	for {
		/* find first use of shift result; abort if shift operands or result are changed */
		r1 = gc.Uniqs(r1)

		if r1 == nil {
			if gc.Debug['P'] != 0 {
				fmt.Printf("\tbranch; FAILURE\n")
			}
			return false
		}

		if gc.Uniqp(r1) == nil {
			if gc.Debug['P'] != 0 {
				fmt.Printf("\tmerge; FAILURE\n")
			}
			return false
		}

		p1 = r1.Prog
		if gc.Debug['P'] != 0 {
			fmt.Printf("\n%v", p1)
		}
		switch copyu(p1, &p.To, nil) {
		case 0: /* not used or set */
			if (p.From.Type == obj.TYPE_REG && copyu(p1, &p.From, nil) > 1) || (a.Type == obj.TYPE_REG && copyu(p1, &a, nil) > 1) {
				if gc.Debug['P'] != 0 {
					fmt.Printf("\targs modified; FAILURE\n")
				}
				return false
			}

			continue
		case 3: /* set, not used */
			{
				if gc.Debug['P'] != 0 {
					fmt.Printf("\tBOTCH: noref; FAILURE\n")
				}
				return false
			}
		}

		break
	}

	/* check whether substitution can be done */
	switch p1.As {
	default:
		if gc.Debug['P'] != 0 {
			fmt.Printf("\tnon-dpi; FAILURE\n")
		}
		return false

	case arm.AAND,
		arm.AEOR,
		arm.AADD,
		arm.AADC,
		arm.AORR,
		arm.ASUB,
		arm.ASBC,
		arm.ARSB,
		arm.ARSC:
		if int(p1.Reg) == n || (p1.Reg == 0 && p1.To.Type == obj.TYPE_REG && int(p1.To.Reg) == n) {
			if p1.From.Type != obj.TYPE_REG {
				if gc.Debug['P'] != 0 {
					fmt.Printf("\tcan't swap; FAILURE\n")
				}
				return false
			}
//.........這裏部分代碼省略.........
開發者ID:xiezerozero,項目名稱:go,代碼行數:101,代碼來源:peep.go

示例12: copy1

func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool {
	if uint32(r.Active) == gactive {
		if gc.Debug['P'] != 0 {
			fmt.Printf("act set; return 1\n")
		}
		return true
	}

	r.Active = int32(gactive)
	if gc.Debug['P'] != 0 {
		fmt.Printf("copy %v->%v f=%d\n", gc.Ctxt.Dconv(v1), gc.Ctxt.Dconv(v2), f)
	}
	var t int
	var p *obj.Prog
	for ; r != nil; r = r.S1 {
		p = r.Prog
		if gc.Debug['P'] != 0 {
			fmt.Printf("%v", p)
		}
		if f == 0 && gc.Uniqp(r) == nil {
			f = 1
			if gc.Debug['P'] != 0 {
				fmt.Printf("; merge; f=%d", f)
			}
		}

		t = copyu(p, v2, nil)
		switch t {
		case 2: /* rar, can't split */
			if gc.Debug['P'] != 0 {
				fmt.Printf("; %vrar; return 0\n", gc.Ctxt.Dconv(v2))
			}
			return false

		case 3: /* set */
			if gc.Debug['P'] != 0 {
				fmt.Printf("; %vset; return 1\n", gc.Ctxt.Dconv(v2))
			}
			return true

		case 1, /* used, substitute */
			4: /* use and set */
			if f != 0 {
				if gc.Debug['P'] == 0 {
					return false
				}
				if t == 4 {
					fmt.Printf("; %vused+set and f=%d; return 0\n", gc.Ctxt.Dconv(v2), f)
				} else {
					fmt.Printf("; %vused and f=%d; return 0\n", gc.Ctxt.Dconv(v2), f)
				}
				return false
			}

			if copyu(p, v2, v1) != 0 {
				if gc.Debug['P'] != 0 {
					fmt.Printf("; sub fail; return 0\n")
				}
				return false
			}

			if gc.Debug['P'] != 0 {
				fmt.Printf("; sub%v/%v", gc.Ctxt.Dconv(v2), gc.Ctxt.Dconv(v1))
			}
			if t == 4 {
				if gc.Debug['P'] != 0 {
					fmt.Printf("; %vused+set; return 1\n", gc.Ctxt.Dconv(v2))
				}
				return true
			}
		}

		if f == 0 {
			t = copyu(p, v1, nil)
			if f == 0 && (t == 2 || t == 3 || t == 4) {
				f = 1
				if gc.Debug['P'] != 0 {
					fmt.Printf("; %vset and !f; f=%d", gc.Ctxt.Dconv(v1), f)
				}
			}
		}

		if gc.Debug['P'] != 0 {
			fmt.Printf("\n")
		}
		if r.S2 != nil {
			if !copy1(v1, v2, r.S2, f) {
				return false
			}
		}
	}

	return true
}
開發者ID:xiezerozero,項目名稱:go,代碼行數:94,代碼來源:peep.go

示例13: subprop

/*
 * the idea is to substitute
 * one register for another
 * from one MOV to another
 *	MOV	a, R0
 *	ADD	b, R0	/ no use of R1
 *	MOV	R0, R1
 * would be converted to
 *	MOV	a, R1
 *	ADD	b, R1
 *	MOV	R1, R0
 * hopefully, then the former or latter MOV
 * will be eliminated by copy propagation.
 */
func subprop(r0 *gc.Flow) bool {
	p := (*obj.Prog)(r0.Prog)
	v1 := (*obj.Addr)(&p.From)
	if !regtyp(v1) {
		return false
	}
	v2 := (*obj.Addr)(&p.To)
	if !regtyp(v2) {
		return false
	}
	for r := gc.Uniqp(r0); r != nil; r = gc.Uniqp(r) {
		if gc.Uniqs(r) == nil {
			break
		}
		p = r.Prog
		if p.As == obj.AVARDEF || p.As == obj.AVARKILL {
			continue
		}
		if p.Info.Flags&gc.Call != 0 {
			return false
		}

		// TODO(rsc): Whatever invalidated the info should have done this call.
		proginfo(p)

		if (p.Info.Flags&gc.CanRegRead != 0) && p.To.Type == obj.TYPE_REG {
			p.Info.Flags |= gc.RegRead
			p.Info.Flags &^= (gc.CanRegRead | gc.RightRead)
			p.Reg = p.To.Reg
		}

		switch p.As {
		case arm.AMULLU,
			arm.AMULA,
			arm.AMVN:
			return false
		}

		if p.Info.Flags&(gc.RightRead|gc.RightWrite) == gc.RightWrite {
			if p.To.Type == v1.Type {
				if p.To.Reg == v1.Reg {
					if p.Scond == arm.C_SCOND_NONE {
						copysub(&p.To, v1, v2, 1)
						if gc.Debug['P'] != 0 {
							fmt.Printf("gotit: %v->%v\n%v", gc.Ctxt.Dconv(v1), gc.Ctxt.Dconv(v2), r.Prog)
							if p.From.Type == v2.Type {
								fmt.Printf(" excise")
							}
							fmt.Printf("\n")
						}

						for r = gc.Uniqs(r); r != r0; r = gc.Uniqs(r) {
							p = r.Prog
							copysub(&p.From, v1, v2, 1)
							copysub1(p, v1, v2, 1)
							copysub(&p.To, v1, v2, 1)
							if gc.Debug['P'] != 0 {
								fmt.Printf("%v\n", r.Prog)
							}
						}

						t := int(int(v1.Reg))
						v1.Reg = v2.Reg
						v2.Reg = int16(t)
						if gc.Debug['P'] != 0 {
							fmt.Printf("%v last\n", r.Prog)
						}
						return true
					}
				}
			}
		}

		if copyau(&p.From, v2) || copyau1(p, v2) || copyau(&p.To, v2) {
			break
		}
		if copysub(&p.From, v1, v2, 0) != 0 || copysub1(p, v1, v2, 0) != 0 || copysub(&p.To, v1, v2, 0) != 0 {
			break
		}
	}

	return false
}
開發者ID:xiezerozero,項目名稱:go,代碼行數:97,代碼來源:peep.go

示例14: subprop

/*
 * the idea is to substitute
 * one register for another
 * from one MOV to another
 *	MOV	a, R0
 *	ADD	b, R0	/ no use of R1
 *	MOV	R0, R1
 * would be converted to
 *	MOV	a, R1
 *	ADD	b, R1
 *	MOV	R1, R0
 * hopefully, then the former or latter MOV
 * will be eliminated by copy propagation.
 */
func subprop(r0 *gc.Flow) bool {
	if gc.Debug['P'] != 0 && gc.Debug['v'] != 0 {
		fmt.Printf("subprop %v\n", r0.Prog)
	}
	p := (*obj.Prog)(r0.Prog)
	v1 := (*obj.Addr)(&p.From)
	if !regtyp(v1) {
		if gc.Debug['P'] != 0 && gc.Debug['v'] != 0 {
			fmt.Printf("\tnot regtype %v; return 0\n", gc.Ctxt.Dconv(v1))
		}
		return false
	}

	v2 := (*obj.Addr)(&p.To)
	if !regtyp(v2) {
		if gc.Debug['P'] != 0 && gc.Debug['v'] != 0 {
			fmt.Printf("\tnot regtype %v; return 0\n", gc.Ctxt.Dconv(v2))
		}
		return false
	}

	for r := gc.Uniqp(r0); r != nil; r = gc.Uniqp(r) {
		if gc.Debug['P'] != 0 && gc.Debug['v'] != 0 {
			fmt.Printf("\t? %v\n", r.Prog)
		}
		if gc.Uniqs(r) == nil {
			if gc.Debug['P'] != 0 && gc.Debug['v'] != 0 {
				fmt.Printf("\tno unique successor\n")
			}
			break
		}

		p = r.Prog
		if p.As == obj.AVARDEF || p.As == obj.AVARKILL {
			continue
		}
		if p.Info.Flags&gc.Call != 0 {
			if gc.Debug['P'] != 0 && gc.Debug['v'] != 0 {
				fmt.Printf("\tfound %v; return 0\n", p)
			}
			return false
		}

		if p.Info.Reguse|p.Info.Regset != 0 {
			if gc.Debug['P'] != 0 && gc.Debug['v'] != 0 {
				fmt.Printf("\tfound %v; return 0\n", p)
			}
			return false
		}

		if (p.Info.Flags&gc.Move != 0) && (p.Info.Flags&(gc.SizeL|gc.SizeQ|gc.SizeF|gc.SizeD) != 0) && p.To.Type == v1.Type && p.To.Reg == v1.Reg {
			copysub(&p.To, v1, v2, 1)
			if gc.Debug['P'] != 0 {
				fmt.Printf("gotit: %v->%v\n%v", gc.Ctxt.Dconv(v1), gc.Ctxt.Dconv(v2), r.Prog)
				if p.From.Type == v2.Type && p.From.Reg == v2.Reg {
					fmt.Printf(" excise")
				}
				fmt.Printf("\n")
			}

			for r = gc.Uniqs(r); r != r0; r = gc.Uniqs(r) {
				p = r.Prog
				copysub(&p.From, v1, v2, 1)
				copysub(&p.To, v1, v2, 1)
				if gc.Debug['P'] != 0 {
					fmt.Printf("%v\n", r.Prog)
				}
			}

			t := int(int(v1.Reg))
			v1.Reg = v2.Reg
			v2.Reg = int16(t)
			if gc.Debug['P'] != 0 {
				fmt.Printf("%v last\n", r.Prog)
			}
			return true
		}

		if copyau(&p.From, v2) || copyau(&p.To, v2) {
			if gc.Debug['P'] != 0 && gc.Debug['v'] != 0 {
				fmt.Printf("\tcopyau %v failed\n", gc.Ctxt.Dconv(v2))
			}
			break
		}

		if copysub(&p.From, v1, v2, 0) != 0 || copysub(&p.To, v1, v2, 0) != 0 {
//.........這裏部分代碼省略.........
開發者ID:danny8002,項目名稱:go,代碼行數:101,代碼來源:peep.go

示例15: fuseMultiple

// fuseMultiple merges memory loads and stores into load multiple and
// store multiple operations.
//
// Looks for this pattern (sequence of loads or stores):
// 	MOVD	R1, 0(R15)
//	MOVD	R2, 8(R15)
//	MOVD	R3, 16(R15)
// Replaces with:
//	STMG	R1, R3, 0(R15)
func fuseMultiple(r *gc.Flow) int {
	n := 0
	var fused *obj.Prog
	for ; r != nil; r = r.Link {
		// If there is a branch into the instruction stream then
		// we can't fuse into previous instructions.
		if gc.Uniqp(r) == nil {
			fused = nil
		}

		p := r.Prog

		isStore := isGPR(&p.From) && isBDMem(&p.To)
		isLoad := isGPR(&p.To) && isBDMem(&p.From)

		// are we a candidate?
		size := int64(0)
		switch p.As {
		default:
			fused = nil
			continue
		case obj.ANOP:
			// skip over nops
			continue
		case s390x.AMOVW, s390x.AMOVWZ:
			size = 4
			// TODO(mundaym): 32-bit load multiple is currently not supported
			// as it requires sign/zero extension.
			if !isStore {
				fused = nil
				continue
			}
		case s390x.AMOVD:
			size = 8
			if !isLoad && !isStore {
				fused = nil
				continue
			}
		}

		// If we merge two loads/stores with different source/destination Nodes
		// then we will lose a reference the second Node which means that the
		// compiler might mark the Node as unused and free its slot on the stack.
		// TODO(mundaym): allow this by adding a dummy reference to the Node.
		if fused == nil ||
			fused.From.Node != p.From.Node ||
			fused.From.Type != p.From.Type ||
			fused.To.Node != p.To.Node ||
			fused.To.Type != p.To.Type {
			fused = p
			continue
		}

		// check two addresses
		ca := func(a, b *obj.Addr, offset int64) bool {
			return a.Reg == b.Reg && a.Offset+offset == b.Offset &&
				a.Sym == b.Sym && a.Name == b.Name
		}

		switch fused.As {
		default:
			fused = p
		case s390x.AMOVW, s390x.AMOVWZ:
			if size == 4 && fused.From.Reg+1 == p.From.Reg && ca(&fused.To, &p.To, 4) {
				fused.As = s390x.ASTMY
				fused.Reg = p.From.Reg
				excise(r)
				n++
			} else {
				fused = p
			}
		case s390x.AMOVD:
			if size == 8 && fused.From.Reg+1 == p.From.Reg && ca(&fused.To, &p.To, 8) {
				fused.As = s390x.ASTMG
				fused.Reg = p.From.Reg
				excise(r)
				n++
			} else if size == 8 && fused.To.Reg+1 == p.To.Reg && ca(&fused.From, &p.From, 8) {
				fused.As = s390x.ALMG
				fused.Reg = fused.To.Reg
				fused.To.Reg = p.To.Reg
				excise(r)
				n++
			} else {
				fused = p
			}
		case s390x.ASTMG, s390x.ASTMY:
			if (fused.As == s390x.ASTMY && size != 4) ||
				(fused.As == s390x.ASTMG && size != 8) {
				fused = p
				continue
//.........這裏部分代碼省略.........
開發者ID:hurkgu,項目名稱:go,代碼行數:101,代碼來源:peep.go


注:本文中的cmd/compile/internal/gc.Uniqp函數示例由純淨天空整理自Github/MSDocs等開源代碼及文檔管理平台,相關代碼片段篩選自各路編程大神貢獻的開源項目,源碼版權歸原作者所有,傳播和使用請參考對應項目的License;未經允許,請勿轉載。