summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-mca/Instruction.h
Commit message (Collapse)AuthorAgeFilesLines
* [llvm-mca] Introduce the llvm-mca library and organize the directory ↵Matt Davis2018-08-271-449/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | accordingly. NFC. Summary: This patch introduces llvm-mca as a library. The driver (llvm-mca.cpp), views, and stats, are not part of the library. Those are separate components that are not required for the functioning of llvm-mca. The directory has been organized as follows: All library source files now reside in: - `lib/HardwareUnits/` - All subclasses of HardwareUnit (these represent the simulated hardware components of a backend). (LSUnit does not inherit from HardwareUnit, but Scheduler does which uses LSUnit). - `lib/Stages/` - All subclasses of the pipeline stages. - `lib/` - This is the root of the library and contains library code that does not fit into the Stages or HardwareUnit subdirs. All library header files now reside in the `include` directory and mimic the same layout as the `lib` directory mentioned above. In the (near) future we would like to move the library (include and lib) contents from tools and into the core of llvm somewhere. That change would allow various analysis and optimization passes to make use of MCA functionality for things like cost modeling. I left all of the non-library code just where it has always been, in the root of the llvm-mca directory. The include directives for the non-library source file have been updated to refer to the llvm-mca library headers. I updated the llvm-mca/CMakeLists.txt file to include the library headers, but I made the non-library code explicitly reference the library's 'include' directory. Once we eventually (hopefully) migrate the MCA library components into llvm the include directives used by the non-library source files will be updated to point to the proper location in llvm. Reviewers: andreadb, courbet, RKSimon Reviewed By: andreadb Subscribers: mgorny, javed.absar, tschuett, gbedwell, llvm-commits Differential Revision: https://reviews.llvm.org/D50929 llvm-svn: 340755
* [llvm-mca] Replace use of llvm::any_of with std::any_of.Andrea Di Biagio2018-08-211-2/+3
| | | | | | This should unbreak the buildbots. llvm-svn: 340274
* [llvm-mca] Add method cycleEvent() to class Scheduler. NFCIAndrea Di Biagio2018-08-211-3/+16
| | | | | | | | | | | | | | | | | | | | The goal of this patch is to simplify the Scheduler's interface in preparation for D50929. Some methods in the Scheduler's interface should not be exposed to external users, since their presence makes it hard to both understand, and extend the Scheduler's interface. This patch removes the following two methods from the public Scheduler's API: - reclaimSimulatedResources() - updatePendingQueue() Their logic has been migrated to a new method named 'cycleEvent()'. Methods 'updateIssuedSet()' and 'promoteToReadySet()' still exist. However, they are now private members of class Scheduler. This simplifies the interaction with the Scheduler from the ExecuteStage. llvm-svn: 340273
* [llvm-mca] Reformat a few lines (fix spacing). NFC.Matt Davis2018-08-171-3/+1
| | | | llvm-svn: 340065
* [llvm-mca] Speed up the computation of the wait/ready/issued sets in the ↵Andrea Di Biagio2018-08-031-1/+4
| | | | | | | | | | | | | | Scheduler. This patch is a follow-up to r338702. We don't need to use a map to model the wait/ready/issued sets. It is much more efficient to use a vector instead. This patch gives us an average 7.5% speedup (on top of the ~12% speedup obtained after r338702). llvm-svn: 338883
* [llvm-mca][BtVer2] Teach how to identify dependency-breaking idioms.Andrea Di Biagio2018-07-311-3/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This patch teaches llvm-mca how to identify dependency breaking instructions on btver2. An example of dependency breaking instructions is the zero-idiom XOR (example: `XOR %eax, %eax`), which always generates zero regardless of the actual value of the input register operands. Dependency breaking instructions don't have to wait on their input register operands before executing. This is because the computation is not dependent on the inputs. Not all dependency breaking idioms are also zero-latency instructions. For example, `CMPEQ %xmm1, %xmm1` is independent on the value of XMM1, and it generates a vector of all-ones. That instruction is not eliminated at register renaming stage, and its opcode is issued to a pipeline for execution. So, the latency is not zero. This patch adds a new method named isDependencyBreaking() to the MCInstrAnalysis interface. That method takes as input an instruction (i.e. MCInst) and a MCSubtargetInfo. The default implementation of isDependencyBreaking() conservatively returns false for all instructions. Targets may override the default behavior for specific CPUs, and return a value which better matches the subtarget behavior. In future, we should teach to Tablegen how to automatically generate the body of isDependencyBreaking from scheduling predicate definitions. This would allow us to expose the knowledge about dependency breaking instructions to the machine schedulers (and, potentially, other codegen passes). Differential Revision: https://reviews.llvm.org/D49310 llvm-svn: 338372
* [llvm-mca][BtVer2] teach how to identify false dependencies on partially writtenAndrea Di Biagio2018-07-151-1/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | registers. The goal of this patch is to improve the throughput analysis in llvm-mca for the case where instructions perform partial register writes. On x86, partial register writes are quite difficult to model, mainly because different processors tend to implement different register merging schemes in hardware. When the code contains partial register writes, the IPC (instructions per cycles) estimated by llvm-mca tends to diverge quite significantly from the observed IPC (using perf). Modern AMD processors (at least, from Bulldozer onwards) don't rename partial registers. Quoting Agner Fog's microarchitecture.pdf: " The processor always keeps the different parts of an integer register together. For example, AL and AH are not treated as independent by the out-of-order execution mechanism. An instruction that writes to part of a register will therefore have a false dependence on any previous write to the same register or any part of it." This patch is a first important step towards improving the analysis of partial register updates. It changes the semantic of RegisterFile descriptors in tablegen, and teaches llvm-mca how to identify false dependences in the presence of partial register writes (for more details: see the new code comments in include/Target/TargetSchedule.h - class RegisterFile). This patch doesn't address the case where a write to a part of a register is followed by a read from the whole register. On Intel chips, high8 registers (AH/BH/CH/DH)) can be stored in separate physical registers. However, a later (dirty) read of the full register (example: AX/EAX) triggers a merge uOp, which adds extra latency (and potentially affects the pipe usage). This is a very interesting article on the subject with a very informative answer from Peter Cordes: https://stackoverflow.com/questions/45660139/how-exactly-do-partial-registers-on-haswell-skylake-perform-writing-al-seems-to In future, the definition of RegisterFile can be extended with extra information that may be used to identify delays caused by merge opcodes triggered by a dirty read of a partial write. Differential Revision: https://reviews.llvm.org/D49196 llvm-svn: 337123
* [llvm-mca] A write latency cannot be a negative value. NFCAndrea Di Biagio2018-07-061-6/+4
| | | | llvm-svn: 336437
* [llvm-mca] improve the instruction issue logic implemented by the Scheduler.Andrea Di Biagio2018-07-061-1/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | This patch modifies the Scheduler heuristic used to select the next instruction to issue to the pipelines. The motivating example is test X86/BtVer2/add-sequence.s, for which llvm-mca wrongly reported an estimated IPC of 1.50. According to perf, the actual IPC for that test should have been ~2.00. It turns out that an IPC of 2.00 for test add-sequence.s cannot possibly be predicted by a Scheduler that only prioritizes instructions based on their "age". A similar issue also affected test X86/BtVer2/dependent-pmuld-paddd.s, for which llvm-mca wrongly estimated an IPC of 0.84 instead of an IPC of 1.00. Instructions in the ReadyQueue are now ranked based on two factors: - The "age" of an instruction. - The number of unique users of writes associated with an instruction. The new logic still prioritizes older instructions over younger instructions to minimize the pressure on the reorder buffer. However, the number of users of an instruction now also affects the overall rank. This potentially increases the ability of the Scheduler to extract instruction level parallelism. This patch fixes the problem with the wrong IPC reported for test add-sequence.s and test dependent-pmuld-paddd.s. llvm-svn: 336420
* [llvm-mca] Remove field HasReadAdvanceEntries from class ReadDescriptor.Andrea Di Biagio2018-06-291-5/+0
| | | | | | | | | | | | This simplifies the logic that updates RAW dependencies in the DispatchStage. There is no advantage in storing that flag in the ReadDescriptor; we should simply rely on the call to `STI.getReadAdvanceCycles()` to obtain the ReadAdvance cycles. If there are no read-advance entries, then method `getReadAdvanceCycles()` quickly returns 0. No functional change intended. llvm-svn: 335977
* [llvm-mca] Use a WriteRef to describe register writes in class RegisterFile.Andrea Di Biagio2018-06-281-0/+30
| | | | | | | | | | | This patch introduces a new class named WriteRef. A WriteRef is used by the RegisterFile to keep track of register definitions. Internally it wraps a WriteState, as well as the source index of the defining instruction. This patch allows the tool to propagate additional information to support future analysis on data dependencies. llvm-svn: 335867
* [llvm-mca] Avoid calling method update() on instructions that are already in ↵Andrea Di Biagio2018-06-271-7/+9
| | | | | | | | | | the IS_READY state. NFCI When promoting instructions from the wait queue to the ready queue, we should check if an instruction has already reached the IS_READY state before calling method update(). llvm-svn: 335722
* [llvm-mca] Remove unused header files and correctly guard some include ↵Andrea Di Biagio2018-06-261-0/+4
| | | | | | headers under NDEBUG. NFC llvm-svn: 335589
* [llvm-mca] Rename Backend to Pipeline. NFC.Matt Davis2018-06-251-4/+4
| | | | | | | | | | | | | | | | | | Summary: This change renames the Backend and BackendPrinter to Pipeline and PipelinePrinter respectively. Variables and comments have also been updated to reflect this change. The reason for this rename, is to be slightly more correct about what MCA is modeling. MCA models a Pipeline, which implies some logical sequence of stages. Reviewers: andreadb, courbet, RKSimon Reviewed By: andreadb, courbet Subscribers: mgorny, javed.absar, tschuett, gbedwell, llvm-commits Differential Revision: https://reviews.llvm.org/D48496 llvm-svn: 335496
* [llvm-mca] Set the operand ID for implicit register reads/writes. NFCAndrea Di Biagio2018-06-221-32/+39
| | | | | | | Also, move the definition of InstRef at the end of Instruction.h to avoid a forward declaration. llvm-svn: 335363
* [llvm-mca][X86] Teach how to identify register writes that implicitly clear ↵Andrea Di Biagio2018-06-201-8/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | the upper portion of a super-register. This patch teaches llvm-mca how to identify register writes that implicitly zero the upper portion of a super-register. On X86-64, a general purpose register is implemented in hardware as a 64-bit register. Quoting the Intel 64 Software Developer's Manual: "an update to the lower 32 bits of a 64 bit integer register is architecturally defined to zero extend the upper 32 bits". Also, a write to an XMM register performed by an AVX instruction implicitly zeroes the upper 128 bits of the aliasing YMM register. This patch adds a new method named clearsSuperRegisters to the MCInstrAnalysis interface to help identify instructions that implicitly clear the upper portion of a super-register. The rest of the patch teaches llvm-mca how to use that new method to obtain the information, and update the register dependencies accordingly. I compared the kernels from tests clear-super-register-1.s and clear-super-register-2.s against the output from perf on btver2. Previously there was a large discrepancy between the estimated IPC and the measured IPC. Now the differences are mostly in the noise. Differential Revision: https://reviews.llvm.org/D48225 llvm-svn: 335113
* [llvm-mca] Correctly update the CyclesLeft of a register read in the ↵Andrea Di Biagio2018-06-051-0/+11
| | | | | | | | | | | presence of partial register updates. This patch fixe the logic in ReadState::cycleEvent(). That method was not correctly updating field `TotalCycles`. Added extra code comments in class ReadState to better describe each field. llvm-svn: 334028
* [llvm-mca] Introduce a pipeline Stage class and FetchStage.Matt Davis2018-05-151-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: This is just an idea, really two ideas. I expect some push-back, but I realize that posting a diff is the most comprehensive way to express these concepts. This patch introduces a Stage class which represents the various stages of an instruction pipeline. As a start, I have created a simple FetchStage that is based on existing logic for how MCA produces instructions, but now encapsulated in a Stage. The idea should become more concrete once we introduce additional stages. The idea being, that when a stage completes, the next stage in the pipeline will be executed. Stages are chained together as a singly linked list to closely model a real pipeline. For now there is only one stage, so the stage-to-stage flow of instructions isn't immediately obvious. Eventually, Stage will also handle event notifications, but that functionality is not complete, and not destined for this patch. Ideally, an interested party can register for notifications from a particular stage. Callbacks will be issued to these listeners at various points in the execution of the stage. For now, eventing functionality remains similar to what it has been in mca::Backend. We will be building-up the Stage class as we move on, such as adding debug output. This patch also removes the unique_ptr<Instruction> return value from InstrBuilder::createInstruction. An Instruction pointer is still produced, but now it's up to the caller to decide how that item should be managed post-allocation (e.g., smart pointer). This allows the Fetch stage to create instructions and manage the lifetime of those instructions as it wishes, and not have to be bound to any specific managed pointer type. Other callers of createInstruction might have different requirements, and thus can manage the pointer to fit their needs. Another idea would be to push the ownership to the RCU. Currently, the FetchStage will wrap the Instruction pointer in a shared_ptr. This allows us to remove the Instruction container in Backend, which was probably going to disappear, or move, at some point anyways. Note that I did run these changes through valgrind, to make sure we are not leaking memory. While the shared_ptr comes with some additional overhead it relieves us from having to manage a list of generated instructions, and/or make lookup calls to remove the instructions. I realize that both the Stage class and the Instruction pointer management (mentioned directly above) are separate but related ideas, and probably should land as separate patches; I am happy to do that if either idea is decent. The main reason these two ideas are together is that Stage::execute() can mutate an InstRef. For the fetch stage, the InstRef is populated as the primary action of that stage (execute()). I didn't want to change the Stage interface to support the idea of generating an instruction. Ideally, instructions are to be pushed through the pipeline. I didn't want to draw too much of a specialization just for the fetch stage. Excuse the word-salad. Reviewers: andreadb, courbet, RKSimon Reviewed By: andreadb Subscribers: llvm-commits, mgorny, javed.absar, tschuett, gbedwell Differential Revision: https://reviews.llvm.org/D46741 llvm-svn: 332390
* [llvm-mca] Improved support for dependency-breaking instructions.Andrea Di Biagio2018-05-141-0/+3
| | | | | | | | | The tool assumes that a zero-latency instruction that doesn't consume hardware resources is an optimizable dependency-breaking instruction. That means, it doesn't have to wait on register input operands, and it doesn't consume any physical register. The PRF knows how to optimize it at register renaming stage. llvm-svn: 332249
* [llvm-mca] Avoid exposing index values in the MCA interfaces.Matt Davis2018-05-071-0/+31
| | | | | | | | | | | | | | | | | | | | | | | Summary: This patch eliminates many places where we originally needed to pass index values to represent an instruction. The index is still used as a key, in various parts of MCA. I'm not comfortable eliminating the index just yet. By burying the index in the instruction, we can avoid exposing that value in many places. Eventually, we should consider removing the Instructions list in the Backend all together, it's only used to hold and reclaim the memory for the allocated Instruction instances. Instead we could pass around a smart pointer. But that's a separate discussion/patch. Reviewers: andreadb, courbet, RKSimon Reviewed By: andreadb Subscribers: javed.absar, tschuett, gbedwell, llvm-commits Differential Revision: https://reviews.llvm.org/D46367 llvm-svn: 331660
* Remove \brief commands from doxygen comments.Adrian Prantl2018-05-011-7/+7
| | | | | | | | | | | | | | | | We've been running doxygen with the autobrief option for a couple of years now. This makes the \brief markers into our comments redundant. Since they are a visual distraction and we don't want to encourage more \brief markers in new code either, this patch removes them all. Patch produced by for i in $(git grep -l '\\brief'); do perl -pi -e 's/\\brief //g' $i & done Differential Revision: https://reviews.llvm.org/D46290 llvm-svn: 331272
* [llvm-mca] Remove method Instruction::isZeroLatency(). NFCIAndrea Di Biagio2018-04-251-1/+0
| | | | llvm-svn: 330807
* [llvm-mca] Do not assume that implicit reads cannot be associated with ↵Andrea Di Biagio2018-04-021-5/+6
| | | | | | | | | | ReadAdvance entries. Before, the instruction builder incorrectly assumed that only explicit reads could have been associated with ReadAdvance entries. This patch fixes the issue and adds a test to verify it. llvm-svn: 328972
* [llvm-mca] Correctly set the ReadAdvance information for register use operands.Andrea Di Biagio2018-03-291-1/+13
| | | | | | | | | | | | The tool was passing the wrong operand index to method MCSubtargetInfo::getReadAdvanceCycles(). That method requires a "UseIdx", and not the operand index. This was found when testing X86 code where instructions had a memory folded operand. This patch fixes the issue and adds test read-advance-1.s to ensure that the ReadAfterLd (a ReadAdvance of 3cy) information is correctly used. llvm-svn: 328790
* [llvm-mca] run clang-format on all files.Andrea Di Biagio2018-03-241-1/+0
| | | | | | This also addresses Simon's review comment in D44839. llvm-svn: 328428
* [llvm-mca] Minor refactoring. NFCIAndrea Di Biagio2018-03-221-3/+0
| | | | | | Also, removed a couple of unused methods from class Instruction. llvm-svn: 328198
* [llvm-mca] Simplify (and better standardize) the Instruction interface.Andrea Di Biagio2018-03-221-12/+4
| | | | llvm-svn: 328190
* [llvm-mca] Simplify code. NFCAndrea Di Biagio2018-03-221-15/+3
| | | | llvm-svn: 328187
* [llvm-mca] Use llvm::make_unique in a few places. NFCAndrea Di Biagio2018-03-201-2/+2
| | | | | | Also, clang-format a couple of DEBUG functions. llvm-svn: 327978
* [llvm-mca] Move the logic that updates the register files from InstrBuilder ↵Andrea Di Biagio2018-03-141-3/+5
| | | | | | | | | | | | | | | | | | | to DispatchUnit. NFCI Before this patch, the register file was always updated at instruction creation time. That means, new read-after-write dependencies, and new temporary registers were allocated at instruction creation time. This patch refactors the code in InstrBuilder, and move all the logic that updates the register file into the dispatch unit. We only want to update the register file when instructions are effectively dispatched (not before). This refactoring also helps removing a bad dependency between the InstrBuilder and the DispatchUnit. No functional change intended. llvm-svn: 327514
* [llvm-mca] LLVM Machine Code Analyzer.Andrea Di Biagio2018-03-081-0/+336
llvm-mca is an LLVM based performance analysis tool that can be used to statically measure the performance of code, and to help triage potential problems with target scheduling models. llvm-mca uses information which is already available in LLVM (e.g. scheduling models) to statically measure the performance of machine code in a specific cpu. Performance is measured in terms of throughput as well as processor resource consumption. The tool currently works for processors with an out-of-order backend, for which there is a scheduling model available in LLVM. The main goal of this tool is not just to predict the performance of the code when run on the target, but also help with diagnosing potential performance issues. Given an assembly code sequence, llvm-mca estimates the IPC (instructions per cycle), as well as hardware resources pressure. The analysis and reporting style were mostly inspired by the IACA tool from Intel. This patch is related to the RFC on llvm-dev visible at this link: http://lists.llvm.org/pipermail/llvm-dev/2018-March/121490.html Differential Revision: https://reviews.llvm.org/D43951 llvm-svn: 326998
OpenPOWER on IntegriCloud