//===- lib/CodeGen/MachineTraceMetrics.h - Super-scalar metrics -*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file defines the interface for the MachineTraceMetrics analysis pass // that estimates CPU resource usage and critical data dependency paths through // preferred traces. This is useful for super-scalar CPUs where execution speed // can be limited both by data dependencies and by limited execution resources. // // Out-of-order CPUs will often be executing instructions from multiple basic // blocks at the same time. This makes it difficult to estimate the resource // usage accurately in a single basic block. Resources can be estimated better // by looking at a trace through the current basic block. // // For every block, the MachineTraceMetrics pass will pick a preferred trace // that passes through the block. The trace is chosen based on loop structure, // branch probabilities, and resource usage. The intention is to pick likely // traces that would be the most affected by code transformations. // // It is expensive to compute a full arbitrary trace for every block, so to // save some computations, traces are chosen to be convergent. This means that // if the traces through basic blocks A and B ever cross when moving away from // A and B, they never diverge again. This applies in both directions - If the // traces meet above A and B, they won't diverge when going further back. // // Traces tend to align with loops. The trace through a block in an inner loop // will begin at the loop entry block and end at a back edge. If there are // nested loops, the trace may begin and end at those instead. // // For each trace, we compute the critical path length, which is the number of // cycles required to execute the trace when execution is limited by data // dependencies only. We also compute the resource height, which is the number // of cycles required to execute all instructions in the trace when ignoring // data dependencies. // // Every instruction in the current block has a slack - the number of cycles // execution of the instruction can be delayed without extending the critical // path. // //===----------------------------------------------------------------------===// #ifndef LLVM_CODEGEN_MACHINETRACEMETRICS_H #define LLVM_CODEGEN_MACHINETRACEMETRICS_H #include "llvm/ADT/SparseSet.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/TargetSchedule.h" namespace llvm { class AnalysisUsage; class MachineFunction; class MachineInstr; class MachineLoop; class MachineLoopInfo; class MachineRegisterInfo; struct MCSchedClassDesc; class raw_ostream; class TargetInstrInfo; class TargetRegisterInfo; // Keep track of physreg data dependencies by recording each live register unit. // Associate each regunit with an instruction operand. Depending on the // direction instructions are scanned, it could be the operand that defined the // regunit, or the highest operand to read the regunit. struct LiveRegUnit { … }; /// Strategies for selecting traces. enum class MachineTraceStrategy { … }; class MachineTraceMetrics : public MachineFunctionPass { … }; inline raw_ostream &operator<<(raw_ostream &OS, const MachineTraceMetrics::Trace &Tr) { … } inline raw_ostream &operator<<(raw_ostream &OS, const MachineTraceMetrics::Ensemble &En) { … } } // end namespace llvm #endif // LLVM_CODEGEN_MACHINETRACEMETRICS_H