blob: a2c8c757222f661b8ec77f75c7c06d10413ddee5 [file] [log] [blame]
Tom Stellardee346802016-04-22 14:43:50 +00001/// - Targets that need the hazard recognizer to be run at -O0.
2/// - Targets that want to guarantee that hazards at the beginning of
3/// scheduling regions are handled correctly. The post-RA scheduler is
4/// a top-down scheduler, but when there are multiple scheduling regions
5/// in a basic block, it visits the regions in bottom-up order. This
6/// makes it impossible for the scheduler to gauranttee it can correctly
7/// handle hazards at the beginning of scheduling regions.
8///
9/// This pass traverses all the instructions in a program in top-down order.
10/// In contrast to the instruction scheduling passes, this pass never resets
11/// the hazard recognizer to ensure it can correctly handles noop hazards at
Hiroshi Inouee9dea6e2017-07-13 06:48:39 +000012/// the beginning of blocks.
Tom Stellardee346802016-04-22 14:43:50 +000013//
14//===----------------------------------------------------------------------===//
15
Tom Stellardee346802016-04-22 14:43:50 +000016#include "llvm/ADT/Statistic.h"
17#include "llvm/CodeGen/MachineFunctionPass.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000018#include "llvm/CodeGen/Passes.h"
Tom Stellardee346802016-04-22 14:43:50 +000019#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
David Blaikie3f833ed2017-11-08 01:01:31 +000020#include "llvm/CodeGen/TargetInstrInfo.h"
David Blaikieb3bde2e2017-11-17 01:07:10 +000021#include "llvm/CodeGen/TargetSubtargetInfo.h"
Reid Kleckner05da2fe2019-11-13 13:15:01 -080022#include "llvm/InitializePasses.h"
Tom Stellardee346802016-04-22 14:43:50 +000023#include "llvm/Support/Debug.h"
24#include "llvm/Support/ErrorHandling.h"
25#include "llvm/Support/raw_ostream.h"
Tom Stellardee346802016-04-22 14:43:50 +000026using namespace llvm;
27
28#define DEBUG_TYPE "post-RA-hazard-rec"
29
30STATISTIC(NumNoops, "Number of noops inserted");
31
32namespace {
33 class PostRAHazardRecognizer : public MachineFunctionPass {
Tom Stellardee346802016-04-22 14:43:50 +000034
35 public:
36 static char ID;
37 PostRAHazardRecognizer() : MachineFunctionPass(ID) {}
38
39 void getAnalysisUsage(AnalysisUsage &AU) const override {
40 AU.setPreservesCFG();
41 MachineFunctionPass::getAnalysisUsage(AU);
42 }
43
44 bool runOnMachineFunction(MachineFunction &Fn) override;
45
46 };
47 char PostRAHazardRecognizer::ID = 0;
48
49}
50
51char &llvm::PostRAHazardRecognizerID = PostRAHazardRecognizer::ID;
52
53INITIALIZE_PASS(PostRAHazardRecognizer, DEBUG_TYPE,
54 "Post RA hazard recognizer", false, false)
55
56bool PostRAHazardRecognizer::runOnMachineFunction(MachineFunction &Fn) {
57 const TargetInstrInfo *TII = Fn.getSubtarget().getInstrInfo();
58 std::unique_ptr<ScheduleHazardRecognizer> HazardRec(
59 TII->CreateTargetPostRAHazardRecognizer(Fn));
60
61 // Return if the target has not implemented a hazard recognizer.
62 if (!HazardRec.get())
63 return false;
64
65 // Loop over all of the basic blocks
66 for (auto &MBB : Fn) {
67 // We do not call HazardRec->reset() here to make sure we are handling noop
68 // hazards at the start of basic blocks.
Duncan P. N. Exon Smith286d9482016-07-01 00:50:29 +000069 for (MachineInstr &MI : MBB) {
Tom Stellardee346802016-04-22 14:43:50 +000070 // If we need to emit noops prior to this instruction, then do so.
Duncan P. N. Exon Smith286d9482016-07-01 00:50:29 +000071 unsigned NumPreNoops = HazardRec->PreEmitNoops(&MI);
Tom Stellardee346802016-04-22 14:43:50 +000072 for (unsigned i = 0; i != NumPreNoops; ++i) {
73 HazardRec->EmitNoop();
Duncan P. N. Exon Smith286d9482016-07-01 00:50:29 +000074 TII->insertNoop(MBB, MachineBasicBlock::iterator(MI));
Tom Stellardee346802016-04-22 14:43:50 +000075 ++NumNoops;
76 }
77
Duncan P. N. Exon Smith286d9482016-07-01 00:50:29 +000078 HazardRec->EmitInstruction(&MI);
Tom Stellardee346802016-04-22 14:43:50 +000079 if (HazardRec->atIssueLimit()) {
80 HazardRec->AdvanceCycle();
81 }
82 }
83 }
84 return true;
85}