40#define DEBUG_TYPE "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));
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();
171bool HexagonTfrCleanup::rewriteIfImm(
MachineInstr *
MI, ImmediateMap &IMap,
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);
197 int64_t SVal = Is32 ? int32_t(Val) : Val;
202 else if (isInt<8>(SVal))
204 else if (isInt<8>(SVal >> 32) && isInt<8>(int32_t(Val & 0xFFFFFFFFLL)))
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();
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();
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();
262 bool Changed =
false;
266 auto *SIWrapper = getAnalysisIfAvailable<SlotIndexesWrapperPass>();
267 SlotIndexes *Indexes = SIWrapper ? &SIWrapper->getSI() :
nullptr;
271 TRI = HST.getRegisterInfo();
276 bool Inserted =
false, Erased =
false;
277 for (J =
B.begin(),
F =
B.end(); J !=
F; J = NextJ) {
278 NextJ = std::next(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< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Register const TargetRegisterInfo * TRI
static unsigned 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.
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.
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
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...
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.
FunctionPass * createHexagonTfrCleanup()