88#define DEBUG_TYPE "aarch64-condopt"
90STATISTIC(NumConditionsAdjusted,
"Number of conditions adjusted");
102 using CmpInfo = std::tuple<int, unsigned, AArch64CC::CondCode>;
113 void modifyCmp(
MachineInstr *CmpMI,
const CmpInfo &Info);
119 return "AArch64 Condition Optimizer";
125char AArch64ConditionOptimizer::ID = 0;
128 "AArch64 CondOpt Pass",
false,
false)
134 return new AArch64ConditionOptimizer();
137void AArch64ConditionOptimizer::getAnalysisUsage(
AnalysisUsage &AU)
const {
146MachineInstr *AArch64ConditionOptimizer::findSuitableCompare(
152 if (
Term->getOpcode() != AArch64::Bcc)
157 if (SuccBB->isLiveIn(AArch64::NZCV))
164 assert(!
I.isTerminator() &&
"Spurious terminator");
166 if (
I.readsRegister(AArch64::NZCV,
nullptr))
168 switch (
I.getOpcode()) {
170 case AArch64::SUBSWri:
171 case AArch64::SUBSXri:
173 case AArch64::ADDSWri:
174 case AArch64::ADDSXri: {
176 if (!
I.getOperand(2).isImm()) {
179 }
else if (
I.getOperand(2).getImm() << ShiftAmt >= 0xfff) {
183 }
else if (!
MRI->use_nodbg_empty(
I.getOperand(0).getReg())) {
195 case AArch64::FCMPDri:
196 case AArch64::FCMPSri:
197 case AArch64::FCMPESri:
198 case AArch64::FCMPEDri:
200 case AArch64::SUBSWrr:
201 case AArch64::SUBSXrr:
202 case AArch64::ADDSWrr:
203 case AArch64::ADDSXrr:
204 case AArch64::FCMPSrr:
205 case AArch64::FCMPDrr:
206 case AArch64::FCMPESrr:
207 case AArch64::FCMPEDrr:
220 case AArch64::ADDSWri:
return AArch64::SUBSWri;
221 case AArch64::ADDSXri:
return AArch64::SUBSXri;
222 case AArch64::SUBSWri:
return AArch64::ADDSWri;
223 case AArch64::SUBSXri:
return AArch64::ADDSXri;
243AArch64ConditionOptimizer::CmpInfo AArch64ConditionOptimizer::adjustCmp(
249 bool Negative = (Opc == AArch64::ADDSWri || Opc == AArch64::ADDSXri);
254 Correction = -Correction;
258 const int NewImm = std::abs(OldImm + Correction);
262 if (OldImm == 0 && ((Negative && Correction == 1) ||
263 (!Negative && Correction == -1))) {
271void AArch64ConditionOptimizer::modifyCmp(
MachineInstr *CmpMI,
272 const CmpInfo &Info) {
276 std::tie(Imm, Opc, Cmp) =
Info;
298 ++NumConditionsAdjusted;
306 if (
Cond[0].getImm() != -1) {
307 assert(
Cond.size() == 1 &&
"Unknown Cond array format");
317bool AArch64ConditionOptimizer::adjustTo(
MachineInstr *CmpMI,
320 CmpInfo
Info = adjustCmp(CmpMI, Cmp);
321 if (std::get<0>(Info) == ToImm && std::get<1>(Info) == To->
getOpcode()) {
322 modifyCmp(CmpMI, Info);
328bool AArch64ConditionOptimizer::runOnMachineFunction(
MachineFunction &MF) {
329 LLVM_DEBUG(
dbgs() <<
"********** AArch64 Conditional Compares **********\n"
330 <<
"********** Function: " << MF.
getName() <<
'\n');
335 DomTree = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
338 bool Changed =
false;
400 std::abs(TrueImm - HeadImm) == 2) {
411 CmpInfo HeadCmpInfo = adjustCmp(HeadCmpMI, HeadCmp);
412 CmpInfo TrueCmpInfo = adjustCmp(TrueCmpMI, TrueCmp);
413 if (std::get<0>(HeadCmpInfo) == std::get<0>(TrueCmpInfo) &&
414 std::get<1>(HeadCmpInfo) == std::get<1>(TrueCmpInfo)) {
415 modifyCmp(HeadCmpMI, HeadCmpInfo);
416 modifyCmp(TrueCmpMI, TrueCmpInfo);
421 std::abs(TrueImm - HeadImm) == 1) {
434 bool adjustHeadCond = (HeadImm < TrueImm);
436 adjustHeadCond = !adjustHeadCond;
439 if (adjustHeadCond) {
440 Changed |= adjustTo(HeadCmpMI, HeadCmp, TrueCmpMI, TrueImm);
442 Changed |= adjustTo(TrueCmpMI, TrueCmp, HeadCmpMI, HeadImm);
unsigned const MachineRegisterInfo * MRI
static int getComplementOpc(int Opc)
static bool parseCond(ArrayRef< MachineOperand > Cond, AArch64CC::CondCode &CC)
static AArch64CC::CondCode getAdjustedCmp(AArch64CC::CondCode Cmp)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Analysis containing CSE Info
This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.
const HexagonInstrInfo * TII
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Base class for the actual dominator tree node.
FunctionPass class - This class is used to implement most global optimizations.
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
Analyze the branching code at the end of MBB, returning true if it cannot be understood (e....
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
iterator_range< succ_iterator > successors()
Analysis pass which computes a MachineDominatorTree.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
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.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const MachineOperand & getOperand(unsigned i) const
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Pass interface - Implemented by all 'passes'.
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
TargetInstrInfo - Interface to description of machine instruction set.
virtual const TargetInstrInfo * getInstrInfo() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static const char * getCondCodeName(CondCode Code)
static unsigned getShiftValue(unsigned Imm)
getShiftValue - Extract the shift value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionPass * createAArch64ConditionOptimizerPass()
iterator_range< df_iterator< T > > depth_first(const T &G)
void initializeAArch64ConditionOptimizerPass(PassRegistry &)
IterT prev_nodbg(IterT It, IterT Begin, bool SkipPseudoOp=true)
Decrement It, then continue decrementing it while it points to a debug instruction.
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.