Skip to content
UNDER THE HOOD

Removing guards

Every rule is local to a function, needs no fact about another function but LLVM’s nofree attribute, and is monitored by verify mode (-fweavec-checks=verify), which emits each guard a rule removed as a monitor: a failing monitor reports weavec.proven (RFC 0035 §6).

  • 6.1 In bounds of a local or global. An access whose address is O + x, where O is a static alloca or a global with an exact definition in the unit of size S, and x is a constant or an expression whose range (ScalarEvolution’s signed range, or known bits) lies in [0, S - w], needs no guard, provided a local’s scope holds the access. GuardPrune applies the constant-offset case after inlining, and GuardExpand the rest.
  • 6.2 Covered by a dominating guard. A guard is removed when a guard of the same base value whose bytes cover it is available: executed on every path to it with no kill since. A kill is an instruction that may release memory or change the shadow: a call not marked nofree (LLVM infers it, and the library functions carry it), a lifetime end of a tracked local, a release. Availability is a forward data-flow problem over the function’s blocks.
  • 6.3 Merged in a block. The guards of one block on one base at constant offsets whose hull is at most 32 bytes, with no kill and no call that may not return between them, become one guard of the hull at the first of them. Its slow path checks each access it covers, so a failure names the access that fails.
  • 6.4 Loop ranges (RFC 0035 amendment 6). GuardLoop versions a loop with a known trip count, one exit block and nothing that may end a lifetime. Its preheader asks __weavec_rt_range_ok(lo, n) (no report) whether the whole range of each invariant or affine access over the trip is addressable; when the trip has at least 16 iterations and every range is, a copy of the loop without those guards runs, and LLVM may vectorise it; otherwise the guarded loop runs and stops at the access that fails. Verify mode does not version.

Everything else stays guarded, including every access through a pointer loaded from memory or passed in, however often a guard on another pointer covered its bytes.