summaryrefslogtreecommitdiffstats
path: root/gnu/llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp
diff options
context:
space:
mode:
authorpatrick <patrick@openbsd.org>2020-08-03 15:06:44 +0000
committerpatrick <patrick@openbsd.org>2020-08-03 15:06:44 +0000
commitb64793999546ed8adebaeebd9d8345d18db8927d (patch)
tree4357c27b561d73b0e089727c6ed659f2ceff5f47 /gnu/llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp
parentAdd support for UTF-8 DISPLAY-HINTs with octet length. For now only (diff)
downloadwireguard-openbsd-b64793999546ed8adebaeebd9d8345d18db8927d.tar.xz
wireguard-openbsd-b64793999546ed8adebaeebd9d8345d18db8927d.zip
Remove LLVM 8.0.1 files.
Diffstat (limited to 'gnu/llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp')
-rw-r--r--gnu/llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp435
1 files changed, 0 insertions, 435 deletions
diff --git a/gnu/llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp b/gnu/llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp
deleted file mode 100644
index 5f6966cecd6..00000000000
--- a/gnu/llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp
+++ /dev/null
@@ -1,435 +0,0 @@
-//===-- PPCHazardRecognizers.cpp - PowerPC Hazard Recognizer Impls --------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements hazard recognizers for scheduling on PowerPC processors.
-//
-//===----------------------------------------------------------------------===//
-
-#include "PPCHazardRecognizers.h"
-#include "PPC.h"
-#include "PPCInstrInfo.h"
-#include "PPCTargetMachine.h"
-#include "llvm/CodeGen/ScheduleDAG.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/raw_ostream.h"
-using namespace llvm;
-
-#define DEBUG_TYPE "pre-RA-sched"
-
-bool PPCDispatchGroupSBHazardRecognizer::isLoadAfterStore(SUnit *SU) {
- // FIXME: Move this.
- if (isBCTRAfterSet(SU))
- return true;
-
- const MCInstrDesc *MCID = DAG->getInstrDesc(SU);
- if (!MCID)
- return false;
-
- if (!MCID->mayLoad())
- return false;
-
- // SU is a load; for any predecessors in this dispatch group, that are stores,
- // and with which we have an ordering dependency, return true.
- for (unsigned i = 0, ie = (unsigned) SU->Preds.size(); i != ie; ++i) {
- const MCInstrDesc *PredMCID = DAG->getInstrDesc(SU->Preds[i].getSUnit());
- if (!PredMCID || !PredMCID->mayStore())
- continue;
-
- if (!SU->Preds[i].isNormalMemory() && !SU->Preds[i].isBarrier())
- continue;
-
- for (unsigned j = 0, je = CurGroup.size(); j != je; ++j)
- if (SU->Preds[i].getSUnit() == CurGroup[j])
- return true;
- }
-
- return false;
-}
-
-bool PPCDispatchGroupSBHazardRecognizer::isBCTRAfterSet(SUnit *SU) {
- const MCInstrDesc *MCID = DAG->getInstrDesc(SU);
- if (!MCID)
- return false;
-
- if (!MCID->isBranch())
- return false;
-
- // SU is a branch; for any predecessors in this dispatch group, with which we
- // have a data dependence and set the counter register, return true.
- for (unsigned i = 0, ie = (unsigned) SU->Preds.size(); i != ie; ++i) {
- const MCInstrDesc *PredMCID = DAG->getInstrDesc(SU->Preds[i].getSUnit());
- if (!PredMCID || PredMCID->getSchedClass() != PPC::Sched::IIC_SprMTSPR)
- continue;
-
- if (SU->Preds[i].isCtrl())
- continue;
-
- for (unsigned j = 0, je = CurGroup.size(); j != je; ++j)
- if (SU->Preds[i].getSUnit() == CurGroup[j])
- return true;
- }
-
- return false;
-}
-
-// FIXME: Remove this when we don't need this:
-namespace llvm { namespace PPC { extern int getNonRecordFormOpcode(uint16_t); } }
-
-// FIXME: A lot of code in PPCDispatchGroupSBHazardRecognizer is P7 specific.
-
-bool PPCDispatchGroupSBHazardRecognizer::mustComeFirst(const MCInstrDesc *MCID,
- unsigned &NSlots) {
- // FIXME: Indirectly, this information is contained in the itinerary, and
- // we should derive it from there instead of separately specifying it
- // here.
- unsigned IIC = MCID->getSchedClass();
- switch (IIC) {
- default:
- NSlots = 1;
- break;
- case PPC::Sched::IIC_IntDivW:
- case PPC::Sched::IIC_IntDivD:
- case PPC::Sched::IIC_LdStLoadUpd:
- case PPC::Sched::IIC_LdStLDU:
- case PPC::Sched::IIC_LdStLFDU:
- case PPC::Sched::IIC_LdStLFDUX:
- case PPC::Sched::IIC_LdStLHA:
- case PPC::Sched::IIC_LdStLHAU:
- case PPC::Sched::IIC_LdStLWA:
- case PPC::Sched::IIC_LdStSTU:
- case PPC::Sched::IIC_LdStSTFDU:
- NSlots = 2;
- break;
- case PPC::Sched::IIC_LdStLoadUpdX:
- case PPC::Sched::IIC_LdStLDUX:
- case PPC::Sched::IIC_LdStLHAUX:
- case PPC::Sched::IIC_LdStLWARX:
- case PPC::Sched::IIC_LdStLDARX:
- case PPC::Sched::IIC_LdStSTUX:
- case PPC::Sched::IIC_LdStSTDCX:
- case PPC::Sched::IIC_LdStSTWCX:
- case PPC::Sched::IIC_BrMCRX: // mtcr
- // FIXME: Add sync/isync (here and in the itinerary).
- NSlots = 4;
- break;
- }
-
- // FIXME: record-form instructions need a different itinerary class.
- if (NSlots == 1 && PPC::getNonRecordFormOpcode(MCID->getOpcode()) != -1)
- NSlots = 2;
-
- switch (IIC) {
- default:
- // All multi-slot instructions must come first.
- return NSlots > 1;
- case PPC::Sched::IIC_BrCR: // cr logicals
- case PPC::Sched::IIC_SprMFCR:
- case PPC::Sched::IIC_SprMFCRF:
- case PPC::Sched::IIC_SprMTSPR:
- return true;
- }
-}
-
-ScheduleHazardRecognizer::HazardType
-PPCDispatchGroupSBHazardRecognizer::getHazardType(SUnit *SU, int Stalls) {
- if (Stalls == 0 && isLoadAfterStore(SU))
- return NoopHazard;
-
- return ScoreboardHazardRecognizer::getHazardType(SU, Stalls);
-}
-
-bool PPCDispatchGroupSBHazardRecognizer::ShouldPreferAnother(SUnit *SU) {
- const MCInstrDesc *MCID = DAG->getInstrDesc(SU);
- unsigned NSlots;
- if (MCID && mustComeFirst(MCID, NSlots) && CurSlots)
- return true;
-
- return ScoreboardHazardRecognizer::ShouldPreferAnother(SU);
-}
-
-unsigned PPCDispatchGroupSBHazardRecognizer::PreEmitNoops(SUnit *SU) {
- // We only need to fill out a maximum of 5 slots here: The 6th slot could
- // only be a second branch, and otherwise the next instruction will start a
- // new group.
- if (isLoadAfterStore(SU) && CurSlots < 6) {
- unsigned Directive =
- DAG->MF.getSubtarget<PPCSubtarget>().getDarwinDirective();
- // If we're using a special group-terminating nop, then we need only one.
- // FIXME: the same for P9 as previous gen until POWER9 scheduling is ready
- if (Directive == PPC::DIR_PWR6 || Directive == PPC::DIR_PWR7 ||
- Directive == PPC::DIR_PWR8 || Directive == PPC::DIR_PWR9)
- return 1;
-
- return 5 - CurSlots;
- }
-
- return ScoreboardHazardRecognizer::PreEmitNoops(SU);
-}
-
-void PPCDispatchGroupSBHazardRecognizer::EmitInstruction(SUnit *SU) {
- const MCInstrDesc *MCID = DAG->getInstrDesc(SU);
- if (MCID) {
- if (CurSlots == 5 || (MCID->isBranch() && CurBranches == 1)) {
- CurGroup.clear();
- CurSlots = CurBranches = 0;
- } else {
- LLVM_DEBUG(dbgs() << "**** Adding to dispatch group: ");
- LLVM_DEBUG(DAG->dumpNode(*SU));
-
- unsigned NSlots;
- bool MustBeFirst = mustComeFirst(MCID, NSlots);
-
- // If this instruction must come first, but does not, then it starts a
- // new group.
- if (MustBeFirst && CurSlots) {
- CurSlots = CurBranches = 0;
- CurGroup.clear();
- }
-
- CurSlots += NSlots;
- CurGroup.push_back(SU);
-
- if (MCID->isBranch())
- ++CurBranches;
- }
- }
-
- return ScoreboardHazardRecognizer::EmitInstruction(SU);
-}
-
-void PPCDispatchGroupSBHazardRecognizer::AdvanceCycle() {
- return ScoreboardHazardRecognizer::AdvanceCycle();
-}
-
-void PPCDispatchGroupSBHazardRecognizer::RecedeCycle() {
- llvm_unreachable("Bottom-up scheduling not supported");
-}
-
-void PPCDispatchGroupSBHazardRecognizer::Reset() {
- CurGroup.clear();
- CurSlots = CurBranches = 0;
- return ScoreboardHazardRecognizer::Reset();
-}
-
-void PPCDispatchGroupSBHazardRecognizer::EmitNoop() {
- unsigned Directive =
- DAG->MF.getSubtarget<PPCSubtarget>().getDarwinDirective();
- // If the group has now filled all of its slots, or if we're using a special
- // group-terminating nop, the group is complete.
- // FIXME: the same for P9 as previous gen until POWER9 scheduling is ready
- if (Directive == PPC::DIR_PWR6 || Directive == PPC::DIR_PWR7 ||
- Directive == PPC::DIR_PWR8 || Directive == PPC::DIR_PWR9 ||
- CurSlots == 6) {
- CurGroup.clear();
- CurSlots = CurBranches = 0;
- } else {
- CurGroup.push_back(nullptr);
- ++CurSlots;
- }
-}
-
-//===----------------------------------------------------------------------===//
-// PowerPC 970 Hazard Recognizer
-//
-// This models the dispatch group formation of the PPC970 processor. Dispatch
-// groups are bundles of up to five instructions that can contain various mixes
-// of instructions. The PPC970 can dispatch a peak of 4 non-branch and one
-// branch instruction per-cycle.
-//
-// There are a number of restrictions to dispatch group formation: some
-// instructions can only be issued in the first slot of a dispatch group, & some
-// instructions fill an entire dispatch group. Additionally, only branches can
-// issue in the 5th (last) slot.
-//
-// Finally, there are a number of "structural" hazards on the PPC970. These
-// conditions cause large performance penalties due to misprediction, recovery,
-// and replay logic that has to happen. These cases include setting a CTR and
-// branching through it in the same dispatch group, and storing to an address,
-// then loading from the same address within a dispatch group. To avoid these
-// conditions, we insert no-op instructions when appropriate.
-//
-// FIXME: This is missing some significant cases:
-// 1. Modeling of microcoded instructions.
-// 2. Handling of serialized operations.
-// 3. Handling of the esoteric cases in "Resource-based Instruction Grouping".
-//
-
-PPCHazardRecognizer970::PPCHazardRecognizer970(const ScheduleDAG &DAG)
- : DAG(DAG) {
- EndDispatchGroup();
-}
-
-void PPCHazardRecognizer970::EndDispatchGroup() {
- LLVM_DEBUG(errs() << "=== Start of dispatch group\n");
- NumIssued = 0;
-
- // Structural hazard info.
- HasCTRSet = false;
- NumStores = 0;
-}
-
-
-PPCII::PPC970_Unit
-PPCHazardRecognizer970::GetInstrType(unsigned Opcode,
- bool &isFirst, bool &isSingle,
- bool &isCracked,
- bool &isLoad, bool &isStore) {
- const MCInstrDesc &MCID = DAG.TII->get(Opcode);
-
- isLoad = MCID.mayLoad();
- isStore = MCID.mayStore();
-
- uint64_t TSFlags = MCID.TSFlags;
-
- isFirst = TSFlags & PPCII::PPC970_First;
- isSingle = TSFlags & PPCII::PPC970_Single;
- isCracked = TSFlags & PPCII::PPC970_Cracked;
- return (PPCII::PPC970_Unit)(TSFlags & PPCII::PPC970_Mask);
-}
-
-/// isLoadOfStoredAddress - If we have a load from the previously stored pointer
-/// as indicated by StorePtr1/StorePtr2/StoreSize, return true.
-bool PPCHazardRecognizer970::
-isLoadOfStoredAddress(uint64_t LoadSize, int64_t LoadOffset,
- const Value *LoadValue) const {
- for (unsigned i = 0, e = NumStores; i != e; ++i) {
- // Handle exact and commuted addresses.
- if (LoadValue == StoreValue[i] && LoadOffset == StoreOffset[i])
- return true;
-
- // Okay, we don't have an exact match, if this is an indexed offset, see if
- // we have overlap (which happens during fp->int conversion for example).
- if (StoreValue[i] == LoadValue) {
- // Okay the base pointers match, so we have [c1+r] vs [c2+r]. Check
- // to see if the load and store actually overlap.
- if (StoreOffset[i] < LoadOffset) {
- if (int64_t(StoreOffset[i]+StoreSize[i]) > LoadOffset) return true;
- } else {
- if (int64_t(LoadOffset+LoadSize) > StoreOffset[i]) return true;
- }
- }
- }
- return false;
-}
-
-/// getHazardType - We return hazard for any non-branch instruction that would
-/// terminate the dispatch group. We turn NoopHazard for any
-/// instructions that wouldn't terminate the dispatch group that would cause a
-/// pipeline flush.
-ScheduleHazardRecognizer::HazardType PPCHazardRecognizer970::
-getHazardType(SUnit *SU, int Stalls) {
- assert(Stalls == 0 && "PPC hazards don't support scoreboard lookahead");
-
- MachineInstr *MI = SU->getInstr();
-
- if (MI->isDebugInstr())
- return NoHazard;
-
- unsigned Opcode = MI->getOpcode();
- bool isFirst, isSingle, isCracked, isLoad, isStore;
- PPCII::PPC970_Unit InstrType =
- GetInstrType(Opcode, isFirst, isSingle, isCracked,
- isLoad, isStore);
- if (InstrType == PPCII::PPC970_Pseudo) return NoHazard;
-
- // We can only issue a PPC970_First/PPC970_Single instruction (such as
- // crand/mtspr/etc) if this is the first cycle of the dispatch group.
- if (NumIssued != 0 && (isFirst || isSingle))
- return Hazard;
-
- // If this instruction is cracked into two ops by the decoder, we know that
- // it is not a branch and that it cannot issue if 3 other instructions are
- // already in the dispatch group.
- if (isCracked && NumIssued > 2)
- return Hazard;
-
- switch (InstrType) {
- default: llvm_unreachable("Unknown instruction type!");
- case PPCII::PPC970_FXU:
- case PPCII::PPC970_LSU:
- case PPCII::PPC970_FPU:
- case PPCII::PPC970_VALU:
- case PPCII::PPC970_VPERM:
- // We can only issue a branch as the last instruction in a group.
- if (NumIssued == 4) return Hazard;
- break;
- case PPCII::PPC970_CRU:
- // We can only issue a CR instruction in the first two slots.
- if (NumIssued >= 2) return Hazard;
- break;
- case PPCII::PPC970_BRU:
- break;
- }
-
- // Do not allow MTCTR and BCTRL to be in the same dispatch group.
- if (HasCTRSet && Opcode == PPC::BCTRL)
- return NoopHazard;
-
- // If this is a load following a store, make sure it's not to the same or
- // overlapping address.
- if (isLoad && NumStores && !MI->memoperands_empty()) {
- MachineMemOperand *MO = *MI->memoperands_begin();
- if (isLoadOfStoredAddress(MO->getSize(),
- MO->getOffset(), MO->getValue()))
- return NoopHazard;
- }
-
- return NoHazard;
-}
-
-void PPCHazardRecognizer970::EmitInstruction(SUnit *SU) {
- MachineInstr *MI = SU->getInstr();
-
- if (MI->isDebugInstr())
- return;
-
- unsigned Opcode = MI->getOpcode();
- bool isFirst, isSingle, isCracked, isLoad, isStore;
- PPCII::PPC970_Unit InstrType =
- GetInstrType(Opcode, isFirst, isSingle, isCracked,
- isLoad, isStore);
- if (InstrType == PPCII::PPC970_Pseudo) return;
-
- // Update structural hazard information.
- if (Opcode == PPC::MTCTR || Opcode == PPC::MTCTR8) HasCTRSet = true;
-
- // Track the address stored to.
- if (isStore && NumStores < 4 && !MI->memoperands_empty()) {
- MachineMemOperand *MO = *MI->memoperands_begin();
- StoreSize[NumStores] = MO->getSize();
- StoreOffset[NumStores] = MO->getOffset();
- StoreValue[NumStores] = MO->getValue();
- ++NumStores;
- }
-
- if (InstrType == PPCII::PPC970_BRU || isSingle)
- NumIssued = 4; // Terminate a d-group.
- ++NumIssued;
-
- // If this instruction is cracked into two ops by the decoder, remember that
- // we issued two pieces.
- if (isCracked)
- ++NumIssued;
-
- if (NumIssued == 5)
- EndDispatchGroup();
-}
-
-void PPCHazardRecognizer970::AdvanceCycle() {
- assert(NumIssued < 5 && "Illegal dispatch group!");
- ++NumIssued;
- if (NumIssued == 5)
- EndDispatchGroup();
-}
-
-void PPCHazardRecognizer970::Reset() {
- EndDispatchGroup();
-}
-