From cf93cdde567c2fd4a5e5539a736836cdfe935c66 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 30 Jan 2004 22:13:44 +0000 Subject: [PATCH] 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 --- lib/Target/X86/InstSelectSimple.cpp | 51 ++++++++++++++++++++++++++--- lib/Target/X86/X86ISelSimple.cpp | 51 ++++++++++++++++++++++++++--- 2 files changed, 94 insertions(+), 8 deletions(-) diff --git a/lib/Target/X86/InstSelectSimple.cpp b/lib/Target/X86/InstSelectSimple.cpp index 745c219c4fb..5135385ddff 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) diff --git a/lib/Target/X86/X86ISelSimple.cpp b/lib/Target/X86/X86ISelSimple.cpp index 745c219c4fb..5135385ddff 100644 --- a/lib/Target/X86/X86ISelSimple.cpp +++ b/lib/Target/X86/X86ISelSimple.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)