aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/X86/X86ISelPattern.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2005-05-13 07:38:09 +0000
committerChris Lattner <sabre@nondot.org>2005-05-13 07:38:09 +0000
commit63602fb868cd41b35e9896fe021e890c729518e4 (patch)
tree83083acadd500535e3640bc00e2f29655b5891c4 /lib/Target/X86/X86ISelPattern.cpp
parent405ef9e28d955c1b107c27bedfd4be8b9165af01 (diff)
Do not CopyFromReg physregs for live-in values. Instead, create a vreg for
each live in, and copy the regs from the vregs. As the very first thing we do in the function, insert copies from the pregs to the vregs. This fixes problems where the token chain of CopyFromReg was not enough to allow reordering of the copyfromreg nodes and other unchained nodes (e.g. div, which clobbers eax on intel). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@21932 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/X86/X86ISelPattern.cpp')
-rw-r--r--lib/Target/X86/X86ISelPattern.cpp101
1 files changed, 70 insertions, 31 deletions
diff --git a/lib/Target/X86/X86ISelPattern.cpp b/lib/Target/X86/X86ISelPattern.cpp
index dd88367209..a8e88818a8 100644
--- a/lib/Target/X86/X86ISelPattern.cpp
+++ b/lib/Target/X86/X86ISelPattern.cpp
@@ -375,6 +375,19 @@ LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList,
// Note that this can be enhanced in the future to pass fp vals in registers
// (when we have a global fp allocator) and do other tricks.
//
+
+/// AddLiveIn - This helper function adds the specified physical register to the
+/// MachineFunction as a live in value. It also creates a corresponding virtual
+/// register for it.
+static unsigned AddLiveIn(MachineFunction &MF, unsigned PReg,
+ TargetRegisterClass *RC) {
+ assert(RC->contains(PReg) && "Not the correct regclass!");
+ unsigned VReg = MF.getSSARegMap()->createVirtualRegister(RC);
+ MF.addLiveIn(PReg, VReg);
+ return VReg;
+}
+
+
std::vector<SDOperand>
X86TargetLowering::LowerFastCCArguments(Function &F, SelectionDAG &DAG) {
std::vector<SDOperand> ArgValues;
@@ -408,9 +421,9 @@ X86TargetLowering::LowerFastCCArguments(Function &F, SelectionDAG &DAG) {
case MVT::i8:
if (NumIntRegs < 2) {
if (!I->use_empty()) {
- MF.addLiveIn(NumIntRegs ? X86::DL : X86::AL);
- ArgValue = DAG.getCopyFromReg(NumIntRegs ? X86::DL : X86::AL, MVT::i8,
- DAG.getRoot());
+ unsigned VReg = AddLiveIn(MF, NumIntRegs ? X86::DL : X86::AL,
+ X86::R8RegisterClass);
+ ArgValue = DAG.getCopyFromReg(VReg, MVT::i8, DAG.getRoot());
DAG.setRoot(ArgValue.getValue(1));
}
++NumIntRegs;
@@ -422,9 +435,9 @@ X86TargetLowering::LowerFastCCArguments(Function &F, SelectionDAG &DAG) {
case MVT::i16:
if (NumIntRegs < 2) {
if (!I->use_empty()) {
- MF.addLiveIn(NumIntRegs ? X86::DX : X86::AX);
- ArgValue = DAG.getCopyFromReg(NumIntRegs ? X86::DX : X86::AX,
- MVT::i16, DAG.getRoot());
+ unsigned VReg = AddLiveIn(MF, NumIntRegs ? X86::DX : X86::AX,
+ X86::R16RegisterClass);
+ ArgValue = DAG.getCopyFromReg(VReg, MVT::i16, DAG.getRoot());
DAG.setRoot(ArgValue.getValue(1));
}
++NumIntRegs;
@@ -435,9 +448,9 @@ X86TargetLowering::LowerFastCCArguments(Function &F, SelectionDAG &DAG) {
case MVT::i32:
if (NumIntRegs < 2) {
if (!I->use_empty()) {
- MF.addLiveIn(NumIntRegs ? X86::EDX : X86::EAX);
- ArgValue = DAG.getCopyFromReg(NumIntRegs ? X86::EDX : X86::EAX,
- MVT::i32, DAG.getRoot());
+ unsigned VReg = AddLiveIn(MF,NumIntRegs ? X86::EDX : X86::EAX,
+ X86::R32RegisterClass);
+ ArgValue = DAG.getCopyFromReg(VReg, MVT::i32, DAG.getRoot());
DAG.setRoot(ArgValue.getValue(1));
}
++NumIntRegs;
@@ -448,11 +461,11 @@ X86TargetLowering::LowerFastCCArguments(Function &F, SelectionDAG &DAG) {
case MVT::i64:
if (NumIntRegs == 0) {
if (!I->use_empty()) {
- MF.addLiveIn(X86::EDX);
- MF.addLiveIn(X86::EAX);
+ unsigned BotReg = AddLiveIn(MF, X86::EAX, X86::R32RegisterClass);
+ unsigned TopReg = AddLiveIn(MF, X86::EDX, X86::R32RegisterClass);
- SDOperand Low=DAG.getCopyFromReg(X86::EAX, MVT::i32, DAG.getRoot());
- SDOperand Hi =DAG.getCopyFromReg(X86::EDX, MVT::i32, Low.getValue(1));
+ SDOperand Low=DAG.getCopyFromReg(BotReg, MVT::i32, DAG.getRoot());
+ SDOperand Hi =DAG.getCopyFromReg(TopReg, MVT::i32, Low.getValue(1));
DAG.setRoot(Hi.getValue(1));
ArgValue = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Low, Hi);
@@ -461,8 +474,8 @@ X86TargetLowering::LowerFastCCArguments(Function &F, SelectionDAG &DAG) {
break;
} else if (NumIntRegs == 1) {
if (!I->use_empty()) {
- MF.addLiveIn(X86::EDX);
- SDOperand Low = DAG.getCopyFromReg(X86::EDX, MVT::i32, DAG.getRoot());
+ unsigned BotReg = AddLiveIn(MF, X86::EDX, X86::R32RegisterClass);
+ SDOperand Low = DAG.getCopyFromReg(BotReg, MVT::i32, DAG.getRoot());
DAG.setRoot(Low.getValue(1));
// Load the high part from memory.
@@ -760,6 +773,8 @@ namespace {
/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
virtual void InstructionSelectBasicBlock(SelectionDAG &DAG);
+ virtual void EmitFunctionEntryCode(Function &Fn, MachineFunction &MF);
+
bool isFoldableLoad(SDOperand Op, SDOperand OtherOp,
bool FloatPromoteOk = false);
void EmitFoldedLoad(SDOperand Op, X86AddressMode &AM);
@@ -795,6 +810,36 @@ static void EmitSpecialCodeForMain(MachineBasicBlock *BB,
addFrameReference(BuildMI(BB, X86::FLDCW16m, 4), CWFrameIdx);
}
+void ISel::EmitFunctionEntryCode(Function &Fn, MachineFunction &MF) {
+ // If this function has live-in values, emit the copies from pregs to vregs at
+ // the top of the function, before anything else.
+ MachineBasicBlock *BB = MF.begin();
+ if (MF.livein_begin() != MF.livein_end()) {
+ SSARegMap *RegMap = MF.getSSARegMap();
+ for (MachineFunction::livein_iterator LI = MF.livein_begin(),
+ E = MF.livein_end(); LI != E; ++LI) {
+ const TargetRegisterClass *RC = RegMap->getRegClass(LI->second);
+ if (RC == X86::R8RegisterClass) {
+ BuildMI(BB, X86::MOV8rr, 1, LI->second).addReg(LI->first);
+ } else if (RC == X86::R16RegisterClass) {
+ BuildMI(BB, X86::MOV16rr, 1, LI->second).addReg(LI->first);
+ } else if (RC == X86::R32RegisterClass) {
+ BuildMI(BB, X86::MOV32rr, 1, LI->second).addReg(LI->first);
+ } else if (RC == X86::RFPRegisterClass) {
+ BuildMI(BB, X86::FpMOV, 1, LI->second).addReg(LI->first);
+ } else {
+ assert(0 && "Unknown regclass!");
+ }
+ }
+ }
+
+
+ // If this is main, emit special code for main.
+ if (Fn.hasExternalLinkage() && Fn.getName() == "main")
+ EmitSpecialCodeForMain(BB, MF.getFrameInfo());
+}
+
+
/// InstructionSelectBasicBlock - This callback is invoked by SelectionDAGISel
/// when it has created a SelectionDAG for us to codegen.
void ISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
@@ -807,23 +852,17 @@ void ISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
// of them is a PHI of a floating point value, we need to insert an
// FP_REG_KILL.
SSARegMap *RegMap = MF->getSSARegMap();
- for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end();
- I != E; ++I) {
- assert(I->getOpcode() == X86::PHI &&
- "Isn't just PHI nodes?");
- if (RegMap->getRegClass(I->getOperand(0).getReg()) ==
- X86::RFPRegisterClass) {
- ContainsFPCode = true;
- break;
+ if (BB != MF->begin())
+ for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end();
+ I != E; ++I) {
+ assert(I->getOpcode() == X86::PHI &&
+ "Isn't just PHI nodes?");
+ if (RegMap->getRegClass(I->getOperand(0).getReg()) ==
+ X86::RFPRegisterClass) {
+ ContainsFPCode = true;
+ break;
+ }
}
- }
-
- // If this is the entry block of main, emit special code for main.
- if (BB == MF->begin()) {
- const Function *F = MF->getFunction();
- if (F->hasExternalLinkage() && F->getName() == "main")
- EmitSpecialCodeForMain(BB, MF->getFrameInfo());
- }
// Compute the RegPressureMap, which is an approximation for the number of
// registers required to compute each node.