source: icGREP/icgrep-devel/icgrep/pablo/branch.cpp @ 5217

Last change on this file since 5217 was 5217, checked in by nmedfort, 2 years ago

Merged PabloFunction? and PabloKernel? classes. Updated projects where necessary.

File size: 3.3 KB
Line 
1#include <pablo/branch.h>
2#include <pablo/codegenstate.h>
3#include <pablo/printer_pablos.h>
4
5namespace pablo {
6
7Branch::Branch(const ClassTypeId typeId, PabloAST * condition, PabloBlock * body)
8: Statement(typeId, nullptr, {condition}, nullptr)
9, mBody(body) {
10
11}
12
13/** ------------------------------------------------------------------------------------------------------------- *
14 * @brief escapes
15 ** ------------------------------------------------------------------------------------------------------------- */
16inline bool escapes(const Var * const var, const Branch * const br) {
17    bool inside = false;
18    bool outside = false;
19    for (const PabloAST * user : var->users()) {
20        if (isa<Assign>(user)) {           
21
22            const PabloBlock * const scope = cast<Assign>(user)->getParent();
23
24            // Is this Var assigned a value within the body of this branch?
25            for (const PabloBlock * test = scope; test; test = test->getPredecessor()) {
26                if (test == br->getBody()) {
27                    if (outside) {
28                        return true;
29                    }
30                    inside = true;
31                    goto outer_loop;
32                }
33            }
34
35            // Is there an assignment to this Var that dominates this branch?
36            const Branch * check = br;
37            for (const PabloBlock * test = br->getParent(); test; ) {
38                if (test == scope) {
39                    // verify this assignment actually dominates the branch
40                    const Statement * temp1 = cast<Assign>(user);
41                    const Statement * temp2 = check;
42                    while (temp1 && temp2) {
43                        if (temp1 == check) {
44                            break;
45                        } else if (temp2 == cast<Assign>(user)) {
46                            temp1 = nullptr;
47                            break;
48                        }
49                        temp1 = temp1->getNextNode();
50                        temp2 = temp2->getNextNode();
51                    }
52                    if (temp1 != nullptr) {
53                        if (inside) {
54                            return true;
55                        }
56                        outside = true;
57                    }
58                    break;
59                }
60                check = test->getBranch();
61                if (LLVM_UNLIKELY(check == nullptr)) {
62                    break;
63                }
64                test = check->getParent();
65            }
66        }
67outer_loop: continue;
68    }
69    return false;
70}
71
72/** ------------------------------------------------------------------------------------------------------------- *
73 * @brief getEscaped
74 ** ------------------------------------------------------------------------------------------------------------- */
75std::vector<Var *> Branch::getEscaped() const {
76
77    const auto f = getParent()->getParent();
78    const auto n = f->getNumOfVariables();
79
80    std::vector<Var *> escaped;   
81    for (unsigned i = 0; i < n; ++i) {
82        Var * const var = f->getVariable(i);
83        if (escapes(var, this)) {
84            escaped.push_back(var);
85        }
86    }
87    return escaped;
88}
89
90PabloBlock * Branch::setBody(PabloBlock * const body) {
91    body->setBranch(this);
92    PabloBlock * const priorBody = mBody;
93    mBody = body;
94    priorBody->setBranch(nullptr);
95    return priorBody;
96}
97
98}
Note: See TracBrowser for help on using the repository browser.