[llvm] r270417 - [Sparc][LEON] LEON Erratum fix. Insert NOP after LD or LDF instruction.

Chris Dewhurst via llvm-commits llvm-commits at lists.llvm.org
Mon May 23 03:56:38 PDT 2016


Author: lerochris
Date: Mon May 23 05:56:36 2016
New Revision: 270417

URL: http://llvm.org/viewvc/llvm-project?rev=270417&view=rev
Log:
[Sparc][LEON] LEON Erratum fix. Insert NOP after LD or LDF instruction.

Due to an erratum in some versions of LEON, we must insert a NOP after any LD or LDF instruction to ensure the processor has time to load the value correctly before using it. This pass will implement that erratum fix.

The code will have no effect for other Sparc, but non-LEON processors.

Differential Review: http://reviews.llvm.org/D20353

Added:
    llvm/trunk/lib/Target/Sparc/LeonPasses.cpp   (with props)
    llvm/trunk/lib/Target/Sparc/LeonPasses.h   (with props)
    llvm/trunk/test/CodeGen/SPARC/LeonInsertNOPLoadPassUT.ll   (with props)
Modified:
    llvm/trunk/lib/Target/Sparc/CMakeLists.txt
    llvm/trunk/lib/Target/Sparc/LeonFeatures.td
    llvm/trunk/lib/Target/Sparc/Sparc.td
    llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp
    llvm/trunk/lib/Target/Sparc/SparcSubtarget.cpp
    llvm/trunk/lib/Target/Sparc/SparcSubtarget.h
    llvm/trunk/lib/Target/Sparc/SparcTargetMachine.cpp
    llvm/trunk/lib/Target/Sparc/SparcTargetMachine.h

Modified: llvm/trunk/lib/Target/Sparc/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/CMakeLists.txt?rev=270417&r1=270416&r2=270417&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Sparc/CMakeLists.txt (original)
+++ llvm/trunk/lib/Target/Sparc/CMakeLists.txt Mon May 23 05:56:36 2016
@@ -13,6 +13,7 @@ add_public_tablegen_target(SparcCommonTa
 
 add_llvm_target(SparcCodeGen
   DelaySlotFiller.cpp
+  LeonPasses.cpp
   SparcAsmPrinter.cpp
   SparcInstrInfo.cpp
   SparcISelDAGToDAG.cpp

Modified: llvm/trunk/lib/Target/Sparc/LeonFeatures.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/LeonFeatures.td?rev=270417&r1=270416&r2=270417&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Sparc/LeonFeatures.td (original)
+++ llvm/trunk/lib/Target/Sparc/LeonFeatures.td Mon May 23 05:56:36 2016
@@ -36,4 +36,10 @@ def LeonCASA : SubtargetFeature<
   "true", 
   "Enable CASA instruction for LEON3 and LEON4 processors"
 >;
-  
\ No newline at end of file
+
+def InsertNOPLoad: SubtargetFeature<
+  "insertnopload",
+  "InsertNOPLoad",
+  "true",
+  "LEON3 erratum fix: Insert a NOP instruction after every single-cycle load instruction when the next instruction is another load/store instruction" 
+>;

Added: llvm/trunk/lib/Target/Sparc/LeonPasses.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/LeonPasses.cpp?rev=270417&view=auto
==============================================================================
--- llvm/trunk/lib/Target/Sparc/LeonPasses.cpp (added)
+++ llvm/trunk/lib/Target/Sparc/LeonPasses.cpp Mon May 23 05:56:36 2016
@@ -0,0 +1,79 @@
+//===------ LeonPasses.cpp - Define passes specific to LEON ---------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//
+//===----------------------------------------------------------------------===//
+
+#include "LeonPasses.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/ISDOpcodes.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+
+LEONMachineFunctionPass::LEONMachineFunctionPass(TargetMachine &tm, char& ID) :
+  MachineFunctionPass(ID)
+{
+}
+
+LEONMachineFunctionPass::LEONMachineFunctionPass(char& ID) :
+  MachineFunctionPass(ID)
+{
+}
+
+//*****************************************************************************
+//**** InsertNOPLoad pass
+//*****************************************************************************
+//This pass inserts a NOP after any LD or LDF instruction.
+//
+char InsertNOPLoad::ID = 0;
+
+InsertNOPLoad::InsertNOPLoad(TargetMachine &tm) :
+                    LEONMachineFunctionPass(tm, ID)
+{
+}
+
+bool InsertNOPLoad::runOnMachineFunction(MachineFunction& MF)
+{
+  Subtarget = &MF.getSubtarget<SparcSubtarget>();
+  const TargetInstrInfo& TII = *Subtarget->getInstrInfo();
+  DebugLoc DL = DebugLoc();
+
+  bool Modified = false;
+  for (auto MFI = MF.begin(), E = MF.end(); MFI != E; ++MFI) {
+    MachineBasicBlock &MBB = *MFI;
+    for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; ++ MBBI) {
+      MachineInstr &MI = *MBBI;
+      unsigned Opcode = MI.getOpcode();
+      if (Opcode >=  SP::LDDArr && Opcode <= SP::LDrr) {
+        //errs() << "Inserting NOP after LD instruction\n";
+        MachineBasicBlock::iterator NMBBI = std::next(MBBI);
+        BuildMI(MBB, NMBBI, DL, TII.get(SP::NOP));
+        Modified = true;
+      }
+      else if (MI.isInlineAsm()) {
+        std::string AsmString (MI.getOperand(InlineAsm::MIOp_AsmString)
+            .getSymbolName());
+        std::string LDOpCoode ("ld");
+        std::transform(AsmString.begin(), AsmString.end(), AsmString.begin(),
+            ::tolower);
+        if (AsmString.find(LDOpCoode) == 0) { // an inline ld or ldf instruction
+          //errs() << "Inserting NOP after LD instruction\n";
+          MachineBasicBlock::iterator NMBBI = std::next(MBBI);
+          BuildMI(MBB, NMBBI, DL, TII.get(SP::NOP));
+          Modified = true;
+        }
+      }
+    }
+  }
+
+  return Modified;
+}

Propchange: llvm/trunk/lib/Target/Sparc/LeonPasses.cpp
------------------------------------------------------------------------------
    svn:executable = *

Added: llvm/trunk/lib/Target/Sparc/LeonPasses.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/LeonPasses.h?rev=270417&view=auto
==============================================================================
--- llvm/trunk/lib/Target/Sparc/LeonPasses.h (added)
+++ llvm/trunk/lib/Target/Sparc/LeonPasses.h Mon May 23 05:56:36 2016
@@ -0,0 +1,46 @@
+//===------- LeonPasses.h - Define passes specific to LEON ----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_SPARC_LEON_PASSES_H
+#define LLVM_LIB_TARGET_SPARC_LEON_PASSES_H
+
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+
+#include "Sparc.h"
+#include "SparcSubtarget.h"
+
+using namespace llvm;
+
+class LEONMachineFunctionPass : public MachineFunctionPass {
+protected:
+  const SparcSubtarget *Subtarget;
+
+protected:
+  LEONMachineFunctionPass(TargetMachine &tm, char& ID);
+  LEONMachineFunctionPass(char& ID);
+};
+
+class InsertNOPLoad : public LEONMachineFunctionPass {
+public:
+  static char ID;
+
+  InsertNOPLoad(TargetMachine &tm);
+  bool runOnMachineFunction(MachineFunction& MF) override;
+
+  const char *getPassName() const override {
+    return "InsertNOPLoad: Erratum Fix LBR35: insert a NOP instruction after every single-cycle load instruction when the next instruction is another load/store instruction";
+  }
+};
+
+#endif

Propchange: llvm/trunk/lib/Target/Sparc/LeonPasses.h
------------------------------------------------------------------------------
    svn:executable = *

Modified: llvm/trunk/lib/Target/Sparc/Sparc.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/Sparc.td?rev=270417&r1=270416&r2=270417&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Sparc/Sparc.td (original)
+++ llvm/trunk/lib/Target/Sparc/Sparc.td Mon May 23 05:56:36 2016
@@ -107,12 +107,12 @@ def : Processor<"leon2", LEON2Itinerarie
 // LEON 2 FT (AT697E)
 // TO DO: Place-holder: Processor specific features will be added *very* soon here.
 def : Processor<"at697e", LEON2Itineraries,
-                [FeatureLeon]>;
+                [FeatureLeon, InsertNOPLoad]>;
 
 // LEON 2 FT (AT697F)
 // TO DO: Place-holder: Processor specific features will be added *very* soon here.
 def : Processor<"at697f", LEON2Itineraries,
-                [FeatureLeon]>;
+                [FeatureLeon, InsertNOPLoad]>;
 
 
 // LEON 3 FT generic
@@ -122,12 +122,12 @@ def : Processor<"leon3", LEON3Itinerarie
 // LEON 3 FT (UT699). Provides features for the UT699 processor
 // - covers all the erratum fixes for LEON3, but does not support the CASA instruction.
 def : Processor<"ut699", LEON3Itineraries, 
-                [FeatureLeon, UMACSMACSupport]>;
+                [FeatureLeon, InsertNOPLoad]>;
 
 // LEON3 FT (GR712RC). Provides features for the GR712RC processor.
 // - covers all the erratum fixed for LEON3 and support for the CASA instruction. 
 def : Processor<"gr712rc", LEON3Itineraries,
-                [FeatureLeon, UMACSMACSupport, LeonCASA]>;
+                [FeatureLeon, LeonCASA]>;
 
 // LEON 4 FT generic
 def : Processor<"leon4", LEON4Itineraries,

Modified: llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp?rev=270417&r1=270416&r2=270417&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp Mon May 23 05:56:36 2016
@@ -1642,8 +1642,8 @@ SparcTargetLowering::SparcTargetLowering
   if (Subtarget->isV9())
     setMaxAtomicSizeInBitsSupported(64);
   else if (false && Subtarget->hasLeonCasa())
-   // Test made to fail pending completion of AtomicExpandPass,
-   // as this will cause a regression until that work is completed.
+    // Test made to fail pending completion of AtomicExpandPass,
+    // as this will cause a regression until that work is completed.
     setMaxAtomicSizeInBitsSupported(32);
   else
     setMaxAtomicSizeInBitsSupported(0);

Modified: llvm/trunk/lib/Target/Sparc/SparcSubtarget.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcSubtarget.cpp?rev=270417&r1=270416&r2=270417&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Sparc/SparcSubtarget.cpp (original)
+++ llvm/trunk/lib/Target/Sparc/SparcSubtarget.cpp Mon May 23 05:56:36 2016
@@ -39,6 +39,7 @@ SparcSubtarget &SparcSubtarget::initiali
   // Leon features
   HasLeonCasa = false;
   HasUmacSmac = false;
+  InsertNOPLoad = false;
 
   // Determine default and user specified characteristics
   std::string CPUName = CPU;

Modified: llvm/trunk/lib/Target/Sparc/SparcSubtarget.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcSubtarget.h?rev=270417&r1=270416&r2=270417&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Sparc/SparcSubtarget.h (original)
+++ llvm/trunk/lib/Target/Sparc/SparcSubtarget.h Mon May 23 05:56:36 2016
@@ -44,6 +44,7 @@ class SparcSubtarget : public SparcGenSu
   // LEON features
   bool HasUmacSmac;
   bool HasLeonCasa;
+  bool InsertNOPLoad;
 
   SparcInstrInfo InstrInfo;
   SparcTargetLowering TLInfo;
@@ -83,6 +84,7 @@ public:
   // Leon options
   bool hasUmacSmac() const { return HasUmacSmac; }
   bool hasLeonCasa() const { return HasLeonCasa; }
+  bool insertNOPLoad() const { return InsertNOPLoad; }
 
   /// ParseSubtargetFeatures - Parses features string setting specified
   /// subtarget options.  Definition of function is auto generated by tblgen.

Modified: llvm/trunk/lib/Target/Sparc/SparcTargetMachine.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcTargetMachine.cpp?rev=270417&r1=270416&r2=270417&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Sparc/SparcTargetMachine.cpp (original)
+++ llvm/trunk/lib/Target/Sparc/SparcTargetMachine.cpp Mon May 23 05:56:36 2016
@@ -13,6 +13,7 @@
 #include "SparcTargetMachine.h"
 #include "SparcTargetObjectFile.h"
 #include "Sparc.h"
+#include "LeonPasses.h"
 #include "llvm/CodeGen/Passes.h"
 #include "llvm/CodeGen/TargetPassConfig.h"
 #include "llvm/IR/LegacyPassManager.h"
@@ -68,9 +69,9 @@ SparcTargetMachine::SparcTargetMachine(c
                                        CodeGenOpt::Level OL, bool is64bit)
     : LLVMTargetMachine(T, computeDataLayout(TT, is64bit), TT, CPU, FS, Options,
                         getEffectiveRelocModel(RM), CM, OL),
-      TLOF(make_unique<SparcELFTargetObjectFile>()) {
+      TLOF(make_unique<SparcELFTargetObjectFile>()),
+      Subtarget(TT, CPU, FS, *this, is64bit), is64Bit(is64bit) {
   initAsmInfo();
-  this->is64Bit = is64bit;
 }
 
 SparcTargetMachine::~SparcTargetMachine() {}
@@ -143,6 +144,11 @@ bool SparcPassConfig::addInstSelector()
 
 void SparcPassConfig::addPreEmitPass(){
   addPass(createSparcDelaySlotFillerPass(getSparcTargetMachine()));
+
+  if (this->getSparcTargetMachine().getSubtargetImpl()->insertNOPLoad())
+  {
+    addPass(new InsertNOPLoad(getSparcTargetMachine()));
+  }
 }
 
 void SparcV8TargetMachine::anchor() { }

Modified: llvm/trunk/lib/Target/Sparc/SparcTargetMachine.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcTargetMachine.h?rev=270417&r1=270416&r2=270417&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Sparc/SparcTargetMachine.h (original)
+++ llvm/trunk/lib/Target/Sparc/SparcTargetMachine.h Mon May 23 05:56:36 2016
@@ -22,6 +22,7 @@ namespace llvm {
 
 class SparcTargetMachine : public LLVMTargetMachine {
   std::unique_ptr<TargetLoweringObjectFile> TLOF;
+  SparcSubtarget Subtarget;
   bool is64Bit;
   mutable StringMap<std::unique_ptr<SparcSubtarget>> SubtargetMap;
 public:
@@ -31,6 +32,7 @@ public:
                      CodeGenOpt::Level OL, bool is64bit);
   ~SparcTargetMachine() override;
 
+  const SparcSubtarget *getSubtargetImpl() const { return &Subtarget; }
   const SparcSubtarget *getSubtargetImpl(const Function &) const override;
 
   // Pass Pipeline Configuration

Added: llvm/trunk/test/CodeGen/SPARC/LeonInsertNOPLoadPassUT.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/SPARC/LeonInsertNOPLoadPassUT.ll?rev=270417&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/SPARC/LeonInsertNOPLoadPassUT.ll (added)
+++ llvm/trunk/test/CodeGen/SPARC/LeonInsertNOPLoadPassUT.ll Mon May 23 05:56:36 2016
@@ -0,0 +1,43 @@
+; RUN: llc %s -O0 -march=sparc -mcpu=ut699 -o - | FileCheck %s
+; RUN: llc %s -O0 -march=sparc -mcpu=leon3 -mattr=+insertnopload -o - | FileCheck %s
+
+; CHECK-LABEL: ld_float_test
+; CHECK:       ld [%o0+%lo(.LCPI0_0)], %f0
+; CHECK-NEXT:  nop
+define float @ld_float_test() #0 {
+entry:
+  %f = alloca float, align 4
+  store float 0x3FF3C08320000000, float* %f, align 4
+  %0 = load float, float* %f, align 4
+  ret float %0
+}
+
+; CHECK-LABEL: ld_i32_test
+; CHECK:       ld [%o0], %o0
+; CHECK-NEXT:  nop
+define i32 @ld_i32_test(i32 *%p) {
+  %res = load i32, i32* %p
+  ret i32 %res
+}
+
+; CHECK-LABEL: ld_inlineasm_test_1
+; CHECK:       ld [%o0], %o0
+; CHECK-NEXT:  !NO_APP
+; CHECK-NEXT:  nop
+define float @ld_inlineasm_test_1(float* %a) {
+entry:
+  %res = tail call float asm sideeffect "ld [$1], $0", "=r,r"(float* %a)
+
+  ret float %res
+}
+
+; CHECK-LABEL: ld_inlineasm_test_2
+; CHECK:       ld [%o0], %o0
+; CHECK-NEXT:  !NO_APP
+; CHECK-NEXT:  nop
+define i32 @ld_inlineasm_test_2(i32* %a) {
+entry:
+  %res = tail call i32 asm sideeffect "ld [$1], $0", "=r,r"(i32* %a)
+
+  ret i32 %res
+}
\ No newline at end of file

Propchange: llvm/trunk/test/CodeGen/SPARC/LeonInsertNOPLoadPassUT.ll
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: llvm/trunk/test/CodeGen/SPARC/LeonInsertNOPLoadPassUT.ll
------------------------------------------------------------------------------
    svn:executable = *




More information about the llvm-commits mailing list