Skip to content

Commit

Permalink
Modulo based -dlm 1 is now -dlm 2. Add a faster and correct 'if based…
Browse files Browse the repository at this point in the history
…' -dlm 1 mode. Set version to 2.24.1.
  • Loading branch information
sletz committed May 26, 2020
1 parent 1167326 commit 675cb0d
Show file tree
Hide file tree
Showing 23 changed files with 172 additions and 64 deletions.
2 changes: 1 addition & 1 deletion COPYING.txt
@@ -1,4 +1,4 @@
FAUST compiler, Version 2.24.0
FAUST compiler, Version 2.24.1
Copyright (C) 2003-2019 GRAME, Centre National de Creation Musicale
---------------------------------------------------------------------
This program is free software; you can redistribute it and/or modify
Expand Down
2 changes: 1 addition & 1 deletion Makefile
@@ -1,4 +1,4 @@
version := 2.24.0
version := 2.24.1

system ?= $(shell uname -s)

Expand Down
2 changes: 1 addition & 1 deletion build/CMakeLists.txt
Expand Up @@ -3,7 +3,7 @@ project (faust)

#######################################
# versions management
set (VERSION 2.24.0)
set (VERSION 2.24.1)
macro (get_major_minor_patch version)
string( REGEX REPLACE "([0-9]*)\\.([0-9]*)\\.([0-9]*)" "\\1" VERSION_MAJOR ${version} )
string( REGEX REPLACE "([0-9]*)\\.([0-9]*)\\.([0-9]*)" "\\2" VERSION_MINOR ${version} )
Expand Down
2 changes: 1 addition & 1 deletion build/Makefile
Expand Up @@ -11,7 +11,7 @@ system := $(shell echo $(system) | grep MINGW > /dev/null && echo MINGW || echo
# output directories
FAUSTDIR ?= faustdir
IOSDIR := iosdir
VERSION := 2.24.0
VERSION := 2.24.1

#===============================================================
# current generator and backends
Expand Down
4 changes: 2 additions & 2 deletions compiler/README.md
@@ -1,4 +1,4 @@
% man(1) Version 2.24.0 (24-May-2020) | Faust man page
% man(1) Version 2.24.1 (25-May-2020) | Faust man page

NAME
====
Expand Down Expand Up @@ -92,7 +92,7 @@ Code generation options:

**-mcd** \<n> **--max-copy-delay** \<n> threshold between copy and ring buffer implementation (default 16 samples).

**-dlm** \<n> **--delay-line-model** \<n> model of delay line [0:mask (default), 1:modulo].
**-dlm** \<n> **--delay-line-model** \<n> model of ring buffer delay line [0:mask (default), 1:select, 2:modulo].

**-mem** **--memory** allocate static in global state using a custom memory manager.

Expand Down
8 changes: 4 additions & 4 deletions compiler/generator/code_container.hh
Expand Up @@ -169,7 +169,7 @@ class CodeContainer : public virtual Garbageable {
if (!fGeneratedSR) {
pushDeclare(InstBuilder::genDecStructVar("fSampleRate", InstBuilder::genInt32Typed()));
}
pushFrontInitMethod(
pushPreInitMethod(
InstBuilder::genStoreStructVar("fSampleRate", InstBuilder::genLoadFunArgsVar("sample_rate")));
}

Expand Down Expand Up @@ -514,7 +514,7 @@ class CodeContainer : public virtual Garbageable {
fPostInitInstructions->pushBackInst(inst);
return inst;
}
StatementInst* pushFrontInitMethod(StatementInst* inst)
StatementInst* pushPreInitMethod(StatementInst* inst)
{
fInitInstructions->pushFrontInst(inst);
return inst;
Expand Down Expand Up @@ -570,9 +570,9 @@ class CodeContainer : public virtual Garbageable {
return inst;
}

StatementInst* pushComputePreDSPMethod(StatementInst* inst) { return fCurLoop->pushComputePreDSPMethod(inst); }
StatementInst* pushPreComputeDSPMethod(StatementInst* inst) { return fCurLoop->pushPreComputeDSPMethod(inst); }
StatementInst* pushComputeDSPMethod(StatementInst* inst) { return fCurLoop->pushComputeDSPMethod(inst); }
StatementInst* pushComputePostDSPMethod(StatementInst* inst) { return fCurLoop->pushComputePostDSPMethod(inst); }
StatementInst* pushPostComputeDSPMethod(StatementInst* inst) { return fCurLoop->pushPostComputeDSPMethod(inst); }

void generateSubContainers()
{
Expand Down
6 changes: 3 additions & 3 deletions compiler/generator/compile_scal.cpp
Expand Up @@ -1385,7 +1385,7 @@ string ScalarCompiler::generateFixDelay(Tree sig, Tree exp, Tree delay)
}

} else {
switch (gGlobal->gDelayCodeModel) {
switch (gGlobal->gDelayLineModel) {
// mask based delay with a power_of_two size
case 0: {
// long delay : we use a ring buffer of size 2^x
Expand Down Expand Up @@ -1451,7 +1451,7 @@ string ScalarCompiler::generateDelayVecNoTemp(Tree sig, const string& exp, const
return subst("$0[0]", vname);

} else {
switch (gGlobal->gDelayCodeModel) {
switch (gGlobal->gDelayLineModel) {
// mask based delay with a power_of_two size
case 0: {
// generate code for a long delay : we use a ring buffer of size N = 2**x > mxd
Expand Down Expand Up @@ -1522,7 +1522,7 @@ void ScalarCompiler::generateDelayLine(const string& ctype, const string& vname,
}

} else {
switch (gGlobal->gDelayCodeModel) {
switch (gGlobal->gDelayLineModel) {
// mask based delay with a power_of_two size
case 0: {
// generate code for a long delay : we use a ring buffer of size N = 2**x > mxd
Expand Down
4 changes: 2 additions & 2 deletions compiler/generator/cpp/cpp_gpu_code_container.cpp
Expand Up @@ -123,7 +123,7 @@ void CPPOpenCLCodeContainer::produceClass()
// Initialize "fSamplingFreq" with the "samplingFreq" parameter of the init function
// Generates fSamplingFreq field and initialize it with the "samplingFreq" parameter of the init function
pushDeclare(InstBuilder::genDecStructVar("fSampleRate", InstBuilder::genInt32Typed()));
pushFrontInitMethod(InstBuilder::genStoreStructVar("fSampleRate", InstBuilder::genLoadFunArgsVar("sample_rate")));
pushPreInitMethod(InstBuilder::genStoreStructVar("fSampleRate", InstBuilder::genLoadFunArgsVar("sample_rate")));

addIncludeFile("<iostream>");
addIncludeFile("<fstream>");
Expand Down Expand Up @@ -1247,7 +1247,7 @@ void CPPCUDACodeContainer::produceClass()
// Initialize "fSamplingFreq" with the "samplingFreq" parameter of the init function
// Generates fSamplingFreq field and initialize it with the "samplingFreq" parameter of the init function
pushDeclare(InstBuilder::genDecStructVar("fSampleRate", InstBuilder::genInt32Typed()));
pushFrontInitMethod(InstBuilder::genStoreStructVar("fSampleRate", InstBuilder::genLoadFunArgsVar("sample_rate")));
pushPreInitMethod(InstBuilder::genStoreStructVar("fSampleRate", InstBuilder::genLoadFunArgsVar("sample_rate")));

addIncludeFile("<iostream>");
addIncludeFile("<fstream>");
Expand Down
10 changes: 5 additions & 5 deletions compiler/generator/dag_instructions_compiler.cpp
Expand Up @@ -575,13 +575,13 @@ void DAGInstructionsCompiler::generateDlineLoop(Typed::VarType ctype, const stri
pushComputeBlockMethod(table_inst2);

// -- copy the stored samples to the delay line
pushComputePreDSPMethod(generateCopyArray(buf, pmem, delay));
pushPreComputeDSPMethod(generateCopyArray(buf, pmem, delay));

// -- compute the new samples
pushComputeDSPMethod(InstBuilder::genStoreArrayStackVar(vname, getCurrentLoopIndex(), exp));

// -- copy back to stored samples
pushComputePostDSPMethod(generateCopyBackArray(pmem, buf, delay));
pushPostComputeDSPMethod(generateCopyBackArray(pmem, buf, delay));

// Set desired variable access
var_access = Address::kStack;
Expand All @@ -607,7 +607,7 @@ void DAGInstructionsCompiler::generateDlineLoop(Typed::VarType ctype, const stri
FIRIndex index1 = FIRIndex(InstBuilder::genLoadStructVar(idx)) + InstBuilder::genLoadStructVar(idx_save);
FIRIndex index2 = index1 & InstBuilder::genInt32NumInst(delay - 1);

pushComputePreDSPMethod(InstBuilder::genStoreStructVar(idx, index2));
pushPreComputeDSPMethod(InstBuilder::genStoreStructVar(idx, index2));

// -- compute the new samples
FIRIndex index3 = getCurrentLoopIndex() + InstBuilder::genLoadStructVar(idx);
Expand All @@ -616,7 +616,7 @@ void DAGInstructionsCompiler::generateDlineLoop(Typed::VarType ctype, const stri
pushComputeDSPMethod(InstBuilder::genStoreArrayStructVar(vname, index4, exp));

// -- save index
pushComputePostDSPMethod(InstBuilder::genStoreStructVar(idx_save, InstBuilder::genLoadLoopVar("vsize")));
pushPostComputeDSPMethod(InstBuilder::genStoreStructVar(idx_save, InstBuilder::genLoadLoopVar("vsize")));

// Set desired variable access
var_access = Address::kStruct;
Expand Down Expand Up @@ -653,7 +653,7 @@ ValueInst* DAGInstructionsCompiler::generateWaveform(Tree sig)
string idx = subst("$0_idx", vname);
FIRIndex index1 = (FIRIndex(InstBuilder::genLoadStructVar(idx)) + InstBuilder::genLoadLoopVar("vsize")) %
InstBuilder::genInt32NumInst(size);
pushComputePostDSPMethod(InstBuilder::genStoreStructVar(idx, index1));
pushPostComputeDSPMethod(InstBuilder::genStoreStructVar(idx, index1));
FIRIndex index2 =
(FIRIndex(InstBuilder::genLoadStructVar(idx)) + getCurrentLoopIndex()) % InstBuilder::genInt32NumInst(size);
return generateCacheCode(sig, InstBuilder::genLoadArrayStaticStructVar(vname, index2));
Expand Down
2 changes: 1 addition & 1 deletion compiler/generator/export.hh
Expand Up @@ -22,7 +22,7 @@
#ifndef __export__
#define __export__

#define FAUSTVERSION "2.24.0"
#define FAUSTVERSION "2.24.1"

#ifdef _WIN32
#define EXPORT __declspec(dllexport)
Expand Down
32 changes: 32 additions & 0 deletions compiler/generator/instructions.hh
Expand Up @@ -2423,6 +2423,7 @@ struct FIRIndex {
/* implicitly convert to ValueInst* in order to simplify the usage */
operator ValueInst*(void)const { return fValue; }

// Add
friend FIRIndex operator+(FIRIndex const& lhs, ValueInst* rhs)
{
return FIRIndex(InstBuilder::genAdd(lhs.fValue, rhs));
Expand All @@ -2435,6 +2436,7 @@ struct FIRIndex {
return operator+(lhs, InstBuilder::genInt32NumInst(rhs));
}

// Sub
friend FIRIndex operator-(FIRIndex const& lhs, ValueInst* rhs)
{
return FIRIndex(InstBuilder::genSub(lhs.fValue, rhs));
Expand All @@ -2447,6 +2449,7 @@ struct FIRIndex {
return operator-(lhs, InstBuilder::genInt32NumInst(rhs));
}

// Mult
friend FIRIndex operator*(FIRIndex const& lhs, ValueInst* rhs)
{
return FIRIndex(InstBuilder::genMul(lhs.fValue, rhs));
Expand All @@ -2459,6 +2462,7 @@ struct FIRIndex {
return operator*(lhs, InstBuilder::genInt32NumInst(rhs));
}

// Div
friend FIRIndex operator/(FIRIndex const& lhs, ValueInst* rhs)
{
return FIRIndex(InstBuilder::genDiv(lhs.fValue, rhs));
Expand All @@ -2471,6 +2475,7 @@ struct FIRIndex {
return operator/(lhs, InstBuilder::genInt32NumInst(rhs));
}

// And
friend FIRIndex operator&(FIRIndex const& lhs, ValueInst* rhs)
{
return FIRIndex(InstBuilder::genAnd(lhs.fValue, rhs));
Expand All @@ -2483,6 +2488,7 @@ struct FIRIndex {
return operator&(lhs, InstBuilder::genInt32NumInst(rhs));
}

// Modulo
friend FIRIndex operator%(FIRIndex const& lhs, ValueInst* rhs)
{
return FIRIndex(InstBuilder::genRem(lhs.fValue, rhs));
Expand All @@ -2495,6 +2501,32 @@ struct FIRIndex {
return operator%(lhs, InstBuilder::genInt32NumInst(rhs));
}

// Equal
friend FIRIndex operator==(FIRIndex const& lhs, ValueInst* rhs)
{
return FIRIndex(InstBuilder::genEqual(lhs.fValue, rhs));
}

friend FIRIndex operator==(FIRIndex const& lhs, FIRIndex const& rhs) { return operator==(lhs, rhs.fValue); }

friend FIRIndex operator==(FIRIndex const& lhs, int rhs)
{
return operator==(lhs, InstBuilder::genInt32NumInst(rhs));
}

// Inf
friend FIRIndex operator<(FIRIndex const& lhs, ValueInst* rhs)
{
return FIRIndex(InstBuilder::genLessThan(lhs.fValue, rhs));
}

friend FIRIndex operator<(FIRIndex const& lhs, FIRIndex const& rhs) { return operator<(lhs, rhs.fValue); }

friend FIRIndex operator<(FIRIndex const& lhs, int rhs)
{
return operator<(lhs, InstBuilder::genInt32NumInst(rhs));
}

private:
ValueInst* fValue;
};
Expand Down
74 changes: 61 additions & 13 deletions compiler/generator/instructions_compiler.cpp
Expand Up @@ -1681,7 +1681,7 @@ void InstructionsCompiler::ensureIotaCode()
pushClearMethod(InstBuilder::genStoreStructVar("IOTA", InstBuilder::genInt32NumInst(fMaxIota)));

FIRIndex value = FIRIndex(InstBuilder::genLoadStructVar("IOTA")) + 1;
pushComputePostDSPMethod(InstBuilder::genStoreStructVar("IOTA", value));
pushPostComputeDSPMethod(InstBuilder::genStoreStructVar("IOTA", value));
}
}

Expand Down Expand Up @@ -1789,7 +1789,7 @@ ValueInst* InstructionsCompiler::generateFixDelay(Tree sig, Tree exp, Tree delay
return generateCacheCode(sig, InstBuilder::genLoadArrayStructVar(vname, CS(delay)));
}
} else {
switch (gGlobal->gDelayCodeModel) {
switch (gGlobal->gDelayLineModel) {
// mask based delay with a power_of_two size
case 0: {
// long delay : we use a ring buffer of size 2^x
Expand All @@ -1800,10 +1800,24 @@ ValueInst* InstructionsCompiler::generateFixDelay(Tree sig, Tree exp, Tree delay
return generateCacheCode(sig, InstBuilder::genLoadArrayStructVar(vname, value2));
}

// modulo based delay
// 'select' based delay
case 1: {
string ridx_name = gGlobal->getFreshID(vname + "_ridx_tmp");

// int ridx = widx - delay;
FIRIndex widx1 = FIRIndex(InstBuilder::genLoadStructVar(vname + "_widx"));
pushComputeDSPMethod(InstBuilder::genDecStackVar(ridx_name, InstBuilder::genBasicTyped(Typed::kInt32), widx1 - CS(delay)));

// dline[((ridx < 0) ? ridx + delay : ridx)];
FIRIndex ridx1 = FIRIndex(InstBuilder::genLoadStackVar(ridx_name));
FIRIndex ridx2 = FIRIndex(InstBuilder::genSelect2Inst(ridx1 < 0, ridx1 + FIRIndex(mxd + 1), ridx1));
return generateCacheCode(sig, InstBuilder::genLoadArrayStructVar(vname, ridx2));
}

// modulo based delay
case 2: {
FIRIndex value2 =
(FIRIndex(InstBuilder::genLoadStructVar("IOTA")) - CS(delay)) % InstBuilder::genInt32NumInst(mxd + 1);
(FIRIndex(InstBuilder::genLoadStructVar("IOTA")) - CS(delay)) % FIRIndex(mxd + 1);
return generateCacheCode(sig, InstBuilder::genLoadArrayStructVar(vname, value2));
}

Expand Down Expand Up @@ -1904,16 +1918,16 @@ ValueInst* InstructionsCompiler::generateDelayLine(ValueInst* exp, Typed::VarTyp

// Generates post processing copy code to update delay values
if (mxd == 1) {
pushComputePostDSPMethod(generateCopyArray(vname, 0, 1));
pushPostComputeDSPMethod(generateCopyArray(vname, 0, 1));
} else if (mxd == 2) {
pushComputePostDSPMethod(generateCopyArray(vname, 1, 2));
pushComputePostDSPMethod(generateCopyArray(vname, 0, 1));
pushPostComputeDSPMethod(generateCopyArray(vname, 1, 2));
pushPostComputeDSPMethod(generateCopyArray(vname, 0, 1));
} else {
pushComputePostDSPMethod(generateShiftArray(vname, mxd));
pushPostComputeDSPMethod(generateShiftArray(vname, mxd));
}

} else {
switch (gGlobal->gDelayCodeModel) {
switch (gGlobal->gDelayLineModel) {
case 0: {
// Generate code for a long delay : we use a ring buffer of size N = 2**x > mxd
int N = pow2limit(mxd + 1);
Expand All @@ -1940,9 +1954,43 @@ ValueInst* InstructionsCompiler::generateDelayLine(ValueInst* exp, Typed::VarTyp
}
break;
}

// 'select' based delay
case 1: {

string widx_tmp_name = vname + "_widx_tmp";
string widx_name = vname + "_widx";

// Generates table write index
pushDeclare(InstBuilder::genDecStructVar(widx_name, InstBuilder::genInt32Typed()));
pushInitMethod(InstBuilder::genStoreStructVar(widx_name, InstBuilder::genInt32NumInst(0)));

// Generates table init
pushClearMethod(generateInitArray(vname, ctype, mxd + 1));

// int w = widx;
pushComputeDSPMethod(InstBuilder::genDecStackVar(widx_tmp_name, InstBuilder::genBasicTyped(Typed::kInt32), InstBuilder::genLoadStructVar(widx_name)));

// dline[w] = v;
pushComputeDSPMethod(InstBuilder::genStoreArrayStructVar(vname, InstBuilder::genLoadStackVar(widx_tmp_name), exp));

// w = w+1;
FIRIndex widx_tmp1 = FIRIndex(InstBuilder::genLoadStackVar(widx_tmp_name));
pushPostComputeDSPMethod(InstBuilder::genStoreStackVar(widx_tmp_name, widx_tmp1 + 1));

// w = ((w == delay) ? 0 : w);
FIRIndex widx_tmp2 = FIRIndex(InstBuilder::genLoadStackVar(widx_tmp_name));
pushPostComputeDSPMethod(InstBuilder::genStoreStackVar(widx_tmp_name,
InstBuilder::genSelect2Inst(FIRIndex(widx_tmp2 == FIRIndex(mxd + 1)),
FIRIndex(0),
widx_tmp2)));
// *widx = w
pushPostComputeDSPMethod(InstBuilder::genStoreStructVar(widx_name, InstBuilder::genLoadStackVar(widx_tmp_name)));
break;
}

// modulo based delay
case 1: {
case 2: {

// we need an iota index
fMaxIota = std::max(fMaxIota, mxd);
Expand All @@ -1954,14 +2002,14 @@ ValueInst* InstructionsCompiler::generateDelayLine(ValueInst* exp, Typed::VarTyp
if (gGlobal->gComputeIOTA) { // Ensure IOTA base fixed delays are computed once
if (fIOTATable.find(mxd) == fIOTATable.end()) {
string iota_name = subst("i$0", gGlobal->getFreshID("IOTA_temp"));
FIRIndex value2 = FIRIndex(InstBuilder::genLoadStructVar("IOTA")) % InstBuilder::genInt32NumInst(mxd + 1);
FIRIndex value2 = FIRIndex(InstBuilder::genLoadStructVar("IOTA")) % FIRIndex(mxd + 1);
pushComputeDSPMethod(InstBuilder::genDecStackVar(iota_name, InstBuilder::genInt32Typed(), value2));
fIOTATable[mxd] = iota_name;
}
pushComputeDSPMethod(
InstBuilder::genStoreArrayStructVar(vname, InstBuilder::genLoadStackVar(fIOTATable[mxd]), exp));
} else {
FIRIndex value2 = FIRIndex(InstBuilder::genLoadStructVar("IOTA")) % InstBuilder::genInt32NumInst(mxd + 1);
FIRIndex value2 = FIRIndex(InstBuilder::genLoadStructVar("IOTA")) % FIRIndex(mxd + 1);
pushComputeDSPMethod(InstBuilder::genStoreArrayStructVar(vname, value2, exp));
}
break;
Expand Down Expand Up @@ -2054,7 +2102,7 @@ ValueInst* InstructionsCompiler::generateWaveform(Tree sig)

string idx = subst("$0_idx", vname);
FIRIndex index = (FIRIndex(1) + InstBuilder::genLoadStructVar(idx)) % InstBuilder::genInt32NumInst(size);
pushComputePostDSPMethod(InstBuilder::genStoreStructVar(idx, index));
pushPostComputeDSPMethod(InstBuilder::genStoreStructVar(idx, index));
return generateCacheCode(sig, InstBuilder::genLoadArrayStaticStructVar(vname, InstBuilder::genLoadStructVar(idx)));
}

Expand Down

0 comments on commit 675cb0d

Please sign in to comment.