Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

backend: add infinite_register class method to RegisterType #3929

Merged
merged 6 commits into from
Feb 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions tests/backend/test_register.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import pytest

from xdsl.backend.register_type import RegisterType
from xdsl.irdl import irdl_attr_definition


@irdl_attr_definition
class TestRegister(RegisterType):
name = "test.reg"

def verify(self) -> None: ...

@classmethod
def instruction_set_name(cls) -> str:
return "TEST"

@classmethod
def abi_index_by_name(cls) -> dict[str, int]:
return {"x0": 0}

@classmethod
def infinite_register_prefix(cls):
return "x"


def test_register_clashes():
with pytest.raises(
AssertionError,
match="Invalid 'infinite' register name: x0 clashes with finite register set",
):
TestRegister.infinite_register(0)
24 changes: 24 additions & 0 deletions xdsl/backend/register_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from abc import ABC, abstractmethod
from collections.abc import Sequence

from typing_extensions import Self

from xdsl.dialects.builtin import (
IntAttr,
NoneAttr,
Expand Down Expand Up @@ -78,3 +80,25 @@ def instruction_set_name(cls) -> str:
@abstractmethod
def abi_index_by_name(cls) -> dict[str, int]:
raise NotImplementedError()

@classmethod
@abstractmethod
def infinite_register_prefix(cls) -> str:
"""
Provide the prefix for the spelling for a register at the given index in the
"infinite" register set.
For a prefix `x`, the spelling of the first infinite register will be `x0`.
"""
raise NotImplementedError()

@classmethod
def infinite_register(cls, index: int) -> Self:
"""
Provide the register at the given index in the "infinite" register set.
"""
spelling = cls.infinite_register_prefix() + str(index)
res = cls(spelling)
assert isinstance(res.index, NoneAttr), (
f"Invalid 'infinite' register name: {spelling} clashes with finite register set"
)
return res
4 changes: 2 additions & 2 deletions xdsl/backend/riscv/riscv_register_queue.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,10 @@ def pop(
reg = available_registers.pop()
else:
if issubclass(reg_type, IntRegisterType):
reg = reg_type(f"j_{self._j_idx}")
reg = reg_type.infinite_register(self._j_idx)
self._j_idx += 1
else:
reg = reg_type(f"fj_{self._fj_idx}")
reg = reg_type.infinite_register(self._fj_idx)
self._fj_idx += 1

reserved_registers = (
Expand Down
4 changes: 4 additions & 0 deletions xdsl/dialects/arm/register.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ def instruction_set_name(cls) -> str:
def abi_index_by_name(cls) -> dict[str, int]:
return ARM_INDEX_BY_NAME

@classmethod
def infinite_register_prefix(cls):
return "inf_"


UNALLOCATED_INT = IntRegisterType("")
X0 = IntRegisterType("x0")
Expand Down
8 changes: 8 additions & 0 deletions xdsl/dialects/riscv.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,10 @@ def abi_index_by_name(cls) -> dict[str, int]:
def a_register(cls, index: int) -> IntRegisterType:
return Registers.A[index]

@classmethod
def infinite_register_prefix(cls):
return "j_"


RV32F_INDEX_BY_NAME = {
"ft0": 0,
Expand Down Expand Up @@ -213,6 +217,10 @@ def abi_index_by_name(cls) -> dict[str, int]:
def a_register(cls, index: int) -> FloatRegisterType:
return Registers.FA[index]

@classmethod
def infinite_register_prefix(cls):
return "fj_"


RDInvT = TypeVar("RDInvT", bound=RISCVRegisterType)
RSInvT = TypeVar("RSInvT", bound=RISCVRegisterType)
Expand Down
20 changes: 20 additions & 0 deletions xdsl/dialects/x86/register.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ def instruction_set_name(cls) -> str:
def abi_index_by_name(cls) -> dict[str, int]:
return X86_INDEX_BY_NAME

@classmethod
def infinite_register_prefix(cls):
return "inf_reg_"


UNALLOCATED_GENERAL = GeneralRegisterType("")
RAX = GeneralRegisterType("rax")
Expand Down Expand Up @@ -117,6 +121,10 @@ def instruction_set_name(cls) -> str:
def abi_index_by_name(cls) -> dict[str, int]:
return RFLAGS_INDEX_BY_NAME

@classmethod
def infinite_register_prefix(cls):
return "inf_rflags_"


UNALLOCATED_RFLAGS = RFLAGSRegisterType("")
RFLAGS = RFLAGSRegisterType("rflags")
Expand Down Expand Up @@ -146,6 +154,10 @@ def instruction_set_name(cls) -> str:
def abi_index_by_name(cls) -> dict[str, int]:
return SSE_INDEX_BY_NAME

@classmethod
def infinite_register_prefix(cls):
return "inf_sse_"


# See https://wiki.osdev.org/X86-64_Instruction_Encoding#Registers
SSE_INDEX_BY_NAME = {
Expand Down Expand Up @@ -202,6 +214,10 @@ def instruction_set_name(cls) -> str:
def abi_index_by_name(cls) -> dict[str, int]:
return AVX2_INDEX_BY_NAME

@classmethod
def infinite_register_prefix(cls):
return "inf_avx2_"


# See https://wiki.osdev.org/X86-64_Instruction_Encoding#Registers
AVX2_INDEX_BY_NAME = {
Expand Down Expand Up @@ -258,6 +274,10 @@ def instruction_set_name(cls) -> str:
def abi_index_by_name(cls) -> dict[str, int]:
return X86AVX512_INDEX_BY_NAME

@classmethod
def infinite_register_prefix(cls):
return "inf_avx512_"


# See https://wiki.osdev.org/X86-64_Instruction_Encoding#Registers
X86AVX512_INDEX_BY_NAME = {
Expand Down
Loading