1 | #include <pablo/ps_if.h> |
---|
2 | #include <pablo/codegenstate.h> |
---|
3 | #include <pablo/ps_assign.h> |
---|
4 | |
---|
5 | namespace pablo { |
---|
6 | |
---|
7 | If::If(PabloAST * expr, const std::initializer_list<Assign *> definedVars, PabloBlock * body) |
---|
8 | : Statement(ClassTypeId::If, {expr}, nullptr) |
---|
9 | , mBody(body) |
---|
10 | , mDefined(definedVars.begin(), definedVars.end(), reinterpret_cast<DefinedAllocator &>(mAllocator)) { |
---|
11 | // Conceptually, having a defined var X is identical to having: |
---|
12 | // |
---|
13 | // Assign(X, 0) |
---|
14 | // If (...) |
---|
15 | // Next(Assign(X), ...) |
---|
16 | // |
---|
17 | // Since the implied 'Next' node is a user of the Assign node, and the Assign node is |
---|
18 | // embedded into the If, the defined var is a user of the If node. However, since the |
---|
19 | // Assign's value is also dependant on the 'Next' value, the If node is also a user |
---|
20 | // of it. |
---|
21 | mBody->setBranch(this); |
---|
22 | mBody->setParent(getParent()); |
---|
23 | for (Assign * def : mDefined) { |
---|
24 | def->addUser(this); |
---|
25 | this->addUser(def); |
---|
26 | } |
---|
27 | } |
---|
28 | |
---|
29 | If::If(PabloAST * expr, const std::vector<Assign *> & definedVars, PabloBlock * body) |
---|
30 | : Statement(ClassTypeId::If, {expr}, nullptr) |
---|
31 | , mBody(body) |
---|
32 | , mDefined(definedVars.begin(), definedVars.end(), reinterpret_cast<DefinedAllocator &>(mAllocator)) { |
---|
33 | mBody->setBranch(this); |
---|
34 | mBody->setParent(getParent()); |
---|
35 | for (Assign * def : mDefined) { |
---|
36 | def->addUser(this); |
---|
37 | this->addUser(def); |
---|
38 | } |
---|
39 | } |
---|
40 | |
---|
41 | void If::addDefined(Assign * def) { |
---|
42 | if (LLVM_LIKELY(std::find(mDefined.begin(), mDefined.end(), def) == mDefined.end())) { |
---|
43 | mDefined.push_back(def); |
---|
44 | def->addUser(this); |
---|
45 | this->addUser(def); |
---|
46 | } |
---|
47 | } |
---|
48 | |
---|
49 | If::DefinedVars::iterator If::removeDefined(Assign * def) { |
---|
50 | auto f = std::find(mDefined.begin(), mDefined.end(), def); |
---|
51 | if (LLVM_LIKELY(f != mDefined.end())) { |
---|
52 | def->removeUser(this); |
---|
53 | this->removeUser(def); |
---|
54 | return mDefined.erase(f); |
---|
55 | } |
---|
56 | return mDefined.end(); |
---|
57 | } |
---|
58 | |
---|
59 | PabloBlock * If::setBody(PabloBlock * body) { |
---|
60 | body->setParent(mBody->getParent()); |
---|
61 | std::swap(mBody, body); |
---|
62 | body->setParent(nullptr); |
---|
63 | return body; |
---|
64 | } |
---|
65 | |
---|
66 | } |
---|