STATISTIC(NumFPKill , "Number of FP_REG_KILL instructions added");
STATISTIC(NumLoadMoved, "Number of loads moved below TokenFactor");
-namespace {
- static cl::opt<bool>
- AlwaysFoldAndInTest("always-fold-and-in-test",
- cl::desc("Always fold and operation in test"),
- cl::init(false), cl::Hidden);
-}
-
//===----------------------------------------------------------------------===//
// Pattern Matcher Implementation
//===----------------------------------------------------------------------===//
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() &&
- TargetRegisterInfo::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::GlobalBaseReg:
return getGlobalBaseReg();
- case X86ISD::FP_GET_RESULT2: {
+ // 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 X86ISD::FP_GET_ST0_ST1: {
SDOperand Chain = N.getOperand(0);
SDOperand InFlag = N.getOperand(1);
AddToISelQueue(Chain);
Tys.push_back(MVT::Other);
Tys.push_back(MVT::Flag);
SDOperand Ops[] = { Chain, InFlag };
- SDNode *ResNode = CurDAG->getTargetNode(X86::FpGETRESULT80x2, Tys,
+ SDNode *ResNode = CurDAG->getTargetNode(X86::FpGET_ST0_ST1, Tys,
Ops, 2);
Chain = SDOperand(ResNode, 2);
InFlag = SDOperand(ResNode, 3);