1 /************************************************************************
2 ************************************************************************
3 FAUST compiler
4 Copyright (C) 2003-2018 GRAME, Centre National de Creation Musicale
5 ---------------------------------------------------------------------
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 ************************************************************************
20 ************************************************************************/
21
22 #ifndef _INSTRUCTIONS_H
23 #define _INSTRUCTIONS_H
24
25 #include <stdio.h>
26 #include <algorithm>
27 #include <iostream>
28 #include <list>
29 #include <map>
30 #include <set>
31 #include <sstream>
32 #include <stack>
33 #include <string>
34 #include <vector>
35
36 #ifdef WIN32
37 #pragma warning(disable : 4800)
38 #endif
39
40 #include "Text.hh"
41 #include "binop.hh"
42 #include "exception.hh"
43 #include "garbageable.hh"
44 #include "instructions_type.hh"
45 #include "property.hh"
46 #include "sigtype.hh"
47
48 // ============================
49 // Generic instruction visitor
50 // ============================
51
52 struct Printable;
53 struct NullValueInst;
54 struct NullStatementInst;
55 struct DeclareVarInst;
56 struct DeclareBufferIterators;
57 struct DeclareFunInst;
58 struct DeclareStructTypeInst;
59 struct LoadVarInst;
60 struct LoadVarAddressInst;
61 struct TeeVarInst;
62 struct StoreVarInst;
63 struct ShiftArrayVarInst;
64 template <class TYPE>
65 struct ArrayNumInst;
66 struct FloatNumInst;
67 struct FloatArrayNumInst;
68 struct Int32NumInst;
69 struct Int64NumInst;
70 struct Int32ArrayNumInst;
71 struct BoolNumInst;
72 struct DoubleNumInst;
73 struct DoubleArrayNumInst;
74 struct FixedPointNumInst;
75 struct FixedPointArrayNumInst;
76 struct BinopInst;
77 struct CastInst;
78 struct BitcastInst;
79 struct RetInst;
80 struct DropInst;
81
82 struct FunCallInst;
83 struct Select2Inst;
84 struct ControlInst;
85 struct IfInst;
86 struct ForLoopInst;
87 struct SimpleForLoopInst;
88 struct IteratorForLoopInst;
89 struct WhileLoopInst;
90 struct BlockInst;
91 struct SwitchInst;
92
93 // User interface
94 struct AddMetaDeclareInst;
95 struct OpenboxInst;
96 struct CloseboxInst;
97 struct AddButtonInst;
98 struct AddSliderInst;
99 struct AddBargraphInst;
100 struct AddSoundfileInst;
101 struct LabelInst;
102
103 struct Typed;
104 struct Address;
105 struct ValueInst;
106 struct StatementInst;
107
108 struct BasicTyped;
109 struct NamedTyped;
110 struct FunTyped;
111 struct ArrayTyped;
112 struct StructTyped;
113 struct VectorTyped;
114
115 struct NamedAddress;
116 struct IndexedAddress;
117
118 // Type checking
119
isRealType(Typed::VarType type)120 inline bool isRealType(Typed::VarType type)
121 {
122 return (type == Typed::kFloat || type == Typed::kFloatMacro || type == Typed::kDouble);
123 }
124
isRealPtrType(Typed::VarType type)125 inline bool isRealPtrType(Typed::VarType type)
126 {
127 return (type == Typed::kFloat_ptr
128 || type == Typed::kFloat_ptr_ptr
129 || type == Typed::kFloatMacro_ptr
130 || type == Typed::kFloatMacro_ptr_ptr
131 || type == Typed::kDouble_ptr
132 || type == Typed::kDouble_ptr_ptr);
133 }
134
isIntType(Typed::VarType type)135 inline bool isIntType(Typed::VarType type)
136 {
137 return (type == Typed::kInt32 || type == Typed::kInt64);
138 }
139
isInt32Type(Typed::VarType type)140 inline bool isInt32Type(Typed::VarType type)
141 {
142 return (type == Typed::kInt32);
143 }
144
isInt64Type(Typed::VarType type)145 inline bool isInt64Type(Typed::VarType type)
146 {
147 return (type == Typed::kInt64);
148 }
149
isFloatType(Typed::VarType type)150 inline bool isFloatType(Typed::VarType type)
151 {
152 return (type == Typed::kFloat);
153 }
154
isDoubleType(Typed::VarType type)155 inline bool isDoubleType(Typed::VarType type)
156 {
157 return (type == Typed::kDouble);
158 }
159
isIntPtrType(Typed::VarType type)160 inline bool isIntPtrType(Typed::VarType type)
161 {
162 return (type == Typed::kInt32_ptr || type == Typed::kInt64_ptr);
163 }
164
isPtrType(Typed::VarType type)165 inline bool isPtrType(Typed::VarType type)
166 {
167 return isRealPtrType(type) || isIntPtrType(type);
168 }
169
isBoolType(Typed::VarType type)170 inline bool isBoolType(Typed::VarType type)
171 {
172 return (type == Typed::kBool);
173 }
174
isIntOrPtrType(Typed::VarType type)175 inline bool isIntOrPtrType(Typed::VarType type)
176 {
177 return (isIntType(type)
178 || isIntPtrType(type)
179 || isRealPtrType(type)
180 || type == Typed::kVoid_ptr
181 || type == Typed::kObj_ptr
182 || type == Typed::kSound_ptr);
183 }
184
185 DeclareStructTypeInst* isStructType(const string& name);
186
187 // =========
188 // Visitors
189 // =========
190
191 struct InstVisitor : public virtual Garbageable {
InstVisitorInstVisitor192 InstVisitor() {}
~InstVisitorInstVisitor193 virtual ~InstVisitor() {}
194
195 // User interface
visitInstVisitor196 virtual void visit(AddMetaDeclareInst* inst) {}
visitInstVisitor197 virtual void visit(OpenboxInst* inst) {}
visitInstVisitor198 virtual void visit(CloseboxInst* inst) {}
visitInstVisitor199 virtual void visit(AddButtonInst* inst) {}
visitInstVisitor200 virtual void visit(AddSliderInst* inst) {}
visitInstVisitor201 virtual void visit(AddBargraphInst* inst) {}
visitInstVisitor202 virtual void visit(AddSoundfileInst* inst) {}
203
visitInstVisitor204 virtual void visit(LabelInst* inst) {}
205
visitInstVisitor206 virtual void visit(Printable* inst) {}
visitInstVisitor207 virtual void visit(NullValueInst* inst) {}
visitInstVisitor208 virtual void visit(NullStatementInst* inst) {}
209
210 // Declarations
visitInstVisitor211 virtual void visit(DeclareVarInst* inst) {}
visitInstVisitor212 virtual void visit(DeclareFunInst* inst) {}
visitInstVisitor213 virtual void visit(DeclareStructTypeInst* inst) {}
visitInstVisitor214 virtual void visit(DeclareBufferIterators* inst) {}
215
216 // Memory
visitInstVisitor217 virtual void visit(LoadVarInst* inst) {}
visitInstVisitor218 virtual void visit(LoadVarAddressInst* inst) {}
visitInstVisitor219 virtual void visit(TeeVarInst* inst) {}
visitInstVisitor220 virtual void visit(StoreVarInst* inst) {}
visitInstVisitor221 virtual void visit(ShiftArrayVarInst* inst) {}
222
223 // Addresses
visitInstVisitor224 virtual void visit(NamedAddress* address) {}
visitInstVisitor225 virtual void visit(IndexedAddress* address) {}
226
227 // Numbers
visitInstVisitor228 virtual void visit(FloatNumInst* inst) {}
visitInstVisitor229 virtual void visit(FloatArrayNumInst* inst) {}
visitInstVisitor230 virtual void visit(Int32NumInst* inst) {}
visitInstVisitor231 virtual void visit(Int64NumInst* inst) {}
visitInstVisitor232 virtual void visit(Int32ArrayNumInst* inst) {}
visitInstVisitor233 virtual void visit(BoolNumInst* inst) {}
visitInstVisitor234 virtual void visit(DoubleNumInst* inst) {}
visitInstVisitor235 virtual void visit(DoubleArrayNumInst* inst) {}
visitInstVisitor236 virtual void visit(FixedPointNumInst* inst) {}
visitInstVisitor237 virtual void visit(FixedPointArrayNumInst* inst) {}
238
239 // Numerical computation
visitInstVisitor240 virtual void visit(BinopInst* inst) {}
241
242 // Cast
visitInstVisitor243 virtual void visit(CastInst* inst) {}
visitInstVisitor244 virtual void visit(BitcastInst* inst) {}
245
246 // Function call
visitInstVisitor247 virtual void visit(FunCallInst* inst) {}
visitInstVisitor248 virtual void visit(RetInst* inst) {}
visitInstVisitor249 virtual void visit(DropInst* inst) {}
250
251 // Conditional
visitInstVisitor252 virtual void visit(Select2Inst* inst) {}
visitInstVisitor253 virtual void visit(ControlInst* inst) {}
visitInstVisitor254 virtual void visit(IfInst* inst) {}
visitInstVisitor255 virtual void visit(SwitchInst* inst) {}
256
257 // Loops
visitInstVisitor258 virtual void visit(ForLoopInst* inst) {}
visitInstVisitor259 virtual void visit(SimpleForLoopInst* inst) {}
visitInstVisitor260 virtual void visit(IteratorForLoopInst* inst) {}
visitInstVisitor261 virtual void visit(WhileLoopInst* inst) {}
262
263 // Block
visitInstVisitor264 virtual void visit(BlockInst* inst) {}
265
266 // Typed
visitInstVisitor267 virtual void visit(BasicTyped* typed) {}
visitInstVisitor268 virtual void visit(NamedTyped* typed) {}
visitInstVisitor269 virtual void visit(FunTyped* typed) {}
visitInstVisitor270 virtual void visit(ArrayTyped* typed) {}
visitInstVisitor271 virtual void visit(StructTyped* typed) {}
visitInstVisitor272 virtual void visit(VectorTyped* typed) {}
273 };
274
275 // Clone a FIR expression
276
277 struct CloneVisitor : public virtual Garbageable {
CloneVisitorCloneVisitor278 CloneVisitor() {}
~CloneVisitorCloneVisitor279 virtual ~CloneVisitor() {}
280
281 virtual ValueInst* visit(NullValueInst* inst) = 0;
282 virtual StatementInst* visit(NullStatementInst* inst) = 0;
283
284 // Declarations
285 virtual StatementInst* visit(DeclareVarInst* inst) = 0;
286 virtual StatementInst* visit(DeclareFunInst* inst) = 0;
287 virtual StatementInst* visit(DeclareStructTypeInst* inst) = 0;
288 virtual StatementInst* visit(DeclareBufferIterators* inst) = 0;
289
290 // Memory
291 virtual ValueInst* visit(LoadVarInst* inst) = 0;
292 virtual ValueInst* visit(LoadVarAddressInst* inst) = 0;
293 virtual ValueInst* visit(TeeVarInst* inst) = 0;
294 virtual StatementInst* visit(StoreVarInst* inst) = 0;
295 virtual StatementInst* visit(ShiftArrayVarInst* inst) = 0;
296
297 // Addresses
298 virtual Address* visit(NamedAddress* address) = 0;
299 virtual Address* visit(IndexedAddress* address) = 0;
300
301 // Numbers
302 virtual ValueInst* visit(FloatNumInst* inst) = 0;
303 virtual ValueInst* visit(FloatArrayNumInst* inst) = 0;
304 virtual ValueInst* visit(Int32NumInst* inst) = 0;
305 virtual ValueInst* visit(Int64NumInst* inst) = 0;
306 virtual ValueInst* visit(Int32ArrayNumInst* inst) = 0;
307 virtual ValueInst* visit(BoolNumInst* inst) = 0;
308 virtual ValueInst* visit(DoubleNumInst* inst) = 0;
309 virtual ValueInst* visit(DoubleArrayNumInst* inst) = 0;
310 virtual ValueInst* visit(FixedPointNumInst* inst) = 0;
311 virtual ValueInst* visit(FixedPointArrayNumInst* inst) = 0;
312
313 // Numerical computation
314 virtual ValueInst* visit(BinopInst* inst) = 0;
315
316 // Cast
317 virtual ValueInst* visit(CastInst* inst) = 0;
318 virtual ValueInst* visit(BitcastInst* inst) = 0;
319
320 // Function call
321 virtual ValueInst* visit(FunCallInst* inst) = 0;
322 virtual StatementInst* visit(RetInst* inst) = 0;
323 virtual StatementInst* visit(DropInst* inst) = 0;
324
325 // Conditional
326 virtual ValueInst* visit(Select2Inst* inst) = 0;
327 virtual StatementInst* visit(ControlInst* inst) = 0;
328 virtual StatementInst* visit(IfInst* inst) = 0;
329 virtual StatementInst* visit(SwitchInst* inst) = 0;
330
331 // Loops
332 virtual StatementInst* visit(ForLoopInst* inst) = 0;
333 virtual StatementInst* visit(SimpleForLoopInst* inst) = 0;
334 virtual StatementInst* visit(IteratorForLoopInst* inst) = 0;
335 virtual StatementInst* visit(WhileLoopInst* inst) = 0;
336
337 // Block
338 virtual StatementInst* visit(BlockInst* inst) = 0;
339
340 // User interface
341 virtual StatementInst* visit(AddMetaDeclareInst* inst) = 0;
342 virtual StatementInst* visit(OpenboxInst* inst) = 0;
343 virtual StatementInst* visit(CloseboxInst* inst) = 0;
344 virtual StatementInst* visit(AddButtonInst* inst) = 0;
345 virtual StatementInst* visit(AddSliderInst* inst) = 0;
346 virtual StatementInst* visit(AddBargraphInst* inst) = 0;
347 virtual StatementInst* visit(AddSoundfileInst* inst) = 0;
348 virtual StatementInst* visit(LabelInst* inst) = 0;
349
350 // Types
351 virtual Typed* visit(BasicTyped* type) = 0;
352 virtual Typed* visit(NamedTyped* type) = 0;
353 virtual Typed* visit(FunTyped* type) = 0;
354 virtual Typed* visit(ArrayTyped* type) = 0;
355 virtual Typed* visit(StructTyped* type) = 0;
356 virtual Typed* visit(VectorTyped* type) = 0;
357 };
358
359 // ============================
360 // Base class for instructions
361 // ============================
362
363 // Printable is defined in instructions_type.h
364
365 // Added in compilation environment
366 struct StatementInst : public Printable {
367 virtual void accept(InstVisitor* visitor) = 0;
368
369 virtual StatementInst* clone(CloneVisitor* cloner) = 0;
370
getNameStatementInst371 virtual string getName() const { return ""; }
372 };
373
374 // Results from the compilation
375 struct ValueInst : public Printable {
376 virtual void accept(InstVisitor* visitor) = 0;
377
378 virtual ValueInst* clone(CloneVisitor* cloner) = 0;
379
ValueInstValueInst380 ValueInst() {}
381
sizeValueInst382 virtual int size() const { return 1; }
383
isSimpleValueValueInst384 virtual bool isSimpleValue() const { return false; }
385 };
386
387 // =======================
388 // Null value instruction
389 // =======================
390
391 struct NullValueInst : public ValueInst {
NullValueInstNullValueInst392 NullValueInst() {}
393
acceptNullValueInst394 virtual void accept(InstVisitor* visitor) { visitor->visit(this); }
395
cloneNullValueInst396 ValueInst* clone(CloneVisitor* cloner) { return cloner->visit(this); }
397 };
398
399 // ===========================
400 // Null statement instruction
401 // ===========================
402
403 struct NullStatementInst : public StatementInst {
NullStatementInstNullStatementInst404 NullStatementInst() {}
405
acceptNullStatementInst406 virtual void accept(InstVisitor* visitor) { visitor->visit(this); }
407
cloneNullStatementInst408 StatementInst* clone(CloneVisitor* cloner) { return cloner->visit(this); }
409 };
410
411 // ==========================
412 // Instruction with a type
413 // ==========================
414
415 // Base type is defined in instructions_type.h
416
417 Typed::VarType ctType(Type t);
418
419 struct BasicTyped : public Typed {
420 const VarType fType;
421
422 static void cleanup();
423
BasicTypedBasicTyped424 BasicTyped(VarType type) : fType(type) {}
425
getTypeBasicTyped426 VarType getType() const { return fType; }
427
428 int getSize() const; // moved in "instructions.cpp"
429
acceptBasicTyped430 virtual void accept(InstVisitor* visitor) { visitor->visit(this); }
431
cloneBasicTyped432 Typed* clone(CloneVisitor* cloner) { return cloner->visit(this); }
433 };
434
435 struct NamedTyped : public Typed {
436 const string fName;
437 Typed* fType;
438
NamedTypedNamedTyped439 NamedTyped(const string& name, Typed* type) : fName(name), fType(type) {}
440
~NamedTypedNamedTyped441 virtual ~NamedTyped() {}
442
getTypeNamedTyped443 VarType getType() const { return fType->getType(); }
444
getSizeNamedTyped445 int getSize() const { return fType->getSize(); }
446
acceptNamedTyped447 virtual void accept(InstVisitor* visitor) { visitor->visit(this); }
448
cloneNamedTyped449 Typed* clone(CloneVisitor* cloner) { return cloner->visit(this); }
450 };
451
452 struct FunTyped : public Typed {
453 enum FunAttribute { kDefault = 0x1, kLocal = 0x2, kVirtual = 0x4, kStatic = 0x8, kInline = 0x10 };
454
455 list<NamedTyped*> fArgsTypes;
456 BasicTyped* fResult;
457 FunAttribute fAttribute;
458
FunTypedFunTyped459 FunTyped(const list<NamedTyped*>& args, BasicTyped* result, FunAttribute attribute = kDefault)
460 : fArgsTypes(args), fResult(result), fAttribute(attribute)
461 {
462 }
463
getTypeFunTyped464 VarType getType() const { return fResult->getType(); }
465
getTypedFunTyped466 Typed* getTyped() { return fResult; }
467
468 // Arguments type encoded as a string
getPrototypeFunTyped469 string getPrototype()
470 {
471 string res;
472 if (fArgsTypes.size() > 0) {
473 for (const auto& it : fArgsTypes) {
474 res += gTypeString[it->getType()];
475 }
476 } else {
477 res = "void";
478 }
479 return res;
480 }
481
482 int getSize() const; // moved in "instructions.cpp"
483
acceptFunTyped484 virtual void accept(InstVisitor* visitor) { visitor->visit(this); }
485
cloneFunTyped486 Typed* clone(CloneVisitor* cloner) { return cloner->visit(this); }
487 };
488
489 struct ArrayTyped : public Typed {
490 Typed* fType;
491 const int fSize;
492 const bool fIsPtr;
493
ArrayTypedArrayTyped494 ArrayTyped(Typed* type, int size, bool is_ptr = false) : fType(type), fSize(size), fIsPtr(is_ptr) {}
495
~ArrayTypedArrayTyped496 virtual ~ArrayTyped() {}
497
getTypeArrayTyped498 VarType getType() const { return getPtrFromType(fType->getType()); }
499
500 int getSize() const; // moved in "instructions.cpp"
501
acceptArrayTyped502 virtual void accept(InstVisitor* visitor) { visitor->visit(this); }
503
cloneArrayTyped504 Typed* clone(CloneVisitor* cloner) { return cloner->visit(this); }
505 };
506
507 struct StructTyped : public Typed {
508 const string fName;
509 vector<NamedTyped*> fFields;
510
StructTypedStructTyped511 StructTyped(const string& name, const vector<NamedTyped*>& fields) : fName(name), fFields(fields) {}
512
~StructTypedStructTyped513 virtual ~StructTyped() {}
514
getTypeStructTyped515 VarType getType() const { return kObj_ptr; }
getTypeStructTyped516 VarType getType(int index) { return fFields[index]->getType(); }
517
getSizeStructTyped518 int getSize() const
519 {
520 int size = 0;
521 for (const auto& it : fFields) {
522 size += it->getSize();
523 }
524 return size;
525 }
526
getOffsetStructTyped527 int getOffset(int field) const
528 {
529 int offset = 0;
530 for (int i = 0; i < field; i++) {
531 offset += fFields[i]->getSize();
532 }
533 return offset;
534 }
535
getNameStructTyped536 string getName(int index) { return fFields[index]->fName; }
537
acceptStructTyped538 virtual void accept(InstVisitor* visitor) { visitor->visit(this); }
539
cloneStructTyped540 Typed* clone(CloneVisitor* cloner) { return cloner->visit(this); }
541 };
542
543 struct VectorTyped : public Typed {
544 BasicTyped* fType;
545 const int fSize;
546
VectorTypedVectorTyped547 VectorTyped(BasicTyped* type, int size) : fType(type), fSize(size) {}
548
~VectorTypedVectorTyped549 virtual ~VectorTyped() {}
550
getTypeVectorTyped551 VarType getType() const { return getVecFromType(fType->getType()); }
552
getSizeVectorTyped553 int getSize() const { return fType->getSize() * fSize; }
554
acceptVectorTyped555 virtual void accept(InstVisitor* visitor) { visitor->visit(this); }
556
cloneVectorTyped557 Typed* clone(CloneVisitor* cloner) { return cloner->visit(this); }
558 };
559
560 struct NumValueInst {
561 };
562
563 // ===========
564 // Addresses
565 // ===========
566
567 struct Address : public Printable {
568 enum AccessType {
569 kStruct = 0x1,
570 kStaticStruct = 0x2, // Static shared variable between all DSPs
571 kFunArgs = 0x4,
572 kStack = 0x8,
573 kGlobal = 0x10,
574 kLink = 0x20,
575 kLoop = 0x40,
576 kVolatile = 0x80,
577 kReference = 0x100, // Access by reference (for Rust backend)
578 kMutable = 0x200, // Mutable access (for Rust backend)
579 kConst = 0x400 // Const access
580 };
581
AddressAddress582 Address() {}
583
584 virtual void setAccess(Address::AccessType type) = 0;
585 virtual Address::AccessType getAccess() const = 0;
586
587 virtual void setName(const string& name) = 0;
588 virtual string getName() const = 0;
589
dumpAddress590 static void dump(AccessType access) { *fOut << dumpString(access); }
591
592 #define hasAccess(arg) res += (res != "") ? (string("|") + string(arg)) : string(arg);
593
dumpStringAddress594 static string dumpString(AccessType access)
595 {
596 string res;
597 if (access & kStruct) hasAccess("kStruct");
598 if (access & kStaticStruct) hasAccess("kStaticStruct");
599 if (access & kFunArgs) hasAccess("kFunArgs");
600 if (access & kStack) hasAccess("kStack");
601 if (access & kGlobal) hasAccess("kGlobal");
602 if (access & kLink) hasAccess("kLink");
603 if (access & kLoop) hasAccess("kLoop");
604 if (access & kVolatile) hasAccess("kVolatile");
605 if (access & kReference) hasAccess("kReference");
606 if (access & kMutable) hasAccess("kMutable");
607 if (access & kConst) hasAccess("kConst");
608 return res;
609 }
610
611 virtual Address* clone(CloneVisitor* cloner) = 0;
612
613 virtual void accept(InstVisitor* visitor) = 0;
614 };
615
616 struct NamedAddress : public Address {
617 string fName;
618 AccessType fAccess;
619
NamedAddressNamedAddress620 NamedAddress(const string& name, AccessType access) : fName(name), fAccess(access) {}
621
setAccessNamedAddress622 void setAccess(Address::AccessType type) { fAccess = type; }
getAccessNamedAddress623 Address::AccessType getAccess() const { return fAccess; }
624
setNameNamedAddress625 void setName(const string& name) { fName = name; }
getNameNamedAddress626 string getName() const { return fName; }
627
cloneNamedAddress628 Address* clone(CloneVisitor* cloner) { return cloner->visit(this); }
629
acceptNamedAddress630 void accept(InstVisitor* visitor) { visitor->visit(this); }
631 };
632
633 struct IndexedAddress : public Address {
634 Address* fAddress;
635 ValueInst* fIndex;
636
IndexedAddressIndexedAddress637 IndexedAddress(Address* address, ValueInst* index) : fAddress(address), fIndex(index) {}
638
~IndexedAddressIndexedAddress639 virtual ~IndexedAddress() {}
640
setAccessIndexedAddress641 void setAccess(Address::AccessType type) { fAddress->setAccess(type); }
getAccessIndexedAddress642 Address::AccessType getAccess() const { return fAddress->getAccess(); }
643
setNameIndexedAddress644 void setName(const string& name) { fAddress->setName(name); }
getNameIndexedAddress645 string getName() const { return fAddress->getName(); }
646
getIndexIndexedAddress647 ValueInst* getIndex() const { return fIndex; }
648
cloneIndexedAddress649 Address* clone(CloneVisitor* cloner) { return cloner->visit(this); }
650
acceptIndexedAddress651 void accept(InstVisitor* visitor) { visitor->visit(this); }
652 };
653
654 // ===============
655 // User interface
656 // ===============
657
658 struct AddMetaDeclareInst : public StatementInst {
659 const string fZone;
660 const string fKey;
661 const string fValue;
662
AddMetaDeclareInstAddMetaDeclareInst663 AddMetaDeclareInst(const string& zone, const string& key, const string& value)
664 : fZone(zone), fKey(key), fValue(value)
665 {
666 }
667
acceptAddMetaDeclareInst668 void accept(InstVisitor* visitor) { visitor->visit(this); }
669
cloneAddMetaDeclareInst670 StatementInst* clone(CloneVisitor* cloner) { return cloner->visit(this); }
671 };
672
673 struct OpenboxInst : public StatementInst {
674 enum BoxType { kVerticalBox, kHorizontalBox, kTabBox };
675
676 const string fName;
677 const BoxType fOrient;
678
OpenboxInstOpenboxInst679 OpenboxInst(const string& name, BoxType orient) : fName(name), fOrient(orient) {}
680
acceptOpenboxInst681 void accept(InstVisitor* visitor) { visitor->visit(this); }
682
cloneOpenboxInst683 StatementInst* clone(CloneVisitor* cloner) { return cloner->visit(this); }
684 };
685
686 struct CloseboxInst : public StatementInst {
CloseboxInstCloseboxInst687 CloseboxInst() {}
688
acceptCloseboxInst689 void accept(InstVisitor* visitor) { visitor->visit(this); }
690
cloneCloseboxInst691 StatementInst* clone(CloneVisitor* cloner) { return cloner->visit(this); }
692 };
693
694 struct AddButtonInst : public StatementInst {
695 enum ButtonType { kDefaultButton, kCheckButton };
696
697 const string fLabel;
698 const string fZone;
699 const ButtonType fType;
700
AddButtonInstAddButtonInst701 AddButtonInst(const string& label, const string& zone, ButtonType type) : fLabel(label), fZone(zone), fType(type) {}
702
acceptAddButtonInst703 void accept(InstVisitor* visitor) { visitor->visit(this); }
704
cloneAddButtonInst705 StatementInst* clone(CloneVisitor* cloner) { return cloner->visit(this); }
706 };
707
708 struct AddSliderInst : public StatementInst {
709 enum SliderType { kHorizontal, kVertical, kNumEntry };
710
711 const string fLabel;
712 const string fZone;
713 const double fInit;
714 const double fMin;
715 const double fMax;
716 const double fStep;
717 const SliderType fType;
718
AddSliderInstAddSliderInst719 AddSliderInst(const string& label, const string& zone, double init, double min, double max, double step,
720 SliderType type)
721 : fLabel(label), fZone(zone), fInit(init), fMin(min), fMax(max), fStep(step), fType(type)
722 {
723 }
724
acceptAddSliderInst725 void accept(InstVisitor* visitor) { visitor->visit(this); }
726
cloneAddSliderInst727 StatementInst* clone(CloneVisitor* cloner) { return cloner->visit(this); }
728 };
729
730 struct AddBargraphInst : public StatementInst {
731 enum BargraphType { kHorizontal, kVertical };
732
733 const string fLabel;
734 const string fZone;
735 const double fMin;
736 const double fMax;
737 const BargraphType fType;
738
AddBargraphInstAddBargraphInst739 AddBargraphInst(const string& label, const string& zone, double min, double max, BargraphType type)
740 : fLabel(label), fZone(zone), fMin(min), fMax(max), fType(type)
741 {
742 }
743
acceptAddBargraphInst744 void accept(InstVisitor* visitor) { visitor->visit(this); }
745
cloneAddBargraphInst746 StatementInst* clone(CloneVisitor* cloner) { return cloner->visit(this); }
747 };
748
749 struct AddSoundfileInst : public StatementInst {
750 const string fLabel;
751 const string fURL;
752 const string fSFZone;
753
AddSoundfileInstAddSoundfileInst754 AddSoundfileInst(const string& label, const string& url, const string& sf_zone)
755 : fLabel(label), fURL(url), fSFZone(sf_zone)
756 {
757 }
758
acceptAddSoundfileInst759 void accept(InstVisitor* visitor) { visitor->visit(this); }
760
cloneAddSoundfileInst761 StatementInst* clone(CloneVisitor* cloner) { return cloner->visit(this); }
762 };
763
764 struct LabelInst : public StatementInst {
765 const string fLabel;
766
LabelInstLabelInst767 LabelInst(const string& label) : fLabel(label) {}
768
acceptLabelInst769 void accept(InstVisitor* visitor) { visitor->visit(this); }
770
cloneLabelInst771 StatementInst* clone(CloneVisitor* cloner) { return cloner->visit(this); }
772 };
773
774 // =============
775 // Declarations
776 // =============
777
778 struct DeclareVarInst : public StatementInst {
779 Address* fAddress;
780 Typed* fType;
781 ValueInst* fValue;
782
783 static void cleanup();
784
785 DeclareVarInst(Address* address, Typed* typed, ValueInst* value);
786
~DeclareVarInstDeclareVarInst787 virtual ~DeclareVarInst() {}
788
setAccessDeclareVarInst789 void setAccess(Address::AccessType type) { fAddress->setAccess(type); }
getAccessDeclareVarInst790 Address::AccessType getAccess() const { return fAddress->getAccess(); }
791
setNameDeclareVarInst792 void setName(const string& name) { fAddress->setName(name); }
getNameDeclareVarInst793 string getName() const { return fAddress->getName(); }
794
acceptDeclareVarInst795 void accept(InstVisitor* visitor) { visitor->visit(this); }
796
cloneDeclareVarInst797 StatementInst* clone(CloneVisitor* cloner) { return cloner->visit(this); }
798
799 struct StoreVarInst* store(ValueInst* val);
800 struct LoadVarInst* load();
801 };
802
803 struct DeclareBufferIterators : public StatementInst {
804 std::string fBufferName1;
805 std::string fBufferName2;
806 int fNumChannels;
807 bool fMutable;
808
DeclareBufferIteratorsDeclareBufferIterators809 DeclareBufferIterators(const std::string& name1, const std::string& name2, int num_channels, bool mut) :
810 fBufferName1(name1), fBufferName2(name2), fNumChannels(num_channels), fMutable(mut)
811 {};
812
~DeclareBufferIteratorsDeclareBufferIterators813 virtual ~DeclareBufferIterators() {}
814
acceptDeclareBufferIterators815 void accept(InstVisitor* visitor) { visitor->visit(this); }
816
cloneDeclareBufferIterators817 StatementInst* clone(CloneVisitor* cloner) { return cloner->visit(this); }
818 };
819
820 // ==============
821 // Memory access
822 // ==============
823
824 struct DropInst : public StatementInst {
825 ValueInst* fResult;
826
DropInstDropInst827 DropInst(ValueInst* result = nullptr) : fResult(result) {}
828
~DropInstDropInst829 virtual ~DropInst() {}
830
acceptDropInst831 void accept(InstVisitor* visitor) { visitor->visit(this); }
832
cloneDropInst833 StatementInst* clone(CloneVisitor* cloner) { return cloner->visit(this); }
834 };
835
836 struct LoadVarInst : public ValueInst {
837 Address* fAddress;
838
LoadVarInstLoadVarInst839 LoadVarInst(Address* address) : ValueInst(), fAddress(address) {}
840
~LoadVarInstLoadVarInst841 virtual ~LoadVarInst() {}
842
setNameLoadVarInst843 void setName(const string& name) { fAddress->setName(name); }
getNameLoadVarInst844 string getName() const { return fAddress->getName(); }
845
acceptLoadVarInst846 void accept(InstVisitor* visitor) { visitor->visit(this); }
847
cloneLoadVarInst848 ValueInst* clone(CloneVisitor* cloner) { return cloner->visit(this); }
849
850 virtual bool isSimpleValue() const;
851
852 };
853
854 struct LoadVarAddressInst : public ValueInst {
855 Address* fAddress;
856
LoadVarAddressInstLoadVarAddressInst857 LoadVarAddressInst(Address* address) : ValueInst(), fAddress(address) {}
858
~LoadVarAddressInstLoadVarAddressInst859 virtual ~LoadVarAddressInst() {}
860
setNameLoadVarAddressInst861 void setName(const string& name) { fAddress->setName(name); }
getNameLoadVarAddressInst862 string getName() const { return fAddress->getName(); }
863
acceptLoadVarAddressInst864 void accept(InstVisitor* visitor) { visitor->visit(this); }
865
cloneLoadVarAddressInst866 ValueInst* clone(CloneVisitor* cloner) { return cloner->visit(this); }
867
isSimpleValueLoadVarAddressInst868 virtual bool isSimpleValue() const { return dynamic_cast<NamedAddress*>(fAddress); }
869 };
870
871 // Special for wast/wasm backend : combine a store and a load
872 struct TeeVarInst : public ValueInst {
873 Address* fAddress;
874 ValueInst* fValue;
875
TeeVarInstTeeVarInst876 TeeVarInst(Address* address, ValueInst* value) : ValueInst(), fAddress(address), fValue(value) {}
877
~TeeVarInstTeeVarInst878 virtual ~TeeVarInst() {}
879
setNameTeeVarInst880 void setName(const string& name) { fAddress->setName(name); }
getNameTeeVarInst881 string getName() const { return fAddress->getName(); }
882
acceptTeeVarInst883 void accept(InstVisitor* visitor) { visitor->visit(this); }
884
cloneTeeVarInst885 ValueInst* clone(CloneVisitor* cloner) { return cloner->visit(this); }
886 };
887
888 struct StoreVarInst : public StatementInst {
889 Address* fAddress;
890 ValueInst* fValue;
891
StoreVarInstStoreVarInst892 StoreVarInst(Address* address, ValueInst* value) : fAddress(address), fValue(value) {}
893
~StoreVarInstStoreVarInst894 virtual ~StoreVarInst() {}
895
setNameStoreVarInst896 void setName(const string& name) { fAddress->setName(name); }
getNameStoreVarInst897 string getName() const { return fAddress->getName(); }
898
acceptStoreVarInst899 void accept(InstVisitor* visitor) { visitor->visit(this); }
900
cloneStoreVarInst901 StatementInst* clone(CloneVisitor* cloner) { return cloner->visit(this); }
902 };
903
904 struct ShiftArrayVarInst : public StatementInst {
905 Address* fAddress;
906 const int fDelay;
907
ShiftArrayVarInstShiftArrayVarInst908 ShiftArrayVarInst(Address* address, int delay) : fAddress(address), fDelay(delay) {}
909
~ShiftArrayVarInstShiftArrayVarInst910 virtual ~ShiftArrayVarInst() {}
911
acceptShiftArrayVarInst912 void accept(InstVisitor* visitor) { visitor->visit(this); }
913
cloneShiftArrayVarInst914 StatementInst* clone(CloneVisitor* cloner) { return cloner->visit(this); }
915 };
916
917 // ========
918 // Numbers
919 // ========
920
921 struct FloatNumInst : public ValueInst, public NumValueInst {
922 const float fNum;
923
FloatNumInstFloatNumInst924 FloatNumInst(float num) : ValueInst(), fNum(num) {}
925
acceptFloatNumInst926 void accept(InstVisitor* visitor) { visitor->visit(this); }
927
cloneFloatNumInst928 ValueInst* clone(CloneVisitor* cloner) { return cloner->visit(this); }
929
isSimpleValueFloatNumInst930 virtual bool isSimpleValue() const { return true; }
931 };
932
933 template <class TYPE>
934 struct ArrayNumInst : public ValueInst {
935 vector<TYPE> fNumTable;
936
ArrayNumInstArrayNumInst937 ArrayNumInst(const vector<TYPE>& nums) : ValueInst(), fNumTable(nums) {}
938
ArrayNumInstArrayNumInst939 ArrayNumInst(int size) : ValueInst() { fNumTable.resize(size); }
940
setValueArrayNumInst941 void setValue(int index, TYPE num) { fNumTable[index] = num; }
addValueArrayNumInst942 void addValue(TYPE num) { fNumTable.push_back(num); }
getValueArrayNumInst943 TYPE getValue(int index) { return fNumTable[index]; }
944
acceptArrayNumInst945 void accept(InstVisitor* visitor) { visitor->visit(this); }
946
isSimpleValueArrayNumInst947 virtual bool isSimpleValue() const { return true; }
948 };
949
950 struct FloatArrayNumInst : public ArrayNumInst<float> {
FloatArrayNumInstFloatArrayNumInst951 FloatArrayNumInst(const vector<float>& nums) : ArrayNumInst<float>(nums) {}
FloatArrayNumInstFloatArrayNumInst952 FloatArrayNumInst(int size) : ArrayNumInst<float>(size) {}
953
acceptFloatArrayNumInst954 void accept(InstVisitor* visitor) { visitor->visit(this); }
955
cloneFloatArrayNumInst956 ValueInst* clone(CloneVisitor* cloner) { return cloner->visit(this); }
957 };
958
959 struct DoubleNumInst : public ValueInst, public NumValueInst {
960 const double fNum;
961
DoubleNumInstDoubleNumInst962 DoubleNumInst(double num) : ValueInst(), fNum(num) {}
963
acceptDoubleNumInst964 void accept(InstVisitor* visitor) { visitor->visit(this); }
965
cloneDoubleNumInst966 ValueInst* clone(CloneVisitor* cloner) { return cloner->visit(this); }
967
isSimpleValueDoubleNumInst968 virtual bool isSimpleValue() const { return true; }
969 };
970
971 struct DoubleArrayNumInst : public ArrayNumInst<double> {
DoubleArrayNumInstDoubleArrayNumInst972 DoubleArrayNumInst(const vector<double>& nums) : ArrayNumInst<double>(nums) {}
DoubleArrayNumInstDoubleArrayNumInst973 DoubleArrayNumInst(int size) : ArrayNumInst<double>(size) {}
974
acceptDoubleArrayNumInst975 void accept(InstVisitor* visitor) { visitor->visit(this); }
976
cloneDoubleArrayNumInst977 ValueInst* clone(CloneVisitor* cloner) { return cloner->visit(this); }
978 };
979
980 struct FixedPointNumInst : public ValueInst, public NumValueInst {
981 const double fNum;
982
FixedPointNumInstFixedPointNumInst983 FixedPointNumInst(double num) : ValueInst(), fNum(num) {}
984
acceptFixedPointNumInst985 void accept(InstVisitor* visitor) { visitor->visit(this); }
986
cloneFixedPointNumInst987 ValueInst* clone(CloneVisitor* cloner) { return cloner->visit(this); }
988
isSimpleValueFixedPointNumInst989 virtual bool isSimpleValue() const { return true; }
990 };
991
992 struct FixedPointArrayNumInst : public ArrayNumInst<double> {
FixedPointArrayNumInstFixedPointArrayNumInst993 FixedPointArrayNumInst(const vector<double>& nums) : ArrayNumInst<double>(nums) {}
FixedPointArrayNumInstFixedPointArrayNumInst994 FixedPointArrayNumInst(int size) : ArrayNumInst<double>(size) {}
995
acceptFixedPointArrayNumInst996 void accept(InstVisitor* visitor) { visitor->visit(this); }
997
cloneFixedPointArrayNumInst998 ValueInst* clone(CloneVisitor* cloner) { return cloner->visit(this); }
999 };
1000
1001 struct Int32NumInst : public ValueInst, public NumValueInst {
1002 const int fNum;
1003
Int32NumInstInt32NumInst1004 Int32NumInst(int num) : ValueInst(), fNum(num) {}
1005
acceptInt32NumInst1006 void accept(InstVisitor* visitor) { visitor->visit(this); }
1007
cloneInt32NumInst1008 ValueInst* clone(CloneVisitor* cloner) { return cloner->visit(this); }
1009
isSimpleValueInt32NumInst1010 virtual bool isSimpleValue() const { return true; }
1011 };
1012
1013 struct Int64NumInst : public ValueInst, public NumValueInst {
1014 const int64_t fNum;
1015
Int64NumInstInt64NumInst1016 Int64NumInst(int64_t num) : ValueInst(), fNum(num) {}
1017
acceptInt64NumInst1018 void accept(InstVisitor* visitor) { visitor->visit(this); }
1019
cloneInt64NumInst1020 ValueInst* clone(CloneVisitor* cloner) { return cloner->visit(this); }
1021
isSimpleValueInt64NumInst1022 virtual bool isSimpleValue() const { return true; }
1023 };
1024
1025 struct Int32ArrayNumInst : public ArrayNumInst<int> {
Int32ArrayNumInstInt32ArrayNumInst1026 Int32ArrayNumInst(const vector<int>& nums) : ArrayNumInst<int>(nums) {}
Int32ArrayNumInstInt32ArrayNumInst1027 Int32ArrayNumInst(int size) : ArrayNumInst<int>(size) {}
1028
acceptInt32ArrayNumInst1029 void accept(InstVisitor* visitor) { visitor->visit(this); }
1030
cloneInt32ArrayNumInst1031 ValueInst* clone(CloneVisitor* cloner) { return cloner->visit(this); }
1032 };
1033
1034 struct BoolNumInst : public ValueInst, public NumValueInst {
1035 const bool fNum;
1036
BoolNumInstBoolNumInst1037 BoolNumInst(bool num) : ValueInst(), fNum(num) {}
1038
acceptBoolNumInst1039 void accept(InstVisitor* visitor) { visitor->visit(this); }
1040
cloneBoolNumInst1041 ValueInst* clone(CloneVisitor* cloner) { return cloner->visit(this); }
1042
isSimpleValueBoolNumInst1043 virtual bool isSimpleValue() const { return true; }
1044 };
1045
1046 // ======================
1047 // Numerical computation
1048 // ======================
1049
1050 struct BinopInst : public ValueInst {
1051 const int fOpcode;
1052 ValueInst* fInst1;
1053 ValueInst* fInst2;
1054
BinopInstBinopInst1055 BinopInst(int opcode, ValueInst* inst1, ValueInst* inst2)
1056 : ValueInst(), fOpcode(opcode), fInst1(inst1), fInst2(inst2)
1057 {
1058 }
1059
~BinopInstBinopInst1060 virtual ~BinopInst() {}
1061
acceptBinopInst1062 void accept(InstVisitor* visitor) { visitor->visit(this); }
1063
cloneBinopInst1064 ValueInst* clone(CloneVisitor* cloner) { return cloner->visit(this); }
1065
sizeBinopInst1066 virtual int size() const { return fInst1->size() + fInst2->size(); }
1067 };
1068
1069 // =====
1070 // Cast
1071 // =====
1072
1073 struct CastInst : public ValueInst {
1074 Typed* fType;
1075 ValueInst* fInst;
1076
CastInstCastInst1077 CastInst(ValueInst* inst, Typed* typed) : ValueInst(), fType(typed), fInst(inst) {}
1078
~CastInstCastInst1079 virtual ~CastInst() {}
1080
acceptCastInst1081 void accept(InstVisitor* visitor) { visitor->visit(this); }
1082
cloneCastInst1083 ValueInst* clone(CloneVisitor* cloner) { return cloner->visit(this); }
1084
sizeCastInst1085 virtual int size() const { return fInst->size(); }
1086 };
1087
1088 struct BitcastInst : public ValueInst {
1089 Typed* fType;
1090 ValueInst* fInst;
1091
BitcastInstBitcastInst1092 BitcastInst(ValueInst* inst, Typed* typed) : ValueInst(), fType(typed), fInst(inst) {}
1093
~BitcastInstBitcastInst1094 virtual ~BitcastInst() {}
1095
acceptBitcastInst1096 void accept(InstVisitor* visitor) { visitor->visit(this); }
1097
cloneBitcastInst1098 ValueInst* clone(CloneVisitor* cloner) { return cloner->visit(this); }
1099
sizeBitcastInst1100 virtual int size() const { return fInst->size(); }
1101 };
1102
1103 // =============
1104 // Control flow
1105 // =============
1106
1107 struct BlockInst : public StatementInst {
1108 list<StatementInst*> fCode;
1109 bool fIndent;
1110
BlockInstBlockInst1111 BlockInst(list<StatementInst*> code) : fCode(code), fIndent(false) {}
1112
BlockInstBlockInst1113 BlockInst() : fIndent(false) {}
1114
~BlockInstBlockInst1115 virtual ~BlockInst() {}
1116
setIndentBlockInst1117 void setIndent(bool indent) { fIndent = indent; }
getIndentBlockInst1118 bool getIndent() { return fIndent; }
1119
acceptBlockInst1120 void accept(InstVisitor* visitor) { visitor->visit(this); }
1121
cloneBlockInst1122 StatementInst* clone(CloneVisitor* cloner) { return cloner->visit(this); }
1123
pushFrontInstBlockInst1124 void pushFrontInst(StatementInst* inst) { fCode.push_front(inst); }
1125
pushBackInstBlockInst1126 void pushBackInst(StatementInst* inst) { fCode.push_back(inst); }
1127
mergeBlockInst1128 void merge(BlockInst* inst)
1129 {
1130 for (const auto& it : inst->fCode) {
1131 fCode.push_back(it);
1132 }
1133 }
1134
sizeBlockInst1135 int size() const { return int(fCode.size()); }
1136
1137 bool hasReturn() const;
1138 ValueInst* getReturnValue();
1139 };
1140
1141 struct Select2Inst : public ValueInst {
1142 ValueInst* fCond;
1143 ValueInst* fThen;
1144 ValueInst* fElse;
1145
Select2InstSelect2Inst1146 Select2Inst(ValueInst* cond_inst, ValueInst* then_inst, ValueInst* else_inst)
1147 : ValueInst(), fCond(cond_inst), fThen(then_inst), fElse(else_inst)
1148 {
1149 }
1150
~Select2InstSelect2Inst1151 virtual ~Select2Inst() {}
1152
acceptSelect2Inst1153 void accept(InstVisitor* visitor) { visitor->visit(this); }
1154
cloneSelect2Inst1155 ValueInst* clone(CloneVisitor* cloner) { return cloner->visit(this); }
1156
sizeSelect2Inst1157 virtual int size() const { return std::max(fThen->size(), fElse->size()); }
1158 };
1159
1160 // Contains a condition (derived from 'enable/contol') and a statement to be computed if the cond is true
1161 struct ControlInst : public StatementInst {
1162 ValueInst* fCond;
1163 StatementInst* fStatement;
1164
ControlInstControlInst1165 ControlInst(ValueInst* cond_inst, StatementInst* exp_inst)
1166 : fCond(cond_inst), fStatement(exp_inst)
1167 {
1168 }
1169
~ControlInstControlInst1170 virtual ~ControlInst() {}
1171
1172 // Test if (cond == fCond)
1173 bool hasCondition(ValueInst* cond);
1174
acceptControlInst1175 void accept(InstVisitor* visitor) { visitor->visit(this); }
1176
cloneControlInst1177 StatementInst* clone(CloneVisitor* cloner) { return cloner->visit(this); }
1178
1179 };
1180
1181 struct IfInst : public StatementInst {
1182 ValueInst* fCond;
1183 BlockInst* fThen;
1184 BlockInst* fElse;
1185
IfInstIfInst1186 IfInst(ValueInst* cond_inst, BlockInst* then_inst, BlockInst* else_inst)
1187 : fCond(cond_inst), fThen(then_inst), fElse(else_inst)
1188 {
1189 }
1190
IfInstIfInst1191 IfInst(ValueInst* cond_inst, BlockInst* then_inst) : fCond(cond_inst), fThen(then_inst), fElse(new BlockInst()) {}
1192
~IfInstIfInst1193 virtual ~IfInst() {}
1194
acceptIfInst1195 void accept(InstVisitor* visitor) { visitor->visit(this); }
1196
cloneIfInst1197 StatementInst* clone(CloneVisitor* cloner) { return cloner->visit(this); }
1198 };
1199
1200 struct SwitchInst : public StatementInst {
1201 ValueInst* fCond;
1202 list<pair<int, BlockInst*> > fCode;
1203
SwitchInstSwitchInst1204 SwitchInst(ValueInst* cond, const list<pair<int, BlockInst*> >& code) : fCond(cond), fCode(code) {}
1205
SwitchInstSwitchInst1206 SwitchInst(ValueInst* cond) : fCond(cond) {}
1207
~SwitchInstSwitchInst1208 virtual ~SwitchInst() {}
1209
addCaseSwitchInst1210 void addCase(int value, BlockInst* block) { fCode.push_back(make_pair(value, block)); }
1211
acceptSwitchInst1212 void accept(InstVisitor* visitor) { visitor->visit(this); }
1213
cloneSwitchInst1214 StatementInst* clone(CloneVisitor* cloner) { return cloner->visit(this); }
1215 };
1216
1217 struct RetInst : public StatementInst {
1218 ValueInst* fResult;
1219
RetInstRetInst1220 RetInst(ValueInst* result = nullptr) : fResult(result) {}
1221
~RetInstRetInst1222 virtual ~RetInst() {}
1223
acceptRetInst1224 void accept(InstVisitor* visitor) { visitor->visit(this); }
1225
cloneRetInst1226 StatementInst* clone(CloneVisitor* cloner) { return cloner->visit(this); }
1227 };
1228
1229 struct FunCallInst : public ValueInst {
1230 const string fName;
1231 list<ValueInst*> fArgs; // List of arguments
1232 const bool fMethod;
1233
FunCallInstFunCallInst1234 FunCallInst(const string& name, const list<ValueInst*>& args, bool method)
1235 : ValueInst(), fName(name), fArgs(args), fMethod(method)
1236 {
1237 }
1238
~FunCallInstFunCallInst1239 virtual ~FunCallInst() {}
1240
acceptFunCallInst1241 void accept(InstVisitor* visitor) { visitor->visit(this); }
1242
cloneFunCallInst1243 ValueInst* clone(CloneVisitor* cloner) { return cloner->visit(this); }
1244 };
1245
1246 struct DeclareFunInst : public StatementInst {
1247 const string fName;
1248 FunTyped* fType; // Describes type of all arguments and function result
1249 BlockInst* fCode; // Code is a list of StatementInst*
1250
1251 DeclareFunInst(const string& name, FunTyped* type, BlockInst* code = new BlockInst());
1252
~DeclareFunInstDeclareFunInst1253 virtual ~DeclareFunInst() {}
1254
getResTypeDeclareFunInst1255 Typed::VarType getResType() { return fType->fResult->getType(); }
1256
acceptDeclareFunInst1257 void accept(InstVisitor* visitor) { visitor->visit(this); }
1258
cloneDeclareFunInst1259 StatementInst* clone(CloneVisitor* cloner) { return cloner->visit(this); }
1260 };
1261
1262 struct DeclareStructTypeInst : public StatementInst {
1263 StructTyped* fType;
1264
DeclareStructTypeInstDeclareStructTypeInst1265 DeclareStructTypeInst(StructTyped* type) : fType(type) {}
1266
~DeclareStructTypeInstDeclareStructTypeInst1267 virtual ~DeclareStructTypeInst() {}
1268
acceptDeclareStructTypeInst1269 void accept(InstVisitor* visitor) { visitor->visit(this); }
1270
cloneDeclareStructTypeInst1271 StatementInst* clone(CloneVisitor* cloner) { return cloner->visit(this); }
1272 };
1273
1274 // ======
1275 // Loops
1276 // ======
1277
1278 struct ForLoopInst : public StatementInst {
1279 StatementInst* fInit;
1280 StatementInst* fIncrement;
1281 ValueInst* fEnd;
1282 BlockInst* fCode;
1283 const bool fIsRecursive;
1284
ForLoopInstForLoopInst1285 ForLoopInst(StatementInst* init, ValueInst* end, StatementInst* increment, BlockInst* code, bool is_recursive)
1286 : fInit(init), fIncrement(increment), fEnd(end), fCode(code), fIsRecursive(is_recursive)
1287 {
1288 }
1289
~ForLoopInstForLoopInst1290 virtual ~ForLoopInst() {}
1291
pushFrontInstForLoopInst1292 void pushFrontInst(StatementInst* inst) { fCode->pushFrontInst(inst); }
1293
pushBackInstForLoopInst1294 void pushBackInst(StatementInst* inst) { fCode->pushBackInst(inst); }
1295
getNameForLoopInst1296 string getName() const { return fInit->getName(); }
1297
acceptForLoopInst1298 void accept(InstVisitor* visitor) { visitor->visit(this); }
1299
cloneForLoopInst1300 StatementInst* clone(CloneVisitor* cloner) { return cloner->visit(this); }
1301 };
1302
1303 // To be used for the 'rust' backend
1304 struct SimpleForLoopInst : public StatementInst {
1305 ValueInst* fUpperBound;
1306 ValueInst* fLowerBound;
1307 const string fName;
1308 const bool fReverse;
1309 BlockInst* fCode;
1310
SimpleForLoopInstSimpleForLoopInst1311 SimpleForLoopInst(const string& name, ValueInst* upperBound, ValueInst* lowerBound, bool reverse, BlockInst* code)
1312 : fUpperBound(upperBound), fLowerBound(lowerBound), fName(name), fReverse(reverse), fCode(code)
1313 {
1314 }
1315
getNameSimpleForLoopInst1316 string getName() const { return fName; }
1317
~SimpleForLoopInstSimpleForLoopInst1318 virtual ~SimpleForLoopInst() {}
1319
pushFrontInstSimpleForLoopInst1320 void pushFrontInst(StatementInst* inst) { fCode->pushFrontInst(inst); }
1321
pushBackInstSimpleForLoopInst1322 void pushBackInst(StatementInst* inst) { fCode->pushBackInst(inst); }
1323
acceptSimpleForLoopInst1324 void accept(InstVisitor* visitor) { visitor->visit(this); }
1325
cloneSimpleForLoopInst1326 StatementInst* clone(CloneVisitor* cloner) { return cloner->visit(this); }
1327 };
1328
1329 struct IteratorForLoopInst : public StatementInst {
1330 std::vector<NamedAddress*> fIterators;
1331 const bool fReverse;
1332 BlockInst* fCode;
1333
IteratorForLoopInstIteratorForLoopInst1334 IteratorForLoopInst(const std::vector<NamedAddress*>& iterators, bool reverse, BlockInst* code)
1335 : fIterators(iterators), fReverse(reverse), fCode(code)
1336 {
1337 }
1338
~IteratorForLoopInstIteratorForLoopInst1339 virtual ~IteratorForLoopInst() {}
1340
pushFrontInstIteratorForLoopInst1341 void pushFrontInst(StatementInst* inst) { fCode->pushFrontInst(inst); }
1342
pushBackInstIteratorForLoopInst1343 void pushBackInst(StatementInst* inst) { fCode->pushBackInst(inst); }
1344
acceptIteratorForLoopInst1345 void accept(InstVisitor* visitor) { visitor->visit(this); }
1346
cloneIteratorForLoopInst1347 StatementInst* clone(CloneVisitor* cloner) { return cloner->visit(this); }
1348 };
1349
1350 struct WhileLoopInst : public StatementInst {
1351 ValueInst* fCond;
1352 BlockInst* fCode;
1353
WhileLoopInstWhileLoopInst1354 WhileLoopInst(ValueInst* cond, BlockInst* code) : fCond(cond), fCode(code) {}
1355
~WhileLoopInstWhileLoopInst1356 virtual ~WhileLoopInst() {}
1357
acceptWhileLoopInst1358 void accept(InstVisitor* visitor) { visitor->visit(this); }
1359
cloneWhileLoopInst1360 StatementInst* clone(CloneVisitor* cloner) { return cloner->visit(this); }
1361 };
1362
1363 // ====================
1364 // Basic clone visitor
1365 // ====================
1366
1367 class BasicCloneVisitor : public CloneVisitor {
1368 protected:
1369 // Used when inlining functions
1370 static std::stack<BlockInst*> fBlockStack;
1371
1372 public:
BasicCloneVisitor()1373 BasicCloneVisitor() {}
1374
visit(NullValueInst * inst)1375 virtual NullValueInst* visit(NullValueInst* inst) { return new NullValueInst(); }
visit(NullStatementInst * inst)1376 virtual NullStatementInst* visit(NullStatementInst* inst) { return new NullStatementInst(); }
1377
1378 // Declarations
visit(DeclareVarInst * inst)1379 virtual StatementInst* visit(DeclareVarInst* inst)
1380 {
1381 return new DeclareVarInst(inst->fAddress->clone(this), inst->fType->clone(this),
1382 ((inst->fValue) ? inst->fValue->clone(this) : nullptr));
1383 }
visit(DeclareFunInst * inst)1384 virtual StatementInst* visit(DeclareFunInst* inst)
1385 {
1386 return new DeclareFunInst(inst->fName, static_cast<FunTyped*>(inst->fType->clone(this)),
1387 static_cast<BlockInst*>(inst->fCode->clone(this)));
1388 }
visit(DeclareStructTypeInst * inst)1389 virtual StatementInst* visit(DeclareStructTypeInst* inst)
1390 {
1391 return new DeclareStructTypeInst(static_cast<StructTyped*>(inst->fType->clone(this)));
1392 }
visit(DeclareBufferIterators * inst)1393 virtual StatementInst* visit(DeclareBufferIterators* inst)
1394 {
1395 return new DeclareBufferIterators(inst->fBufferName1, inst->fBufferName2, inst->fNumChannels, inst->fMutable);
1396 }
1397
1398 // Memory
visit(LoadVarInst * inst)1399 virtual ValueInst* visit(LoadVarInst* inst) { return new LoadVarInst(inst->fAddress->clone(this)); }
visit(LoadVarAddressInst * inst)1400 virtual ValueInst* visit(LoadVarAddressInst* inst) { return new LoadVarAddressInst(inst->fAddress->clone(this)); }
visit(TeeVarInst * inst)1401 virtual ValueInst* visit(TeeVarInst* inst)
1402 {
1403 return new TeeVarInst(inst->fAddress->clone(this), inst->fValue->clone(this));
1404 }
visit(StoreVarInst * inst)1405 virtual StatementInst* visit(StoreVarInst* inst)
1406 {
1407 return new StoreVarInst(inst->fAddress->clone(this), inst->fValue->clone(this));
1408 }
visit(ShiftArrayVarInst * inst)1409 virtual StatementInst* visit(ShiftArrayVarInst* inst)
1410 {
1411 return new ShiftArrayVarInst(inst->fAddress->clone(this), inst->fDelay);
1412 }
1413
1414 // Addresses
visit(NamedAddress * address)1415 virtual Address* visit(NamedAddress* address) { return new NamedAddress(address->fName, address->fAccess); }
visit(IndexedAddress * address)1416 virtual Address* visit(IndexedAddress* address)
1417 {
1418 return new IndexedAddress(address->fAddress->clone(this), address->fIndex->clone(this));
1419 }
1420
1421 // Numbers
visit(FloatNumInst * inst)1422 virtual ValueInst* visit(FloatNumInst* inst) { return new FloatNumInst(inst->fNum); }
visit(FloatArrayNumInst * inst)1423 virtual ValueInst* visit(FloatArrayNumInst* inst) { return new FloatArrayNumInst(inst->fNumTable); }
visit(Int32NumInst * inst)1424 virtual ValueInst* visit(Int32NumInst* inst) { return new Int32NumInst(inst->fNum); }
visit(Int64NumInst * inst)1425 virtual ValueInst* visit(Int64NumInst* inst) { return new Int64NumInst(inst->fNum); }
visit(Int32ArrayNumInst * inst)1426 virtual ValueInst* visit(Int32ArrayNumInst* inst) { return new Int32ArrayNumInst(inst->fNumTable); }
visit(BoolNumInst * inst)1427 virtual ValueInst* visit(BoolNumInst* inst) { return new BoolNumInst(inst->fNum); }
visit(DoubleNumInst * inst)1428 virtual ValueInst* visit(DoubleNumInst* inst) { return new DoubleNumInst(inst->fNum); }
visit(DoubleArrayNumInst * inst)1429 virtual ValueInst* visit(DoubleArrayNumInst* inst) { return new DoubleArrayNumInst(inst->fNumTable); }
visit(FixedPointNumInst * inst)1430 virtual ValueInst* visit(FixedPointNumInst* inst) { return new FixedPointNumInst(inst->fNum); }
visit(FixedPointArrayNumInst * inst)1431 virtual ValueInst* visit(FixedPointArrayNumInst* inst) { return new FixedPointArrayNumInst(inst->fNumTable); }
1432
1433 // Numerical computation
visit(BinopInst * inst)1434 virtual ValueInst* visit(BinopInst* inst)
1435 {
1436 return new BinopInst(inst->fOpcode, inst->fInst1->clone(this), inst->fInst2->clone(this));
1437 }
1438
1439 // Cast
visit(CastInst * inst)1440 virtual ValueInst* visit(CastInst* inst)
1441 {
1442 return new CastInst(inst->fInst->clone(this), inst->fType->clone(this));
1443 }
1444
visit(BitcastInst * inst)1445 virtual ValueInst* visit(BitcastInst* inst)
1446 {
1447 return new BitcastInst(inst->fInst->clone(this), inst->fType->clone(this));
1448 }
1449
1450 // Function call
visit(FunCallInst * inst)1451 virtual ValueInst* visit(FunCallInst* inst)
1452 {
1453 list<ValueInst*> cloned_args;
1454 for (const auto& it : inst->fArgs) {
1455 cloned_args.push_back(it->clone(this));
1456 }
1457
1458 return new FunCallInst(inst->fName, cloned_args, inst->fMethod);
1459 }
visit(RetInst * inst)1460 virtual StatementInst* visit(RetInst* inst)
1461 {
1462 return new RetInst((inst->fResult) ? inst->fResult->clone(this) : nullptr);
1463 }
visit(DropInst * inst)1464 virtual StatementInst* visit(DropInst* inst)
1465 {
1466 return new DropInst((inst->fResult) ? inst->fResult->clone(this) : nullptr);
1467 }
1468
1469 // Conditional
visit(Select2Inst * inst)1470 virtual ValueInst* visit(Select2Inst* inst)
1471 {
1472 ValueInst* then_exp = inst->fThen->clone(this);
1473 ValueInst* else_exp = inst->fElse->clone(this);
1474 ValueInst* cond_exp = inst->fCond->clone(this);
1475 // cond_exp has to be evaluated last for FunctionInliner to correctly work in gHasTeeLocal mode
1476 return new Select2Inst(cond_exp, then_exp, else_exp);
1477 }
1478
visit(ControlInst * inst)1479 virtual StatementInst* visit(ControlInst* inst)
1480 {
1481 return new ControlInst(inst->fCond->clone(this), inst->fStatement->clone(this));
1482 }
1483
visit(IfInst * inst)1484 virtual StatementInst* visit(IfInst* inst)
1485 {
1486 return new IfInst(inst->fCond->clone(this), static_cast<BlockInst*>(inst->fThen->clone(this)),
1487 static_cast<BlockInst*>(inst->fElse->clone(this)));
1488 }
visit(SwitchInst * inst)1489 virtual StatementInst* visit(SwitchInst* inst)
1490 {
1491 SwitchInst* cloned = new SwitchInst(inst->fCond->clone(this));
1492 for (const auto& it : inst->fCode) {
1493 cloned->addCase(it.first, static_cast<BlockInst*>((it.second)->clone(this)));
1494 }
1495 return cloned;
1496 }
1497
1498 // Loop
visit(ForLoopInst * inst)1499 virtual StatementInst* visit(ForLoopInst* inst)
1500 {
1501 return new ForLoopInst(inst->fInit->clone(this), inst->fEnd->clone(this), inst->fIncrement->clone(this),
1502 static_cast<BlockInst*>(inst->fCode->clone(this)), inst->fIsRecursive);
1503 }
1504
visit(SimpleForLoopInst * inst)1505 virtual StatementInst* visit(SimpleForLoopInst* inst)
1506 {
1507 return new SimpleForLoopInst(inst->fName, inst->fUpperBound->clone(this), inst->fLowerBound->clone(this),
1508 inst->fReverse, static_cast<BlockInst*>(inst->fCode->clone(this)));
1509 }
1510
visit(IteratorForLoopInst * inst)1511 virtual StatementInst* visit(IteratorForLoopInst* inst)
1512 {
1513 return new IteratorForLoopInst(inst->fIterators, inst->fReverse, static_cast<BlockInst*>(inst->fCode->clone(this)));
1514 }
1515
visit(WhileLoopInst * inst)1516 virtual StatementInst* visit(WhileLoopInst* inst)
1517 {
1518 return new WhileLoopInst(inst->fCond->clone(this), static_cast<BlockInst*>(inst->fCode->clone(this)));
1519 }
1520
1521 // Block
visit(BlockInst * inst)1522 virtual StatementInst* visit(BlockInst* inst)
1523 {
1524 // fBlockStack is used when inlining functions
1525 BlockInst* cloned = new BlockInst();
1526 fBlockStack.push(cloned);
1527 for (const auto& it : inst->fCode) {
1528 cloned->pushBackInst(it->clone(this));
1529 }
1530 fBlockStack.pop();
1531 return cloned;
1532 }
1533
1534 // User interface
visit(AddMetaDeclareInst * inst)1535 virtual StatementInst* visit(AddMetaDeclareInst* inst)
1536 {
1537 return new AddMetaDeclareInst(inst->fZone, inst->fKey, inst->fValue);
1538 }
visit(OpenboxInst * inst)1539 virtual StatementInst* visit(OpenboxInst* inst) { return new OpenboxInst(inst->fName, inst->fOrient); }
visit(CloseboxInst * inst)1540 virtual StatementInst* visit(CloseboxInst* inst) { return new CloseboxInst(); }
visit(AddButtonInst * inst)1541 virtual StatementInst* visit(AddButtonInst* inst)
1542 {
1543 return new AddButtonInst(inst->fLabel, inst->fZone, inst->fType);
1544 }
visit(AddSliderInst * inst)1545 virtual StatementInst* visit(AddSliderInst* inst)
1546 {
1547 return new AddSliderInst(inst->fLabel, inst->fZone, inst->fInit, inst->fMin, inst->fMax, inst->fStep,
1548 inst->fType);
1549 }
visit(AddBargraphInst * inst)1550 virtual StatementInst* visit(AddBargraphInst* inst)
1551 {
1552 return new AddBargraphInst(inst->fLabel, inst->fZone, inst->fMin, inst->fMax, inst->fType);
1553 }
visit(AddSoundfileInst * inst)1554 virtual StatementInst* visit(AddSoundfileInst* inst)
1555 {
1556 return new AddSoundfileInst(inst->fLabel, inst->fURL, inst->fSFZone);
1557 }
visit(LabelInst * inst)1558 virtual StatementInst* visit(LabelInst* inst) { return new LabelInst(inst->fLabel); }
1559
1560 // Typed
1561 virtual Typed* visit(BasicTyped* typed); // Moved in instructions.cpp
visit(NamedTyped * typed)1562 virtual Typed* visit(NamedTyped* typed) { return new NamedTyped(typed->fName, typed->fType); }
visit(FunTyped * typed)1563 virtual Typed* visit(FunTyped* typed)
1564 {
1565 list<NamedTyped*> cloned;
1566 for (const auto& it : typed->fArgsTypes) {
1567 cloned.push_back(static_cast<NamedTyped*>(it->clone(this)));
1568 }
1569 return new FunTyped(cloned, static_cast<BasicTyped*>(typed->fResult->clone(this)), typed->fAttribute);
1570 }
visit(ArrayTyped * typed)1571 virtual Typed* visit(ArrayTyped* typed)
1572 {
1573 return new ArrayTyped(typed->fType->clone(this), typed->fSize, typed->fIsPtr);
1574 }
visit(StructTyped * typed)1575 virtual Typed* visit(StructTyped* typed)
1576 {
1577 vector<NamedTyped*> cloned;
1578 for (const auto& it : typed->fFields) {
1579 cloned.push_back(static_cast<NamedTyped*>(it->clone(this)));
1580 }
1581 return new StructTyped(typed->fName, cloned);
1582 }
1583
visit(VectorTyped * typed)1584 virtual Typed* visit(VectorTyped* typed)
1585 {
1586 return new VectorTyped(static_cast<BasicTyped*>(typed->fType->clone(this)), typed->fSize);
1587 }
1588 };
1589
1590 // =======================
1591 // Basic dispatch visitor
1592 // =======================
1593
1594 struct DispatchVisitor : public InstVisitor {
1595 using InstVisitor::visit;
1596
visitDispatchVisitor1597 virtual void visit(DeclareVarInst* inst)
1598 {
1599 inst->fAddress->accept(this);
1600 // No visitor on types
1601 if (inst->fValue) {
1602 inst->fValue->accept(this);
1603 }
1604 }
1605
visitDispatchVisitor1606 virtual void visit(DeclareFunInst* inst)
1607 {
1608 if (inst->fCode) {
1609 inst->fCode->accept(this);
1610 }
1611 }
1612
visitDispatchVisitor1613 virtual void visit(LoadVarInst* inst) { inst->fAddress->accept(this); }
visitDispatchVisitor1614 virtual void visit(LoadVarAddressInst* inst) { inst->fAddress->accept(this); }
visitDispatchVisitor1615 virtual void visit(TeeVarInst* inst)
1616 {
1617 inst->fAddress->accept(this);
1618 inst->fValue->accept(this);
1619 }
visitDispatchVisitor1620 virtual void visit(StoreVarInst* inst)
1621 {
1622 inst->fAddress->accept(this);
1623 inst->fValue->accept(this);
1624 }
1625
visitDispatchVisitor1626 virtual void visit(ShiftArrayVarInst* inst) { inst->fAddress->accept(this); }
1627
visitDispatchVisitor1628 virtual void visit(IndexedAddress* address)
1629 {
1630 address->fAddress->accept(this);
1631 address->fIndex->accept(this);
1632 }
1633
visitDispatchVisitor1634 virtual void visit(BinopInst* inst)
1635 {
1636 inst->fInst1->accept(this);
1637 inst->fInst2->accept(this);
1638 }
1639
visitDispatchVisitor1640 virtual void visit(CastInst* inst) { inst->fInst->accept(this); }
1641
visitDispatchVisitor1642 virtual void visit(BitcastInst* inst) { inst->fInst->accept(this); }
1643
visitDispatchVisitor1644 virtual void visit(FunCallInst* inst)
1645 {
1646 for (const auto& it : inst->fArgs) {
1647 it->accept(this);
1648 }
1649 }
1650
visitDispatchVisitor1651 virtual void visit(RetInst* inst)
1652 {
1653 if (inst->fResult) {
1654 inst->fResult->accept(this);
1655 }
1656 }
1657
visitDispatchVisitor1658 virtual void visit(DropInst* inst)
1659 {
1660 if (inst->fResult) {
1661 inst->fResult->accept(this);
1662 }
1663 }
1664
visitDispatchVisitor1665 virtual void visit(Select2Inst* inst)
1666 {
1667 inst->fCond->accept(this);
1668 inst->fThen->accept(this);
1669 inst->fElse->accept(this);
1670 }
1671
visitDispatchVisitor1672 virtual void visit(ControlInst* inst)
1673 {
1674 inst->fCond->accept(this);
1675 inst->fStatement->accept(this);
1676 }
1677
visitDispatchVisitor1678 virtual void visit(IfInst* inst)
1679 {
1680 inst->fCond->accept(this);
1681 inst->fThen->accept(this);
1682 inst->fElse->accept(this);
1683 }
1684
visitDispatchVisitor1685 virtual void visit(ForLoopInst* inst)
1686 {
1687 inst->fInit->accept(this);
1688 inst->fEnd->accept(this);
1689 inst->fIncrement->accept(this);
1690 inst->fCode->accept(this);
1691 }
1692
visitDispatchVisitor1693 virtual void visit(SimpleForLoopInst* inst)
1694 {
1695 inst->fUpperBound->accept(this);
1696 inst->fLowerBound->accept(this);
1697 inst->fCode->accept(this);
1698 }
1699
visitDispatchVisitor1700 virtual void visit(IteratorForLoopInst* inst)
1701 {
1702 for (const auto& it : inst->fIterators) {
1703 it->accept(this);
1704 }
1705 inst->fCode->accept(this);
1706 }
1707
visitDispatchVisitor1708 virtual void visit(WhileLoopInst* inst)
1709 {
1710 inst->fCond->accept(this);
1711 inst->fCode->accept(this);
1712 }
1713
visitDispatchVisitor1714 virtual void visit(SwitchInst* inst)
1715 {
1716 inst->fCond->accept(this);
1717 for (const auto& it : inst->fCode) {
1718 (it.second)->accept(this);
1719 }
1720 }
1721
visitDispatchVisitor1722 virtual void visit(BlockInst* inst)
1723 {
1724 for (const auto& it : inst->fCode) {
1725 it->accept(this);
1726 }
1727 }
1728
1729 // Typed
visitDispatchVisitor1730 virtual void visit(FunTyped* typed)
1731 {
1732 typed->fResult->accept(this);
1733 for (const auto& it : typed->fArgsTypes) {
1734 it->accept(this);
1735 }
1736 }
visitDispatchVisitor1737 virtual void visit(ArrayTyped* typed) { typed->fType->accept(this); }
visitDispatchVisitor1738 virtual void visit(StructTyped* typed)
1739 {
1740 for (const auto& it : typed->fFields) {
1741 it->accept(this);
1742 }
1743 }
1744
visitDispatchVisitor1745 virtual void visit(VectorTyped* typed) { typed->fType->accept(this); }
1746 };
1747
1748 struct VariableScopeVisitor : public DispatchVisitor {
1749 stack<list<DeclareVarInst*> > fBlockVarTable;
1750
VariableScopeVisitorVariableScopeVisitor1751 VariableScopeVisitor() {}
1752
visitVariableScopeVisitor1753 virtual void visit(DeclareVarInst* inst)
1754 {
1755 fBlockVarTable.top().push_back(inst);
1756 DispatchVisitor::visit(inst);
1757 }
1758
visitVariableScopeVisitor1759 virtual void visit(BlockInst* inst)
1760 {
1761 list<DeclareVarInst*> variable_block;
1762 fBlockVarTable.push(variable_block);
1763 DispatchVisitor::visit(inst);
1764 fBlockVarTable.pop();
1765 }
1766 };
1767
1768 class ScalVecDispatcherVisitor : public DispatchVisitor {
1769 protected:
1770 InstVisitor* fScalarVisitor;
1771 InstVisitor* fVectorVisitor;
1772
1773 void Dispatch2Visitor(ValueInst* inst);
1774
1775 public:
1776 using DispatchVisitor::visit;
1777
ScalVecDispatcherVisitor(InstVisitor * scal,InstVisitor * vec)1778 ScalVecDispatcherVisitor(InstVisitor* scal, InstVisitor* vec) : fScalarVisitor(scal), fVectorVisitor(vec) {}
1779
~ScalVecDispatcherVisitor()1780 ~ScalVecDispatcherVisitor()
1781 {
1782 delete fScalarVisitor;
1783 delete fVectorVisitor;
1784 }
1785
visit(LoadVarInst * inst)1786 virtual void visit(LoadVarInst* inst) { Dispatch2Visitor(inst); }
1787
visit(LoadVarAddressInst * inst)1788 virtual void visit(LoadVarAddressInst* inst) { Dispatch2Visitor(inst); }
1789
visit(TeeVarInst * inst)1790 virtual void visit(TeeVarInst* inst) { Dispatch2Visitor(inst); }
1791
visit(StoreVarInst * inst)1792 virtual void visit(StoreVarInst* inst)
1793 {
1794 /*
1795 if (inst->fValue->fSize == 1) {
1796 fScalarVisitor->visit(inst);
1797 } else {
1798 fVectorVisitor->visit(inst);
1799 }
1800 */
1801
1802 fScalarVisitor->visit(inst);
1803 }
1804
visit(ShiftArrayVarInst * inst)1805 virtual void visit(ShiftArrayVarInst* inst) { fScalarVisitor->visit(inst); }
1806
visit(FloatNumInst * inst)1807 virtual void visit(FloatNumInst* inst) { Dispatch2Visitor(inst); }
1808
visit(FloatArrayNumInst * inst)1809 virtual void visit(FloatArrayNumInst* inst) { Dispatch2Visitor(inst); }
1810
visit(Int32NumInst * inst)1811 virtual void visit(Int32NumInst* inst) { Dispatch2Visitor(inst); }
1812
visit(Int64NumInst * inst)1813 virtual void visit(Int64NumInst* inst) { Dispatch2Visitor(inst); }
1814
visit(BoolNumInst * inst)1815 virtual void visit(BoolNumInst* inst) { Dispatch2Visitor(inst); }
1816
visit(DoubleNumInst * inst)1817 virtual void visit(DoubleNumInst* inst) { Dispatch2Visitor(inst); }
1818
visit(DoubleArrayNumInst * inst)1819 virtual void visit(DoubleArrayNumInst* inst) { Dispatch2Visitor(inst); }
1820
visit(FixedPointNumInst * inst)1821 virtual void visit(FixedPointNumInst* inst) { Dispatch2Visitor(inst); }
1822
visit(FixedPointArrayNumInst * inst)1823 virtual void visit(FixedPointArrayNumInst* inst) { Dispatch2Visitor(inst); }
1824
visit(BinopInst * inst)1825 virtual void visit(BinopInst* inst) { Dispatch2Visitor(inst); }
1826
visit(CastInst * inst)1827 virtual void visit(CastInst* inst) { Dispatch2Visitor(inst); }
1828
visit(BitcastInst * inst)1829 virtual void visit(BitcastInst* inst) { Dispatch2Visitor(inst); }
1830
visit(FunCallInst * inst)1831 virtual void visit(FunCallInst* inst) { Dispatch2Visitor(inst); }
1832
visit(Select2Inst * inst)1833 virtual void visit(Select2Inst* inst) { Dispatch2Visitor(inst); }
1834
1835 };
1836
1837 // ===================
1838 // Combining visitors
1839 // ===================
1840
1841 class CombinerVisitor : public DispatchVisitor {
1842 protected:
1843 InstVisitor* fVisitor1;
1844 InstVisitor* fVisitor2;
1845 InstVisitor* fCurVisitor;
1846
1847 public:
CombinerVisitor(InstVisitor * v1,InstVisitor * v2)1848 CombinerVisitor(InstVisitor* v1, InstVisitor* v2) : fVisitor1(v1), fVisitor2(v2) { fCurVisitor = v1; }
1849
~CombinerVisitor()1850 virtual ~CombinerVisitor() {}
1851 };
1852
1853 // ======================
1854 // Instruction generator
1855 // ======================
1856
1857 struct InstBuilder {
1858 // User interface
genAddMetaDeclareInstInstBuilder1859 static AddMetaDeclareInst* genAddMetaDeclareInst(const string& zone, const string& key, const string& value)
1860 {
1861 return new AddMetaDeclareInst(zone, key, value);
1862 }
1863
genOpenboxInstInstBuilder1864 static OpenboxInst* genOpenboxInst(const string& name, OpenboxInst::BoxType orient)
1865 {
1866 faustassert(orient >= OpenboxInst::kVerticalBox && orient <= OpenboxInst::kTabBox);
1867 return new OpenboxInst(name, orient);
1868 }
1869
genCloseboxInstInstBuilder1870 static CloseboxInst* genCloseboxInst() { return new CloseboxInst(); }
1871
genAddButtonInstInstBuilder1872 static AddButtonInst* genAddButtonInst(const string& label, const string& zone)
1873 {
1874 return new AddButtonInst(label, zone, AddButtonInst::kDefaultButton);
1875 }
1876
genAddCheckbuttonInstInstBuilder1877 static AddButtonInst* genAddCheckbuttonInst(const string& label, const string& zone)
1878 {
1879 return new AddButtonInst(label, zone, AddButtonInst::kCheckButton);
1880 }
1881
genAddHorizontalSliderInstInstBuilder1882 static AddSliderInst* genAddHorizontalSliderInst(const string& label, const string& zone, double init, double min,
1883 double max, double step)
1884 {
1885 stringstream error;
1886 if (min > max) {
1887 error << "ERROR : horizontal slider \'"<< label << "\' min = " << min << " should be less than max = " << max << "\n";
1888 throw faustexception(error.str());
1889 } else if (init < min || init > max) {
1890 error << "ERROR : horizontal slider \'"<< label << "\' init = " << init << " outside of [" << min << " " << max << "] range\n";
1891 throw faustexception(error.str());
1892 }
1893 return new AddSliderInst(label, zone, init, min, max, step, AddSliderInst::kHorizontal);
1894 }
1895
genAddVerticalSliderInstInstBuilder1896 static AddSliderInst* genAddVerticalSliderInst(const string& label, const string& zone, double init, double min,
1897 double max, double step)
1898 {
1899 stringstream error;
1900 if (min > max) {
1901 error << "ERROR : vertical slider \'"<< label << "\' min = " << min << " should be less than max = " << max << "\n";
1902 throw faustexception(error.str());
1903 } else if (init < min || init > max) {
1904 error << "ERROR : vertical slider \'" << label << "\' init = " << init << " outside of [" << min << " " << max << "] range\n";
1905 throw faustexception(error.str());
1906 }
1907 return new AddSliderInst(label, zone, init, min, max, step, AddSliderInst::kVertical);
1908 }
1909
genAddNumEntryInstInstBuilder1910 static AddSliderInst* genAddNumEntryInst(const string& label, const string& zone, double init, double min,
1911 double max, double step)
1912 {
1913 stringstream error;
1914 if (min > max) {
1915 error << "ERROR : num entry \'"<< label << "\' min = " << min << " should be less than max = " << max << "\n";
1916 throw faustexception(error.str());
1917 } else if (init < min || init > max) {
1918 error << "ERROR : num entry \'" << label << "\' init = " << init << " outside of [" << min << " " << max << "] range\n";
1919 throw faustexception(error.str());
1920 }
1921 return new AddSliderInst(label, zone, init, min, max, step, AddSliderInst::kNumEntry);
1922 }
1923
genAddHorizontalBargraphInstInstBuilder1924 static AddBargraphInst* genAddHorizontalBargraphInst(const string& label, const string& zone, double min,
1925 double max)
1926 {
1927 return new AddBargraphInst(label, zone, min, max, AddBargraphInst::kHorizontal);
1928 }
1929
genAddVerticalBargraphInstInstBuilder1930 static AddBargraphInst* genAddVerticalBargraphInst(const string& label, const string& zone, double min, double max)
1931 {
1932 return new AddBargraphInst(label, zone, min, max, AddBargraphInst::kVertical);
1933 }
1934
genAddSoundfileInstInstBuilder1935 static AddSoundfileInst* genAddSoundfileInst(const string& label, const string& url, const string& sf_zone)
1936 {
1937 return new AddSoundfileInst(label, url, sf_zone);
1938 }
1939
genLabelInstInstBuilder1940 static LabelInst* genLabelInst(const string& label) { return new LabelInst(label); }
1941
1942 // Null instruction
genNullValueInstInstBuilder1943 static NullValueInst* genNullValueInst() { return new NullValueInst(); }
genNullStatementInstInstBuilder1944 static NullStatementInst* genNullStatementInst() { return new NullStatementInst(); }
1945
1946 // Declarations
genDeclareVarInstInstBuilder1947 static DeclareVarInst* genDeclareVarInst(Address* address, Typed* typed, ValueInst* value = nullptr)
1948 {
1949 return new DeclareVarInst(address, typed, value);
1950 }
1951
genDeclareFunInstInstBuilder1952 static DeclareFunInst* genDeclareFunInst(const string& name, FunTyped* typed, BlockInst* code)
1953 {
1954 return new DeclareFunInst(name, typed, code);
1955 }
genDeclareFunInstInstBuilder1956 static DeclareFunInst* genDeclareFunInst(const string& name, FunTyped* typed)
1957 {
1958 return new DeclareFunInst(name, typed);
1959 }
1960
genDeclareStructTypeInstInstBuilder1961 static DeclareStructTypeInst* genDeclareStructTypeInst(StructTyped* type)
1962 {
1963 return new DeclareStructTypeInst(type);
1964 }
1965
genDeclareBufferIteratorsInstBuilder1966 static DeclareBufferIterators* genDeclareBufferIterators(const std::string& name1, const std::string& name2, int num_channels, bool mut)
1967 {
1968 return new DeclareBufferIterators(name1, name2, num_channels, mut);
1969 }
1970
1971 // Memory
genLoadVarInstInstBuilder1972 static LoadVarInst* genLoadVarInst(Address* address) { return new LoadVarInst(address); }
genLoadVarAddressInstInstBuilder1973 static LoadVarAddressInst* genLoadVarAddressInst(Address* address) { return new LoadVarAddressInst(address); }
genTeeVarInstBuilder1974 static TeeVarInst* genTeeVar(const string& vname, ValueInst* value)
1975 {
1976 return new TeeVarInst(InstBuilder::genNamedAddress(vname, Address::kStack), value);
1977 }
genStoreVarInstInstBuilder1978 static StoreVarInst* genStoreVarInst(Address* address, ValueInst* value)
1979 {
1980 return new StoreVarInst(address, value);
1981 }
genShiftArrayVarInstInstBuilder1982 static ShiftArrayVarInst* genShiftArrayVarInst(Address* address, int delay)
1983 {
1984 return new ShiftArrayVarInst(address, delay);
1985 }
1986
1987 // Numbers
genFloatNumInstInstBuilder1988 static FloatNumInst* genFloatNumInst(float num) { return new FloatNumInst(num); }
genFloatArrayNumInstInstBuilder1989 static FloatArrayNumInst* genFloatArrayNumInst(int size) { return new FloatArrayNumInst(size); }
genDoubleNumInstInstBuilder1990 static DoubleNumInst* genDoubleNumInst(double num) { return new DoubleNumInst(num); }
genDoubleArrayNumInstInstBuilder1991 static DoubleArrayNumInst* genDoubleArrayNumInst(int size) { return new DoubleArrayNumInst(size); }
genFixedPointNumInstInstBuilder1992 static FixedPointNumInst* genFixedPointNumInst(double num) { return new FixedPointNumInst(num); }
genFixedPointArrayNumInstInstBuilder1993 static FixedPointArrayNumInst* genFixedPointArrayNumInst(int size) { return new FixedPointArrayNumInst(size); }
genQuadNumInstInstBuilder1994 static DoubleNumInst* genQuadNumInst(double num) { return new DoubleNumInst(num); } // Use DoubleNumInst
1995
1996 static ValueInst* genTypedZero(Typed::VarType type);
1997
genRealNumInstInstBuilder1998 static ValueInst* genRealNumInst(Typed::VarType ctype, double num)
1999 {
2000 if (ctype == Typed::kFloat) {
2001 return new FloatNumInst(float(num));
2002 } else if (ctype == Typed::kFloatMacro) {
2003 return genCastInst(new DoubleNumInst(num), genBasicTyped(Typed::kFloatMacro));
2004 } else if (ctype == Typed::kDouble) {
2005 return new DoubleNumInst(num);
2006 } else if (ctype == Typed::kQuad) {
2007 return new DoubleNumInst(num);
2008 } else if (ctype == Typed::kFixedPoint) {
2009 return new FixedPointNumInst(num);
2010 } else {
2011 faustassert(false);
2012 }
2013 return nullptr;
2014 }
2015
genArrayNumInstInstBuilder2016 static ValueInst* genArrayNumInst(Typed::VarType ctype, int size)
2017 {
2018 if (ctype == Typed::kInt32) {
2019 return new Int32ArrayNumInst(size);
2020 } else if (ctype == Typed::kFloat) {
2021 return new FloatArrayNumInst(size);
2022 } else if (ctype == Typed::kDouble) {
2023 return new DoubleArrayNumInst(size);
2024 } else if (ctype == Typed::kFixedPoint) {
2025 return new FixedPointArrayNumInst(size);
2026 } else {
2027 faustassert(false);
2028 }
2029 return nullptr;
2030 }
2031
genInt32NumInstInstBuilder2032 static Int32NumInst* genInt32NumInst(int num) { return new Int32NumInst(num); }
genInt64NumInstInstBuilder2033 static Int64NumInst* genInt64NumInst(int64_t num) { return new Int64NumInst(num); }
genBoolNumInstInstBuilder2034 static BoolNumInst* genBoolNumInst(bool num) { return new BoolNumInst(num); }
2035
2036 // Numerical computation
genBinopInstInstBuilder2037 static BinopInst* genBinopInst(int opcode, ValueInst* inst1, ValueInst* inst2)
2038 {
2039 return new BinopInst(opcode, inst1, inst2);
2040 }
2041
genCastInstInstBuilder2042 static ValueInst* genCastInst(ValueInst* inst, Typed* typed_ext)
2043 {
2044 Int32NumInst* int_num = dynamic_cast<Int32NumInst*>(inst);
2045 FloatNumInst* float_num = dynamic_cast<FloatNumInst*>(inst);
2046 DoubleNumInst* double_num = dynamic_cast<DoubleNumInst*>(inst);
2047 BasicTyped* typed = dynamic_cast<BasicTyped*>(typed_ext);
2048 CastInst* cast = dynamic_cast<CastInst*>(inst);
2049
2050 if (!typed) {
2051 // Default case
2052 return new CastInst(inst, typed_ext);
2053 } else if (cast && (cast->fType == typed_ext)) {
2054 // Casting an already casted value with the same type
2055 return inst;
2056 } else if (typed->getType() == Typed::kFloat) {
2057 if (int_num) {
2058 // Simple float cast of integer
2059 return genFloatNumInst(float(int_num->fNum));
2060 } else if (float_num) {
2061 // No cast needed
2062 return inst;
2063 } else if (double_num) {
2064 return genFloatNumInst(float(double_num->fNum));
2065 } else {
2066 // Default case
2067 return new CastInst(inst, typed);
2068 }
2069 } else if (typed->getType() == Typed::kDouble || typed->getType() == Typed::kQuad) {
2070 if (int_num) {
2071 // Simple double cast of integer
2072 return genDoubleNumInst(double(int_num->fNum));
2073 } else if (float_num) {
2074 return genDoubleNumInst(double(float_num->fNum));
2075 } else if (double_num) {
2076 // No cast needed
2077 return inst;
2078 } else {
2079 // Default case
2080 return new CastInst(inst, typed);
2081 }
2082 } else if (typed->getType() == Typed::kInt32) {
2083 if (int_num) {
2084 // No cast needed
2085 return inst;
2086 } else if (float_num) {
2087 // Simple int cast of float
2088 return genInt32NumInst(int(float_num->fNum));
2089 } else if (double_num) {
2090 // Simple int cast of double
2091 return genInt32NumInst(int(double_num->fNum));
2092 } else {
2093 // Default case
2094 return new CastInst(inst, typed);
2095 }
2096 } else {
2097 // Default case
2098 return new CastInst(inst, typed);
2099 }
2100 }
2101
genBitcastInstInstBuilder2102 static ValueInst* genBitcastInst(ValueInst* inst, Typed* typed) { return new BitcastInst(inst, typed); }
2103 static ValueInst* genCastFloatInst(ValueInst* inst);
2104 static ValueInst* genCastFloatMacroInst(ValueInst* inst);
2105 static ValueInst* genCastInt32Inst(ValueInst* inst);
2106
2107 // Control flow
genRetInstInstBuilder2108 static RetInst* genRetInst(ValueInst* result = nullptr) { return new RetInst(result); }
genDropInstInstBuilder2109 static DropInst* genDropInst(ValueInst* result = nullptr) { return new DropInst(result); }
2110
2111 // Conditional
genSelect2InstInstBuilder2112 static Select2Inst* genSelect2Inst(ValueInst* cond_inst, ValueInst* then_inst, ValueInst* else_inst)
2113 {
2114 return new Select2Inst(cond_inst, then_inst, else_inst);
2115 }
2116
genControlInstInstBuilder2117 static StatementInst* genControlInst(ValueInst* cond_inst, StatementInst* exp_inst)
2118 {
2119 // If called with a NullValueInst, then the exp_inst is going to be always computed
2120 return (dynamic_cast<NullValueInst*>(cond_inst)) ? exp_inst : new ControlInst(cond_inst, exp_inst);
2121 }
2122
genIfInstInstBuilder2123 static IfInst* genIfInst(ValueInst* cond_inst, BlockInst* then_inst, BlockInst* else_inst)
2124 {
2125 return new IfInst(cond_inst, then_inst, else_inst);
2126 }
genIfInstInstBuilder2127 static IfInst* genIfInst(ValueInst* cond_inst, BlockInst* then_inst) { return new IfInst(cond_inst, then_inst); }
genSwitchInstInstBuilder2128 static SwitchInst* genSwitchInst(ValueInst* cond) { return new SwitchInst(cond); }
2129
2130 // Function management
genFunCallInstInstBuilder2131 static FunCallInst* genFunCallInst(const string& name, const list<ValueInst*>& args)
2132 {
2133 return new FunCallInst(name, args, false);
2134 }
genFunCallInstInstBuilder2135 static FunCallInst* genFunCallInst(const string& name, const list<ValueInst*>& args, bool method)
2136 {
2137 return new FunCallInst(name, args, method);
2138 }
genVoidFunCallInstInstBuilder2139 static DropInst* genVoidFunCallInst(const string& name, const list<ValueInst*>& args)
2140 {
2141 return new DropInst(new FunCallInst(name, args, false));
2142 }
genVoidFunCallInstInstBuilder2143 static DropInst* genVoidFunCallInst(const string& name, const list<ValueInst*>& args, bool method)
2144 {
2145 return new DropInst(new FunCallInst(name, args, method));
2146 }
2147
2148 // Loop
genForLoopInstInstBuilder2149 static ForLoopInst* genForLoopInst(StatementInst* init, ValueInst* end, StatementInst* increment,
2150 BlockInst* code = new BlockInst(), bool is_recursive = false)
2151 {
2152 faustassert(dynamic_cast<DeclareVarInst*>(init) || dynamic_cast<StoreVarInst*>(init));
2153 return new ForLoopInst(init, end, increment, code, is_recursive);
2154 }
2155
2156 // TODO: add access to the loop variable, generate ascending/descending loops...
genForLoopInstInstBuilder2157 static ForLoopInst* genForLoopInst(const string& index, int init, int size, int step = 1)
2158 {
2159 DeclareVarInst* dec = genDecLoopVar(index, genInt32Typed(), genInt32NumInst(init));
2160 ValueInst* end = genLessThan(dec->load(), genInt32NumInst(size));
2161 StoreVarInst* inc = dec->store(genAdd(dec->load(), step));
2162 return genForLoopInst(dec, end, inc);
2163 }
2164
2165 // Used for Rust backend
genSimpleForLoopInstInstBuilder2166 static SimpleForLoopInst* genSimpleForLoopInst(const string& name, ValueInst* upperBound,
2167 ValueInst* lowerBound = new Int32NumInst(0), bool reverse = false,
2168 BlockInst* code = new BlockInst())
2169 {
2170 faustassert(dynamic_cast<Int32NumInst*>(upperBound) || dynamic_cast<LoadVarInst*>(upperBound));
2171 faustassert(dynamic_cast<Int32NumInst*>(lowerBound) || dynamic_cast<LoadVarInst*>(lowerBound));
2172 return new SimpleForLoopInst(name, upperBound, lowerBound, reverse, code);
2173 }
genIteratorForLoopInstInstBuilder2174 static IteratorForLoopInst* genIteratorForLoopInst(const std::vector<NamedAddress*>& iterators, bool reverse = false,
2175 BlockInst* code = new BlockInst())
2176 {
2177 return new IteratorForLoopInst(iterators, reverse, code);
2178 }
2179
genWhileLoopInstInstBuilder2180 static WhileLoopInst* genWhileLoopInst(ValueInst* cond, BlockInst* code) { return new WhileLoopInst(cond, code); }
2181
genBlockInstInstBuilder2182 static BlockInst* genBlockInst(const list<StatementInst*>& code) { return new BlockInst(code); }
genBlockInstInstBuilder2183 static BlockInst* genBlockInst() { return new BlockInst(); }
2184
2185 // Types
2186 static BasicTyped* genBasicTyped(Typed::VarType type); // moved in instructions.cpp
2187
genInt32TypedInstBuilder2188 static BasicTyped* genInt32Typed() { return genBasicTyped(Typed::kInt32); }
genInt64TypedInstBuilder2189 static BasicTyped* genInt64Typed() { return genBasicTyped(Typed::kInt64); }
genVoidTypedInstBuilder2190 static BasicTyped* genVoidTyped() { return genBasicTyped(Typed::kVoid); }
genFloatTypedInstBuilder2191 static BasicTyped* genFloatTyped() { return genBasicTyped(Typed::kFloat); }
genDoubleTypedInstBuilder2192 static BasicTyped* genDoubleTyped() { return genBasicTyped(Typed::kDouble); }
genFloatMacroTypedInstBuilder2193 static BasicTyped* genFloatMacroTyped() { return genBasicTyped(Typed::kFloatMacro); }
2194
2195 static NamedTyped* genNamedTyped(const string& name, Typed* type);
2196 static NamedTyped* genNamedTyped(const string& name, Typed::VarType type);
2197
genFunTypedInstBuilder2198 static FunTyped* genFunTyped(const list<NamedTyped*>& args, BasicTyped* result,
2199 FunTyped::FunAttribute attribute = FunTyped::kDefault)
2200 {
2201 return new FunTyped(args, result, attribute);
2202 }
genVectorTypedInstBuilder2203 static VectorTyped* genVectorTyped(BasicTyped* type, int size) { return new VectorTyped(type, size); }
genArrayTypedInstBuilder2204 static ArrayTyped* genArrayTyped(Typed* type, int size, bool is_ptr = false)
2205 {
2206 return new ArrayTyped(type, size, is_ptr);
2207 }
genStructTypedInstBuilder2208 static StructTyped* genStructTyped(const string& name, const vector<NamedTyped*>& fields)
2209 {
2210 return new StructTyped(name, fields);
2211 }
2212
2213 // Addresses
genNamedAddressInstBuilder2214 static NamedAddress* genNamedAddress(const string& name, Address::AccessType access)
2215 {
2216 return new NamedAddress(name, access);
2217 }
genIndexedAddressInstBuilder2218 static IndexedAddress* genIndexedAddress(Address* address, ValueInst* index)
2219 {
2220 return new IndexedAddress(address, index);
2221 }
2222
2223 // Helper build methods
genDecArrayVarInstBuilder2224 static DeclareVarInst* genDecArrayVar(const string& vname, Address::AccessType var_access, Typed* type, int size)
2225 {
2226 return genDeclareVarInst(genNamedAddress(vname, var_access), genArrayTyped(type, size));
2227 }
2228
genLoadArrayVarInstBuilder2229 static LoadVarInst* genLoadArrayVar(const string& vname, Address::AccessType var_access, ValueInst* index)
2230 {
2231 return genLoadVarInst(genIndexedAddress(genNamedAddress(vname, var_access), index));
2232 }
2233 // Actually same as genLoadArrayVar
genLoadStructPtrVarInstBuilder2234 static LoadVarInst* genLoadStructPtrVar(const string& vname, Address::AccessType var_access, ValueInst* index)
2235 {
2236 return genLoadArrayVar(vname, var_access, index);
2237 }
2238
genStoreArrayVarInstBuilder2239 static StoreVarInst* genStoreArrayVar(const string& vname, Address::AccessType var_access, ValueInst* index,
2240 ValueInst* exp)
2241 {
2242 return genStoreVarInst(genIndexedAddress(genNamedAddress(vname, var_access), index), exp);
2243 }
2244
2245 // Struct variable
genDecStructVarInstBuilder2246 static DeclareVarInst* genDecStructVar(const string& vname, Typed* type, ValueInst* exp = nullptr)
2247 {
2248 return genDeclareVarInst(genNamedAddress(vname, Address::kStruct), type, exp);
2249 }
2250
genDecVolatileStructVarInstBuilder2251 static DeclareVarInst* genDecVolatileStructVar(const string& vname, Typed* type, ValueInst* exp = nullptr)
2252 {
2253 return genDeclareVarInst(genNamedAddress(vname, (Address::AccessType)(Address::kStruct | Address::kVolatile)),
2254 type, exp);
2255 }
2256
genDecArrayStructVarInstBuilder2257 static DeclareVarInst* genDecArrayStructVar(const string& vname, Typed* type, int size)
2258 {
2259 return genDecArrayVar(vname, Address::kStruct, type, size);
2260 }
2261
genLoadStructVarInstBuilder2262 static LoadVarInst* genLoadStructVar(const string& vname)
2263 {
2264 return genLoadVarInst(genNamedAddress(vname, Address::kStruct));
2265 }
2266
genLoadMutRefStructVarInstBuilder2267 static LoadVarInst* genLoadMutRefStructVar(const string& vname)
2268 {
2269 return genLoadVarInst(
2270 genNamedAddress(vname, (Address::AccessType)(Address::kStruct | Address::kReference | Address::kMutable)));
2271 }
2272
genVolatileLoadStructVarInstBuilder2273 static LoadVarInst* genVolatileLoadStructVar(const string& vname)
2274 {
2275 return genLoadVarInst(genNamedAddress(vname, (Address::AccessType)(Address::kStruct | Address::kVolatile)));
2276 }
2277
2278 template <typename Iterator>
genLoadArrayStructVarInstBuilder2279 static LoadVarInst* genLoadArrayStructVar(const string& vname, Iterator indexBegin, Iterator indexEnd)
2280 {
2281 typedef reverse_iterator<Iterator> Rit;
2282 Rit rbegin(indexEnd);
2283 Rit rend(indexBegin);
2284
2285 Address* address = genNamedAddress(vname, Address::kStruct);
2286 for (Rit it = rbegin; it != rend; ++it) {
2287 address = genIndexedAddress(address, *it);
2288 }
2289
2290 return genLoadVarInst(address);
2291 }
2292
genLoadArrayStructVarInstBuilder2293 static LoadVarInst* genLoadArrayStructVar(const string& vname, ValueInst* index)
2294 {
2295 vector<ValueInst*> indices;
2296 indices.push_back(index);
2297 return genLoadArrayStructVar(vname, indices.begin(), indices.end());
2298 }
2299
genLoadArrayStructVarInstBuilder2300 static LoadVarInst* genLoadArrayStructVar(const string& vname)
2301 {
2302 return genLoadVarInst(genNamedAddress(vname, Address::kStruct));
2303 }
2304
genLoadArrayStructVarAddressInstBuilder2305 static LoadVarAddressInst* genLoadArrayStructVarAddress(const string& vname, ValueInst* index)
2306 {
2307 return genLoadVarAddressInst(genIndexedAddress(genNamedAddress(vname, Address::kStruct), index));
2308 }
2309
genStoreStructVarInstBuilder2310 static StoreVarInst* genStoreStructVar(const string& vname, ValueInst* exp)
2311 {
2312 return genStoreVarInst(genNamedAddress(vname, Address::kStruct), exp);
2313 }
2314
genVolatileStoreStructVarInstBuilder2315 static StoreVarInst* genVolatileStoreStructVar(const string& vname, ValueInst* exp)
2316 {
2317 return genStoreVarInst(genNamedAddress(vname, (Address::AccessType)(Address::kStruct | Address::kVolatile)),
2318 exp);
2319 }
2320
2321 template <typename Iterator>
genStoreArrayStructVarInstBuilder2322 static StoreVarInst* genStoreArrayStructVar(const string& vname, ValueInst* exp, Iterator indexBegin,
2323 Iterator indexEnd)
2324 {
2325 typedef reverse_iterator<Iterator> Rit;
2326 Rit rbegin(indexEnd);
2327 Rit rend(indexBegin);
2328
2329 Address* address = genNamedAddress(vname, Address::kStruct);
2330 for (Rit it = rbegin; it != rend; ++it) {
2331 address = genIndexedAddress(address, *it);
2332 }
2333
2334 return genStoreVarInst(address, exp);
2335 }
2336
genStoreArrayStructVarInstBuilder2337 static StoreVarInst* genStoreArrayStructVar(const string& vname, ValueInst* index, ValueInst* exp)
2338 {
2339 vector<ValueInst*> indices;
2340 indices.push_back(index);
2341 return genStoreArrayStructVar(vname, exp, indices.begin(), indices.end());
2342 }
2343
genStoreArrayStructVarInstBuilder2344 static StoreVarInst* genStoreArrayStructVar(const string& vname, ValueInst* exp)
2345 {
2346 return genStoreVarInst(genNamedAddress(vname, Address::kStruct), exp);
2347 }
2348
2349 // Static struct variable
genDecStaticStructVarInstBuilder2350 static DeclareVarInst* genDecStaticStructVar(const string& vname, Typed* type, ValueInst* exp = nullptr)
2351 {
2352 return genDeclareVarInst(genNamedAddress(vname, Address::kStaticStruct), type, exp);
2353 }
2354
genDecConstStaticStructVarInstBuilder2355 static DeclareVarInst* genDecConstStaticStructVar(const string& vname, Typed* type, ValueInst* exp = nullptr)
2356 {
2357 return genDeclareVarInst(
2358 genNamedAddress(vname, (Address::AccessType)(Address::kStaticStruct | Address::kConst)), type, exp);
2359 }
2360
genLoadStaticStructVarInstBuilder2361 static LoadVarInst* genLoadStaticStructVar(const string& vname)
2362 {
2363 return genLoadVarInst(genNamedAddress(vname, Address::kStaticStruct));
2364 }
2365
genLoadStaticMutRefStructVarInstBuilder2366 static LoadVarInst* genLoadStaticMutRefStructVar(const string& vname)
2367 {
2368 return genLoadVarInst(genNamedAddress(
2369 vname, (Address::AccessType)(Address::kStaticStruct | Address::kReference | Address::kMutable)));
2370 }
2371
genStoreStaticStructVarInstBuilder2372 static StoreVarInst* genStoreStaticStructVar(const string& vname, ValueInst* exp)
2373 {
2374 return genStoreVarInst(genNamedAddress(vname, Address::kStaticStruct), exp);
2375 }
2376
2377 template <typename Iterator>
genLoadArrayStaticStructVarInstBuilder2378 static LoadVarInst* genLoadArrayStaticStructVar(const string& vname, Iterator indexBegin, Iterator indexEnd)
2379 {
2380 typedef reverse_iterator<Iterator> Rit;
2381 Rit rbegin(indexEnd);
2382 Rit rend(indexBegin);
2383
2384 Address* address = genNamedAddress(vname, Address::kStaticStruct);
2385 for (Rit it = rbegin; it != rend; ++it) {
2386 address = genIndexedAddress(address, *it);
2387 }
2388
2389 return genLoadVarInst(address);
2390 }
2391
genLoadArrayStaticStructVarInstBuilder2392 static LoadVarInst* genLoadArrayStaticStructVar(const string& vname, ValueInst* index)
2393 {
2394 vector<ValueInst*> indices;
2395 indices.push_back(index);
2396 return genLoadArrayStaticStructVar(vname, indices.begin(), indices.end());
2397 }
2398
2399 template <typename Iterator>
genStoreArrayStaticStructVarInstBuilder2400 static StoreVarInst* genStoreArrayStaticStructVar(const string& vname, ValueInst* exp, Iterator indexBegin,
2401 Iterator indexEnd)
2402 {
2403 typedef reverse_iterator<Iterator> Rit;
2404 Rit rbegin(indexEnd);
2405 Rit rend(indexBegin);
2406
2407 Address* address = genNamedAddress(vname, Address::kStaticStruct);
2408 for (Rit it = rbegin; it != rend; ++it) {
2409 address = genIndexedAddress(address, *it);
2410 }
2411
2412 return genStoreVarInst(address, exp);
2413 }
2414
genStoreArrayStaticStructVarInstBuilder2415 static StoreVarInst* genStoreArrayStaticStructVar(const string& vname, ValueInst* index, ValueInst* exp)
2416 {
2417 vector<ValueInst*> indices;
2418 indices.push_back(index);
2419 return genStoreArrayStructVar(vname, exp, indices.begin(), indices.end());
2420 }
2421
2422 // Stack variable
genDecStackVarInstBuilder2423 static DeclareVarInst* genDecStackVar(const string& vname, Typed* type, ValueInst* exp = nullptr)
2424 {
2425 return genDeclareVarInst(genNamedAddress(vname, Address::kStack), type, exp);
2426 }
2427
genDecArrayStackVarInstBuilder2428 static DeclareVarInst* genDecArrayStackVar(const string& vname, Typed* type, int size)
2429 {
2430 return genDecArrayVar(vname, Address::kStack, type, size);
2431 }
2432
genLoadStackVarInstBuilder2433 static LoadVarInst* genLoadStackVar(const string& vname)
2434 {
2435 return genLoadVarInst(genNamedAddress(vname, Address::kStack));
2436 }
2437
genLoadStackVarAddressInstBuilder2438 static LoadVarAddressInst* genLoadStackVarAddress(const string& vname)
2439 {
2440 return genLoadVarAddressInst(genNamedAddress(vname, Address::kStack));
2441 }
2442
genLoadArrayStackVarInstBuilder2443 static LoadVarInst* genLoadArrayStackVar(const string& vname, ValueInst* index)
2444 {
2445 return genLoadVarInst(genIndexedAddress(genNamedAddress(vname, Address::kStack), index));
2446 }
2447
genLoadArrayStackVarAddressInstBuilder2448 static LoadVarAddressInst* genLoadArrayStackVarAddress(const string& vname, ValueInst* index)
2449 {
2450 return genLoadVarAddressInst(genIndexedAddress(genNamedAddress(vname, Address::kStack), index));
2451 }
2452
genStoreStackVarInstBuilder2453 static StoreVarInst* genStoreStackVar(const string& vname, ValueInst* exp)
2454 {
2455 return genStoreVarInst(genNamedAddress(vname, Address::kStack), exp);
2456 }
2457
genStoreArrayStackVarInstBuilder2458 static StoreVarInst* genStoreArrayStackVar(const string& vname, ValueInst* index, ValueInst* exp)
2459 {
2460 return genStoreVarInst(genIndexedAddress(genNamedAddress(vname, Address::kStack), index), exp);
2461 }
2462
2463 // Loop variable
genDecLoopVarInstBuilder2464 static DeclareVarInst* genDecLoopVar(const string& vname, Typed* type, ValueInst* exp = nullptr)
2465 {
2466 return genDeclareVarInst(genNamedAddress(vname, Address::kLoop), type, exp);
2467 }
2468
genLoadLoopVarInstBuilder2469 static LoadVarInst* genLoadLoopVar(const string& vname)
2470 {
2471 return genLoadVarInst(genNamedAddress(vname, Address::kLoop));
2472 }
2473
genStoreLoopVarInstBuilder2474 static StoreVarInst* genStoreLoopVar(const string& vname, ValueInst* exp)
2475 {
2476 return genStoreVarInst(genNamedAddress(vname, Address::kLoop), exp);
2477 }
2478
2479 // FunArgs variable
genLoadFunArgsVarInstBuilder2480 static LoadVarInst* genLoadFunArgsVar(const string& vname)
2481 {
2482 return genLoadVarInst(genNamedAddress(vname, Address::kFunArgs));
2483 }
2484
genLoadArrayFunArgsVarInstBuilder2485 static LoadVarInst* genLoadArrayFunArgsVar(const string& vname, ValueInst* index)
2486 {
2487 return genLoadVarInst(genIndexedAddress(genNamedAddress(vname, Address::kFunArgs), index));
2488 }
2489
genStoreArrayFunArgsVarInstBuilder2490 static StoreVarInst* genStoreArrayFunArgsVar(const string& vname, ValueInst* index, ValueInst* exp)
2491 {
2492 return genStoreVarInst(genIndexedAddress(genNamedAddress(vname, Address::kFunArgs), index), exp);
2493 }
2494
2495 // Global variable
genDecGlobalVarInstBuilder2496 static DeclareVarInst* genDecGlobalVar(const string& vname, Typed* type, ValueInst* exp = nullptr)
2497 {
2498 return genDeclareVarInst(genNamedAddress(vname, Address::kGlobal), type, exp);
2499 }
2500
genDecConstGlobalVarInstBuilder2501 static DeclareVarInst* genDecConstGlobalVar(const string& vname, Typed* type, ValueInst* exp = nullptr)
2502 {
2503 return genDeclareVarInst(genNamedAddress(vname, (Address::AccessType)(Address::kGlobal | Address::kConst)),
2504 type, exp);
2505 }
2506
genLoadGlobalVarInstBuilder2507 static LoadVarInst* genLoadGlobalVar(const string& vname)
2508 {
2509 return genLoadVarInst(genNamedAddress(vname, Address::kGlobal));
2510 }
2511
genStoreGlobalVarInstBuilder2512 static StoreVarInst* genStoreGlobalVar(const string& vname, ValueInst* exp)
2513 {
2514 return genStoreVarInst(genNamedAddress(vname, Address::kGlobal), exp);
2515 }
2516
2517 // Binop operations
genAddInstBuilder2518 static BinopInst* genAdd(ValueInst* a1, ValueInst* a2) { return genBinopInst(kAdd, a1, a2); }
2519
genAddInstBuilder2520 static BinopInst* genAdd(ValueInst* a1, int a2) { return genBinopInst(kAdd, a1, genInt32NumInst(a2)); }
2521
genSubInstBuilder2522 static BinopInst* genSub(ValueInst* a1, ValueInst* a2) { return genBinopInst(kSub, a1, a2); }
2523
genSubInstBuilder2524 static BinopInst* genSub(ValueInst* a1, int a2) { return genBinopInst(kSub, a1, genInt32NumInst(a2)); }
2525
genMulInstBuilder2526 static BinopInst* genMul(ValueInst* a1, ValueInst* a2) { return genBinopInst(kMul, a1, a2); }
2527
genDivInstBuilder2528 static BinopInst* genDiv(ValueInst* a1, ValueInst* a2) { return genBinopInst(kDiv, a1, a2); }
2529
genRemInstBuilder2530 static BinopInst* genRem(ValueInst* a1, ValueInst* a2) { return genBinopInst(kRem, a1, a2); }
2531
genGreaterThanInstBuilder2532 static BinopInst* genGreaterThan(ValueInst* a1, ValueInst* a2) { return genBinopInst(kGT, a1, a2); }
2533
genLessThanInstBuilder2534 static BinopInst* genLessThan(ValueInst* a1, ValueInst* a2) { return genBinopInst(kLT, a1, a2); }
2535
genGreaterEqualInstBuilder2536 static BinopInst* genGreaterEqual(ValueInst* a1, ValueInst* a2) { return genBinopInst(kGE, a1, a2); }
2537
genLessEqualInstBuilder2538 static BinopInst* genLessEqual(ValueInst* a1, ValueInst* a2) { return genBinopInst(kLE, a1, a2); }
2539
genEqualInstBuilder2540 static BinopInst* genEqual(ValueInst* a1, ValueInst* a2) { return genBinopInst(kEQ, a1, a2); }
2541
genNotEqualInstBuilder2542 static BinopInst* genNotEqual(ValueInst* a1, ValueInst* a2) { return genBinopInst(kNE, a1, a2); }
2543
genAndInstBuilder2544 static BinopInst* genAnd(ValueInst* a1, ValueInst* a2) { return genBinopInst(kAND, a1, a2); }
2545
genOrInstBuilder2546 static BinopInst* genOr(ValueInst* a1, ValueInst* a2) { return genBinopInst(kOR, a1, a2); }
2547
genXOrInstBuilder2548 static BinopInst* genXOr(ValueInst* a1, ValueInst* a2) { return genBinopInst(kXOR, a1, a2); }
2549
2550 // Functions
2551 static DeclareFunInst* genVoidFunction(const string& name, BlockInst* code = new BlockInst());
2552 static DeclareFunInst* genVoidFunction(const string& name, list<NamedTyped*>& args, BlockInst* code,
2553 bool isvirtual = false);
2554 static DeclareFunInst* genFunction0(const string& name, Typed::VarType res, BlockInst* code = new BlockInst());
2555 static DeclareFunInst* genFunction1(const string& name, Typed::VarType res, const string& arg1,
2556 Typed::VarType arg1_ty, BlockInst* code = new BlockInst());
2557 static DeclareFunInst* genFunction2(const string& name, Typed::VarType res, const string& arg1,
2558 Typed::VarType arg1_ty, const string& arg2, Typed::VarType arg2_ty,
2559 BlockInst* code = new BlockInst());
2560 static DeclareFunInst* genFunction3(const string& name, Typed::VarType res, const string& arg1,
2561 Typed::VarType arg1_ty, const string& arg2, Typed::VarType arg2_ty,
2562 const string& arg3, Typed::VarType arg3_ty, BlockInst* code = new BlockInst());
2563 static DeclareFunInst* genFunction4(const string& name, Typed::VarType res, const string& arg1,
2564 Typed::VarType arg1_ty, const string& arg2, Typed::VarType arg2_ty,
2565 const string& arg3, Typed::VarType arg3_ty, const string& arg4,
2566 Typed::VarType arg4_ty, BlockInst* code = new BlockInst());
2567 static DeclareFunInst* genFunction5(const string& name, Typed::VarType res, const string& arg1,
2568 Typed::VarType arg1_ty, const string& arg2, Typed::VarType arg2_ty,
2569 const string& arg3, Typed::VarType arg3_ty, const string& arg4,
2570 Typed::VarType arg4_ty, const string& arg5, Typed::VarType arg5_ty,
2571 BlockInst* code = new BlockInst());
2572 static DeclareFunInst* genFunction6(const string& name, Typed::VarType res, const string& arg1,
2573 Typed::VarType arg1_ty, const string& arg2, Typed::VarType arg2_ty,
2574 const string& arg3, Typed::VarType arg3_ty, const string& arg4,
2575 Typed::VarType arg4_ty, const string& arg5, Typed::VarType arg5_ty,
2576 const string& arg6, Typed::VarType arg6_ty, BlockInst* code = new BlockInst());
2577
2578 // Convert a signal type in a Fir type by using an intermediate Tree based implementation to assure type creation
2579 // unicity. HACK : 09/12/11
2580 // static DeclareTypeInst* genType(AudioType* type);
2581
2582 // HACK : 09/12/11
2583 // static Typed* mapFIRType(AudioType* type);
2584 };
2585
2586 /* syntactic sugar for index computations
2587 *
2588 * wrapper for ValueInst* with support for basic arithmetics
2589 *
2590 */
2591 struct FIRIndex {
2592 /* explicit constructors in order to avoid the generation of implicit conversions */
FIRIndexFIRIndex2593 explicit FIRIndex(ValueInst* inst) : fValue(inst) {}
2594
FIRIndexFIRIndex2595 explicit FIRIndex(int num) : fValue(InstBuilder::genInt32NumInst(num)) {}
2596
FIRIndexFIRIndex2597 FIRIndex(FIRIndex const& rhs) : fValue(rhs.fValue) {}
2598
2599 /* implicitly convert to ValueInst* in order to simplify the usage */
operator ValueInst*FIRIndex2600 operator ValueInst*(void)const { return fValue; }
2601
2602 // Add
operator +(FIRIndex const & lhs,ValueInst * rhs)2603 friend FIRIndex operator+(FIRIndex const& lhs, ValueInst* rhs)
2604 {
2605 return FIRIndex(InstBuilder::genAdd(lhs.fValue, rhs));
2606 }
2607
operator +(FIRIndex const & lhs,FIRIndex const & rhs)2608 friend FIRIndex operator+(FIRIndex const& lhs, FIRIndex const& rhs) { return operator+(lhs, rhs.fValue); }
2609
operator +(FIRIndex const & lhs,int rhs)2610 friend FIRIndex operator+(FIRIndex const& lhs, int rhs)
2611 {
2612 return operator+(lhs, InstBuilder::genInt32NumInst(rhs));
2613 }
2614
2615 // Sub
operator -(FIRIndex const & lhs,ValueInst * rhs)2616 friend FIRIndex operator-(FIRIndex const& lhs, ValueInst* rhs)
2617 {
2618 return FIRIndex(InstBuilder::genSub(lhs.fValue, rhs));
2619 }
2620
operator -(FIRIndex const & lhs,FIRIndex const & rhs)2621 friend FIRIndex operator-(FIRIndex const& lhs, FIRIndex const& rhs) { return operator-(lhs, rhs.fValue); }
2622
operator -(FIRIndex const & lhs,int rhs)2623 friend FIRIndex operator-(FIRIndex const& lhs, int rhs)
2624 {
2625 return operator-(lhs, InstBuilder::genInt32NumInst(rhs));
2626 }
2627
2628 // Mult
operator *(FIRIndex const & lhs,ValueInst * rhs)2629 friend FIRIndex operator*(FIRIndex const& lhs, ValueInst* rhs)
2630 {
2631 return FIRIndex(InstBuilder::genMul(lhs.fValue, rhs));
2632 }
2633
operator *(FIRIndex const & lhs,FIRIndex const & rhs)2634 friend FIRIndex operator*(FIRIndex const& lhs, FIRIndex const& rhs) { return operator*(lhs, rhs.fValue); }
2635
operator *(FIRIndex const & lhs,int rhs)2636 friend FIRIndex operator*(FIRIndex const& lhs, int rhs)
2637 {
2638 return operator*(lhs, InstBuilder::genInt32NumInst(rhs));
2639 }
2640
2641 // Div
operator /(FIRIndex const & lhs,ValueInst * rhs)2642 friend FIRIndex operator/(FIRIndex const& lhs, ValueInst* rhs)
2643 {
2644 return FIRIndex(InstBuilder::genDiv(lhs.fValue, rhs));
2645 }
2646
operator /(FIRIndex const & lhs,FIRIndex const & rhs)2647 friend FIRIndex operator/(FIRIndex const& lhs, FIRIndex const& rhs) { return operator/(lhs, rhs.fValue); }
2648
operator /(FIRIndex const & lhs,int rhs)2649 friend FIRIndex operator/(FIRIndex const& lhs, int rhs)
2650 {
2651 return operator/(lhs, InstBuilder::genInt32NumInst(rhs));
2652 }
2653
2654 // And
operator &(FIRIndex const & lhs,ValueInst * rhs)2655 friend FIRIndex operator&(FIRIndex const& lhs, ValueInst* rhs)
2656 {
2657 return FIRIndex(InstBuilder::genAnd(lhs.fValue, rhs));
2658 }
2659
operator &(FIRIndex const & lhs,FIRIndex const & rhs)2660 friend FIRIndex operator&(FIRIndex const& lhs, FIRIndex const& rhs) { return operator&(lhs, rhs.fValue); }
2661
operator &(FIRIndex const & lhs,int rhs)2662 friend FIRIndex operator&(FIRIndex const& lhs, int rhs)
2663 {
2664 return operator&(lhs, InstBuilder::genInt32NumInst(rhs));
2665 }
2666
2667 // Modulo
operator %(FIRIndex const & lhs,ValueInst * rhs)2668 friend FIRIndex operator%(FIRIndex const& lhs, ValueInst* rhs)
2669 {
2670 return FIRIndex(InstBuilder::genRem(lhs.fValue, rhs));
2671 }
2672
operator %(FIRIndex const & lhs,FIRIndex const & rhs)2673 friend FIRIndex operator%(FIRIndex const& lhs, FIRIndex const& rhs) { return operator%(lhs, rhs.fValue); }
2674
operator %(FIRIndex const & lhs,int rhs)2675 friend FIRIndex operator%(FIRIndex const& lhs, int rhs)
2676 {
2677 return operator%(lhs, InstBuilder::genInt32NumInst(rhs));
2678 }
2679
2680 // Equal
operator ==(FIRIndex const & lhs,ValueInst * rhs)2681 friend FIRIndex operator==(FIRIndex const& lhs, ValueInst* rhs)
2682 {
2683 return FIRIndex(InstBuilder::genEqual(lhs.fValue, rhs));
2684 }
2685
operator ==(FIRIndex const & lhs,FIRIndex const & rhs)2686 friend FIRIndex operator==(FIRIndex const& lhs, FIRIndex const& rhs) { return operator==(lhs, rhs.fValue); }
2687
operator ==(FIRIndex const & lhs,int rhs)2688 friend FIRIndex operator==(FIRIndex const& lhs, int rhs)
2689 {
2690 return operator==(lhs, InstBuilder::genInt32NumInst(rhs));
2691 }
2692
2693 // Inf
operator <(FIRIndex const & lhs,ValueInst * rhs)2694 friend FIRIndex operator<(FIRIndex const& lhs, ValueInst* rhs)
2695 {
2696 return FIRIndex(InstBuilder::genLessThan(lhs.fValue, rhs));
2697 }
2698
operator <(FIRIndex const & lhs,FIRIndex const & rhs)2699 friend FIRIndex operator<(FIRIndex const& lhs, FIRIndex const& rhs) { return operator<(lhs, rhs.fValue); }
2700
operator <(FIRIndex const & lhs,int rhs)2701 friend FIRIndex operator<(FIRIndex const& lhs, int rhs)
2702 {
2703 return operator<(lhs, InstBuilder::genInt32NumInst(rhs));
2704 }
2705
2706 private:
2707 ValueInst* fValue;
2708 };
2709
2710 #endif
2711
2712 /*
2713
2714 Name := sequence of char
2715
2716 Size := digits
2717
2718 Opcode := + | - | * | / |...etc...
2719
2720 Access := kGlobal | kStruct | kStaticStruct | kFunArgs | kStack | kLoop
2721
2722 Type := kFloat | kInt32 | kDouble | kVoid | Type* --> Type | Vector (Type) | Array (Type) if size = 0, then
2723 equivalent to a pointer on the considered type
2724
2725 Address := Access name | Address index
2726
2727 Statement := DeclareVar (Address, Type, Value)
2728 | DeclareFun (Name, Type, Block)
2729 | ForLoop (Statement, Value, Statement, Block)
2730 | SimpleForLoop (string, Value, Block)
2731 | WhileLoop (Value, Block)
2732 | StoreVar (Address, Value)
2733 | Drop (Value)
2734 | Return (Value)
2735 | BlockInst (Statement*)
2736 | If (Value, BlockInst, BlockInst)
2737 | Switch (Value, <int>, BlockInst>*)
2738
2739 Value := LoadVar (Address)
2740 | Float | Int | Double | Bool
2741 | Select (Value1, Value2, Value3)
2742 | Binop (Opcode, Value1, Value2)
2743 | Cast (Type, Value)
2744 | Null ()
2745
2746 Code rewritting :
2747
2748 For WSS:
2749
2750 1) change access of variable of type kStack in kStruct
2751
2752 Loop to function rewritting (faster compilation ?):
2753
2754 2 methods
2755
2756 I)
2757
2758 1) change kStack variables in kStruct
2759 2) transform Loop (Name, Value, Statement*) in DeclareFun (Name, Type, Statement*) : function type kVoid --> kVoid
2760 3) in Compute, replace each loop with a call to the created function
2761
2762 II)
2763
2764 1) in each loop, transform in put vector access from kStack in kFunArgs
2765 2) transform Loop (Name, Value, Statement*) in DeclareFun (Name, Type, Statement*) : all input variables become function
2766 parameters 3) in Compute, replace each loop with a call to the created function giving it the good parameters
2767
2768 Scalarisation (some ideas, possibly not correct or not complete...):
2769
2770 1) transform all vectors *without delay* on the stack (used in loops) in scalar
2771 2) in each loop, transform input vector accessing scalar access (Load/Store)
2772 3) regroup all "postcode" of all loop at the end
2773 4) rename loop variable into the Compute variable name
2774 5) extract code and put it in Compute, suppress Loop statements
2775
2776 Vision des boucles (count, liste de vecteurs d'entrée, liste de vecteurs de sorties) différente du prototype externe
2777 compute(count, float**, float**) ou veut homogenéiser
2778
2779 D'ou:
2780
2781 DAG de boucles au format (count, liste de vecteurs d'entrée, liste de vecteurs de sorties)
2782 compute(count, float**, float**)
2783
2784 1) générer le header qui prépare les tableaux d'entrée et de sortie séparés
2785 2) compiler les boucles
2786
2787 Comment différencier les vecteurs sans retard (qu'on peut transformer en scalaire) des vecteurs avec retard ? Avec un
2788 nommage spécifique ?
2789
2790 TODO : gestion des indices de boucles:
2791
2792 - dans IndexedAddress, mettre un ValueInst à la place de fIndex, mettre à jour les visiteurs
2793
2794 - dans InstructionsCompiler, générer des accès avec "LoadVar" (loop-index)
2795
2796 - dans ForLoopInst, fName devient un "DeclareVarInst" (permet de nommer et d'initialiser l'indice), ajout d'une
2797 expression test, ajout de ValueInst fNext, calcul qui utilise fName.
2798
2799 - nouveau type d'accès kLoop pour les variables de loop
2800
2801 - lors des transformations sur les loops, Loop2FunctionBuider, SeqLoopBuilderVisitor, "désactiver" les statements qui
2802 manipulent les indices de la boucle ?? (pas besoin, ils n'apparaissent pas dans le corps de le boucle, par contre
2803 l'indice de la boucle est utilisé dans le corps de la boucle, il faut le faire correspondre au nouvel indice de boucle,
2804 renommage nécessaire ?)
2805
2806 - utiliser le *même* nom d'index dans ForLoopInst et dans le code interne de la loop
2807
2808 */
2809