aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/X86
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2004-04-01 04:06:09 +0000
committerChris Lattner <sabre@nondot.org>2004-04-01 04:06:09 +0000
commit0526f01fec0945eca49ccd91f22a93af6bb71c17 (patch)
treedf125c09c70d13daafc35c5c681710f99ff9f1cd /lib/Target/X86
parentf1ac50ec53889a4cf16ddc80907edc54119360d0 (diff)
downloadexternal_llvm-0526f01fec0945eca49ccd91f22a93af6bb71c17.zip
external_llvm-0526f01fec0945eca49ccd91f22a93af6bb71c17.tar.gz
external_llvm-0526f01fec0945eca49ccd91f22a93af6bb71c17.tar.bz2
Simplify code by using the more powerful BuildMI forms.
Implement a small optimization. In test/Regression/CodeGen/X86/select.ll, we now generate this for foldSel3: foldSel3: mov %AL, BYTE PTR [%ESP + 4] fld DWORD PTR [%ESP + 8] fld DWORD PTR [%ESP + 12] mov %EAX, DWORD PTR [%ESP + 16] mov %ECX, DWORD PTR [%ESP + 20] cmp %EAX, %ECX fxch %ST(1) fcmovae %ST(0), %ST(1) *** fstp %ST(1) ret Instead of: foldSel3: mov %AL, BYTE PTR [%ESP + 4] fld DWORD PTR [%ESP + 8] fld DWORD PTR [%ESP + 12] mov %EAX, DWORD PTR [%ESP + 16] mov %ECX, DWORD PTR [%ESP + 20] cmp %EAX, %ECX fxch %ST(1) fcmovae %ST(0), %ST(1) *** fxch %ST(1) *** fstp %ST(0) ret In practice, this only effects code size: performance should be basically unaffected. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@12588 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/X86')
-rw-r--r--lib/Target/X86/FloatingPoint.cpp75
-rw-r--r--lib/Target/X86/X86FloatingPoint.cpp75
2 files changed, 82 insertions, 68 deletions
diff --git a/lib/Target/X86/FloatingPoint.cpp b/lib/Target/X86/FloatingPoint.cpp
index f2ff6c5..b1a2ceb 100644
--- a/lib/Target/X86/FloatingPoint.cpp
+++ b/lib/Target/X86/FloatingPoint.cpp
@@ -118,25 +118,29 @@ namespace {
std::swap(Stack[RegMap[RegOnTop]], Stack[StackTop-1]);
// Emit an fxch to update the runtime processors version of the state
- MachineInstr *MI = BuildMI(X86::FXCH, 1).addReg(STReg);
- MBB->insert(I, MI);
+ BuildMI(*MBB, I, X86::FXCH, 1).addReg(STReg);
NumFXCH++;
}
}
- void duplicateToTop(unsigned RegNo, unsigned AsReg,
- MachineBasicBlock::iterator &I) {
+ void duplicateToTop(unsigned RegNo, unsigned AsReg, MachineInstr *I) {
unsigned STReg = getSTReg(RegNo);
pushReg(AsReg); // New register on top of stack
- MachineInstr *MI = BuildMI(X86::FLDrr, 1).addReg(STReg);
- MBB->insert(I, MI);
+ BuildMI(*MBB, I, X86::FLDrr, 1).addReg(STReg);
}
// popStackAfter - Pop the current value off of the top of the FP stack
// after the specified instruction.
void popStackAfter(MachineBasicBlock::iterator &I);
+ // freeStackSlotAfter - Free the specified register from the register stack,
+ // so that it is no longer in a register. If the register is currently at
+ // the top of the stack, we just pop the current instruction, otherwise we
+ // store the current top-of-stack into the specified slot, then pop the top
+ // of stack.
+ void freeStackSlotAfter(MachineBasicBlock::iterator &I, unsigned Reg);
+
bool processBasicBlock(MachineFunction &MF, MachineBasicBlock &MBB);
void handleZeroArgFP(MachineBasicBlock::iterator &I);
@@ -250,7 +254,7 @@ bool FPS::processBasicBlock(MachineFunction &MF, MachineBasicBlock &BB) {
DEBUG(
MachineBasicBlock::iterator PrevI(PrevMI);
if (I == PrevI) {
- std::cerr<< "Just deleted pseudo instruction\n";
+ std::cerr << "Just deleted pseudo instruction\n";
} else {
MachineBasicBlock::iterator Start = I;
// Rewind to first instruction newly inserted.
@@ -358,11 +362,34 @@ void FPS::popStackAfter(MachineBasicBlock::iterator &I) {
I->RemoveOperand(0);
} else { // Insert an explicit pop
- MachineInstr *MI = BuildMI(X86::FSTPrr, 1).addReg(X86::ST0);
- I = MBB->insert(++I, MI);
+ I = BuildMI(*MBB, ++I, X86::FSTPrr, 1).addReg(X86::ST0);
+ }
+}
+
+/// freeStackSlotAfter - Free the specified register from the register stack, so
+/// that it is no longer in a register. If the register is currently at the top
+/// of the stack, we just pop the current instruction, otherwise we store the
+/// current top-of-stack into the specified slot, then pop the top of stack.
+void FPS::freeStackSlotAfter(MachineBasicBlock::iterator &I, unsigned FPRegNo) {
+ if (getStackEntry(0) == FPRegNo) { // already at the top of stack? easy.
+ popStackAfter(I);
+ return;
}
+
+ // Otherwise, store the top of stack into the dead slot, killing the operand
+ // without having to add in an explicit xchg then pop.
+ //
+ unsigned STReg = getSTReg(FPRegNo);
+ unsigned OldSlot = getSlot(FPRegNo);
+ unsigned TopReg = Stack[StackTop-1];
+ Stack[OldSlot] = TopReg;
+ RegMap[TopReg] = OldSlot;
+ RegMap[FPRegNo] = ~0;
+ Stack[--StackTop] = ~0;
+ I = BuildMI(*MBB, ++I, X86::FSTPrr, 1).addReg(STReg);
}
+
static unsigned getFPReg(const MachineOperand &MO) {
assert(MO.isRegister() && "Expected an FP register!");
unsigned Reg = MO.getReg();
@@ -596,8 +623,7 @@ void FPS::handleTwoArgFP(MachineBasicBlock::iterator &I) {
// Replace the old instruction with a new instruction
MBB->remove(I++);
- BuildMI(*MBB, I, Opcode, 1).addReg(getSTReg(NotTOS));
- --I;
+ I = BuildMI(*MBB, I, Opcode, 1).addReg(getSTReg(NotTOS));
// If both operands are killed, pop one off of the stack in addition to
// overwriting the other one.
@@ -610,25 +636,8 @@ void FPS::handleTwoArgFP(MachineBasicBlock::iterator &I) {
if (MI->getOpcode() == X86::FpUCOM) {
if (KillsOp0 && !KillsOp1)
popStackAfter(I); // If we kill the first operand, pop it!
- else if (KillsOp1 && Op0 != Op1) {
- if (getStackEntry(0) == Op1) {
- popStackAfter(I); // If it's right at the top of stack, just pop it
- } else {
- // Otherwise, move the top of stack into the dead slot, killing the
- // operand without having to add in an explicit xchg then pop.
- //
- unsigned STReg = getSTReg(Op1);
- unsigned OldSlot = getSlot(Op1);
- unsigned TopReg = Stack[StackTop-1];
- Stack[OldSlot] = TopReg;
- RegMap[TopReg] = OldSlot;
- RegMap[Op1] = ~0;
- Stack[--StackTop] = ~0;
-
- MachineInstr *MI = BuildMI(X86::FSTPrr, 1).addReg(STReg);
- I = MBB->insert(++I, MI);
- }
- }
+ else if (KillsOp1 && Op0 != Op1)
+ freeStackSlotAfter(I, Op1);
}
// Update stack information so that we know the destination register is now on
@@ -663,10 +672,8 @@ void FPS::handleCondMovFP(MachineBasicBlock::iterator &I) {
for (LiveVariables::killed_iterator KI = LV->killed_begin(MI),
E = LV->killed_end(MI); KI != E; ++KI)
if (KI->second == X86::FP0+Op1) {
- ++I;
- moveToTop(Op1, I); // Insert fxch if necessary
- --I;
- popStackAfter(I); // Pop the top of the stack, killing value
+ // Get this value off of the register stack.
+ freeStackSlotAfter(I, Op1);
break;
}
}
diff --git a/lib/Target/X86/X86FloatingPoint.cpp b/lib/Target/X86/X86FloatingPoint.cpp
index f2ff6c5..b1a2ceb 100644
--- a/lib/Target/X86/X86FloatingPoint.cpp
+++ b/lib/Target/X86/X86FloatingPoint.cpp
@@ -118,25 +118,29 @@ namespace {
std::swap(Stack[RegMap[RegOnTop]], Stack[StackTop-1]);
// Emit an fxch to update the runtime processors version of the state
- MachineInstr *MI = BuildMI(X86::FXCH, 1).addReg(STReg);
- MBB->insert(I, MI);
+ BuildMI(*MBB, I, X86::FXCH, 1).addReg(STReg);
NumFXCH++;
}
}
- void duplicateToTop(unsigned RegNo, unsigned AsReg,
- MachineBasicBlock::iterator &I) {
+ void duplicateToTop(unsigned RegNo, unsigned AsReg, MachineInstr *I) {
unsigned STReg = getSTReg(RegNo);
pushReg(AsReg); // New register on top of stack
- MachineInstr *MI = BuildMI(X86::FLDrr, 1).addReg(STReg);
- MBB->insert(I, MI);
+ BuildMI(*MBB, I, X86::FLDrr, 1).addReg(STReg);
}
// popStackAfter - Pop the current value off of the top of the FP stack
// after the specified instruction.
void popStackAfter(MachineBasicBlock::iterator &I);
+ // freeStackSlotAfter - Free the specified register from the register stack,
+ // so that it is no longer in a register. If the register is currently at
+ // the top of the stack, we just pop the current instruction, otherwise we
+ // store the current top-of-stack into the specified slot, then pop the top
+ // of stack.
+ void freeStackSlotAfter(MachineBasicBlock::iterator &I, unsigned Reg);
+
bool processBasicBlock(MachineFunction &MF, MachineBasicBlock &MBB);
void handleZeroArgFP(MachineBasicBlock::iterator &I);
@@ -250,7 +254,7 @@ bool FPS::processBasicBlock(MachineFunction &MF, MachineBasicBlock &BB) {
DEBUG(
MachineBasicBlock::iterator PrevI(PrevMI);
if (I == PrevI) {
- std::cerr<< "Just deleted pseudo instruction\n";
+ std::cerr << "Just deleted pseudo instruction\n";
} else {
MachineBasicBlock::iterator Start = I;
// Rewind to first instruction newly inserted.
@@ -358,11 +362,34 @@ void FPS::popStackAfter(MachineBasicBlock::iterator &I) {
I->RemoveOperand(0);
} else { // Insert an explicit pop
- MachineInstr *MI = BuildMI(X86::FSTPrr, 1).addReg(X86::ST0);
- I = MBB->insert(++I, MI);
+ I = BuildMI(*MBB, ++I, X86::FSTPrr, 1).addReg(X86::ST0);
+ }
+}
+
+/// freeStackSlotAfter - Free the specified register from the register stack, so
+/// that it is no longer in a register. If the register is currently at the top
+/// of the stack, we just pop the current instruction, otherwise we store the
+/// current top-of-stack into the specified slot, then pop the top of stack.
+void FPS::freeStackSlotAfter(MachineBasicBlock::iterator &I, unsigned FPRegNo) {
+ if (getStackEntry(0) == FPRegNo) { // already at the top of stack? easy.
+ popStackAfter(I);
+ return;
}
+
+ // Otherwise, store the top of stack into the dead slot, killing the operand
+ // without having to add in an explicit xchg then pop.
+ //
+ unsigned STReg = getSTReg(FPRegNo);
+ unsigned OldSlot = getSlot(FPRegNo);
+ unsigned TopReg = Stack[StackTop-1];
+ Stack[OldSlot] = TopReg;
+ RegMap[TopReg] = OldSlot;
+ RegMap[FPRegNo] = ~0;
+ Stack[--StackTop] = ~0;
+ I = BuildMI(*MBB, ++I, X86::FSTPrr, 1).addReg(STReg);
}
+
static unsigned getFPReg(const MachineOperand &MO) {
assert(MO.isRegister() && "Expected an FP register!");
unsigned Reg = MO.getReg();
@@ -596,8 +623,7 @@ void FPS::handleTwoArgFP(MachineBasicBlock::iterator &I) {
// Replace the old instruction with a new instruction
MBB->remove(I++);
- BuildMI(*MBB, I, Opcode, 1).addReg(getSTReg(NotTOS));
- --I;
+ I = BuildMI(*MBB, I, Opcode, 1).addReg(getSTReg(NotTOS));
// If both operands are killed, pop one off of the stack in addition to
// overwriting the other one.
@@ -610,25 +636,8 @@ void FPS::handleTwoArgFP(MachineBasicBlock::iterator &I) {
if (MI->getOpcode() == X86::FpUCOM) {
if (KillsOp0 && !KillsOp1)
popStackAfter(I); // If we kill the first operand, pop it!
- else if (KillsOp1 && Op0 != Op1) {
- if (getStackEntry(0) == Op1) {
- popStackAfter(I); // If it's right at the top of stack, just pop it
- } else {
- // Otherwise, move the top of stack into the dead slot, killing the
- // operand without having to add in an explicit xchg then pop.
- //
- unsigned STReg = getSTReg(Op1);
- unsigned OldSlot = getSlot(Op1);
- unsigned TopReg = Stack[StackTop-1];
- Stack[OldSlot] = TopReg;
- RegMap[TopReg] = OldSlot;
- RegMap[Op1] = ~0;
- Stack[--StackTop] = ~0;
-
- MachineInstr *MI = BuildMI(X86::FSTPrr, 1).addReg(STReg);
- I = MBB->insert(++I, MI);
- }
- }
+ else if (KillsOp1 && Op0 != Op1)
+ freeStackSlotAfter(I, Op1);
}
// Update stack information so that we know the destination register is now on
@@ -663,10 +672,8 @@ void FPS::handleCondMovFP(MachineBasicBlock::iterator &I) {
for (LiveVariables::killed_iterator KI = LV->killed_begin(MI),
E = LV->killed_end(MI); KI != E; ++KI)
if (KI->second == X86::FP0+Op1) {
- ++I;
- moveToTop(Op1, I); // Insert fxch if necessary
- --I;
- popStackAfter(I); // Pop the top of the stack, killing value
+ // Get this value off of the register stack.
+ freeStackSlotAfter(I, Op1);
break;
}
}