Skip to content
Open
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
15 changes: 15 additions & 0 deletions include/circt/Dialect/RTG/IR/RTGOps.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,21 @@
#include "mlir/Interfaces/InferTypeOpInterface.h"
#include "mlir/Interfaces/SideEffectInterfaces.h"

namespace circt {
namespace rtg {

/// A custom resource representing the RNG state. Operations that read from or
/// write to the RNG state should declare effects on this resource to prevent
/// CSE and DCE.
struct RNGStateResource
: public mlir::SideEffects::Resource::Base<RNGStateResource> {
StringRef getName() const final { return "RTGRNGStateResource"; }
bool isAddressable() const override { return false; }
};

} // namespace rtg
} // namespace circt

#define GET_OP_CLASSES
#include "circt/Dialect/RTG/IR/RTG.h.inc"

Expand Down
16 changes: 12 additions & 4 deletions include/circt/Dialect/RTG/IR/RTGOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ include "circt/Dialect/RTG/IR/RTGInterfaces.td"
include "circt/Dialect/RTG/IR/RTGISAAssemblyInterfaces.td"
include "circt/Dialect/Emit/EmitOpInterfaces.td"

// Resource representing the RNG state. Operations that read from or write to
// the RNG state should declare effects on this resource to prevent CSE and DCE.
def RNGStateResource : Resource<"RNGStateResource">;

// Base class for the operation in this dialect.
class RTGOp<string mnemonic, list<Trait> traits = []> :
Op<RTGDialect, mnemonic, traits>;
Expand Down Expand Up @@ -363,8 +367,8 @@ def SetCreateOp : RTGOp<"set_create", [Pure, SameTypeOperands]> {
}

def SetSelectRandomOp : RTGOp<"set_select_random", [
Pure,
TypesMatchWith<"output must be of the element type of input set",
MemoryEffects<[MemRead<RNGStateResource>, MemWrite<RNGStateResource>]>,
TypesMatchWith<"output must be of the element type of input set",
"set", "output",
"llvm::cast<rtg::SetType>($_self).getElementType()">
]> {
Expand Down Expand Up @@ -496,7 +500,7 @@ def BagCreateOp : RTGOp<"bag_create", [Pure, SameVariadicOperandSize]> {
}

def BagSelectRandomOp : RTGOp<"bag_select_random", [
Pure,
MemoryEffects<[MemRead<RNGStateResource>, MemWrite<RNGStateResource>]>,
TypesMatchWith<"output must be element type of input bag", "bag", "output",
"llvm::cast<rtg::BagType>($_self).getElementType()">
]> {
Expand Down Expand Up @@ -712,7 +716,9 @@ def TupleExtractOp : RTGOp<"tuple_extract", [

//===- Integer Operations -------------------------------------------------===//

def RandomNumberInRangeOp : RTGOp<"random_number_in_range", []> {
def RandomNumberInRangeOp : RTGOp<"random_number_in_range", [
MemoryEffects<[MemRead<RNGStateResource>, MemWrite<RNGStateResource>]>
]> {
let summary = "returns a number uniformly at random within the given range";
let description = [{
This operation computes a random number based on a uniform distribution
Expand Down Expand Up @@ -760,6 +766,8 @@ def ConstraintOp : RTGOp<"constraint", []> {

def RandomScopeOp : RTGOp<"random_scope", [
NoRegionArguments,
MemoryEffects<[MemRead<RNGStateResource>, MemWrite<RNGStateResource>]>,
RecursiveMemoryEffects,
SingleBlockImplicitTerminator<"rtg::YieldOp">,
]> {
let summary = "introduce a new scope for randomization";
Expand Down
54 changes: 53 additions & 1 deletion test/Dialect/RTG/IR/cse.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,63 @@ rtg.sequence @seq0() attributes {rtg.some_attr} {
%str = rtg.constant "label_string" : !rtg.string
// CHECK-NEXT: rtg.label_unique_decl [[STR]]
// CHECK-NEXT: rtg.label_unique_decl [[STR]]
// They are DCE'd but not CSE'd
// They are DCE'd but not CSE'd
%2 = rtg.label_unique_decl %str
%3 = rtg.label_unique_decl %str
%4 = rtg.label_unique_decl %str
// CHECK-NEXT: rtg.label global
rtg.label global %2
rtg.label global %3
}

// CHECK-LABEL: rtg.sequence @setSelectRandom
rtg.sequence @setSelectRandom(%arg0: i32, %arg1: i32) {
// CHECK: [[SET:%.+]] = rtg.set_create %arg0, %arg1 : i32
%set = rtg.set_create %arg0, %arg1 : i32
// CHECK-NEXT: rtg.set_select_random [[SET]] : !rtg.set<i32>
// CHECK-NEXT: rtg.set_select_random [[SET]] : !rtg.set<i32>
// CHECK-NEXT: rtg.set_select_random [[SET]] : !rtg.set<i32>
Comment on lines +23 to +25
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider:

Suggested change
// CHECK-NEXT: rtg.set_select_random [[SET]] : !rtg.set<i32>
// CHECK-NEXT: rtg.set_select_random [[SET]] : !rtg.set<i32>
// CHECK-NEXT: rtg.set_select_random [[SET]] : !rtg.set<i32>
// CHECK-COUNT-3: rtg.set_select_random [[SET]] : !rtg.set<i32>
// CHECK-NOT: rtg.set_select_random [[SET]]

Same comment throughout.

// They are not CSE'd and not DCE'd
%0 = rtg.set_select_random %set : !rtg.set<i32>
%1 = rtg.set_select_random %set : !rtg.set<i32>
%2 = rtg.set_select_random %set : !rtg.set<i32>
}

// CHECK-LABEL: rtg.sequence @bagSelectRandom
rtg.sequence @bagSelectRandom(%arg0: i32, %arg1: i32, %arg2: index) {
// CHECK: [[BAG:%.+]] = rtg.bag_create (%arg2 x %arg0, %arg2 x %arg1) : i32
%bag = rtg.bag_create (%arg2 x %arg0, %arg2 x %arg1) : i32
// CHECK-NEXT: rtg.bag_select_random [[BAG]] : !rtg.bag<i32>
// CHECK-NEXT: rtg.bag_select_random [[BAG]] : !rtg.bag<i32>
// CHECK-NEXT: rtg.bag_select_random [[BAG]] : !rtg.bag<i32>
// They are not CSE'd and not DCE'd
%0 = rtg.bag_select_random %bag : !rtg.bag<i32>
%1 = rtg.bag_select_random %bag : !rtg.bag<i32>
%2 = rtg.bag_select_random %bag : !rtg.bag<i32>
}

// CHECK-LABEL: rtg.sequence @randomScope
rtg.sequence @randomScope() {
// CHECK: rtg.random_scope attributes {a}
// CHECK: rtg.random_scope attributes {b}
// CHECK: rtg.random_scope attributes {c}
// They are not CSE'd and not DCE'd
rtg.random_scope attributes {a} {}
rtg.random_scope attributes {b} {}
rtg.random_scope attributes {c} {}
}

// CHECK-LABEL: rtg.sequence @randomNumberInRange
rtg.sequence @randomNumberInRange() {
// CHECK: [[LOW:%.+]] = index.constant 0
// CHECK-NEXT: [[HIGH:%.+]] = index.constant 100
// CHECK-NEXT: rtg.random_number_in_range {{\[}}[[LOW]], [[HIGH]]{{\]}}
// CHECK-NEXT: rtg.random_number_in_range {{\[}}[[LOW]], [[HIGH]]{{\]}}
// CHECK-NEXT: rtg.random_number_in_range {{\[}}[[LOW]], [[HIGH]]{{\]}}
%low = index.constant 0
%high = index.constant 100
// They are not CSE'd and not DCE'd
%0 = rtg.random_number_in_range [%low, %high]
%1 = rtg.random_number_in_range [%low, %high]
%2 = rtg.random_number_in_range [%low, %high]
}
Loading