40#define DEBUG_TYPE "tfr-cleanup"
47 StringRef getPassName()
const override {
return "Hexagon TFR Cleanup"; }
60 bool isIntReg(
unsigned Reg,
bool &Is32);
61 void setReg(
unsigned R32,
uint32_t V32, ImmediateMap &IMap);
69char HexagonTfrCleanup::ID = 0;
75bool HexagonTfrCleanup::isIntReg(
unsigned Reg,
bool &Is32) {
76 Is32 = Hexagon::IntRegsRegClass.contains(
Reg);
77 return Is32 || Hexagon::DoubleRegsRegClass.contains(
Reg);
82void HexagonTfrCleanup::setReg(
unsigned R32, uint32_t V32, ImmediateMap &IMap) {
88bool HexagonTfrCleanup::getReg(
unsigned Reg, uint64_t &Val,
95 ImmediateMap::iterator
F = IMap.find(
Reg);
104 unsigned SubL =
TRI->getSubReg(
Reg, Hexagon::isub_lo);
105 unsigned SubH =
TRI->getSubReg(
Reg, Hexagon::isub_hi);
106 ImmediateMap::iterator FL = IMap.find(SubL), FH = IMap.find(SubH);
107 if (FL == IMap.end() || FH == IMap.end())
109 Val = (FH->second << 32) | FL->second;
115bool HexagonTfrCleanup::updateImmMap(MachineInstr *
MI, ImmediateMap &IMap) {
116 using namespace Hexagon;
125 unsigned Opc =
MI->getOpcode();
126 if (
Opc == A2_tfrsi ||
Opc == A2_tfrpi) {
127 unsigned DefR =
MI->getOperand(0).getReg();
131 if (!
MI->getOperand(1).isImm()) {
133 IMap.erase(
TRI->getSubReg(DefR, isub_lo));
134 IMap.erase(
TRI->getSubReg(DefR, isub_hi));
140 uint64_t Val =
MI->getOperand(1).getImm();
143 uint32_t VH = (Val >> 32), VL = (Val & 0xFFFFFFFFU);
144 setReg(
TRI->getSubReg(DefR, isub_lo), VL, IMap);
145 setReg(
TRI->getSubReg(DefR, isub_hi), VH, IMap);
147 setReg(DefR, Val, IMap);
154 E =
MI->operands_end();
156 if (Mo->isRegMask()) {
160 if (!Mo->isReg() || !Mo->isDef())
162 unsigned R = Mo->getReg();
163 for (MCRegAliasIterator AR(R,
TRI,
true); AR.isValid(); ++AR)
171bool HexagonTfrCleanup::rewriteIfImm(MachineInstr *
MI, ImmediateMap &IMap,
172 SlotIndexes *Indexes) {
173 using namespace Hexagon;
174 unsigned Opc =
MI->getOpcode();
184 unsigned DstR =
MI->getOperand(0).getReg();
185 unsigned SrcR =
MI->getOperand(1).getReg();
189 assert(Tmp == Is32 &&
"Register size mismatch");
191 bool Found =
getReg(SrcR, Val, IMap);
195 MachineBasicBlock &
B = *
MI->getParent();
197 int64_t SVal = Is32 ? int32_t(Val) : Val;
198 auto &HST =
B.getParent()->getSubtarget<HexagonSubtarget>();
205 NewMI =
BuildMI(
B,
MI,
DL, HII->get(A2_combineii), DstR)
206 .
addImm(int32_t(SVal >> 32))
207 .
addImm(int32_t(Val & 0xFFFFFFFFLL));
208 else if (HST.isTinyCore())
217 MI->eraseFromParent();
222bool HexagonTfrCleanup::eraseIfRedundant(MachineInstr *
MI,
223 SlotIndexes *Indexes) {
224 unsigned Opc =
MI->getOpcode();
226 bool IsUndef =
false;
228 case Hexagon::A2_tfr:
230 DefR =
MI->getOperand(0).getReg();
231 SrcR =
MI->getOperand(1).getReg();
232 IsUndef =
MI->getOperand(1).isUndef();
234 case Hexagon::A2_tfrt:
235 case Hexagon::A2_tfrf:
237 DefR =
MI->getOperand(0).getReg();
238 SrcR =
MI->getOperand(2).getReg();
239 IsUndef =
MI->getOperand(2).isUndef();
247 MachineBasicBlock &
B = *
MI->getParent();
249 auto DefI =
BuildMI(
B,
MI,
DL, HII->get(TargetOpcode::IMPLICIT_DEF), DefR);
250 for (
auto &
Op :
MI->operands())
251 if (
Op.isReg() &&
Op.isDef() &&
Op.isImplicit())
252 DefI->addOperand(
Op);
257 MI->eraseFromParent();
261bool HexagonTfrCleanup::runOnMachineFunction(MachineFunction &MF) {
266 auto *SIWrapper = getAnalysisIfAvailable<SlotIndexesWrapperPass>();
267 SlotIndexes *Indexes = SIWrapper ? &SIWrapper->getSI() :
nullptr;
270 HII = HST.getInstrInfo();
271 TRI = HST.getRegisterInfo();
273 for (MachineBasicBlock &
B : MF) {
276 bool Inserted =
false, Erased =
false;
277 for (J =
B.begin(),
F =
B.end(); J !=
F; J = NextJ) {
278 NextJ = std::next(J);
279 MachineInstr *
MI = &*J;
280 bool E = eraseIfRedundant(
MI, Indexes);
286 updateImmMap(&*NewJ, IMap);
290 if (BlockC && Indexes)
304 return new HexagonTfrCleanup();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Register const TargetRegisterInfo * TRI
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Represent the analysis usage information of a pass.
void setPreservesAll()
Set by analyses that do not transform their input at all.
FunctionPass class - This class is used to implement most global optimizations.
MachineInstrBundleIterator< MachineInstr > iterator
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.
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 * mop_iterator
iterator/begin/end - Iterate over all operands of a machine instruction.
LLVM_ABI void removeMachineInstrFromMaps(MachineInstr &MI, bool AllowBundled=false)
Removes machine instruction (bundle) MI from the mapping.
LLVM_ABI 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...
Represent a constant reference to a string, i.e.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
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.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
DWARFExpression::Operation Op
FunctionPass * createHexagonTfrCleanup()