-------------------------------------------------------------------------------- I1 cache: 65536 B, 64 B, 4-way associative D1 cache: 32768 B, 64 B, 8-way associative LL cache: 67108864 B, 64 B, 64-way associative Command: /usr/home/liquid/.rustup/toolchains/w-profiling/bin/rustc --crate-name matrixmultiply --edition=2018 src/lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --crate-type lib --emit=dep-info,metadata,link -C opt-level=3 -C embed-bitcode=no -C debuginfo=2 --cfg feature="default" --cfg feature="std" -C metadata=2a345018774987de -C extra-filename=-2a345018774987de --out-dir /usr/home/liquid/tmp/.tmp0vPKQv/target/release/deps -L dependency=/usr/home/liquid/tmp/.tmp0vPKQv/target/release/deps --extern rawpointer=/usr/home/liquid/tmp/.tmp0vPKQv/target/release/deps/librawpointer-b4d326dbc7d6c1c5.rmeta -Adeprecated -Aunknown-lints -Zincremental-verify-ich Data file: results/cgout-w-profiling-matrixmultiply-0.3.2-Opt-Full Events recorded: Ir Events shown: Ir Event sort order: Ir Thresholds: 0.1 Include dirs: User annotated: Auto-annotation: on -------------------------------------------------------------------------------- Ir -------------------------------------------------------------------------------- 16,180,971,091 (100.0%) PROGRAM TOTALS -------------------------------------------------------------------------------- Ir file:function -------------------------------------------------------------------------------- 351,639,000 ( 2.17%) ???:llvm::BasicAAResult::alias(llvm::MemoryLocation const&, llvm::MemoryLocation const&, llvm::AAQueryInfo&) 340,980,710 ( 2.11%) ./malloc/malloc.c:_int_free 301,942,772 ( 1.87%) ./malloc/malloc.c:_int_malloc 245,411,741 ( 1.52%) ???:llvm::isNonEscapingLocalObject(llvm::Value const*, llvm::SmallDenseMap, llvm::detail::DenseMapPair >*) 222,731,264 ( 1.38%) ???:llvm::DataLayout::getTypeSizeInBits(llvm::Type*) const 212,472,512 ( 1.31%) ./malloc/malloc.c:malloc 177,371,276 ( 1.10%) ???:llvm::DataLayout::getAlignment(llvm::Type*, bool) const 165,160,904 ( 1.02%) ???:combineInstructionsOverFunction(llvm::Function&, llvm::InstCombineWorklist&, llvm::AAResults*, llvm::AssumptionCache&, llvm::TargetLibraryInfo&, llvm::TargetTransformInfo&, llvm::DominatorTree&, llvm::OptimizationRemarkEmitter&, llvm::BlockFrequencyInfo*, llvm::ProfileSummaryInfo*, unsigned int, llvm::LoopInfo*) 160,404,963 ( 0.99%) ???:llvm::InstCombinerImpl::run() 146,779,371 ( 0.91%) ???:computeKnownBits(llvm::Value const*, llvm::KnownBits&, unsigned int, (anonymous namespace)::Query const&) [clone .llvm.15619146473165121143] 137,128,369 ( 0.85%) ???:computeKnownBits(llvm::Value const*, llvm::APInt const&, llvm::KnownBits&, unsigned int, (anonymous namespace)::Query const&) 121,020,823 ( 0.75%) ???:(anonymous namespace)::Verifier::visitCallBase(llvm::CallBase&) 119,767,924 ( 0.74%) ???:llvm::ScalarEvolution::getSCEV(llvm::Value*) 117,054,448 ( 0.72%) ???:llvm::CallBase::getArgOperand(unsigned int) const 106,843,279 ( 0.66%) ./malloc/malloc.c:free 106,349,822 ( 0.66%) ???:llvm::ScalarEvolution::getAddExpr(llvm::SmallVectorImpl&, llvm::SCEV::NoWrapFlags, unsigned int) 98,444,887 ( 0.61%) ???:(anonymous namespace)::Verifier::visitInstruction(llvm::Instruction&) 94,517,588 ( 0.58%) ???:llvm::MachineInstr::findRegisterDefOperandIdx(llvm::Register, bool, bool, llvm::TargetRegisterInfo const*) const 90,522,814 ( 0.56%) ???:llvm::BitstreamCursor::readRecord(unsigned int, llvm::SmallVectorImpl&, llvm::StringRef*) 86,694,890 ( 0.54%) ???:llvm::TargetTransformInfo::Model::getUserCost(llvm::User const*, llvm::ArrayRef, llvm::TargetTransformInfo::TargetCostKind) 85,649,251 ( 0.53%) ???:llvm::SelectionDAG::Combine(llvm::CombineLevel, llvm::AAResults*, llvm::CodeGenOpt::Level) 84,721,694 ( 0.52%) ./string/../sysdeps/x86_64/multiarch/memcmp-avx2-movbe.S:__memcmp_avx2_movbe 84,483,859 ( 0.52%) ???:llvm::ValueHandleBase::AddToUseList() 82,962,864 ( 0.51%) ???:computeKnownBitsFromOperator(llvm::Operator const*, llvm::APInt const&, llvm::KnownBits&, unsigned int, (anonymous namespace)::Query const&) 82,358,004 ( 0.51%) ???:(anonymous namespace)::Verifier::visitMDNode(llvm::MDNode const&, (anonymous namespace)::Verifier::AreDebugLocsAllowed) 81,648,676 ( 0.50%) ???:llvm::TargetLibraryInfoImpl::getLibFunc(llvm::Function const&, llvm::LibFunc&) const 81,273,397 ( 0.50%) ???:llvm::MetadataTracking::track(void*, llvm::Metadata&, llvm::PointerUnion) 75,132,316 ( 0.46%) ???:llvm::BasicAAResult::getModRefInfo(llvm::CallBase const*, llvm::MemoryLocation const&, llvm::AAQueryInfo&) 69,505,739 ( 0.43%) ???:llvm::SimplifyInstruction(llvm::Instruction*, llvm::SimplifyQuery const&, llvm::OptimizationRemarkEmitter*) 68,488,157 ( 0.42%) ./string/../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:__memcpy_avx_unaligned_erms 68,305,153 ( 0.42%) ???:runCVP(llvm::Module&) [clone .llvm.11785992503873176614] 63,378,944 ( 0.39%) ???:(anonymous namespace)::LazyValueInfoImpl::getEdgeValue(llvm::Value*, llvm::BasicBlock*, llvm::BasicBlock*, llvm::Instruction*) [clone .llvm.4316243980339171764] 62,581,001 ( 0.39%) ???:computeKnownBitsFromAssume(llvm::Value const*, llvm::KnownBits&, unsigned int, (anonymous namespace)::Query const&) 62,275,538 ( 0.38%) ???:llvm::Type::isSizedDerivedType(llvm::SmallPtrSetImpl*) const 61,431,046 ( 0.38%) ???:llvm::ScalarEvolution::getMulExpr(llvm::SmallVectorImpl&, llvm::SCEV::NoWrapFlags, unsigned int) 58,855,071 ( 0.36%) ???:llvm::InlineFunction(llvm::CallBase&, llvm::InlineFunctionInfo&, llvm::AAResults*, bool, llvm::Function*) 58,192,526 ( 0.36%) ???:(anonymous namespace)::LazyValueInfoImpl::solve() [clone .llvm.4316243980339171764] 56,897,933 ( 0.35%) ???:llvm::SmallPtrSetImplBase::insert_imp_big(void const*) 56,241,800 ( 0.35%) ???:llvm::MachineInstr::addOperand(llvm::MachineFunction&, llvm::MachineOperand const&) 55,235,924 ( 0.34%) ???:llvm::getObjectSize(llvm::Value const*, unsigned long&, llvm::DataLayout const&, llvm::TargetLibraryInfo const*, llvm::ObjectSizeOpts) 54,533,463 ( 0.34%) ???:(anonymous namespace)::eliminateDeadStores(llvm::Function&, llvm::AAResults&, llvm::MemorySSA&, llvm::DominatorTree&, llvm::PostDominatorTree&, llvm::TargetLibraryInfo const&, llvm::LoopInfo const&) [clone .llvm.5769264623867638418] 53,071,355 ( 0.33%) ???:bool llvm::DenseMapBase*, llvm::DenseMapInfo<(anonymous namespace)::SimpleValue>, llvm::detail::DenseMapPair<(anonymous namespace)::SimpleValue, llvm::ScopedHashTableVal<(anonymous namespace)::SimpleValue, llvm::Value*>*> >, (anonymous namespace)::SimpleValue, llvm::ScopedHashTableVal<(anonymous namespace)::SimpleValue, llvm::Value*>*, llvm::DenseMapInfo<(anonymous namespace)::SimpleValue>, llvm::detail::DenseMapPair<(anonymous namespace)::SimpleValue, llvm::ScopedHashTableVal<(anonymous namespace)::SimpleValue, llvm::Value*>*> >::LookupBucketFor<(anonymous namespace)::SimpleValue>((anonymous namespace)::SimpleValue const&, llvm::detail::DenseMapPair<(anonymous namespace)::SimpleValue, llvm::ScopedHashTableVal<(anonymous namespace)::SimpleValue, llvm::Value*>*> const*&) const 51,555,538 ( 0.32%) ???:llvm::AAResults::getModRefInfo(llvm::Instruction const*, llvm::Optional const&, llvm::AAQueryInfo&) 50,610,210 ( 0.31%) ???:llvm::removeUnreachableBlocks(llvm::Function&, llvm::DomTreeUpdater*, llvm::MemorySSAUpdater*) 49,997,542 ( 0.31%) ???:llvm::DebugVariable::operator<(llvm::DebugVariable const&) const 48,065,881 ( 0.30%) ???:llvm::hashing::detail::hash_combine_recursive_helper::combine(unsigned long, char*, char*) 47,083,545 ( 0.29%) ???:(anonymous namespace)::MachineCopyPropagation::runOnMachineFunction(llvm::MachineFunction&) 46,606,227 ( 0.29%) ???:(anonymous namespace)::EarlyCSE::run() [clone .llvm.7062997131228810369] 45,773,221 ( 0.28%) ???:llvm::InstCombinerImpl::visitLoadInst(llvm::LoadInst&) 42,818,074 ( 0.26%) ./malloc/malloc.c:malloc_consolidate 42,387,372 ( 0.26%) ???:(anonymous namespace)::PruningFunctionCloner::CloneBlock(llvm::BasicBlock const*, llvm::ilist_iterator, false, true>, std::vector >&) 41,832,017 ( 0.26%) ???:llvm::sinkRegion(llvm::DomTreeNodeBase*, llvm::AAResults*, llvm::LoopInfo*, llvm::DominatorTree*, llvm::BlockFrequencyInfo*, llvm::TargetLibraryInfo*, llvm::TargetTransformInfo*, llvm::Loop*, llvm::AliasSetTracker*, llvm::MemorySSAUpdater*, llvm::ICFLoopSafetyInfo*, llvm::SinkAndHoistLICMFlags&, llvm::OptimizationRemarkEmitter*) 41,420,069 ( 0.26%) ???:isKnownNonZero(llvm::Value const*, llvm::APInt const&, unsigned int, (anonymous namespace)::Query const&) [clone .llvm.15619146473165121143] 40,065,800 ( 0.25%) ???:llvm::InstCombinerImpl::visitCallInst(llvm::CallInst&) 39,730,139 ( 0.25%) ???:llvm::DomTreeBuilder::SemiNCAInfo >::CalculateFromScratch(llvm::DominatorTreeBase&, llvm::DomTreeBuilder::SemiNCAInfo >::BatchUpdateInfo*) 39,683,756 ( 0.25%) ???:llvm::FPPassManager::runOnFunction(llvm::Function&) 39,048,595 ( 0.24%) ???:std::less<(anonymous namespace)::VarLocBasedLDV::VarLoc>::operator()((anonymous namespace)::VarLocBasedLDV::VarLoc const&, (anonymous namespace)::VarLocBasedLDV::VarLoc const&) const 38,833,323 ( 0.24%) ???:llvm::MemorySSA::buildMemorySSA(llvm::BatchAAResults&) 38,506,476 ( 0.24%) ???:(anonymous namespace)::BitcodeReader::parseFunctionBody(llvm::Function*) 37,694,738 ( 0.23%) ???:llvm::AnalysisManager::getResultImpl(llvm::AnalysisKey*, llvm::Function&) 37,119,572 ( 0.23%) ???:updateCGAndAnalysisManagerForPass(llvm::LazyCallGraph&, llvm::LazyCallGraph::SCC&, llvm::LazyCallGraph::Node&, llvm::AnalysisManager&, llvm::CGSCCUpdateResult&, llvm::AnalysisManager&, bool) [clone .llvm.5426518467876156712] 36,944,115 ( 0.23%) ???:llvm::Loop::isLCSSAForm(llvm::DominatorTree const&) const 36,779,273 ( 0.23%) ???:llvm::ScalarEvolution::getRangeRef(llvm::SCEV const*, llvm::ScalarEvolution::RangeSignHint) 36,255,599 ( 0.22%) ???:llvm::DILocalScope::getSubprogram() const 36,255,213 ( 0.22%) ???:(anonymous namespace)::ModuleBitcodeWriter::writeInstruction(llvm::Instruction const&, unsigned int, llvm::SmallVectorImpl&) 35,748,216 ( 0.22%) ???:llvm::LivePhysRegs::stepBackward(llvm::MachineInstr const&) 35,127,531 ( 0.22%) ???:llvm::hoistRegion(llvm::DomTreeNodeBase*, llvm::AAResults*, llvm::LoopInfo*, llvm::DominatorTree*, llvm::BlockFrequencyInfo*, llvm::TargetLibraryInfo*, llvm::Loop*, llvm::AliasSetTracker*, llvm::MemorySSAUpdater*, llvm::ScalarEvolution*, llvm::ICFLoopSafetyInfo*, llvm::SinkAndHoistLICMFlags&, llvm::OptimizationRemarkEmitter*, bool) 34,973,042 ( 0.22%) ???:llvm::Loop::isRecursivelyLCSSAForm(llvm::DominatorTree const&, llvm::LoopInfo const&) const 34,949,541 ( 0.22%) /tmp/gcc-build/x86_64-unknown-linux-gnu/libstdc++-v3/libsupc++/../../../../gcc-5.5.0/libstdc++-v3/libsupc++/new_op.cc:operator new(unsigned long) 34,641,068 ( 0.21%) ???:(anonymous namespace)::UserValue::insertDebugValue(llvm::MachineBasicBlock*, llvm::SlotIndex, llvm::SlotIndex, (anonymous namespace)::DbgVariableValue, llvm::ArrayRef, llvm::ArrayRef, llvm::LiveIntervals&, llvm::TargetInstrInfo const&, llvm::TargetRegisterInfo const&, llvm::DenseMap, llvm::DenseMapInfo, llvm::detail::DenseMapPair > >&) 34,243,492 ( 0.21%) ???:llvm::JumpThreadingPass::runImpl(llvm::Function&, llvm::TargetLibraryInfo*, llvm::LazyValueInfo*, llvm::AAResults*, llvm::DomTreeUpdater*, bool, std::unique_ptr >, std::unique_ptr >) 33,443,400 ( 0.21%) ???:llvm::DemandedBits::isInstructionDead(llvm::Instruction*) 32,709,683 ( 0.20%) ???:llvm::LoopBase::verifyLoop() const 32,048,293 ( 0.20%) ???:llvm::AnalysisManager::invalidate(llvm::Function&, llvm::PreservedAnalyses const&) 32,000,756 ( 0.20%) ./malloc/malloc.c:unlink_chunk.constprop.0 31,935,267 ( 0.20%) ???:llvm::simplifyCFG(llvm::BasicBlock*, llvm::TargetTransformInfo const&, llvm::DomTreeUpdater*, llvm::SimplifyCFGOptions const&, llvm::ArrayRef) 31,567,563 ( 0.20%) ./string/../sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S:__memset_avx2_erms 31,293,484 ( 0.19%) ???:llvm::AttributeList::addAttributes(llvm::LLVMContext&, unsigned int, llvm::AttrBuilder const&) const 31,202,638 ( 0.19%) ???:(anonymous namespace)::RAGreedy::tryAssign(llvm::LiveInterval&, llvm::AllocationOrder&, llvm::SmallVectorImpl&, llvm::SmallSet > const&) 30,751,208 ( 0.19%) ???:runImpl(llvm::Function&, llvm::LazyValueInfo*, llvm::DominatorTree*, llvm::SimplifyQuery const&) [clone .llvm.16011871802505272439] 30,498,724 ( 0.19%) ???:llvm::ScalarEvolution::addToLoopUseLists(llvm::SCEV const*) 30,479,795 ( 0.19%) ???:llvm::DomTreeBuilder::SemiNCAInfo >::runSemiNCA(llvm::DominatorTreeBase&, unsigned int) 30,422,395 ( 0.19%) ???:llvm::SROA::runOnAlloca(llvm::AllocaInst&) 30,104,360 ( 0.19%) ???:llvm::SelectionDAGISel::SelectCodeCommon(llvm::SDNode*, unsigned char const*, unsigned int) 30,093,147 ( 0.19%) ???:llvm::SelectionDAG::computeKnownBits(llvm::SDValue, llvm::APInt const&, unsigned int) const 29,468,970 ( 0.18%) ???:CompareSCEVComplexity(llvm::EquivalenceClasses&, llvm::EquivalenceClasses&, llvm::LoopInfo const*, llvm::SCEV const*, llvm::SCEV const*, llvm::DominatorTree&, unsigned int) 29,109,935 ( 0.18%) ???:llvm::DIExpression::ExprOperand::getSize() const 28,988,510 ( 0.18%) ???:llvm::ScalarEvolution::getLoopDisposition(llvm::SCEV const*, llvm::Loop const*) 28,569,874 ( 0.18%) ???:(anonymous namespace)::AggressiveDeadCodeElimination::performDeadCodeElimination() 28,256,698 ( 0.17%) ???:llvm::SmallVectorImpl<(anonymous namespace)::VarLocBasedLDV::VarLoc::MachineLoc>::operator<(llvm::SmallVectorImpl<(anonymous namespace)::VarLocBasedLDV::VarLoc::MachineLoc> const&) const 28,120,645 ( 0.17%) ???:llvm::hash_code llvm::hash_combine(llvm::DILocalVariable const* const&, unsigned int const&, llvm::DILocation const* const&) 27,857,559 ( 0.17%) ???:llvm::GVN::processBlock(llvm::BasicBlock*) 27,359,279 ( 0.17%) ???:llvm::InstCombinerImpl::visitStoreInst(llvm::StoreInst&) 26,953,360 ( 0.17%) ???:llvm::DILocation::getImpl(llvm::LLVMContext&, unsigned int, unsigned int, llvm::Metadata*, llvm::Metadata*, bool, llvm::Metadata::StorageType, bool) 26,808,270 ( 0.17%) ???:llvm::ImplicitControlFlowTracking::isSpecialInstruction(llvm::Instruction const*) const 26,646,444 ( 0.16%) ???:llvm::IntervalMapImpl::LeafNode >::insertFrom(unsigned int&, unsigned int, unsigned long, unsigned long, char) 26,513,751 ( 0.16%) ???:llvm::hash_code llvm::hashing::detail::hash_combine_recursive_helper::combine(unsigned long, char*, char*, unsigned int const&, llvm::DILocation const* const&) 25,762,454 ( 0.16%) ???:(anonymous namespace)::Mapper::mapValue(llvm::Value const*) [clone .llvm.12166235158543170009] 25,603,714 ( 0.16%) ???:llvm::KnownBits::mul(llvm::KnownBits const&, llvm::KnownBits const&) 25,540,353 ( 0.16%) ???:(anonymous namespace)::ClobberWalker::addSearches(llvm::MemoryPhi*, llvm::SmallVectorImpl&, unsigned int) 25,509,469 ( 0.16%) ???:llvm::SHA1::hashBlock() 24,950,172 ( 0.15%) ???:(anonymous namespace)::RAGreedy::growRegion((anonymous namespace)::RAGreedy::GlobalSplitCandidate&) 24,922,846 ( 0.15%) ???:llvm::MemoryDependenceResults::getNonLocalPointerDepFromBB(llvm::Instruction*, llvm::PHITransAddr const&, llvm::MemoryLocation const&, bool, llvm::BasicBlock*, llvm::SmallVectorImpl&, llvm::DenseMap, llvm::detail::DenseMapPair >&, bool, bool) 24,831,288 ( 0.15%) /usr/home/liquid/rust/worktree-benchmarking/library/core/src/slice/mod.rs:::lookup_source_file_idx 24,756,534 ( 0.15%) ???:DecodeIITType(unsigned int&, llvm::ArrayRef, IIT_Info, llvm::SmallVectorImpl&) [clone .llvm.4021314427178024980] 24,600,049 ( 0.15%) ???:llvm::ConstantRange::makeExactICmpRegion(llvm::CmpInst::Predicate, llvm::APInt const&) 24,537,691 ( 0.15%) ???:llvm::Intrinsic::getDeclaration(llvm::Module*, unsigned int, llvm::ArrayRef) 24,382,264 ( 0.15%) ???:llvm::FoldingSetBase::FindNodeOrInsertPos(llvm::FoldingSetNodeID const&, void*&, llvm::FoldingSetBase::FoldingSetInfo const&) 24,097,826 ( 0.15%) ???:llvm::ScalarEvolution::getAddRecExpr(llvm::SmallVectorImpl&, llvm::Loop const*, llvm::SCEV::NoWrapFlags) 24,038,413 ( 0.15%) ???:llvm::InterferenceCache::Entry::update(unsigned int) 23,967,149 ( 0.15%) ???:(anonymous namespace)::CVPLatticeFunc::ComputeInstructionState(llvm::Instruction&, llvm::DenseMap, llvm::PointerIntPairInfo > >, (anonymous namespace)::CVPLatticeVal, llvm::DenseMapInfo, llvm::PointerIntPairInfo > > >, llvm::detail::DenseMapPair, llvm::PointerIntPairInfo > >, (anonymous namespace)::CVPLatticeVal> >&, llvm::SparseSolver, llvm::PointerIntPairInfo > >, (anonymous namespace)::CVPLatticeVal, llvm::LatticeKeyInfo, llvm::PointerIntPairInfo > > > >&) 23,836,290 ( 0.15%) ???:(anonymous namespace)::ClobberWalker::findClobber(llvm::MemoryAccess*, (anonymous namespace)::UpwardsMemoryQuery&, unsigned int&) 23,759,153 ( 0.15%) ???:llvm::ConstantRange::multiply(llvm::ConstantRange const&) const 23,209,161 ( 0.14%) ???:llvm::calculateDbgEntityHistory(llvm::MachineFunction const*, llvm::TargetRegisterInfo const*, llvm::DbgValueHistoryMap&, llvm::DbgLabelInstrMap&) 22,590,523 ( 0.14%) ???:llvm::ScalarEvolution::getOrCreateAddExpr(llvm::ArrayRef, llvm::SCEV::NoWrapFlags) 22,573,189 ( 0.14%) ???:llvm::SmallVectorTemplateBase::push_back(llvm::IntervalMapImpl::Path::Entry) 22,508,534 ( 0.14%) ???:llvm::Instruction::clone() const 22,479,572 ( 0.14%) ???:llvm::ValueMap > >::operator[](llvm::Value const* const&) 22,071,544 ( 0.14%) ???:(anonymous namespace)::DeadMachineInstructionElim::eliminateDeadMI(llvm::MachineFunction&) 21,901,252 ( 0.14%) ???:ComputeNumSignBitsImpl(llvm::Value const*, llvm::APInt const&, unsigned int, (anonymous namespace)::Query const&) [clone .llvm.15619146473165121143] 21,590,322 ( 0.13%) ???:llvm::ValueHandleBase::RemoveFromUseList() 21,530,608 ( 0.13%) ???:(anonymous namespace)::RemoveRedundantDebugValues::runOnMachineFunction(llvm::MachineFunction&) 21,409,054 ( 0.13%) ???:llvm::ReassociatePass::BuildRankMap(llvm::Function&, llvm::ReversePostOrderTraversal >&) 21,303,099 ( 0.13%) ???:llvm::DIExpression::getFragmentInfo(llvm::DIExpression::expr_op_iterator, llvm::DIExpression::expr_op_iterator) 21,223,398 ( 0.13%) ./string/../sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S:__memset_avx2_unaligned_erms 21,116,039 ( 0.13%) ???:llvm::MetadataAsValue::get(llvm::LLVMContext&, llvm::Metadata*) 21,004,222 ( 0.13%) ???:llvm::InstCombinerImpl::visitAdd(llvm::BinaryOperator&) 20,742,359 ( 0.13%) /usr/home/liquid/rust/worktree-benchmarking/compiler/rustc_trait_selection/src/traits/fulfill.rs:>::process_obligations::> 20,613,010 ( 0.13%) ???:bool __gnu_cxx::__ops::_Iter_less_iter::operator()<(anonymous namespace)::VarLocBasedLDV::VarLoc::MachineLoc const*, (anonymous namespace)::VarLocBasedLDV::VarLoc::MachineLoc const*>((anonymous namespace)::VarLocBasedLDV::VarLoc::MachineLoc const*, (anonymous namespace)::VarLocBasedLDV::VarLoc::MachineLoc const*) const 20,281,462 ( 0.13%) ???:llvm::CodeMetrics::analyzeBasicBlock(llvm::BasicBlock const*, llvm::TargetTransformInfo const&, llvm::SmallPtrSetImpl const&, bool) 19,813,171 ( 0.12%) ???:llvm::SimplifyGEPInst(llvm::Type*, llvm::ArrayRef, llvm::SimplifyQuery const&) 19,793,102 ( 0.12%) ???:llvm::isInstructionTriviallyDead(llvm::Instruction*, llvm::TargetLibraryInfo const*) 19,662,117 ( 0.12%) ???:llvm::raw_svector_ostream::write_impl(char const*, unsigned long) 19,436,306 ( 0.12%) ./string/../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:memcpy@GLIBC_2.2.5 19,068,038 ( 0.12%) ???:llvm::KnownBits::computeForAddSub(bool, bool, llvm::KnownBits const&, llvm::KnownBits) 19,062,947 ( 0.12%) ???:llvm::MetadataTracking::untrack(void*, llvm::Metadata&) 18,983,028 ( 0.12%) ???:(anonymous namespace)::LDVImpl::runOnMachineFunction(llvm::MachineFunction&, bool) 18,775,863 ( 0.12%) ???:??? 18,773,028 ( 0.12%) ???:llvm::InstCombinerImpl::visitICmpInst(llvm::ICmpInst&) 18,750,424 ( 0.12%) /usr/home/liquid/rust/worktree-benchmarking/library/core/src/str/lossy.rs:::next 18,579,980 ( 0.11%) ???:llvm::Value::deleteValue() 18,570,662 ( 0.11%) ???:bool llvm::DenseMapBase, llvm::detail::DenseSetPair >, llvm::DILocation*, llvm::detail::DenseSetEmpty, llvm::MDNodeInfo, llvm::detail::DenseSetPair >::LookupBucketFor(llvm::DILocation* const&, llvm::detail::DenseSetPair const*&) const 18,215,082 ( 0.11%) ???:llvm::AAResults::Model::pointsToConstantMemory(llvm::MemoryLocation const&, llvm::AAQueryInfo&, bool) 18,115,741 ( 0.11%) ???:llvm::ValueMapper::remapInstruction(llvm::Instruction&) 17,976,536 ( 0.11%) /usr/home/liquid/rust/worktree-benchmarking/compiler/rustc_data_structures/src/obligation_forest/mod.rs:>::process_obligations::> 17,898,416 ( 0.11%) ???:llvm::DIExpression::isValid() const 17,691,080 ( 0.11%) ???:(anonymous namespace)::Verifier::verify(llvm::Function const&) [clone .llvm.4153962086227604281] 17,653,690 ( 0.11%) ???:llvm::IntervalMap >::insert(unsigned long, unsigned long, char) 17,586,662 ( 0.11%) ???:std::__tuple_compare const&, llvm::DILocation const* const&>, std::tuple const&, llvm::DILocation const* const&>, 1ul, 3ul>::__less(std::tuple const&, llvm::DILocation const* const&> const&, std::tuple const&, llvm::DILocation const* const&> const&) 17,576,433 ( 0.11%) ???:char* llvm::hashing::detail::hash_combine_recursive_helper::combine_data(unsigned long&, char*, char*, unsigned int) 17,524,982 ( 0.11%) ???:llvm::LLVMContextImpl::~LLVMContextImpl() 17,500,717 ( 0.11%) ???:SimplifyICmpInst(unsigned int, llvm::Value*, llvm::Value*, llvm::SimplifyQuery const&, unsigned int) [clone .llvm.1619516508949622737] 17,431,577 ( 0.11%) ???:llvm::IntervalMap >::const_iterator::setRoot(unsigned int) 17,424,083 ( 0.11%) ???:(anonymous namespace)::DAGCombiner::combine(llvm::SDNode*) 17,302,909 ( 0.11%) ./string/../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:__memcpy_sse2_unaligned_erms 17,193,833 ( 0.11%) ???:bool llvm::DenseMapBase, llvm::DIExpression*>, llvm::DenseMapInfo, llvm::detail::DenseMapPair, llvm::DIExpression*> > >, llvm::DebugVariable, std::pair, llvm::DIExpression*>, llvm::DenseMapInfo, llvm::detail::DenseMapPair, llvm::DIExpression*> > >::LookupBucketFor(llvm::DebugVariable const&, llvm::detail::DenseMapPair, llvm::DIExpression*> > const*&) const 17,180,236 ( 0.11%) ???:llvm::SROA::rewritePartition(llvm::AllocaInst&, llvm::sroa::AllocaSlices&, llvm::sroa::Partition&) 17,161,753 ( 0.11%) ???:llvm::SCCPInstVisitor::solve() 17,144,691 ( 0.11%) ???:(anonymous namespace)::CodeGenPrepare::optimizeCallInst(llvm::CallInst*, bool&) 17,028,853 ( 0.11%) ???:matchIntrinsicType(llvm::Type*, llvm::ArrayRef&, llvm::SmallVectorImpl&, llvm::SmallVectorImpl > >&, bool) [clone .llvm.4021314427178024980] 17,026,015 ( 0.11%) ???:(anonymous namespace)::VarLocBasedLDV::process(llvm::MachineInstr&, (anonymous namespace)::VarLocBasedLDV::OpenRangesSet&, (anonymous namespace)::VarLocBasedLDV::VarLocMap&, llvm::SmallVector<(anonymous namespace)::VarLocBasedLDV::TransferDebugPair, 4u>&) 16,966,438 ( 0.10%) ???:llvm::AttributeSetNode::get(llvm::LLVMContext&, llvm::AttrBuilder const&) 16,884,026 ( 0.10%) ???:llvm::TargetLowering::SimplifyDemandedBits(llvm::SDValue, llvm::APInt const&, llvm::APInt const&, llvm::KnownBits&, llvm::TargetLowering::TargetLoweringOpt&, unsigned int, bool) const 16,839,397 ( 0.10%) ./stdlib/msort.c:msort_with_tmp.part.0 16,720,863 ( 0.10%) ???:llvm::IntervalMap >::const_iterator::pathFillFind(unsigned long) 16,440,777 ( 0.10%) ???:llvm::LiveVariables::runOnBlock(llvm::MachineBasicBlock*, unsigned int) 16,299,081 ( 0.10%) ???:llvm::Value::stripAndAccumulateConstantOffsets(llvm::DataLayout const&, llvm::APInt&, bool, llvm::function_ref) const 16,277,199 ( 0.10%) ???:llvm::AAResults::Model::getModRefBehavior(llvm::CallBase const*) 16,247,515 ( 0.10%) ???:bitTrackingDCE(llvm::Function&, llvm::DemandedBits&) [clone .llvm.10382385614880861749] 16,199,208 ( 0.10%) ???:llvm::IntervalMap >::const_iterator::unsafeStop() const -------------------------------------------------------------------------------- -- Auto-annotated source: /usr/home/liquid/rust/worktree-benchmarking/library/core/src/slice/mod.rs -------------------------------------------------------------------------------- Ir -- line 141 ---------------------------------------- . /// ``` . /// let a = [1, 2, 3]; . /// assert!(!a.is_empty()); . /// ``` . #[stable(feature = "rust1", since = "1.0.0")] . #[rustc_const_stable(feature = "const_slice_is_empty", since = "1.39.0")] . #[inline] . pub const fn is_empty(&self) -> bool { 1,049,443 ( 0.01%) self.len() == 0 . } . . /// Returns the first element of the slice, or `None` if it is empty. . /// . /// # Examples . /// . /// ``` . /// let v = [10, 40, 30]; -- line 157 ---------------------------------------- -- line 159 ---------------------------------------- . /// . /// let w: &[i32] = &[]; . /// assert_eq!(None, w.first()); . /// ``` . #[stable(feature = "rust1", since = "1.0.0")] . #[rustc_const_stable(feature = "const_slice_first_last_not_mut", since = "1.56.0")] . #[inline] . pub const fn first(&self) -> Option<&T> { 7,312 ( 0.00%) if let [first, ..] = self { Some(first) } else { None } . } . . /// Returns a mutable pointer to the first element of the slice, or `None` if it is empty. . /// . /// # Examples . /// . /// ``` . /// let x = &mut [0, 1, 2]; -- line 175 ---------------------------------------- -- line 178 ---------------------------------------- . /// *first = 5; . /// } . /// assert_eq!(x, &[5, 1, 2]); . /// ``` . #[stable(feature = "rust1", since = "1.0.0")] . #[rustc_const_unstable(feature = "const_slice_first_last", issue = "83570")] . #[inline] . pub const fn first_mut(&mut self) -> Option<&mut T> { 232 ( 0.00%) if let [first, ..] = self { Some(first) } else { None } . } . . /// Returns the first and all the rest of the elements of the slice, or `None` if it is empty. . /// . /// # Examples . /// . /// ``` . /// let x = &[0, 1, 2]; -- line 194 ---------------------------------------- -- line 197 ---------------------------------------- . /// assert_eq!(first, &0); . /// assert_eq!(elements, &[1, 2]); . /// } . /// ``` . #[stable(feature = "slice_splits", since = "1.5.0")] . #[rustc_const_stable(feature = "const_slice_first_last_not_mut", since = "1.56.0")] . #[inline] . pub const fn split_first(&self) -> Option<(&T, &[T])> { 8 ( 0.00%) if let [first, tail @ ..] = self { Some((first, tail)) } else { None } . } . . /// Returns the first and all the rest of the elements of the slice, or `None` if it is empty. . /// . /// # Examples . /// . /// ``` . /// let x = &mut [0, 1, 2]; -- line 213 ---------------------------------------- -- line 237 ---------------------------------------- . /// assert_eq!(last, &2); . /// assert_eq!(elements, &[0, 1]); . /// } . /// ``` . #[stable(feature = "slice_splits", since = "1.5.0")] . #[rustc_const_stable(feature = "const_slice_first_last_not_mut", since = "1.56.0")] . #[inline] . pub const fn split_last(&self) -> Option<(&T, &[T])> { 6,772 ( 0.00%) if let [init @ .., last] = self { Some((last, init)) } else { None } . } . . /// Returns the last and all the rest of the elements of the slice, or `None` if it is empty. . /// . /// # Examples . /// . /// ``` . /// let x = &mut [0, 1, 2]; -- line 253 ---------------------------------------- -- line 276 ---------------------------------------- . /// . /// let w: &[i32] = &[]; . /// assert_eq!(None, w.last()); . /// ``` . #[stable(feature = "rust1", since = "1.0.0")] . #[rustc_const_stable(feature = "const_slice_first_last_not_mut", since = "1.56.0")] . #[inline] . pub const fn last(&self) -> Option<&T> { 437,773 ( 0.00%) if let [.., last] = self { Some(last) } else { None } . } . . /// Returns a mutable pointer to the last item in the slice. . /// . /// # Examples . /// . /// ``` . /// let x = &mut [0, 1, 2]; -- line 292 ---------------------------------------- -- line 295 ---------------------------------------- . /// *last = 10; . /// } . /// assert_eq!(x, &[0, 1, 10]); . /// ``` . #[stable(feature = "rust1", since = "1.0.0")] . #[rustc_const_unstable(feature = "const_slice_first_last", issue = "83570")] . #[inline] . pub const fn last_mut(&mut self) -> Option<&mut T> { 510,689 ( 0.00%) if let [.., last] = self { Some(last) } else { None } . } . . /// Returns a reference to an element or subslice depending on the type of . /// index. . /// . /// - If given a position, returns a reference to the element at that . /// position or `None` if out of bounds. . /// - If given a range, returns the subslice corresponding to that range, -- line 311 ---------------------------------------- -- line 448 ---------------------------------------- . /// } . /// ``` . /// . /// [`as_mut_ptr`]: slice::as_mut_ptr . #[stable(feature = "rust1", since = "1.0.0")] . #[rustc_const_stable(feature = "const_slice_as_ptr", since = "1.32.0")] . #[inline] . pub const fn as_ptr(&self) -> *const T { 1,137,915 ( 0.01%) self as *const [T] as *const T . } . . /// Returns an unsafe mutable pointer to the slice's buffer. . /// . /// The caller must ensure that the slice outlives the pointer this . /// function returns, or else it will end up pointing to garbage. . /// . /// Modifying the container referenced by this slice may cause its buffer -- line 464 ---------------------------------------- -- line 476 ---------------------------------------- . /// } . /// } . /// assert_eq!(x, &[3, 4, 6]); . /// ``` . #[stable(feature = "rust1", since = "1.0.0")] . #[rustc_const_unstable(feature = "const_ptr_offset", issue = "71499")] . #[inline] . pub const fn as_mut_ptr(&mut self) -> *mut T { 15 ( 0.00%) self as *mut [T] as *mut T . } . . /// Returns the two raw pointers spanning the slice. . /// . /// The returned range is half-open, which means that the end pointer . /// points *one past* the last element of the slice. This way, an empty . /// slice is represented by two equal pointers, and the difference between . /// the two pointers represents the size of the slice. -- line 492 ---------------------------------------- -- line 582 ---------------------------------------- . /// v.swap(2, 4); . /// assert!(v == ["a", "b", "e", "d", "c"]); . /// ``` . #[stable(feature = "rust1", since = "1.0.0")] . #[rustc_const_unstable(feature = "const_swap", issue = "83163")] . #[inline] . #[track_caller] . pub const fn swap(&mut self, a: usize, b: usize) { 38,450 ( 0.00%) let _ = &self[a]; 216,226 ( 0.00%) let _ = &self[b]; . . // SAFETY: we just checked that both `a` and `b` are in bounds . unsafe { self.swap_unchecked(a, b) } . } . . /// Swaps two elements in the slice, without doing bounds checking. . /// . /// For a safe alternative see [`swap`]. -- line 599 ---------------------------------------- -- line 677 ---------------------------------------- . . // Because this function is first compiled in isolation, . // this check tells LLVM that the indexing below is . // in-bounds. Then after inlining -- once the actual . // lengths of the slices are known -- it's removed. . let (a, b) = (&mut a[..n], &mut b[..n]); . . for i in 0..n { 1,079 ( 0.00%) mem::swap(&mut a[i], &mut b[n - 1 - i]); . } . } . } . . /// Returns an iterator over the slice. . /// . /// # Examples . /// -- line 693 ---------------------------------------- -- line 1499 ---------------------------------------- . /// assert_eq!(left, [1, 2, 3, 4, 5, 6]); . /// assert_eq!(right, []); . /// } . /// ``` . #[stable(feature = "rust1", since = "1.0.0")] . #[inline] . #[track_caller] . pub fn split_at(&self, mid: usize) -> (&[T], &[T]) { 366 ( 0.00%) assert!(mid <= self.len()); . // SAFETY: `[ptr; mid]` and `[mid; len]` are inside `self`, which . // fulfills the requirements of `from_raw_parts_mut`. . unsafe { self.split_at_unchecked(mid) } . } . . /// Divides one mutable slice into two at an index. . /// . /// The first will contain all indices from `[0, mid)` (excluding -- line 1515 ---------------------------------------- -- line 1530 ---------------------------------------- . /// left[1] = 2; . /// right[1] = 4; . /// assert_eq!(v, [1, 2, 3, 4, 5, 6]); . /// ``` . #[stable(feature = "rust1", since = "1.0.0")] . #[inline] . #[track_caller] . pub fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) { 9,190 ( 0.00%) assert!(mid <= self.len()); . // SAFETY: `[ptr; mid]` and `[mid; len]` are inside `self`, which . // fulfills the requirements of `from_raw_parts_mut`. . unsafe { self.split_at_mut_unchecked(mid) } . } . . /// Divides one slice into two at an index, without doing bounds checking. . /// . /// The first will contain all indices from `[0, mid)` (excluding -- line 1546 ---------------------------------------- -- line 1628 ---------------------------------------- . pub unsafe fn split_at_mut_unchecked(&mut self, mid: usize) -> (&mut [T], &mut [T]) { . let len = self.len(); . let ptr = self.as_mut_ptr(); . . // SAFETY: Caller has to check that `0 <= mid <= self.len()`. . // . // `[ptr; mid]` and `[mid; len]` are not overlapping, so returning a mutable reference . // is fine. 1,923 ( 0.00%) unsafe { (from_raw_parts_mut(ptr, mid), from_raw_parts_mut(ptr.add(mid), len - mid)) } . } . . /// Divides one slice into an array and a remainder slice at an index. . /// . /// The array will contain all indices from `[0, N)` (excluding . /// the index `N` itself) and the slice will contain all . /// indices from `[N, len)` (excluding the index `len` itself). . /// -- line 1644 ---------------------------------------- -- line 2113 ---------------------------------------- . /// assert!(!v.iter().any(|e| e == "hi")); . /// ``` . #[stable(feature = "rust1", since = "1.0.0")] . #[inline] . pub fn contains(&self, x: &T) -> bool . where . T: PartialEq, . { 58 ( 0.00%) cmp::SliceContains::slice_contains(x, self) . } . . /// Returns `true` if `needle` is a prefix of the slice. . /// . /// # Examples . /// . /// ``` . /// let v = [10, 40, 30]; -- line 2129 ---------------------------------------- -- line 2142 ---------------------------------------- . /// assert!(v.starts_with(&[])); . /// ``` . #[stable(feature = "rust1", since = "1.0.0")] . pub fn starts_with(&self, needle: &[T]) -> bool . where . T: PartialEq, . { . let n = needle.len(); 4,625 ( 0.00%) self.len() >= n && needle == &self[..n] . } . . /// Returns `true` if `needle` is a suffix of the slice. . /// . /// # Examples . /// . /// ``` . /// let v = [10, 40, 30]; -- line 2158 ---------------------------------------- -- line 2171 ---------------------------------------- . /// assert!(v.ends_with(&[])); . /// ``` . #[stable(feature = "rust1", since = "1.0.0")] . pub fn ends_with(&self, needle: &[T]) -> bool . where . T: PartialEq, . { . let (m, n) = (self.len(), needle.len()); 10,256 ( 0.00%) m >= n && needle == &self[m - n..] . } . . /// Returns a subslice with the prefix removed. . /// . /// If the slice starts with `prefix`, returns the subslice after the prefix, wrapped in `Some`. . /// If `prefix` is empty, simply returns the original slice. . /// . /// If the slice does not start with `prefix`, returns `None`. -- line 2187 ---------------------------------------- -- line 2293 ---------------------------------------- . /// s.insert(idx, num); . /// assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]); . /// ``` . #[stable(feature = "rust1", since = "1.0.0")] . pub fn binary_search(&self, x: &T) -> Result . where . T: Ord, . { 3 ( 0.00%) self.binary_search_by(|p| p.cmp(x)) . } . . /// Binary searches this sorted slice with a comparator function. . /// . /// The comparator function should implement an order consistent . /// with the sort order of the underlying slice, returning an . /// order code that indicates whether its argument is `Less`, . /// `Equal` or `Greater` the desired target. -- line 2309 ---------------------------------------- -- line 2345 ---------------------------------------- . #[inline] . pub fn binary_search_by<'a, F>(&'a self, mut f: F) -> Result . where . F: FnMut(&'a T) -> Ordering, . { . let mut size = self.len(); . let mut left = 0; . let mut right = size; 10,619,634 ( 0.07%) while left < right { 17,235,614 ( 0.11%) let mid = left + size / 2; . . // SAFETY: the call is made safe by the following invariants: . // - `mid >= 0` . // - `mid < size`: `mid` is limited by `[left; right)` bound. 1,958,609 ( 0.01%) let cmp = f(unsafe { self.get_unchecked(mid) }); . . // The reason why we use if/else control flow rather than match . // is because match reorders comparison operations, which is perf sensitive. . // This is x86 asm for u8: https://rust.godbolt.org/z/8Y8Pra. 4,491,739 ( 0.03%) if cmp == Less { 9,562,129 ( 0.06%) left = mid + 1; 2,226,212 ( 0.01%) } else if cmp == Greater { . right = mid; . } else { . // SAFETY: same as the `get_unchecked` above . unsafe { crate::intrinsics::assume(mid < self.len()) }; . return Ok(mid); . } . 13,817,669 ( 0.09%) size = right - left; . } . Err(left) . } . . /// Binary searches this sorted slice with a key extraction function. . /// . /// Assumes that the slice is sorted by the key, for instance with . /// [`sort_by_key`] using the same key extraction function. -- line 2382 ---------------------------------------- -- line 3203 ---------------------------------------- . #[track_caller] . fn len_mismatch_fail(dst_len: usize, src_len: usize) -> ! { . panic!( . "source slice length ({}) does not match destination slice length ({})", . src_len, dst_len, . ); . } . 126,422 ( 0.00%) if self.len() != src.len() { . len_mismatch_fail(self.len(), src.len()); . } . . // SAFETY: `self` is valid for `self.len()` elements by definition, and `src` was . // checked to have the same length. The slices cannot overlap because . // mutable references are exclusive. . unsafe { . ptr::copy_nonoverlapping(src.as_ptr(), self.as_mut_ptr(), self.len()); -- line 3219 ---------------------------------------- -- line 3382 ---------------------------------------- . } . let gcd: usize = gcd(mem::size_of::(), mem::size_of::()); . let ts: usize = mem::size_of::() / gcd; . let us: usize = mem::size_of::() / gcd; . . // Armed with this knowledge, we can find how many `U`s we can fit! . let us_len = self.len() / ts * us; . // And how many `T`s will be in the trailing slice! 14,924 ( 0.00%) let ts_len = self.len() % ts; . (us_len, ts_len) . } . . /// Transmute the slice to a slice of another type, ensuring alignment of the types is . /// maintained. . /// . /// This method splits the slice into three distinct slices: prefix, correctly aligned middle . /// slice of a new type, and the suffix slice. The method may make the middle slice the greatest -- line 3398 ---------------------------------------- -- line 3429 ---------------------------------------- . return (self, &[], &[]); . } . . // First, find at what point do we split between the first and 2nd slice. Easy with . // ptr.align_offset. . let ptr = self.as_ptr(); . // SAFETY: See the `align_to_mut` method for the detailed safety comment. . let offset = unsafe { crate::ptr::align_offset(ptr, mem::align_of::()) }; 14,924 ( 0.00%) if offset > self.len() { . (self, &[], &[]) . } else { . let (left, rest) = self.split_at(offset); . let (us_len, ts_len) = rest.align_to_offsets::(); . // SAFETY: now `rest` is definitely aligned, so `from_raw_parts` below is okay, . // since the caller guarantees that we can transmute `T` to `U` safely. . unsafe { . ( . left, . from_raw_parts(rest.as_ptr() as *const U, us_len), 14,924 ( 0.00%) from_raw_parts(rest.as_ptr().add(rest.len() - ts_len), ts_len), . ) . } . } . } . . /// Transmute the slice to a slice of another type, ensuring alignment of the types is . /// maintained. . /// -- line 3456 ---------------------------------------- -- line 3731 ---------------------------------------- . /// let v = [1, 2, 3, 3, 5, 6, 7]; . /// let i = v.partition_point(|&x| x < 5); . /// . /// assert_eq!(i, 4); . /// assert!(v[..i].iter().all(|&x| x < 5)); . /// assert!(v[i..].iter().all(|&x| !(x < 5))); . /// ``` . #[stable(feature = "partition_point", since = "1.52.0")] 3 ( 0.00%) pub fn partition_point

(&self, mut pred: P) -> usize . where . P: FnMut(&T) -> bool, . { . self.binary_search_by(|x| if pred(x) { Less } else { Greater }).unwrap_or_else(|i| i) 6 ( 0.00%) } . . /// Removes the subslice corresponding to the given range . /// and returns a reference to it. . /// . /// Returns `None` and does not modify the slice if the given . /// range is out of bounds. . /// . /// Note that this method only accepts one-sided ranges such as -- line 3752 ---------------------------------------- 8,623,493 ( 0.05%) -------------------------------------------------------------------------------- -- Auto-annotated source: /usr/home/liquid/rust/worktree-benchmarking/compiler/rustc_trait_selection/src/traits/fulfill.rs -------------------------------------------------------------------------------- Ir -- line 33 ---------------------------------------- . . impl<'tcx> ForestObligation for PendingPredicateObligation<'tcx> { . /// Note that we include both the `ParamEnv` and the `Predicate`, . /// as the `ParamEnv` can influence whether fulfillment succeeds . /// or fails. . type CacheKey = ty::ParamEnvAnd<'tcx, ty::Predicate<'tcx>>; . . fn as_cache_key(&self) -> Self::CacheKey { 368,595 ( 0.00%) self.obligation.param_env.and(self.obligation.predicate) . } . } . . /// The fulfillment context is used to drive trait resolution. It . /// consists of a list of obligations that must be (eventually) . /// satisfied. The job is to track which are satisfied, which yielded . /// errors, and which are still pending. At any point, users can call . /// `select_where_possible`, and the fulfillment context will try to do -- line 49 ---------------------------------------- -- line 79 ---------------------------------------- . // outside of any snapshot, so any use of it inside a snapshot . // will lead to trouble and therefore is checked against, but . // other fulfillment contexts sometimes do live inside of . // a snapshot (they don't *straddle* a snapshot, so there . // is no trouble there). . usable_in_snapshot: bool, . } . 60 ( 0.00%) #[derive(Clone, Debug)] . pub struct PendingPredicateObligation<'tcx> { . pub obligation: PredicateObligation<'tcx>, . // This is far more often read than modified, meaning that we . // should mostly optimize for reading speed, while modifying is not as relevant. . // . // For whatever reason using a boxed slice is slower than using a `Vec` here. . pub stalled_on: Vec>, . } . . // `PendingPredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger. . #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] . static_assert_size!(PendingPredicateObligation<'_>, 72); . . impl<'a, 'tcx> FulfillmentContext<'tcx> { . /// Creates a new fulfillment context. 1,352 ( 0.00%) pub fn new() -> FulfillmentContext<'tcx> { 21,082 ( 0.00%) FulfillmentContext { 4,017 ( 0.00%) predicates: ObligationForest::new(), . relationships: FxHashMap::default(), . register_region_obligations: true, . usable_in_snapshot: false, . } 1,352 ( 0.00%) } . . pub fn new_in_snapshot() -> FulfillmentContext<'tcx> { . FulfillmentContext { . predicates: ObligationForest::new(), . relationships: FxHashMap::default(), . register_region_obligations: true, . usable_in_snapshot: true, . } . } . . pub fn new_ignoring_regions() -> FulfillmentContext<'tcx> { 10,044 ( 0.00%) FulfillmentContext { 2,511 ( 0.00%) predicates: ObligationForest::new(), . relationships: FxHashMap::default(), . register_region_obligations: false, . usable_in_snapshot: false, . } . } . . /// Attempts to select obligations using `selcx`. . fn select(&mut self, selcx: &mut SelectionContext<'a, 'tcx>) -> Vec> { 47,868 ( 0.00%) let span = debug_span!("select", obligation_forest_size = ?self.predicates.len()); . let _enter = span.enter(); . . let mut errors = Vec::new(); . . loop { . debug!("select: starting another iteration"); . . // Process pending obligations. . let outcome: Outcome<_, _> = 226,170 ( 0.00%) self.predicates.process_obligations(&mut FulfillProcessor { . selcx, 32,310 ( 0.00%) register_region_obligations: self.register_region_obligations, . }); . debug!("select: outcome={:#?}", outcome); . . // FIXME: if we kept the original cache key, we could mark projection . // obligations as complete for the projection cache here. . . errors.extend(outcome.errors.into_iter().map(to_fulfillment_error)); . . // If nothing new was added, no need to keep looping. 64,620 ( 0.00%) if outcome.stalled { . break; . } . } . . debug!( . "select({} predicates remaining, {} errors) done", . self.predicates.len(), . errors.len() -- line 162 ---------------------------------------- -- line 198 ---------------------------------------- . ); . self.register_predicate_obligations(infcx, obligations); . . debug!(?normalized_ty); . . normalized_ty . } . 234,420 ( 0.00%) fn register_predicate_obligation( . &mut self, . infcx: &InferCtxt<'_, 'tcx>, . obligation: PredicateObligation<'tcx>, . ) { . // this helps to reduce duplicate errors, as well as making . // debug output much nicer to read and so on. 117,210 ( 0.00%) let obligation = infcx.resolve_vars_if_possible(obligation); . . debug!(?obligation, "register_predicate_obligation"); . 234,420 ( 0.00%) assert!(!infcx.is_in_snapshot() || self.usable_in_snapshot); . 117,210 ( 0.00%) super::relationships::update(self, infcx, &obligation); . . self.predicates . .register_obligation(PendingPredicateObligation { obligation, stalled_on: vec![] }); 195,350 ( 0.00%) } . 62,520 ( 0.00%) fn select_all_or_error(&mut self, infcx: &InferCtxt<'_, 'tcx>) -> Vec> { . { 7,815 ( 0.00%) let errors = self.select_where_possible(infcx); 7,815 ( 0.00%) if !errors.is_empty() { 15 ( 0.00%) return errors; . } . } . 39,060 ( 0.00%) self.predicates.to_errors(CodeAmbiguity).into_iter().map(to_fulfillment_error).collect() 54,705 ( 0.00%) } . 239,340 ( 0.00%) fn select_where_possible( . &mut self, . infcx: &InferCtxt<'_, 'tcx>, . ) -> Vec> { . let mut selcx = SelectionContext::new(infcx); . self.select(&mut selcx) 215,406 ( 0.00%) } . 255 ( 0.00%) fn pending_obligations(&self) -> Vec> { . self.predicates.map_pending_obligations(|o| o.obligation.clone()) 340 ( 0.00%) } . . fn relationships(&mut self) -> &mut FxHashMap { 75 ( 0.00%) &mut self.relationships 75 ( 0.00%) } . } . . struct FulfillProcessor<'a, 'b, 'tcx> { . selcx: &'a mut SelectionContext<'b, 'tcx>, . register_region_obligations: bool, . } . . fn mk_pending(os: Vec>) -> Vec> { -- line 258 ---------------------------------------- -- line 275 ---------------------------------------- . #[inline(always)] . fn process_obligation( . &mut self, . pending_obligation: &mut Self::Obligation, . ) -> ProcessResult { . // If we were stalled on some unresolved variables, first check whether . // any of them have been resolved; if not, don't bother doing more work . // yet. 8,729,694 ( 0.05%) let change = match pending_obligation.stalled_on.len() { . // Match arms are in order of frequency, which matters because this . // code is so hot. 1 and 0 dominate; 2+ is fairly rare. . 1 => { 4,237,434 ( 0.03%) let infer_var = pending_obligation.stalled_on[0]; 1,412,478 ( 0.01%) self.selcx.infcx().ty_or_const_infer_var_changed(infer_var) . } . 0 => { . // In this case we haven't changed, but wish to make a change. . true . } . _ => { . // This `for` loop was once a call to `all()`, but this lower-level . // form was a perf win. See #64545 for details. 72,387 ( 0.00%) (|| { 142,530 ( 0.00%) for &infer_var in &pending_obligation.stalled_on { 42,140 ( 0.00%) if self.selcx.infcx().ty_or_const_infer_var_changed(infer_var) { . return true; . } . } . false . })() . } . }; . 1,038 ( 0.00%) if !change { . debug!( . "process_predicate: pending obligation {:?} still stalled on {:?}", . self.selcx.infcx().resolve_vars_if_possible(pending_obligation.obligation.clone()), . pending_obligation.stalled_on . ); . return ProcessResult::Unchanged; . } . 179,115 ( 0.00%) self.progress_changed_obligations(pending_obligation) . } . 98 ( 0.00%) fn process_backedge<'c, I>( . &mut self, . cycle: I, . _marker: PhantomData<&'c PendingPredicateObligation<'tcx>>, . ) where . I: Clone + Iterator>, . { 14 ( 0.00%) if self.selcx.coinductive_match(cycle.clone().map(|s| s.obligation.predicate)) { . debug!("process_child_obligations: coinductive match"); . } else { . let cycle: Vec<_> = cycle.map(|c| c.obligation.clone()).collect(); . self.selcx.infcx().report_overflow_error_cycle(&cycle); . } 112 ( 0.00%) } . } . . impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { . // The code calling this method is extremely hot and only rarely . // actually uses this, so move this part of the code . // out of that loop. . #[inline(never)] 597,050 ( 0.00%) fn progress_changed_obligations( . &mut self, . pending_obligation: &mut PendingPredicateObligation<'tcx>, . ) -> ProcessResult, FulfillmentErrorCode<'tcx>> { . pending_obligation.stalled_on.truncate(0); . . let obligation = &mut pending_obligation.obligation; . 179,115 ( 0.00%) if obligation.predicate.has_infer_types_or_consts() { 52,981 ( 0.00%) obligation.predicate = 158,943 ( 0.00%) self.selcx.infcx().resolve_vars_if_possible(obligation.predicate); . } . . debug!(?obligation, ?obligation.cause, "process_obligation"); . . let infcx = self.selcx.infcx(); . 13,448 ( 0.00%) let binder = obligation.predicate.kind(); 417,935 ( 0.00%) match binder.no_bound_vars() { 198 ( 0.00%) None => match binder.skip_binder() { . // Evaluation will discard candidates using the leak check. . // This means we need to pass it the bound version of our . // predicate. . ty::PredicateKind::Trait(trait_ref) => { . let trait_obligation = obligation.with(binder.rebind(trait_ref)); . 36 ( 0.00%) self.process_trait_obligation( . obligation, 108 ( 0.00%) trait_obligation, . &mut pending_obligation.stalled_on, . ) . } . ty::PredicateKind::Projection(data) => { . let project_obligation = obligation.with(binder.rebind(data)); . 36 ( 0.00%) self.process_projection_obligation( . obligation, 108 ( 0.00%) project_obligation, . &mut pending_obligation.stalled_on, . ) . } . ty::PredicateKind::RegionOutlives(_) . | ty::PredicateKind::TypeOutlives(_) . | ty::PredicateKind::WellFormed(_) . | ty::PredicateKind::ObjectSafe(_) . | ty::PredicateKind::ClosureKind(..) -- line 386 ---------------------------------------- -- line 397 ---------------------------------------- . ty::PredicateKind::TypeWellFormedFromEnv(..) => { . bug!("TypeWellFormedFromEnv is only used for Chalk") . } . }, . Some(pred) => match pred { . ty::PredicateKind::Trait(data) => { . let trait_obligation = obligation.with(Binder::dummy(data)); . 163,115 ( 0.00%) self.process_trait_obligation( . obligation, 717,706 ( 0.00%) trait_obligation, . &mut pending_obligation.stalled_on, . ) . } . . ty::PredicateKind::RegionOutlives(data) => { 180 ( 0.00%) match infcx.region_outlives_predicate(&obligation.cause, Binder::dummy(data)) { 120 ( 0.00%) Ok(()) => ProcessResult::Changed(vec![]), . Err(_) => ProcessResult::Error(CodeSelectionError(Unimplemented)), . } . } . . ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(t_a, r_b)) => { 8,270 ( 0.00%) if self.register_region_obligations { 20,675 ( 0.00%) self.selcx.infcx().register_region_obligation_with_cause( . t_a, . r_b, . &obligation.cause, . ); . } . ProcessResult::Changed(vec![]) . } . . ty::PredicateKind::Projection(ref data) => { . let project_obligation = obligation.with(Binder::dummy(*data)); . 30,185 ( 0.00%) self.process_projection_obligation( . obligation, 90,555 ( 0.00%) project_obligation, . &mut pending_obligation.stalled_on, . ) . } . . ty::PredicateKind::ObjectSafe(trait_def_id) => { . if !self.selcx.tcx().is_object_safe(trait_def_id) { . ProcessResult::Error(CodeSelectionError(Unimplemented)) . } else { . ProcessResult::Changed(vec![]) . } . } . . ty::PredicateKind::ClosureKind(_, closure_substs, kind) => { 174 ( 0.00%) match self.selcx.infcx().closure_kind(closure_substs) { . Some(closure_kind) => { 348 ( 0.00%) if closure_kind.extends(kind) { . ProcessResult::Changed(vec![]) . } else { . ProcessResult::Error(CodeSelectionError(Unimplemented)) . } . } . None => ProcessResult::Unchanged, . } . } . . ty::PredicateKind::WellFormed(arg) => { 116,200 ( 0.00%) match wf::obligations( . self.selcx.infcx(), 33,200 ( 0.00%) obligation.param_env, 33,200 ( 0.00%) obligation.cause.body_id, 49,800 ( 0.00%) obligation.recursion_depth + 1, . arg, . obligation.cause.span, . ) { . None => { 22,952 ( 0.00%) pending_obligation.stalled_on = 40,166 ( 0.00%) vec![TyOrConstInferVar::maybe_from_generic_arg(arg).unwrap()]; 11,476 ( 0.00%) ProcessResult::Unchanged . } 32,586 ( 0.00%) Some(os) => ProcessResult::Changed(mk_pending(os)), . } . } . . ty::PredicateKind::Subtype(subtype) => { 616 ( 0.00%) match self.selcx.infcx().subtype_predicate( . &obligation.cause, . obligation.param_env, . Binder::dummy(subtype), . ) { . None => { . // None means that both are unresolved. 385 ( 0.00%) pending_obligation.stalled_on = vec![ 77 ( 0.00%) TyOrConstInferVar::maybe_from_ty(subtype.a).unwrap(), 154 ( 0.00%) TyOrConstInferVar::maybe_from_ty(subtype.b).unwrap(), . ]; . ProcessResult::Unchanged . } . Some(Ok(ok)) => ProcessResult::Changed(mk_pending(ok.obligations)), . Some(Err(err)) => { . let expected_found = . ExpectedFound::new(subtype.a_is_expected, subtype.a, subtype.b); . ProcessResult::Error(FulfillmentErrorCode::CodeSubtypeError( -- line 497 ---------------------------------------- -- line 498 ---------------------------------------- . expected_found, . err, . )) . } . } . } . . ty::PredicateKind::Coerce(coerce) => { 144 ( 0.00%) match self.selcx.infcx().coerce_predicate( . &obligation.cause, . obligation.param_env, . Binder::dummy(coerce), . ) { . None => { . // None means that both are unresolved. 10 ( 0.00%) pending_obligation.stalled_on = vec![ 2 ( 0.00%) TyOrConstInferVar::maybe_from_ty(coerce.a).unwrap(), 4 ( 0.00%) TyOrConstInferVar::maybe_from_ty(coerce.b).unwrap(), . ]; . ProcessResult::Unchanged . } . Some(Ok(ok)) => ProcessResult::Changed(mk_pending(ok.obligations)), . Some(Err(err)) => { . let expected_found = ExpectedFound::new(false, coerce.a, coerce.b); . ProcessResult::Error(FulfillmentErrorCode::CodeSubtypeError( . expected_found, . err, . )) . } . } . } . . ty::PredicateKind::ConstEvaluatable(uv) => { 654 ( 0.00%) match const_evaluatable::is_const_evaluatable( . self.selcx.infcx(), 1,308 ( 0.00%) uv, 218 ( 0.00%) obligation.param_env, 109 ( 0.00%) obligation.cause.span, . ) { . Ok(()) => ProcessResult::Changed(vec![]), . Err(NotConstEvaluatable::MentionsInfer) => { . pending_obligation.stalled_on.clear(); . pending_obligation.stalled_on.extend( . uv.substs . .iter() . .filter_map(TyOrConstInferVar::maybe_from_generic_arg), -- line 543 ---------------------------------------- -- line 639 ---------------------------------------- . } . } . } . ty::PredicateKind::TypeWellFormedFromEnv(..) => { . bug!("TypeWellFormedFromEnv is only used for Chalk") . } . }, . } 537,345 ( 0.00%) } . 620,008 ( 0.00%) #[instrument(level = "debug", skip(self, obligation, stalled_on))] . fn process_trait_obligation( . &mut self, . obligation: &PredicateObligation<'tcx>, . trait_obligation: TraitObligation<'tcx>, . stalled_on: &mut Vec>, . ) -> ProcessResult, FulfillmentErrorCode<'tcx>> { 32,632 ( 0.00%) let infcx = self.selcx.infcx(); 97,896 ( 0.00%) if obligation.predicate.is_global() { . // no type variables present, can use evaluation for better caching. . // FIXME: consider caching errors too. 24,158 ( 0.00%) if infcx.predicate_must_hold_considering_regions(obligation) { . debug!( . "selecting trait at depth {} evaluated to holds", . obligation.recursion_depth . ); 24,144 ( 0.00%) return ProcessResult::Changed(vec![]); . } . } . 143,908 ( 0.00%) match self.selcx.select(&trait_obligation) { . Ok(Some(impl_source)) => { . debug!("selecting trait at depth {} yielded Ok(Some)", obligation.recursion_depth); 118,062 ( 0.00%) ProcessResult::Changed(mk_pending(impl_source.nested_obligations())) . } . Ok(None) => { . debug!("selecting trait at depth {} yielded Ok(None)", obligation.recursion_depth); . . // This is a bit subtle: for the most part, the . // only reason we can fail to make progress on . // trait selection is because we don't have enough . // information about the types in the trait. . stalled_on.clear(); . stalled_on.extend(substs_infer_vars( . self.selcx, 13,995 ( 0.00%) trait_obligation.predicate.map_bound(|pred| pred.trait_ref.substs), . )); . . debug!( . "process_predicate: pending obligation {:?} now stalled on {:?}", . infcx.resolve_vars_if_possible(obligation.clone()), . stalled_on . ); . 13,995 ( 0.00%) ProcessResult::Unchanged . } . Err(selection_err) => { . debug!("selecting trait at depth {} yielded Err", obligation.recursion_depth); . 84 ( 0.00%) ProcessResult::Error(CodeSelectionError(selection_err)) . } . } . } . 66,506 ( 0.00%) fn process_projection_obligation( . &mut self, . obligation: &PredicateObligation<'tcx>, . project_obligation: PolyProjectionObligation<'tcx>, . stalled_on: &mut Vec>, . ) -> ProcessResult, FulfillmentErrorCode<'tcx>> { 6,046 ( 0.00%) let tcx = self.selcx.tcx(); . 18,138 ( 0.00%) if obligation.predicate.is_global() { . // no type variables present, can use evaluation for better caching. . // FIXME: consider caching errors too. 3,172 ( 0.00%) if self.selcx.infcx().predicate_must_hold_considering_regions(obligation) { 9,516 ( 0.00%) if let Some(key) = ProjectionCacheKey::from_poly_projection_predicate( . &mut self.selcx, 11,102 ( 0.00%) project_obligation.predicate, . ) { . // If `predicate_must_hold_considering_regions` succeeds, then we've . // evaluated all sub-obligations. We can therefore mark the 'root' . // obligation as complete, and skip evaluating sub-obligations. 9,516 ( 0.00%) self.selcx . .infcx() . .inner . .borrow_mut() . .projection_cache() . .complete(key, EvaluationResult::EvaluatedToOk); . } 3,172 ( 0.00%) return ProcessResult::Changed(vec![]); . } else { . tracing::debug!("Does NOT hold: {:?}", obligation); . } . } . 31,220 ( 0.00%) match project::poly_project_and_unify_type(self.selcx, &project_obligation) { . Ok(Ok(Some(os))) => ProcessResult::Changed(mk_pending(os)), . Ok(Ok(None)) => { . stalled_on.clear(); . stalled_on.extend(substs_infer_vars( . self.selcx, 3,286 ( 0.00%) project_obligation.predicate.map_bound(|pred| pred.projection_ty.substs), . )); 3,286 ( 0.00%) ProcessResult::Unchanged . } . // Let the caller handle the recursion . Ok(Err(project::InProgress)) => ProcessResult::Changed(mk_pending(vec![ . project_obligation.with(project_obligation.predicate.to_predicate(tcx)), . ])), . Err(e) => ProcessResult::Error(CodeProjectionError(e)), . } 48,368 ( 0.00%) } . } . . /// Returns the set of inference variables contained in `substs`. . fn substs_infer_vars<'a, 'tcx>( . selcx: &mut SelectionContext<'a, 'tcx>, . substs: ty::Binder<'tcx, SubstsRef<'tcx>>, . ) -> impl Iterator> { . selcx . .infcx() . .resolve_vars_if_possible(substs) . .skip_binder() // ok because this check doesn't care about regions . .iter() . .filter(|arg| arg.has_infer_types_or_consts()) . .flat_map(|arg| { 93,885 ( 0.00%) let mut walker = arg.walk(); 168,993 ( 0.00%) while let Some(c) = walker.next() { 18,777 ( 0.00%) if !c.has_infer_types_or_consts() { . walker.visited.remove(&c); . walker.skip_current_subtree(); . } . } . walker.visited.into_iter() . }) . .filter_map(TyOrConstInferVar::maybe_from_generic_arg) . } . . fn to_fulfillment_error<'tcx>( . error: Error, FulfillmentErrorCode<'tcx>>, . ) -> FulfillmentError<'tcx> { . let mut iter = error.backtrace.into_iter(); 6 ( 0.00%) let obligation = iter.next().unwrap().obligation; . // The root obligation is the last item in the backtrace - if there's only . // one item, then it's the same as the main obligation . let root_obligation = iter.next_back().map_or_else(|| obligation.clone(), |e| e.obligation); 180 ( 0.00%) FulfillmentError::new(obligation, error.error, root_obligation) . } 6,404,637 ( 0.04%) -------------------------------------------------------------------------------- -- Auto-annotated source: /usr/home/liquid/rust/worktree-benchmarking/library/core/src/str/lossy.rs -------------------------------------------------------------------------------- Ir -- line 8 ---------------------------------------- . /// Lossy UTF-8 string. . #[unstable(feature = "str_internals", issue = "none")] . pub struct Utf8Lossy { . bytes: [u8], . } . . impl Utf8Lossy { . #[must_use] 188,552 ( 0.00%) pub fn from_bytes(bytes: &[u8]) -> &Utf8Lossy { . // SAFETY: Both use the same memory layout, and UTF-8 correctness isn't required. . unsafe { mem::transmute(bytes) } 94,276 ( 0.00%) } . 188,546 ( 0.00%) pub fn chunks(&self) -> Utf8LossyChunksIter<'_> { . Utf8LossyChunksIter { source: &self.bytes } 94,273 ( 0.00%) } . } . . /// Iterator over lossy UTF-8 string . #[must_use = "iterators are lazy and do nothing unless consumed"] . #[unstable(feature = "str_internals", issue = "none")] . #[allow(missing_debug_implementations)] . pub struct Utf8LossyChunksIter<'a> { . source: &'a [u8], -- line 31 ---------------------------------------- -- line 40 ---------------------------------------- . /// Single broken char, empty if none. . /// Empty iff iterator item is last. . pub broken: &'a [u8], . } . . impl<'a> Iterator for Utf8LossyChunksIter<'a> { . type Item = Utf8LossyChunk<'a>; . 282,828 ( 0.00%) fn next(&mut self) -> Option> { 188,552 ( 0.00%) if self.source.is_empty() { . return None; . } . . const TAG_CONT_U8: u8 = 128; . fn safe_get(xs: &[u8], i: usize) -> u8 { . *xs.get(i).unwrap_or(&0) . } . . let mut i = 0; . let mut valid_up_to = 0; 4,764,672 ( 0.03%) while i < self.source.len() { . // SAFETY: `i < self.source.len()` per previous line. . // For some reason the following are both significantly slower: . // while let Some(&byte) = self.source.get(i) { . // while let Some(byte) = self.source.get(i).copied() { 2,382,336 ( 0.01%) let byte = unsafe { *self.source.get_unchecked(i) }; 2,382,336 ( 0.01%) i += 1; . 4,764,672 ( 0.03%) if byte < 128 { . // This could be a `1 => ...` case in the match below, but for . // the common case of all-ASCII inputs, we bypass loading the . // sizeable UTF8_CHAR_WIDTH table into cache. . } else { . let w = utf8_char_width(byte); . . match w { . 2 => { -- line 76 ---------------------------------------- -- line 121 ---------------------------------------- . // via `i += 1` and in between every single one of those increments, `i` . // is compared against `self.source.len()`. That happens either . // literally by `i < self.source.len()` in the while-loop's condition, . // or indirectly by `safe_get(self.source, i) & 192 != TAG_CONT_U8`. The . // loop is terminated as soon as the latest `i += 1` has made `i` no . // longer less than `self.source.len()`, which means it'll be at most . // equal to `self.source.len()`. . let (inspected, remaining) = unsafe { self.source.split_at_unchecked(i) }; 188,552 ( 0.00%) self.source = remaining; . . // SAFETY: `valid_up_to <= i` because it is only ever assigned via . // `valid_up_to = i` and `i` only increases. . let (valid, broken) = unsafe { inspected.split_at_unchecked(valid_up_to) }; . 471,380 ( 0.00%) Some(Utf8LossyChunk { . // SAFETY: All bytes up to `valid_up_to` are valid UTF-8. . valid: unsafe { from_utf8_unchecked(valid) }, . broken, . }) 471,380 ( 0.00%) } . } . . impl fmt::Display for Utf8Lossy { 24 ( 0.00%) fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { . // If we're the empty string then our iterator won't actually yield . // anything, so perform the formatting manually 3 ( 0.00%) if self.bytes.is_empty() { . return "".fmt(f); . } . 33 ( 0.00%) for Utf8LossyChunk { valid, broken } in self.chunks() { . // If we successfully decoded the whole chunk as a valid string then . // we can return a direct formatting of the string which will also . // respect various formatting flags if possible. 6 ( 0.00%) if valid.len() == self.bytes.len() { 3 ( 0.00%) assert!(broken.is_empty()); . return valid.fmt(f); . } . . f.write_str(valid)?; . if !broken.is_empty() { . f.write_char(char::REPLACEMENT_CHARACTER)?; . } . } . Ok(()) 27 ( 0.00%) } . } . . impl fmt::Debug for Utf8Lossy { . fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { . f.write_char('"')?; . . for Utf8LossyChunk { valid, broken } in self.chunks() { . // Valid part. -- line 174 ---------------------------------------- 2,853,725 ( 0.02%) -------------------------------------------------------------------------------- -- Auto-annotated source: /usr/home/liquid/rust/worktree-benchmarking/compiler/rustc_data_structures/src/obligation_forest/mod.rs -------------------------------------------------------------------------------- Ir -- line 121 ---------------------------------------- . #[derive(Debug)] . pub enum ProcessResult { . Unchanged, . Changed(Vec), . Error(E), . } . . #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] 39,880 ( 0.00%) struct ObligationTreeId(usize); . . type ObligationTreeIdGenerator = . std::iter::Map, fn(usize) -> ObligationTreeId>; . . pub struct ObligationForest { . /// The list of obligations. In between calls to `process_obligations`, . /// this list only contains nodes in the `Pending` or `Waiting` state. . /// -- line 137 ---------------------------------------- -- line 181 ---------------------------------------- . has_parent: bool, . . /// Identifier of the obligation tree to which this node belongs. . obligation_tree_id: ObligationTreeId, . } . . impl Node { . fn new(parent: Option, obligation: O, obligation_tree_id: ObligationTreeId) -> Node { 586,944 ( 0.00%) Node { . obligation, . state: Cell::new(NodeState::Pending), 86,916 ( 0.00%) dependents: if let Some(parent_index) = parent { vec![parent_index] } else { vec![] }, . has_parent: parent.is_some(), . obligation_tree_id, . } . } . } . . /// The state of one node in some tree within the forest. This represents the . /// current state of processing for the obligation (of type `O`) associated -- line 200 ---------------------------------------- -- line 223 ---------------------------------------- . /// | compress() . /// v . /// (Removed) . /// ``` . /// The `Error` state can be introduced in several places, via `error_at()`. . /// . /// Outside of `ObligationForest` methods, nodes should be either `Pending` or . /// `Waiting`. 3,209,507 ( 0.02%) #[derive(Debug, Copy, Clone, PartialEq, Eq)] . enum NodeState { . /// This obligation has not yet been selected successfully. Cannot have . /// subobligations. . Pending, . . /// This obligation was selected successfully, but may or may not have . /// subobligations. . Success, -- line 239 ---------------------------------------- -- line 279 ---------------------------------------- . pub stalled: bool, . } . . impl OutcomeTrait for Outcome { . type Error = Error; . type Obligation = O; . . fn new() -> Self { 64,620 ( 0.00%) Self { stalled: true, errors: vec![] } . } . . fn mark_not_stalled(&mut self) { 36,607 ( 0.00%) self.stalled = false; . } . . fn is_stalled(&self) -> bool { 21,396 ( 0.00%) self.stalled . } . . fn record_completed(&mut self, _outcome: &Self::Obligation) { . // do nothing . } . . fn record_error(&mut self, error: Self::Error) { 96 ( 0.00%) self.errors.push(error) . } . } . . #[derive(Debug, PartialEq, Eq)] . pub struct Error { . pub error: E, . pub backtrace: Vec, . } . . impl ObligationForest { 6,522 ( 0.00%) pub fn new() -> ObligationForest { 78,264 ( 0.00%) ObligationForest { . nodes: vec![], . done_cache: Default::default(), . active_cache: Default::default(), . reused_node_vec: vec![], . obligation_tree_id_generator: (0..).map(ObligationTreeId), . error_cache: Default::default(), . } 6,522 ( 0.00%) } . . /// Returns the total number of nodes in the forest that have not . /// yet been fully resolved. . pub fn len(&self) -> usize { . self.nodes.len() . } . . /// Registers an obligation. . pub fn register_obligation(&mut self, obligation: O) { . // Ignore errors here - there is no guarantee of success. 507,910 ( 0.00%) let _ = self.register_obligation_at(obligation, None); . } . . // Returns Err(()) if we already know this obligation failed. 702,350 ( 0.00%) fn register_obligation_at(&mut self, obligation: O, parent: Option) -> Result<(), ()> { 127,700 ( 0.00%) let cache_key = obligation.as_cache_key(); 127,700 ( 0.00%) if self.done_cache.contains(&cache_key) { . debug!("register_obligation_at: ignoring already done obligation: {:?}", obligation); . return Ok(()); . } . 225,642 ( 0.00%) match self.active_cache.entry(cache_key) { . Entry::Occupied(o) => { 1,846 ( 0.00%) let node = &mut self.nodes[*o.get()]; 1,846 ( 0.00%) if let Some(parent_index) = parent { . // If the node is already in `active_cache`, it has already . // had its chance to be marked with a parent. So if it's . // not already present, just dump `parent` into the . // dependents as a non-parent. 750 ( 0.00%) if !node.dependents.contains(&parent_index) { . node.dependents.push(parent_index); . } . } 2,769 ( 0.00%) if let NodeState::Error = node.state.get() { Err(()) } else { Ok(()) } . } 110,052 ( 0.00%) Entry::Vacant(v) => { 220,104 ( 0.00%) let obligation_tree_id = match parent { 33,488 ( 0.00%) Some(parent_index) => self.nodes[parent_index].obligation_tree_id, . None => self.obligation_tree_id_generator.next().unwrap(), . }; . . let already_failed = parent.is_some() . && self . .error_cache . .get(&obligation_tree_id) . .map_or(false, |errors| errors.contains(v.key())); . . if already_failed { . Err(()) . } else { 36,684 ( 0.00%) let new_index = self.nodes.len(); . v.insert(new_index); . self.nodes.push(Node::new(parent, obligation, obligation_tree_id)); . Ok(()) . } . } . } 574,650 ( 0.00%) } . . /// Converts all remaining obligations to the given error. 54,684 ( 0.00%) pub fn to_errors(&mut self, error: E) -> Vec> { . let errors = self . .nodes . .iter() . .enumerate() . .filter(|(_index, node)| node.state.get() == NodeState::Pending) . .map(|(index, _node)| Error { error: error.clone(), backtrace: self.error_at(index) }) . .collect(); . 15,624 ( 0.00%) self.compress(|_| assert!(false)); . errors 46,872 ( 0.00%) } . . /// Returns the set of obligations that are in a pending state. . pub fn map_pending_obligations(&self, f: F) -> Vec

. where . F: Fn(&O) -> P, . { . self.nodes . .iter() . .filter(|node| node.state.get() == NodeState::Pending) . .map(|node| f(&node.obligation)) . .collect() . } . 42 ( 0.00%) fn insert_into_error_cache(&mut self, index: usize) { . let node = &self.nodes[index]; 6 ( 0.00%) self.error_cache 18 ( 0.00%) .entry(node.obligation_tree_id) . .or_default() . .insert(node.obligation.as_cache_key()); 48 ( 0.00%) } . . /// Performs a pass through the obligation list. This must . /// be called in a loop until `outcome.stalled` is false. . /// . /// This _cannot_ be unrolled (presently, at least). . #[inline(never)] 290,790 ( 0.00%) pub fn process_obligations(&mut self, processor: &mut P) -> OUT . where . P: ObligationProcessor, . OUT: OutcomeTrait>, . { . let mut outcome = OUT::new(); . . // Note that the loop body can append new nodes, and those new nodes . // will then be processed by subsequent iterations of the loop. . // . // We can't use an iterator for the loop because `self.nodes` is . // appended to and the borrow checker would complain. We also can't use . // `for index in 0..self.nodes.len() { ... }` because the range would . // be computed with the initial length, and we would miss the appended . // nodes. Therefore we use a `while` loop. . let mut index = 0; 1,530,360 ( 0.01%) while let Some(node) = self.nodes.get_mut(index) { . // `processor.process_obligation` can modify the predicate within . // `node.obligation`, and that predicate is the key used for . // `self.active_cache`. This means that `self.active_cache` can get . // out of sync with `nodes`. It's not very common, but it does . // happen, and code in `compress` has to allow for it. 2,996,100 ( 0.02%) if node.state.get() != NodeState::Pending { 24,759 ( 0.00%) index += 1; . continue; . } . 252,329 ( 0.00%) match processor.process_obligation(&mut node.obligation) { . ProcessResult::Unchanged => { . // No change in state. . } 146,404 ( 0.00%) ProcessResult::Changed(children) => { . // We are not (yet) stalled. . outcome.mark_not_stalled(); . node.state.set(NodeState::Success); . 195,964 ( 0.00%) for child in children { 421,260 ( 0.00%) let st = self.register_obligation_at(child, Some(index)); 49,560 ( 0.00%) if let Err(()) = st { . // Error already reported - propagate it . // to our node. . self.error_at(index); . } . } . } . ProcessResult::Error(err) => { . outcome.mark_not_stalled(); 198 ( 0.00%) outcome.record_error(Error { error: err, backtrace: self.error_at(index) }); . } . } 2,946,582 ( 0.02%) index += 1; . } . . // There's no need to perform marking, cycle processing and compression when nothing . // changed. 21,396 ( 0.00%) if !outcome.is_stalled() { . self.mark_successes(); . self.process_cycles(processor); 16,752 ( 0.00%) self.compress(|obl| outcome.record_completed(obl)); . } . . outcome 290,790 ( 0.00%) } . . /// Returns a vector of obligations for `p` and all of its . /// ancestors, putting them into the error state in the process. 42 ( 0.00%) fn error_at(&self, mut index: usize) -> Vec { . let mut error_stack: Vec = vec![]; . let mut trace = vec![]; . . loop { . let node = &self.nodes[index]; 6 ( 0.00%) node.state.set(NodeState::Error); . trace.push(node.obligation.clone()); 12 ( 0.00%) if node.has_parent { . // The first dependent is the parent, which is treated . // specially. . error_stack.extend(node.dependents.iter().skip(1)); . index = node.dependents[0]; . } else { . // No parent; treat all dependents non-specially. . error_stack.extend(node.dependents.iter()); . break; -- line 504 ---------------------------------------- -- line 509 ---------------------------------------- . let node = &self.nodes[index]; . if node.state.get() != NodeState::Error { . node.state.set(NodeState::Error); . error_stack.extend(node.dependents.iter()); . } . } . . trace 48 ( 0.00%) } . . /// Mark all `Waiting` nodes as `Success`, except those that depend on a . /// pending node. . fn mark_successes(&self) { . // Convert all `Waiting` nodes to `Success`. . for node in &self.nodes { 650,892 ( 0.00%) if node.state.get() == NodeState::Waiting { . node.state.set(NodeState::Success); . } . } . . // Convert `Success` nodes that depend on a pending node back to . // `Waiting`. . for node in &self.nodes { 547,206 ( 0.00%) if node.state.get() == NodeState::Pending { . // This call site is hot. . self.inlined_mark_dependents_as_waiting(node); . } . } . } . . // This always-inlined function is for the hot call site. . #[inline(always)] . fn inlined_mark_dependents_as_waiting(&self, node: &Node) { 15,870 ( 0.00%) for &index in node.dependents.iter() { . let node = &self.nodes[index]; 15,870 ( 0.00%) let state = node.state.get(); 15,870 ( 0.00%) if state == NodeState::Success { . // This call site is cold. 25,905 ( 0.00%) self.uninlined_mark_dependents_as_waiting(node); . } else { . debug_assert!(state == NodeState::Waiting || state == NodeState::Error) . } . } . } . . // This never-inlined function is for the cold call site. . #[inline(never)] 60,445 ( 0.00%) fn uninlined_mark_dependents_as_waiting(&self, node: &Node) { . // Mark node Waiting in the cold uninlined code instead of the hot inlined . node.state.set(NodeState::Waiting); . self.inlined_mark_dependents_as_waiting(node) 69,080 ( 0.00%) } . . /// Report cycles between all `Success` nodes, and convert all `Success` . /// nodes to `Done`. This must be called after `mark_successes`. . fn process_cycles

(&mut self, processor: &mut P) . where . P: ObligationProcessor, . { 8,376 ( 0.00%) let mut stack = std::mem::take(&mut self.reused_node_vec); . for (index, node) in self.nodes.iter().enumerate() { . // For some benchmarks this state test is extremely hot. It's a win . // to handle the no-op cases immediately to avoid the cost of the . // function call. 547,206 ( 0.00%) if node.state.get() == NodeState::Success { 182,675 ( 0.00%) self.find_cycles_from_node(&mut stack, processor, index); . } . } . . debug_assert!(stack.is_empty()); 67,008 ( 0.00%) self.reused_node_vec = stack; . } . 481,248 ( 0.00%) fn find_cycles_from_node

(&self, stack: &mut Vec, processor: &mut P, index: usize) . where . P: ObligationProcessor, . { . let node = &self.nodes[index]; 106,944 ( 0.00%) if node.state.get() == NodeState::Success { 160 ( 0.00%) match stack.iter().rposition(|&n| n == index) { . None => { . stack.push(index); 16,937 ( 0.00%) for &dep_index in node.dependents.iter() { 67,748 ( 0.00%) self.find_cycles_from_node(stack, processor, dep_index); . } . stack.pop(); . node.state.set(NodeState::Done); . } . Some(rpos) => { . // Cycle detected. 42 ( 0.00%) processor.process_backedge( . stack[rpos..].iter().map(|&i| &self.nodes[i].obligation), . PhantomData, . ); . } . } . } 427,776 ( 0.00%) } . . /// Compresses the vector, removing all popped nodes. This adjusts the . /// indices and hence invalidates any outstanding indices. `process_cycles` . /// must be run beforehand to remove any cycles on `Success` nodes. . #[inline(never)] 121,692 ( 0.00%) fn compress(&mut self, mut outcome_cb: impl FnMut(&O)) { 16,188 ( 0.00%) let orig_nodes_len = self.nodes.len(); . let mut node_rewrites: Vec<_> = std::mem::take(&mut self.reused_node_vec); . debug_assert!(node_rewrites.is_empty()); . node_rewrites.extend(0..orig_nodes_len); . let mut dead_nodes = 0; . . // Move removable nodes to the end, preserving the order of the . // remaining nodes. . // . // LOOP INVARIANT: . // self.nodes[0..index - dead_nodes] are the first remaining nodes . // self.nodes[index - dead_nodes..index] are all dead . // self.nodes[index..] are unchanged . for index in 0..orig_nodes_len { . let node = &self.nodes[index]; 2,769,534 ( 0.02%) match node.state.get() { . NodeState::Pending | NodeState::Waiting => { 1,021,198 ( 0.01%) if dead_nodes > 0 { 263,937 ( 0.00%) self.nodes.swap(index, index - dead_nodes); 439,895 ( 0.00%) node_rewrites[index] -= dead_nodes; . } . } . NodeState::Done => { . // This lookup can fail because the contents of . // `self.active_cache` are not guaranteed to match those of . // `self.nodes`. See the comment in `process_obligation` . // for more details. 124,002 ( 0.00%) if let Some((predicate, _)) = 109,803 ( 0.00%) self.active_cache.remove_entry(&node.obligation.as_cache_key()) . { . self.done_cache.insert(predicate); . } else { . self.done_cache.insert(node.obligation.as_cache_key().clone()); . } . // Extract the success stories. . outcome_cb(&node.obligation); 73,202 ( 0.00%) node_rewrites[index] = orig_nodes_len; 73,202 ( 0.00%) dead_nodes += 1; . } . NodeState::Error => { . // We *intentionally* remove the node from the cache at this point. Otherwise . // tests must come up with a different type on every type error they . // check against. 18 ( 0.00%) self.active_cache.remove(&node.obligation.as_cache_key()); 12 ( 0.00%) self.insert_into_error_cache(index); 12 ( 0.00%) node_rewrites[index] = orig_nodes_len; 12 ( 0.00%) dead_nodes += 1; . } . NodeState::Success => unreachable!(), . } . } . . if dead_nodes > 0 { . // Remove the dead nodes and rewrite indices. 13,544 ( 0.00%) self.nodes.truncate(orig_nodes_len - dead_nodes); 6,772 ( 0.00%) self.apply_rewrites(&node_rewrites); . } . . node_rewrites.truncate(0); 64,752 ( 0.00%) self.reused_node_vec = node_rewrites; 129,504 ( 0.00%) } . . #[inline(never)] 60,948 ( 0.00%) fn apply_rewrites(&mut self, node_rewrites: &[usize]) { . let orig_nodes_len = node_rewrites.len(); . . for node in &mut self.nodes { . let mut i = 0; 430,285 ( 0.00%) while let Some(dependent) = node.dependents.get_mut(i) { 46,040 ( 0.00%) let new_index = node_rewrites[*dependent]; 23,020 ( 0.00%) if new_index >= orig_nodes_len { . node.dependents.swap_remove(i); . if i == 0 && node.has_parent { . // We just removed the parent. . node.has_parent = false; . } . } else { 11,510 ( 0.00%) *dependent = new_index; 23,020 ( 0.00%) i += 1; . } . } . } . . // This updating of `self.active_cache` is necessary because the . // removal of nodes within `compress` can fail. See above. . self.active_cache.retain(|_predicate, index| { 1,764,708 ( 0.01%) let new_index = node_rewrites[*index]; 882,354 ( 0.01%) if new_index >= orig_nodes_len { . false . } else { 418,775 ( 0.00%) *index = new_index; . true . } . }); 54,176 ( 0.00%) } . } 3,853,510 ( 0.02%) -------------------------------------------------------------------------------- The following files chosen for auto-annotation could not be found: -------------------------------------------------------------------------------- ./malloc/malloc.c ./stdlib/msort.c ./string/../sysdeps/x86_64/multiarch/memcmp-avx2-movbe.S ./string/../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S ./string/../sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S /tmp/gcc-build/x86_64-unknown-linux-gnu/libstdc++-v3/libsupc++/../../../../gcc-5.5.0/libstdc++-v3/libsupc++/new_op.cc -------------------------------------------------------------------------------- Ir -------------------------------------------------------------------------------- 130,377,374 ( 0.81%) events annotated