Remove the X86::FP_REG_KILL pseudo-instruction and the X86FloatingPointRegKill

pass that inserted it.

It is no longer necessary to limit the live ranges of FP registers to a single
basic block.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@108536 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jakob Stoklund Olesen 2010-07-16 17:41:44 +00:00
parent e098e7a96d
commit 468a2a44e2
8 changed files with 1 additions and 315 deletions

View File

@ -22,7 +22,6 @@ set(sources
X86COFFMachineModuleInfo.cpp
X86ELFWriterInfo.cpp
X86FloatingPoint.cpp
X86FloatingPointRegKill.cpp
X86ISelDAGToDAG.cpp
X86ISelLowering.cpp
X86InstrInfo.cpp

View File

@ -49,11 +49,6 @@ FunctionPass *createX86FloatingPointStackifierPass();
/// crossings.
FunctionPass *createSSEDomainFixPass();
/// createX87FPRegKillInserterPass - This function returns a pass which
/// inserts FP_REG_KILL instructions where needed.
///
FunctionPass *createX87FPRegKillInserterPass();
/// createX86CodeEmitterPass - Return a pass that emits the collected X86 code
/// to the specified MCE object.
FunctionPass *createX86JITCodeEmitterPass(X86TargetMachine &TM,

View File

@ -622,7 +622,6 @@ void Emitter<CodeEmitter>::emitInstruction(const MachineInstr &MI,
case TargetOpcode::IMPLICIT_DEF:
case TargetOpcode::KILL:
case X86::FP_REG_KILL:
break;
case X86::MOVPC32r: {
// This emits the "call" portion of this pseudo instruction.

View File

@ -1,153 +0,0 @@
//===-- X86FloatingPoint.cpp - FP_REG_KILL inserter -----------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the pass which inserts FP_REG_KILL instructions.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "x86-codegen"
#include "X86.h"
#include "X86InstrInfo.h"
#include "llvm/Instructions.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/CFG.h"
#include "llvm/ADT/Statistic.h"
using namespace llvm;
STATISTIC(NumFPKill, "Number of FP_REG_KILL instructions added");
namespace {
struct FPRegKiller : public MachineFunctionPass {
static char ID;
FPRegKiller() : MachineFunctionPass(&ID) {}
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesCFG();
AU.addPreservedID(MachineLoopInfoID);
AU.addPreservedID(MachineDominatorsID);
MachineFunctionPass::getAnalysisUsage(AU);
}
virtual bool runOnMachineFunction(MachineFunction &MF);
virtual const char *getPassName() const {
return "X86 FP_REG_KILL inserter";
}
};
char FPRegKiller::ID = 0;
}
FunctionPass *llvm::createX87FPRegKillInserterPass() {
return new FPRegKiller();
}
/// isFPStackVReg - Return true if the specified vreg is from a fp stack
/// register class.
static bool isFPStackVReg(unsigned RegNo, const MachineRegisterInfo &MRI) {
if (!TargetRegisterInfo::isVirtualRegister(RegNo))
return false;
switch (MRI.getRegClass(RegNo)->getID()) {
default: return false;
case X86::RFP32RegClassID:
case X86::RFP64RegClassID:
case X86::RFP80RegClassID:
return true;
}
}
/// ContainsFPStackCode - Return true if the specific MBB has floating point
/// stack code, and thus needs an FP_REG_KILL.
static bool ContainsFPStackCode(MachineBasicBlock *MBB,
const MachineRegisterInfo &MRI) {
// Scan the block, looking for instructions that define or use fp stack vregs.
for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end();
I != E; ++I) {
for (unsigned op = 0, e = I->getNumOperands(); op != e; ++op) {
if (!I->getOperand(op).isReg())
continue;
if (unsigned Reg = I->getOperand(op).getReg())
if (isFPStackVReg(Reg, MRI))
return true;
}
}
// Check PHI nodes in successor blocks. These PHI's will be lowered to have
// a copy of the input value in this block, which is a definition of the
// value.
for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(),
E = MBB->succ_end(); SI != E; ++ SI) {
MachineBasicBlock *SuccBB = *SI;
for (MachineBasicBlock::iterator I = SuccBB->begin(), E = SuccBB->end();
I != E; ++I) {
// All PHI nodes are at the top of the block.
if (!I->isPHI()) break;
if (isFPStackVReg(I->getOperand(0).getReg(), MRI))
return true;
}
}
return false;
}
bool FPRegKiller::runOnMachineFunction(MachineFunction &MF) {
// If we are emitting FP stack code, scan the basic block to determine if this
// block defines or uses any FP values. If so, put an FP_REG_KILL instruction
// before the terminator of the block.
// Note that FP stack instructions are used in all modes for long double,
// so we always need to do this check.
// Also note that it's possible for an FP stack register to be live across
// an instruction that produces multiple basic blocks (SSE CMOV) so we
// must check all the generated basic blocks.
// Scan all of the machine instructions in these MBBs, checking for FP
// stores. (RFP32 and RFP64 will not exist in SSE mode, but RFP80 might.)
// Fast-path: If nothing is using the x87 registers, we don't need to do
// any scanning.
const MachineRegisterInfo &MRI = MF.getRegInfo();
if (MRI.getRegClassVirtRegs(X86::RFP80RegisterClass).empty() &&
MRI.getRegClassVirtRegs(X86::RFP64RegisterClass).empty() &&
MRI.getRegClassVirtRegs(X86::RFP32RegisterClass).empty())
return false;
bool Changed = false;
MachineFunction::iterator MBBI = MF.begin();
MachineFunction::iterator EndMBB = MF.end();
for (; MBBI != EndMBB; ++MBBI) {
MachineBasicBlock *MBB = MBBI;
// If this block returns, ignore it. We don't want to insert an FP_REG_KILL
// before the return.
if (!MBB->empty()) {
MachineBasicBlock::iterator EndI = MBB->end();
--EndI;
if (EndI->getDesc().isReturn())
continue;
}
// If we find any FP stack code, emit the FP_REG_KILL instruction.
if (ContainsFPStackCode(MBB, MRI)) {
BuildMI(*MBB, MBBI->getFirstTerminator(), DebugLoc(),
MF.getTarget().getInstrInfo()->get(X86::FP_REG_KILL));
++NumFPKill;
Changed = true;
}
}
return Changed;
}

View File

@ -108,10 +108,6 @@ let usesCustomInserter = 1 in { // Expanded after instruction selection.
[(X86fp_to_i64mem RFP80:$src, addr:$dst)]>;
}
let isTerminator = 1 in
let Defs = [FP0, FP1, FP2, FP3, FP4, FP5, FP6] in
def FP_REG_KILL : I<0, Pseudo, (outs), (ins), "##FP_REG_KILL", []>;
// All FP Stack operations are represented with four instructions here. The
// first three instructions, generated by the instruction selector, use "RFP32"
// "RFP64" or "RFP80" registers: traditional register files to reference 32-bit,

View File

@ -1664,14 +1664,6 @@ bool X86InstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const {
return !isPredicated(MI);
}
// For purposes of branch analysis do not count FP_REG_KILL as a terminator.
static bool isBrAnalysisUnpredicatedTerminator(const MachineInstr *MI,
const X86InstrInfo &TII) {
if (MI->getOpcode() == X86::FP_REG_KILL)
return false;
return TII.isUnpredicatedTerminator(MI);
}
bool X86InstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
MachineBasicBlock *&TBB,
MachineBasicBlock *&FBB,
@ -1688,7 +1680,7 @@ bool X86InstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
// Working from the bottom, when we see a non-terminator instruction, we're
// done.
if (!isBrAnalysisUnpredicatedTerminator(I, *this))
if (!isUnpredicatedTerminator(I))
break;
// A terminator that isn't a branch can't easily be handled by this
@ -3341,7 +3333,6 @@ static unsigned GetInstSizeWithDesc(const MachineInstr &MI,
break;
case TargetOpcode::IMPLICIT_DEF:
case TargetOpcode::KILL:
case X86::FP_REG_KILL:
break;
case X86::MOVPC32r: {
// This emits the "call" portion of this pseudo instruction.

View File

@ -19,15 +19,11 @@
#include "llvm/CodeGen/Passes.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetRegistry.h"
using namespace llvm;
static cl::opt<bool>
LiveX87("live-x87", cl::desc("Allow live X87 registers across blocks"));
static MCAsmInfo *createMCAsmInfo(const Target &T, StringRef TT) {
Triple TheTriple(TT);
switch (TheTriple.getOS()) {
@ -186,10 +182,6 @@ bool X86TargetMachine::addInstSelector(PassManagerBase &PM,
bool X86TargetMachine::addPreRegAlloc(PassManagerBase &PM,
CodeGenOpt::Level OptLevel) {
// Install a pass to insert x87 FP_REG_KILL instructions, as needed.
if (!LiveX87)
PM.add(createX87FPRegKillInserterPass());
PM.add(createX86MaxStackAlignmentHeuristicPass());
return false; // -print-machineinstr shouldn't print after this.
}

View File

@ -1,133 +0,0 @@
; RUN: llc < %s -march=x86 -mcpu=i686 | not grep jmp
; check that branch folding understands FP_REG_KILL is not a branch
target triple = "i686-pc-linux-gnu"
%struct.FRAME.c34003a = type { float, float }
@report_E = global i8 0 ; <i8*> [#uses=0]
define void @main() {
entry:
%FRAME.31 = alloca %struct.FRAME.c34003a, align 8 ; <%struct.FRAME.c34003a*> [#uses=4]
%tmp20 = call i32 @report__ident_int( i32 -50 ) ; <i32> [#uses=1]
%tmp2021 = sitofp i32 %tmp20 to float ; <float> [#uses=5]
%tmp23 = fcmp ult float %tmp2021, 0xC7EFFFFFE0000000 ; <i1> [#uses=1]
%tmp26 = fcmp ugt float %tmp2021, 0x47EFFFFFE0000000 ; <i1> [#uses=1]
%bothcond = or i1 %tmp23, %tmp26 ; <i1> [#uses=1]
br i1 %bothcond, label %bb, label %bb30
bb: ; preds = %entry
unwind
bb30: ; preds = %entry
%tmp35 = call i32 @report__ident_int( i32 50 ) ; <i32> [#uses=1]
%tmp3536 = sitofp i32 %tmp35 to float ; <float> [#uses=4]
%tmp38 = fcmp ult float %tmp3536, 0xC7EFFFFFE0000000 ; <i1> [#uses=1]
%tmp44 = fcmp ugt float %tmp3536, 0x47EFFFFFE0000000 ; <i1> [#uses=1]
%bothcond226 = or i1 %tmp38, %tmp44 ; <i1> [#uses=1]
br i1 %bothcond226, label %bb47, label %bb49
bb47: ; preds = %bb30
unwind
bb49: ; preds = %bb30
%tmp60 = fcmp ult float %tmp3536, %tmp2021 ; <i1> [#uses=1]
%tmp60.not = xor i1 %tmp60, true ; <i1> [#uses=1]
%tmp65 = fcmp olt float %tmp2021, 0xC7EFFFFFE0000000 ; <i1> [#uses=1]
%bothcond227 = and i1 %tmp65, %tmp60.not ; <i1> [#uses=1]
br i1 %bothcond227, label %cond_true68, label %cond_next70
cond_true68: ; preds = %bb49
unwind
cond_next70: ; preds = %bb49
%tmp71 = call i32 @report__ident_int( i32 -30 ) ; <i32> [#uses=1]
%tmp7172 = sitofp i32 %tmp71 to float ; <float> [#uses=3]
%tmp74 = fcmp ult float %tmp7172, 0xC7EFFFFFE0000000 ; <i1> [#uses=1]
%tmp80 = fcmp ugt float %tmp7172, 0x47EFFFFFE0000000 ; <i1> [#uses=1]
%bothcond228 = or i1 %tmp74, %tmp80 ; <i1> [#uses=1]
br i1 %bothcond228, label %bb83, label %bb85
bb83: ; preds = %cond_next70
unwind
bb85: ; preds = %cond_next70
%tmp90 = getelementptr %struct.FRAME.c34003a* %FRAME.31, i32 0, i32 1 ; <float*> [#uses=3]
store float %tmp7172, float* %tmp90
%tmp92 = call i32 @report__ident_int( i32 30 ) ; <i32> [#uses=1]
%tmp9293 = sitofp i32 %tmp92 to float ; <float> [#uses=7]
%tmp95 = fcmp ult float %tmp9293, 0xC7EFFFFFE0000000 ; <i1> [#uses=1]
%tmp101 = fcmp ugt float %tmp9293, 0x47EFFFFFE0000000 ; <i1> [#uses=1]
%bothcond229 = or i1 %tmp95, %tmp101 ; <i1> [#uses=1]
br i1 %bothcond229, label %bb104, label %bb106
bb104: ; preds = %bb85
unwind
bb106: ; preds = %bb85
%tmp111 = getelementptr %struct.FRAME.c34003a* %FRAME.31, i32 0, i32 0 ; <float*> [#uses=2]
store float %tmp9293, float* %tmp111
%tmp123 = load float* %tmp90 ; <float> [#uses=4]
%tmp125 = fcmp ult float %tmp9293, %tmp123 ; <i1> [#uses=1]
br i1 %tmp125, label %cond_next147, label %cond_true128
cond_true128: ; preds = %bb106
%tmp133 = fcmp olt float %tmp123, %tmp2021 ; <i1> [#uses=1]
%tmp142 = fcmp ogt float %tmp9293, %tmp3536 ; <i1> [#uses=1]
%bothcond230 = or i1 %tmp133, %tmp142 ; <i1> [#uses=1]
br i1 %bothcond230, label %bb145, label %cond_next147
bb145: ; preds = %cond_true128
unwind
cond_next147: ; preds = %cond_true128, %bb106
%tmp157 = fcmp ugt float %tmp123, -3.000000e+01 ; <i1> [#uses=1]
%tmp165 = fcmp ult float %tmp9293, -3.000000e+01 ; <i1> [#uses=1]
%bothcond231 = or i1 %tmp157, %tmp165 ; <i1> [#uses=1]
br i1 %bothcond231, label %bb168, label %bb169
bb168: ; preds = %cond_next147
unwind
bb169: ; preds = %cond_next147
%tmp176 = fcmp ugt float %tmp123, 3.000000e+01 ; <i1> [#uses=1]
%tmp184 = fcmp ult float %tmp9293, 3.000000e+01 ; <i1> [#uses=1]
%bothcond232 = or i1 %tmp176, %tmp184 ; <i1> [#uses=1]
br i1 %bothcond232, label %bb187, label %bb188
bb187: ; preds = %bb169
unwind
bb188: ; preds = %bb169
%tmp192 = call fastcc float @c34003a__ident.154( %struct.FRAME.c34003a* %FRAME.31, float 3.000000e+01 ) ; <float> [#uses=2]
%tmp194 = load float* %tmp90 ; <float> [#uses=1]
%tmp196 = fcmp ugt float %tmp194, 0.000000e+00 ; <i1> [#uses=1]
br i1 %tmp196, label %bb207, label %cond_next200
cond_next200: ; preds = %bb188
%tmp202 = load float* %tmp111 ; <float> [#uses=1]
%tmp204 = fcmp ult float %tmp202, 0.000000e+00 ; <i1> [#uses=1]
br i1 %tmp204, label %bb207, label %bb208
bb207: ; preds = %cond_next200, %bb188
unwind
bb208: ; preds = %cond_next200
%tmp212 = call fastcc float @c34003a__ident.154( %struct.FRAME.c34003a* %FRAME.31, float 0.000000e+00 ) ; <float> [#uses=1]
%tmp214 = fcmp oge float %tmp212, %tmp192 ; <i1> [#uses=1]
%tmp217 = fcmp oge float %tmp192, 1.000000e+02 ; <i1> [#uses=1]
%tmp221 = or i1 %tmp214, %tmp217 ; <i1> [#uses=1]
br i1 %tmp221, label %cond_true224, label %UnifiedReturnBlock
cond_true224: ; preds = %bb208
call void @abort( ) noreturn
ret void
UnifiedReturnBlock: ; preds = %bb208
ret void
}
declare fastcc float @c34003a__ident.154(%struct.FRAME.c34003a* %CHAIN.32, float %x)
declare i32 @report__ident_int(i32 %x)
declare void @abort() noreturn