diff options
author | Chris Lattner <sabre@nondot.org> | 2006-01-11 01:15:34 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2006-01-11 01:15:34 +0000 |
commit | 92cb0af6754b0d20b9eda4b459a5a27578bfd9ae (patch) | |
tree | f558bb977a59be41911f70d229dcf733a5edf40f | |
parent | a2b694ce3522eb8ebe60748dd5021b27472fc68f (diff) |
implement FP_REG_KILL insertion for the dag-dag instruction selector
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25192 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/X86/X86ISelDAGToDAG.cpp | 59 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelPattern.cpp | 1 |
2 files changed, 59 insertions, 1 deletions
diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp index f4956b44cc..c6d4e6727e 100644 --- a/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -13,12 +13,17 @@ //===----------------------------------------------------------------------===// #include "X86.h" +#include "X86RegisterInfo.h" #include "X86Subtarget.h" #include "X86ISelLowering.h" #include "llvm/GlobalValue.h" +#include "llvm/Instructions.h" +#include "llvm/Support/CFG.h" #include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/SSARegMap.h" #include "llvm/CodeGen/SelectionDAGISel.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Support/Debug.h" @@ -139,6 +144,7 @@ namespace { /// when it has created a SelectionDAG for us to codegen. void X86DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) { DEBUG(BB->dump()); + MachineFunction::iterator FirstMBB = BB; // Codegen the basic block. DAG.setRoot(Select(DAG.getRoot())); @@ -147,6 +153,59 @@ void X86DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) { // Emit machine code to BB. ScheduleAndEmitDAG(DAG); + + // If we are emitting FP stack code, scan the basic block to determine if this + // block defines any FP values. If so, put an FP_REG_KILL instruction before + // the terminator of the block. + if (X86Vector < SSE2) { + // Note that FP stack instructions *are* used in SSE code when returning + // values, but these are not live out of the basic block, so we don't need + // an FP_REG_KILL in this case either. + bool ContainsFPCode = false; + + // Scan all of the machine instructions in these MBBs, checking for FP + // stores. + MachineFunction::iterator MBBI = FirstMBB; + do { + for (MachineBasicBlock::iterator I = MBBI->begin(), E = MBBI->end(); + !ContainsFPCode && I != E; ++I) { + for (unsigned op = 0, e = I->getNumOperands(); op != e; ++op) { + if (I->getOperand(op).isRegister() && I->getOperand(op).isDef() && + MRegisterInfo::isVirtualRegister(I->getOperand(op).getReg()) && + RegMap->getRegClass(I->getOperand(0).getReg()) == + X86::RFPRegisterClass) { + ContainsFPCode = true; + break; + } + } + } + } while (!ContainsFPCode && &*(MBBI++) != BB); + + // Check PHI nodes in successor blocks. These PHI's will be lowered to have + // a copy of the input value in this block. + if (!ContainsFPCode) { + // Final check, check LLVM BB's that are successors to the LLVM BB + // corresponding to BB for FP PHI nodes. + const BasicBlock *LLVMBB = BB->getBasicBlock(); + const PHINode *PN; + for (succ_const_iterator SI = succ_begin(LLVMBB), E = succ_end(LLVMBB); + !ContainsFPCode && SI != E; ++SI) { + for (BasicBlock::const_iterator II = SI->begin(); + (PN = dyn_cast<PHINode>(II)); ++II) { + if (PN->getType()->isFloatingPoint()) { + ContainsFPCode = true; + break; + } + } + } + } + + // Finally, if we found any FP code, emit the FP_REG_KILL instruction. + if (ContainsFPCode) { + BuildMI(*BB, BB->getFirstTerminator(), X86::FP_REG_KILL, 0); + ++NumFPKill; + } + } } /// FIXME: copied from X86ISelPattern.cpp diff --git a/lib/Target/X86/X86ISelPattern.cpp b/lib/Target/X86/X86ISelPattern.cpp index 20c97bc963..146ee752e9 100644 --- a/lib/Target/X86/X86ISelPattern.cpp +++ b/lib/Target/X86/X86ISelPattern.cpp @@ -226,7 +226,6 @@ void ISel::InstructionSelectBasicBlock(SelectionDAG &DAG) { break; } - // Insert FP_REG_KILL instructions into basic blocks that need them. This // only occurs due to the floating point stackifier not being aggressive // enough to handle arbitrary global stackification. |