148c2b03965830c73cdddeae8aea8030f08430137Calin Juravle/* 248c2b03965830c73cdddeae8aea8030f08430137Calin Juravle * Copyright (C) 2014 The Android Open Source Project 348c2b03965830c73cdddeae8aea8030f08430137Calin Juravle * 448c2b03965830c73cdddeae8aea8030f08430137Calin Juravle * Licensed under the Apache License, Version 2.0 (the "License"); 548c2b03965830c73cdddeae8aea8030f08430137Calin Juravle * you may not use this file except in compliance with the License. 648c2b03965830c73cdddeae8aea8030f08430137Calin Juravle * You may obtain a copy of the License at 748c2b03965830c73cdddeae8aea8030f08430137Calin Juravle * 848c2b03965830c73cdddeae8aea8030f08430137Calin Juravle * http://www.apache.org/licenses/LICENSE-2.0 948c2b03965830c73cdddeae8aea8030f08430137Calin Juravle * 1048c2b03965830c73cdddeae8aea8030f08430137Calin Juravle * Unless required by applicable law or agreed to in writing, software 1148c2b03965830c73cdddeae8aea8030f08430137Calin Juravle * distributed under the License is distributed on an "AS IS" BASIS, 1248c2b03965830c73cdddeae8aea8030f08430137Calin Juravle * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1348c2b03965830c73cdddeae8aea8030f08430137Calin Juravle * See the License for the specific language governing permissions and 1448c2b03965830c73cdddeae8aea8030f08430137Calin Juravle * limitations under the License. 1548c2b03965830c73cdddeae8aea8030f08430137Calin Juravle */ 1648c2b03965830c73cdddeae8aea8030f08430137Calin Juravle 1748c2b03965830c73cdddeae8aea8030f08430137Calin Juravle#ifndef ART_COMPILER_OPTIMIZING_OPTIMIZING_COMPILER_STATS_H_ 1848c2b03965830c73cdddeae8aea8030f08430137Calin Juravle#define ART_COMPILER_OPTIMIZING_OPTIMIZING_COMPILER_STATS_H_ 1948c2b03965830c73cdddeae8aea8030f08430137Calin Juravle 20438709f4f2454854f09a3b5c058834bbf772aaa8Vladimir Marko#include <atomic> 21ad543383b5883d6e32993efaefc704eff3225ffeCalin Juravle#include <iomanip> 2248c2b03965830c73cdddeae8aea8030f08430137Calin Juravle#include <string> 23da9badb9edea5e0d18cd9f97eff0d0937ad48310Andreas Gampe#include <type_traits> 2448c2b03965830c73cdddeae8aea8030f08430137Calin Juravle 258f4b056427a9d2321e3aa4f21ca8ffb18b3e5ae6David Sehr#include "base/atomic.h" 268f4b056427a9d2321e3aa4f21ca8ffb18b3e5ae6David Sehr#include "base/globals.h" 2757943810cfc789da890d73621741729da5feaaf8Andreas Gampe#include "base/logging.h" // For VLOG_IS_ON. 2848c2b03965830c73cdddeae8aea8030f08430137Calin Juravle 2948c2b03965830c73cdddeae8aea8030f08430137Calin Juravlenamespace art { 3048c2b03965830c73cdddeae8aea8030f08430137Calin Juravle 31cd09e1f4f9902b82fa62cb2da984ea499e3b2d70Vladimir Markoenum class MethodCompilationStat { 32cd09e1f4f9902b82fa62cb2da984ea499e3b2d70Vladimir Marko kAttemptBytecodeCompilation = 0, 33cd09e1f4f9902b82fa62cb2da984ea499e3b2d70Vladimir Marko kAttemptIntrinsicCompilation, 34cd09e1f4f9902b82fa62cb2da984ea499e3b2d70Vladimir Marko kCompiledNativeStub, 35cd09e1f4f9902b82fa62cb2da984ea499e3b2d70Vladimir Marko kCompiledIntrinsic, 36cd09e1f4f9902b82fa62cb2da984ea499e3b2d70Vladimir Marko kCompiledBytecode, 37063fc772b5b8aed7d769cd7cccb6ddc7619326eeMingyao Yang kCHAInline, 38e53798a7e3267305f696bf658e418c92e63e0834Nicolas Geoffray kInlinedInvoke, 39be10e8e99a78caae01fb65769218800d465144aeVladimir Marko kReplacedInvokeWithSimplePattern, 40702d26018769f9fbc4763c7ed02331aed596ac7dCalin Juravle kInstructionSimplifications, 4144b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames kInstructionSimplificationsArch, 42175dc732c80e6f2afd83209348124df349290ba8Calin Juravle kUnresolvedMethod, 43e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle kUnresolvedField, 4407380a2d6cb9feee02facc81f699eed5cb670cd5Calin Juravle kUnresolvedFieldNotAFastAccess, 45ad543383b5883d6e32993efaefc704eff3225ffeCalin Juravle kRemovedCheckedCast, 46ad543383b5883d6e32993efaefc704eff3225ffeCalin Juravle kRemovedDeadInstruction, 47ad543383b5883d6e32993efaefc704eff3225ffeCalin Juravle kRemovedNullCheck, 4886ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil kNotCompiledSkipped, 4986ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil kNotCompiledInvalidBytecode, 504833f5a1990c76bc2be89504225fb13cca22bedfDavid Brazdil kNotCompiledThrowCatchLoop, 5115693bfdf9fa3ec79327a77b7e10315614d716ccDavid Brazdil kNotCompiledAmbiguousArrayOp, 5248c2b03965830c73cdddeae8aea8030f08430137Calin Juravle kNotCompiledHugeMethod, 5348c2b03965830c73cdddeae8aea8030f08430137Calin Juravle kNotCompiledLargeMethodNoBranches, 542e33525bd4eb892246b4c244c6d4ebf6c6d07501Nicolas Geoffray kNotCompiledMalformedOpcode, 5548c2b03965830c73cdddeae8aea8030f08430137Calin Juravle kNotCompiledNoCodegen, 56702d26018769f9fbc4763c7ed02331aed596ac7dCalin Juravle kNotCompiledPathological, 5736540cb4d549c706cc7cd23086684f1548a91042Nicolas Geoffray kNotCompiledSpaceFilter, 5848c2b03965830c73cdddeae8aea8030f08430137Calin Juravle kNotCompiledUnhandledInstruction, 59702d26018769f9fbc4763c7ed02331aed596ac7dCalin Juravle kNotCompiledUnsupportedIsa, 60ad543383b5883d6e32993efaefc704eff3225ffeCalin Juravle kNotCompiledVerificationError, 61f1c6d9e87cbfd27702103ccc7c7f08ce784dc872Calin Juravle kNotCompiledVerifyAtRuntime, 6273be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray kInlinedMonomorphicCall, 63a42363f79832a6e14f348514664dc6dc3edf9da2Nicolas Geoffray kInlinedPolymorphicCall, 6473be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray kMonomorphicCall, 6573be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray kPolymorphicCall, 6673be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray kMegamorphicCall, 6738e9e8046ea2196284bdb4638771c31108a30a4aJean-Philippe Halimi kBooleanSimplified, 6838e9e8046ea2196284bdb4638771c31108a30a4aJean-Philippe Halimi kIntrinsicRecognized, 6938e9e8046ea2196284bdb4638771c31108a30a4aJean-Philippe Halimi kLoopInvariantMoved, 7021b859210d690d25563423eeed5fd630023d23ccAart Bik kLoopVectorized, 7121b859210d690d25563423eeed5fd630023d23ccAart Bik kLoopVectorizedIdiom, 7238e9e8046ea2196284bdb4638771c31108a30a4aJean-Philippe Halimi kSelectGenerated, 736915898b28cea6c9836ca1be6814d87e89cc6d76Calin Juravle kRemovedInstanceOf, 746915898b28cea6c9836ca1be6814d87e89cc6d76Calin Juravle kInlinedInvokeVirtualOrInterface, 752ae48182573da7087bffc2873730bc758ec29696Calin Juravle kImplicitNullCheckGenerated, 762ae48182573da7087bffc2873730bc758ec29696Calin Juravle kExplicitNullCheckGenerated, 77dac9b19b822e6cc6f1d7f40e27780515d1fddf22Nicolas Geoffray kSimplifyIf, 78a8b8e9b12a9740d71cff2fa65d47825b74f72c37Aart Bik kSimplifyThrowingInvoke, 79b813ca14be33f7db8b7049c3b08a1eb776f25d1bNicolas Geoffray kInstructionSunk, 80f6d4668c42933e2f85ddbc94e276c49db4e2b1ddNicolas Geoffray kNotInlinedUnresolvedEntrypoint, 81f6d4668c42933e2f85ddbc94e276c49db4e2b1ddNicolas Geoffray kNotInlinedDexCache, 82f6d4668c42933e2f85ddbc94e276c49db4e2b1ddNicolas Geoffray kNotInlinedStackMaps, 83f6d4668c42933e2f85ddbc94e276c49db4e2b1ddNicolas Geoffray kNotInlinedEnvironmentBudget, 84f6d4668c42933e2f85ddbc94e276c49db4e2b1ddNicolas Geoffray kNotInlinedInstructionBudget, 85f6d4668c42933e2f85ddbc94e276c49db4e2b1ddNicolas Geoffray kNotInlinedLoopWithoutExit, 86f6d4668c42933e2f85ddbc94e276c49db4e2b1ddNicolas Geoffray kNotInlinedIrreducibleLoop, 87f6d4668c42933e2f85ddbc94e276c49db4e2b1ddNicolas Geoffray kNotInlinedAlwaysThrows, 88f6d4668c42933e2f85ddbc94e276c49db4e2b1ddNicolas Geoffray kNotInlinedInfiniteLoop, 89f6d4668c42933e2f85ddbc94e276c49db4e2b1ddNicolas Geoffray kNotInlinedTryCatch, 90f6d4668c42933e2f85ddbc94e276c49db4e2b1ddNicolas Geoffray kNotInlinedRegisterAllocator, 91f6d4668c42933e2f85ddbc94e276c49db4e2b1ddNicolas Geoffray kNotInlinedCannotBuild, 92f6d4668c42933e2f85ddbc94e276c49db4e2b1ddNicolas Geoffray kNotInlinedNotVerified, 93f6d4668c42933e2f85ddbc94e276c49db4e2b1ddNicolas Geoffray kNotInlinedCodeItem, 94f6d4668c42933e2f85ddbc94e276c49db4e2b1ddNicolas Geoffray kNotInlinedWont, 95f6d4668c42933e2f85ddbc94e276c49db4e2b1ddNicolas Geoffray kNotInlinedRecursiveBudget, 96f6d4668c42933e2f85ddbc94e276c49db4e2b1ddNicolas Geoffray kNotInlinedProxy, 976ef45677305048c2bf0600f1c4b98a11b2cfaffbIgor Murashkin kConstructorFenceGeneratedNew, 986ef45677305048c2bf0600f1c4b98a11b2cfaffbIgor Murashkin kConstructorFenceGeneratedFinal, 996ef45677305048c2bf0600f1c4b98a11b2cfaffbIgor Murashkin kConstructorFenceRemovedLSE, 1006ef45677305048c2bf0600f1c4b98a11b2cfaffbIgor Murashkin kConstructorFenceRemovedPFRA, 101dd018df8a00e841fe38fabe38520b7d297a885c1Igor Murashkin kConstructorFenceRemovedCFRE, 102cd09e1f4f9902b82fa62cb2da984ea499e3b2d70Vladimir Marko kJitOutOfMemoryForCommit, 10348c2b03965830c73cdddeae8aea8030f08430137Calin Juravle kLastStat 10448c2b03965830c73cdddeae8aea8030f08430137Calin Juravle}; 105cd09e1f4f9902b82fa62cb2da984ea499e3b2d70Vladimir Markostd::ostream& operator<<(std::ostream& os, const MethodCompilationStat& rhs); 10648c2b03965830c73cdddeae8aea8030f08430137Calin Juravle 10748c2b03965830c73cdddeae8aea8030f08430137Calin Juravleclass OptimizingCompilerStats { 10848c2b03965830c73cdddeae8aea8030f08430137Calin Juravle public: 109ff754d19946de43bfd2fc04adcd430459cac1f16Vladimir Marko OptimizingCompilerStats() { 110ff754d19946de43bfd2fc04adcd430459cac1f16Vladimir Marko // The std::atomic<> default constructor leaves values uninitialized, so initialize them now. 111ff754d19946de43bfd2fc04adcd430459cac1f16Vladimir Marko Reset(); 112ff754d19946de43bfd2fc04adcd430459cac1f16Vladimir Marko } 11348c2b03965830c73cdddeae8aea8030f08430137Calin Juravle 114438709f4f2454854f09a3b5c058834bbf772aaa8Vladimir Marko void RecordStat(MethodCompilationStat stat, uint32_t count = 1) { 115cd09e1f4f9902b82fa62cb2da984ea499e3b2d70Vladimir Marko size_t stat_index = static_cast<size_t>(stat); 116cd09e1f4f9902b82fa62cb2da984ea499e3b2d70Vladimir Marko DCHECK_LT(stat_index, arraysize(compile_stats_)); 117cd09e1f4f9902b82fa62cb2da984ea499e3b2d70Vladimir Marko compile_stats_[stat_index] += count; 118cd09e1f4f9902b82fa62cb2da984ea499e3b2d70Vladimir Marko } 119cd09e1f4f9902b82fa62cb2da984ea499e3b2d70Vladimir Marko 120cd09e1f4f9902b82fa62cb2da984ea499e3b2d70Vladimir Marko uint32_t GetStat(MethodCompilationStat stat) const { 121cd09e1f4f9902b82fa62cb2da984ea499e3b2d70Vladimir Marko size_t stat_index = static_cast<size_t>(stat); 122cd09e1f4f9902b82fa62cb2da984ea499e3b2d70Vladimir Marko DCHECK_LT(stat_index, arraysize(compile_stats_)); 123cd09e1f4f9902b82fa62cb2da984ea499e3b2d70Vladimir Marko return compile_stats_[stat_index]; 12448c2b03965830c73cdddeae8aea8030f08430137Calin Juravle } 12548c2b03965830c73cdddeae8aea8030f08430137Calin Juravle 12648c2b03965830c73cdddeae8aea8030f08430137Calin Juravle void Log() const { 127ad543383b5883d6e32993efaefc704eff3225ffeCalin Juravle if (!kIsDebugBuild && !VLOG_IS_ON(compiler)) { 128ad543383b5883d6e32993efaefc704eff3225ffeCalin Juravle // Log only in debug builds or if the compiler is verbose. 129ad543383b5883d6e32993efaefc704eff3225ffeCalin Juravle return; 130ad543383b5883d6e32993efaefc704eff3225ffeCalin Juravle } 131ad543383b5883d6e32993efaefc704eff3225ffeCalin Juravle 132cd09e1f4f9902b82fa62cb2da984ea499e3b2d70Vladimir Marko uint32_t compiled_intrinsics = GetStat(MethodCompilationStat::kCompiledIntrinsic); 133cd09e1f4f9902b82fa62cb2da984ea499e3b2d70Vladimir Marko uint32_t compiled_native_stubs = GetStat(MethodCompilationStat::kCompiledNativeStub); 134cd09e1f4f9902b82fa62cb2da984ea499e3b2d70Vladimir Marko uint32_t bytecode_attempts = 135cd09e1f4f9902b82fa62cb2da984ea499e3b2d70Vladimir Marko GetStat(MethodCompilationStat::kAttemptBytecodeCompilation); 136cd09e1f4f9902b82fa62cb2da984ea499e3b2d70Vladimir Marko if (compiled_intrinsics == 0u && compiled_native_stubs == 0u && bytecode_attempts == 0u) { 13748c2b03965830c73cdddeae8aea8030f08430137Calin Juravle LOG(INFO) << "Did not compile any method."; 13848c2b03965830c73cdddeae8aea8030f08430137Calin Juravle } else { 139cd09e1f4f9902b82fa62cb2da984ea499e3b2d70Vladimir Marko uint32_t compiled_bytecode_methods = 140cd09e1f4f9902b82fa62cb2da984ea499e3b2d70Vladimir Marko GetStat(MethodCompilationStat::kCompiledBytecode); 141cd09e1f4f9902b82fa62cb2da984ea499e3b2d70Vladimir Marko // Successful intrinsic compilation preempts other compilation attempts but failed intrinsic 142cd09e1f4f9902b82fa62cb2da984ea499e3b2d70Vladimir Marko // compilation shall still count towards bytecode or native stub compilation attempts. 143cd09e1f4f9902b82fa62cb2da984ea499e3b2d70Vladimir Marko uint32_t num_compilation_attempts = 144cd09e1f4f9902b82fa62cb2da984ea499e3b2d70Vladimir Marko compiled_intrinsics + compiled_native_stubs + bytecode_attempts; 145cd09e1f4f9902b82fa62cb2da984ea499e3b2d70Vladimir Marko uint32_t num_successful_compilations = 146cd09e1f4f9902b82fa62cb2da984ea499e3b2d70Vladimir Marko compiled_intrinsics + compiled_native_stubs + compiled_bytecode_methods; 147cd09e1f4f9902b82fa62cb2da984ea499e3b2d70Vladimir Marko float compiled_percent = num_successful_compilations * 100.0f / num_compilation_attempts; 148cd09e1f4f9902b82fa62cb2da984ea499e3b2d70Vladimir Marko LOG(INFO) << "Attempted compilation of " 149cd09e1f4f9902b82fa62cb2da984ea499e3b2d70Vladimir Marko << num_compilation_attempts << " methods: " << std::fixed << std::setprecision(2) 150cd09e1f4f9902b82fa62cb2da984ea499e3b2d70Vladimir Marko << compiled_percent << "% (" << num_successful_compilations << ") compiled."; 151cd09e1f4f9902b82fa62cb2da984ea499e3b2d70Vladimir Marko 152cd09e1f4f9902b82fa62cb2da984ea499e3b2d70Vladimir Marko for (size_t i = 0; i < arraysize(compile_stats_); ++i) { 15348c2b03965830c73cdddeae8aea8030f08430137Calin Juravle if (compile_stats_[i] != 0) { 154cd09e1f4f9902b82fa62cb2da984ea499e3b2d70Vladimir Marko LOG(INFO) << "OptStat#" << static_cast<MethodCompilationStat>(i) << ": " 155da9badb9edea5e0d18cd9f97eff0d0937ad48310Andreas Gampe << compile_stats_[i]; 15648c2b03965830c73cdddeae8aea8030f08430137Calin Juravle } 15748c2b03965830c73cdddeae8aea8030f08430137Calin Juravle } 15848c2b03965830c73cdddeae8aea8030f08430137Calin Juravle } 15948c2b03965830c73cdddeae8aea8030f08430137Calin Juravle } 16048c2b03965830c73cdddeae8aea8030f08430137Calin Juravle 161438709f4f2454854f09a3b5c058834bbf772aaa8Vladimir Marko void AddTo(OptimizingCompilerStats* other_stats) { 162cd09e1f4f9902b82fa62cb2da984ea499e3b2d70Vladimir Marko for (size_t i = 0; i != arraysize(compile_stats_); ++i) { 163438709f4f2454854f09a3b5c058834bbf772aaa8Vladimir Marko uint32_t count = compile_stats_[i]; 164438709f4f2454854f09a3b5c058834bbf772aaa8Vladimir Marko if (count != 0) { 165438709f4f2454854f09a3b5c058834bbf772aaa8Vladimir Marko other_stats->RecordStat(static_cast<MethodCompilationStat>(i), count); 166438709f4f2454854f09a3b5c058834bbf772aaa8Vladimir Marko } 167438709f4f2454854f09a3b5c058834bbf772aaa8Vladimir Marko } 168438709f4f2454854f09a3b5c058834bbf772aaa8Vladimir Marko } 169438709f4f2454854f09a3b5c058834bbf772aaa8Vladimir Marko 170438709f4f2454854f09a3b5c058834bbf772aaa8Vladimir Marko void Reset() { 171cd09e1f4f9902b82fa62cb2da984ea499e3b2d70Vladimir Marko for (std::atomic<uint32_t>& stat : compile_stats_) { 172cd09e1f4f9902b82fa62cb2da984ea499e3b2d70Vladimir Marko stat = 0u; 173438709f4f2454854f09a3b5c058834bbf772aaa8Vladimir Marko } 174438709f4f2454854f09a3b5c058834bbf772aaa8Vladimir Marko } 175438709f4f2454854f09a3b5c058834bbf772aaa8Vladimir Marko 17648c2b03965830c73cdddeae8aea8030f08430137Calin Juravle private: 177cd09e1f4f9902b82fa62cb2da984ea499e3b2d70Vladimir Marko std::atomic<uint32_t> compile_stats_[static_cast<size_t>(MethodCompilationStat::kLastStat)]; 17848c2b03965830c73cdddeae8aea8030f08430137Calin Juravle 17948c2b03965830c73cdddeae8aea8030f08430137Calin Juravle DISALLOW_COPY_AND_ASSIGN(OptimizingCompilerStats); 18048c2b03965830c73cdddeae8aea8030f08430137Calin Juravle}; 18148c2b03965830c73cdddeae8aea8030f08430137Calin Juravle 1821e065a54845da12541572f4f149e6ab0dcd20180Igor Murashkininline void MaybeRecordStat(OptimizingCompilerStats* compiler_stats, 1831e065a54845da12541572f4f149e6ab0dcd20180Igor Murashkin MethodCompilationStat stat, 1841e065a54845da12541572f4f149e6ab0dcd20180Igor Murashkin uint32_t count = 1) { 1851e065a54845da12541572f4f149e6ab0dcd20180Igor Murashkin if (compiler_stats != nullptr) { 1861e065a54845da12541572f4f149e6ab0dcd20180Igor Murashkin compiler_stats->RecordStat(stat, count); 1871e065a54845da12541572f4f149e6ab0dcd20180Igor Murashkin } 1881e065a54845da12541572f4f149e6ab0dcd20180Igor Murashkin} 1891e065a54845da12541572f4f149e6ab0dcd20180Igor Murashkin 19048c2b03965830c73cdddeae8aea8030f08430137Calin Juravle} // namespace art 19148c2b03965830c73cdddeae8aea8030f08430137Calin Juravle 19248c2b03965830c73cdddeae8aea8030f08430137Calin Juravle#endif // ART_COMPILER_OPTIMIZING_OPTIMIZING_COMPILER_STATS_H_ 193