Home | History | Annotate | Download | only in PowerPC
      1 //===-- PPCHazardRecognizers.cpp - PowerPC Hazard Recognizer Impls --------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file implements hazard recognizers for scheduling on PowerPC processors.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "PPCHazardRecognizers.h"
     15 #include "PPC.h"
     16 #include "PPCInstrInfo.h"
     17 #include "PPCTargetMachine.h"
     18 #include "llvm/CodeGen/ScheduleDAG.h"
     19 #include "llvm/Support/Debug.h"
     20 #include "llvm/Support/ErrorHandling.h"
     21 #include "llvm/Support/raw_ostream.h"
     22 using namespace llvm;
     23 
     24 #define DEBUG_TYPE "pre-RA-sched"
     25 
     26 bool PPCDispatchGroupSBHazardRecognizer::isLoadAfterStore(SUnit *SU) {
     27   // FIXME: Move this.
     28   if (isBCTRAfterSet(SU))
     29     return true;
     30 
     31   const MCInstrDesc *MCID = DAG->getInstrDesc(SU);
     32   if (!MCID)
     33     return false;
     34 
     35   if (!MCID->mayLoad())
     36     return false;
     37 
     38   // SU is a load; for any predecessors in this dispatch group, that are stores,
     39   // and with which we have an ordering dependency, return true.
     40   for (unsigned i = 0, ie = (unsigned) SU->Preds.size(); i != ie; ++i) {
     41     const MCInstrDesc *PredMCID = DAG->getInstrDesc(SU->Preds[i].getSUnit());
     42     if (!PredMCID || !PredMCID->mayStore())
     43       continue;
     44 
     45     if (!SU->Preds[i].isNormalMemory() && !SU->Preds[i].isBarrier())
     46       continue;
     47 
     48     for (unsigned j = 0, je = CurGroup.size(); j != je; ++j)
     49       if (SU->Preds[i].getSUnit() == CurGroup[j])
     50         return true;
     51   }
     52 
     53   return false;
     54 }
     55 
     56 bool PPCDispatchGroupSBHazardRecognizer::isBCTRAfterSet(SUnit *SU) {
     57   const MCInstrDesc *MCID = DAG->getInstrDesc(SU);
     58   if (!MCID)
     59     return false;
     60 
     61   if (!MCID->isBranch())
     62     return false;
     63 
     64   // SU is a branch; for any predecessors in this dispatch group, with which we
     65   // have a data dependence and set the counter register, return true.
     66   for (unsigned i = 0, ie = (unsigned) SU->Preds.size(); i != ie; ++i) {
     67     const MCInstrDesc *PredMCID = DAG->getInstrDesc(SU->Preds[i].getSUnit());
     68     if (!PredMCID || PredMCID->getSchedClass() != PPC::Sched::IIC_SprMTSPR)
     69       continue;
     70 
     71     if (SU->Preds[i].isCtrl())
     72       continue;
     73 
     74     for (unsigned j = 0, je = CurGroup.size(); j != je; ++j)
     75       if (SU->Preds[i].getSUnit() == CurGroup[j])
     76         return true;
     77   }
     78 
     79   return false;
     80 }
     81 
     82 // FIXME: Remove this when we don't need this:
     83 namespace llvm { namespace PPC { extern int getNonRecordFormOpcode(uint16_t); } }
     84 
     85 // FIXME: A lot of code in PPCDispatchGroupSBHazardRecognizer is P7 specific.
     86 
     87 bool PPCDispatchGroupSBHazardRecognizer::mustComeFirst(const MCInstrDesc *MCID,
     88                                                        unsigned &NSlots) {
     89   // FIXME: Indirectly, this information is contained in the itinerary, and
     90   // we should derive it from there instead of separately specifying it
     91   // here.
     92   unsigned IIC = MCID->getSchedClass();
     93   switch (IIC) {
     94   default:
     95     NSlots = 1;
     96     break;
     97   case PPC::Sched::IIC_IntDivW:
     98   case PPC::Sched::IIC_IntDivD:
     99   case PPC::Sched::IIC_LdStLoadUpd:
    100   case PPC::Sched::IIC_LdStLDU:
    101   case PPC::Sched::IIC_LdStLFDU:
    102   case PPC::Sched::IIC_LdStLFDUX:
    103   case PPC::Sched::IIC_LdStLHA:
    104   case PPC::Sched::IIC_LdStLHAU:
    105   case PPC::Sched::IIC_LdStLWA:
    106   case PPC::Sched::IIC_LdStSTDU:
    107   case PPC::Sched::IIC_LdStSTFDU:
    108     NSlots = 2;
    109     break;
    110   case PPC::Sched::IIC_LdStLoadUpdX:
    111   case PPC::Sched::IIC_LdStLDUX:
    112   case PPC::Sched::IIC_LdStLHAUX:
    113   case PPC::Sched::IIC_LdStLWARX:
    114   case PPC::Sched::IIC_LdStLDARX:
    115   case PPC::Sched::IIC_LdStSTDUX:
    116   case PPC::Sched::IIC_LdStSTDCX:
    117   case PPC::Sched::IIC_LdStSTWCX:
    118   case PPC::Sched::IIC_BrMCRX: // mtcr
    119   // FIXME: Add sync/isync (here and in the itinerary).
    120     NSlots = 4;
    121     break;
    122   }
    123 
    124   // FIXME: record-form instructions need a different itinerary class.
    125   if (NSlots == 1 && PPC::getNonRecordFormOpcode(MCID->getOpcode()) != -1)
    126     NSlots = 2;
    127 
    128   switch (IIC) {
    129   default:
    130     // All multi-slot instructions must come first.
    131     return NSlots > 1;
    132   case PPC::Sched::IIC_BrCR: // cr logicals
    133   case PPC::Sched::IIC_SprMFCR:
    134   case PPC::Sched::IIC_SprMFCRF:
    135   case PPC::Sched::IIC_SprMTSPR:
    136     return true;
    137   }
    138 }
    139 
    140 ScheduleHazardRecognizer::HazardType
    141 PPCDispatchGroupSBHazardRecognizer::getHazardType(SUnit *SU, int Stalls) {
    142   if (Stalls == 0 && isLoadAfterStore(SU))
    143     return NoopHazard;
    144 
    145   return ScoreboardHazardRecognizer::getHazardType(SU, Stalls);
    146 }
    147 
    148 bool PPCDispatchGroupSBHazardRecognizer::ShouldPreferAnother(SUnit *SU) {
    149   const MCInstrDesc *MCID = DAG->getInstrDesc(SU);
    150   unsigned NSlots;
    151   if (MCID && mustComeFirst(MCID, NSlots) && CurSlots)
    152     return true;
    153 
    154   return ScoreboardHazardRecognizer::ShouldPreferAnother(SU);
    155 }
    156 
    157 unsigned PPCDispatchGroupSBHazardRecognizer::PreEmitNoops(SUnit *SU) {
    158   // We only need to fill out a maximum of 5 slots here: The 6th slot could
    159   // only be a second branch, and otherwise the next instruction will start a
    160   // new group.
    161   if (isLoadAfterStore(SU) && CurSlots < 6) {
    162     unsigned Directive =
    163       DAG->TM.getSubtarget<PPCSubtarget>().getDarwinDirective();
    164     // If we're using a special group-terminating nop, then we need only one.
    165     if (Directive == PPC::DIR_PWR6 || Directive == PPC::DIR_PWR7 ||
    166         Directive == PPC::DIR_PWR8 )
    167       return 1;
    168 
    169     return 5 - CurSlots;
    170   }
    171 
    172   return ScoreboardHazardRecognizer::PreEmitNoops(SU);
    173 }
    174 
    175 void PPCDispatchGroupSBHazardRecognizer::EmitInstruction(SUnit *SU) {
    176   const MCInstrDesc *MCID = DAG->getInstrDesc(SU);
    177   if (MCID) {
    178     if (CurSlots == 5 || (MCID->isBranch() && CurBranches == 1)) {
    179       CurGroup.clear();
    180       CurSlots = CurBranches = 0;
    181     } else {
    182       DEBUG(dbgs() << "**** Adding to dispatch group: SU(" <<
    183                       SU->NodeNum << "): ");
    184       DEBUG(DAG->dumpNode(SU));
    185 
    186       unsigned NSlots;
    187       bool MustBeFirst = mustComeFirst(MCID, NSlots);
    188 
    189       // If this instruction must come first, but does not, then it starts a
    190       // new group.
    191       if (MustBeFirst && CurSlots) {
    192         CurSlots = CurBranches = 0;
    193         CurGroup.clear();
    194       }
    195 
    196       CurSlots += NSlots;
    197       CurGroup.push_back(SU);
    198 
    199       if (MCID->isBranch())
    200         ++CurBranches;
    201     }
    202   }
    203 
    204   return ScoreboardHazardRecognizer::EmitInstruction(SU);
    205 }
    206 
    207 void PPCDispatchGroupSBHazardRecognizer::AdvanceCycle() {
    208   return ScoreboardHazardRecognizer::AdvanceCycle();
    209 }
    210 
    211 void PPCDispatchGroupSBHazardRecognizer::RecedeCycle() {
    212   llvm_unreachable("Bottom-up scheduling not supported");
    213 }
    214 
    215 void PPCDispatchGroupSBHazardRecognizer::Reset() {
    216   CurGroup.clear();
    217   CurSlots = CurBranches = 0;
    218   return ScoreboardHazardRecognizer::Reset();
    219 }
    220 
    221 void PPCDispatchGroupSBHazardRecognizer::EmitNoop() {
    222   unsigned Directive =
    223     DAG->TM.getSubtarget<PPCSubtarget>().getDarwinDirective();
    224   // If the group has now filled all of its slots, or if we're using a special
    225   // group-terminating nop, the group is complete.
    226   if (Directive == PPC::DIR_PWR6 || Directive == PPC::DIR_PWR7 ||
    227       Directive == PPC::DIR_PWR8 || CurSlots == 6)  {
    228     CurGroup.clear();
    229     CurSlots = CurBranches = 0;
    230   } else {
    231     CurGroup.push_back(nullptr);
    232     ++CurSlots;
    233   }
    234 }
    235 
    236 //===----------------------------------------------------------------------===//
    237 // PowerPC 970 Hazard Recognizer
    238 //
    239 // This models the dispatch group formation of the PPC970 processor.  Dispatch
    240 // groups are bundles of up to five instructions that can contain various mixes
    241 // of instructions.  The PPC970 can dispatch a peak of 4 non-branch and one
    242 // branch instruction per-cycle.
    243 //
    244 // There are a number of restrictions to dispatch group formation: some
    245 // instructions can only be issued in the first slot of a dispatch group, & some
    246 // instructions fill an entire dispatch group.  Additionally, only branches can
    247 // issue in the 5th (last) slot.
    248 //
    249 // Finally, there are a number of "structural" hazards on the PPC970.  These
    250 // conditions cause large performance penalties due to misprediction, recovery,
    251 // and replay logic that has to happen.  These cases include setting a CTR and
    252 // branching through it in the same dispatch group, and storing to an address,
    253 // then loading from the same address within a dispatch group.  To avoid these
    254 // conditions, we insert no-op instructions when appropriate.
    255 //
    256 // FIXME: This is missing some significant cases:
    257 //   1. Modeling of microcoded instructions.
    258 //   2. Handling of serialized operations.
    259 //   3. Handling of the esoteric cases in "Resource-based Instruction Grouping".
    260 //
    261 
    262 PPCHazardRecognizer970::PPCHazardRecognizer970(const ScheduleDAG &DAG)
    263     : DAG(DAG) {
    264   EndDispatchGroup();
    265 }
    266 
    267 void PPCHazardRecognizer970::EndDispatchGroup() {
    268   DEBUG(errs() << "=== Start of dispatch group\n");
    269   NumIssued = 0;
    270 
    271   // Structural hazard info.
    272   HasCTRSet = false;
    273   NumStores = 0;
    274 }
    275 
    276 
    277 PPCII::PPC970_Unit
    278 PPCHazardRecognizer970::GetInstrType(unsigned Opcode,
    279                                      bool &isFirst, bool &isSingle,
    280                                      bool &isCracked,
    281                                      bool &isLoad, bool &isStore) {
    282   const MCInstrDesc &MCID = DAG.TII->get(Opcode);
    283 
    284   isLoad  = MCID.mayLoad();
    285   isStore = MCID.mayStore();
    286 
    287   uint64_t TSFlags = MCID.TSFlags;
    288 
    289   isFirst   = TSFlags & PPCII::PPC970_First;
    290   isSingle  = TSFlags & PPCII::PPC970_Single;
    291   isCracked = TSFlags & PPCII::PPC970_Cracked;
    292   return (PPCII::PPC970_Unit)(TSFlags & PPCII::PPC970_Mask);
    293 }
    294 
    295 /// isLoadOfStoredAddress - If we have a load from the previously stored pointer
    296 /// as indicated by StorePtr1/StorePtr2/StoreSize, return true.
    297 bool PPCHazardRecognizer970::
    298 isLoadOfStoredAddress(uint64_t LoadSize, int64_t LoadOffset,
    299   const Value *LoadValue) const {
    300   for (unsigned i = 0, e = NumStores; i != e; ++i) {
    301     // Handle exact and commuted addresses.
    302     if (LoadValue == StoreValue[i] && LoadOffset == StoreOffset[i])
    303       return true;
    304 
    305     // Okay, we don't have an exact match, if this is an indexed offset, see if
    306     // we have overlap (which happens during fp->int conversion for example).
    307     if (StoreValue[i] == LoadValue) {
    308       // Okay the base pointers match, so we have [c1+r] vs [c2+r].  Check
    309       // to see if the load and store actually overlap.
    310       if (StoreOffset[i] < LoadOffset) {
    311         if (int64_t(StoreOffset[i]+StoreSize[i]) > LoadOffset) return true;
    312       } else {
    313         if (int64_t(LoadOffset+LoadSize) > StoreOffset[i]) return true;
    314       }
    315     }
    316   }
    317   return false;
    318 }
    319 
    320 /// getHazardType - We return hazard for any non-branch instruction that would
    321 /// terminate the dispatch group.  We turn NoopHazard for any
    322 /// instructions that wouldn't terminate the dispatch group that would cause a
    323 /// pipeline flush.
    324 ScheduleHazardRecognizer::HazardType PPCHazardRecognizer970::
    325 getHazardType(SUnit *SU, int Stalls) {
    326   assert(Stalls == 0 && "PPC hazards don't support scoreboard lookahead");
    327 
    328   MachineInstr *MI = SU->getInstr();
    329 
    330   if (MI->isDebugValue())
    331     return NoHazard;
    332 
    333   unsigned Opcode = MI->getOpcode();
    334   bool isFirst, isSingle, isCracked, isLoad, isStore;
    335   PPCII::PPC970_Unit InstrType =
    336     GetInstrType(Opcode, isFirst, isSingle, isCracked,
    337                  isLoad, isStore);
    338   if (InstrType == PPCII::PPC970_Pseudo) return NoHazard;
    339 
    340   // We can only issue a PPC970_First/PPC970_Single instruction (such as
    341   // crand/mtspr/etc) if this is the first cycle of the dispatch group.
    342   if (NumIssued != 0 && (isFirst || isSingle))
    343     return Hazard;
    344 
    345   // If this instruction is cracked into two ops by the decoder, we know that
    346   // it is not a branch and that it cannot issue if 3 other instructions are
    347   // already in the dispatch group.
    348   if (isCracked && NumIssued > 2)
    349     return Hazard;
    350 
    351   switch (InstrType) {
    352   default: llvm_unreachable("Unknown instruction type!");
    353   case PPCII::PPC970_FXU:
    354   case PPCII::PPC970_LSU:
    355   case PPCII::PPC970_FPU:
    356   case PPCII::PPC970_VALU:
    357   case PPCII::PPC970_VPERM:
    358     // We can only issue a branch as the last instruction in a group.
    359     if (NumIssued == 4) return Hazard;
    360     break;
    361   case PPCII::PPC970_CRU:
    362     // We can only issue a CR instruction in the first two slots.
    363     if (NumIssued >= 2) return Hazard;
    364     break;
    365   case PPCII::PPC970_BRU:
    366     break;
    367   }
    368 
    369   // Do not allow MTCTR and BCTRL to be in the same dispatch group.
    370   if (HasCTRSet && Opcode == PPC::BCTRL)
    371     return NoopHazard;
    372 
    373   // If this is a load following a store, make sure it's not to the same or
    374   // overlapping address.
    375   if (isLoad && NumStores && !MI->memoperands_empty()) {
    376     MachineMemOperand *MO = *MI->memoperands_begin();
    377     if (isLoadOfStoredAddress(MO->getSize(),
    378                               MO->getOffset(), MO->getValue()))
    379       return NoopHazard;
    380   }
    381 
    382   return NoHazard;
    383 }
    384 
    385 void PPCHazardRecognizer970::EmitInstruction(SUnit *SU) {
    386   MachineInstr *MI = SU->getInstr();
    387 
    388   if (MI->isDebugValue())
    389     return;
    390 
    391   unsigned Opcode = MI->getOpcode();
    392   bool isFirst, isSingle, isCracked, isLoad, isStore;
    393   PPCII::PPC970_Unit InstrType =
    394     GetInstrType(Opcode, isFirst, isSingle, isCracked,
    395                  isLoad, isStore);
    396   if (InstrType == PPCII::PPC970_Pseudo) return;
    397 
    398   // Update structural hazard information.
    399   if (Opcode == PPC::MTCTR || Opcode == PPC::MTCTR8) HasCTRSet = true;
    400 
    401   // Track the address stored to.
    402   if (isStore && NumStores < 4 && !MI->memoperands_empty()) {
    403     MachineMemOperand *MO = *MI->memoperands_begin();
    404     StoreSize[NumStores] = MO->getSize();
    405     StoreOffset[NumStores] = MO->getOffset();
    406     StoreValue[NumStores] = MO->getValue();
    407     ++NumStores;
    408   }
    409 
    410   if (InstrType == PPCII::PPC970_BRU || isSingle)
    411     NumIssued = 4;  // Terminate a d-group.
    412   ++NumIssued;
    413 
    414   // If this instruction is cracked into two ops by the decoder, remember that
    415   // we issued two pieces.
    416   if (isCracked)
    417     ++NumIssued;
    418 
    419   if (NumIssued == 5)
    420     EndDispatchGroup();
    421 }
    422 
    423 void PPCHazardRecognizer970::AdvanceCycle() {
    424   assert(NumIssued < 5 && "Illegal dispatch group!");
    425   ++NumIssued;
    426   if (NumIssued == 5)
    427     EndDispatchGroup();
    428 }
    429 
    430 void PPCHazardRecognizer970::Reset() {
    431   EndDispatchGroup();
    432 }
    433 
    434