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

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

Bug fix for long advance

File size: 4.1 KB
Line 
1#include "branch.h"
2#include <pablo/codegenstate.h>
3#include <pablo/pe_var.h>
4#include <pablo/ps_assign.h>
5#include <pablo/pablo_kernel.h>
6
7#include <llvm/Support/raw_ostream.h>
8
9using namespace llvm;
10
11namespace pablo {
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
20    for (const PabloAST * user : var->users()) {
21
22        if (isa<Assign>(user)) {
23
24            const PabloBlock * const scope = cast<Assign>(user)->getParent();
25            // Is this Var assigned a value within the body of this branch?
26            for (const PabloBlock * test = scope; test; test = test->getPredecessor()) {
27                if (test == br->getBody()) {
28                    if (outside) {
29                        return true;
30                    }
31                    inside = true;
32                    goto outer_loop;
33                }
34            }
35
36            // Is there an assignment to this Var that dominates this branch?
37            const Branch * check = br;
38            for (const PabloBlock * test = br->getParent(); test; ) {
39                if (test == scope) {
40                    // verify this assignment actually dominates the branch
41                    const Statement * temp1 = cast<Assign>(user);
42                    const Statement * temp2 = check;
43                    while (temp1 && temp2) {
44                        if (temp1 == check) {
45                            break;
46                        } else if (temp2 == cast<Assign>(user)) {
47                            temp1 = nullptr;
48                            break;
49                        }
50                        temp1 = temp1->getNextNode();
51                        temp2 = temp2->getNextNode();
52                    }
53                    if (temp1 != nullptr) {
54                        if (inside) {
55                            return true;
56                        }
57                        outside = true;
58                    }
59                    break;
60                }
61                check = test->getBranch();
62                if (LLVM_UNLIKELY(check == nullptr)) {
63                    break;
64                }
65                test = check->getParent();
66            }
67        } else if (isa<PabloKernel>(user)) {
68            if (inside) {
69                return true;
70            }
71            outside = true;
72        }
73outer_loop: continue;
74    }
75    return false;
76}
77
78/** ------------------------------------------------------------------------------------------------------------- *
79 * @brief getEscaped
80 ** ------------------------------------------------------------------------------------------------------------- */
81Branch::EscapedVars Branch::getEscaped() const {
82    const auto f = getParent()->getParent();
83    const auto n = f->getNumOfVariables();
84    EscapedVars escaped;
85    for (unsigned i = 0; i < n; ++i) {
86        Var * const var = f->getVariable(i);
87        if (escapes(var, this)) {
88            escaped.push_back(var);
89        }
90    }
91    return escaped;
92}
93
94/** ------------------------------------------------------------------------------------------------------------- *
95 * @brief setBody
96 ** ------------------------------------------------------------------------------------------------------------- */
97PabloBlock * Branch::setBody(PabloBlock * const body) {
98    body->setBranch(this);
99    PabloBlock * const priorBody = mBody;
100    mBody = body;
101    priorBody->setBranch(nullptr);
102    return priorBody;
103}
104
105
106/** ------------------------------------------------------------------------------------------------------------- *
107 * @brief constructor
108 ** ------------------------------------------------------------------------------------------------------------- */
109Branch::Branch(const ClassTypeId typeId, PabloAST * condition, PabloBlock * body, Allocator &allocator)
110: Statement(typeId, nullptr, {condition}, nullptr, allocator)
111, mBody(body)
112, mEscapedCount(0)
113, mEscapedCapacity(0)
114, mEscaped(nullptr)
115{
116
117}
118
119}
Note: See TracBrowser for help on using the repository browser.