#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
#include "llvm/Target/TargetMachine.h"
+#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/MathExtras.h"
STATISTIC(NumFPKill , "Number of FP_REG_KILL instructions added");
STATISTIC(NumLoadMoved, "Number of loads moved below TokenFactor");
-
//===----------------------------------------------------------------------===//
// Pattern Matcher Implementation
//===----------------------------------------------------------------------===//
int FrameIndex;
} Base;
- bool isRIPRel; // RIP relative?
+ bool isRIPRel; // RIP as base?
unsigned Scale;
SDOperand IndexReg;
unsigned Disp;
static SDNode *findFlagUse(SDNode *N) {
unsigned FlagResNo = N->getNumValues()-1;
for (SDNode::use_iterator I = N->use_begin(), E = N->use_end(); I != E; ++I) {
- SDNode *User = *I;
+ SDNode *User = I->getUser();
for (unsigned i = 0, e = User->getNumOperands(); i != e; ++i) {
SDOperand Op = User->getOperand(i);
if (Op.Val == N && Op.ResNo == FlagResNo)
RModW = true;
std::swap(N10, N11);
}
- RModW = RModW && N10.Val->isOperand(Chain.Val) && N10.hasOneUse() &&
+ RModW = RModW && N10.Val->isOperandOf(Chain.Val) && N10.hasOneUse() &&
(N10.getOperand(1) == N2) &&
(N10.Val->getValueType(0) == N1.getValueType());
if (RModW)
case X86ISD::SHRD: {
SDOperand N10 = N1.getOperand(0);
if (ISD::isNON_EXTLoad(N10.Val))
- RModW = N10.Val->isOperand(Chain.Val) && N10.hasOneUse() &&
+ RModW = N10.Val->isOperandOf(Chain.Val) && N10.hasOneUse() &&
(N10.getOperand(1) == N2) &&
(N10.Val->getValueType(0) == N1.getValueType());
if (RModW)
if (SrcIsSSE && DstIsSSE)
continue;
- // If this is an FPStack extension (but not a truncation), it is a noop.
- if (!SrcIsSSE && !DstIsSSE && N->getOpcode() == ISD::FP_EXTEND)
- continue;
-
+ if (!SrcIsSSE && !DstIsSSE) {
+ // If this is an FPStack extension, it is a noop.
+ if (N->getOpcode() == ISD::FP_EXTEND)
+ continue;
+ // If this is a value-preserving FPStack truncation, it is a noop.
+ if (N->getConstantOperandVal(1))
+ continue;
+ }
+
// Here we could have an FP stack truncation or an FPStack <-> SSE convert.
// FPStack has extload and truncstore. SSE can fold direct loads into other
// operations. Based on this, decide what we want to do.
DAG.RemoveDeadNodes();
- // Emit machine code to BB.
+ // Emit machine code to BB. This can change 'BB' to the last block being
+ // inserted into.
ScheduleAndEmitDAG(DAG);
// If we are emitting FP stack code, scan the basic block to determine if this
// 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.)
MachineFunction::iterator MBBI = FirstMBB;
- do {
+ MachineFunction::iterator EndMBB = BB; ++EndMBB;
+ 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;
+ }
+
bool ContainsFPCode = false;
- for (MachineBasicBlock::iterator I = MBBI->begin(), E = MBBI->end();
+ for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end();
!ContainsFPCode && I != E; ++I) {
if (I->getNumOperands() != 0 && I->getOperand(0).isRegister()) {
const TargetRegisterClass *clas;
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()) &&
+ TargetRegisterInfo::isVirtualRegister(I->getOperand(op).getReg()) &&
((clas = RegInfo->getRegClass(I->getOperand(0).getReg())) ==
X86::RFP32RegisterClass ||
clas == X86::RFP64RegisterClass ||
}
// Finally, if we found any FP code, emit the FP_REG_KILL instruction.
if (ContainsFPCode) {
- BuildMI(*MBBI, MBBI->getFirstTerminator(),
+ BuildMI(*MBB, MBBI->getFirstTerminator(),
TM.getInstrInfo()->get(X86::FP_REG_KILL));
++NumFPKill;
}
- } while (&*(MBBI++) != BB);
+ }
}
/// EmitSpecialCodeForMain - Emit any code that needs to be executed only in
case X86ISD::Wrapper: {
bool is64Bit = Subtarget->is64Bit();
// Under X86-64 non-small code model, GV (and friends) are 64-bits.
- if (is64Bit && TM.getCodeModel() != CodeModel::Small)
+ // Also, base and index reg must be 0 in order to use rip as base.
+ if (is64Bit && (TM.getCodeModel() != CodeModel::Small ||
+ AM.Base.Reg.Val || AM.IndexReg.Val))
break;
if (AM.GV != 0 || AM.CP != 0 || AM.ES != 0 || AM.JT != -1)
break;
// been picked, we can't fit the result available in the register in the
// addressing mode. Duplicate GlobalAddress or ConstantPool as displacement.
if (!AlreadySelected || (AM.Base.Reg.Val && AM.IndexReg.Val)) {
- bool isStatic = TM.getRelocationModel() == Reloc::Static;
SDOperand N0 = N.getOperand(0);
- // Mac OS X X86-64 lower 4G address is not available.
- bool isAbs32 = !is64Bit ||
- (isStatic && Subtarget->hasLow4GUserSpaceAddress());
if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(N0)) {
GlobalValue *GV = G->getGlobal();
- if (isAbs32 || isRoot) {
- AM.GV = GV;
- AM.Disp += G->getOffset();
- AM.isRIPRel = !isAbs32;
- return false;
- }
+ AM.GV = GV;
+ AM.Disp += G->getOffset();
+ AM.isRIPRel = TM.getRelocationModel() != Reloc::Static &&
+ Subtarget->isPICStyleRIPRel();
+ return false;
} else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(N0)) {
- if (isAbs32 || isRoot) {
- AM.CP = CP->getConstVal();
- AM.Align = CP->getAlignment();
- AM.Disp += CP->getOffset();
- AM.isRIPRel = !isAbs32;
- return false;
- }
+ AM.CP = CP->getConstVal();
+ AM.Align = CP->getAlignment();
+ AM.Disp += CP->getOffset();
+ AM.isRIPRel = TM.getRelocationModel() != Reloc::Static &&
+ Subtarget->isPICStyleRIPRel();
+ return false;
} else if (ExternalSymbolSDNode *S =dyn_cast<ExternalSymbolSDNode>(N0)) {
- if (isAbs32 || isRoot) {
- AM.ES = S->getSymbol();
- AM.isRIPRel = !isAbs32;
- return false;
- }
+ AM.ES = S->getSymbol();
+ AM.isRIPRel = TM.getRelocationModel() != Reloc::Static &&
+ Subtarget->isPICStyleRIPRel();
+ return false;
} else if (JumpTableSDNode *J = dyn_cast<JumpTableSDNode>(N0)) {
- if (isAbs32 || isRoot) {
- AM.JT = J->getIndex();
- AM.isRIPRel = !isAbs32;
- return false;
- }
+ AM.JT = J->getIndex();
+ AM.isRIPRel = TM.getRelocationModel() != Reloc::Static &&
+ Subtarget->isPICStyleRIPRel();
+ return false;
}
}
break;
break;
case ISD::SHL:
- if (AlreadySelected || AM.IndexReg.Val != 0 || AM.Scale != 1)
+ if (AlreadySelected || AM.IndexReg.Val != 0 || AM.Scale != 1 || AM.isRIPRel)
break;
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.Val->getOperand(1))) {
if (!AlreadySelected &&
AM.BaseType == X86ISelAddressMode::RegBase &&
AM.Base.Reg.Val == 0 &&
- AM.IndexReg.Val == 0) {
+ AM.IndexReg.Val == 0 &&
+ !AM.isRIPRel) {
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.Val->getOperand(1)))
if (CN->getValue() == 3 || CN->getValue() == 5 || CN->getValue() == 9) {
AM.Scale = unsigned(CN->getValue())-1;
// On x86-64, the resultant disp must fit in 32-bits.
isInt32(AM.Disp + CN->getSignExtended()) &&
// Check to see if the LHS & C is zero.
- CurDAG->MaskedValueIsZero(N.getOperand(0), CN->getValue())) {
+ CurDAG->MaskedValueIsZero(N.getOperand(0), CN->getAPIntValue())) {
AM.Disp += CN->getValue();
return false;
}
// Scale must not be used already.
if (AM.IndexReg.Val != 0 || AM.Scale != 1) break;
+
+ // Not when RIP is used as the base.
+ if (AM.isRIPRel) break;
ConstantSDNode *C2 = dyn_cast<ConstantSDNode>(N.getOperand(1));
ConstantSDNode *C1 = dyn_cast<ConstantSDNode>(Shift.getOperand(1));
// Is the base register already occupied?
if (AM.BaseType != X86ISelAddressMode::RegBase || AM.Base.Reg.Val) {
// If so, check to see if the scale index register is set.
- if (AM.IndexReg.Val == 0) {
+ if (AM.IndexReg.Val == 0 && !AM.isRIPRel) {
AM.IndexReg = N;
AM.Scale = 1;
return false;
case X86ISD::GlobalBaseReg:
return getGlobalBaseReg();
- case X86ISD::FP_GET_RESULT2: {
- SDOperand Chain = N.getOperand(0);
- SDOperand InFlag = N.getOperand(1);
- AddToISelQueue(Chain);
- AddToISelQueue(InFlag);
- std::vector<MVT::ValueType> Tys;
- Tys.push_back(MVT::f80);
- Tys.push_back(MVT::f80);
- Tys.push_back(MVT::Other);
- Tys.push_back(MVT::Flag);
- SDOperand Ops[] = { Chain, InFlag };
- SDNode *ResNode = CurDAG->getTargetNode(X86::FpGETRESULT80x2, Tys,
- Ops, 2);
- Chain = SDOperand(ResNode, 2);
- InFlag = SDOperand(ResNode, 3);
- ReplaceUses(SDOperand(N.Val, 2), Chain);
- ReplaceUses(SDOperand(N.Val, 3), InFlag);
- return ResNode;
- }
-
+ // FIXME: This is a workaround for a tblgen problem: rdar://5791600
+ case X86ISD::RET_FLAG:
+ if (ConstantSDNode *Amt = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
+ if (Amt->getSignExtended() != 0) break;
+
+ // Match (X86retflag 0).
+ SDOperand Chain = N.getOperand(0);
+ bool HasInFlag = N.getOperand(N.getNumOperands()-1).getValueType()
+ == MVT::Flag;
+ SmallVector<SDOperand, 8> Ops0;
+ AddToISelQueue(Chain);
+ SDOperand InFlag(0, 0);
+ if (HasInFlag) {
+ InFlag = N.getOperand(N.getNumOperands()-1);
+ AddToISelQueue(InFlag);
+ }
+ for (unsigned i = 2, e = N.getNumOperands()-(HasInFlag?1:0); i != e;
+ ++i) {
+ AddToISelQueue(N.getOperand(i));
+ Ops0.push_back(N.getOperand(i));
+ }
+ Ops0.push_back(Chain);
+ if (HasInFlag)
+ Ops0.push_back(InFlag);
+ return CurDAG->getTargetNode(X86::RET, MVT::Other,
+ &Ops0[0], Ops0.size());
+ }
+ break;
+
case ISD::ADD: {
// Turn ADD X, c to MOV32ri X+c. This cannot be done with tblgen'd
// code and is matched first so to prevent it from being turned into
SDOperand N0 = Node->getOperand(0);
SDOperand N1 = Node->getOperand(1);
- // There are several forms of IMUL that just return the low part and
- // don't have fixed-register operands. If we don't need the high part,
- // use these instead. They can be selected with the generated ISel code.
- if (NVT != MVT::i8 &&
- N.getValue(1).use_empty()) {
- N = CurDAG->getNode(ISD::MUL, NVT, N0, N1);
- break;
- }
-
bool isSigned = Opcode == ISD::SMUL_LOHI;
if (!isSigned)
switch (NVT) {
}
case ISD::ANY_EXTEND: {
+ // Check if the type extended to supports subregs.
+ if (NVT == MVT::i8)
+ break;
+
SDOperand N0 = Node->getOperand(0);
+ // Get the subregsiter index for the type to extend.
+ MVT::ValueType N0VT = N0.getValueType();
+ unsigned Idx = (N0VT == MVT::i32) ? X86::SUBREG_32BIT :
+ (N0VT == MVT::i16) ? X86::SUBREG_16BIT :
+ (Subtarget->is64Bit()) ? X86::SUBREG_8BIT : 0;
+
+ // If we don't have a subreg Idx, let generated ISel have a try.
+ if (Idx == 0)
+ break;
+
+ // If we have an index, generate an insert_subreg into undef.
AddToISelQueue(N0);
- if (NVT == MVT::i64 || NVT == MVT::i32 || NVT == MVT::i16) {
- SDOperand SRIdx;
- switch(N0.getValueType()) {
- case MVT::i32:
- SRIdx = CurDAG->getTargetConstant(3, MVT::i32); // SubRegSet 3
- break;
- case MVT::i16:
- SRIdx = CurDAG->getTargetConstant(2, MVT::i32); // SubRegSet 2
- break;
- case MVT::i8:
- if (Subtarget->is64Bit())
- SRIdx = CurDAG->getTargetConstant(1, MVT::i32); // SubRegSet 1
- break;
- default: assert(0 && "Unknown any_extend!");
- }
- if (SRIdx.Val) {
- SDNode *ResNode = CurDAG->getTargetNode(X86::INSERT_SUBREG,
- NVT, N0, SRIdx);
+ SDOperand Undef =
+ SDOperand(CurDAG->getTargetNode(X86::IMPLICIT_DEF, NVT), 0);
+ SDOperand SRIdx = CurDAG->getTargetConstant(Idx, MVT::i32);
+ SDNode *ResNode = CurDAG->getTargetNode(X86::INSERT_SUBREG,
+ NVT, Undef, N0, SRIdx);
#ifndef NDEBUG
- DOUT << std::string(Indent-2, ' ') << "=> ";
- DEBUG(ResNode->dump(CurDAG));
- DOUT << "\n";
- Indent -= 2;
+ DOUT << std::string(Indent-2, ' ') << "=> ";
+ DEBUG(ResNode->dump(CurDAG));
+ DOUT << "\n";
+ Indent -= 2;
#endif
- return ResNode;
- } // Otherwise let generated ISel handle it.
- }
- break;
+ return ResNode;
}
case ISD::SIGN_EXTEND_INREG: {