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

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

Back up check in. Memory leaks should be fixed.

File size: 4.7 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    Var * getParameter(const unsigned index) {
93        if (LLVM_LIKELY(index < getNumOfParameters()))
94            return mParameters[index];
95        else throwInvalidParameterIndex(index);
96    }
97
98    const Var * getParameter(const unsigned index) const {
99        if (LLVM_LIKELY(index < getNumOfParameters()))
100            return mParameters[index];
101        else throwInvalidParameterIndex(index);
102    }
103
104    void setParameter(const unsigned index, Var * value) {
105        if (LLVM_LIKELY(index < getNumOfParameters()))
106            mParameters[index] = value;
107        else throwInvalidParameterIndex(index);
108    }
109
110    Assign * getResult(const unsigned index) {
111        if (LLVM_LIKELY(index < getNumOfResults()))
112            return mResults[index];
113        else throwInvalidResultIndex(index);
114    }
115
116    const Assign * getResult(const unsigned index) const {
117        if (LLVM_LIKELY(index < getNumOfResults()))
118            return mResults[index];
119        else throwInvalidResultIndex(index);
120    }
121
122    void setResult(const unsigned index, Assign * value) {       
123        if (LLVM_LIKELY(index < getNumOfResults())) {
124            if (LLVM_LIKELY(mResults[index] != value)) {
125                if (LLVM_UNLIKELY(mResults[index] != nullptr)) {
126                    mResults[index]->removeUser(this);
127                }
128                mResults[index] = value;
129                value->addUser(this);
130            }
131        }
132        else throwInvalidResultIndex(index);
133    }
134
135    void setFunctionPtr(void * functionPtr) {
136        mFunctionPtr = functionPtr;
137    }
138
139    void operator delete (void*);
140
141    virtual ~PabloFunction() { }
142
143protected:
144
145    __attribute__((noreturn)) void throwInvalidParameterIndex(const unsigned index) const;
146
147    __attribute__((noreturn)) void throwInvalidResultIndex(const unsigned index) const;
148
149    PabloFunction(std::string && name, const unsigned numOfParameters, const unsigned numOfResults);
150private:
151    SymbolGenerator *   mSymbolTable;
152    PabloBlock &        mEntryBlock;   
153    Var ** const        mParameters;
154    Assign ** const     mResults;
155};
156
157inline PabloFunction * PabloFunction::Create(std::string name, const unsigned numOfParameters, const unsigned numOfResults) {
158    return new PabloFunction(std::move(name), numOfParameters, numOfResults);
159}
160   
161}
162
163#endif // FUNCTION_H
Note: See TracBrowser for help on using the repository browser.