-
Notifications
You must be signed in to change notification settings - Fork 305
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
[RTGTest] Add some registers #7924
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
//===- RTGTestAttributes.td - RTGTest attributes -----------*- tablegen -*-===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This describes the RTGTest attributes. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef CIRCT_DIALECT_RTGTEST_IR_RTGTESTATTRIBUTES_TD | ||
#define CIRCT_DIALECT_RTGTEST_IR_RTGTESTATTRIBUTES_TD | ||
|
||
include "mlir/IR/AttrTypeBase.td" | ||
include "mlir/IR/EnumAttr.td" | ||
|
||
// Flat allocation of unique IDs to all registers. The actual ID value does not | ||
// matter. | ||
def RegisterAttr : I32EnumAttr< | ||
"Registers", "Unique IDs for all RTGTest registers", [ | ||
I32EnumAttrCase<"zero", 0>, | ||
I32EnumAttrCase<"ra", 1>, | ||
I32EnumAttrCase<"sp", 2>, | ||
I32EnumAttrCase<"gp", 3>, | ||
I32EnumAttrCase<"tp", 4>, | ||
I32EnumAttrCase<"t0", 5>, | ||
I32EnumAttrCase<"t1", 6>, | ||
I32EnumAttrCase<"t2", 7>, | ||
I32EnumAttrCase<"s0", 8>, | ||
I32EnumAttrCase<"s1", 9>, | ||
I32EnumAttrCase<"a0", 10>, | ||
I32EnumAttrCase<"a1", 11>, | ||
I32EnumAttrCase<"a2", 12>, | ||
I32EnumAttrCase<"a3", 13>, | ||
I32EnumAttrCase<"a4", 14>, | ||
I32EnumAttrCase<"a5", 15>, | ||
I32EnumAttrCase<"a6", 16>, | ||
I32EnumAttrCase<"a7", 17>, | ||
I32EnumAttrCase<"s2", 18>, | ||
I32EnumAttrCase<"s3", 19>, | ||
I32EnumAttrCase<"s4", 20>, | ||
I32EnumAttrCase<"s5", 21>, | ||
I32EnumAttrCase<"s6", 22>, | ||
I32EnumAttrCase<"s7", 23>, | ||
I32EnumAttrCase<"s8", 24>, | ||
I32EnumAttrCase<"s9", 25>, | ||
I32EnumAttrCase<"s10", 26>, | ||
I32EnumAttrCase<"s11", 27>, | ||
I32EnumAttrCase<"t3", 28>, | ||
I32EnumAttrCase<"t4", 29>, | ||
I32EnumAttrCase<"t5", 30>, | ||
I32EnumAttrCase<"t6", 31>, | ||
maerhart marked this conversation as resolved.
Show resolved
Hide resolved
|
||
I32EnumAttrCase<"Virtual", 32> | ||
]> { | ||
let cppNamespace = "::circt::rtgtest"; | ||
} | ||
|
||
#endif // CIRCT_DIALECT_RTGTEST_IR_RTGTESTATTRIBUTES_TD |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,7 +11,9 @@ | |
//===----------------------------------------------------------------------===// | ||
|
||
include "mlir/IR/CommonAttrConstraints.td" | ||
include "mlir/Interfaces/InferTypeOpInterface.td" | ||
include "circt/Dialect/RTG/IR/RTGInterfaces.td" | ||
include "circt/Dialect/RTG/IR/RTGISAAssemblyInterfaces.td" | ||
|
||
// Base class for the operation in this dialect. | ||
class RTGTestOp<string mnemonic, list<Trait> traits = []> : | ||
|
@@ -43,3 +45,21 @@ def ConstantTestOp : RTGTestOp<"constant_test", [ | |
let assemblyFormat = "type($result) attr-dict"; | ||
let hasFolder = 1; | ||
} | ||
|
||
def RegisterOp : RTGTestOp<"reg", [ | ||
DeclareOpInterfaceMethods<RegisterOpInterface>, | ||
DeclareOpInterfaceMethods<InferTypeOpInterface>, | ||
]> { | ||
let summary = "returns a value representing a register"; | ||
let description = [{ | ||
This operation creates a value representing the register given as the 'reg' | ||
attribute. A register can be a concrete register or a virtual register. | ||
Virtual registers will be assigned a concrete register when running register | ||
allocation. | ||
Comment on lines
+57
to
+58
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This probably doesn't make sense for a test dialect, but in practice, would you have virtual registers as a separate op that cannot be CSEd, and actual ISA register as something "pure" or maybe even "constant-like"? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point! Having concrete registers CSE would be very nice. Having separate ops for concrete and virtual registers complicates register allocation a bit but makes elaboration easier. Let me think about that a bit more. |
||
}]; | ||
|
||
let arguments = (ins RegisterAttr:$reg); | ||
let results = (outs RegisterType:$result); | ||
|
||
let assemblyFormat = "$reg attr-dict"; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
add_circt_unittest(CIRCTRTGTestTests | ||
RegisterTest.cpp | ||
) | ||
|
||
target_link_libraries(CIRCTRTGTestTests | ||
PRIVATE | ||
CIRCTRTGTestDialect | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
//===- RegisterTest.cpp - RTGTest register unit tests ---------------------===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#include "circt/Dialect/RTGTest/IR/RTGTestOps.h" | ||
#include "gtest/gtest.h" | ||
|
||
using namespace mlir; | ||
using namespace circt; | ||
using namespace rtgtest; | ||
|
||
namespace { | ||
|
||
TEST(RegisterInterfaceTest, IntegerRegisters) { | ||
MLIRContext context; | ||
context.loadDialect<RTGTestDialect>(); | ||
Location loc(UnknownLoc::get(&context)); | ||
|
||
SmallVector<std::tuple<Registers, std::string, unsigned>> regs{ | ||
{Registers::zero, "zero", 0}, {Registers::ra, "ra", 1}, | ||
{Registers::sp, "sp", 2}, {Registers::gp, "gp", 3}, | ||
{Registers::tp, "tp", 4}, {Registers::t0, "t0", 5}, | ||
{Registers::t1, "t1", 6}, {Registers::t2, "t2", 7}, | ||
{Registers::s0, "s0", 8}, {Registers::s1, "s1", 9}, | ||
{Registers::a0, "a0", 10}, {Registers::a1, "a1", 11}, | ||
{Registers::a2, "a2", 12}, {Registers::a3, "a3", 13}, | ||
{Registers::a4, "a4", 14}, {Registers::a5, "a5", 15}, | ||
{Registers::a6, "a6", 16}, {Registers::a7, "a7", 17}, | ||
{Registers::s2, "s2", 18}, {Registers::s3, "s3", 19}, | ||
{Registers::s4, "s4", 20}, {Registers::s5, "s5", 21}, | ||
{Registers::s6, "s6", 22}, {Registers::s7, "s7", 23}, | ||
{Registers::s8, "s8", 24}, {Registers::s9, "s9", 25}, | ||
{Registers::s10, "s10", 26}, {Registers::s11, "s11", 27}, | ||
{Registers::t3, "t3", 28}, {Registers::t4, "t4", 29}, | ||
{Registers::t5, "t5", 30}, {Registers::t6, "t6", 31}}; | ||
|
||
auto moduleOp = ModuleOp::create(loc); | ||
OpBuilder builder = OpBuilder::atBlockBegin(moduleOp.getBody()); | ||
auto regOp = builder.create<RegisterOp>(loc, Registers::Virtual); | ||
ASSERT_EQ(regOp.getAllowedRegs(), | ||
llvm::BitVector(getMaxEnumValForRegisters(), true)); | ||
ASSERT_EQ(regOp.getFixedReg(), ~0U); | ||
|
||
for (auto [reg, str, idx] : regs) { | ||
regOp.setFixedReg(idx); | ||
ASSERT_EQ(regOp.getClassIndex(), idx); | ||
ASSERT_EQ(regOp.getClassIndexBinary(), APInt(5, idx)); | ||
ASSERT_EQ(regOp.getRegisterAssembly(), str); | ||
ASSERT_EQ(regOp.getAllowedRegs(), | ||
llvm::BitVector(getMaxEnumValForRegisters(), false).set(idx)); | ||
ASSERT_EQ(regOp.getFixedReg(), idx); | ||
} | ||
} | ||
|
||
} // namespace |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think ideally this attribute should be of IntegerRegisterType, not I32. It's not a big deal for now though.