Ensure that the nop that should follow a bl call in PPC64 ELF actually does
authorHal Finkel <hfinkel@anl.gov>
Thu, 15 Dec 2011 17:54:01 +0000 (17:54 +0000)
committerHal Finkel <hfinkel@anl.gov>
Thu, 15 Dec 2011 17:54:01 +0000 (17:54 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146664 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/PowerPC/PPCHazardRecognizers.cpp
lib/Target/PowerPC/PPCHazardRecognizers.h

index c90e2951a3cc5fddbfd41485cfcc05fbf1a9f1cf..ae317af4823a6f1f88ed0b03ebee0489d86f786b 100644 (file)
@@ -61,6 +61,7 @@ void PPCHazardRecognizer440::EmitInstruction(SUnit *SU) {
 
 PPCHazardRecognizer970::PPCHazardRecognizer970(const TargetInstrInfo &tii)
   : TII(tii) {
+  LastWasBL8_ELF = false;
   EndDispatchGroup();
 }
 
@@ -132,6 +133,14 @@ getHazardType(SUnit *SU, int Stalls) {
 
   unsigned Opcode = MI->getOpcode();
 
+  // If the last instruction was a BL8_ELF, then the NOP must follow it
+  // directly (this is strong requirement from the linker due to the ELF ABI).
+  // We return only Hazard (and not NoopHazard) because if the NOP is necessary
+  // then it will already be in the instruction stream (it is not always
+  // necessary; tail calls, for example, do not need it).
+  if (LastWasBL8_ELF && Opcode != PPC::NOP)
+    return Hazard;
+
   bool isFirst, isSingle, isCracked, isLoad, isStore;
   PPCII::PPC970_Unit InstrType =
     GetInstrType(Opcode, isFirst, isSingle, isCracked,
@@ -190,6 +199,7 @@ void PPCHazardRecognizer970::EmitInstruction(SUnit *SU) {
     return;
 
   unsigned Opcode = MI->getOpcode();
+  LastWasBL8_ELF = (Opcode == PPC::BL8_ELF);
 
   bool isFirst, isSingle, isCracked, isLoad, isStore;
   PPCII::PPC970_Unit InstrType =
@@ -230,6 +240,7 @@ void PPCHazardRecognizer970::AdvanceCycle() {
 }
 
 void PPCHazardRecognizer970::Reset() {
+  LastWasBL8_ELF = false;
   EndDispatchGroup();
 }
 
index 279567eaa0a1830345e7bae69dd98b3d816a680d..95d0d64972798a12b14449814a13e2753c3d2fd2 100644 (file)
@@ -49,6 +49,9 @@ class PPCHazardRecognizer970 : public ScheduleHazardRecognizer {
   // HasCTRSet - If the CTR register is set in this group, disallow BCTRL.
   bool HasCTRSet;
 
+  // Was the last instruction issued a BL8_ELF
+  bool LastWasBL8_ELF;
+
   // StoredPtr - Keep track of the address of any store.  If we see a load from
   // the same address (or one that aliases it), disallow the store.  We can have
   // up to four stores in one dispatch group, hence we track up to 4.