LLVM  10.0.0svn
LeonPasses.cpp
Go to the documentation of this file.
1 //===------ LeonPasses.cpp - Define passes specific to LEON ---------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 //
10 //===----------------------------------------------------------------------===//
11 
12 #include "LeonPasses.h"
18 #include "llvm/IR/DiagnosticInfo.h"
19 #include "llvm/IR/LLVMContext.h"
21 using namespace llvm;
22 
24  : MachineFunctionPass(ID) {}
25 
26 //*****************************************************************************
27 //**** InsertNOPLoad pass
28 //*****************************************************************************
29 // This pass fixes the incorrectly working Load instructions that exists for
30 // some earlier versions of the LEON processor line. NOP instructions must
31 // be inserted after the load instruction to ensure that the Load instruction
32 // behaves as expected for these processors.
33 //
34 // This pass inserts a NOP after any LD or LDF instruction.
35 //
36 char InsertNOPLoad::ID = 0;
37 
39 
43  DebugLoc DL = DebugLoc();
44 
45  bool Modified = false;
46  for (auto MFI = MF.begin(), E = MF.end(); MFI != E; ++MFI) {
47  MachineBasicBlock &MBB = *MFI;
48  for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; ++MBBI) {
49  MachineInstr &MI = *MBBI;
50  unsigned Opcode = MI.getOpcode();
51  if (Opcode >= SP::LDDArr && Opcode <= SP::LDrr) {
52  MachineBasicBlock::iterator NMBBI = std::next(MBBI);
53  BuildMI(MBB, NMBBI, DL, TII.get(SP::NOP));
54  Modified = true;
55  }
56  }
57  }
58 
59  return Modified;
60 }
61 
62 
63 
64 //*****************************************************************************
65 //**** DetectRoundChange pass
66 //*****************************************************************************
67 // To prevent any explicit change of the default rounding mode, this pass
68 // detects any call of the fesetround function.
69 // A warning is generated to ensure the user knows this has happened.
70 //
71 // Detects an erratum in UT699 LEON 3 processor
72 
73 char DetectRoundChange::ID = 0;
74 
76 
79 
80  bool Modified = false;
81  for (auto MFI = MF.begin(), E = MF.end(); MFI != E; ++MFI) {
82  MachineBasicBlock &MBB = *MFI;
83  for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; ++MBBI) {
84  MachineInstr &MI = *MBBI;
85  unsigned Opcode = MI.getOpcode();
86  if (Opcode == SP::CALL && MI.getNumOperands() > 0) {
87  MachineOperand &MO = MI.getOperand(0);
88 
89  if (MO.isGlobal()) {
90  StringRef FuncName = MO.getGlobal()->getName();
91  if (FuncName.compare_lower("fesetround") == 0) {
92  errs() << "Error: You are using the detectroundchange "
93  "option to detect rounding changes that will "
94  "cause LEON errata. The only way to fix this "
95  "is to remove the call to fesetround from "
96  "the source code.\n";
97  }
98  }
99  }
100  }
101  }
102 
103  return Modified;
104 }
105 
106 //*****************************************************************************
107 //**** FixAllFDIVSQRT pass
108 //*****************************************************************************
109 // This pass fixes the incorrectly working FDIVx and FSQRTx instructions that
110 // exist for some earlier versions of the LEON processor line. Five NOP
111 // instructions need to be inserted after these instructions to ensure the
112 // correct result is placed in the destination registers before they are used.
113 //
114 // This pass implements two fixes:
115 // 1) fixing the FSQRTS and FSQRTD instructions.
116 // 2) fixing the FDIVS and FDIVD instructions.
117 //
118 // FSQRTS and FDIVS are converted to FDIVD and FSQRTD respectively earlier in
119 // the pipeline when this option is enabled, so this pass needs only to deal
120 // with the changes that still need implementing for the "double" versions
121 // of these instructions.
122 //
123 char FixAllFDIVSQRT::ID = 0;
124 
126 
130  DebugLoc DL = DebugLoc();
131 
132  bool Modified = false;
133  for (auto MFI = MF.begin(), E = MF.end(); MFI != E; ++MFI) {
134  MachineBasicBlock &MBB = *MFI;
135  for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; ++MBBI) {
136  MachineInstr &MI = *MBBI;
137  unsigned Opcode = MI.getOpcode();
138 
139  // Note: FDIVS and FSQRTS cannot be generated when this erratum fix is
140  // switched on so we don't need to check for them here. They will
141  // already have been converted to FSQRTD or FDIVD earlier in the
142  // pipeline.
143  if (Opcode == SP::FSQRTD || Opcode == SP::FDIVD) {
144  for (int InsertedCount = 0; InsertedCount < 5; InsertedCount++)
145  BuildMI(MBB, MBBI, DL, TII.get(SP::NOP));
146 
147  MachineBasicBlock::iterator NMBBI = std::next(MBBI);
148  for (int InsertedCount = 0; InsertedCount < 28; InsertedCount++)
149  BuildMI(MBB, NMBBI, DL, TII.get(SP::NOP));
150 
151  Modified = true;
152  }
153  }
154  }
155 
156  return Modified;
157 }
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
DILocation * get() const
Get the underlying DILocation.
Definition: DebugLoc.cpp:21
This class represents lattice values for constants.
Definition: AllocatorList.h:23
static char ID
Definition: LeonPasses.h:75
static char ID
Definition: LeonPasses.h:47
A debug info location.
Definition: DebugLoc.h:33
const SparcInstrInfo * getInstrInfo() const override
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
unsigned getNumOperands() const
Retuns the total number of operands.
Definition: MachineInstr.h:414
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:411
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
Definition: LeonPasses.cpp:40
TargetInstrInfo - Interface to description of machine instruction set.
const SparcSubtarget * Subtarget
Definition: LeonPasses.h:26
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const GlobalValue * getGlobal() const
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
Definition: LeonPasses.cpp:127
LLVM_NODISCARD int compare_lower(StringRef RHS) const
compare_lower - Compare two strings, ignoring case.
Definition: StringRef.cpp:37
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
MachineOperand class - Representation of each machine instruction operand.
Representation of each machine instruction.
Definition: MachineInstr.h:64
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
Definition: LeonPasses.cpp:77
StringRef getName() const
Return a constant reference to the value&#39;s name.
Definition: Value.cpp:214
IRTranslator LLVM IR MI
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:416