Extract the initial value from the |induction| OpPhi instruction and store it in |value|. If the function couldn't find the initial value of |induction| return false.
| 167 | // in |value|. If the function couldn't find the initial value of |induction| |
| 168 | // return false. |
| 169 | bool Loop::GetInductionInitValue(const Instruction* induction, |
| 170 | int64_t* value) const { |
| 171 | Instruction* constant_instruction = nullptr; |
| 172 | analysis::DefUseManager* def_use_manager = context_->get_def_use_mgr(); |
| 173 | |
| 174 | for (uint32_t operand_id = 0; operand_id < induction->NumInOperands(); |
| 175 | operand_id += 2) { |
| 176 | BasicBlock* bb = context_->cfg()->block( |
| 177 | induction->GetSingleWordInOperand(operand_id + 1)); |
| 178 | |
| 179 | if (!IsInsideLoop(bb)) { |
| 180 | constant_instruction = def_use_manager->GetDef( |
| 181 | induction->GetSingleWordInOperand(operand_id)); |
| 182 | } |
| 183 | } |
| 184 | |
| 185 | if (!constant_instruction) return false; |
| 186 | |
| 187 | const analysis::Constant* constant = |
| 188 | context_->get_constant_mgr()->FindDeclaredConstant( |
| 189 | constant_instruction->result_id()); |
| 190 | if (!constant) return false; |
| 191 | |
| 192 | if (value) { |
| 193 | const analysis::Integer* type = constant->type()->AsInteger(); |
| 194 | if (!type) { |
| 195 | return false; |
| 196 | } |
| 197 | |
| 198 | *value = type->IsSigned() ? constant->GetSignExtendedValue() |
| 199 | : constant->GetZeroExtendedValue(); |
| 200 | } |
| 201 | |
| 202 | return true; |
| 203 | } |
| 204 | |
| 205 | Loop::Loop(IRContext* context, DominatorAnalysis* dom_analysis, |
| 206 | BasicBlock* header, BasicBlock* continue_target, |
no test coverage detected