Skip to content

Commit 75cf609

Browse files
committed
Hoist out helpers & reduce redundant converts.
1 parent bdb7e33 commit 75cf609

2 files changed

Lines changed: 34 additions & 53 deletions

File tree

lib/Conversion/ImportVerilog/Expressions.cpp

Lines changed: 32 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,30 @@ static FVInt convertSVIntToFVInt(const slang::SVInt &svint) {
3838
return FVInt(APInt(svint.getBitWidth(), value));
3939
}
4040

41+
/// Check if a Moore integer value contains any unknown (x/z) bits.
42+
/// Returns a Moore i1 result: 1 if any bit is unknown, 0 otherwise.
43+
static Value getIsUnknown(OpBuilder &builder, Location loc, Value value,
44+
moore::IntType valTy, MLIRContext *ctx) {
45+
Value bitVal = value;
46+
if (valTy.getWidth() > 1) {
47+
auto mooreI1Type = moore::IntType::get(ctx, 1, valTy.getDomain());
48+
bitVal = moore::ReduceXorOp::create(builder, loc, mooreI1Type, value);
49+
}
50+
auto xType = moore::IntType::get(ctx, 1, moore::Domain::FourValued);
51+
auto xConst =
52+
moore::ConstantOp::create(builder, loc, xType, FVInt::getAllX(1));
53+
return moore::CaseEqOp::create(builder, loc, bitVal, xConst).getResult();
54+
}
55+
56+
/// Coerce a Moore integer value to a builtin integer, handling four-valued
57+
/// inputs by first mapping x/z to 0 via LogicToIntOp.
58+
static Value coerceToBuiltinInt(OpBuilder &builder, Location loc, Value value,
59+
moore::IntType valTy) {
60+
if (valTy.getDomain() == moore::Domain::FourValued)
61+
value = builder.createOrFold<moore::LogicToIntOp>(loc, value);
62+
return builder.createOrFold<moore::ToBuiltinIntOp>(loc, value);
63+
}
64+
4165
/// Map an index into an array, with bounds `range`, to a bit offset of the
4266
/// underlying bit storage. This is a dynamic version of
4367
/// `slang::ConstantRange::translateIndex`.
@@ -3281,17 +3305,7 @@ Value Context::convertSystemCall(
32813305
mlir::emitError(loc) << "expected integer argument for `$isunknown`";
32823306
return {};
32833307
}
3284-
Value bitVal = value;
3285-
if (valTy.getWidth() > 1) {
3286-
auto mooreI1Type =
3287-
moore::IntType::get(getContext(), 1, valTy.getDomain());
3288-
bitVal = moore::ReduceXorOp::create(builder, loc, mooreI1Type, value);
3289-
}
3290-
auto xType =
3291-
moore::IntType::get(getContext(), 1, moore::Domain::FourValued);
3292-
auto xValue = FVInt::getAllX(1);
3293-
auto xConst = moore::ConstantOp::create(builder, loc, xType, xValue);
3294-
return moore::CaseEqOp::create(builder, loc, bitVal, xConst).getResult();
3308+
return getIsUnknown(builder, loc, value, valTy, getContext());
32953309
}
32963310

32973311
if (nameId == ksn::OneHot0 || nameId == ksn::OneHot) {
@@ -3310,30 +3324,14 @@ Value Context::convertSystemCall(
33103324
// contains any unknown (x/z) bits. Detect and squash if four-valued.
33113325
Value isUnknown;
33123326
if (valTy.getDomain() == Domain::FourValued) {
3313-
Value bitVal = value;
3314-
if (valTy.getWidth() > 1) {
3315-
auto mooreI1Type =
3316-
moore::IntType::get(getContext(), 1, valTy.getDomain());
3317-
bitVal = moore::ReduceXorOp::create(builder, loc, mooreI1Type, value);
3318-
}
3319-
auto xType =
3320-
moore::IntType::get(getContext(), 1, moore::Domain::FourValued);
3321-
auto xConst =
3322-
moore::ConstantOp::create(builder, loc, xType, FVInt::getAllX(1));
33233327
Value isUnknownMoore =
3324-
moore::CaseEqOp::create(builder, loc, bitVal, xConst).getResult();
3328+
getIsUnknown(builder, loc, value, valTy, getContext());
33253329
isUnknown =
33263330
builder.createOrFold<moore::ToBuiltinIntOp>(loc, isUnknownMoore);
33273331
}
33283332

33293333
// Coerce four-valued input to two-valued for the comb ops.
3330-
Value intVal;
3331-
if (valTy.getDomain() == Domain::FourValued) {
3332-
Value coerced = builder.createOrFold<moore::LogicToIntOp>(loc, value);
3333-
intVal = builder.createOrFold<moore::ToBuiltinIntOp>(loc, coerced);
3334-
} else {
3335-
intVal = builder.createOrFold<moore::ToBuiltinIntOp>(loc, value);
3336-
}
3334+
Value intVal = coerceToBuiltinInt(builder, loc, value, valTy);
33373335

33383336
// Compute onehot0: (value & (value - 1)) == 0
33393337
auto one = hw::ConstantOp::create(builder, loc, intVal.getType(), 1);
@@ -3350,22 +3348,15 @@ Value Context::convertSystemCall(
33503348
result = comb::AndOp::create(builder, loc, result, isNotZero);
33513349
}
33523350

3353-
// Wrap back into Moore type.
3354-
result = moore::FromBuiltinIntOp::create(builder, loc, result);
3355-
33563351
// If four-valued, squash to 0 when unknown bits exist.
33573352
if (isUnknown) {
3358-
Value resultI1 = convertToI1(result);
33593353
Value zeroI1 =
33603354
hw::ConstantOp::create(builder, loc, builder.getI1Type(), 0);
3361-
Value squashed =
3362-
comb::MuxOp::create(builder, loc, isUnknown, zeroI1, resultI1);
3363-
Value squashedMoore =
3364-
moore::FromBuiltinIntOp::create(builder, loc, squashed);
3365-
return moore::IntToLogicOp::create(builder, loc, squashedMoore)
3366-
.getResult();
3355+
result = comb::MuxOp::create(builder, loc, isUnknown, zeroI1, result);
3356+
Value resultMoore = moore::FromBuiltinIntOp::create(builder, loc, result);
3357+
return moore::IntToLogicOp::create(builder, loc, resultMoore).getResult();
33673358
}
3368-
return result;
3359+
return moore::FromBuiltinIntOp::create(builder, loc, result);
33693360
}
33703361

33713362
if (nameId == ksn::CountOnes) {
@@ -3380,13 +3371,7 @@ Value Context::convertSystemCall(
33803371
}
33813372

33823373
// Coerce four-valued input to two-valued for the comb ops.
3383-
Value intVal;
3384-
if (valTy.getDomain() == Domain::FourValued) {
3385-
Value coerced = builder.createOrFold<moore::LogicToIntOp>(loc, value);
3386-
intVal = builder.createOrFold<moore::ToBuiltinIntOp>(loc, coerced);
3387-
} else {
3388-
intVal = builder.createOrFold<moore::ToBuiltinIntOp>(loc, value);
3389-
}
3374+
Value intVal = coerceToBuiltinInt(builder, loc, value, valTy);
33903375

33913376
// Popcount: extract each bit, zero-extend to result width, and sum.
33923377
auto builtinIntTy = cast<IntegerType>(intVal.getType());

test/Conversion/ImportVerilog/builtins.sv

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -602,10 +602,8 @@ module SampleValueBuiltins #() (
602602
// CHECK: [[AND:%.+]] = comb.and [[DB]], [[SUB]] : i8
603603
// CHECK: [[ZERO:%.+]] = hw.constant 0 : i8
604604
// CHECK: [[EQ:%.+]] = comb.icmp eq [[AND]], [[ZERO]] : i8
605-
// CHECK: [[EQ_INT:%.+]] = moore.from_builtin_int [[EQ]] : i1
606-
// CHECK: [[EQ_BUILTIN:%.+]] = moore.to_builtin_int [[EQ_INT]] : i1
607605
// CHECK: [[FALSE:%.+]] = hw.constant false
608-
// CHECK: [[MUX:%.+]] = comb.mux [[ISUNKNOWN_I1]], [[FALSE]], [[EQ_BUILTIN]] : i1
606+
// CHECK: [[MUX:%.+]] = comb.mux [[ISUNKNOWN_I1]], [[FALSE]], [[EQ]] : i1
609607
// CHECK: [[RES_INT:%.+]] = moore.from_builtin_int [[MUX]] : i1
610608
// CHECK: [[RES_LOGIC:%.+]] = moore.int_to_logic [[RES_INT]] : i1
611609
// CHECK: [[RES_BUILTIN:%.+]] = moore.to_builtin_int [[RES_INT]] : i1
@@ -627,10 +625,8 @@ module SampleValueBuiltins #() (
627625
// CHECK: [[EQ:%.+]] = comb.icmp eq [[AND]], [[ZERO]] : i8
628626
// CHECK: [[NE:%.+]] = comb.icmp ne [[DB]], [[ZERO]] : i8
629627
// CHECK: [[AND2:%.+]] = comb.and [[EQ]], [[NE]] : i1
630-
// CHECK: [[RES_INT_2:%.+]] = moore.from_builtin_int [[AND2]] : i1
631-
// CHECK: [[RES_BUILTIN_2:%.+]] = moore.to_builtin_int [[RES_INT_2]] : i1
632628
// CHECK: [[FALSE:%.+]] = hw.constant false
633-
// CHECK: [[MUX:%.+]] = comb.mux [[ISUNKNOWN_I1]], [[FALSE]], [[RES_BUILTIN_2]] : i1
629+
// CHECK: [[MUX:%.+]] = comb.mux [[ISUNKNOWN_I1]], [[FALSE]], [[AND2]] : i1
634630
// CHECK: [[RES_INT:%.+]] = moore.from_builtin_int [[MUX]] : i1
635631
// CHECK: [[RES_LOGIC:%.+]] = moore.int_to_logic [[RES_INT]] : i1
636632
// CHECK: [[RES_BUILTIN:%.+]] = moore.to_builtin_int [[RES_INT]] : i1

0 commit comments

Comments
 (0)