aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlkis Evlogimenos <alkis@evlogimenos.com>2003-12-13 05:36:22 +0000
committerAlkis Evlogimenos <alkis@evlogimenos.com>2003-12-13 05:36:22 +0000
commit359b65f782cc323daba4f8c5c21c70a98c9d40ea (patch)
tree2174dc005900c6176f0e1a90d0ffd5b8a691816e
parent9435eda6993944e74419d2f586fdd25635293760 (diff)
Add a floating point killer pass. This pass runs before register
allocaton on the X86 to add information to the machine code denoting that our floating point stackifier cannot handle virtual point register that are alive across basic blocks. This pass adds an implicit def of all virtual floating point register at the end of each basic block. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@10446 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/X86/FloatingPoint.cpp52
-rw-r--r--lib/Target/X86/X86.h6
-rw-r--r--lib/Target/X86/X86FloatingPoint.cpp52
-rw-r--r--lib/Target/X86/X86TargetMachine.cpp10
4 files changed, 120 insertions, 0 deletions
diff --git a/lib/Target/X86/FloatingPoint.cpp b/lib/Target/X86/FloatingPoint.cpp
index 5c6e6ebfdd..b6bae6dffa 100644
--- a/lib/Target/X86/FloatingPoint.cpp
+++ b/lib/Target/X86/FloatingPoint.cpp
@@ -18,6 +18,7 @@
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/LiveVariables.h"
+#include "llvm/CodeGen/Passes.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "Support/Debug.h"
@@ -601,4 +602,55 @@ void FPS::handleSpecialFP(MachineBasicBlock::iterator &I) {
I = MBB->erase(I)-1; // Remove the pseudo instruction
}
+namespace {
+
+ struct FPK : public MachineFunctionPass {
+ virtual const char *getPassName() const { return "X86 FP Killer"; }
+ virtual bool runOnMachineFunction(MachineFunction &MF);
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ AU.addRequired<LiveVariables>();
+ AU.addRequiredID(PHIEliminationID);
+ MachineFunctionPass::getAnalysisUsage(AU);
+ }
+ };
+}
+
+FunctionPass * createX86FloatingPointKillerPass() { return new FPK(); }
+
+bool FPK::runOnMachineFunction(MachineFunction &MF)
+{
+ const TargetInstrInfo& tii = MF.getTarget().getInstrInfo();;
+
+ for (MachineFunction::iterator
+ mbbi = MF.begin(), mbbe = MF.end(); mbbi != mbbe; ++mbbi) {
+ MachineBasicBlock& mbb = *mbbi;
+ MachineBasicBlock::reverse_iterator mii = mbb.rbegin();
+ // rewind to the last non terminating instruction
+ while (mii != mbb.rend() && tii.isTerminatorInstr((*mii)->getOpcode())) {
+ ++mii;
+ }
+ // add implicit def for all virtual floating point registers so that
+ // they are spilled at the end of each basic block, since our
+ // register stackifier doesn't handle them otherwise.
+ MachineInstr* instr = BuildMI(X86::IMPLICIT_DEF, 7)
+ .addReg(X86::FP6, MOTy::Def)
+ .addReg(X86::FP5, MOTy::Def)
+ .addReg(X86::FP4, MOTy::Def)
+ .addReg(X86::FP3, MOTy::Def)
+ .addReg(X86::FP2, MOTy::Def)
+ .addReg(X86::FP1, MOTy::Def)
+ .addReg(X86::FP0, MOTy::Def);
+
+ mbb.insert(mii.base(), instr);
+ LiveVariables& lv = getAnalysis<LiveVariables>();
+ for (unsigned i = 0; i < instr->getNumOperands(); ++i) {
+ lv.HandlePhysRegDef(instr->getOperand(i).getAllocatedRegNum(), instr);
+ // force live variables to compute that these registers are dead
+ lv.HandlePhysRegDef(instr->getOperand(i).getAllocatedRegNum(), 0);
+ }
+ }
+ return true;
+}
+
} // End llvm namespace
diff --git a/lib/Target/X86/X86.h b/lib/Target/X86/X86.h
index c474d18ead..35845fb038 100644
--- a/lib/Target/X86/X86.h
+++ b/lib/Target/X86/X86.h
@@ -44,6 +44,12 @@ FunctionPass *createX86SSAPeepholeOptimizerPass();
///
FunctionPass *createX86PeepholeOptimizerPass();
+/// createX86FloatingPointKiller - This function returns a pass which
+/// kills every floating point register at the end of each basic block
+/// because our FloatingPointStackifier cannot handle them.
+///
+FunctionPass *createX86FloatingPointKillerPass();
+
/// createX86FloatingPointStackifierPass - This function returns a pass which
/// converts floating point register references and pseudo instructions into
/// floating point stack references and physical instructions.
diff --git a/lib/Target/X86/X86FloatingPoint.cpp b/lib/Target/X86/X86FloatingPoint.cpp
index 5c6e6ebfdd..b6bae6dffa 100644
--- a/lib/Target/X86/X86FloatingPoint.cpp
+++ b/lib/Target/X86/X86FloatingPoint.cpp
@@ -18,6 +18,7 @@
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/LiveVariables.h"
+#include "llvm/CodeGen/Passes.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "Support/Debug.h"
@@ -601,4 +602,55 @@ void FPS::handleSpecialFP(MachineBasicBlock::iterator &I) {
I = MBB->erase(I)-1; // Remove the pseudo instruction
}
+namespace {
+
+ struct FPK : public MachineFunctionPass {
+ virtual const char *getPassName() const { return "X86 FP Killer"; }
+ virtual bool runOnMachineFunction(MachineFunction &MF);
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ AU.addRequired<LiveVariables>();
+ AU.addRequiredID(PHIEliminationID);
+ MachineFunctionPass::getAnalysisUsage(AU);
+ }
+ };
+}
+
+FunctionPass * createX86FloatingPointKillerPass() { return new FPK(); }
+
+bool FPK::runOnMachineFunction(MachineFunction &MF)
+{
+ const TargetInstrInfo& tii = MF.getTarget().getInstrInfo();;
+
+ for (MachineFunction::iterator
+ mbbi = MF.begin(), mbbe = MF.end(); mbbi != mbbe; ++mbbi) {
+ MachineBasicBlock& mbb = *mbbi;
+ MachineBasicBlock::reverse_iterator mii = mbb.rbegin();
+ // rewind to the last non terminating instruction
+ while (mii != mbb.rend() && tii.isTerminatorInstr((*mii)->getOpcode())) {
+ ++mii;
+ }
+ // add implicit def for all virtual floating point registers so that
+ // they are spilled at the end of each basic block, since our
+ // register stackifier doesn't handle them otherwise.
+ MachineInstr* instr = BuildMI(X86::IMPLICIT_DEF, 7)
+ .addReg(X86::FP6, MOTy::Def)
+ .addReg(X86::FP5, MOTy::Def)
+ .addReg(X86::FP4, MOTy::Def)
+ .addReg(X86::FP3, MOTy::Def)
+ .addReg(X86::FP2, MOTy::Def)
+ .addReg(X86::FP1, MOTy::Def)
+ .addReg(X86::FP0, MOTy::Def);
+
+ mbb.insert(mii.base(), instr);
+ LiveVariables& lv = getAnalysis<LiveVariables>();
+ for (unsigned i = 0; i < instr->getNumOperands(); ++i) {
+ lv.HandlePhysRegDef(instr->getOperand(i).getAllocatedRegNum(), instr);
+ // force live variables to compute that these registers are dead
+ lv.HandlePhysRegDef(instr->getOperand(i).getAllocatedRegNum(), 0);
+ }
+ }
+ return true;
+}
+
} // End llvm namespace
diff --git a/lib/Target/X86/X86TargetMachine.cpp b/lib/Target/X86/X86TargetMachine.cpp
index eb4d19a778..fba8e8dc9e 100644
--- a/lib/Target/X86/X86TargetMachine.cpp
+++ b/lib/Target/X86/X86TargetMachine.cpp
@@ -76,6 +76,11 @@ bool X86TargetMachine::addPassesToEmitAssembly(PassManager &PM,
if (PrintCode)
PM.add(createMachineFunctionPrinterPass());
+ // kill floating point registers at the end of basic blocks. this is
+ // done because the floating point register stackifier cannot handle
+ // floating point regs that are live across basic blocks.
+ PM.add(createX86FloatingPointKillerPass());
+
// Perform register allocation to convert to a concrete x86 representation
PM.add(createRegisterAllocator());
@@ -129,6 +134,11 @@ bool X86TargetMachine::addPassesToJITCompile(FunctionPassManager &PM) {
if (PrintCode)
PM.add(createMachineFunctionPrinterPass());
+ // kill floating point registers at the end of basic blocks. this is
+ // done because the floating point register stackifier cannot handle
+ // floating point regs that are live across basic blocks.
+ PM.add(createX86FloatingPointKillerPass());
+
// Perform register allocation to convert to a concrete x86 representation
PM.add(createRegisterAllocator());