/// ScanReachableFromBlock - Mark all blocks reachable from Start. /// Returns the total number of blocks that were marked reachable. unsigned ScanReachableFromBlock(const CFGBlock &Start, llvm::BitVector &Reachable) { unsigned count = 0; llvm::SmallVector<const CFGBlock*, 32> WL; // Prep work queue Reachable.set(Start.getBlockID()); ++count; WL.push_back(&Start); // Find the reachable blocks from 'Start'. CFGBlock::FilterOptions FO; FO.IgnoreDefaultsWithCoveredEnums = 1; while (!WL.empty()) { const CFGBlock *item = WL.back(); WL.pop_back(); // Look at the successors and mark then reachable. for (CFGBlock::filtered_succ_iterator I= item->filtered_succ_start_end(FO); I.hasMore(); ++I) if (const CFGBlock *B = *I) { unsigned blockID = B->getBlockID(); if (!Reachable[blockID]) { Reachable.set(blockID); ++count; WL.push_back(B); } } } return count; }
size_t randomBit(const llvm::BitVector &Vector) { assert(Vector.any()); auto Itr = Vector.set_bits_begin(); for (size_t I = randomIndex(Vector.count()); I != 0; --I) ++Itr; return *Itr; }
static SourceLocation MarkLiveTop(const CFGBlock *Start, llvm::BitVector &reachable, SourceManager &SM) { // Prep work worklist. llvm::SmallVector<const CFGBlock*, 32> WL; WL.push_back(Start); SourceRange R1, R2; SourceLocation top = GetUnreachableLoc(*Start, R1, R2); bool FromMainFile = false; bool FromSystemHeader = false; bool TopValid = false; if (top.isValid()) { FromMainFile = SM.isFromMainFile(top); FromSystemHeader = SM.isInSystemHeader(top); TopValid = true; } // Solve CFGBlock::FilterOptions FO; FO.IgnoreDefaultsWithCoveredEnums = 1; while (!WL.empty()) { const CFGBlock *item = WL.back(); WL.pop_back(); SourceLocation c = GetUnreachableLoc(*item, R1, R2); if (c.isValid() && (!TopValid || (SM.isFromMainFile(c) && !FromMainFile) || (FromSystemHeader && !SM.isInSystemHeader(c)) || SM.isBeforeInTranslationUnit(c, top))) { top = c; FromMainFile = SM.isFromMainFile(top); FromSystemHeader = SM.isInSystemHeader(top); } reachable.set(item->getBlockID()); for (CFGBlock::filtered_succ_iterator I = item->filtered_succ_start_end(FO); I.hasMore(); ++I) if (const CFGBlock *B = *I) { unsigned blockID = B->getBlockID(); if (!reachable[blockID]) { reachable.set(blockID); WL.push_back(B); } } } return top; }
unsigned ScanReachableFromBlock(const CFGBlock *Start, llvm::BitVector &Reachable) { unsigned count = 0; // Prep work queue SmallVector<const CFGBlock*, 32> WL; // The entry block may have already been marked reachable // by the caller. if (!Reachable[Start->getBlockID()]) { ++count; Reachable[Start->getBlockID()] = true; } WL.push_back(Start); // Find the reachable blocks from 'Start'. while (!WL.empty()) { const CFGBlock *item = WL.pop_back_val(); // Look at the successors and mark then reachable. for (CFGBlock::const_succ_iterator I = item->succ_begin(), E = item->succ_end(); I != E; ++I) if (const CFGBlock *B = *I) { unsigned blockID = B->getBlockID(); if (!Reachable[blockID]) { Reachable.set(blockID); WL.push_back(B); ++count; } } } return count; }
void RegisterAliasingTracker::FillOriginAndAliasedBits( const llvm::MCRegisterInfo &RegInfo, const llvm::BitVector &SourceBits) { using RegAliasItr = llvm::MCRegAliasIterator; for (const size_t PhysReg : SourceBits.set_bits()) { for (auto Itr = RegAliasItr(PhysReg, &RegInfo, true); Itr.isValid(); ++Itr) { AliasedBits.set(*Itr); Origins[*Itr] = PhysReg; } } }
llvm::BitVector getAliasedBits(const llvm::MCRegisterInfo &RegInfo, const llvm::BitVector &SourceBits) { llvm::BitVector AliasedBits(RegInfo.getNumRegs()); for (const size_t PhysReg : SourceBits.set_bits()) { using RegAliasItr = llvm::MCRegAliasIterator; for (auto Itr = RegAliasItr(PhysReg, &RegInfo, true); Itr.isValid(); ++Itr) { AliasedBits.set(*Itr); } } return AliasedBits; }
static void randomize(const Instruction &Instr, const Variable &Var, llvm::MCOperand &AssignedValue, const llvm::BitVector &ForbiddenRegs) { const Operand &Op = Instr.getPrimaryOperand(Var); switch (Op.getExplicitOperandInfo().OperandType) { case llvm::MCOI::OperandType::OPERAND_IMMEDIATE: // FIXME: explore immediate values too. AssignedValue = llvm::MCOperand::createImm(1); break; case llvm::MCOI::OperandType::OPERAND_REGISTER: { assert(Op.isReg()); auto AllowedRegs = Op.getRegisterAliasing().sourceBits(); assert(AllowedRegs.size() == ForbiddenRegs.size()); for (auto I : ForbiddenRegs.set_bits()) AllowedRegs.reset(I); AssignedValue = llvm::MCOperand::createReg(randomBit(AllowedRegs)); break; } default: break; } }
static unsigned scanFromBlock(const CFGBlock *Start, llvm::BitVector &Reachable, Preprocessor *PP, bool IncludeSometimesUnreachableEdges) { unsigned count = 0; // Prep work queue SmallVector<const CFGBlock*, 32> WL; // The entry block may have already been marked reachable // by the caller. if (!Reachable[Start->getBlockID()]) { ++count; Reachable[Start->getBlockID()] = true; } WL.push_back(Start); // Find the reachable blocks from 'Start'. while (!WL.empty()) { const CFGBlock *item = WL.pop_back_val(); // There are cases where we want to treat all successors as reachable. // The idea is that some "sometimes unreachable" code is not interesting, // and that we should forge ahead and explore those branches anyway. // This allows us to potentially uncover some "always unreachable" code // within the "sometimes unreachable" code. // Look at the successors and mark then reachable. Optional<bool> TreatAllSuccessorsAsReachable; if (!IncludeSometimesUnreachableEdges) TreatAllSuccessorsAsReachable = false; for (CFGBlock::const_succ_iterator I = item->succ_begin(), E = item->succ_end(); I != E; ++I) { const CFGBlock *B = *I; if (!B) do { const CFGBlock *UB = I->getPossiblyUnreachableBlock(); if (!UB) break; if (!TreatAllSuccessorsAsReachable.hasValue()) { assert(PP); TreatAllSuccessorsAsReachable = shouldTreatSuccessorsAsReachable(item, *PP); } if (TreatAllSuccessorsAsReachable.getValue()) { B = UB; break; } } while (false); if (B) { unsigned blockID = B->getBlockID(); if (!Reachable[blockID]) { Reachable.set(blockID); WL.push_back(B); ++count; } } } } return count; }
bool BlockState::isTrackingLSLocation(llvm::BitVector &BV, unsigned i) { return BV.test(i); }
void BlockState::stopTrackingLocation(llvm::BitVector &BV, unsigned i) { BV.reset(i); }
static void remove(llvm::BitVector &a, const llvm::BitVector &b) { assert(a.size() == b.size()); for (auto I : b.set_bits()) a.reset(I); }