mirror of https://github.com/llvm/circt.git
[ImportVerilog]: Create variables for function arguments (#7829)
Adds shadow variables for SV function arguments. Fixes: #7431 Adjusts two test cases test/Conversion/ImportVerilog/basic.sv and test/Conversion/ImportVerilog/builtins.sv Adds two test functions in test/Conversion/ImportVerilog/builtins.sv, which will crash in the former circt-verilog tool. --------- Co-authored-by: Max Zhou <max@Maxs-MBP.lan>
This commit is contained in:
parent
fb2343d626
commit
7fa8632474
|
@ -894,13 +894,27 @@ Context::convertFunction(const slang::ast::SubroutineSymbol &subroutine) {
|
|||
ValueSymbolScope scope(valueSymbols);
|
||||
|
||||
// Create a function body block and populate it with block arguments.
|
||||
SmallVector<moore::VariableOp> argVariables;
|
||||
auto &block = lowering->op.getBody().emplaceBlock();
|
||||
for (auto [astArg, type] :
|
||||
llvm::zip(subroutine.getArguments(),
|
||||
lowering->op.getFunctionType().getInputs())) {
|
||||
auto loc = convertLocation(astArg->location);
|
||||
auto blockArg = block.addArgument(type, loc);
|
||||
valueSymbols.insert(astArg, blockArg);
|
||||
|
||||
if (isa<moore::RefType>(type)) {
|
||||
valueSymbols.insert(astArg, blockArg);
|
||||
} else {
|
||||
// Convert the body of the function.
|
||||
OpBuilder::InsertionGuard g(builder);
|
||||
builder.setInsertionPointToEnd(&block);
|
||||
|
||||
auto shadowArg = builder.create<moore::VariableOp>(
|
||||
loc, moore::RefType::get(cast<moore::UnpackedType>(type)),
|
||||
StringAttr{}, blockArg);
|
||||
valueSymbols.insert(astArg, shadowArg);
|
||||
argVariables.push_back(shadowArg);
|
||||
}
|
||||
}
|
||||
|
||||
// Convert the body of the function.
|
||||
|
@ -934,5 +948,16 @@ Context::convertFunction(const slang::ast::SubroutineSymbol &subroutine) {
|
|||
}
|
||||
if (returnVar && returnVar.use_empty())
|
||||
returnVar.getDefiningOp()->erase();
|
||||
|
||||
for (auto var : argVariables) {
|
||||
if (llvm::all_of(var->getUsers(),
|
||||
[](auto *user) { return isa<moore::ReadOp>(user); })) {
|
||||
for (auto *user : llvm::make_early_inc_range(var->getUsers())) {
|
||||
user->getResult(0).replaceAllUsesWith(var.getInitial());
|
||||
user->erase();
|
||||
}
|
||||
var->erase();
|
||||
}
|
||||
}
|
||||
return success();
|
||||
}
|
||||
|
|
|
@ -2072,3 +2072,31 @@ endfunction
|
|||
|
||||
function void SignCastsB(logic [31:0] value);
|
||||
endfunction
|
||||
|
||||
// CHECK-LABEL: func.func private @AssignFuncArgs(
|
||||
// CHECK-SAME: %arg0: !moore.i32
|
||||
function void AssignFuncArgs(int x);
|
||||
// CHECK: [[ARG:%.+]] = moore.variable %arg0 : <i32>
|
||||
// CHECK: [[READ:%.+]] = moore.constant 1 : i32
|
||||
// CHECK: moore.blocking_assign [[ARG]], [[READ]] : i32
|
||||
x = 1;
|
||||
endfunction
|
||||
|
||||
// CHECK-LABEL: func.func private @AssignFuncArgs2(
|
||||
// CHECK-SAME: %arg0: !moore.i32, %arg1: !moore.i32
|
||||
function int AssignFuncArgs2(int x, int y);
|
||||
// CHECK: [[X:%.+]] = moore.variable %arg0 : <i32>
|
||||
// CHECK: [[Y:%.+]] = moore.variable %arg1 : <i32>
|
||||
// CHECK: [[C1:%.+]] = moore.constant 1 : i32
|
||||
// CHECK: moore.blocking_assign [[X]], [[C1]] : i32
|
||||
x = 1;
|
||||
|
||||
// CHECK: [[C2:%.+]] = moore.constant 2 : i32
|
||||
// CHECK: moore.blocking_assign [[Y]], [[C2]] : i32
|
||||
y = 2;
|
||||
|
||||
// CHECK: [[READ_X:%.+]] = moore.read [[X]] : <i32>
|
||||
// CHECK: [[READ_Y:%.+]] = moore.read [[Y]] : <i32>
|
||||
// CHECK: [[ADD:%.+]] = moore.add [[READ_X]], [[READ_Y]] : i32
|
||||
return x+y;
|
||||
endfunction
|
||||
|
|
Loading…
Reference in New Issue