diff options
Diffstat (limited to 'llvm/lib/Target/Sparc')
-rw-r--r-- | llvm/lib/Target/Sparc/CMakeLists.txt | 1 | ||||
-rwxr-xr-x | llvm/lib/Target/Sparc/LeonFeatures.td | 8 | ||||
-rwxr-xr-x | llvm/lib/Target/Sparc/LeonPasses.cpp | 79 | ||||
-rwxr-xr-x | llvm/lib/Target/Sparc/LeonPasses.h | 46 | ||||
-rw-r--r-- | llvm/lib/Target/Sparc/Sparc.td | 8 | ||||
-rw-r--r-- | llvm/lib/Target/Sparc/SparcISelLowering.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Target/Sparc/SparcSubtarget.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/Target/Sparc/SparcSubtarget.h | 2 | ||||
-rw-r--r-- | llvm/lib/Target/Sparc/SparcTargetMachine.cpp | 10 | ||||
-rw-r--r-- | llvm/lib/Target/Sparc/SparcTargetMachine.h | 2 |
10 files changed, 152 insertions, 9 deletions
diff --git a/llvm/lib/Target/Sparc/CMakeLists.txt b/llvm/lib/Target/Sparc/CMakeLists.txt index 5b7bfdd2802..312215cf6cd 100644 --- a/llvm/lib/Target/Sparc/CMakeLists.txt +++ b/llvm/lib/Target/Sparc/CMakeLists.txt @@ -13,6 +13,7 @@ add_public_tablegen_target(SparcCommonTableGen) add_llvm_target(SparcCodeGen DelaySlotFiller.cpp + LeonPasses.cpp SparcAsmPrinter.cpp SparcInstrInfo.cpp SparcISelDAGToDAG.cpp diff --git a/llvm/lib/Target/Sparc/LeonFeatures.td b/llvm/lib/Target/Sparc/LeonFeatures.td index 5e62891c3ff..7de98407dac 100755 --- a/llvm/lib/Target/Sparc/LeonFeatures.td +++ b/llvm/lib/Target/Sparc/LeonFeatures.td @@ -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" +>; diff --git a/llvm/lib/Target/Sparc/LeonPasses.cpp b/llvm/lib/Target/Sparc/LeonPasses.cpp new file mode 100755 index 00000000000..0a99a9825f1 --- /dev/null +++ b/llvm/lib/Target/Sparc/LeonPasses.cpp @@ -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; +} diff --git a/llvm/lib/Target/Sparc/LeonPasses.h b/llvm/lib/Target/Sparc/LeonPasses.h new file mode 100755 index 00000000000..ea17b55bef3 --- /dev/null +++ b/llvm/lib/Target/Sparc/LeonPasses.h @@ -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 diff --git a/llvm/lib/Target/Sparc/Sparc.td b/llvm/lib/Target/Sparc/Sparc.td index 51e0b9acdb0..4fb82ff5c74 100644 --- a/llvm/lib/Target/Sparc/Sparc.td +++ b/llvm/lib/Target/Sparc/Sparc.td @@ -107,12 +107,12 @@ def : Processor<"leon2", LEON2Itineraries, // 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", LEON3Itineraries, // 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, diff --git a/llvm/lib/Target/Sparc/SparcISelLowering.cpp b/llvm/lib/Target/Sparc/SparcISelLowering.cpp index e5fbc477c06..23385a92579 100644 --- a/llvm/lib/Target/Sparc/SparcISelLowering.cpp +++ b/llvm/lib/Target/Sparc/SparcISelLowering.cpp @@ -1642,8 +1642,8 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM, 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); diff --git a/llvm/lib/Target/Sparc/SparcSubtarget.cpp b/llvm/lib/Target/Sparc/SparcSubtarget.cpp index f3b50d40323..3dd8a84ba47 100644 --- a/llvm/lib/Target/Sparc/SparcSubtarget.cpp +++ b/llvm/lib/Target/Sparc/SparcSubtarget.cpp @@ -39,6 +39,7 @@ SparcSubtarget &SparcSubtarget::initializeSubtargetDependencies(StringRef CPU, // Leon features HasLeonCasa = false; HasUmacSmac = false; + InsertNOPLoad = false; // Determine default and user specified characteristics std::string CPUName = CPU; diff --git a/llvm/lib/Target/Sparc/SparcSubtarget.h b/llvm/lib/Target/Sparc/SparcSubtarget.h index 4ad963e31d8..a69c2efd913 100644 --- a/llvm/lib/Target/Sparc/SparcSubtarget.h +++ b/llvm/lib/Target/Sparc/SparcSubtarget.h @@ -44,6 +44,7 @@ class SparcSubtarget : public SparcGenSubtargetInfo { // 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. diff --git a/llvm/lib/Target/Sparc/SparcTargetMachine.cpp b/llvm/lib/Target/Sparc/SparcTargetMachine.cpp index 80c78514831..cc2be3a9ef0 100644 --- a/llvm/lib/Target/Sparc/SparcTargetMachine.cpp +++ b/llvm/lib/Target/Sparc/SparcTargetMachine.cpp @@ -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(const Target &T, const Triple &TT, 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() { } diff --git a/llvm/lib/Target/Sparc/SparcTargetMachine.h b/llvm/lib/Target/Sparc/SparcTargetMachine.h index 8c056b3c361..48193fe095b 100644 --- a/llvm/lib/Target/Sparc/SparcTargetMachine.h +++ b/llvm/lib/Target/Sparc/SparcTargetMachine.h @@ -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 |