source: icGREP/icgrep-devel/icgrep/pablo/pabloAST.cpp @ 4414

Last change on this file since 4414 was 4404, checked in by nmedfort, 5 years ago

Some work towards maintaining UseDef? information. Use PabloBlock::Create() instead of the PabloBlock? constructors.

File size: 5.9 KB
Line 
1/*
2 *  Copyright (c) 2014 International Characters.
3 *  This software is licensed to the public under the Open Software License 3.0.
4 *  icgrep is a trademark of International Characters.
5 */
6
7#include "pabloAST.h"
8#include "pe_advance.h"
9#include "pe_and.h"
10#include "pe_call.h"
11#include "pe_matchstar.h"
12#include "pe_not.h"
13#include "pe_or.h"
14#include "pabloAST.h"
15#include "pe_scanthru.h"
16#include "pe_sel.h"
17#include "pe_var.h"
18#include "pe_xor.h"
19#include "pe_zeroes.h"
20#include "pe_ones.h"
21#include <pablo/codegenstate.h>
22#include <llvm/Support/Compiler.h>
23
24namespace pablo {
25
26PabloAST::Allocator PabloAST::mAllocator;
27
28/*
29
30    Return true if expr1 and expr2 can be proven equivalent according to some rules,
31    false otherwise.  Note that false may be returned i some cases when the exprs are
32    equivalent.
33
34*/
35
36bool equals(const PabloAST * expr1, const PabloAST * expr2) {
37    assert (expr1 && expr2);
38    if (expr1->getClassTypeId() == expr2->getClassTypeId()) {
39        if ((isa<const Zeroes>(expr1)) || (isa<const Ones>(expr1))) {
40            return true;
41        }
42        else if (const Var * var1 = dyn_cast<const Var>(expr1)) {
43            if (const Var * var2 = cast<const Var>(expr2)) {
44                return (var1->getName() == var2->getName());
45            }
46        }
47        else if (const Not* not1 = dyn_cast<const Not>(expr1)) {
48            if (const Not* not2 = cast<const Not>(expr2)) {
49                return equals(not1->getExpr(), not2->getExpr());
50            }
51        }
52        else if (const And* and1 = dyn_cast<const And>(expr1)) {
53            if (const And* and2 = cast<const And>(expr2)) {
54                if (equals(and1->getExpr1(), and2->getExpr1())) {
55                    return equals(and1->getExpr2(), and2->getExpr2());
56                }
57                else if (equals(and1->getExpr1(), and2->getExpr2())) {
58                    return equals(and1->getExpr2(), and2->getExpr1());
59                }
60            }
61        }
62        else if (const Or * or1 = dyn_cast<const Or>(expr1)) {
63            if (const Or* or2 = cast<const Or>(expr2)) {
64                if (equals(or1->getExpr1(), or2->getExpr1())) {
65                    return equals(or1->getExpr2(), or2->getExpr2());
66                }
67                else if (equals(or1->getExpr1(), or2->getExpr2())) {
68                    return equals(or1->getExpr2(), or2->getExpr1());
69                }
70            }
71        }
72        else if (const Xor * xor1 = dyn_cast<const Xor>(expr1)) {
73            if (const Xor * xor2 = cast<const Xor>(expr2)) {
74                if (equals(xor1->getExpr1(), xor2->getExpr1())) {
75                    return equals(xor1->getExpr2(), xor2->getExpr2());
76                }
77                else if (equals(xor1->getExpr1(), xor2->getExpr2())) {
78                    return equals(xor1->getExpr2(), xor2->getExpr1());
79                }
80            }
81        }
82        else if (const Sel* sel1 = dyn_cast<const Sel>(expr1)) {
83            if (const Sel* sel2 = cast<const Sel>(expr2)) {
84                if (equals(sel1->getCondition(), sel2->getCondition())) {
85                    if (equals(sel1->getTrueExpr(), sel2->getTrueExpr())) {
86                        return equals(sel1->getFalseExpr(), sel2->getFalseExpr());
87                    }
88                }
89            }
90        }
91    }
92    return false;
93}
94
95void PabloAST::setMetadata(const std::string & name, PMDNode * node) {
96    if (LLVM_UNLIKELY(mMetadataMap == nullptr)) {
97        mMetadataMap = new PMDNodeMap();
98    }
99    mMetadataMap->insert(std::make_pair(name, node));
100}
101
102PMDNode * PabloAST::getMetadata(const std::string & name) {
103    if (LLVM_UNLIKELY(mMetadataMap == nullptr)) {
104        return nullptr;
105    }
106    auto f = mMetadataMap->find(name);
107    if (f == mMetadataMap->end()) {
108        return nullptr;
109    }
110    return f->second;
111}
112
113
114void Statement::insertBefore(Statement * const statement) {
115    assert (statement);
116    assert (statement != this);
117    assert (statement->mParent);
118    removeFromParent();
119    mParent = statement->mParent;
120    if (LLVM_UNLIKELY(mParent->mFirst == statement)) {
121        mParent->mFirst = this;
122    }
123    mNext = statement;
124    mPrev = statement->mPrev;
125    statement->mPrev = this;
126    if (LLVM_LIKELY(mPrev != nullptr)) {
127        mPrev->mNext = this;
128    }
129}
130
131void Statement::insertAfter(Statement * const statement) {
132    assert (statement);
133    assert (statement != this);
134    assert (statement->mParent);
135    removeFromParent();
136    mParent = statement->mParent;
137    if (LLVM_UNLIKELY(mParent->mLast == statement)) {
138        mParent->mLast = this;
139    }
140    mPrev = statement;
141    mNext = statement->mNext;
142    statement->mNext = this;
143    if (LLVM_LIKELY(mNext != nullptr)) {
144        mNext->mPrev = this;
145    }
146}
147
148void Statement::removeFromParent() {
149    if (LLVM_LIKELY(mParent != nullptr)) {
150        if (LLVM_UNLIKELY(mParent->mFirst == this)) {
151            mParent->mFirst = mNext;
152        }
153        if (LLVM_UNLIKELY(mParent->mLast == this)) {
154            mParent->mLast = mPrev;
155        }
156        if (LLVM_LIKELY(mPrev != nullptr)) {
157            mPrev->mNext = mNext;
158        }
159        if (LLVM_LIKELY(mNext != nullptr)) {
160            mNext->mPrev = mPrev;
161        }
162    }
163    mPrev = nullptr;
164    mNext = nullptr;
165    mParent = nullptr;
166}
167
168void Statement::replaceWith(Statement * const statement) {
169    if (LLVM_UNLIKELY(mParent != nullptr)) {
170        statement->removeFromParent();
171    }
172    statement->mParent = mParent;
173    statement->mNext = mNext;
174    statement->mPrev = mPrev;
175    if (LLVM_LIKELY(mPrev != nullptr)) {
176        mPrev->mNext = statement;
177    }
178    if (LLVM_LIKELY(mNext != nullptr)) {
179        mNext->mPrev = statement;
180    }
181    mParent=nullptr;
182    mNext=nullptr;
183    mPrev=nullptr;
184}
185
186Statement::~Statement() {
187
188}
189
190void StatementList::push_back(Statement * const statement) {
191    if (LLVM_UNLIKELY(mLast == nullptr)) {
192        mFirst = mLast = statement;
193    }
194    else {
195        statement->insertAfter(mLast);
196        mLast = statement;
197    }
198}
199
200}
Note: See TracBrowser for help on using the repository browser.