//===----------------------------------------------------------------------===//
#include "AArch64.h"
+#include "MCTargetDesc/AArch64AddressingModes.h"
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
class AArch64ConditionOptimizer : public MachineFunctionPass {
const TargetInstrInfo *TII;
MachineDominatorTree *DomTree;
+ const MachineRegisterInfo *MRI;
public:
// Stores immediate, compare instruction opcode and branch condition (in this
// order) of adjusted comparison.
- typedef std::tuple<int, int, AArch64CC::CondCode> CmpInfo;
+ typedef std::tuple<int, unsigned, AArch64CC::CondCode> CmpInfo;
static char ID;
AArch64ConditionOptimizer() : MachineFunctionPass(ID) {}
INITIALIZE_PASS_BEGIN(AArch64ConditionOptimizer, "aarch64-condopt",
"AArch64 CondOpt Pass", false, false)
INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
-INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
INITIALIZE_PASS_END(AArch64ConditionOptimizer, "aarch64-condopt",
"AArch64 CondOpt Pass", false, false)
void AArch64ConditionOptimizer::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<MachineDominatorTree>();
AU.addPreserved<MachineDominatorTree>();
- AU.addRequired<LiveIntervals>();
- AU.addPreserved<LiveIntervals>();
MachineFunctionPass::getAnalysisUsage(AU);
}
case AArch64::SUBSXri:
// cmn is an alias for adds with a dead destination register.
case AArch64::ADDSWri:
- case AArch64::ADDSXri:
- if (I->getOperand(0).isDead())
- return I;
-
- DEBUG(dbgs() << "Destination of cmp is not dead, " << *I << '\n');
- return nullptr;
-
+ case AArch64::ADDSXri: {
+ unsigned ShiftAmt = AArch64_AM::getShiftValue(I->getOperand(3).getImm());
+ if (!I->getOperand(2).isImm()) {
+ DEBUG(dbgs() << "Immediate of cmp is symbolic, " << *I << '\n');
+ return nullptr;
+ } else if (I->getOperand(2).getImm() << ShiftAmt >= 0xfff) {
+ DEBUG(dbgs() << "Immediate of cmp may be out of range, " << *I << '\n');
+ return nullptr;
+ } else if (!MRI->use_empty(I->getOperand(0).getReg())) {
+ DEBUG(dbgs() << "Destination of cmp is not dead, " << *I << '\n');
+ return nullptr;
+ }
+ return I;
+ }
// Prevent false positive case like:
// cmp w19, #0
// cinc w0, w19, gt
// operator and condition code.
AArch64ConditionOptimizer::CmpInfo AArch64ConditionOptimizer::adjustCmp(
MachineInstr *CmpMI, AArch64CC::CondCode Cmp) {
- int Opc = CmpMI->getOpcode();
+ unsigned Opc = CmpMI->getOpcode();
// CMN (compare with negative immediate) is an alias to ADDS (as
// "operand - negative" == "operand + positive")
void AArch64ConditionOptimizer::modifyCmp(MachineInstr *CmpMI,
const CmpInfo &Info) {
int Imm;
- int Opc;
+ unsigned Opc;
AArch64CC::CondCode Cmp;
std::tie(Imm, Opc, Cmp) = Info;
<< "********** Function: " << MF.getName() << '\n');
TII = MF.getSubtarget().getInstrInfo();
DomTree = &getAnalysis<MachineDominatorTree>();
+ MRI = &MF.getRegInfo();
bool Changed = false;