Skip to content

Commit

Permalink
[DSLX:BC] Fix disagreement between typechecker and interpreter on whe…
Browse files Browse the repository at this point in the history
…ther trace returns its operand.
  • Loading branch information
cdleary committed Dec 31, 2024
1 parent 4651f2e commit 8ae7cb1
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 12 deletions.
13 changes: 9 additions & 4 deletions xls/dslx/bytecode/bytecode.cc
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,11 @@ absl::StatusOr<Bytecode::Op> OpFromString(std::string_view s) {
if (s == "swap") {
return Bytecode::Op::kSwap;
}
if (s == "trace") {
return Bytecode::Op::kTrace;
if (s == "trace_arg") {
return Bytecode::Op::kTraceArg;
}
if (s == "trace_fmt") {
return Bytecode::Op::kTraceFmt;
}
if (s == "width_slice") {
return Bytecode::Op::kWidthSlice;
Expand Down Expand Up @@ -313,8 +316,10 @@ std::string OpToString(Bytecode::Op op) {
return "usub";
case Bytecode::Op::kSwap:
return "swap";
case Bytecode::Op::kTrace:
return "trace";
case Bytecode::Op::kTraceArg:
return "trace_arg";
case Bytecode::Op::kTraceFmt:
return "trace_fmt";
case Bytecode::Op::kWidthSlice:
return "width_slice";
case Bytecode::Op::kXor:
Expand Down
6 changes: 5 additions & 1 deletion xls/dslx/bytecode/bytecode.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,11 @@ class Bytecode {
// Swaps TOS0 and TOS1 on the stack.
kSwap,
// Prints information about the given arguments to the terminal.
kTrace,
kTraceFmt,
// Prints a single operand argument to the terminal and acts as identity
// function
// (places the value back on the stack).
kTraceArg,
// Slices out TOS0 bits of the array- or bits-typed value on TOS2,
// starting at index TOS1.
kWidthSlice,
Expand Down
4 changes: 2 additions & 2 deletions xls/dslx/bytecode/bytecode_emitter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -975,7 +975,7 @@ absl::Status BytecodeEmitter::HandleFormatMacro(const FormatMacro* node) {
std::vector<FormatStep>(node->format().begin(), node->format().end()),
std::move(value_fmt_descs));
bytecode_.push_back(
Bytecode(node->span(), Bytecode::Op::kTrace, std::move(trace_data)));
Bytecode(node->span(), Bytecode::Op::kTraceFmt, std::move(trace_data)));
return absl::OkStatus();
}

Expand Down Expand Up @@ -1086,7 +1086,7 @@ absl::Status BytecodeEmitter::HandleInvocation(const Invocation* node) {
steps.push_back(
absl::StrCat("trace of ", node->args()[0]->ToString(), ": "));
steps.push_back(options_.format_preference);
bytecode_.push_back(Bytecode(node->span(), Bytecode::Op::kTrace,
bytecode_.push_back(Bytecode(node->span(), Bytecode::Op::kTraceArg,
Bytecode::TraceData(std::move(steps), {})));
return absl::OkStatus();
}
Expand Down
25 changes: 22 additions & 3 deletions xls/dslx/bytecode/bytecode_interpreter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -475,8 +475,12 @@ absl::Status BytecodeInterpreter::EvalNextInstruction() {
XLS_RETURN_IF_ERROR(EvalSwap(bytecode));
break;
}
case Bytecode::Op::kTrace: {
XLS_RETURN_IF_ERROR(EvalTrace(bytecode));
case Bytecode::Op::kTraceFmt: {
XLS_RETURN_IF_ERROR(EvalTraceFmt(bytecode));
break;
}
case Bytecode::Op::kTraceArg: {
XLS_RETURN_IF_ERROR(EvalTraceArg(bytecode));
break;
}
case Bytecode::Op::kWidthSlice: {
Expand Down Expand Up @@ -1410,7 +1414,7 @@ absl::Status BytecodeInterpreter::EvalSwap(const Bytecode& bytecode) {
return absl::StrJoin(pieces, "");
}

absl::Status BytecodeInterpreter::EvalTrace(const Bytecode& bytecode) {
absl::Status BytecodeInterpreter::EvalTraceFmt(const Bytecode& bytecode) {
XLS_ASSIGN_OR_RETURN(const Bytecode::TraceData* trace_data,
bytecode.trace_data());
XLS_ASSIGN_OR_RETURN(std::string message,
Expand All @@ -1422,6 +1426,21 @@ absl::Status BytecodeInterpreter::EvalTrace(const Bytecode& bytecode) {
return absl::OkStatus();
}

absl::Status BytecodeInterpreter::EvalTraceArg(const Bytecode& bytecode) {
XLS_ASSIGN_OR_RETURN(const Bytecode::TraceData* trace_data,
bytecode.trace_data());
// The trace operation acts as an identity function so we peek at the TOS to
// push it later.
InterpValue value = stack_.PeekOrDie();
XLS_ASSIGN_OR_RETURN(std::string message,
TraceDataToString(*trace_data, stack_));
if (options_.trace_hook()) {
options_.trace_hook()(bytecode.source_span(), message);
}
stack_.Push(value);
return absl::OkStatus();
}

absl::Status BytecodeInterpreter::EvalWidthSlice(const Bytecode& bytecode) {
XLS_ASSIGN_OR_RETURN(const Type* type, bytecode.type_data());
XLS_ASSIGN_OR_RETURN(const Type* unwrapped_type, UnwrapMetaType(*type));
Expand Down
3 changes: 2 additions & 1 deletion xls/dslx/bytecode/bytecode_interpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,8 @@ class BytecodeInterpreter {
}
absl::Status EvalStore(const Bytecode& bytecode);
absl::Status EvalSwap(const Bytecode& bytecode);
absl::Status EvalTrace(const Bytecode& bytecode);
absl::Status EvalTraceFmt(const Bytecode& bytecode);
absl::Status EvalTraceArg(const Bytecode& bytecode);
absl::Status EvalWidthSlice(const Bytecode& bytecode);
absl::Status EvalXor(const Bytecode& bytecode);

Expand Down
10 changes: 10 additions & 0 deletions xls/dslx/bytecode/bytecode_interpreter_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,16 @@ fn main() -> () {
EXPECT_EQ(value, InterpValue::MakeUnit());
}

TEST_F(BytecodeInterpreterTest, TraceActsAsIdentity) {
constexpr std::string_view kProgram = R"(
fn main() -> u32 {
trace!(u32:42) >> trace!(u32:1)
}
)";
XLS_ASSERT_OK_AND_ASSIGN(InterpValue value, Interpret(kProgram, "main"));
EXPECT_EQ(value, InterpValue::MakeU32(42 >> 1));
}

TEST_F(BytecodeInterpreterTest, TraceFmtBitsValueDefaultFormat) {
constexpr std::string_view kProgram = R"(
fn main() -> () {
Expand Down
4 changes: 3 additions & 1 deletion xls/dslx/bytecode/interpreter_stack.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,9 @@ class InterpreterStack {
}

const InterpValue& PeekOrDie(int64_t from_top = 0) const {
CHECK_GE(stack_.size(), from_top + 1);
CHECK_GE(stack_.size(), from_top + 1) << absl::StreamFormat(
"Attempted to peek at from_top=%d but stack size is %d", from_top,
stack_.size());
return stack_.at(stack_.size() - from_top - 1).value;
}

Expand Down

0 comments on commit 8ae7cb1

Please sign in to comment.