Add a floating point killer pass. This pass runs before register
authorAlkis Evlogimenos <alkis@evlogimenos.com>
Sat, 13 Dec 2003 05:36:22 +0000 (05:36 +0000)
committerAlkis Evlogimenos <alkis@evlogimenos.com>
Sat, 13 Dec 2003 05:36:22 +0000 (05:36 +0000)
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

lib/Target/X86/FloatingPoint.cpp
lib/Target/X86/X86.h
lib/Target/X86/X86FloatingPoint.cpp
lib/Target/X86/X86TargetMachine.cpp

index 5c6e6ebfddec041c301587ceb97b6980aef99ccd..b6bae6dffaef863e6e18129bdcb7c19bd803a0a7 100644 (file)
@@ -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
index c474d18ead3c74b243f500668e276578185fa6ec..35845fb0380add4b8a7abbdd925f4dd07033fed2 100644 (file)
@@ -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.
index 5c6e6ebfddec041c301587ceb97b6980aef99ccd..b6bae6dffaef863e6e18129bdcb7c19bd803a0a7 100644 (file)
@@ -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
index eb4d19a7783e7b5ea82913e15bb8cdea05e373fa..fba8e8dc9eacf9a543e1e80a723fa1f4dcdf5dfb 100644 (file)
@@ -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());