Skip to content

[Model] MinimumCodeGenerationParallelAssignments #903

@isPANN

Description

@isPANN

Motivation

MINIMUM CODE GENERATION FOR PARALLEL ASSIGNMENTS (P298) from Garey & Johnson, A11 PO6. Given a set of simultaneous variable assignments, find an execution ordering that minimizes the number of backward dependencies (cases where a variable is overwritten before a later assignment reads its old value). This models the problem of sequencing parallel assignment statements in compilers when all assignments should conceptually happen simultaneously.

Associated reduction rules:

  • As target: R319 (FEEDBACK VERTEX SET →)
  • Connections (beyond G&J):
    • Closely related to MinimumFeedbackVertexSet: backward dependencies correspond to back-arcs in the dependency graph
    • Applications: parallel assignment scheduling in compilers, register renaming, SSA destruction

Definition

Name: MinimumCodeGenerationParallelAssignments
Reference: Garey & Johnson, Computers and Intractability, A11 PO6

Mathematical definition:

INSTANCE: A set V of variables, a set of assignments A_1, A_2, ..., A_m where each A_i has the form "v_i ← op(B_i)" with v_i ∈ V and B_i ⊆ V being the set of variables read by the assignment.
OBJECTIVE: Find an ordering (permutation π) of the assignments that minimizes the number of backward dependencies. A backward dependency occurs when variable v_{π(i)} (written by the i-th executed assignment) appears in B_{π(j)} (read by the j-th executed assignment) for some j > i — i.e., the old value of v_{π(i)} is needed by a later assignment but has already been overwritten.

Variables

  • Count: m (one variable per assignment, representing its position in the execution order)
  • Per-variable domain: {0, 1, ..., m-1} (position in the permutation)
  • Meaning: A permutation π of assignments. The cost is the number of pairs (i, j) with i < j such that v_{π(i)} ∈ B_{π(j)}.

Schema (data type)

Type name: MinimumCodeGenerationParallelAssignments
Variants: (none)

Field Type Description
num_variables usize Number of variables
assignments Vec<(usize, Vec<usize>)> Each assignment (target_var, read_vars): v_i ← op(B_i)

Complexity

  • Decision complexity: NP-complete (Sethi, 1975; transformation from FEEDBACK VERTEX SET).
  • Best known exact algorithm: O*(num_assignments! ) brute-force over all permutations, or equivalently O*(2^num_assignments) via dynamic programming.
  • Restrictions: NP-complete even when |B_i| ≤ 2 for all assignments.
  • References:
    • R. Sethi (1975). "Complete Register Allocation Problems." SIAM Journal on Computing, 4(3), pp. 226–248.

Extra Remark

Full book text:

INSTANCE: Set V of variables, collection of assignments A_i: "v_i ← op(B_i)" where B_i ⊆ V, positive integer K.
QUESTION: Is there an ordering of the assignments such that the number of backward dependencies (where v_{π(i)} ∈ B_{π(j)} for some j > i) is at most K?
Reference: [Sethi, 1975]. Transformation from FEEDBACK VERTEX SET.
Comment: NP-complete even with |B_i| ≤ 2.

Note: The original G&J formulation is a decision problem with threshold K. We use the equivalent optimization formulation: minimize the number of backward dependencies.

How to solve

  • It can be solved by (existing) bruteforce. (Enumerate all m! permutations of assignments and count backward dependencies for each; return the minimum.)
  • It can be solved by reducing to integer programming.
  • Other: Reduction to minimum feedback arc set in the dependency digraph.

Example Instance

Variables: V = {a, b, c, d} (indices 0, 1, 2, 3)

Assignments:

  • A_0: a ← op(b, c) — writes a (index 0), reads {b, c} (indices {1, 2})
  • A_1: b ← op(a) — writes b (index 1), reads {a} (index {0})
  • A_2: c ← op(d) — writes c (index 2), reads {d} (index {3})
  • A_3: d ← op(b, c) — writes d (index 3), reads {b, c} (indices {1, 2})

Dependency graph: An arc from A_i to A_j exists when v_i ∈ B_j (A_i's target variable is read by A_j):

  • A_0 → A_1 (a written by A_0, read by A_1)
  • A_1 → A_0 (b written by A_1, read by A_0)
  • A_1 → A_3 (b written by A_1, read by A_3)
  • A_2 → A_0 (c written by A_2, read by A_0)
  • A_2 → A_3 (c written by A_2, read by A_3)
  • A_3 → A_2 (d written by A_3, read by A_2)

Cycles: A_0 ↔ A_1 (mutual dependency on a and b), A_2 ↔ A_3 (mutual dependency on c and d).

Optimal ordering π = (A_0, A_2, A_3, A_1):

  • Position 1: A_0 writes a → a ∈ B_{A_1} (position 4) → 1 backward dep
  • Position 2: A_2 writes c → c ∈ B_{A_3} (position 3) → 1 backward dep
  • Position 3: A_3 writes d → d ∉ B_{A_1} → 0
  • Position 4: A_1 writes b → no later assignments → 0
  • Total: 2 backward dependencies

Why 1 backward dependency is impossible: The two cycles A_0 ↔ A_1 and A_2 ↔ A_3 are independent. Each cycle forces at least 1 backward dependency (in any ordering, one member of the cycle must come before the other). Since there are 2 independent cycles, the minimum is 2.

Suboptimal ordering π = (A_2, A_0, A_3, A_1):

  • A_2 writes c, read by A_0 (pos 2) and A_3 (pos 3) → 2 backward deps
  • A_0 writes a, read by A_1 (pos 4) → 1 backward dep
  • Total: 3 backward dependencies

Expected Outcome

Optimal value: Min(2) — the minimum number of backward dependencies is 2. Out of 24 permutations: 6 achieve 2 deps, 12 have 3 deps, and 6 have 4 deps, giving 3 distinct objective values.

Metadata

Metadata

Assignees

No one assigned

    Labels

    GoodAn issue passed all checks.modelA model problem to be implemented.

    Type

    No type

    Projects

    Status

    Done

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions