| 327 | } |
| 328 | |
| 329 | bool SSARewriter::ProcessLoad(Instruction* inst, BasicBlock* bb) { |
| 330 | // Get the pointer that we are using to load from. |
| 331 | uint32_t var_id = 0; |
| 332 | (void)pass_->GetPtr(inst, &var_id); |
| 333 | |
| 334 | // Get the immediate reaching definition for |var_id|. |
| 335 | // |
| 336 | // In the presence of variable pointers, the reaching definition may be |
| 337 | // another pointer. For example, the following fragment: |
| 338 | // |
| 339 | // %2 = OpVariable %_ptr_Input_float Input |
| 340 | // %11 = OpVariable %_ptr_Function__ptr_Input_float Function |
| 341 | // OpStore %11 %2 |
| 342 | // %12 = OpLoad %_ptr_Input_float %11 |
| 343 | // %13 = OpLoad %float %12 |
| 344 | // |
| 345 | // corresponds to the pseudo-code: |
| 346 | // |
| 347 | // layout(location = 0) in flat float *%2 |
| 348 | // float %13; |
| 349 | // float *%12; |
| 350 | // float **%11; |
| 351 | // *%11 = %2; |
| 352 | // %12 = *%11; |
| 353 | // %13 = *%12; |
| 354 | // |
| 355 | // which ultimately, should correspond to: |
| 356 | // |
| 357 | // %13 = *%2; |
| 358 | // |
| 359 | // During rewriting, the pointer %12 is found to be replaceable by %2 (i.e., |
| 360 | // load_replacement_[12] is 2). However, when processing the load |
| 361 | // %13 = *%12, the type of %12's reaching definition is another float |
| 362 | // pointer (%2), instead of a float value. |
| 363 | // |
| 364 | // When this happens, we need to continue looking up the reaching definition |
| 365 | // chain until we get to a float value or a non-target var (i.e. a variable |
| 366 | // that cannot be SSA replaced, like %2 in this case since it is a function |
| 367 | // argument). |
| 368 | analysis::DefUseManager* def_use_mgr = pass_->context()->get_def_use_mgr(); |
| 369 | analysis::TypeManager* type_mgr = pass_->context()->get_type_mgr(); |
| 370 | analysis::Type* load_type = type_mgr->GetType(inst->type_id()); |
| 371 | uint32_t val_id = 0; |
| 372 | bool found_reaching_def = false; |
| 373 | while (!found_reaching_def) { |
| 374 | if (!pass_->IsTargetVar(var_id)) { |
| 375 | // If the variable we are loading from is not an SSA target (globals, |
| 376 | // function parameters), do nothing. |
| 377 | return true; |
| 378 | } |
| 379 | |
| 380 | val_id = GetReachingDef(var_id, bb); |
| 381 | if (val_id == 0) { |
| 382 | return false; |
| 383 | } |
| 384 | |
| 385 | // If the reaching definition is a pointer type different than the type of |
| 386 | // the instruction we are analyzing, then it must be a reference to another |
nothing calls this directly
no test coverage detected