Пример #1
0
Файл: ssa.go Проект: hinike/llgo
// If this value is sufficiently large, look through referrers to see if we can
// avoid a load.
func (fr *frame) canAvoidLoad(instr *ssa.UnOp, op llvm.Value) bool {
	if fr.types.Sizeof(instr.Type()) < 16 {
		// Don't bother with small values.
		return false
	}

	// Keep track of whether our pointer may escape. We conservatively assume
	// that MakeInterfaces will escape.
	esc := false

	// We only know how to avoid loads if they are used to create an interface
	// or read an element of the structure. If we see any other referrer, abort.
	for _, ref := range *instr.Referrers() {
		switch ref.(type) {
		case *ssa.MakeInterface:
			esc = true
		case *ssa.Field, *ssa.Index:
			// ok
		default:
			return false
		}
	}

	var opcopy llvm.Value
	if esc {
		opcopy = fr.createTypeMalloc(instr.Type())
	} else {
		opcopy = fr.allocaBuilder.CreateAlloca(fr.types.ToLLVM(instr.Type()), "")
	}
	fr.memcpy(opcopy, op, llvm.ConstInt(fr.types.inttype, uint64(fr.types.Sizeof(instr.Type())), false))

	fr.ptr[instr] = opcopy
	return true
}