7 #ifndef SETINITIALVALUECODEGENBASE_H_
8 #define SETINITIALVALUECODEGENBASE_H_
10 #include "CodeGenBase.h"
11 #include "ModelGeneratorContext.h"
12 #include "SymbolForest.h"
13 #include "ASTNodeFactory.h"
14 #include "ModelDataIRBuilder.h"
15 #include "ModelInitialValueSymbolResolver.h"
16 #include "LLVMException.h"
18 #include <sbml/Model.h>
19 #include <Poco/Logger.h>
26 typedef bool (*SetInitialValueCodeGenBase_FunctionPtr)(LLVMModelData*, int32_t, double);
28 template <
typename Derived,
bool substanceUnits>
29 class SetInitialValueCodeGenBase :
30 public CodeGenBase<SetInitialValueCodeGenBase_FunctionPtr>
33 SetInitialValueCodeGenBase(
const ModelGeneratorContext& mgc);
34 virtual ~SetInitialValueCodeGenBase();
36 llvm::Value* codeGen();
38 typedef SetInitialValueCodeGenBase_FunctionPtr FunctionPtr;
42 template <
typename Derived,
bool substanceUnits>
43 SetInitialValueCodeGenBase<Derived, substanceUnits>::SetInitialValueCodeGenBase(
44 const ModelGeneratorContext& mgc) :
45 CodeGenBase<SetInitialValueCodeGenBase_FunctionPtr>(mgc)
49 template <
typename Derived,
bool substanceUnits>
50 SetInitialValueCodeGenBase<Derived, substanceUnits>::~SetInitialValueCodeGenBase()
54 template <
typename Derived,
bool substanceUnits>
55 llvm::Value* SetInitialValueCodeGenBase<Derived, substanceUnits>::codeGen()
58 llvm::Type* argTypes[] = {
59 llvm::PointerType::get(ModelDataIRBuilder::getStructType(this->module), 0),
60 llvm::Type::getInt32Ty(this->context),
61 llvm::Type::getDoubleTy(this->context)
64 const char* argNames[] = {
65 "modelData", Derived::IndexArgName,
"value"
68 llvm::Value* args[] = { 0, 0, 0 };
70 llvm::BasicBlock* entry = this->codeGenHeader(Derived::FunctionName, llvm::Type::getInt8Ty(this->context),
71 argTypes, argNames, args);
73 StringIntVector ids =
static_cast<Derived*
>(
this)->getIds();
75 ModelInitialValueSymbolResolver loadResolver(args[0], this->modelGenContext);
77 ModelInitialValueStoreSymbolResolver storeResolver(args[0], this->model, this->modelSymbols,
78 this->dataSymbols, this->builder, loadResolver);
81 llvm::BasicBlock* def = llvm::BasicBlock::Create(this->context,
"default", this->
function);
82 this->builder.SetInsertPoint(def);
85 this->builder.CreateRet(llvm::ConstantInt::get(llvm::Type::getInt8Ty(this->context), 0));
89 this->builder.SetInsertPoint(entry);
91 llvm::SwitchInst* s = this->builder.CreateSwitch(args[1], def,
static_cast<unsigned int>(ids.size()));
93 for (
int i = 0; i < ids.size(); ++i)
95 llvm::BasicBlock* block = llvm::BasicBlock::Create(this->context, ids[i].first +
"_block", this->
function);
96 this->builder.SetInsertPoint(block);
100 llvm::Value* value = args[2];
102 std::string element = ids[i].first;
106 const libsbml::SBase* sbase =
const_cast<libsbml::Model*
>(model)->getElementBySId(ids[i].first);
107 if (sbase && sbase->getTypeCode() == libsbml::SBML_SPECIES)
109 const libsbml::Species* species =
static_cast<const libsbml::Species*
>(sbase);
111 std::string compId = species->getCompartment();
113 llvm::Value* comp = loadResolver.loadSymbolValue(compId);
115 if (species->getHasOnlySubstanceUnits())
121 value = this->builder.CreateFMul(value, comp, ids[i].first +
"_amt");
130 value = this->builder.CreateFDiv(value, comp, ids[i].first +
"_value_conc");
136 storeResolver.storeSymbolValue(ids[i].first, value);
139 this->builder.CreateRet(llvm::ConstantInt::get(llvm::Type::getInt8Ty(this->context), 1));
140 s->addCase(llvm::ConstantInt::get(llvm::Type::getInt32Ty(this->context), ids[i].second), block);
143 return this->verifyFunction();