Cấp phát thanh ghi (register allocation) bằng tô màu đồ thị giao (interference graph coloring) là kỹ thuật tối ưu cốt lõi ở giai đoạn sinh mã: các biến tạm (temporary) xung đột (cùng "sống" tại một thời điểm) không được cấp cùng một thanh ghi. Bài này yêu cầu cài đặt thuật toán simplify/select đơn giản hoá của Chaitin.
Cho đồ thị giao gồm n biến tạm (đánh số 0,…,n−1), m cạnh xung đột, và k thanh ghi khả dụng (đánh số 0,…,k−1). Thực hiện hai giai đoạn sau:
Giai đoạn 1 — Đơn giản hoá (simplify), lặp cho tới khi đồ thị (phần còn lại) rỗng:
Giai đoạn 2 — Tô màu (select): rút các đỉnh ra khỏi S theo thứ tự ngược lại với thứ tự đã đẩy vào (đỉnh đẩy vào sau cùng được tô màu đầu tiên). Với mỗi đỉnh v được rút ra, xét tập màu đã dùng bởi các đỉnh kề với v trong đồ thị gốc mà đã được tô màu (tính đến thời điểm này); gán cho v màu nhỏ nhất trong {0,…,k−1} chưa bị các đỉnh kề đã tô dùng. Nếu cả k màu đều đã bị dùng bởi các đỉnh kề đã tô, đỉnh v bị tràn thanh ghi (SPILL) — không có thanh ghi nào được gán.
Ví dụ: đồ thị tam giác (3 đỉnh, 3 cạnh đôi một xung đột) với k=2: không đủ 2 thanh ghi để tô 3 đỉnh xung đột đôi một, nên đúng một đỉnh sẽ bị SPILL, hai đỉnh còn lại nhận hai thanh ghi khác nhau.
Dòng đầu tiên chứa ba số nguyên n, m, k (1≤n≤300, 0≤m≤20000, 1≤k≤n).
m dòng tiếp theo, mỗi dòng hai số nguyên u, v (0≤u,v<n, u=v) — nghĩa là biến tạm u và v xung đột. Có thể có cạnh lặp lại, không ảnh hưởng tới kết quả.
In ra n dòng: dòng thứ i (ứng với biến tạm i−1, i=1,…,n) chứa số hiệu thanh ghi (0,…,k−1) được gán cho biến đó theo thuật toán trên, hoặc chuỗi SPILL nếu biến đó bị tràn thanh ghi.
Ví dụ:
Đầu vào:
3 3 2
0 1
1 2
0 2
Đầu ra:
SPILL
1
0
Đầu vào:
1 0 1
Đầu ra:
0
Đang tải editor...