MCPcopy Create free account
hub / github.com/Samsung/UTopia / getTrackingVariable

Method getTrackingVariable

lib/propanalysis/ArrayAnalyzer.cpp:135–216  ·  view source on GitHub ↗

This API returns a variable would be tracked TODO: This API analyze single loop, not a nested loop. If there is an instruction (array access) in the outer loop, only the outer loop is analyzed If exist in inner loop, analyze only inner loop Nested loop support is required when analyzing ranges of array index.

Source from the content-addressed store, hash-verified

133// If exist in inner loop, analyze only inner loop
134// Nested loop support is required when analyzing ranges of array index.
135Value *ArrayAnalyzer::getTrackingVariable(Loop &L) {
136 bool PositiveStride = false;
137
138 auto LoopHeader = L.getHeader();
139 assert(LoopHeader && "Unexpected Program State");
140
141 auto *F = LoopHeader->getParent();
142 assert(F && "Unexpected Program State");
143
144 auto &SEA = FAM.getResult<ScalarEvolutionAnalysis>(*F);
145 auto *VariantV = getRelatedIndV(L, SEA);
146 auto *ExitCond = getLoopExitCond(L);
147 if (!ExitCond)
148 return nullptr;
149 assert(ExitCond->getNumOperands() > 1 && "Unexpected Program State");
150
151 auto *CmpOp0 = ExitCond->getOperand(0);
152 auto *CmpOp1 = ExitCond->getOperand(1);
153
154 // For a variable dependent on the induction variable,
155 // use the Scalar Evolution to get a phinode(loop-variant) and step
156 if (VariantV) {
157 if (const auto *AR = dyn_cast<SCEVAddRecExpr>(SEA.getSCEV(VariantV))) {
158 const auto *Stride = AR->getStepRecurrence(SEA);
159 PositiveStride = SEA.isKnownPositive(Stride);
160 }
161 } else {
162 // For non induction variable, analyze loop termination
163 // to get the phinode(loop-variant) and step
164 //
165 // ex) while(size > 0) size -= getSize()
166 //
167 // The induction variable increases/decreases by a fixed amount.
168 // However the "size" is reduced by the external API's return value.
169 // So "size" is not induction variable.
170 // There is no induction variable in this loop
171 for (unsigned CmpOpNum = 0, E1 = ExitCond->getNumOperands(); CmpOpNum < E1;
172 CmpOpNum++) {
173 auto *PN = dyn_cast<PHINode>(ExitCond->getOperand(CmpOpNum));
174 if (!PN)
175 continue;
176
177 VariantV = ExitCond->getOperand(CmpOpNum);
178
179 for (unsigned PnOpNum = 0, E2 = PN->getNumIncomingValues(); PnOpNum < E2;
180 PnOpNum++) {
181 if (!L.contains(PN->getIncomingBlock(PnOpNum)))
182 continue;
183
184 auto *BO = dyn_cast<BinaryOperator>(PN->getIncomingValue(PnOpNum));
185 if (!BO)
186 continue;
187
188 if (BO->getOpcode() == Instruction::Add ||
189 BO->getOpcode() == Instruction::Mul ||
190 BO->getOpcode() == Instruction::FAdd ||
191 BO->getOpcode() == Instruction::FMul)
192 PositiveStride = true;

Callers

nothing calls this directly

Calls 2

getLoopExitCondFunction · 0.85
containsMethod · 0.80

Tested by

no test coverage detected