source: icGREP/icgrep-devel/icgrep/pablo/printer_pablos.cpp @ 5646

Last change on this file since 5646 was 5646, checked in by nmedfort, 22 months ago

Minor clean up. Bug fix for object cache when the same cached kernel is used twice in a single run. Improvement to RE Minimizer.

File size: 8.3 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 "printer_pablos.h"
8#include <pablo/arithmetic.h>
9#include <pablo/boolean.h>
10#include <pablo/branch.h>
11#include <pablo/codegenstate.h>
12#include <pablo/pablo_kernel.h>
13#include <pablo/pe_advance.h>
14#include <pablo/pe_count.h>
15#include <pablo/pe_infile.h>
16#include <pablo/pe_integer.h>
17#include <pablo/pe_lookahead.h>
18#include <pablo/pe_matchstar.h>
19#include <pablo/pe_ones.h>
20#include <pablo/pe_phi.h>
21#include <pablo/pe_scanthru.h>
22#include <pablo/pe_string.h>
23#include <pablo/pe_var.h>
24#include <pablo/pe_zeroes.h>
25#include <pablo/ps_assign.h>
26#include <llvm/Support/raw_os_ostream.h>
27
28using namespace pablo;
29using namespace llvm;
30using TypeId = PabloAST::ClassTypeId;
31
32const unsigned BlockIndenting = 2;
33
34void PabloPrinter::print(const PabloKernel * kernel, raw_ostream & out) {
35    print(kernel->getEntryBlock(), out, true);
36}
37
38void PabloPrinter::print(const Statement * stmt, raw_ostream & out, const bool expandNested, const unsigned indent) {
39    out.indent(indent);
40    if (stmt == nullptr) {
41        out << "<null-stmt>";
42    } else if (const Assign * assign = dyn_cast<Assign>(stmt)) {
43        print(assign->getVariable(), out);
44        out << " = ";
45        print(assign->getValue(), out);
46    } else if (const Branch * br = dyn_cast<Branch>(stmt)) {
47        if (isa<If>(br)) {
48            out << "If ";
49        } else if (isa<While>(br)) {
50            out << "While ";
51        }
52        print(br->getCondition(), out);
53        if (expandNested) {
54            out << ":\n";
55            print(br->getBody(), out, true, indent + BlockIndenting);
56        }
57    } else {
58        print(cast<PabloAST>(stmt), out);
59
60        if (const Extract * extract = dyn_cast<Extract>(stmt)) {
61            out << " = Extract ";
62            print(extract->getArray(), out);
63            out << ", ";
64            print(extract->getIndex(), out);
65        } else if (const And * andNode = dyn_cast<And>(stmt)) {
66            out << " = (";
67            for (unsigned i = 0; i != andNode->getNumOperands(); ++i) {
68                if (i) out << " & ";
69                print(andNode->getOperand(i), out);
70            }
71            out << ")";
72        } else if (const Or * orNode = dyn_cast<Or>(stmt)) {
73            out << " = (";
74            for (unsigned i = 0; i != orNode->getNumOperands(); ++i) {
75                if (i) out << " | ";
76                print(orNode->getOperand(i), out);
77            }
78            out << ")";
79        } else if (const Xor * xorNode = dyn_cast<Xor>(stmt)) {
80            out << " = (";
81            for (unsigned i = 0; i != xorNode->getNumOperands(); ++i) {
82                if (i) out << " ^ ";
83                print(xorNode->getOperand(i), out);
84            }
85            out << ")";
86        } else if (const Sel * selNode = dyn_cast<Sel>(stmt)) {
87            out << " = (";
88            print(selNode->getCondition(), out);
89            out << " ? ";
90            print(selNode->getTrueExpr(), out);
91            out << " : ";
92            print(selNode->getFalseExpr(), out);
93            out << ")";
94        } else if (const Not * notNode = dyn_cast<Not>(stmt)) {
95            out << " = (~";
96            print(notNode->getExpr(), out);
97            out << ")";
98        } else if (const Advance * adv = dyn_cast<Advance>(stmt)) {
99            out << " = pablo.Advance(";
100            print(adv->getExpression(), out);
101            out << ", " << std::to_string(adv->getAmount()) << ")";
102        } else if (const Lookahead * adv = dyn_cast<Lookahead>(stmt)) {
103            out << " = pablo.Lookahead(";
104            print(adv->getExpression(), out);
105            out << ", " << std::to_string(adv->getAmount()) << ")";
106        } else if (const MatchStar * mstar = dyn_cast<MatchStar>(stmt)) {
107            out << " = pablo.MatchStar(";
108            print(mstar->getMarker(), out);
109            out << ", ";
110            print(mstar->getCharClass(), out);
111            out << ")";
112        } else if (const ScanThru * sthru = dyn_cast<ScanThru>(stmt)) {
113            out << " = pablo.ScanThru(";
114            print(sthru->getScanFrom(), out);
115            out << ", ";
116            print(sthru->getScanThru(), out);
117            out << ")";
118        } else if (const ScanTo * sto = dyn_cast<ScanTo>(stmt)) {
119            out << " = pablo.ScanTo(";
120            print(sto->getScanFrom(), out);
121            out << ", ";
122            print(sto->getScanTo(), out);
123            out << ")";
124        } else if (const AdvanceThenScanThru * sthru = dyn_cast<AdvanceThenScanThru>(stmt)) {
125            out << " = pablo.AdvanceThenScanThru(";
126            print(sthru->getScanFrom(), out);
127            out << ", ";
128            print(sthru->getScanThru(), out);
129            out << ")";
130        } else if (const AdvanceThenScanTo * sto = dyn_cast<AdvanceThenScanTo>(stmt)) {
131            out << " = pablo.AdvanceThenScanTo(";
132            print(sto->getScanFrom(), out);
133            out << ", ";
134            print(sto->getScanTo(), out);
135            out << ")";
136        } else if (const Count * count = dyn_cast<Count>(stmt)) {
137            out << " = pablo.Count(";
138            print(count->getExpr(), out);
139            out << ")";
140        } else if (const InFile * e = dyn_cast<InFile>(stmt)) {
141            out << " = pablo.InFile(";
142            print(e->getExpr(), out);
143            out << ")";
144        } else if (const AtEOF * e = dyn_cast<AtEOF>(stmt)) {
145            out << " = pablo.AtEOF(";
146            print(e->getExpr(), out);
147            out << ")";
148        } else {
149            out << "???";
150        }
151    }
152}
153
154void PabloPrinter::print(const PabloAST * expr, llvm::raw_ostream & out) {
155    if (expr == nullptr) {
156        out << "<null-expr>";
157    } else if (isa<Zeroes>(expr)) {
158        out << "0";
159    } else if (isa<Ones>(expr)) {
160        out << "1";
161    } else if (const Var * var = dyn_cast<Var>(expr)) {
162        out << var->getName();
163    } else if (const Phi * const phi = dyn_cast<Phi>(expr)) {
164        out << "phi(";
165        for (unsigned i = 0; i != phi->getNumIncomingValues(); ++i) {
166            if (i) out << ", ";
167            print(phi->getIncomingValue(i), out);
168        }
169        out << ")";
170    } else if (const If * ifstmt = dyn_cast<If>(expr)) {
171        out << "If ";
172        print(ifstmt->getCondition(), out);
173    } else if (const While * whl = dyn_cast<While>(expr)) {
174        out << "While ";
175        print(whl->getCondition(), out);
176    } else if (const Assign * assign = dyn_cast<Assign>(expr)) {
177        print(assign->getVariable(), out);
178        out << " = ";
179        print(assign->getValue(), out);
180    } else if (const Add * op = dyn_cast<Add>(expr)) {
181        print(op->getLH(), out);
182        out << " + ";
183        print(op->getRH(), out);
184    } else if (const Subtract * op = dyn_cast<Subtract>(expr)) {
185        print(op->getLH(), out);
186        out << " - ";
187        print(op->getRH(), out);
188    } else if (const LessThan * op = dyn_cast<LessThan>(expr)) {
189        print(op->getLH(), out);
190        out << " < ";
191        print(op->getRH(), out);
192    } else if (const LessThanEquals * op = dyn_cast<LessThanEquals>(expr)) {
193        print(op->getLH(), out);
194        out << " <= ";
195        print(op->getRH(), out);
196    } else if (const Equals * op = dyn_cast<Equals>(expr)) {
197        print(op->getLH(), out);
198        out << " == ";
199        print(op->getRH(), out);
200    } else if (const GreaterThanEquals * op = dyn_cast<GreaterThanEquals>(expr)) {
201        print(op->getLH(), out);
202        out << " >= ";
203        print(op->getRH(), out);
204    } else if (const GreaterThan * op = dyn_cast<GreaterThan>(expr)) {
205        print(op->getLH(), out);
206        out << " > ";
207        print(op->getRH(), out);
208    } else if (const NotEquals * op = dyn_cast<NotEquals>(expr)) {
209        print(op->getLH(), out);
210        out << " != ";
211        print(op->getRH(), out);
212    } else if (const Statement * stmt = dyn_cast<Statement>(expr)) {
213        out << stmt->getName();
214    } else if (isa<Integer>(expr)) {
215        out << cast<Integer>(expr)->value();
216    } else {
217        out << "???";
218    }
219}
220
221void PabloPrinter::print(const PabloBlock * block, raw_ostream & strm, const bool expandNested, const unsigned indent) {
222    for (const Statement * stmt : *block) {
223        print(stmt, strm, expandNested, indent);
224        if (LLVM_LIKELY(!isa<Branch>(stmt) || !expandNested)) {
225            strm << "\n";
226        }
227    }
228}
229
230
Note: See TracBrowser for help on using the repository browser.