}
}
-// markUnsafePoints finds unsafe points and computes lv.unsafePoints.
-func (lv *Liveness) markUnsafePoints() {
+// allUnsafe indicates that all points in this function are
+// unsafe-points.
+func allUnsafe(f *ssa.Func) bool {
// The runtime assumes the only safe-points are function
// prologues (because that's how it used to be). We could and
// should improve that, but for now keep consider all points
// go:nosplit functions are similar. Since safe points used to
// be coupled with stack checks, go:nosplit often actually
// means "no safe points in this function".
- if compiling_runtime || lv.f.NoSplit {
+ return compiling_runtime || f.NoSplit
+}
+
+// markUnsafePoints finds unsafe points and computes lv.unsafePoints.
+func (lv *Liveness) markUnsafePoints() {
+ if allUnsafe(lv.f) {
// No complex analysis necessary.
lv.allUnsafe = true
return
// for an empty block this will be used for its control
// instruction. We won't use the actual liveness map on a
// control instruction. Just mark it something that is
- // preemptible.
- s.pp.nextLive = LivenessIndex{-1, -1, false}
+ // preemptible, unless this function is "all unsafe".
+ s.pp.nextLive = LivenessIndex{-1, -1, allUnsafe(f)}
// Emit values in block
thearch.SSAMarkMoves(&s, b)