mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-14 14:24:05 +00:00
Add an MCID::Select flag and TII hooks for optimizing selects.
Select instructions pick one of two virtual registers based on a condition, like x86 cmov. On targets like ARM that support predication, selects can sometimes be eliminated by predicating the instruction defining one of the operands. Teach PeepholeOptimizer to recognize select instructions, and ask the target to optimize them. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162059 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -79,6 +79,7 @@ STATISTIC(NumBitcasts, "Number of bitcasts eliminated");
|
||||
STATISTIC(NumCmps, "Number of compares eliminated");
|
||||
STATISTIC(NumImmFold, "Number of move immediate folded");
|
||||
STATISTIC(NumLoadFold, "Number of loads folded");
|
||||
STATISTIC(NumSelects, "Number of selects optimized");
|
||||
|
||||
namespace {
|
||||
class PeepholeOptimizer : public MachineFunctionPass {
|
||||
@ -109,6 +110,7 @@ namespace {
|
||||
bool optimizeCmpInstr(MachineInstr *MI, MachineBasicBlock *MBB);
|
||||
bool optimizeExtInstr(MachineInstr *MI, MachineBasicBlock *MBB,
|
||||
SmallPtrSet<MachineInstr*, 8> &LocalMIs);
|
||||
bool optimizeSelect(MachineInstr *MI);
|
||||
bool isMoveImmediate(MachineInstr *MI,
|
||||
SmallSet<unsigned, 4> &ImmDefRegs,
|
||||
DenseMap<unsigned, MachineInstr*> &ImmDefMIs);
|
||||
@ -386,6 +388,23 @@ bool PeepholeOptimizer::optimizeCmpInstr(MachineInstr *MI,
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Optimize a select instruction.
|
||||
bool PeepholeOptimizer::optimizeSelect(MachineInstr *MI) {
|
||||
unsigned TrueOp = 0;
|
||||
unsigned FalseOp = 0;
|
||||
bool Optimizable = false;
|
||||
SmallVector<MachineOperand, 4> Cond;
|
||||
if (TII->analyzeSelect(MI, Cond, TrueOp, FalseOp, Optimizable))
|
||||
return false;
|
||||
if (!Optimizable)
|
||||
return false;
|
||||
if (!TII->optimizeSelect(MI))
|
||||
return false;
|
||||
MI->eraseFromParent();
|
||||
++NumSelects;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// isLoadFoldable - Check whether MI is a candidate for folding into a later
|
||||
/// instruction. We only fold loads to virtual registers and the virtual
|
||||
/// register defined has a single use.
|
||||
@ -496,22 +515,14 @@ bool PeepholeOptimizer::runOnMachineFunction(MachineFunction &MF) {
|
||||
if (MI->mayStore() || MI->isCall())
|
||||
FoldAsLoadDefReg = 0;
|
||||
|
||||
if (MI->isBitcast()) {
|
||||
if (optimizeBitcastInstr(MI, MBB)) {
|
||||
// MI is deleted.
|
||||
LocalMIs.erase(MI);
|
||||
Changed = true;
|
||||
MII = First ? I->begin() : llvm::next(PMII);
|
||||
continue;
|
||||
}
|
||||
} else if (MI->isCompare()) {
|
||||
if (optimizeCmpInstr(MI, MBB)) {
|
||||
// MI is deleted.
|
||||
LocalMIs.erase(MI);
|
||||
Changed = true;
|
||||
MII = First ? I->begin() : llvm::next(PMII);
|
||||
continue;
|
||||
}
|
||||
if ((MI->isBitcast() && optimizeBitcastInstr(MI, MBB)) ||
|
||||
(MI->isCompare() && optimizeCmpInstr(MI, MBB)) ||
|
||||
(MI->isSelect() && optimizeSelect(MI))) {
|
||||
// MI is deleted.
|
||||
LocalMIs.erase(MI);
|
||||
Changed = true;
|
||||
MII = First ? I->begin() : llvm::next(PMII);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isMoveImmediate(MI, ImmDefRegs, ImmDefMIs)) {
|
||||
|
Reference in New Issue
Block a user