Skip to content

Commit ae54422

Browse files
committed
Code factorization.
1 parent ef2ab2c commit ae54422

File tree

2 files changed

+97
-130
lines changed

2 files changed

+97
-130
lines changed

compiler/transform/signalFIRCompiler.hh

Lines changed: 77 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,20 @@ struct SignalFIRCompiler : public SignalVisitor {
109109

110110
DelayedSig() = default;
111111

112-
DelayedSig(const std::string& name, int size, Address::AccessType access = Address::kStruct)
112+
DelayedSig(const std::string& name, int size, Address::AccessType access = Address::kStruct,
113+
BlockInst* declare_block = nullptr, BlockInst* rest_block = nullptr)
113114
: fName(name), fSize(size), fAccess(access)
114115
{
115116
faustassert((size & (size - 1)) == 0 && "delay‑line size must be a power of two");
117+
118+
// Declare and initialize the delay line a an arry DSP struct
119+
/*
120+
declare_block->pushBackInst(
121+
IB::genDecStructVar(fName,
122+
IB::genBasicTyped(Typed::kFloatMacro))); reset_block->pushBackInst(
123+
IB::genStoreStructVar(fName,
124+
IB::genRealNumInst(Typed::kFloatMacro, init)));
125+
*/
116126
}
117127

118128
void resize(int size) { fSize = std::max(fSize, size); }
@@ -160,7 +170,7 @@ struct SignalFIRCompiler : public SignalVisitor {
160170
/**
161171
* @brief Represents a static table for FIR-like load/store operations.
162172
*
163-
* The `TableData` structure models a named array in the DSP environment, where
173+
* The `TableData` structure models a named array in the DSP struct, where
164174
* each element can be read from or written to using generated FIR
165175
* instructions. It is primarily used to implement lookup tables, buffers, or other
166176
* fixed-size memory structures in the DSP context.
@@ -171,7 +181,7 @@ struct SignalFIRCompiler : public SignalVisitor {
171181
* - Can be used for constant folding or static initialization.
172182
*/
173183
struct TableData {
174-
std::string fName; ///< Variable name for the table array in the DSP environment.
184+
std::string fName; ///< Variable name for the table array in the DSP struct.
175185
int fSize = 0; ///< Number of elements in the table (must be > 0).
176186
Tree fSigGen = nullptr; ///< Optional signal generator used for static initialization.
177187
Address::AccessType fAccess = Address::kStruct; ///< Memory access mode for the table.
@@ -255,13 +265,13 @@ struct SignalFIRCompiler : public SignalVisitor {
255265
*
256266
* The `inputControl` structure defines the configuration and runtime integration of
257267
* user interface controls that allow users to interact with signal parameters.
258-
* These controls are typically generated in DSP environments (e.g., sliders, buttons,
268+
* These controls are typically generated in DSP struct (e.g., sliders, buttons,
259269
* and numerical entries) and are automatically linked to the internal DSP state.
260270
*
261271
* ## Key Features
262272
* - Supports different control types (buttons, sliders, and numerical entries).
263273
* - Maintains control metadata such as label, initial value, range, and step size.
264-
* - Automatically declares and initializes the control in the DSP environment.
274+
* - Automatically declares and initializes the control in the DSP struct.
265275
*/
266276
struct inputControl {
267277
/**
@@ -281,7 +291,7 @@ struct SignalFIRCompiler : public SignalVisitor {
281291

282292
type fType; ///< The type of control.
283293
std::string fLabel; ///< Display label shown to the user.
284-
std::string fName; ///< Unique identifier for this control in the DSP environment.
294+
std::string fName; ///< Unique identifier for this control in the DSP struct.
285295
double fInit; ///< Initial value of the control.
286296
double fMin; ///< Minimum allowed value.
287297
double fMax; ///< Maximum allowed value.
@@ -295,7 +305,7 @@ struct SignalFIRCompiler : public SignalVisitor {
295305
/**
296306
* @brief Constructs a new user interface control and integrates it into the DSP.
297307
*
298-
* This constructor declares the control variable in the DSP environment and
308+
* This constructor declares the control variable in the DSP struct and
299309
* initializes it with the given value.
300310
*
301311
* @param sig The signal tree associated with this control (for DSP binding).
@@ -308,17 +318,17 @@ struct SignalFIRCompiler : public SignalVisitor {
308318
* @param max The maximum value allowed.
309319
* @param step The increment step for adjusting the control.
310320
*/
311-
inputControl(Tree sig, BlockInst* declare_block, BlockInst* reset_block, type type,
312-
const std::string& label, double init, double min, double max, double step)
321+
inputControl(Tree sig, SignalFIRCompiler& compiler, type type, const std::string& label,
322+
double init, double min, double max, double step)
313323
: fType(type), fLabel(label), fInit(init), fMin(min), fMax(max), fStep(step)
314324
{
315325
// Generate a unique variable name for this control based on its type
316326
fName = gGlobal->getFreshID(gTypeName[type]);
317327

318-
// Declare and initialize the control variable in the DSP environment
319-
declare_block->pushBackInst(
328+
// Declare and initialize the control variable in the DSP struct
329+
compiler.fDeclareBlock->pushBackInst(
320330
IB::genDecStructVar(fName, IB::genBasicTyped(Typed::kFloatMacro)));
321-
reset_block->pushBackInst(
331+
compiler.fResetBlock->pushBackInst(
322332
IB::genStoreStructVar(fName, IB::genRealNumInst(Typed::kFloatMacro, init)));
323333
}
324334

@@ -334,13 +344,13 @@ struct SignalFIRCompiler : public SignalVisitor {
334344
* @brief Represents a user interface output control (bargraph).
335345
*
336346
* The `outputControl` structure defines the configuration and integration of output controls
337-
* used to visualize signal values in the DSP environment. These controls do not accept user
347+
* used to visualize signal values in the DSP struct. These controls do not accept user
338348
* input; instead, they display real-time data such as signal levels or metering information.
339349
*
340350
* ## Key Features
341351
* - Supports horizontal and vertical bargraph types.
342352
* - Maintains control metadata such as label and value range.
343-
* - Automatically declares the control in the DSP environment.
353+
* - Automatically declares the control in the DSP struct.
344354
*/
345355
struct outputControl {
346356
/**
@@ -356,7 +366,7 @@ struct SignalFIRCompiler : public SignalVisitor {
356366

357367
type fType; ///< The type of output control.
358368
std::string fLabel; ///< Display label shown to the user.
359-
std::string fName; ///< Unique identifier for this control in the DSP environment.
369+
std::string fName; ///< Unique identifier for this control in the DSP struct.
360370
double fMin; ///< Minimum value displayed by the bargraph (e.g. -60 dB).
361371
double fMax; ///< Maximum value displayed by the bargraph (e.g. 0 dB).
362372

@@ -368,7 +378,7 @@ struct SignalFIRCompiler : public SignalVisitor {
368378
/**
369379
* @brief Constructs a new output control and integrates it into the DSP.
370380
*
371-
* This constructor declares the control variable in the DSP environment.
381+
* This constructor declares the control variable in the DSP struct.
372382
*
373383
* @param sig The signal tree associated with this control (for DSP binding).
374384
* @param declare_block The block in which the control variable is declared.
@@ -377,15 +387,15 @@ struct SignalFIRCompiler : public SignalVisitor {
377387
* @param min The minimum value displayed by the bargraph.
378388
* @param max The maximum value displayed by the bargraph.
379389
*/
380-
outputControl(Tree sig, BlockInst* declare_block, type type, const std::string& label,
390+
outputControl(Tree sig, SignalFIRCompiler& compiler, type type, const std::string& label,
381391
double min, double max)
382392
: fType(type), fLabel(label), fMin(min), fMax(max)
383393
{
384394
// Generate a unique variable name for this control based on its type
385395
fName = gGlobal->getFreshID(gTypeName[type]);
386396

387-
// Declare the control variable in the DSP environment
388-
declare_block->pushBackInst(
397+
// Declare the control variable in the DSP struct
398+
compiler.fDeclareBlock->pushBackInst(
389399
IB::genDecStructVar(fName, IB::genBasicTyped(Typed::kFloatMacro)));
390400
}
391401

@@ -412,12 +422,7 @@ struct SignalFIRCompiler : public SignalVisitor {
412422
* - Registers input and output controls such as sliders and bargraphs.
413423
*/
414424
struct SignalBuilder : public SignalVisitor {
415-
std::map<Tree, DelayedSig>& fDelays;
416-
std::map<Tree, TableData>& fTables;
417-
std::map<Tree, inputControl>& fInputControls;
418-
std::map<Tree, outputControl>& fOutputControls;
419-
BlockInst* fDeclareBlock;
420-
BlockInst* fResetBlock;
425+
SignalFIRCompiler& fCompiler;
421426

422427
/**
423428
* @brief Allocates or resizes a delay line for a given signal. All delay lines have a
@@ -461,24 +466,26 @@ struct SignalFIRCompiler : public SignalVisitor {
461466
int nature = getCertifiedSigType(x)->nature(); // Nature of the signal being delayed
462467
int N = pow2limit(delay + 1); // Max delay rounded up to power of 2
463468

464-
if (fDelays.count(x) == 0) {
469+
if (fCompiler.fDelays.count(x) == 0) {
465470
/*
466471
if (global::isDebug("SIG_COMPILER")) {
467472
std::cout << "allocateDelayLine NEW " << ppsig(x, 8) << std::endl;
468473
}
469474
*/
470475
if (nature == kInt) {
471-
fDelays[x] = DelayedSig(gGlobal->getFreshID((rec) ? "iRec" : "iVec"), N);
476+
fCompiler.fDelays[x] =
477+
DelayedSig(gGlobal->getFreshID((rec) ? "iRec" : "iVec"), N);
472478
} else {
473-
fDelays[x] = DelayedSig(gGlobal->getFreshID((rec) ? "fRec" : "fVec"), N);
479+
fCompiler.fDelays[x] =
480+
DelayedSig(gGlobal->getFreshID((rec) ? "fRec" : "fVec"), N);
474481
}
475482
} else {
476483
/*
477484
if (global::isDebug("SIG_COMPILER")) {
478485
std::cout << "allocateDelayLine RESIZE INT " << ppsig(x, 8) << std::endl;
479486
}
480487
*/
481-
fDelays[x].resize(N);
488+
fCompiler.fDelays[x].resize(N);
482489
}
483490
}
484491

@@ -499,27 +506,9 @@ struct SignalFIRCompiler : public SignalVisitor {
499506
*
500507
* ## Constructor
501508
*
502-
* @param delays A map from signal nodes to allocated delay lines.
503-
* @param tables A map from signal nodes to static table data.
504-
* @param inputs_control A map from signal nodes to input UI controls.
505-
* @param outputs_control A map from signal nodes to output UI controls.
506-
* @param declare_block The block where runtime variable declarations will be emitted.
507-
* @param reset_block The block where reset instructions (e.g., control initialization)
508-
* will be emitted.
509+
* @param compiler The compiler.
509510
*/
510-
SignalBuilder(std::map<Tree, DelayedSig>& delays, std::map<Tree, TableData>& tables,
511-
std::map<Tree, inputControl>& inputs_control,
512-
std::map<Tree, outputControl>& outputs_control, BlockInst* declare_block,
513-
BlockInst* reset_block)
514-
: fDelays(delays),
515-
fTables(tables),
516-
fInputControls(inputs_control),
517-
fOutputControls(outputs_control),
518-
fDeclareBlock(declare_block),
519-
fResetBlock(reset_block)
520-
{
521-
fVisitGen = true;
522-
}
511+
SignalBuilder(SignalFIRCompiler& compiler) : fCompiler(compiler) { fVisitGen = true; }
523512

524513
/**
525514
* @brief Visits a signal node and generates any required runtime structure.
@@ -576,9 +565,11 @@ struct SignalFIRCompiler : public SignalVisitor {
576565
isSigInt(size_tree, &size_val);
577566
Type c_type = getCertifiedSigType(gen_tree);
578567
if (c_type->nature() == kInt) {
579-
fTables[sig] = TableData(gGlobal->getFreshID("iTable"), gen_tree, size_val);
568+
fCompiler.fTables[sig] =
569+
TableData(gGlobal->getFreshID("iTable"), gen_tree, size_val);
580570
} else {
581-
fTables[sig] = TableData(gGlobal->getFreshID("fTable"), gen_tree, size_val);
571+
fCompiler.fTables[sig] =
572+
TableData(gGlobal->getFreshID("fTable"), gen_tree, size_val);
582573
}
583574
SignalVisitor::visit(sig);
584575
} else if (isSigWaveform(sig)) {
@@ -594,39 +585,36 @@ struct SignalFIRCompiler : public SignalVisitor {
594585
}
595586
*/
596587
} else if (isSigButton(sig, path)) { // UI
597-
fInputControls[sig] =
598-
inputControl(sig, fDeclareBlock, fResetBlock, inputControl::kButton,
588+
fCompiler.fInputControls[sig] =
589+
inputControl(sig, fCompiler, inputControl::kButton,
599590
removeMetadata(tree2str(hd(path))), 0, 0, 1, 1);
600591
} else if (isSigCheckbox(sig, path)) {
601-
fInputControls[sig] =
602-
inputControl(sig, fDeclareBlock, fResetBlock, inputControl::kCheckbutton,
592+
fCompiler.fInputControls[sig] =
593+
inputControl(sig, fCompiler, inputControl::kCheckbutton,
603594
removeMetadata(tree2str(hd(path))), 0, 0, 1, 1);
604595
} else if (isSigVSlider(sig, path, c, x, y, z)) {
605-
fInputControls[sig] =
606-
inputControl(sig, fDeclareBlock, fResetBlock, inputControl::kVslider,
607-
removeMetadata(tree2str(hd(path))), tree2double(c), tree2double(x),
608-
tree2double(y), tree2double(z));
596+
fCompiler.fInputControls[sig] = inputControl(
597+
sig, fCompiler, inputControl::kVslider, removeMetadata(tree2str(hd(path))),
598+
tree2double(c), tree2double(x), tree2double(y), tree2double(z));
609599
} else if (isSigHSlider(sig, path, c, x, y, z)) {
610-
fInputControls[sig] =
611-
inputControl(sig, fDeclareBlock, fResetBlock, inputControl::kHslider,
612-
removeMetadata(tree2str(hd(path))), tree2double(c), tree2double(x),
613-
tree2double(y), tree2double(z));
600+
fCompiler.fInputControls[sig] = inputControl(
601+
sig, fCompiler, inputControl::kHslider, removeMetadata(tree2str(hd(path))),
602+
tree2double(c), tree2double(x), tree2double(y), tree2double(z));
614603
} else if (isSigNumEntry(sig, path, c, x, y, z)) {
615-
fInputControls[sig] =
616-
inputControl(sig, fDeclareBlock, fResetBlock, inputControl::kNumEntry,
617-
removeMetadata(tree2str(hd(path))), tree2double(c), tree2double(x),
618-
tree2double(y), tree2double(z));
604+
fCompiler.fInputControls[sig] = inputControl(
605+
sig, fCompiler, inputControl::kNumEntry, removeMetadata(tree2str(hd(path))),
606+
tree2double(c), tree2double(x), tree2double(y), tree2double(z));
619607
} else if (isSigVBargraph(sig, path, x, y,
620608
z)) { // z is the input signal to the bargraph
621-
fOutputControls[sig] = outputControl(sig, fDeclareBlock, outputControl::kVbargraph,
622-
removeMetadata(tree2str(hd(path))),
623-
tree2double(x), tree2double(y));
609+
fCompiler.fOutputControls[sig] = outputControl(
610+
sig, fCompiler, outputControl::kVbargraph, removeMetadata(tree2str(hd(path))),
611+
tree2double(x), tree2double(y));
624612
SignalVisitor::visit(sig); // Visit children (i.e., the input signal z)
625613
} else if (isSigHBargraph(sig, path, x, y,
626614
z)) { // z is the input signal to the bargraph
627-
fOutputControls[sig] = outputControl(sig, fDeclareBlock, outputControl::kHbargraph,
628-
removeMetadata(tree2str(hd(path))),
629-
tree2double(x), tree2double(y));
615+
fCompiler.fOutputControls[sig] = outputControl(
616+
sig, fCompiler, outputControl::kHbargraph, removeMetadata(tree2str(hd(path))),
617+
tree2double(x), tree2double(y));
630618
SignalVisitor::visit(sig); // Visit children (i.e., the input signal z)
631619
} else {
632620
// Other cases
@@ -658,21 +646,20 @@ struct SignalFIRCompiler : public SignalVisitor {
658646
: fNumInputs(inputs), fNumOutputs(outputs), fOutputSig(lsig)
659647
{
660648
// Allocate IR blocks
661-
fGlobalBlock = IB::genBlockInst(); // Global code (e.g., global variables)
662-
fDeclareBlock = IB::genBlockInst(); // Variable declarations
663-
fInitBlock = IB::genBlockInst(); // Initialization code
664-
fResetBlock = IB::genBlockInst(); // Reset code
665-
fClearBlock = IB::genBlockInst(); // Clear state code
666-
fControlBlock = IB::genBlockInst(); // Control/UI update code
667-
fComputeBlock = IB::genBlockInst(); // Main DSP computation
668-
649+
fGlobalBlock = IB::genBlockInst();
650+
fDeclareBlock = IB::genBlockInst();
651+
fInitBlock = IB::genBlockInst();
652+
fResetBlock = IB::genBlockInst();
653+
fClearBlock = IB::genBlockInst();
654+
fControlBlock = IB::genBlockInst();
655+
fComputeBlock = IB::genBlockInst();
656+
669657
// Prepare the signal compilation context
670658
// The SignalBuilder populates:
671659
// - Delay lines (fDelays)
672660
// - Lookup tables (fTables)
673661
// - UI controls (fInputControls, fOutputControls)
674-
SignalBuilder builder(fDelays, fTables, fInputControls, fOutputControls, fDeclareBlock,
675-
fResetBlock);
662+
SignalBuilder builder(*this);
676663
builder.visitRoot(fOutputSig); // Traverse the DSP signal tree and collect resources
677664
}
678665

@@ -867,7 +854,7 @@ struct SignalFIRCompiler : public SignalVisitor {
867854
// to store intermediate `ValueInst*` results in a LIFO
868855
// (last-in, first-out) order.
869856
// ------------------------------------------------------------
870-
857+
871858
/**
872859
* @brief Pop the top value from the stack.
873860
*
@@ -895,12 +882,12 @@ struct SignalFIRCompiler : public SignalVisitor {
895882
ValueInst* topRes() { return fValueStack.top(); }
896883

897884
/**
898-
* @brief Push a value onto the stack.
899-
*
900-
* Adds a new `ValueInst` to the top of the stack.
901-
*
902-
* @param val The `ValueInst*` to push.
903-
*/
885+
* @brief Push a value onto the stack.
886+
*
887+
* Adds a new `ValueInst` to the top of the stack.
888+
*
889+
* @param val The `ValueInst*` to push.
890+
*/
904891
void pushRes(ValueInst* val) { fValueStack.push(val); }
905892

906893
virtual void visit(Tree t) override;

0 commit comments

Comments
 (0)