// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool AggregateCopyPropagation::GetOldestAvailable(Operand* candidateOp, TOperandToIdDict& availableCopies, BitVector& killSet, CopySetInfo& info) { // Check if an original source is available. int id; if(availableCopies.TryGetValue(candidateOp, &id)) { if(killSet.IsSet(id)) { // The original is dirty. return false; } info = infoList_[id]; auto originalOp = info.Source; // Check if an older source is available. This is useful // for a chain of copies, when the copies are not modified. while(availableCopies.TryGetValue(originalOp, &id)) { if(killSet.IsSet(id)) { return originalOp; } info = infoList_[id]; originalOp = info.Source; } return true; } return false; }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void VariableAnalysis::ComputeBlockExposedAndKillSets(Block* block, BitVector& exposedSet, BitVector& killSet) { // Scan all the instructions in the block and look for 'load' and 'store'. for(auto instr = block->FirstInstruction(); instr; instr = instr->NextInstruction()) { if(auto storeInstr = instr->As<StoreInstr>()) { // A variable can be killed only if it's stored into. // Note that we don't care about the effects of function calls, // because in that case the variable is marked as "address taken" // and it isn't considered for SSA conversion anyway. if(auto variableRef = storeInstr->DestinationOp()->As<VariableReference>()) { auto localVar = variableRef->GetVariable(); if(localVar == nullptr) { continue; } killSet.SetBit(localVar->Id()); } } else if(auto loadInstr = instr->As<LoadInstr>()) { // The only way a variable can be "used" is through a 'load' instruction. // All other kinds of uses will render the variable as being "address taken". if(auto variableRef = loadInstr->SourceOp()->As<VariableReference>()) { auto localVar = variableRef->GetVariable(); if(localVar == nullptr) { continue; } // Mark the variable as 'exposed' only if it's not in the 'kill' set. if(killSet.IsSet(localVar->Id()) == false) { exposedSet.SetBit(localVar->Id()); } } } } }