source: icGREP/icgrep-devel/icgrep/pablo/function.h @ 4870

Last change on this file since 4870 was 4870, checked in by nmedfort, 4 years ago

Bug fix for Multiplexing. Added ability to set the body of a If/While? node after creation.

File size: 4.8 KB
Line 
1#ifndef FUNCTION_H
2#define FUNCTION_H
3
4#include <pablo/pabloAST.h>
5#include <pablo/pe_var.h>
6#include <pablo/ps_assign.h>
7#include <pablo/symbol_generator.h>
8
9namespace pablo {
10
11class Var;
12class Assign;
13class PabloBlock;
14class String;
15
16class Prototype : public PabloAST {
17    friend class PabloBlock;
18public:
19
20    static inline bool classof(const PabloAST * e) {
21        return e->getClassTypeId() == ClassTypeId::Prototype;
22    }
23
24    static inline bool classof(void *) {
25        return false;
26    }
27
28    static Prototype * Create(std::string name, const unsigned numOfParameters, const unsigned numOfResults, void * functionPtr = nullptr);
29
30    const String * getName() const {
31        return mName;
32    }
33
34    unsigned getNumOfParameters() const {
35        return mNumOfParameters;
36    }
37
38    unsigned getNumOfResults() const {
39        return mNumOfResults;
40    }
41
42    void * getFunctionPtr() const {
43        return mFunctionPtr;
44    }
45protected:
46    Prototype(const PabloAST::ClassTypeId type, std::string && name, const unsigned numOfParameters, const unsigned numOfResults, void * functionPtr);
47protected:
48    const String * const    mName;
49    const unsigned          mNumOfParameters;
50    const unsigned          mNumOfResults;
51    void *                  mFunctionPtr;
52};
53
54inline Prototype * Prototype::Create(std::string name, const unsigned numOfParameters, const unsigned numOfResults, void * functionPtr) {
55    return new Prototype(PabloAST::ClassTypeId::Prototype, std::move(name), numOfParameters, numOfResults, functionPtr);
56}
57
58class PabloFunction : public Prototype {
59    friend class PabloBlock;
60    using ParamAllocator = VectorAllocator::rebind<Var *>::other;
61    using ResultAllocator = VectorAllocator::rebind<Assign *>::other;
62public:
63
64    static inline bool classof(const PabloAST * e) {
65        switch (e->getClassTypeId()) {
66            case ClassTypeId::Function:
67            case ClassTypeId::Prototype:
68                return true;
69            default:
70                return false;
71        }       
72    }
73
74    static inline bool classof(void *) {
75        return false;
76    }
77
78    static PabloFunction * Create(std::string name, const unsigned numOfParameters, const unsigned numOfResults);
79   
80    virtual bool operator==(const PabloAST & other) const {
81        return &other == this;
82    }
83
84    PabloBlock * getEntryBlock() {
85        return mEntryBlock;
86    }
87
88    const PabloBlock * getEntryBlock() const {
89        return mEntryBlock;
90    }
91
92    PabloBlock * setEntryBlock(PabloBlock * entryBlock) {
93        assert (entryBlock);
94        std::swap(mEntryBlock, entryBlock);
95        return entryBlock;
96    }
97
98    Var * getParameter(const unsigned index) {
99        if (LLVM_LIKELY(index < getNumOfParameters()))
100            return mParameters[index];
101        else throwInvalidParameterIndex(index);
102    }
103
104    const Var * getParameter(const unsigned index) const {
105        if (LLVM_LIKELY(index < getNumOfParameters()))
106            return mParameters[index];
107        else throwInvalidParameterIndex(index);
108    }
109
110    void setParameter(const unsigned index, Var * value) {
111        if (LLVM_LIKELY(index < getNumOfParameters()))
112            mParameters[index] = value;
113        else throwInvalidParameterIndex(index);
114    }
115
116    Assign * getResult(const unsigned index) {
117        if (LLVM_LIKELY(index < getNumOfResults()))
118            return mResults[index];
119        else throwInvalidResultIndex(index);
120    }
121
122    const Assign * getResult(const unsigned index) const {
123        if (LLVM_LIKELY(index < getNumOfResults()))
124            return mResults[index];
125        else throwInvalidResultIndex(index);
126    }
127
128    void setResult(const unsigned index, Assign * value) {       
129        if (LLVM_LIKELY(index < getNumOfResults())) {
130            if (LLVM_LIKELY(mResults[index] != value)) {
131                if (LLVM_UNLIKELY(mResults[index] != nullptr)) {
132                    mResults[index]->removeUser(this);
133                }
134                mResults[index] = value;
135                value->addUser(this);
136            }
137        }
138        else throwInvalidResultIndex(index);
139    }
140
141    void setFunctionPtr(void * functionPtr) {
142        mFunctionPtr = functionPtr;
143    }
144
145    void operator delete (void*);
146
147    virtual ~PabloFunction() { }
148
149protected:
150
151    __attribute__((noreturn)) void throwInvalidParameterIndex(const unsigned index) const;
152
153    __attribute__((noreturn)) void throwInvalidResultIndex(const unsigned index) const;
154
155    PabloFunction(std::string && name, const unsigned numOfParameters, const unsigned numOfResults);
156private:
157    SymbolGenerator *   mSymbolTable;
158    PabloBlock *        mEntryBlock;
159    Var ** const        mParameters;
160    Assign ** const     mResults;
161};
162
163inline PabloFunction * PabloFunction::Create(std::string name, const unsigned numOfParameters, const unsigned numOfResults) {
164    return new PabloFunction(std::move(name), numOfParameters, numOfResults);
165}
166   
167}
168
169#endif // FUNCTION_H
Note: See TracBrowser for help on using the repository browser.