//------------------------------------------------------------------------ CGunTurret::ETargetClass CGunTurret::GetTargetClass(IEntity *pTarget)const { IActor *pActor=GetActor(pTarget->GetId()); if(!pActor) { if(IsTACBullet(pTarget)) return eTC_TACProjectile; return eTC_NotATarget; } if(IsTargetDead(pActor)) return eTC_NotATarget; if(!IsTargetHostile(pActor)) return eTC_NotATarget; if(IsTargetSpectating(pActor)) return eTC_NotATarget; bool vehicle = pActor->GetLinkedVehicle()!=0; //Vehicles only check if(m_turretparams.vehicles_only && !vehicle) return eTC_NotATarget; if(vehicle) return eTC_Vehicle; if(IsTargetCloaked(pActor)) return eTC_NotATarget; return eTC_Player; }
bool AggressiveDCEPass::ProcessGlobalValues() { // Remove debug and annotation statements referencing dead instructions. // This must be done before killing the instructions, otherwise there are // dead objects in the def/use database. bool modified = false; Instruction* instruction = &*get_module()->debug2_begin(); while (instruction) { if (instruction->opcode() != SpvOpName) { instruction = instruction->NextNode(); continue; } if (IsTargetDead(instruction)) { instruction = context()->KillInst(instruction); modified = true; } else { instruction = instruction->NextNode(); } } // This code removes all unnecessary decorations safely (see #1174). It also // does so in a more efficient manner than deleting them only as the targets // are deleted. std::vector<Instruction*> annotations; for (auto& inst : get_module()->annotations()) annotations.push_back(&inst); std::sort(annotations.begin(), annotations.end(), DecorationLess()); for (auto annotation : annotations) { switch (annotation->opcode()) { case SpvOpDecorate: case SpvOpMemberDecorate: case SpvOpDecorateStringGOOGLE: case SpvOpMemberDecorateStringGOOGLE: if (IsTargetDead(annotation)) { context()->KillInst(annotation); modified = true; } break; case SpvOpDecorateId: if (IsTargetDead(annotation)) { context()->KillInst(annotation); modified = true; } else { if (annotation->GetSingleWordInOperand(1) == SpvDecorationHlslCounterBufferGOOGLE) { // HlslCounterBuffer will reference an id other than the target. // If that id is dead, then the decoration can be removed as well. uint32_t counter_buffer_id = annotation->GetSingleWordInOperand(2); Instruction* counter_buffer_inst = get_def_use_mgr()->GetDef(counter_buffer_id); if (IsDead(counter_buffer_inst)) { context()->KillInst(annotation); modified = true; } } } break; case SpvOpGroupDecorate: { // Go through the targets of this group decorate. Remove each dead // target. If all targets are dead, remove this decoration. bool dead = true; bool removed_operand = false; for (uint32_t i = 1; i < annotation->NumOperands();) { Instruction* opInst = get_def_use_mgr()->GetDef(annotation->GetSingleWordOperand(i)); if (IsDead(opInst)) { // Don't increment |i|. annotation->RemoveOperand(i); modified = true; removed_operand = true; } else { i++; dead = false; } } if (dead) { context()->KillInst(annotation); modified = true; } else if (removed_operand) { context()->UpdateDefUse(annotation); } break; } case SpvOpGroupMemberDecorate: { // Go through the targets of this group member decorate. Remove each // dead target (and member index). If all targets are dead, remove this // decoration. bool dead = true; bool removed_operand = false; for (uint32_t i = 1; i < annotation->NumOperands();) { Instruction* opInst = get_def_use_mgr()->GetDef(annotation->GetSingleWordOperand(i)); if (IsDead(opInst)) { // Don't increment |i|. annotation->RemoveOperand(i + 1); annotation->RemoveOperand(i); modified = true; removed_operand = true; } else { i += 2; dead = false; } } if (dead) { context()->KillInst(annotation); modified = true; } else if (removed_operand) { context()->UpdateDefUse(annotation); } break; } case SpvOpDecorationGroup: // By the time we hit decoration groups we've checked everything that // can target them. So if they have no uses they must be dead. if (get_def_use_mgr()->NumUsers(annotation) == 0) { context()->KillInst(annotation); modified = true; } break; default: assert(false); break; } } // Since ADCE is disabled for non-shaders, we don't check for export linkage // attributes here. for (auto& val : get_module()->types_values()) { if (IsDead(&val)) { to_kill_.push_back(&val); } } return modified; }