// 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 }