[ImportVerilog] Refactor constant materialization; NFC

Factor the materialization of Slang `SVInt`s and `ConstantValue`s out
into a helper function on the import context. This will allow for easier
access to constant materialization from outside the expression
conversion code.
This commit is contained in:
Fabian Schuiki 2024-09-24 16:28:35 -07:00
parent 9f952e166c
commit 24715e4d31
No known key found for this signature in database
GPG Key ID: C42F5825FC5275E6
2 changed files with 45 additions and 31 deletions

View File

@ -82,15 +82,13 @@ struct RvalueExprVisitor {
}
// Try to materialize constant values directly.
using slang::ast::EvalFlags;
slang::ast::EvalContext evalContext(context.compilation,
slang::ast::EvalFlags::CacheResults);
EvalFlags::CacheResults |
EvalFlags::SpecparamsAllowed);
auto constant = expr.eval(evalContext);
if (constant.isInteger()) {
auto type = context.convertType(*expr.type);
if (!type)
return {};
return materializeSVInt(constant.integer(), type);
}
if (auto value = context.materializeConstant(constant, *expr.type, loc))
return value;
// Otherwise some other part of ImportVerilog should have added an MLIR
// value for this expression's symbol to the `context.valueSymbols` table.
@ -404,36 +402,14 @@ struct RvalueExprVisitor {
return {};
}
/// Materialize a Slang integer literal as a constant op.
Value materializeSVInt(const slang::SVInt &svint, Type type) {
auto fvint = convertSVIntToFVInt(svint);
bool typeIsFourValued = false;
if (auto unpackedType = dyn_cast<moore::UnpackedType>(type))
typeIsFourValued = unpackedType.getDomain() == moore::Domain::FourValued;
auto intType = moore::IntType::get(
context.getContext(), fvint.getBitWidth(),
fvint.hasUnknown() || typeIsFourValued ? moore::Domain::FourValued
: moore::Domain::TwoValued);
Value result = builder.create<moore::ConstantOp>(loc, intType, fvint);
if (result.getType() != type)
result = builder.create<moore::ConversionOp>(loc, type, result);
return result;
}
// Handle `'0`, `'1`, `'x`, and `'z` literals.
Value visit(const slang::ast::UnbasedUnsizedIntegerLiteral &expr) {
auto type = context.convertType(*expr.type);
if (!type)
return {};
return materializeSVInt(expr.getValue(), type);
return context.materializeSVInt(expr.getValue(), *expr.type, loc);
}
// Handle integer literals.
Value visit(const slang::ast::IntegerLiteral &expr) {
auto type = context.convertType(*expr.type);
if (!type)
return {};
return materializeSVInt(expr.getValue(), type);
return context.materializeSVInt(expr.getValue(), *expr.type, loc);
}
// Handle concatenations.
@ -1038,6 +1014,35 @@ Value Context::convertToBool(Value value) {
return {};
}
/// Materialize a Slang integer literal as a constant op.
Value Context::materializeSVInt(const slang::SVInt &svint,
const slang::ast::Type &astType, Location loc) {
auto type = convertType(astType);
if (!type)
return {};
bool typeIsFourValued = false;
if (auto unpackedType = dyn_cast<moore::UnpackedType>(type))
typeIsFourValued = unpackedType.getDomain() == moore::Domain::FourValued;
auto fvint = convertSVIntToFVInt(svint);
auto intType = moore::IntType::get(getContext(), fvint.getBitWidth(),
fvint.hasUnknown() || typeIsFourValued
? moore::Domain::FourValued
: moore::Domain::TwoValued);
Value result = builder.create<moore::ConstantOp>(loc, intType, fvint);
if (result.getType() != type)
result = builder.create<moore::ConversionOp>(loc, type, result);
return result;
}
Value Context::materializeConstant(const slang::ConstantValue &constant,
const slang::ast::Type &type, Location loc) {
if (constant.isInteger())
return materializeSVInt(constant.integer(), type, loc);
return {};
}
/// Helper function to convert a value to its "truthy" boolean value and
/// convert it to the given domain.
Value Context::convertToBool(Value value, Domain domain) {

View File

@ -114,6 +114,15 @@ struct Context {
/// convert it to the given domain.
Value convertToBool(Value value, Domain domain);
/// Helper function to materialize an `SVInt` as an SSA value.
Value materializeSVInt(const slang::SVInt &svint,
const slang::ast::Type &type, Location loc);
/// Helper function to materialize a `ConstantValue` as an SSA value. Returns
/// null if the constant cannot be materialized.
Value materializeConstant(const slang::ConstantValue &constant,
const slang::ast::Type &type, Location loc);
slang::ast::Compilation &compilation;
mlir::ModuleOp intoModuleOp;
const slang::SourceManager &sourceManager;