28#define DEBUG_TYPE "tfr-cleanup"
66 bool isIntReg(
unsigned Reg,
bool &Is32);
67 void setReg(
unsigned R32,
uint32_t V32, ImmediateMap &IMap);
75char HexagonTfrCleanup::ID = 0;
81bool HexagonTfrCleanup::isIntReg(
unsigned Reg,
bool &Is32) {
82 Is32 = Hexagon::IntRegsRegClass.contains(Reg);
83 return Is32 || Hexagon::DoubleRegsRegClass.contains(Reg);
88void HexagonTfrCleanup::setReg(
unsigned R32,
uint32_t V32, ImmediateMap &IMap) {
94bool HexagonTfrCleanup::getReg(
unsigned Reg,
uint64_t &Val,
101 ImmediateMap::iterator
F = IMap.find(Reg);
110 unsigned SubL =
TRI->getSubReg(Reg, Hexagon::isub_lo);
111 unsigned SubH =
TRI->getSubReg(Reg, Hexagon::isub_hi);
112 ImmediateMap::iterator FL = IMap.find(SubL), FH = IMap.find(SubH);
113 if (FL == IMap.end() || FH == IMap.end())
115 Val = (FH->second << 32) | FL->second;
121bool HexagonTfrCleanup::updateImmMap(
MachineInstr *
MI, ImmediateMap &IMap) {
122 using namespace Hexagon;
131 unsigned Opc =
MI->getOpcode();
132 if (Opc == A2_tfrsi || Opc == A2_tfrpi) {
133 unsigned DefR =
MI->getOperand(0).getReg();
137 if (!
MI->getOperand(1).isImm()) {
139 IMap.erase(
TRI->getSubReg(DefR, isub_lo));
140 IMap.erase(
TRI->getSubReg(DefR, isub_hi));
149 uint32_t VH = (Val >> 32), VL = (Val & 0xFFFFFFFFU);
150 setReg(
TRI->getSubReg(DefR, isub_lo), VL, IMap);
151 setReg(
TRI->getSubReg(DefR, isub_hi), VH, IMap);
153 setReg(DefR, Val, IMap);
160 E =
MI->operands_end();
162 if (Mo->isRegMask()) {
166 if (!Mo->isReg() || !Mo->isDef())
168 unsigned R = Mo->getReg();
170 ImmediateMap::iterator
F = IMap.find(*AR);
180bool HexagonTfrCleanup::rewriteIfImm(
MachineInstr *
MI, ImmediateMap &IMap,
182 using namespace Hexagon;
183 unsigned Opc =
MI->getOpcode();
193 unsigned DstR =
MI->getOperand(0).getReg();
194 unsigned SrcR =
MI->getOperand(1).getReg();
198 assert(Tmp == Is32 &&
"Register size mismatch");
200 bool Found =
getReg(SrcR, Val, IMap);
206 int64_t SVal = Is32 ? int32_t(Val) : Val;
211 else if (isInt<8>(SVal))
213 else if (isInt<8>(SVal >> 32) && isInt<8>(int32_t(Val & 0xFFFFFFFFLL)))
214 NewMI =
BuildMI(
B,
MI,
DL, HII->get(A2_combineii), DstR)
215 .
addImm(int32_t(SVal >> 32))
216 .
addImm(int32_t(Val & 0xFFFFFFFFLL));
217 else if (HST.isTinyCore())
226 MI->eraseFromParent();
233 unsigned Opc =
MI->getOpcode();
235 bool IsUndef =
false;
237 case Hexagon::A2_tfr:
239 DefR =
MI->getOperand(0).getReg();
240 SrcR =
MI->getOperand(1).getReg();
241 IsUndef =
MI->getOperand(1).isUndef();
243 case Hexagon::A2_tfrt:
244 case Hexagon::A2_tfrf:
246 DefR =
MI->getOperand(0).getReg();
247 SrcR =
MI->getOperand(2).getReg();
248 IsUndef =
MI->getOperand(2).isUndef();
258 auto DefI =
BuildMI(
B,
MI,
DL, HII->get(TargetOpcode::IMPLICIT_DEF), DefR);
259 for (
auto &
Op :
MI->operands())
260 if (
Op.isReg() &&
Op.isDef() &&
Op.isImplicit())
261 DefI->addOperand(
Op);
266 MI->eraseFromParent();
271 bool Changed =
false;
275 auto *SIWrapper = getAnalysisIfAvailable<SlotIndexesWrapperPass>();
276 SlotIndexes *Indexes = SIWrapper ? &SIWrapper->getSI() :
nullptr;
280 TRI = HST.getRegisterInfo();
285 bool Inserted =
false, Erased =
false;
286 for (J =
B.begin(),
F =
B.end(); J !=
F; J = NextJ) {
287 NextJ = std::next(J);
289 bool E = eraseIfRedundant(
MI, Indexes);
295 updateImmMap(&*NewJ, IMap);
299 if (BlockC && Indexes)
313 return new HexagonTfrCleanup();
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
unsigned const TargetRegisterInfo * TRI
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Represent the analysis usage information of a pass.
void setPreservesAll()
Set by analyses that do not transform their input at all.
This class represents an Operation in the Expression.
FunctionPass class - This class is used to implement most global optimizations.
const HexagonInstrInfo * getInstrInfo() const override
MCRegAliasIterator enumerates all registers aliasing Reg.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
void removeMachineInstrFromMaps(MachineInstr &MI, bool AllowBundled=false)
Removes machine instruction (bundle) MI from the mapping.
void repairIndexesInRange(MachineBasicBlock *MBB, MachineBasicBlock::iterator Begin, MachineBasicBlock::iterator End)
Repair indexes after adding and removing instructions.
SlotIndex replaceMachineInstrInMaps(MachineInstr &MI, MachineInstr &NewMI)
ReplaceMachineInstrInMaps - Replacing a machine instr with a new one in maps used by register allocat...
StringRef - Represent a constant reference to a string, i.e.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
bool isIntReg(MCRegister Reg)
This is an optimization pass for GlobalISel generic memory operations.
char & HexagonTfrCleanupID
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
void initializeHexagonTfrCleanupPass(PassRegistry &)
FunctionPass * createHexagonTfrCleanup()