// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void AggregateCopyPropagation::SetBit(BitVector& vector, int bit) { if(vector.BitCount() == (bit + 1)) { vector.Resize(bit + 4); } vector.SetBit(bit); }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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()); } } } } }
void BitVector_Test::Test_bitVectorPopulationCount() { { const u32 SIZE = 0; BitVector<SIZE> bits; assert(bits.PopulationCount() == 0); for (u32 i = 0; i < SIZE; ++i) { bits.SetBit(i); assert(bits.PopulationCount() == i + 1); } } { const u32 SIZE = 1; BitVector<SIZE> bits; assert(bits.PopulationCount() == 0); for (u32 i = 0; i < SIZE; ++i) { bits.SetBit(i); assert(bits.PopulationCount() == i + 1); } } { const u32 SIZE = 31; BitVector<SIZE> bits; assert(bits.PopulationCount() == 0); for (u32 i = 0; i < SIZE; ++i) { bits.SetBit(i); assert(bits.PopulationCount() == i + 1); } } { const u32 SIZE = 32; BitVector<SIZE> bits; assert(bits.PopulationCount() == 0); for (u32 i = 0; i < SIZE; ++i) { bits.SetBit(i); assert(bits.PopulationCount() == i + 1); } } { const u32 SIZE = 35; BitVector<SIZE> bits; assert(bits.PopulationCount() == 0); for (u32 i = 0; i < SIZE; ++i) { bits.SetBit(i); assert(bits.PopulationCount() == i + 1); } } { const u32 SIZE = 67; BitVector<SIZE> bits; assert(bits.PopulationCount() == 0); for (u32 i = 0; i < SIZE; ++i) { bits.SetBit(i); assert(bits.PopulationCount() == i + 1); } // all combinations of start and len.. BitVector<SIZE> zbits; for (u32 start = 0; start < SIZE; ++start) { for (u32 end = start; end < SIZE; ++end) { u32 len = end - start + 1; assert(bits.PopulationCount(start, len) == len); assert(zbits.PopulationCount(start, len) == 0); } } } { const u32 SIZE = 258; BitVector<SIZE> bits; assert(bits.PopulationCount() == 0); for (u32 i = 0; i < SIZE; ++i) { bits.SetBit(SIZE - i - 1); assert(bits.PopulationCount() == i + 1); } assert(bits.PopulationCount() == SIZE); for (u32 i = 0; i < SIZE; ++i) { bits.ClearBit(i); assert(bits.PopulationCount() == SIZE - (i + 1)); } } { BitVector<256>* bits = setup(); assert(bits->PopulationCount() == 115); assert(bits->PopulationCount(64,96) == 51); assert(bits->PopulationCount(5,250) == 113); } }