Index: llvm/lib/Analysis/InlineCost.cpp =================================================================== --- llvm/lib/Analysis/InlineCost.cpp +++ llvm/lib/Analysis/InlineCost.cpp @@ -27,6 +27,7 @@ #include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/Config/llvm-config.h" +#include "llvm/IR/AssemblyAnnotationWriter.h" #include "llvm/IR/CallingConv.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/Dominators.h" @@ -38,6 +39,7 @@ #include "llvm/IR/PatternMatch.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/FormattedStream.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -46,6 +48,9 @@ STATISTIC(NumCallsAnalyzed, "Number of call sites analyzed"); +static cl::opt EnableCostAnnotationWriter("print-cost-annotation-writer", + cl::Hidden, cl::init(false)); + static cl::opt InlineThreshold( "inline-threshold", cl::Hidden, cl::init(225), cl::ZeroOrMore, cl::desc("Control the amount of inlining to perform (default = 225)")); @@ -94,10 +99,23 @@ namespace { +class CostAnnotationWriter : public AssemblyAnnotationWriter { +public: + // The first value of DenseMap is the instruction with which the following + // pair of Cost and Threshold is associated. + llvm::DenseMap > CostThresholdMap; + + virtual void emitInstructionAnnot(const llvm::Instruction *I, + llvm::formatted_raw_ostream &OS); +}; + class CallAnalyzer : public InstVisitor { typedef InstVisitor Base; friend class InstVisitor; + /// Annotation Writer for cost annotation + CostAnnotationWriter Writer; + /// The TargetTransformInfo available for this compilation. const TargetTransformInfo &TTI; @@ -363,6 +381,17 @@ disableLoadElimination(); } +void CostAnnotationWriter::emitInstructionAnnot( + const Instruction *I, formatted_raw_ostream &OS) { + // The cost of inlining of the given instruction is printed always. + // The threshold delta is printed only when it is non-zero. It happens + // when we decided to give a bonus at a particular instruction. + OS << "; cost = " << CostThresholdMap[I].first; + if (CostThresholdMap[I].second) + OS << ", threshold delta = " << CostThresholdMap[I].second; + OS << "\n"; +} + /// If 'V' maps to a SROA candidate, disable SROA for it. void CallAnalyzer::disableSROA(Value *V) { Value *SROAArg; @@ -1585,12 +1614,20 @@ // instruction. Visit the instructions using our InstVisitor to account for // all of the per-instruction logic. The visit tree returns true if we // consumed the instruction in any way, and false if the instruction's base - // cost should count against inlining. + // cost should count against inlining. The deltas are saved for the + // CostAnnotationWriter. + int InitialCost = getCost(); + int InitialThreshold = getThreshold(); + if (Base::visit(&*I)) ++NumInstructionsSimplified; else addCost(InlineConstants::InstrCost); + if (EnableCostAnnotationWriter) { + Writer.CostThresholdMap[&*I].first = getCost() - InitialCost; + Writer.CostThresholdMap[&*I].second = getThreshold() - InitialThreshold; + } using namespace ore; // If the visit this instruction detected an uninlinable pattern, abort. InlineResult IR; @@ -1943,6 +1980,8 @@ /// Dump stats about this call's analysis. LLVM_DUMP_METHOD void CallAnalyzer::dump() { #define DEBUG_PRINT_STAT(x) dbgs() << " " #x ": " << x << "\n" + if (EnableCostAnnotationWriter) + F.print(dbgs(), &Writer); DEBUG_PRINT_STAT(NumConstantArgs); DEBUG_PRINT_STAT(NumConstantOffsetPtrArgs); DEBUG_PRINT_STAT(NumAllocaArgs);