roadrunner  2.6.0
Fast simulator for SBML models
GetEventValuesCodeGen.h
1 /*
2  * GetEventValuesCodeGenBas.h
3  *
4  * Created on: Aug 10, 2013
5  * Author: andy
6  */
7 
8 #ifndef RRLLVMGETEVENTVALUECODEGENBASE_H_
9 #define RRLLVMGETEVENTVALUECODEGENBASE_H_
10 
11 #include "CodeGenBase.h"
12 #include "ModelGeneratorContext.h"
13 #include "SymbolForest.h"
14 #include "ASTNodeCodeGen.h"
15 #include "ASTNodeFactory.h"
16 #include "ModelDataIRBuilder.h"
17 #include "ModelDataSymbolResolver.h"
18 #include "LLVMException.h"
19 #include "rrLogger.h"
20 #include <sbml/Model.h>
21 #include <Poco/Logger.h>
22 #include <vector>
23 #include <cstdio>
24 
25 namespace rrllvm
26 {
27 
28  typedef double (*GetEventValueCodeGenBase_FunctionPtr)(LLVMModelData*, size_t);
29 
33  template <typename Derived, typename
34  FunctionPtrType = GetEventValueCodeGenBase_FunctionPtr>
36  public CodeGenBase<FunctionPtrType>
37  {
38  public:
41  {
42  };
43 
44  virtual ~GetEventValueCodeGenBase() {};
45 
46  llvm::Value* codeGen();
47 
48  typedef FunctionPtrType FunctionPtr;
49 
54  llvm::Type* getRetType()
55  {
56  return llvm::Type::getDoubleTy(this->context);
57  }
58 
62  llvm::Value* createRet(llvm::Value* value)
63  {
64  return value ? value :
65  llvm::ConstantFP::get(this->context, llvm::APFloat(123.456));
66  }
67 
68  };
69 
70  template <typename Derived, typename FunctionPtrType>
71  llvm::Value* GetEventValueCodeGenBase<Derived, FunctionPtrType>::codeGen()
72  {
73  // make the set init value function
74  llvm::Type* argTypes[] = {
75  llvm::PointerType::get(ModelDataIRBuilder::getStructType(this->module), 0),
76  llvm::Type::getInt32Ty(this->context)
77  };
78 
79  const char* argNames[] = {
80  "modelData", Derived::IndexArgName
81  };
82 
83  llvm::Value* args[] = { 0, 0 };
84 
85  llvm::Type* retType = static_cast<Derived*>(this)->getRetType();
86 
87  llvm::BasicBlock* entry = this->codeGenHeader(Derived::FunctionName, retType,
88  argTypes, argNames, args);
89 
90  const libsbml::ListOfEvents* events = this->model->getListOfEvents();
91 
92  ModelDataLoadSymbolResolver resolver(args[0], this->modelGenContext);
93 
94  ASTNodeCodeGen astCodeGen(this->builder, resolver, this->modelGenContext, args[0]);
95 
96  // default, return NaN
97  llvm::BasicBlock* def = llvm::BasicBlock::Create(this->context, "default", this->function);
98  this->builder.SetInsertPoint(def);
99 
100  llvm::Value* defRet = static_cast<Derived*>(this)->createRet(0);
101  this->builder.CreateRet(defRet);
102 
103  // write the switch at the func entry point, the switch is also the
104  // entry block terminator
105  this->builder.SetInsertPoint(entry);
106 
107  llvm::SwitchInst* s = this->builder.CreateSwitch(args[1], def, events->size());
108 
109  for (uint i = 0; i < events->size(); ++i)
110  {
111  char block_name[64];
112  std::sprintf(block_name, "event_%i_block", i);
113  llvm::BasicBlock* block = llvm::BasicBlock::Create(this->context, block_name, this->function);
114  this->builder.SetInsertPoint(block);
115  resolver.flushCache();
116 
117  const libsbml::Event* event = events->get(i);
118 
119  llvm::Value* value = static_cast<Derived*>(this)->getMath(event, astCodeGen);
120 
121  // convert type to return type
122  value = static_cast<Derived*>(this)->createRet(value);
123 
124  this->builder.CreateRet(value);
125  s->addCase(llvm::ConstantInt::get(llvm::Type::getInt32Ty(this->context), i), block);
126  }
127 
128  return this->verifyFunction();
129  }
130 
131  typedef unsigned char (*GetEventTriggerCodeGen_FunctionPtr)(LLVMModelData*, size_t);
132 
136  class GetEventTriggerCodeGen : public
137  GetEventValueCodeGenBase<GetEventTriggerCodeGen,
138  GetEventTriggerCodeGen_FunctionPtr>
139  {
140  public:
143 
144  llvm::Value* getMath(const libsbml::Event*, ASTNodeCodeGen& astCodeGen);
145 
146  static const char* FunctionName;
147  static const char* IndexArgName;
148 
149  llvm::Type* getRetType();
150 
151  llvm::Value* createRet(llvm::Value*);
152  };
153 
157  class GetEventPriorityCodeGen : public
158  GetEventValueCodeGenBase<GetEventPriorityCodeGen>
159  {
160  public:
163 
164  llvm::Value* getMath(const libsbml::Event*, ASTNodeCodeGen& astCodeGen);
165 
166  static const char* FunctionName;
167  static const char* IndexArgName;
168 
169  private:
170  libsbml::ASTNode* node;
171  };
172 
176  class GetEventDelayCodeGen : public
177  GetEventValueCodeGenBase<GetEventDelayCodeGen>
178  {
179  public:
182 
183  llvm::Value* getMath(const libsbml::Event*, ASTNodeCodeGen& astCodeGen);
184 
185  llvm::Value* createRet(llvm::Value* value)
186  {
187  // Return the value for the default label
188  if (!value)
189  return llvm::ConstantFP::get(this->context, llvm::APFloat(123.456));
190  // If the delay evaluates to a double then just return it
191  if (value->getType() == llvm::Type::getDoubleTy(context))
192  return value;
193  // Otherwise it's a boolean (i.e. an i1), so convert it to a double
194  return this->builder.CreateCast(llvm::Instruction::CastOps::UIToFP, value, llvm::Type::getDoubleTy(context));
195  }
196 
197  static const char* FunctionName;
198  static const char* IndexArgName;
199  private:
200  libsbml::ASTNode* node;
201  };
202 
203 
204 } /* namespace rr */
205 
206 
207 
208 
209 #endif /* RRLLVMGETVALUECODEGENBASE_H_ */
All of the LLVM IR generation is handled here.
Definition: ASTNodeCodeGen.h:31
a convenience class to pull the vars out of a context, and store them as ivars.
Definition: CodeGenBase.h:54
Get the delay of an SBML Event.
Definition: GetEventValuesCodeGen.h:178
Get the priority of an SBML Event.
Definition: GetEventValuesCodeGen.h:159
Get the trigger of an SBML Event.
Definition: GetEventValuesCodeGen.h:139
Base class for getting event values.
Definition: GetEventValuesCodeGen.h:37
llvm::Type * getRetType()
default ret type is double, derived classes must override if using non-default func sic
Definition: GetEventValuesCodeGen.h:54
llvm::Value * createRet(llvm::Value *value)
create a return type, a zero value should return the default type
Definition: GetEventValuesCodeGen.h:62
static llvm::StructType * getStructType(llvm::Module *module)
get the ModelData struct type.
Definition: ModelDataIRBuilder.cpp:731
All LLVM code generating objects basically need at a minimum three things to operate:
Definition: ModelGeneratorContext.h:95