28#define DEBUG_TYPE "tfr-cleanup"
72 bool isIntReg(
unsigned Reg,
bool &Is32);
73 void setReg(
unsigned R32,
uint32_t V32, ImmediateMap &IMap);
81char HexagonTfrCleanup::ID = 0;
87bool HexagonTfrCleanup::isIntReg(
unsigned Reg,
bool &Is32) {
88 Is32 = Hexagon::IntRegsRegClass.contains(Reg);
89 return Is32 || Hexagon::DoubleRegsRegClass.contains(Reg);
94void HexagonTfrCleanup::setReg(
unsigned R32,
uint32_t V32, ImmediateMap &IMap) {
95 ImmediateMap::iterator
F = IMap.find(R32);
97 IMap.insert(std::make_pair(R32, V32));
104bool HexagonTfrCleanup::getReg(
unsigned Reg,
uint64_t &Val,
105 ImmediateMap &IMap) {
111 ImmediateMap::iterator
F = IMap.find(Reg);
120 unsigned SubL =
TRI->getSubReg(Reg, Hexagon::isub_lo);
121 unsigned SubH =
TRI->getSubReg(Reg, Hexagon::isub_hi);
122 ImmediateMap::iterator FL = IMap.find(SubL), FH = IMap.find(SubH);
123 if (FL == IMap.end() || FH == IMap.end())
125 Val = (FH->second << 32) | FL->second;
131bool HexagonTfrCleanup::updateImmMap(
MachineInstr *
MI, ImmediateMap &IMap) {
132 using namespace Hexagon;
141 unsigned Opc =
MI->getOpcode();
142 if (Opc == A2_tfrsi || Opc == A2_tfrpi) {
143 unsigned DefR =
MI->getOperand(0).getReg();
147 if (!
MI->getOperand(1).isImm()) {
149 IMap.erase(
TRI->getSubReg(DefR, isub_lo));
150 IMap.erase(
TRI->getSubReg(DefR, isub_hi));
159 uint32_t VH = (Val >> 32), VL = (Val & 0xFFFFFFFFU);
160 setReg(
TRI->getSubReg(DefR, isub_lo), VL, IMap);
161 setReg(
TRI->getSubReg(DefR, isub_hi), VH, IMap);
163 setReg(DefR, Val, IMap);
170 E =
MI->operands_end();
172 if (Mo->isRegMask()) {
176 if (!Mo->isReg() || !Mo->isDef())
178 unsigned R = Mo->getReg();
180 ImmediateMap::iterator
F = IMap.find(*AR);
190bool HexagonTfrCleanup::rewriteIfImm(
MachineInstr *
MI, ImmediateMap &IMap,
192 using namespace Hexagon;
193 unsigned Opc =
MI->getOpcode();
203 unsigned DstR =
MI->getOperand(0).getReg();
204 unsigned SrcR =
MI->getOperand(1).getReg();
208 assert(Tmp == Is32 &&
"Register size mismatch");
210 bool Found =
getReg(SrcR, Val, IMap);
216 int64_t SVal = Is32 ? int32_t(Val) : Val;
221 else if (isInt<8>(SVal))
223 else if (isInt<8>(SVal >> 32) && isInt<8>(int32_t(Val & 0xFFFFFFFFLL)))
224 NewMI =
BuildMI(
B,
MI,
DL, HII->get(A2_combineii), DstR)
225 .
addImm(int32_t(SVal >> 32))
226 .
addImm(int32_t(Val & 0xFFFFFFFFLL));
227 else if (HST.isTinyCore())
236 MI->eraseFromParent();
243 unsigned Opc =
MI->getOpcode();
245 bool IsUndef =
false;
247 case Hexagon::A2_tfr:
249 DefR =
MI->getOperand(0).getReg();
250 SrcR =
MI->getOperand(1).getReg();
251 IsUndef =
MI->getOperand(1).isUndef();
253 case Hexagon::A2_tfrt:
254 case Hexagon::A2_tfrf:
256 DefR =
MI->getOperand(0).getReg();
257 SrcR =
MI->getOperand(2).getReg();
258 IsUndef =
MI->getOperand(2).isUndef();
268 auto DefI =
BuildMI(
B,
MI,
DL, HII->get(TargetOpcode::IMPLICIT_DEF), DefR);
269 for (
auto &
Op :
MI->operands())
270 if (
Op.isReg() &&
Op.isDef() &&
Op.isImplicit())
271 DefI->addOperand(
Op);
276 MI->eraseFromParent();
281 bool Changed =
false;
285 auto *SIWrapper = getAnalysisIfAvailable<SlotIndexesWrapperPass>();
286 SlotIndexes *Indexes = SIWrapper ? &SIWrapper->getSI() :
nullptr;
290 TRI = HST.getRegisterInfo();
295 bool Inserted =
false, Erased =
false;
296 for (J =
B.begin(),
F =
B.end(); J !=
F; J = NextJ) {
297 NextJ = std::next(J);
299 bool E = eraseIfRedundant(
MI, Indexes);
305 updateImmMap(&*NewJ, IMap);
309 if (BlockC && Indexes)
323 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(unsigned 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()