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

Last change on this file since 5157 was 5063, checked in by cameron, 3 years ago

New kernel infrastructure

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