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

Last change on this file since 5239 was 5230, checked in by nmedfort, 3 years ago

Multi-threading support for PabloAST / PabloCompiler?. Requires unique LLVM Context / Module for each thread.

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, Allocator &allocator)
8: Statement(typeId, nullptr, {condition}, nullptr, allocator)
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 ** ------------------------------------------------------------------------------------------------------------- */
75Branch::EscapedVars Branch::getEscaped() const {
76    const auto f = getParent()->getParent();
77    const auto n = f->getNumOfVariables();
78    EscapedVars escaped;
79    for (unsigned i = 0; i < n; ++i) {
80        Var * const var = f->getVariable(i);
81        if (escapes(var, this)) {
82            escaped.push_back(var);
83        }
84    }
85    return escaped;
86}
87
88PabloBlock * Branch::setBody(PabloBlock * const body) {
89    body->setBranch(this);
90    PabloBlock * const priorBody = mBody;
91    mBody = body;
92    priorBody->setBranch(nullptr);
93    return priorBody;
94}
95
96}
Note: See TracBrowser for help on using the repository browser.