772 ScopePath&
sPath = _scopes[_currentScopeColor];
773 CPPADCG_ASSERT_UNKNOWN(
sPath.back().beginning ==
nullptr)
774 if (
op == CGOpCode::LoopStart ||
op == CGOpCode::StartIf) {
777 CPPADCG_ASSERT_UNKNOWN(!
code.getArguments().empty() &&
778 code.getArguments()[0].getOperation() !=
nullptr &&
779 code.getArguments()[0].getOperation()->getOperationType() ==
781 sPath.back().beginning =
code.getArguments()[0].getOperation();
783 _currentScopeColor =
sPath.size() > 1 ?
sPath[
sPath.size() - 2].color : 0;
786 if (op == CGOpCode::LoopEnd || op == CGOpCode::EndIf || op == CGOpCode::ElseIf || op == CGOpCode::Else) {
788 _currentScopeColor = ++_scopeColorCount;
790 _scopes.resize(_currentScopeColor + 1);
791 _scopes[_currentScopeColor] = _scopes[previousScope];
794 if (op == CGOpCode::LoopEnd || op == CGOpCode::EndIf) {
796 _scopes[_currentScopeColor].push_back(ScopePathElement<Base>(_currentScopeColor, &code));
799 _scopes[_currentScopeColor].back() = ScopePathElement<Base>(_currentScopeColor, &code);
802 if (op == CGOpCode::LoopEnd) {
803 _loops.addLoopEndNode(code);
810 stack.pushNodeArguments(code, _currentScopeColor);
817 if (op == CGOpCode::Tmp && !code.getInfo().empty()) {
823 if (_scope[code] == _currentScopeColor) {
825 restoreTemporaryVar(code);
827 updateTemporaryVarInDiffScopes(code);
830 }
else if (_scope[code] != _currentScopeColor && op != CGOpCode::LoopIndexedIndep) {
831 ScopeIDType oldScope = _scope[code];
837 size_t depth = findFirstDifferentScope(oldScope, _currentScopeColor);
840 ScopeIDType newScope;
844 newScope = _scopes[_currentScopeColor][depth - 1].color;
846 if (oldScope != newScope) {
850 bool addedIf = handleTemporaryVarInDiffScopes(code, oldScope, newScope);
853 _scope[code] = newScope;
858 const std::vector<Arg>& args = code.getArguments();
859 size_t aSize = args.size();
860 for (
size_t a = 0; a < aSize; a++) {
861 updateVarScopeUsage(args[a].getOperation(), newScope, oldScope);
872 auto endAnalysis = [
this](OperationStackData<Base>& stackEl) {
875 Node& code = stackEl.node();
876 size_t previousScope = stackEl.parentNodeScope;
878 CGOpCode op = code.getOperationType();
880 if (op == CGOpCode::Index) {
881 const auto& inode =
static_cast<const IndexOperationNode <Base>&
> (code);
883 if (inode.isDefinedLocally()) {
884 _loops.indexes.insert(&inode.getIndex());
886 }
else if (op == CGOpCode::LoopIndexedIndep || op == CGOpCode::LoopIndexedDep ||
887 op == CGOpCode::IndexAssign) {
889 if (op == CGOpCode::LoopIndexedDep) {
890 size_t pos = code.getInfo()[0];
891 ip = _loops.dependentIndexPatterns[pos];
892 }
else if (op == CGOpCode::LoopIndexedIndep) {
893 size_t pos = code.getInfo()[1];
894 ip = _loops.independentIndexPatterns[pos];
896 ip = &
static_cast<IndexAssignOperationNode <Base>&
> (code).getIndexPattern();
899 findRandomIndexPatterns(ip, _loops.indexRandomPatterns);
901 }
else if (op == CGOpCode::DependentRefRhs) {
902 CPPADCG_ASSERT_UNKNOWN(code.getInfo().size() == 1)
903 size_t depIndex = code.getInfo()[0];
905 CPPADCG_ASSERT_UNKNOWN(_dependents->size() > depIndex)
906 Node * depNode = (*_dependents)[depIndex].getOperationNode();
907 CPPADCG_ASSERT_UNKNOWN(depNode !=
nullptr && depNode->getOperationType() != CGOpCode::Inv)
909 _varId[code] = _varId[*depNode];
915 _currentScopeColor = previousScope;
919 depthFirstGraphNavigation(root,
930 if (_currentScopeColor == 0)
936 CPPADCG_ASSERT_KNOWN(
code.getOperationType() != CGOpCode::ArrayCreation,
"Not supported yet")
937 CPPADCG_ASSERT_KNOWN(
code.getOperationType() != CGOpCode::SparseArrayCreation,
"Not supported yet")
949 if ((
bNewOp == CGOpCode::EndIf ||
bNewOp == CGOpCode::Else ||
bNewOp == CGOpCode::ElseIf) &&
950 (
bOldOp == CGOpCode::EndIf ||
bOldOp == CGOpCode::Else ||
bOldOp == CGOpCode::ElseIf)) {
1013 tmp.setOperation(CGOpCode::Tmp, {
tmpArg, *endIf});
1014 tmp.getInfo().resize(1);
1017 _scope.adjustSize();
1018 _lastVisit.adjustSize();
1019 _scope.adjustSize();
1020 _evaluationOrder.adjustSize();
1021 _lastUsageOrder.adjustSize();
1022 _totalUseCount.adjustSize();
1023 _operationCount.adjustSize();
1024 _varId.adjustSize();
1048 setTotalUsageCount(*
ifStart, 1);
1049 setTotalUsageCount(*
cond, 1);
1050 setTotalUsageCount(*
opClone, 1);
1053 setTotalUsageCount(*endIf, 1);
1058 const std::vector<Arg>&
cargs =
opClone->getArguments();
1060 for (
size_t a = 0;
a <
aSize;
a++) {
1064 _alteredNodes.push_back(std::make_pair(&
tmp,
opClone));
1069 if (_scope[
code] != _currentScopeColor) {
1076 if (_currentScopeColor == 0)
1077 restoreTemporaryVar(
code);
1086 size_t depth = findFirstDifferentScope(
oldScope, _currentScopeColor);
1089 ScopeIDType
newScope = depth == 0 ? 0 : _scopes[_currentScopeColor][depth - 1].color;
1097 CPPADCG_ASSERT_UNKNOWN(
endif->getOperationType() == CGOpCode::EndIf)
1102 if (
bNewOp == CGOpCode::EndIf ||
bNewOp == CGOpCode::Else ||
bNewOp == CGOpCode::ElseIf) {
1126 restoreTemporaryVar(
code);
1130 CPPADCG_ASSERT_UNKNOWN(
cond->getOperationType() == CGOpCode::IndexCondExpr)
1141 const std::vector<Arg>&
cargs =
code.getArguments();
1143 for (
size_t a = 0;
a <
aSize;
a++) {
1152 CPPADCG_ASSERT_UNKNOWN(
tmp.getOperationType() == CGOpCode::Tmp && !
tmp.getInfo().empty())
1154 Node* endIf =
tmp.getArguments()[1].getOperation();
1161 _scope[
tmp] = _currentScopeColor;
1166 const std::vector<Arg>&
args =
tmp.getArguments();
1168 for (
size_t a = 0;
a <
aSize;
a++) {
1169 updateVarScopeUsage(
args[
a].getOperation(), _currentScopeColor, _scope[*
opClone]);
1176 CPPADCG_ASSERT_UNKNOWN(
tmp->getOperationType() == CGOpCode::Tmp && !
tmp->getInfo().empty())
1181 _scope[*
tmp] = _currentScopeColor;
1186 const std::vector<Arg>&
args =
tmp->getArguments();
1188 for (
size_t a = 0;
a <
aSize;
a++) {
1189 updateVarScopeUsage(
args[
a].getOperation(), _currentScopeColor, _scope[*
opClone]);
1197 if (node ==
nullptr || _scope[*node] ==
usageScope)
1201 ScopeIDType
oldScope = _scope[*node];
1212 if (newScope == oldScope)
1215 _scope[*node] = newScope;
1217 const std::vector<Arg>& args = node->getArguments();
1218 size_t aSize = args.size();
1219 for (
size_t a = 0; a < aSize; a++) {
1220 updateVarScopeUsage(args[a].getOperation(), newScope, oldScope);
1225inline void CodeHandler<Base>::addScopeToVarOrder(
size_t scope,
1227 std::vector<Node*>& vorder = _scopedVariableOrder[scope];
1229 const size_t vsize = vorder.size();
1230 for (
size_t p = 0; p < vsize; p++) {
1231 Node* node = vorder[p];
1232 CGOpCode op = node->getOperationType();
1234 if (op == CGOpCode::LoopEnd || op == CGOpCode::EndIf || op == CGOpCode::ElseIf || op == CGOpCode::Else) {
1235 CPPADCG_ASSERT_UNKNOWN(!node->getArguments().empty())
1237 Node* beginScopeNode = node->getArguments()[0].getOperation();
1238 CPPADCG_ASSERT_UNKNOWN(beginScopeNode !=
nullptr)
1240 addScopeToVarOrder(_scope[*beginScopeNode], e);
1244 _variableOrder[e++] = vorder[p];
1251 CPPADCG_ASSERT_UNKNOWN(
color1 < _scopes.size())
1252 CPPADCG_ASSERT_UNKNOWN(
color2 < _scopes.size())
1260 for (depth = 0; depth <
s1 && depth <
s2; depth++) {
1271 if (_scopedVariableOrder.size() < 3)
1274 for (
size_t scope = 0; scope < _scopedVariableOrder.size(); scope++) {
1275 std::vector<Node*>&
vorder = _scopedVariableOrder[scope];
1277 for (
long p =
vorder.size() - 1;
p > 0;
p--) {
1284 if (
vorder[
p1]->getOperationType() == CGOpCode::TmpDcl) {
1291 if (
endIf1->getOperationType() != CGOpCode::EndIf)
1297 if (
startIf->getOperationType() != CGOpCode::StartIf ||
startIf1->getOperationType() != CGOpCode::StartIf)
1303 CPPADCG_ASSERT_UNKNOWN(
cond->getOperationType() == CGOpCode::IndexCondExpr ||
cond1->getOperationType() == CGOpCode::IndexCondExpr)
1304 if (
cond->getInfo() ==
cond1->getInfo()) {
1316 startNewOperationTreeVisit();
1319 for (
size_t a = 1;
a <
eArgs.size();
a++) {
1320 CPPADCG_ASSERT_UNKNOWN(
eArgs[
a].getOperation() !=
nullptr &&
eArgs[
a].getOperation()->getOperationType() == CGOpCode::CondResult)
1330 for (
size_t a = 1;
a <
eArgs.size();
a++) {
1331 CPPADCG_ASSERT_UNKNOWN(
eArgs[
a].getOperation() !=
nullptr &&
eArgs[
a].getOperation()->getOperationType() == CGOpCode::CondResult)
1358 if (node ==
nullptr || _scope[*node] !=
oldScope)
1363 const std::vector<Arg>&
args = node->getArguments();
1364 for (
size_t a = 0;
a <
args.size();
a++) {
1373 if (node ==
nullptr || isVisited(*node))
1381 if (
op == CGOpCode::Tmp &&
args.size() > 1) {
1390 if (!containedInScope(*node, scope)) {
1394 for (
size_t a = 0;
a <
args.size();
a++) {
1397 if (
op == CGOpCode::StartIf ||
op == CGOpCode::LoopStart) {
1402 breakCyclicDependency(
arg, scope, endIf);
1409 ScopeIDType scope) {
1410 ScopeIDType
nScope = _scope[node];
1414 return _scopes[
nScope].size() >= _scopes[scope].size() &&
1415 _scopes[
nScope][_scopes[scope].size() - 1].color == scope;
1419inline bool CodeHandler<Base>::containsArgument(
const Node& node,
1421 const std::vector<Arg>&
args = node.getArguments();
1422 for (
size_t a = 0;
a <
args.size();
a++) {
1423 if (
args[
a].getOperation() == &
arg) {
1431void CodeHandler<Base>::registerAtomicFunction(CGAbstractAtomicFun<Base>& atomic) {
1432 size_t id = atomic.getId();
1433 auto it = _atomicFunctions.lower_bound(
id);
1434 if (it == _atomicFunctions.end() || it->first !=
id) {
1435 if (it != _atomicFunctions.end()) ++it;
1436 _atomicFunctions.insert(it, std::pair<
size_t, CGAbstractAtomicFun<Base>*>(atomic.getId(), &atomic));
1437 }
else if(it->second != &atomic) {
1438 throw CGException(
"The same atomic function ID (",
id,
") is being used for different atomic functions: '",
1439 atomic.atomic_name(),
"' (", &atomic,
") and '", it->second->atomic_name(),
"' (", it->second,
").");
1450 if (isVisited(
arg)) {
1453 stack.pushNodeArguments(
stackEl.node(), 0);
1461 if (isVisited(
arg)) {
1465 CGOpCode
aType =
arg.getOperationType();
1467 if (
aType == CGOpCode::LoopEnd ||
aType == CGOpCode::ElseIf ||
1468 aType == CGOpCode::Else ||
aType == CGOpCode::EndIf) {
1469 if (_varId[
arg] == 0) {
1471 _varId[
arg] = (std::numeric_limits<size_t>::max)();
1473 }
else if (
aType == CGOpCode::AtomicForward ||
aType == CGOpCode::AtomicReverse) {
1477 CPPADCG_ASSERT_UNKNOWN(
arg.getArguments().size() > 1)
1478 CPPADCG_ASSERT_UNKNOWN(
arg.getInfo().size() > 1)
1479 size_t id =
arg.getInfo()[0];
1482 const std::string&
atomicName = _atomicFunctions.at(
id)->atomic_name();
1483 std::map<std::string, size_t>::const_iterator
itName2Idx;
1486 if (
itName2Idx == _atomicFunctionName2Index.end()) {
1487 pos = _atomicFunctionsOrder->size();
1488 _atomicFunctionsOrder->push_back(
atomicName);
1490 _atomicFunctionsMaxForward.push_back(-1);
1491 _atomicFunctionsMaxReverse.push_back(-1);
1496 if (
aType == CGOpCode::AtomicForward) {
1497 int p =
arg.getInfo()[2];
1498 _atomicFunctionsMaxForward[
pos] = std::max<int>(_atomicFunctionsMaxForward[
pos],
1501 int p =
arg.getInfo()[1];
1502 _atomicFunctionsMaxReverse[
pos] = std::max<int>(_atomicFunctionsMaxReverse[
pos],
1512 if (_varId[
arg] == 0 || !isIndependent(
arg)) {
1514 size_t argIndex =
stackEl.argumentIndex();
1516 if (
aType == CGOpCode::LoopIndexedIndep) {
1518 _varId[
arg] = (std::numeric_limits<size_t>::max)();
1519 }
else if (
aType == CGOpCode::Alias) {
1521 }
else if (
aType == CGOpCode::Tmp) {
1522 _varId[
arg] = (std::numeric_limits<size_t>::max)();
1523 }
else if (
aType == CGOpCode::LoopStart ||
1524 aType == CGOpCode::LoopEnd ||
1525 aType == CGOpCode::StartIf ||
1526 aType == CGOpCode::ElseIf ||
1527 aType == CGOpCode::Else ||
1528 aType == CGOpCode::EndIf) {
1533 addToEvaluationQueue(
arg);
1534 if (_varId[
arg] == 0) {
1536 _varId[
arg] = (std::numeric_limits<size_t>::max)();
1538 }
else if (
aType == CGOpCode::Pri) {
1539 addToEvaluationQueue(
arg);
1540 if (_varId[
arg] == 0) {
1542 _varId[
arg] = (std::numeric_limits<size_t>::max)();
1544 }
else if (
aType == CGOpCode::TmpDcl) {
1545 addToEvaluationQueue(
arg);
1547 _varId[
arg] = _idCount;
1556 for (
const auto&
a:
arg) {
1557 if (
a.getOperation() !=
nullptr) {
1558 auto&
n = *
a.getOperation();
1559 if (_varId[
n] == 0) {
1566 if (_lang->createsNewVariable(
arg, getTotalUsageCount(
arg),
opCount) ||
1567 _lang->requiresVariableArgument(
code.getOperationType(), argIndex)) {
1569 addToEvaluationQueue(
arg);
1571 if (_varId[
arg] == 0) {
1572 if (
aType == CGOpCode::AtomicForward ||
1573 aType == CGOpCode::AtomicReverse) {
1574 _varId[
arg] = _idAtomicCount;
1576 }
else if (
aType == CGOpCode::LoopIndexedDep ||
1577 aType == CGOpCode::LoopIndexedTmp) {
1579 _varId[
arg] = (std::numeric_limits<size_t>::max)();
1580 }
else if (
aType == CGOpCode::ArrayCreation) {
1583 _varId[
arg] = _idArrayCount;
1585 }
else if (
aType == CGOpCode::SparseArrayCreation) {
1587 size_t nnz =
arg.getArguments().size();
1588 _varId[
arg] = _idSparseArrayCount;
1589 _idSparseArrayCount += nnz;
1592 _varId[
arg] = _idCount;
1604 depthFirstGraphNavigation(
root,
1613 ScopeIDType scope = _scope[
arg];
1614 if (scope >= _scopedVariableOrder.size()) {
1615 _scopedVariableOrder.resize(scope + 1);
1618 if (_scopedVariableOrder[scope].empty() &&
1620 _scopes[scope].back().end->getArguments()[0].getOperation() != &
arg) {
1622 checkVariableCreation(*_scopes[scope].back().end);
1626 std::vector<Node*>& varOrder = _scopedVariableOrder[scope];
1628 if (varOrder.size() == varOrder.capacity()) {
1629 varOrder.reserve((varOrder.size() * 3) / 2 + 1);
1632 varOrder.push_back(&arg);
1638 reorderOperations(dependent);
1643 startNewOperationTreeVisit();
1645 for (
size_t i = 0;
i < dependent.size();
i++) {
1646 Node* node = dependent[
i].getOperationNode();
1647 if (node !=
nullptr) {
1648 if (!isVisited(*node)) {
1650 determineLastTempVarUsage(*node);
1657 std::vector<std::vector<Node*>>
tempVarRelease(_variableOrder.size());
1658 for (
size_t i = 0;
i < _variableOrder.size();
i++) {
1660 if (isTemporary(*
var) || isTemporaryArray(*
var) || isTemporarySparseArray(*
var)) {
1671 _idCount = _minTemporaryVarID;
1675 for (
size_t i = 0;
i < _variableOrder.size();
i++) {
1682 }
else if (isTemporaryArray(*
released[
r])) {
1684 }
else if (isTemporarySparseArray(*
released[
r])) {
1689 if (isTemporary(
var)) {
1692 _varId[
var] = _idCount;
1699 }
else if (isTemporaryArray(
var)) {
1703 }
else if (isTemporarySparseArray(
var)) {
1718 startNewOperationTreeVisit();
1721 for (
size_t i = 0;
i < dependent.size(); ++
i) {
1722 Node* node = dependent[
i].getOperationNode();
1723 if (node !=
nullptr) {
1724 reorderOperation(*node);
1730 const std::vector<Arg>&
args =
endNode->getArguments();
1731 for (
size_t i = 1;
i <
args.size(); ++
i) {
1732 CPPADCG_ASSERT_UNKNOWN(
args[
i].getOperation() !=
nullptr)
1734 if (
args[
i].getOperation()->getOperationType() == CGOpCode::LoopIndexedDep) {
1735 reorderOperation(*
args[
i].getOperation());
1746 size_t depPos = getEvaluationOrder(node);
1748 if (!isVisited(node)) {
1750 lastTmpPos = findLastTemporaryLocation(node);
1765 const auto*
n = _variableOrder[l - 1];
1766 if (isTemporary(*
n) || isTemporaryArray(*
n) || isTemporarySparseArray(*
n)) {
1774 CGOpCode
op =
n->getOperationType();
1775 if (
op == CGOpCode::StartIf) {
1779 const auto*
node2 = _variableOrder[l - 1];
1780 if (
node2->getOperationType() == CGOpCode::EndIf &&
1781 node2->getArguments()[0].getOperation() ==
n) {
1787 }
else if (
op == CGOpCode::LoopStart) {
1791 const auto*
node2 = _variableOrder[l - 1];
1792 if (
node2->getOperationType() == CGOpCode::LoopEnd &&
1818 const auto&
args = node.getArguments();
1820 for (
size_t i = 0;
i <
args.size(); ++
i) {
1821 if (
args[
i].getOperation() ==
nullptr) {
1826 CGOpCode
aOp =
arg.getOperationType();
1828 if (
aOp == CGOpCode::LoopEnd ||
aOp == CGOpCode::EndIf ||
aOp == CGOpCode::ElseIf ||
aOp == CGOpCode::Else) {
1832 if (
aOp == CGOpCode::Index) {
1839 stack.emplace_back(node,
i);
1860 Node* node = _variableOrder[
fromPos - 1];
1864 _variableOrder[l] = _variableOrder[l - 1];
1865 updateEvaluationQueueOrder(*_variableOrder[l], l + 1);
1868 _variableOrder[
toPos - 1] = node;
1869 updateEvaluationQueueOrder(*node,
toPos);
1878 CGOpCode
op = node.getOperationType();
1882 if (
op == CGOpCode::LoopEnd) {
1885 _loops.outerVars.resize(_loops.depth + 1);
1886 _loops.startEvalOrder.push_back(getEvaluationOrder(loopEnd.getLoopStart()));
1888 }
else if (
op == CGOpCode::LoopStart) {
1895 auto&
args = node.getArguments();
1896 for (
size_t i = 0;
i <
args.size(); ++
i) {
1897 if (
args[
i].getOperation() !=
nullptr) {
1900 if (!isVisited(
arg)) {
1902 stack.emplace_back(node,
i, 0);
1914 CGOpCode
op = node.getOperationType();
1916 for (
const Arg&
it : node.getArguments()) {
1917 if (
it.getOperation() !=
nullptr) {
1920 size_t order = getEvaluationOrder(node);
1922 if (
aa !=
nullptr) {
1923 if (getLastUsageEvaluationOrder(*
aa) < order) {
1924 setLastUsageEvaluationOrder(*
aa, order);
1927 if (_loops.depth >= 0 &&
1928 getEvaluationOrder(*
aa) < _loops.startEvalOrder[_loops.depth] &&
1931 _loops.outerVars[_loops.depth].insert(
aa);
1937 if (
op == CGOpCode::LoopEnd) {
1942 size_t order = getEvaluationOrder(node);
1947 if (
aa !=
nullptr && getLastUsageEvaluationOrder(*
aa) < order)
1948 setLastUsageEvaluationOrder(*
aa, order);
1952 _loops.outerVars.pop_back();
1953 _loops.startEvalOrder.pop_back();
1955 }
else if (
op == CGOpCode::LoopStart) {
1961 depthFirstGraphNavigation(
root,
1974 auto& node =
stackEl.parent();
1977 if (getEvaluationOrder(
arg) == 0) {
1978 setEvaluationOrder(
arg, getEvaluationOrder(node));
1980 stack.pushNodeArguments(
arg);
1999 for (
const Arg&
a : node.getArguments()) {
2000 if (
a.getOperation() !=
nullptr) {
2001 Node&
arg = *
a.getOperation();
2003 stack.pushNodeArguments(
arg);
2008 depthFirstGraphNavigation(root, analyse,
true);
2013 _variableDependencies.resize(_variableOrder.size());
2015 for (
size_t i = 0;
i < _variableOrder.size();
i++) {
2018 _variableDependencies[
i].clear();
2019 startNewOperationTreeVisit();
2021 for (
const auto&
a :
var) {
2022 if (
a.getOperation() !=
nullptr) {
2023 findVariableDependencies(
i, *
a.getOperation());
2037 if (!isVisited(node)) {
2040 if(_varId[node] != 0) {
2041 _variableDependencies[
i].insert(&node);
2043 stack.pushNodeArguments(node);
2048 depthFirstGraphNavigation(root, analyse,
true);
2052inline bool CodeHandler<Base>::isIndependent(
const Node& arg)
const {
2053 return arg.getOperationType() == CGOpCode::Inv;
2057inline bool CodeHandler<Base>::isTemporary(
const Node& arg)
const {
2058 CGOpCode op = arg.getOperationType();
2059 return op != CGOpCode::ArrayCreation &&
2060 op != CGOpCode::SparseArrayCreation &&
2061 op != CGOpCode::AtomicForward &&
2062 op != CGOpCode::AtomicReverse &&
2063 op != CGOpCode::LoopStart &&
2064 op != CGOpCode::LoopEnd &&
2065 op != CGOpCode::StartIf &&
2066 op != CGOpCode::ElseIf &&
2067 op != CGOpCode::Else &&
2068 op != CGOpCode::EndIf &&
2069 op != CGOpCode::LoopIndexedDep &&
2070 op != CGOpCode::LoopIndexedIndep &&
2071 op != CGOpCode::LoopIndexedTmp &&
2072 op != CGOpCode::Index &&
2073 op != CGOpCode::IndexAssign &&
2074 op != CGOpCode::Tmp &&
2075 _varId[arg] >= _minTemporaryVarID;
2079inline bool CodeHandler<Base>::isTemporaryArray(
const Node& arg) {
2080 return arg.getOperationType() == CGOpCode::ArrayCreation;
2084inline bool CodeHandler<Base>::isTemporarySparseArray(
const Node& arg) {
2085 return arg.getOperationType() == CGOpCode::SparseArrayCreation;
2089inline OperationNode<Base>* CodeHandler<Base>::getOperationFromAlias(Node& alias) {
2090 if (alias.getOperationType() != CGOpCode::Alias) {
2095 CPPADCG_ASSERT_UNKNOWN(aa->getArguments().size() == 1)
2096 aa = aa->getArguments()[0].getOperation();
2097 } while (aa !=
nullptr && aa->getOperationType() == CGOpCode::Alias);
2103inline
size_t CodeHandler<Base>::getEvaluationOrder(const Node& node)
const {
2104 return _evaluationOrder[node];
2108inline void CodeHandler<Base>::setEvaluationOrder(Node& node,
2110 CPPADCG_ASSERT_UNKNOWN(order <= _variableOrder.size())
2111 _evaluationOrder[node] = order;
2115inline
size_t CodeHandler<Base>::getLastUsageEvaluationOrder(const Node& node)
const {
2116 return _lastUsageOrder[node];
2120inline void CodeHandler<Base>::setLastUsageEvaluationOrder(
const Node& node,
2122 CPPADCG_ASSERT_UNKNOWN(last <= _variableOrder.size())
2123 _lastUsageOrder[node] = last;
2125 CGOpCode op = node.getOperationType();
2126 if (op == CGOpCode::ArrayElement) {
2127 Node* array = node.getArguments()[0].getOperation();
2128 CPPADCG_ASSERT_UNKNOWN(array->getOperationType() == CGOpCode::ArrayCreation)
2129 if (getLastUsageEvaluationOrder(*array) < last) {
2130 setLastUsageEvaluationOrder(*array, last);
2132 }
else if (op == CGOpCode::Tmp) {
2133 Node* declr = node.getArguments()[0].getOperation();
2134 CPPADCG_ASSERT_UNKNOWN(declr->getOperationType() == CGOpCode::TmpDcl)
2135 if (getLastUsageEvaluationOrder(*declr) < last) {
2136 setLastUsageEvaluationOrder(*declr, last);
2143 return _totalUseCount[node];