Go to the documentation of this file.
88 #define DEBUG_TYPE "aarch64-condopt"
90 STATISTIC(NumConditionsAdjusted,
"Number of conditions adjusted");
102 using CmpInfo = std::tuple<int, unsigned, AArch64CC::CondCode>;
119 return "AArch64 Condition Optimizer";
128 "AArch64 CondOpt Pass",
false,
false)
134 return new AArch64ConditionOptimizer();
137 void AArch64ConditionOptimizer::getAnalysisUsage(
AnalysisUsage &AU)
const {
146 MachineInstr *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))
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) {
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;
243 AArch64ConditionOptimizer::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))) {
271 void 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");
317 bool AArch64ConditionOptimizer::adjustTo(
MachineInstr *CmpMI,
320 CmpInfo
Info = adjustCmp(CmpMI, Cmp);
322 modifyCmp(CmpMI,
Info);
328 bool AArch64ConditionOptimizer::runOnMachineFunction(
MachineFunction &MF) {
329 LLVM_DEBUG(
dbgs() <<
"********** AArch64 Conditional Compares **********\n"
330 <<
"********** Function: " << MF.
getName() <<
'\n');
335 DomTree = &getAnalysis<MachineDominatorTree>();
338 bool Changed =
false;
376 if (HeadCond.empty() || !
parseCond(HeadCond, HeadCmp)) {
381 if (TrueCond.empty() || !
parseCond(TrueCond, TrueCmp)) {
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);
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);
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
This is an optimization pass for GlobalISel generic memory operations.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
const MachineInstrBuilder & add(const MachineOperand &MO) const
virtual const TargetInstrInfo * getInstrInfo() const
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....
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
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.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static AArch64CC::CondCode getAdjustedCmp(AArch64CC::CondCode Cmp)
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
TargetInstrInfo - Interface to description of machine instruction set.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
const MachineOperand & getOperand(unsigned i) const
Clang compiles this i1 i64 store i64 i64 store i64 i64 store i64 i64 store i64 align Which gets codegen d xmm0 movaps rbp movaps rbp movaps rbp movaps rbp rbp rbp rbp rbp It would be better to have movq s of instead of the movaps s LLVM produces ret int
Represent the analysis usage information of a pass.
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const HexagonInstrInfo * TII
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
STATISTIC(NumFunctions, "Total number of functions")
static unsigned getShiftValue(unsigned Imm)
getShiftValue - Extract the shift value.
static const char * getCondCodeName(CondCode Code)
Analysis containing CSE Info
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
INITIALIZE_PASS_BEGIN(AArch64ConditionOptimizer, "aarch64-condopt", "AArch64 CondOpt Pass", false, false) INITIALIZE_PASS_END(AArch64ConditionOptimizer
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Representation of each machine instruction.
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
IterT prev_nodbg(IterT It, IterT Begin, bool SkipPseudoOp=true)
Decrement It, then continue decrementing it while it points to a debug instruction.
static int getComplementOpc(int Opc)
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool use_nodbg_empty(Register RegNo) const
use_nodbg_empty - Return true if there are no non-Debug instructions using the specified register.
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
SmallVector< MachineOperand, 4 > Cond
iterator_range< succ_iterator > successors()
StringRef - Represent a constant reference to a string, i.e.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
const MachineBasicBlock * getParent() const
Base class for the actual dominator tree node.
unsigned const MachineRegisterInfo * MRI
iterator_range< df_iterator< T > > depth_first(const T &G)
Function & getFunction()
Return the LLVM function that this machine code represents.
Pass interface - Implemented by all 'passes'.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
FunctionPass * createAArch64ConditionOptimizerPass()
void initializeAArch64ConditionOptimizerPass(PassRegistry &)
FunctionPass class - This class is used to implement most global optimizations.
AnalysisUsage & addRequired()
static bool parseCond(ArrayRef< MachineOperand > Cond, AArch64CC::CondCode &CC)
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
APFloat abs(APFloat X)
Returns the absolute value of the argument.