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

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

Optimized Symbol Generation (and fixed potential bug that could allow duplicate names being constructed); made PabloKernel? extend PabloAST (temporarily removed PabloAST::getName() to avoid diamond problem); added an internal scalar to PabloKernel? struct for each Count to avoid InOut? output scalar variable problem; allowed CodeMotionPass? to move code within the same scope but across a branch statement. Began work on separating Kernels into either Block-Oriented or Segment-Oriented kernels.

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