# HG changeset patch # User vnorilo # Date 1669144248 -7200 # Tue Nov 22 21:10:48 2022 +0200 # Branch dev # Node ID 644b0cac2213e10caacf6c673cc9815296dea4db # Parent 62fe7c885dd8c9c12f9d45bd8faf4c35e88aa778 Adds External-Unsafe for external buffers without initializer diff --git a/src/backends/LLVMCompiler.cpp b/src/backends/LLVMCompiler.cpp --- a/src/backends/LLVMCompiler.cpp +++ b/src/backends/LLVMCompiler.cpp @@ -575,10 +575,12 @@ llvm::Value* ptr = b.CreateLoad(ptrPtr); if (lt.IsInitPass()) { if (GetUp(0)) { - llvm::Value* init = lt(GetUp(0)); - ptr = b.CreateSelect( - b.CreateICmpNE(ptr, Constant::getNullValue(ptr->getType())), ptr, init); - b.CreateStore(ptr, ptrPtr); + if (!IsNil(GetUp(0))) { + llvm::Value* init = lt(GetUp(0)); + ptr = b.CreateSelect( + b.CreateICmpNE(ptr, Constant::getNullValue(ptr->getType())), ptr, init); + b.CreateStore(ptr, ptrPtr); + } } else { auto fn = lt.GetModule()->getOrInsertFunction("GetConfigurationSlot", llvm::FunctionType::get(lt.GetBuilder().getInt8PtrTy(), { lt.GetBuilder().getInt32Ty() }, false)); diff --git a/src/backends/SideEffectCompiler.cpp b/src/backends/SideEffectCompiler.cpp --- a/src/backends/SideEffectCompiler.cpp +++ b/src/backends/SideEffectCompiler.cpp @@ -1576,7 +1576,9 @@ auto buf = Buffer::New(sfx, Native::Constant::New(int64_t(t.GetSize())), Buffer::Module, 16); initializer = Deps::New(buf, sfx.CopyData(DataSource::New(buf, layout), initializer, sfx.GetSymbolTable().GetInitializerReactivity(), true, true, true)); - } + } else { + initializer = Typed::Nil(); + } if (key.IsNil() == false) { sfx.GetSymbolTable().RegisterExternalVariable(key, t, uid, k, vectorRate, clock); diff --git a/src/k3/DynamicVariables.cpp b/src/k3/DynamicVariables.cpp --- a/src/k3/DynamicVariables.cpp +++ b/src/k3/DynamicVariables.cpp @@ -37,6 +37,19 @@ Specialization GenericExternalVariable::Specialize(SpecializationState& spec) const { SPECIALIZE(spec, key, GetUp(0)); SPECIALIZE(spec, init, GetUp(1)); + + if (unsafe) { + auto initType = init.result.Fix(); + + return Specialization( + GetGlobalVariable::New(TLS::GetCurrentInstance()->Memoize(key.result.Fix()), + initType, + key.result.Fix(), + std::make_pair(1,1), + nullptr, + External), + initType); + } if (spec.mode == SpecializationState::Configuration) { return init; diff --git a/src/k3/DynamicVariables.h b/src/k3/DynamicVariables.h --- a/src/k3/DynamicVariables.h +++ b/src/k3/DynamicVariables.h @@ -93,9 +93,10 @@ END GENERIC_NODE(GenericExternalVariable,GenericBinary) - GenericExternalVariable(CGRef key, CGRef initializer):GenericBinary(key,initializer){} + bool unsafe; + GenericExternalVariable(CGRef key, CGRef initializer,bool unsafe):GenericBinary(key,initializer), unsafe(unsafe) { } PUBLIC - static GenericExternalVariable* New(CGRef key, CGRef initializer) {return new GenericExternalVariable(key,initializer);} + static GenericExternalVariable* New(CGRef key, CGRef initializer, bool unsafe) {return new GenericExternalVariable(key,initializer,unsafe);} END GENERIC_NODE(GenericStreamInput,GenericTernary) diff --git a/src/k3/TLS.cpp b/src/k3/TLS.cpp --- a/src/k3/TLS.cpp +++ b/src/k3/TLS.cpp @@ -16,6 +16,8 @@ #include #include #include +#include +#include #ifdef HAVE_LLVM #pragma warning(disable: 4126 4267) @@ -56,7 +58,8 @@ build.AddFunction("Eval", Nodes::Evaluate::New("eval", b1, b2), "fn arg...", "Evaluates 'fn' as a function with the arguments in 'arg...'"); - build.AddFunction("External", Nodes::GenericExternalVariable::New(b1, b2), "key default", "External input declaration with the identifier 'key' and type and default value provided by 'default'"); + build.AddFunction("External", Nodes::GenericExternalVariable::New(b1, b2, false), "key default", "External input declaration with the identifier 'key' and type and default value provided by 'default'"); + build.AddFunction("External-Unsafe", Nodes::GenericExternalVariable::New(b1, b2, true), "key default", "External input declaration with the identifier 'key' and type and default value provided by 'default'. The input will not be initialized and must be bound by whomever uses the circuit, before invoking any code that touches the value."); build.AddFunction("External-Stream", Nodes::GenericStreamInput::New(b1, Nodes::GenericFirst::New(b2), Nodes::GenericRest::New(b2)), "stream-key default clock", "Stream input to this module from an external vector. The sample rate of the buffer is determined by 'clock'."); build.AddFunction("External-Asset", Nodes::GenericAsset::New(arg), "uri", "Loads an asset from 'uri' and returns its contents."); build.AddMacro("Audio-File-Tag", Nodes::Invariant::Constant::New(Type(&AudioFileTag)), true);