Go to the documentation of this file.
38 #define DEBUG_TYPE "mir-canonicalizer"
43 cl::desc(
"Function number to canonicalize."));
53 return "Rename register operands in a canonical ordering.";
71 "Rename Register Operands Canonically",
false,
false)
80 std::vector<MachineBasicBlock *> RPOList;
92 using StringInstrPair = std::pair<std::string, MachineInstr *>;
93 std::vector<StringInstrPair> StringInstrMap;
102 const size_t i =
S.find(
'=');
103 StringInstrMap.push_back({(
i == std::string::npos) ?
S :
S.substr(
i), II});
108 for (
auto &II : StringInstrMap) {
111 dbgs() <<
"Splicing ";
113 dbgs() <<
" right before: ";
127 bool Changed =
false;
132 for (
auto &CurMI : *
MI.getParent()) {
143 for (
auto &
MI : *
MBB) {
147 std::map<MachineInstr *, std::vector<MachineInstr *>> MultiUsers;
148 std::map<unsigned, MachineInstr *> MultiUserLookup;
149 unsigned UseToBringDefCloserToCount = 0;
150 std::vector<MachineInstr *> PseudoIdempotentInstructions;
151 std::vector<unsigned> PhysRegDefs;
153 for (
unsigned i = 1;
i < II->getNumOperands();
i++) {
164 PhysRegDefs.push_back(MO.
getReg());
169 if (II->getNumOperands() == 0)
171 if (II->mayLoadOrStore())
180 bool IsPseudoIdempotent =
true;
181 for (
unsigned i = 1;
i < II->getNumOperands();
i++) {
183 if (II->getOperand(
i).isImm()) {
187 if (II->getOperand(
i).isReg()) {
194 IsPseudoIdempotent =
false;
198 if (IsPseudoIdempotent) {
199 PseudoIdempotentInstructions.push_back(II);
206 unsigned Distance = ~0U;
212 const unsigned DefLoc = getInstrIdx(*
Def);
213 const unsigned UseLoc = getInstrIdx(*UseInst);
214 const unsigned Delta = (UseLoc - DefLoc);
218 if (DefLoc >= UseLoc)
221 if (Delta < Distance) {
223 UseToBringDefCloserTo = UseInst;
224 MultiUserLookup[UseToBringDefCloserToCount++] = UseToBringDefCloserTo;
234 if (DefI != BBE && UseI != BBE)
242 if (&*BBI == UseToBringDefCloserTo) {
248 if (DefI == BBE || UseI == BBE)
252 dbgs() <<
"Splicing ";
254 dbgs() <<
" right before: ";
258 MultiUsers[UseToBringDefCloserTo].push_back(
Def);
264 for (
const auto &
E : MultiUserLookup) {
267 return &MI == E.second;
274 dbgs() <<
"Rescheduling Multi-Use Instructions Lexographically.";);
276 MultiUsers[
E.second],
MBB,
280 PseudoIdempotentInstCount = PseudoIdempotentInstructions.size();
282 dbgs() <<
"Rescheduling Idempotent Instructions Lexographically.";);
284 PseudoIdempotentInstructions,
MBB,
291 bool Changed =
false;
294 std::vector<MachineInstr *>
Copies;
302 if (!
MI->getOperand(0).isReg())
304 if (!
MI->getOperand(1).isReg())
307 const Register Dst =
MI->getOperand(0).getReg();
308 const Register Src =
MI->getOperand(1).getReg();
324 std::vector<MachineOperand *>
Uses;
327 for (
auto *MO :
Uses)
331 MI->eraseFromParent();
338 bool Changed =
false;
340 for (
auto &
MI : *
MBB) {
341 for (
auto &MO :
MI.operands()) {
344 if (!MO.isDef() && MO.isKill()) {
349 if (MO.isDef() && MO.isDead()) {
363 dbgs() <<
"\n\n================================================\n\n";
366 bool Changed =
false;
376 unsigned IdempotentInstCount = 0;
389 dbgs() <<
"\n\n================================================\n\n");
395 static unsigned functionNum = 0;
405 std::vector<MachineBasicBlock *> RPOList =
GetRPOList(MF);
408 dbgs() <<
"\n\n NEW MACHINE FUNCTION: " << MF.
getName() <<
" \n\n";
409 dbgs() <<
"\n\n================================================\n\n";
410 dbgs() <<
"Total Basic Blocks: " << RPOList.size() <<
"\n";
413 <<
"\n\n================================================\n\n";);
416 bool Changed =
false;
419 for (
auto MBB : RPOList)
This is an optimization pass for GlobalISel generic memory operations.
static bool runOnBasicBlock(MachineBasicBlock *MBB, unsigned BasicBlockNum, VRegRenamer &Renamer)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
A raw_ostream that writes to an std::string.
static bool propagateLocalCopies(MachineBasicBlock *MBB)
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
mir Rename Register Operands Canonically
static bool rescheduleCanonically(unsigned &PseudoIdempotentInstCount, MachineBasicBlock *MBB)
Code Generation Notes for reduce the size of the ISel and reduce repetition in the implementation In a small number of this can cause even when no optimisation has taken place Instructions
iterator_range< use_iterator > use_operands(Register Reg) const
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
char & MIRCanonicalizerID
MIRCanonicalizer - This pass canonicalizes MIR by renaming vregs according to the semantics of the in...
SmallPtrSet< MachineInstr *, 2 > Uses
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
iterator_range< use_nodbg_iterator > use_nodbg_operands(Register Reg) const
bool renameVRegs(MachineBasicBlock *MBB, unsigned BBNum)
Same as the above, but sets a BBNum depending on BB traversal that will be used as prefix for the vre...
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Function object to check whether the first component of a std::pair compares less than the first comp...
Represent the analysis usage information of a pass.
MachineOperand class - Representation of each machine instruction operand.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
mir Rename Register Operands
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
inst_range instructions(Function *F)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Representation of each machine instruction.
initializer< Ty > init(const Ty &Val)
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.
INITIALIZE_PASS_BEGIN(MIRCanonicalizer, "mir-canonicalizer", "Rename Register Operands Canonically", false, false) INITIALIZE_PASS_END(MIRCanonicalizer
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
const TargetRegisterClass * getRegClassOrNull(Register Reg) const
Return the register class of Reg, or null if Reg has not been assigned a register class yet.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
print Print MemDeps of function
Register getReg() const
getReg - Returns the register number.
instr_iterator instr_begin()
instr_iterator instr_end()
void setPreservesCFG()
This function should be called by the pass, iff they do not:
StringRef - Represent a constant reference to a string, i.e.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
void append_range(Container &C, Range &&R)
Wrapper function to append a range to a container.
static bool rescheduleLexographically(std::vector< MachineInstr * > instructions, MachineBasicBlock *MBB, std::function< MachineBasicBlock::iterator()> getPos)
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
const MachineBasicBlock * getParent() const
unsigned const MachineRegisterInfo * MRI
Wrapper class representing virtual and physical registers.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
static bool doDefKillClear(MachineBasicBlock *MBB)
mir Rename Register Operands static false std::vector< MachineBasicBlock * > GetRPOList(MachineFunction &MF)
void sort(IteratorTy Start, IteratorTy End)
VRegRenamer - This class is used for renaming vregs in a machine basic block according to semantics o...
StringRef getName() const
Return the name of the corresponding LLVM basic block, or an empty string.
static cl::opt< unsigned > CanonicalizeFunctionNumber("canon-nth-function", cl::Hidden, cl::init(~0u), cl::value_desc("N"), cl::desc("Function number to canonicalize."))