aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/X86/InstSelectSimple.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2004-01-30 22:13:44 +0000
committerChris Lattner <sabre@nondot.org>2004-01-30 22:13:44 +0000
commitcf93cdde567c2fd4a5e5539a736836cdfe935c66 (patch)
tree3b66f74f70f741a79c716be25833a55a8b64aaf2 /lib/Target/X86/InstSelectSimple.cpp
parent49a5aaacef127970f91648ac468de1cd2b6f462f (diff)
Add (currently disabled) support to the instruction selector to only insert
FP_REG_KILL instructions at the end of blocks involved with critical edges. Fix a bug where FP_REG_KILL instructions weren't inserted in fall through unconditional branches. Perhaps this will fix some linscan problems? git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@11019 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/X86/InstSelectSimple.cpp')
-rw-r--r--lib/Target/X86/InstSelectSimple.cpp51
1 files changed, 47 insertions, 4 deletions
diff --git a/lib/Target/X86/InstSelectSimple.cpp b/lib/Target/X86/InstSelectSimple.cpp
index 745c219c4f..5135385ddf 100644
--- a/lib/Target/X86/InstSelectSimple.cpp
+++ b/lib/Target/X86/InstSelectSimple.cpp
@@ -28,8 +28,11 @@
#include "llvm/Target/MRegisterInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/InstVisitor.h"
+#include "llvm/Support/CFG.h"
using namespace llvm;
+//#define SMART_FP 1
+
/// BMI - A special BuildMI variant that takes an iterator to insert the
/// instruction at as well as a basic block. This is the version for when you
/// have a destination register in mind.
@@ -843,7 +846,9 @@ void ISel::promote32(unsigned targetReg, const ValueRecord &VR) {
///
void ISel::visitReturnInst(ReturnInst &I) {
if (I.getNumOperands() == 0) {
+#ifndef SMART_FP
BuildMI(BB, X86::FP_REG_KILL, 0);
+#endif
BuildMI(BB, X86::RET, 0); // Just emit a 'ret' instruction
return;
}
@@ -874,7 +879,9 @@ void ISel::visitReturnInst(ReturnInst &I) {
visitInstruction(I);
}
// Emit a 'ret' instruction
+#ifndef SMART_FP
BuildMI(BB, X86::FP_REG_KILL, 0);
+#endif
BuildMI(BB, X86::RET, 0);
}
@@ -885,6 +892,40 @@ static inline BasicBlock *getBlockAfter(BasicBlock *BB) {
return I != BB->getParent()->end() ? &*I : 0;
}
+/// RequiresFPRegKill - The floating point stackifier pass cannot insert
+/// compensation code on critical edges. As such, it requires that we kill all
+/// FP registers on the exit from any blocks that either ARE critical edges, or
+/// branch to a block that has incoming critical edges.
+///
+/// Note that this kill instruction will eventually be eliminated when
+/// restrictions in the stackifier are relaxed.
+///
+static bool RequiresFPRegKill(const BasicBlock *BB) {
+#ifdef SMART_FP
+ for (succ_const_iterator SI = succ_begin(BB), E = succ_end(BB); SI!=E; ++SI) {
+ const BasicBlock *Succ = *SI;
+ pred_const_iterator PI = pred_begin(Succ), PE = pred_end(Succ);
+ ++PI; // Block have at least one predecessory
+ if (PI != PE) { // If it has exactly one, this isn't crit edge
+ // If this block has more than one predecessor, check all of the
+ // predecessors to see if they have multiple successors. If so, then the
+ // block we are analyzing needs an FPRegKill.
+ for (PI = pred_begin(Succ); PI != PE; ++PI) {
+ const BasicBlock *Pred = *PI;
+ succ_const_iterator SI2 = succ_begin(Pred);
+ ++SI2; // There must be at least one successor of this block.
+ if (SI2 != succ_end(Pred))
+ return true; // Yes, we must insert the kill on this edge.
+ }
+ }
+ }
+ // If we got this far, there is no need to insert the kill instruction.
+ return false;
+#else
+ return true;
+#endif
+}
+
/// visitBranchInst - Handle conditional and unconditional branches here. Note
/// that since code layout is frozen at this point, that if we are trying to
/// jump to a block that is the immediate successor of the current block, we can
@@ -894,10 +935,10 @@ void ISel::visitBranchInst(BranchInst &BI) {
BasicBlock *NextBB = getBlockAfter(BI.getParent()); // BB after current one
if (!BI.isConditional()) { // Unconditional branch?
- if (BI.getSuccessor(0) != NextBB) {
+ if (RequiresFPRegKill(BI.getParent()))
BuildMI(BB, X86::FP_REG_KILL, 0);
+ if (BI.getSuccessor(0) != NextBB)
BuildMI(BB, X86::JMP, 1).addPCDisp(BI.getSuccessor(0));
- }
return;
}
@@ -908,7 +949,8 @@ void ISel::visitBranchInst(BranchInst &BI) {
// computed some other way...
unsigned condReg = getReg(BI.getCondition());
BuildMI(BB, X86::CMPri8, 2).addReg(condReg).addZImm(0);
- BuildMI(BB, X86::FP_REG_KILL, 0);
+ if (RequiresFPRegKill(BI.getParent()))
+ BuildMI(BB, X86::FP_REG_KILL, 0);
if (BI.getSuccessor(1) == NextBB) {
if (BI.getSuccessor(0) != NextBB)
BuildMI(BB, X86::JNE, 1).addPCDisp(BI.getSuccessor(0));
@@ -947,7 +989,8 @@ void ISel::visitBranchInst(BranchInst &BI) {
X86::JS, X86::JNS },
};
- BuildMI(BB, X86::FP_REG_KILL, 0);
+ if (RequiresFPRegKill(BI.getParent()))
+ BuildMI(BB, X86::FP_REG_KILL, 0);
if (BI.getSuccessor(0) != NextBB) {
BuildMI(BB, OpcodeTab[isSigned][OpNum], 1).addPCDisp(BI.getSuccessor(0));
if (BI.getSuccessor(1) != NextBB)