1*0b57cec5SDimitry Andric //===-- PPCHazardRecognizers.h - PowerPC Hazard Recognizers -----*- C++ -*-===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric // 9*0b57cec5SDimitry Andric // This file defines hazard recognizers for scheduling on PowerPC processors. 10*0b57cec5SDimitry Andric // 11*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 12*0b57cec5SDimitry Andric 13*0b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_POWERPC_PPCHAZARDRECOGNIZERS_H 14*0b57cec5SDimitry Andric #define LLVM_LIB_TARGET_POWERPC_PPCHAZARDRECOGNIZERS_H 15*0b57cec5SDimitry Andric 16*0b57cec5SDimitry Andric #include "PPCInstrInfo.h" 17*0b57cec5SDimitry Andric #include "llvm/CodeGen/ScheduleHazardRecognizer.h" 18*0b57cec5SDimitry Andric #include "llvm/CodeGen/ScoreboardHazardRecognizer.h" 19*0b57cec5SDimitry Andric #include "llvm/CodeGen/SelectionDAGNodes.h" 20*0b57cec5SDimitry Andric 21*0b57cec5SDimitry Andric namespace llvm { 22*0b57cec5SDimitry Andric 23*0b57cec5SDimitry Andric /// PPCDispatchGroupSBHazardRecognizer - This class implements a scoreboard-based 24*0b57cec5SDimitry Andric /// hazard recognizer for PPC ooo processors with dispatch-group hazards. 25*0b57cec5SDimitry Andric class PPCDispatchGroupSBHazardRecognizer : public ScoreboardHazardRecognizer { 26*0b57cec5SDimitry Andric const ScheduleDAG *DAG; 27*0b57cec5SDimitry Andric SmallVector<SUnit *, 7> CurGroup; 28*0b57cec5SDimitry Andric unsigned CurSlots, CurBranches; 29*0b57cec5SDimitry Andric 30*0b57cec5SDimitry Andric bool isLoadAfterStore(SUnit *SU); 31*0b57cec5SDimitry Andric bool isBCTRAfterSet(SUnit *SU); 32*0b57cec5SDimitry Andric bool mustComeFirst(const MCInstrDesc *MCID, unsigned &NSlots); 33*0b57cec5SDimitry Andric public: PPCDispatchGroupSBHazardRecognizer(const InstrItineraryData * ItinData,const ScheduleDAG * DAG_)34*0b57cec5SDimitry Andric PPCDispatchGroupSBHazardRecognizer(const InstrItineraryData *ItinData, 35*0b57cec5SDimitry Andric const ScheduleDAG *DAG_) : 36*0b57cec5SDimitry Andric ScoreboardHazardRecognizer(ItinData, DAG_), DAG(DAG_), 37*0b57cec5SDimitry Andric CurSlots(0), CurBranches(0) {} 38*0b57cec5SDimitry Andric 39*0b57cec5SDimitry Andric HazardType getHazardType(SUnit *SU, int Stalls) override; 40*0b57cec5SDimitry Andric bool ShouldPreferAnother(SUnit* SU) override; 41*0b57cec5SDimitry Andric unsigned PreEmitNoops(SUnit *SU) override; 42*0b57cec5SDimitry Andric void EmitInstruction(SUnit *SU) override; 43*0b57cec5SDimitry Andric void AdvanceCycle() override; 44*0b57cec5SDimitry Andric void RecedeCycle() override; 45*0b57cec5SDimitry Andric void Reset() override; 46*0b57cec5SDimitry Andric void EmitNoop() override; 47*0b57cec5SDimitry Andric }; 48*0b57cec5SDimitry Andric 49*0b57cec5SDimitry Andric /// PPCHazardRecognizer970 - This class defines a finite state automata that 50*0b57cec5SDimitry Andric /// models the dispatch logic on the PowerPC 970 (aka G5) processor. This 51*0b57cec5SDimitry Andric /// promotes good dispatch group formation and implements noop insertion to 52*0b57cec5SDimitry Andric /// avoid structural hazards that cause significant performance penalties (e.g. 53*0b57cec5SDimitry Andric /// setting the CTR register then branching through it within a dispatch group), 54*0b57cec5SDimitry Andric /// or storing then loading from the same address within a dispatch group. 55*0b57cec5SDimitry Andric class PPCHazardRecognizer970 : public ScheduleHazardRecognizer { 56*0b57cec5SDimitry Andric const ScheduleDAG &DAG; 57*0b57cec5SDimitry Andric 58*0b57cec5SDimitry Andric unsigned NumIssued; // Number of insts issued, including advanced cycles. 59*0b57cec5SDimitry Andric 60*0b57cec5SDimitry Andric // Various things that can cause a structural hazard. 61*0b57cec5SDimitry Andric 62*0b57cec5SDimitry Andric // HasCTRSet - If the CTR register is set in this group, disallow BCTRL. 63*0b57cec5SDimitry Andric bool HasCTRSet; 64*0b57cec5SDimitry Andric 65*0b57cec5SDimitry Andric // StoredPtr - Keep track of the address of any store. If we see a load from 66*0b57cec5SDimitry Andric // the same address (or one that aliases it), disallow the store. We can have 67*0b57cec5SDimitry Andric // up to four stores in one dispatch group, hence we track up to 4. 68*0b57cec5SDimitry Andric // 69*0b57cec5SDimitry Andric // This is null if we haven't seen a store yet. We keep track of both 70*0b57cec5SDimitry Andric // operands of the store here, since we support [r+r] and [r+i] addressing. 71*0b57cec5SDimitry Andric const Value *StoreValue[4]; 72*0b57cec5SDimitry Andric int64_t StoreOffset[4]; 73*0b57cec5SDimitry Andric uint64_t StoreSize[4]; 74*0b57cec5SDimitry Andric unsigned NumStores; 75*0b57cec5SDimitry Andric 76*0b57cec5SDimitry Andric public: 77*0b57cec5SDimitry Andric PPCHazardRecognizer970(const ScheduleDAG &DAG); 78*0b57cec5SDimitry Andric HazardType getHazardType(SUnit *SU, int Stalls) override; 79*0b57cec5SDimitry Andric void EmitInstruction(SUnit *SU) override; 80*0b57cec5SDimitry Andric void AdvanceCycle() override; 81*0b57cec5SDimitry Andric void Reset() override; 82*0b57cec5SDimitry Andric 83*0b57cec5SDimitry Andric private: 84*0b57cec5SDimitry Andric /// EndDispatchGroup - Called when we are finishing a new dispatch group. 85*0b57cec5SDimitry Andric /// 86*0b57cec5SDimitry Andric void EndDispatchGroup(); 87*0b57cec5SDimitry Andric 88*0b57cec5SDimitry Andric /// GetInstrType - Classify the specified powerpc opcode according to its 89*0b57cec5SDimitry Andric /// pipeline. 90*0b57cec5SDimitry Andric PPCII::PPC970_Unit GetInstrType(unsigned Opcode, 91*0b57cec5SDimitry Andric bool &isFirst, bool &isSingle,bool &isCracked, 92*0b57cec5SDimitry Andric bool &isLoad, bool &isStore); 93*0b57cec5SDimitry Andric 94*0b57cec5SDimitry Andric bool isLoadOfStoredAddress(uint64_t LoadSize, int64_t LoadOffset, 95*0b57cec5SDimitry Andric const Value *LoadValue) const; 96*0b57cec5SDimitry Andric }; 97*0b57cec5SDimitry Andric 98*0b57cec5SDimitry Andric } // end namespace llvm 99*0b57cec5SDimitry Andric 100*0b57cec5SDimitry Andric #endif 101*0b57cec5SDimitry Andric 102