//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "x86-codegen"
#include "X86.h"
#include "X86InstrInfo.h"
-#include "llvm/InlineAsm.h"
#include "llvm/ADT/DepthFirstIterator.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
-#include "llvm/ADT/STLExtras.h"
#include "llvm/CodeGen/EdgeBundles.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/InlineAsm.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
using namespace llvm;
+#define DEBUG_TYPE "x86-codegen"
+
STATISTIC(NumFXCH, "Number of fxch instructions inserted");
STATISTIC(NumFP , "Number of floating point instructions");
memset(RegMap, 0, sizeof(RegMap));
}
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.setPreservesCFG();
AU.addRequired<EdgeBundles>();
AU.addPreservedID(MachineLoopInfoID);
MachineFunctionPass::getAnalysisUsage(AU);
}
- virtual bool runOnMachineFunction(MachineFunction &MF);
+ bool runOnMachineFunction(MachineFunction &MF) override;
- virtual const char *getPassName() const { return "X86 FP Stackifier"; }
+ const char *getPassName() const override { return "X86 FP Stackifier"; }
private:
const TargetInstrInfo *TII; // Machine instruction info.
EdgeBundles *Bundles;
// Return a bitmask of FP registers in block's live-in list.
- unsigned calcLiveInMask(MachineBasicBlock *MBB) {
+ static unsigned calcLiveInMask(MachineBasicBlock *MBB) {
unsigned Mask = 0;
for (MachineBasicBlock::livein_iterator I = MBB->livein_begin(),
E = MBB->livein_end(); I != E; ++I) {
- unsigned Reg = *I - X86::FP0;
- if (Reg < 8)
- Mask |= 1 << Reg;
+ unsigned Reg = *I;
+ if (Reg < X86::FP0 || Reg > X86::FP6)
+ continue;
+ Mask |= 1 << (Reg - X86::FP0);
}
return Mask;
}
}
/// getScratchReg - Return an FP register that is not currently in use.
- unsigned getScratchReg() {
+ unsigned getScratchReg() const {
for (int i = NumFPRegs - 1; i >= 8; --i)
if (!isLive(i))
return i;
}
/// isScratchReg - Returns trus if RegNo is a scratch FP register.
- bool isScratchReg(unsigned RegNo) {
+ static bool isScratchReg(unsigned RegNo) {
return RegNo > 8 && RegNo < NumFPRegs;
}
void handleSpecialFP(MachineBasicBlock::iterator &I);
// Check if a COPY instruction is using FP registers.
- bool isFPCopy(MachineInstr *MI) {
+ static bool isFPCopy(MachineInstr *MI) {
unsigned DstReg = MI->getOperand(0).getReg();
unsigned SrcReg = MI->getOperand(1).getReg();
if (FPInstClass == X86II::NotFP)
continue; // Efficiently ignore non-fp insts!
- MachineInstr *PrevMI = 0;
+ MachineInstr *PrevMI = nullptr;
if (I != BB.begin())
- PrevMI = prior(I);
+ PrevMI = std::prev(I);
++NumFP; // Keep track of # of pseudo instrs
DEBUG(dbgs() << "\nFPInst:\t" << *MI);
} else {
MachineBasicBlock::iterator Start = I;
// Rewind to first instruction newly inserted.
- while (Start != BB.begin() && prior(Start) != PrevI) --Start;
+ while (Start != BB.begin() && std::prev(Start) != PrevI) --Start;
dbgs() << "Inserted instructions:\n\t";
Start->print(dbgs(), &MF.getTarget());
- while (++Start != llvm::next(I)) {}
+ while (++Start != std::next(I)) {}
}
dumpStack();
);
// Produce implicit-defs for free by using killed registers.
while (Kills && Defs) {
- unsigned KReg = CountTrailingZeros_32(Kills);
- unsigned DReg = CountTrailingZeros_32(Defs);
+ unsigned KReg = countTrailingZeros(Kills);
+ unsigned DReg = countTrailingZeros(Defs);
DEBUG(dbgs() << "Renaming %FP" << KReg << " as imp %FP" << DReg << "\n");
std::swap(Stack[getSlot(KReg)], Stack[getSlot(DReg)]);
std::swap(RegMap[KReg], RegMap[DReg]);
// Kill registers by popping.
if (Kills && I != MBB->begin()) {
- MachineBasicBlock::iterator I2 = llvm::prior(I);
+ MachineBasicBlock::iterator I2 = std::prev(I);
while (StackTop) {
unsigned KReg = getStackEntry(0);
if (!(Kills & (1 << KReg)))
// Manually kill the rest.
while (Kills) {
- unsigned KReg = CountTrailingZeros_32(Kills);
+ unsigned KReg = countTrailingZeros(Kills);
DEBUG(dbgs() << "Killing %FP" << KReg << "\n");
freeStackSlotBefore(I, KReg);
Kills &= ~(1 << KReg);
// Load zeros for all the imp-defs.
while(Defs) {
- unsigned DReg = CountTrailingZeros_32(Defs);
+ unsigned DReg = countTrailingZeros(Defs);
DEBUG(dbgs() << "Defining %FP" << DReg << " as 0\n");
BuildMI(*MBB, I, DebugLoc(), TII->get(X86::LD_F0));
pushReg(DReg);
// Note: this might be a non-optimal pop sequence. We might be able to do
// better by trying to pop in stack order or something.
while (FPKills) {
- unsigned FPReg = CountTrailingZeros_32(FPKills);
+ unsigned FPReg = countTrailingZeros(FPKills);
if (isLive(FPReg))
freeStackSlotAfter(InsertPt, FPReg);
FPKills &= ~(1U << FPReg);
BuildMI(*MBB, I, MI->getDebugLoc(), TII->get(X86::CALLpcrel32))
.addExternalSymbol("_ftol2")
.addReg(X86::ST0, RegState::ImplicitKill)
+ .addReg(X86::ECX, RegState::ImplicitDefine)
.addReg(X86::EAX, RegState::Define | RegState::Implicit)
.addReg(X86::EDX, RegState::Define | RegState::Implicit)
.addReg(X86::EFLAGS, RegState::Define | RegState::Implicit);
break;
}
- case X86::RET:
- case X86::RETI:
+ case X86::RETQ:
+ case X86::RETL:
+ case X86::RETIL:
+ case X86::RETIQ:
// If RET has an FP register use operand, pass the first one in ST(0) and
// the second one in ST(1).