From 3fba7d16b41dfbefe3b1be6bc0ab94c017728f79 Mon Sep 17 00:00:00 2001 From: rdivacky Date: Fri, 15 Jan 2010 15:37:28 +0000 Subject: Update LLVM to 93512. --- lib/Target/ARM/ARMBaseInstrInfo.cpp | 67 +++-- lib/Target/ARM/ARMBaseInstrInfo.h | 2 + lib/Target/ARM/ARMBaseRegisterInfo.cpp | 15 +- lib/Target/ARM/ARMISelDAGToDAG.cpp | 321 ++++++++++----------- lib/Target/ARM/ARMISelLowering.cpp | 23 +- lib/Target/ARM/ARMInstrInfo.td | 4 +- lib/Target/ARM/ARMInstrThumb.td | 33 ++- lib/Target/ARM/ARMInstrThumb2.td | 2 +- lib/Target/ARM/ARMLoadStoreOptimizer.cpp | 12 + lib/Target/ARM/ARMRegisterInfo.td | 13 - lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 39 ++- lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp | 27 +- lib/Target/Alpha/AlphaISelDAGToDAG.cpp | 26 +- .../Blackfin/AsmPrinter/BlackfinAsmPrinter.cpp | 9 +- lib/Target/Blackfin/BlackfinISelDAGToDAG.cpp | 11 +- lib/Target/CBackend/CBackend.cpp | 38 ++- lib/Target/CellSPU/SPUISelDAGToDAG.cpp | 171 ++++++----- lib/Target/MSP430/MSP430ISelDAGToDAG.cpp | 67 +++-- lib/Target/MSP430/MSP430ISelLowering.cpp | 13 +- lib/Target/MSP430/MSP430InstrInfo.td | 40 +-- lib/Target/Mips/MipsISelDAGToDAG.cpp | 75 +++-- lib/Target/PIC16/PIC16ISelDAGToDAG.cpp | 4 +- lib/Target/PIC16/PIC16ISelDAGToDAG.h | 4 +- lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp | 122 +++++--- lib/Target/PowerPC/PPCISelDAGToDAG.cpp | 36 ++- lib/Target/PowerPC/PPCInstrInfo.td | 8 +- lib/Target/PowerPC/PPCJITInfo.cpp | 2 + lib/Target/PowerPC/PPCMCAsmInfo.cpp | 1 + lib/Target/PowerPC/README.txt | 33 +++ lib/Target/README.txt | 48 +-- lib/Target/Sparc/SparcISelDAGToDAG.cpp | 19 +- lib/Target/SubtargetFeature.cpp | 3 +- lib/Target/SystemZ/SystemZISelDAGToDAG.cpp | 115 ++++---- lib/Target/Target.cpp | 2 +- lib/Target/TargetLoweringObjectFile.cpp | 34 ++- lib/Target/X86/AsmParser/X86AsmParser.cpp | 36 +-- lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp | 66 +++-- lib/Target/X86/AsmPrinter/X86MCInstLower.cpp | 28 ++ lib/Target/X86/README-SSE.txt | 20 ++ lib/Target/X86/README.txt | 83 +----- lib/Target/X86/X86.td | 4 + lib/Target/X86/X86CodeEmitter.cpp | 20 +- lib/Target/X86/X86FastISel.cpp | 16 +- lib/Target/X86/X86FloatingPoint.cpp | 16 +- lib/Target/X86/X86ISelDAGToDAG.cpp | 157 +++++----- lib/Target/X86/X86ISelLowering.cpp | 241 ++++++++++++---- lib/Target/X86/X86Instr64bit.td | 94 +++--- lib/Target/X86/X86InstrInfo.cpp | 73 ++++- lib/Target/X86/X86InstrInfo.h | 10 + lib/Target/X86/X86InstrInfo.td | 75 ++++- lib/Target/X86/X86InstrSSE.td | 10 +- lib/Target/X86/X86JITInfo.cpp | 2 +- lib/Target/X86/X86RegisterInfo.cpp | 9 + lib/Target/X86/X86Subtarget.cpp | 3 +- lib/Target/X86/X86Subtarget.h | 7 +- lib/Target/XCore/XCoreISelDAGToDAG.cpp | 31 +- 56 files changed, 1368 insertions(+), 1072 deletions(-) (limited to 'lib/Target') diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp index 7cfa097..969c4a4 100644 --- a/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -938,6 +938,35 @@ ARMBaseInstrInfo::canFoldMemoryOperand(const MachineInstr *MI, return false; } +/// Create a copy of a const pool value. Update CPI to the new index and return +/// the label UID. +static unsigned duplicateCPV(MachineFunction &MF, unsigned &CPI) { + MachineConstantPool *MCP = MF.getConstantPool(); + ARMFunctionInfo *AFI = MF.getInfo(); + + const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPI]; + assert(MCPE.isMachineConstantPoolEntry() && + "Expecting a machine constantpool entry!"); + ARMConstantPoolValue *ACPV = + static_cast(MCPE.Val.MachineCPVal); + + unsigned PCLabelId = AFI->createConstPoolEntryUId(); + ARMConstantPoolValue *NewCPV = 0; + if (ACPV->isGlobalValue()) + NewCPV = new ARMConstantPoolValue(ACPV->getGV(), PCLabelId, + ARMCP::CPValue, 4); + else if (ACPV->isExtSymbol()) + NewCPV = new ARMConstantPoolValue(MF.getFunction()->getContext(), + ACPV->getSymbol(), PCLabelId, 4); + else if (ACPV->isBlockAddress()) + NewCPV = new ARMConstantPoolValue(ACPV->getBlockAddress(), PCLabelId, + ARMCP::CPBlockAddress, 4); + else + llvm_unreachable("Unexpected ARM constantpool value type!!"); + CPI = MCP->getConstantPoolIndex(NewCPV, MCPE.getAlignment()); + return PCLabelId; +} + void ARMBaseInstrInfo:: reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, @@ -960,28 +989,8 @@ reMaterialize(MachineBasicBlock &MBB, case ARM::tLDRpci_pic: case ARM::t2LDRpci_pic: { MachineFunction &MF = *MBB.getParent(); - ARMFunctionInfo *AFI = MF.getInfo(); - MachineConstantPool *MCP = MF.getConstantPool(); unsigned CPI = Orig->getOperand(1).getIndex(); - const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPI]; - assert(MCPE.isMachineConstantPoolEntry() && - "Expecting a machine constantpool entry!"); - ARMConstantPoolValue *ACPV = - static_cast(MCPE.Val.MachineCPVal); - unsigned PCLabelId = AFI->createConstPoolEntryUId(); - ARMConstantPoolValue *NewCPV = 0; - if (ACPV->isGlobalValue()) - NewCPV = new ARMConstantPoolValue(ACPV->getGV(), PCLabelId, - ARMCP::CPValue, 4); - else if (ACPV->isExtSymbol()) - NewCPV = new ARMConstantPoolValue(MF.getFunction()->getContext(), - ACPV->getSymbol(), PCLabelId, 4); - else if (ACPV->isBlockAddress()) - NewCPV = new ARMConstantPoolValue(ACPV->getBlockAddress(), PCLabelId, - ARMCP::CPBlockAddress, 4); - else - llvm_unreachable("Unexpected ARM constantpool value type!!"); - CPI = MCP->getConstantPoolIndex(NewCPV, MCPE.getAlignment()); + unsigned PCLabelId = duplicateCPV(MF, CPI); MachineInstrBuilder MIB = BuildMI(MBB, I, Orig->getDebugLoc(), get(Opcode), DestReg) .addConstantPoolIndex(CPI).addImm(PCLabelId); @@ -994,6 +1003,22 @@ reMaterialize(MachineBasicBlock &MBB, NewMI->getOperand(0).setSubReg(SubIdx); } +MachineInstr * +ARMBaseInstrInfo::duplicate(MachineInstr *Orig, MachineFunction &MF) const { + MachineInstr *MI = TargetInstrInfoImpl::duplicate(Orig, MF); + switch(Orig->getOpcode()) { + case ARM::tLDRpci_pic: + case ARM::t2LDRpci_pic: { + unsigned CPI = Orig->getOperand(1).getIndex(); + unsigned PCLabelId = duplicateCPV(MF, CPI); + Orig->getOperand(1).setIndex(CPI); + Orig->getOperand(2).setImm(PCLabelId); + break; + } + } + return MI; +} + bool ARMBaseInstrInfo::isIdentical(const MachineInstr *MI0, const MachineInstr *MI1, const MachineRegisterInfo *MRI) const { diff --git a/lib/Target/ARM/ARMBaseInstrInfo.h b/lib/Target/ARM/ARMBaseInstrInfo.h index 78d9135..0d9d4a7 100644 --- a/lib/Target/ARM/ARMBaseInstrInfo.h +++ b/lib/Target/ARM/ARMBaseInstrInfo.h @@ -287,6 +287,8 @@ public: const MachineInstr *Orig, const TargetRegisterInfo *TRI) const; + MachineInstr *duplicate(MachineInstr *Orig, MachineFunction &MF) const; + virtual bool isIdentical(const MachineInstr *MI, const MachineInstr *Other, const MachineRegisterInfo *MRI) const; }; diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/lib/Target/ARM/ARMBaseRegisterInfo.cpp index 7aebdf4..f1b6e1d 100644 --- a/lib/Target/ARM/ARMBaseRegisterInfo.cpp +++ b/lib/Target/ARM/ARMBaseRegisterInfo.cpp @@ -217,7 +217,8 @@ ARMBaseRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const { ? DarwinCalleeSavedRegClasses : CalleeSavedRegClasses; } -BitVector ARMBaseRegisterInfo::getReservedRegs(const MachineFunction &MF) const { +BitVector ARMBaseRegisterInfo:: +getReservedRegs(const MachineFunction &MF) const { // FIXME: avoid re-calculating this everytime. BitVector Reserved(getNumRegs()); Reserved.set(ARM::SP); @@ -494,7 +495,8 @@ needsStackRealignment(const MachineFunction &MF) const { !MFI->hasVarSizedObjects()); } -bool ARMBaseRegisterInfo::cannotEliminateFrame(const MachineFunction &MF) const { +bool ARMBaseRegisterInfo:: +cannotEliminateFrame(const MachineFunction &MF) const { const MachineFrameInfo *MFI = MF.getFrameInfo(); if (NoFramePointerElim && MFI->hasCalls()) return true; @@ -523,7 +525,7 @@ static unsigned estimateStackSize(MachineFunction &MF, MachineFrameInfo *MFI) { /// estimateRSStackSizeLimit - Look at each instruction that references stack /// frames and return the stack size limit beyond which some of these -/// instructions will require scratch register during their expansion later. +/// instructions will require a scratch register during their expansion later. unsigned ARMBaseRegisterInfo::estimateRSStackSizeLimit(MachineFunction &MF) const { unsigned Limit = (1 << 12) - 1; @@ -547,6 +549,9 @@ ARMBaseRegisterInfo::estimateRSStackSizeLimit(MachineFunction &MF) const { // When the stack offset is negative, we will end up using // the i8 instructions instead. return (1 << 8) - 1; + + if (AddrMode == ARMII::AddrMode6) + return 0; break; // At most one FI per instruction } } @@ -557,7 +562,7 @@ ARMBaseRegisterInfo::estimateRSStackSizeLimit(MachineFunction &MF) const { void ARMBaseRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, - RegScavenger *RS) const { + RegScavenger *RS) const { // This tells PEI to spill the FP as if it is any other callee-save register // to take advantage the eliminateFrameIndex machinery. This also ensures it // is spilled in the order specified by getCalleeSavedRegs() to make it easier @@ -852,7 +857,7 @@ int ARMBaseRegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const { } unsigned ARMBaseRegisterInfo::getRegisterPairEven(unsigned Reg, - const MachineFunction &MF) const { + const MachineFunction &MF) const { switch (Reg) { default: break; // Return 0 if either register of the pair is a special register. diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp index d63f3e6..14a45b3 100644 --- a/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -64,53 +64,53 @@ public: return CurDAG->getTargetConstant(Imm, MVT::i32); } - SDNode *Select(SDValue Op); + SDNode *Select(SDNode *N); virtual void InstructionSelect(); - bool SelectShifterOperandReg(SDValue Op, SDValue N, SDValue &A, + bool SelectShifterOperandReg(SDNode *Op, SDValue N, SDValue &A, SDValue &B, SDValue &C); - bool SelectAddrMode2(SDValue Op, SDValue N, SDValue &Base, + bool SelectAddrMode2(SDNode *Op, SDValue N, SDValue &Base, SDValue &Offset, SDValue &Opc); - bool SelectAddrMode2Offset(SDValue Op, SDValue N, + bool SelectAddrMode2Offset(SDNode *Op, SDValue N, SDValue &Offset, SDValue &Opc); - bool SelectAddrMode3(SDValue Op, SDValue N, SDValue &Base, + bool SelectAddrMode3(SDNode *Op, SDValue N, SDValue &Base, SDValue &Offset, SDValue &Opc); - bool SelectAddrMode3Offset(SDValue Op, SDValue N, + bool SelectAddrMode3Offset(SDNode *Op, SDValue N, SDValue &Offset, SDValue &Opc); - bool SelectAddrMode4(SDValue Op, SDValue N, SDValue &Addr, + bool SelectAddrMode4(SDNode *Op, SDValue N, SDValue &Addr, SDValue &Mode); - bool SelectAddrMode5(SDValue Op, SDValue N, SDValue &Base, + bool SelectAddrMode5(SDNode *Op, SDValue N, SDValue &Base, SDValue &Offset); - bool SelectAddrMode6(SDValue Op, SDValue N, SDValue &Addr, SDValue &Update, + bool SelectAddrMode6(SDNode *Op, SDValue N, SDValue &Addr, SDValue &Update, SDValue &Opc, SDValue &Align); - bool SelectAddrModePC(SDValue Op, SDValue N, SDValue &Offset, + bool SelectAddrModePC(SDNode *Op, SDValue N, SDValue &Offset, SDValue &Label); - bool SelectThumbAddrModeRR(SDValue Op, SDValue N, SDValue &Base, + bool SelectThumbAddrModeRR(SDNode *Op, SDValue N, SDValue &Base, SDValue &Offset); - bool SelectThumbAddrModeRI5(SDValue Op, SDValue N, unsigned Scale, + bool SelectThumbAddrModeRI5(SDNode *Op, SDValue N, unsigned Scale, SDValue &Base, SDValue &OffImm, SDValue &Offset); - bool SelectThumbAddrModeS1(SDValue Op, SDValue N, SDValue &Base, + bool SelectThumbAddrModeS1(SDNode *Op, SDValue N, SDValue &Base, SDValue &OffImm, SDValue &Offset); - bool SelectThumbAddrModeS2(SDValue Op, SDValue N, SDValue &Base, + bool SelectThumbAddrModeS2(SDNode *Op, SDValue N, SDValue &Base, SDValue &OffImm, SDValue &Offset); - bool SelectThumbAddrModeS4(SDValue Op, SDValue N, SDValue &Base, + bool SelectThumbAddrModeS4(SDNode *Op, SDValue N, SDValue &Base, SDValue &OffImm, SDValue &Offset); - bool SelectThumbAddrModeSP(SDValue Op, SDValue N, SDValue &Base, + bool SelectThumbAddrModeSP(SDNode *Op, SDValue N, SDValue &Base, SDValue &OffImm); - bool SelectT2ShifterOperandReg(SDValue Op, SDValue N, + bool SelectT2ShifterOperandReg(SDNode *Op, SDValue N, SDValue &BaseReg, SDValue &Opc); - bool SelectT2AddrModeImm12(SDValue Op, SDValue N, SDValue &Base, + bool SelectT2AddrModeImm12(SDNode *Op, SDValue N, SDValue &Base, SDValue &OffImm); - bool SelectT2AddrModeImm8(SDValue Op, SDValue N, SDValue &Base, + bool SelectT2AddrModeImm8(SDNode *Op, SDValue N, SDValue &Base, SDValue &OffImm); - bool SelectT2AddrModeImm8Offset(SDValue Op, SDValue N, + bool SelectT2AddrModeImm8Offset(SDNode *Op, SDValue N, SDValue &OffImm); - bool SelectT2AddrModeImm8s4(SDValue Op, SDValue N, SDValue &Base, + bool SelectT2AddrModeImm8s4(SDNode *Op, SDValue N, SDValue &Base, SDValue &OffImm); - bool SelectT2AddrModeSoReg(SDValue Op, SDValue N, SDValue &Base, + bool SelectT2AddrModeSoReg(SDNode *Op, SDValue N, SDValue &Base, SDValue &OffReg, SDValue &ShImm); // Include the pieces autogenerated from the target description. @@ -119,48 +119,48 @@ public: private: /// SelectARMIndexedLoad - Indexed (pre/post inc/dec) load matching code for /// ARM. - SDNode *SelectARMIndexedLoad(SDValue Op); - SDNode *SelectT2IndexedLoad(SDValue Op); + SDNode *SelectARMIndexedLoad(SDNode *N); + SDNode *SelectT2IndexedLoad(SDNode *N); /// SelectDYN_ALLOC - Select dynamic alloc for Thumb. - SDNode *SelectDYN_ALLOC(SDValue Op); + SDNode *SelectDYN_ALLOC(SDNode *N); /// SelectVLD - Select NEON load intrinsics. NumVecs should /// be 2, 3 or 4. The opcode arrays specify the instructions used for /// loads of D registers and even subregs and odd subregs of Q registers. /// For NumVecs == 2, QOpcodes1 is not used. - SDNode *SelectVLD(SDValue Op, unsigned NumVecs, unsigned *DOpcodes, + SDNode *SelectVLD(SDNode *N, unsigned NumVecs, unsigned *DOpcodes, unsigned *QOpcodes0, unsigned *QOpcodes1); /// SelectVST - Select NEON store intrinsics. NumVecs should /// be 2, 3 or 4. The opcode arrays specify the instructions used for /// stores of D registers and even subregs and odd subregs of Q registers. /// For NumVecs == 2, QOpcodes1 is not used. - SDNode *SelectVST(SDValue Op, unsigned NumVecs, unsigned *DOpcodes, + SDNode *SelectVST(SDNode *N, unsigned NumVecs, unsigned *DOpcodes, unsigned *QOpcodes0, unsigned *QOpcodes1); /// SelectVLDSTLane - Select NEON load/store lane intrinsics. NumVecs should /// be 2, 3 or 4. The opcode arrays specify the instructions used for /// load/store of D registers and even subregs and odd subregs of Q registers. - SDNode *SelectVLDSTLane(SDValue Op, bool IsLoad, unsigned NumVecs, + SDNode *SelectVLDSTLane(SDNode *N, bool IsLoad, unsigned NumVecs, unsigned *DOpcodes, unsigned *QOpcodes0, unsigned *QOpcodes1); /// SelectV6T2BitfieldExtractOp - Select SBFX/UBFX instructions for ARM. - SDNode *SelectV6T2BitfieldExtractOp(SDValue Op, unsigned Opc); + SDNode *SelectV6T2BitfieldExtractOp(SDNode *N, unsigned Opc); /// SelectCMOVOp - Select CMOV instructions for ARM. - SDNode *SelectCMOVOp(SDValue Op); - SDNode *SelectT2CMOVShiftOp(SDValue Op, SDValue FalseVal, SDValue TrueVal, + SDNode *SelectCMOVOp(SDNode *N); + SDNode *SelectT2CMOVShiftOp(SDNode *N, SDValue FalseVal, SDValue TrueVal, ARMCC::CondCodes CCVal, SDValue CCR, SDValue InFlag); - SDNode *SelectARMCMOVShiftOp(SDValue Op, SDValue FalseVal, SDValue TrueVal, + SDNode *SelectARMCMOVShiftOp(SDNode *N, SDValue FalseVal, SDValue TrueVal, ARMCC::CondCodes CCVal, SDValue CCR, SDValue InFlag); - SDNode *SelectT2CMOVSoImmOp(SDValue Op, SDValue FalseVal, SDValue TrueVal, + SDNode *SelectT2CMOVSoImmOp(SDNode *N, SDValue FalseVal, SDValue TrueVal, ARMCC::CondCodes CCVal, SDValue CCR, SDValue InFlag); - SDNode *SelectARMCMOVSoImmOp(SDValue Op, SDValue FalseVal, SDValue TrueVal, + SDNode *SelectARMCMOVSoImmOp(SDNode *N, SDValue FalseVal, SDValue TrueVal, ARMCC::CondCodes CCVal, SDValue CCR, SDValue InFlag); @@ -206,7 +206,7 @@ void ARMDAGToDAGISel::InstructionSelect() { CurDAG->RemoveDeadNodes(); } -bool ARMDAGToDAGISel::SelectShifterOperandReg(SDValue Op, +bool ARMDAGToDAGISel::SelectShifterOperandReg(SDNode *Op, SDValue N, SDValue &BaseReg, SDValue &ShReg, @@ -230,7 +230,7 @@ bool ARMDAGToDAGISel::SelectShifterOperandReg(SDValue Op, return true; } -bool ARMDAGToDAGISel::SelectAddrMode2(SDValue Op, SDValue N, +bool ARMDAGToDAGISel::SelectAddrMode2(SDNode *Op, SDValue N, SDValue &Base, SDValue &Offset, SDValue &Opc) { if (N.getOpcode() == ISD::MUL) { @@ -340,9 +340,9 @@ bool ARMDAGToDAGISel::SelectAddrMode2(SDValue Op, SDValue N, return true; } -bool ARMDAGToDAGISel::SelectAddrMode2Offset(SDValue Op, SDValue N, +bool ARMDAGToDAGISel::SelectAddrMode2Offset(SDNode *Op, SDValue N, SDValue &Offset, SDValue &Opc) { - unsigned Opcode = Op.getOpcode(); + unsigned Opcode = Op->getOpcode(); ISD::MemIndexedMode AM = (Opcode == ISD::LOAD) ? cast(Op)->getAddressingMode() : cast(Op)->getAddressingMode(); @@ -379,7 +379,7 @@ bool ARMDAGToDAGISel::SelectAddrMode2Offset(SDValue Op, SDValue N, } -bool ARMDAGToDAGISel::SelectAddrMode3(SDValue Op, SDValue N, +bool ARMDAGToDAGISel::SelectAddrMode3(SDNode *Op, SDValue N, SDValue &Base, SDValue &Offset, SDValue &Opc) { if (N.getOpcode() == ISD::SUB) { @@ -429,9 +429,9 @@ bool ARMDAGToDAGISel::SelectAddrMode3(SDValue Op, SDValue N, return true; } -bool ARMDAGToDAGISel::SelectAddrMode3Offset(SDValue Op, SDValue N, +bool ARMDAGToDAGISel::SelectAddrMode3Offset(SDNode *Op, SDValue N, SDValue &Offset, SDValue &Opc) { - unsigned Opcode = Op.getOpcode(); + unsigned Opcode = Op->getOpcode(); ISD::MemIndexedMode AM = (Opcode == ISD::LOAD) ? cast(Op)->getAddressingMode() : cast(Op)->getAddressingMode(); @@ -451,14 +451,14 @@ bool ARMDAGToDAGISel::SelectAddrMode3Offset(SDValue Op, SDValue N, return true; } -bool ARMDAGToDAGISel::SelectAddrMode4(SDValue Op, SDValue N, +bool ARMDAGToDAGISel::SelectAddrMode4(SDNode *Op, SDValue N, SDValue &Addr, SDValue &Mode) { Addr = N; Mode = CurDAG->getTargetConstant(0, MVT::i32); return true; } -bool ARMDAGToDAGISel::SelectAddrMode5(SDValue Op, SDValue N, +bool ARMDAGToDAGISel::SelectAddrMode5(SDNode *Op, SDValue N, SDValue &Base, SDValue &Offset) { if (N.getOpcode() != ISD::ADD) { Base = N; @@ -506,7 +506,7 @@ bool ARMDAGToDAGISel::SelectAddrMode5(SDValue Op, SDValue N, return true; } -bool ARMDAGToDAGISel::SelectAddrMode6(SDValue Op, SDValue N, +bool ARMDAGToDAGISel::SelectAddrMode6(SDNode *Op, SDValue N, SDValue &Addr, SDValue &Update, SDValue &Opc, SDValue &Align) { Addr = N; @@ -518,7 +518,7 @@ bool ARMDAGToDAGISel::SelectAddrMode6(SDValue Op, SDValue N, return true; } -bool ARMDAGToDAGISel::SelectAddrModePC(SDValue Op, SDValue N, +bool ARMDAGToDAGISel::SelectAddrModePC(SDNode *Op, SDValue N, SDValue &Offset, SDValue &Label) { if (N.getOpcode() == ARMISD::PIC_ADD && N.hasOneUse()) { Offset = N.getOperand(0); @@ -530,10 +530,10 @@ bool ARMDAGToDAGISel::SelectAddrModePC(SDValue Op, SDValue N, return false; } -bool ARMDAGToDAGISel::SelectThumbAddrModeRR(SDValue Op, SDValue N, +bool ARMDAGToDAGISel::SelectThumbAddrModeRR(SDNode *Op, SDValue N, SDValue &Base, SDValue &Offset){ // FIXME dl should come from the parent load or store, not the address - DebugLoc dl = Op.getDebugLoc(); + DebugLoc dl = Op->getDebugLoc(); if (N.getOpcode() != ISD::ADD) { ConstantSDNode *NC = dyn_cast(N); if (!NC || NC->getZExtValue() != 0) @@ -549,7 +549,7 @@ bool ARMDAGToDAGISel::SelectThumbAddrModeRR(SDValue Op, SDValue N, } bool -ARMDAGToDAGISel::SelectThumbAddrModeRI5(SDValue Op, SDValue N, +ARMDAGToDAGISel::SelectThumbAddrModeRI5(SDNode *Op, SDValue N, unsigned Scale, SDValue &Base, SDValue &OffImm, SDValue &Offset) { if (Scale == 4) { @@ -605,25 +605,25 @@ ARMDAGToDAGISel::SelectThumbAddrModeRI5(SDValue Op, SDValue N, return true; } -bool ARMDAGToDAGISel::SelectThumbAddrModeS1(SDValue Op, SDValue N, +bool ARMDAGToDAGISel::SelectThumbAddrModeS1(SDNode *Op, SDValue N, SDValue &Base, SDValue &OffImm, SDValue &Offset) { return SelectThumbAddrModeRI5(Op, N, 1, Base, OffImm, Offset); } -bool ARMDAGToDAGISel::SelectThumbAddrModeS2(SDValue Op, SDValue N, +bool ARMDAGToDAGISel::SelectThumbAddrModeS2(SDNode *Op, SDValue N, SDValue &Base, SDValue &OffImm, SDValue &Offset) { return SelectThumbAddrModeRI5(Op, N, 2, Base, OffImm, Offset); } -bool ARMDAGToDAGISel::SelectThumbAddrModeS4(SDValue Op, SDValue N, +bool ARMDAGToDAGISel::SelectThumbAddrModeS4(SDNode *Op, SDValue N, SDValue &Base, SDValue &OffImm, SDValue &Offset) { return SelectThumbAddrModeRI5(Op, N, 4, Base, OffImm, Offset); } -bool ARMDAGToDAGISel::SelectThumbAddrModeSP(SDValue Op, SDValue N, +bool ARMDAGToDAGISel::SelectThumbAddrModeSP(SDNode *Op, SDValue N, SDValue &Base, SDValue &OffImm) { if (N.getOpcode() == ISD::FrameIndex) { int FI = cast(N)->getIndex(); @@ -659,7 +659,7 @@ bool ARMDAGToDAGISel::SelectThumbAddrModeSP(SDValue Op, SDValue N, return false; } -bool ARMDAGToDAGISel::SelectT2ShifterOperandReg(SDValue Op, SDValue N, +bool ARMDAGToDAGISel::SelectT2ShifterOperandReg(SDNode *Op, SDValue N, SDValue &BaseReg, SDValue &Opc) { ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N); @@ -679,7 +679,7 @@ bool ARMDAGToDAGISel::SelectT2ShifterOperandReg(SDValue Op, SDValue N, return false; } -bool ARMDAGToDAGISel::SelectT2AddrModeImm12(SDValue Op, SDValue N, +bool ARMDAGToDAGISel::SelectT2AddrModeImm12(SDNode *Op, SDValue N, SDValue &Base, SDValue &OffImm) { // Match simple R + imm12 operands. @@ -729,7 +729,7 @@ bool ARMDAGToDAGISel::SelectT2AddrModeImm12(SDValue Op, SDValue N, return true; } -bool ARMDAGToDAGISel::SelectT2AddrModeImm8(SDValue Op, SDValue N, +bool ARMDAGToDAGISel::SelectT2AddrModeImm8(SDNode *Op, SDValue N, SDValue &Base, SDValue &OffImm) { // Match simple R - imm8 operands. if (N.getOpcode() == ISD::ADD || N.getOpcode() == ISD::SUB) { @@ -753,9 +753,9 @@ bool ARMDAGToDAGISel::SelectT2AddrModeImm8(SDValue Op, SDValue N, return false; } -bool ARMDAGToDAGISel::SelectT2AddrModeImm8Offset(SDValue Op, SDValue N, +bool ARMDAGToDAGISel::SelectT2AddrModeImm8Offset(SDNode *Op, SDValue N, SDValue &OffImm){ - unsigned Opcode = Op.getOpcode(); + unsigned Opcode = Op->getOpcode(); ISD::MemIndexedMode AM = (Opcode == ISD::LOAD) ? cast(Op)->getAddressingMode() : cast(Op)->getAddressingMode(); @@ -772,7 +772,7 @@ bool ARMDAGToDAGISel::SelectT2AddrModeImm8Offset(SDValue Op, SDValue N, return false; } -bool ARMDAGToDAGISel::SelectT2AddrModeImm8s4(SDValue Op, SDValue N, +bool ARMDAGToDAGISel::SelectT2AddrModeImm8s4(SDNode *Op, SDValue N, SDValue &Base, SDValue &OffImm) { if (N.getOpcode() == ISD::ADD) { if (ConstantSDNode *RHS = dyn_cast(N.getOperand(1))) { @@ -798,7 +798,7 @@ bool ARMDAGToDAGISel::SelectT2AddrModeImm8s4(SDValue Op, SDValue N, return false; } -bool ARMDAGToDAGISel::SelectT2AddrModeSoReg(SDValue Op, SDValue N, +bool ARMDAGToDAGISel::SelectT2AddrModeSoReg(SDNode *Op, SDValue N, SDValue &Base, SDValue &OffReg, SDValue &ShImm) { // (R - imm8) should be handled by t2LDRi8. The rest are handled by t2LDRi12. @@ -854,8 +854,8 @@ static inline SDValue getAL(SelectionDAG *CurDAG) { return CurDAG->getTargetConstant((uint64_t)ARMCC::AL, MVT::i32); } -SDNode *ARMDAGToDAGISel::SelectARMIndexedLoad(SDValue Op) { - LoadSDNode *LD = cast(Op); +SDNode *ARMDAGToDAGISel::SelectARMIndexedLoad(SDNode *N) { + LoadSDNode *LD = cast(N); ISD::MemIndexedMode AM = LD->getAddressingMode(); if (AM == ISD::UNINDEXED) return NULL; @@ -866,23 +866,23 @@ SDNode *ARMDAGToDAGISel::SelectARMIndexedLoad(SDValue Op) { unsigned Opcode = 0; bool Match = false; if (LoadedVT == MVT::i32 && - SelectAddrMode2Offset(Op, LD->getOffset(), Offset, AMOpc)) { + SelectAddrMode2Offset(N, LD->getOffset(), Offset, AMOpc)) { Opcode = isPre ? ARM::LDR_PRE : ARM::LDR_POST; Match = true; } else if (LoadedVT == MVT::i16 && - SelectAddrMode3Offset(Op, LD->getOffset(), Offset, AMOpc)) { + SelectAddrMode3Offset(N, LD->getOffset(), Offset, AMOpc)) { Match = true; Opcode = (LD->getExtensionType() == ISD::SEXTLOAD) ? (isPre ? ARM::LDRSH_PRE : ARM::LDRSH_POST) : (isPre ? ARM::LDRH_PRE : ARM::LDRH_POST); } else if (LoadedVT == MVT::i8 || LoadedVT == MVT::i1) { if (LD->getExtensionType() == ISD::SEXTLOAD) { - if (SelectAddrMode3Offset(Op, LD->getOffset(), Offset, AMOpc)) { + if (SelectAddrMode3Offset(N, LD->getOffset(), Offset, AMOpc)) { Match = true; Opcode = isPre ? ARM::LDRSB_PRE : ARM::LDRSB_POST; } } else { - if (SelectAddrMode2Offset(Op, LD->getOffset(), Offset, AMOpc)) { + if (SelectAddrMode2Offset(N, LD->getOffset(), Offset, AMOpc)) { Match = true; Opcode = isPre ? ARM::LDRB_PRE : ARM::LDRB_POST; } @@ -894,15 +894,15 @@ SDNode *ARMDAGToDAGISel::SelectARMIndexedLoad(SDValue Op) { SDValue Base = LD->getBasePtr(); SDValue Ops[]= { Base, Offset, AMOpc, getAL(CurDAG), CurDAG->getRegister(0, MVT::i32), Chain }; - return CurDAG->getMachineNode(Opcode, Op.getDebugLoc(), MVT::i32, MVT::i32, + return CurDAG->getMachineNode(Opcode, N->getDebugLoc(), MVT::i32, MVT::i32, MVT::Other, Ops, 6); } return NULL; } -SDNode *ARMDAGToDAGISel::SelectT2IndexedLoad(SDValue Op) { - LoadSDNode *LD = cast(Op); +SDNode *ARMDAGToDAGISel::SelectT2IndexedLoad(SDNode *N) { + LoadSDNode *LD = cast(N); ISD::MemIndexedMode AM = LD->getAddressingMode(); if (AM == ISD::UNINDEXED) return NULL; @@ -913,7 +913,7 @@ SDNode *ARMDAGToDAGISel::SelectT2IndexedLoad(SDValue Op) { bool isPre = (AM == ISD::PRE_INC) || (AM == ISD::PRE_DEC); unsigned Opcode = 0; bool Match = false; - if (SelectT2AddrModeImm8Offset(Op, LD->getOffset(), Offset)) { + if (SelectT2AddrModeImm8Offset(N, LD->getOffset(), Offset)) { switch (LoadedVT.getSimpleVT().SimpleTy) { case MVT::i32: Opcode = isPre ? ARM::t2LDR_PRE : ARM::t2LDR_POST; @@ -942,20 +942,19 @@ SDNode *ARMDAGToDAGISel::SelectT2IndexedLoad(SDValue Op) { SDValue Base = LD->getBasePtr(); SDValue Ops[]= { Base, Offset, getAL(CurDAG), CurDAG->getRegister(0, MVT::i32), Chain }; - return CurDAG->getMachineNode(Opcode, Op.getDebugLoc(), MVT::i32, MVT::i32, + return CurDAG->getMachineNode(Opcode, N->getDebugLoc(), MVT::i32, MVT::i32, MVT::Other, Ops, 5); } return NULL; } -SDNode *ARMDAGToDAGISel::SelectDYN_ALLOC(SDValue Op) { - SDNode *N = Op.getNode(); +SDNode *ARMDAGToDAGISel::SelectDYN_ALLOC(SDNode *N) { DebugLoc dl = N->getDebugLoc(); - EVT VT = Op.getValueType(); - SDValue Chain = Op.getOperand(0); - SDValue Size = Op.getOperand(1); - SDValue Align = Op.getOperand(2); + EVT VT = N->getValueType(0); + SDValue Chain = N->getOperand(0); + SDValue Size = N->getOperand(1); + SDValue Align = N->getOperand(2); SDValue SP = CurDAG->getRegister(ARM::SP, MVT::i32); int32_t AlignVal = cast(Align)->getSExtValue(); if (AlignVal < 0) @@ -1030,15 +1029,14 @@ static EVT GetNEONSubregVT(EVT VT) { } } -SDNode *ARMDAGToDAGISel::SelectVLD(SDValue Op, unsigned NumVecs, +SDNode *ARMDAGToDAGISel::SelectVLD(SDNode *N, unsigned NumVecs, unsigned *DOpcodes, unsigned *QOpcodes0, unsigned *QOpcodes1) { assert(NumVecs >=2 && NumVecs <= 4 && "VLD NumVecs out-of-range"); - SDNode *N = Op.getNode(); DebugLoc dl = N->getDebugLoc(); SDValue MemAddr, MemUpdate, MemOpc, Align; - if (!SelectAddrMode6(Op, N->getOperand(2), MemAddr, MemUpdate, MemOpc, Align)) + if (!SelectAddrMode6(N, N->getOperand(2), MemAddr, MemUpdate, MemOpc, Align)) return NULL; SDValue Chain = N->getOperand(0); @@ -1124,15 +1122,14 @@ SDNode *ARMDAGToDAGISel::SelectVLD(SDValue Op, unsigned NumVecs, return NULL; } -SDNode *ARMDAGToDAGISel::SelectVST(SDValue Op, unsigned NumVecs, +SDNode *ARMDAGToDAGISel::SelectVST(SDNode *N, unsigned NumVecs, unsigned *DOpcodes, unsigned *QOpcodes0, unsigned *QOpcodes1) { assert(NumVecs >=2 && NumVecs <= 4 && "VST NumVecs out-of-range"); - SDNode *N = Op.getNode(); DebugLoc dl = N->getDebugLoc(); SDValue MemAddr, MemUpdate, MemOpc, Align; - if (!SelectAddrMode6(Op, N->getOperand(2), MemAddr, MemUpdate, MemOpc, Align)) + if (!SelectAddrMode6(N, N->getOperand(2), MemAddr, MemUpdate, MemOpc, Align)) return NULL; SDValue Chain = N->getOperand(0); @@ -1225,16 +1222,15 @@ SDNode *ARMDAGToDAGISel::SelectVST(SDValue Op, unsigned NumVecs, return NULL; } -SDNode *ARMDAGToDAGISel::SelectVLDSTLane(SDValue Op, bool IsLoad, +SDNode *ARMDAGToDAGISel::SelectVLDSTLane(SDNode *N, bool IsLoad, unsigned NumVecs, unsigned *DOpcodes, unsigned *QOpcodes0, unsigned *QOpcodes1) { assert(NumVecs >=2 && NumVecs <= 4 && "VLDSTLane NumVecs out-of-range"); - SDNode *N = Op.getNode(); DebugLoc dl = N->getDebugLoc(); SDValue MemAddr, MemUpdate, MemOpc, Align; - if (!SelectAddrMode6(Op, N->getOperand(2), MemAddr, MemUpdate, MemOpc, Align)) + if (!SelectAddrMode6(N, N->getOperand(2), MemAddr, MemUpdate, MemOpc, Align)) return NULL; SDValue Chain = N->getOperand(0); @@ -1324,38 +1320,38 @@ SDNode *ARMDAGToDAGISel::SelectVLDSTLane(SDValue Op, bool IsLoad, return NULL; } -SDNode *ARMDAGToDAGISel::SelectV6T2BitfieldExtractOp(SDValue Op, +SDNode *ARMDAGToDAGISel::SelectV6T2BitfieldExtractOp(SDNode *N, unsigned Opc) { if (!Subtarget->hasV6T2Ops()) return NULL; unsigned Shl_imm = 0; - if (isOpcWithIntImmediate(Op.getOperand(0).getNode(), ISD::SHL, Shl_imm)) { + if (isOpcWithIntImmediate(N->getOperand(0).getNode(), ISD::SHL, Shl_imm)) { assert(Shl_imm > 0 && Shl_imm < 32 && "bad amount in shift node!"); unsigned Srl_imm = 0; - if (isInt32Immediate(Op.getOperand(1), Srl_imm)) { + if (isInt32Immediate(N->getOperand(1), Srl_imm)) { assert(Srl_imm > 0 && Srl_imm < 32 && "bad amount in shift node!"); unsigned Width = 32 - Srl_imm; int LSB = Srl_imm - Shl_imm; if (LSB < 0) return NULL; SDValue Reg0 = CurDAG->getRegister(0, MVT::i32); - SDValue Ops[] = { Op.getOperand(0).getOperand(0), + SDValue Ops[] = { N->getOperand(0).getOperand(0), CurDAG->getTargetConstant(LSB, MVT::i32), CurDAG->getTargetConstant(Width, MVT::i32), getAL(CurDAG), Reg0 }; - return CurDAG->SelectNodeTo(Op.getNode(), Opc, MVT::i32, Ops, 5); + return CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops, 5); } } return NULL; } SDNode *ARMDAGToDAGISel:: -SelectT2CMOVShiftOp(SDValue Op, SDValue FalseVal, SDValue TrueVal, +SelectT2CMOVShiftOp(SDNode *N, SDValue FalseVal, SDValue TrueVal, ARMCC::CondCodes CCVal, SDValue CCR, SDValue InFlag) { SDValue CPTmp0; SDValue CPTmp1; - if (SelectT2ShifterOperandReg(Op, TrueVal, CPTmp0, CPTmp1)) { + if (SelectT2ShifterOperandReg(N, TrueVal, CPTmp0, CPTmp1)) { unsigned SOVal = cast(CPTmp1)->getZExtValue(); unsigned SOShOp = ARM_AM::getSORegShOp(SOVal); unsigned Opc = 0; @@ -1372,27 +1368,27 @@ SelectT2CMOVShiftOp(SDValue Op, SDValue FalseVal, SDValue TrueVal, CurDAG->getTargetConstant(ARM_AM::getSORegOffset(SOVal), MVT::i32); SDValue CC = CurDAG->getTargetConstant(CCVal, MVT::i32); SDValue Ops[] = { FalseVal, CPTmp0, SOShImm, CC, CCR, InFlag }; - return CurDAG->SelectNodeTo(Op.getNode(), Opc, MVT::i32,Ops, 6); + return CurDAG->SelectNodeTo(N, Opc, MVT::i32,Ops, 6); } return 0; } SDNode *ARMDAGToDAGISel:: -SelectARMCMOVShiftOp(SDValue Op, SDValue FalseVal, SDValue TrueVal, +SelectARMCMOVShiftOp(SDNode *N, SDValue FalseVal, SDValue TrueVal, ARMCC::CondCodes CCVal, SDValue CCR, SDValue InFlag) { SDValue CPTmp0; SDValue CPTmp1; SDValue CPTmp2; - if (SelectShifterOperandReg(Op, TrueVal, CPTmp0, CPTmp1, CPTmp2)) { + if (SelectShifterOperandReg(N, TrueVal, CPTmp0, CPTmp1, CPTmp2)) { SDValue CC = CurDAG->getTargetConstant(CCVal, MVT::i32); SDValue Ops[] = { FalseVal, CPTmp0, CPTmp1, CPTmp2, CC, CCR, InFlag }; - return CurDAG->SelectNodeTo(Op.getNode(), ARM::MOVCCs, MVT::i32, Ops, 7); + return CurDAG->SelectNodeTo(N, ARM::MOVCCs, MVT::i32, Ops, 7); } return 0; } SDNode *ARMDAGToDAGISel:: -SelectT2CMOVSoImmOp(SDValue Op, SDValue FalseVal, SDValue TrueVal, +SelectT2CMOVSoImmOp(SDNode *N, SDValue FalseVal, SDValue TrueVal, ARMCC::CondCodes CCVal, SDValue CCR, SDValue InFlag) { ConstantSDNode *T = dyn_cast(TrueVal); if (!T) @@ -1402,14 +1398,14 @@ SelectT2CMOVSoImmOp(SDValue Op, SDValue FalseVal, SDValue TrueVal, SDValue True = CurDAG->getTargetConstant(T->getZExtValue(), MVT::i32); SDValue CC = CurDAG->getTargetConstant(CCVal, MVT::i32); SDValue Ops[] = { FalseVal, True, CC, CCR, InFlag }; - return CurDAG->SelectNodeTo(Op.getNode(), + return CurDAG->SelectNodeTo(N, ARM::t2MOVCCi, MVT::i32, Ops, 5); } return 0; } SDNode *ARMDAGToDAGISel:: -SelectARMCMOVSoImmOp(SDValue Op, SDValue FalseVal, SDValue TrueVal, +SelectARMCMOVSoImmOp(SDNode *N, SDValue FalseVal, SDValue TrueVal, ARMCC::CondCodes CCVal, SDValue CCR, SDValue InFlag) { ConstantSDNode *T = dyn_cast(TrueVal); if (!T) @@ -1419,19 +1415,19 @@ SelectARMCMOVSoImmOp(SDValue Op, SDValue FalseVal, SDValue TrueVal, SDValue True = CurDAG->getTargetConstant(T->getZExtValue(), MVT::i32); SDValue CC = CurDAG->getTargetConstant(CCVal, MVT::i32); SDValue Ops[] = { FalseVal, True, CC, CCR, InFlag }; - return CurDAG->SelectNodeTo(Op.getNode(), + return CurDAG->SelectNodeTo(N, ARM::MOVCCi, MVT::i32, Ops, 5); } return 0; } -SDNode *ARMDAGToDAGISel::SelectCMOVOp(SDValue Op) { - EVT VT = Op.getValueType(); - SDValue FalseVal = Op.getOperand(0); - SDValue TrueVal = Op.getOperand(1); - SDValue CC = Op.getOperand(2); - SDValue CCR = Op.getOperand(3); - SDValue InFlag = Op.getOperand(4); +SDNode *ARMDAGToDAGISel::SelectCMOVOp(SDNode *N) { + EVT VT = N->getValueType(0); + SDValue FalseVal = N->getOperand(0); + SDValue TrueVal = N->getOperand(1); + SDValue CC = N->getOperand(2); + SDValue CCR = N->getOperand(3); + SDValue InFlag = N->getOperand(4); assert(CC.getOpcode() == ISD::Constant); assert(CCR.getOpcode() == ISD::Register); ARMCC::CondCodes CCVal = @@ -1445,18 +1441,18 @@ SDNode *ARMDAGToDAGISel::SelectCMOVOp(SDValue Op) { SDValue CPTmp1; SDValue CPTmp2; if (Subtarget->isThumb()) { - SDNode *Res = SelectT2CMOVShiftOp(Op, FalseVal, TrueVal, + SDNode *Res = SelectT2CMOVShiftOp(N, FalseVal, TrueVal, CCVal, CCR, InFlag); if (!Res) - Res = SelectT2CMOVShiftOp(Op, TrueVal, FalseVal, + Res = SelectT2CMOVShiftOp(N, TrueVal, FalseVal, ARMCC::getOppositeCondition(CCVal), CCR, InFlag); if (Res) return Res; } else { - SDNode *Res = SelectARMCMOVShiftOp(Op, FalseVal, TrueVal, + SDNode *Res = SelectARMCMOVShiftOp(N, FalseVal, TrueVal, CCVal, CCR, InFlag); if (!Res) - Res = SelectARMCMOVShiftOp(Op, TrueVal, FalseVal, + Res = SelectARMCMOVShiftOp(N, TrueVal, FalseVal, ARMCC::getOppositeCondition(CCVal), CCR, InFlag); if (Res) return Res; @@ -1469,18 +1465,18 @@ SDNode *ARMDAGToDAGISel::SelectCMOVOp(SDValue Op) { // (so_imm:i32 (imm:i32):$true), (imm:i32):$cc) // Pattern complexity = 10 cost = 1 size = 0 if (Subtarget->isThumb()) { - SDNode *Res = SelectT2CMOVSoImmOp(Op, FalseVal, TrueVal, + SDNode *Res = SelectT2CMOVSoImmOp(N, FalseVal, TrueVal, CCVal, CCR, InFlag); if (!Res) - Res = SelectT2CMOVSoImmOp(Op, TrueVal, FalseVal, + Res = SelectT2CMOVSoImmOp(N, TrueVal, FalseVal, ARMCC::getOppositeCondition(CCVal), CCR, InFlag); if (Res) return Res; } else { - SDNode *Res = SelectARMCMOVSoImmOp(Op, FalseVal, TrueVal, + SDNode *Res = SelectARMCMOVSoImmOp(N, FalseVal, TrueVal, CCVal, CCR, InFlag); if (!Res) - Res = SelectARMCMOVSoImmOp(Op, TrueVal, FalseVal, + Res = SelectARMCMOVSoImmOp(N, TrueVal, FalseVal, ARMCC::getOppositeCondition(CCVal), CCR, InFlag); if (Res) return Res; @@ -1514,11 +1510,10 @@ SDNode *ARMDAGToDAGISel::SelectCMOVOp(SDValue Op) { Opc = ARM::VMOVDcc; break; } - return CurDAG->SelectNodeTo(Op.getNode(), Opc, VT, Ops, 5); + return CurDAG->SelectNodeTo(N, Opc, VT, Ops, 5); } -SDNode *ARMDAGToDAGISel::Select(SDValue Op) { - SDNode *N = Op.getNode(); +SDNode *ARMDAGToDAGISel::Select(SDNode *N) { DebugLoc dl = N->getDebugLoc(); if (N->isMachineOpcode()) @@ -1569,7 +1564,7 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) { ResNode=CurDAG->getMachineNode(ARM::LDRcp, dl, MVT::i32, MVT::Other, Ops, 6); } - ReplaceUses(Op, SDValue(ResNode, 0)); + ReplaceUses(SDValue(N, 0), SDValue(ResNode, 0)); return NULL; } @@ -1593,28 +1588,28 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) { } } case ARMISD::DYN_ALLOC: - return SelectDYN_ALLOC(Op); + return SelectDYN_ALLOC(N); case ISD::SRL: - if (SDNode *I = SelectV6T2BitfieldExtractOp(Op, + if (SDNode *I = SelectV6T2BitfieldExtractOp(N, Subtarget->isThumb() ? ARM::t2UBFX : ARM::UBFX)) return I; break; case ISD::SRA: - if (SDNode *I = SelectV6T2BitfieldExtractOp(Op, + if (SDNode *I = SelectV6T2BitfieldExtractOp(N, Subtarget->isThumb() ? ARM::t2SBFX : ARM::SBFX)) return I; break; case ISD::MUL: if (Subtarget->isThumb1Only()) break; - if (ConstantSDNode *C = dyn_cast(Op.getOperand(1))) { + if (ConstantSDNode *C = dyn_cast(N->getOperand(1))) { unsigned RHSV = C->getZExtValue(); if (!RHSV) break; if (isPowerOf2_32(RHSV-1)) { // 2^n+1? unsigned ShImm = Log2_32(RHSV-1); if (ShImm >= 32) break; - SDValue V = Op.getOperand(0); + SDValue V = N->getOperand(0); ShImm = ARM_AM::getSORegOpc(ARM_AM::lsl, ShImm); SDValue ShImmOp = CurDAG->getTargetConstant(ShImm, MVT::i32); SDValue Reg0 = CurDAG->getRegister(0, MVT::i32); @@ -1630,7 +1625,7 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) { unsigned ShImm = Log2_32(RHSV+1); if (ShImm >= 32) break; - SDValue V = Op.getOperand(0); + SDValue V = N->getOperand(0); ShImm = ARM_AM::getSORegOpc(ARM_AM::lsl, ShImm); SDValue ShImmOp = CurDAG->getTargetConstant(ShImm, MVT::i32); SDValue Reg0 = CurDAG->getRegister(0, MVT::i32); @@ -1650,7 +1645,7 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) { // are entirely contributed by c2 and lower 16-bits are entirely contributed // by x. That's equal to (or (and x, 0xffff), (and c1, 0xffff0000)). // Select it to: "movt x, ((c1 & 0xffff) >> 16) - EVT VT = Op.getValueType(); + EVT VT = N->getValueType(0); if (VT != MVT::i32) break; unsigned Opc = (Subtarget->isThumb() && Subtarget->hasThumb2()) @@ -1658,7 +1653,7 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) { : (Subtarget->hasV6T2Ops() ? ARM::MOVTi16 : 0); if (!Opc) break; - SDValue N0 = Op.getOperand(0), N1 = Op.getOperand(1); + SDValue N0 = N->getOperand(0), N1 = N->getOperand(1); ConstantSDNode *N1C = dyn_cast(N1); if (!N1C) break; @@ -1683,18 +1678,18 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) { } case ARMISD::VMOVRRD: return CurDAG->getMachineNode(ARM::VMOVRRD, dl, MVT::i32, MVT::i32, - Op.getOperand(0), getAL(CurDAG), + N->getOperand(0), getAL(CurDAG), CurDAG->getRegister(0, MVT::i32)); case ISD::UMUL_LOHI: { if (Subtarget->isThumb1Only()) break; if (Subtarget->isThumb()) { - SDValue Ops[] = { Op.getOperand(0), Op.getOperand(1), + SDValue Ops[] = { N->getOperand(0), N->getOperand(1), getAL(CurDAG), CurDAG->getRegister(0, MVT::i32), CurDAG->getRegister(0, MVT::i32) }; return CurDAG->getMachineNode(ARM::t2UMULL, dl, MVT::i32, MVT::i32, Ops,4); } else { - SDValue Ops[] = { Op.getOperand(0), Op.getOperand(1), + SDValue Ops[] = { N->getOperand(0), N->getOperand(1), getAL(CurDAG), CurDAG->getRegister(0, MVT::i32), CurDAG->getRegister(0, MVT::i32) }; return CurDAG->getMachineNode(ARM::UMULL, dl, MVT::i32, MVT::i32, Ops, 5); @@ -1704,11 +1699,11 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) { if (Subtarget->isThumb1Only()) break; if (Subtarget->isThumb()) { - SDValue Ops[] = { Op.getOperand(0), Op.getOperand(1), + SDValue Ops[] = { N->getOperand(0), N->getOperand(1), getAL(CurDAG), CurDAG->getRegister(0, MVT::i32) }; return CurDAG->getMachineNode(ARM::t2SMULL, dl, MVT::i32, MVT::i32, Ops,4); } else { - SDValue Ops[] = { Op.getOperand(0), Op.getOperand(1), + SDValue Ops[] = { N->getOperand(0), N->getOperand(1), getAL(CurDAG), CurDAG->getRegister(0, MVT::i32), CurDAG->getRegister(0, MVT::i32) }; return CurDAG->getMachineNode(ARM::SMULL, dl, MVT::i32, MVT::i32, Ops, 5); @@ -1717,9 +1712,9 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) { case ISD::LOAD: { SDNode *ResNode = 0; if (Subtarget->isThumb() && Subtarget->hasThumb2()) - ResNode = SelectT2IndexedLoad(Op); + ResNode = SelectT2IndexedLoad(N); else - ResNode = SelectARMIndexedLoad(Op); + ResNode = SelectARMIndexedLoad(N); if (ResNode) return ResNode; // Other cases are autogenerated. @@ -1740,11 +1735,11 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) { unsigned Opc = Subtarget->isThumb() ? ((Subtarget->hasThumb2()) ? ARM::t2Bcc : ARM::tBcc) : ARM::Bcc; - SDValue Chain = Op.getOperand(0); - SDValue N1 = Op.getOperand(1); - SDValue N2 = Op.getOperand(2); - SDValue N3 = Op.getOperand(3); - SDValue InFlag = Op.getOperand(4); + SDValue Chain = N->getOperand(0); + SDValue N1 = N->getOperand(1); + SDValue N2 = N->getOperand(2); + SDValue N3 = N->getOperand(3); + SDValue InFlag = N->getOperand(4); assert(N1.getOpcode() == ISD::BasicBlock); assert(N2.getOpcode() == ISD::Constant); assert(N3.getOpcode() == ISD::Register); @@ -1756,23 +1751,23 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) { SDNode *ResNode = CurDAG->getMachineNode(Opc, dl, MVT::Other, MVT::Flag, Ops, 5); Chain = SDValue(ResNode, 0); - if (Op.getNode()->getNumValues() == 2) { + if (N->getNumValues() == 2) { InFlag = SDValue(ResNode, 1); - ReplaceUses(SDValue(Op.getNode(), 1), InFlag); + ReplaceUses(SDValue(N, 1), InFlag); } - ReplaceUses(SDValue(Op.getNode(), 0), + ReplaceUses(SDValue(N, 0), SDValue(Chain.getNode(), Chain.getResNo())); return NULL; } case ARMISD::CMOV: - return SelectCMOVOp(Op); + return SelectCMOVOp(N); case ARMISD::CNEG: { - EVT VT = Op.getValueType(); - SDValue N0 = Op.getOperand(0); - SDValue N1 = Op.getOperand(1); - SDValue N2 = Op.getOperand(2); - SDValue N3 = Op.getOperand(3); - SDValue InFlag = Op.getOperand(4); + EVT VT = N->getValueType(0); + SDValue N0 = N->getOperand(0); + SDValue N1 = N->getOperand(1); + SDValue N2 = N->getOperand(2); + SDValue N3 = N->getOperand(3); + SDValue InFlag = N->getOperand(4); assert(N2.getOpcode() == ISD::Constant); assert(N3.getOpcode() == ISD::Register); @@ -1791,7 +1786,7 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) { Opc = ARM::VNEGDcc; break; } - return CurDAG->SelectNodeTo(Op.getNode(), Opc, VT, Ops, 5); + return CurDAG->SelectNodeTo(N, Opc, VT, Ops, 5); } case ARMISD::VZIP: { @@ -1863,7 +1858,7 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) { unsigned DOpcodes[] = { ARM::VLD2d8, ARM::VLD2d16, ARM::VLD2d32, ARM::VLD2d64 }; unsigned QOpcodes[] = { ARM::VLD2q8, ARM::VLD2q16, ARM::VLD2q32 }; - return SelectVLD(Op, 2, DOpcodes, QOpcodes, 0); + return SelectVLD(N, 2, DOpcodes, QOpcodes, 0); } case Intrinsic::arm_neon_vld3: { @@ -1871,7 +1866,7 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) { ARM::VLD3d32, ARM::VLD3d64 }; unsigned QOpcodes0[] = { ARM::VLD3q8a, ARM::VLD3q16a, ARM::VLD3q32a }; unsigned QOpcodes1[] = { ARM::VLD3q8b, ARM::VLD3q16b, ARM::VLD3q32b }; - return SelectVLD(Op, 3, DOpcodes, QOpcodes0, QOpcodes1); + return SelectVLD(N, 3, DOpcodes, QOpcodes0, QOpcodes1); } case Intrinsic::arm_neon_vld4: { @@ -1879,35 +1874,35 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) { ARM::VLD4d32, ARM::VLD4d64 }; unsigned QOpcodes0[] = { ARM::VLD4q8a, ARM::VLD4q16a, ARM::VLD4q32a }; unsigned QOpcodes1[] = { ARM::VLD4q8b, ARM::VLD4q16b, ARM::VLD4q32b }; - return SelectVLD(Op, 4, DOpcodes, QOpcodes0, QOpcodes1); + return SelectVLD(N, 4, DOpcodes, QOpcodes0, QOpcodes1); } case Intrinsic::arm_neon_vld2lane: { unsigned DOpcodes[] = { ARM::VLD2LNd8, ARM::VLD2LNd16, ARM::VLD2LNd32 }; unsigned QOpcodes0[] = { ARM::VLD2LNq16a, ARM::VLD2LNq32a }; unsigned QOpcodes1[] = { ARM::VLD2LNq16b, ARM::VLD2LNq32b }; - return SelectVLDSTLane(Op, true, 2, DOpcodes, QOpcodes0, QOpcodes1); + return SelectVLDSTLane(N, true, 2, DOpcodes, QOpcodes0, QOpcodes1); } case Intrinsic::arm_neon_vld3lane: { unsigned DOpcodes[] = { ARM::VLD3LNd8, ARM::VLD3LNd16, ARM::VLD3LNd32 }; unsigned QOpcodes0[] = { ARM::VLD3LNq16a, ARM::VLD3LNq32a }; unsigned QOpcodes1[] = { ARM::VLD3LNq16b, ARM::VLD3LNq32b }; - return SelectVLDSTLane(Op, true, 3, DOpcodes, QOpcodes0, QOpcodes1); + return SelectVLDSTLane(N, true, 3, DOpcodes, QOpcodes0, QOpcodes1); } case Intrinsic::arm_neon_vld4lane: { unsigned DOpcodes[] = { ARM::VLD4LNd8, ARM::VLD4LNd16, ARM::VLD4LNd32 }; unsigned QOpcodes0[] = { ARM::VLD4LNq16a, ARM::VLD4LNq32a }; unsigned QOpcodes1[] = { ARM::VLD4LNq16b, ARM::VLD4LNq32b }; - return SelectVLDSTLane(Op, true, 4, DOpcodes, QOpcodes0, QOpcodes1); + return SelectVLDSTLane(N, true, 4, DOpcodes, QOpcodes0, QOpcodes1); } case Intrinsic::arm_neon_vst2: { unsigned DOpcodes[] = { ARM::VST2d8, ARM::VST2d16, ARM::VST2d32, ARM::VST2d64 }; unsigned QOpcodes[] = { ARM::VST2q8, ARM::VST2q16, ARM::VST2q32 }; - return SelectVST(Op, 2, DOpcodes, QOpcodes, 0); + return SelectVST(N, 2, DOpcodes, QOpcodes, 0); } case Intrinsic::arm_neon_vst3: { @@ -1915,7 +1910,7 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) { ARM::VST3d32, ARM::VST3d64 }; unsigned QOpcodes0[] = { ARM::VST3q8a, ARM::VST3q16a, ARM::VST3q32a }; unsigned QOpcodes1[] = { ARM::VST3q8b, ARM::VST3q16b, ARM::VST3q32b }; - return SelectVST(Op, 3, DOpcodes, QOpcodes0, QOpcodes1); + return SelectVST(N, 3, DOpcodes, QOpcodes0, QOpcodes1); } case Intrinsic::arm_neon_vst4: { @@ -1923,34 +1918,34 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) { ARM::VST4d32, ARM::VST4d64 }; unsigned QOpcodes0[] = { ARM::VST4q8a, ARM::VST4q16a, ARM::VST4q32a }; unsigned QOpcodes1[] = { ARM::VST4q8b, ARM::VST4q16b, ARM::VST4q32b }; - return SelectVST(Op, 4, DOpcodes, QOpcodes0, QOpcodes1); + return SelectVST(N, 4, DOpcodes, QOpcodes0, QOpcodes1); } case Intrinsic::arm_neon_vst2lane: { unsigned DOpcodes[] = { ARM::VST2LNd8, ARM::VST2LNd16, ARM::VST2LNd32 }; unsigned QOpcodes0[] = { ARM::VST2LNq16a, ARM::VST2LNq32a }; unsigned QOpcodes1[] = { ARM::VST2LNq16b, ARM::VST2LNq32b }; - return SelectVLDSTLane(Op, false, 2, DOpcodes, QOpcodes0, QOpcodes1); + return SelectVLDSTLane(N, false, 2, DOpcodes, QOpcodes0, QOpcodes1); } case Intrinsic::arm_neon_vst3lane: { unsigned DOpcodes[] = { ARM::VST3LNd8, ARM::VST3LNd16, ARM::VST3LNd32 }; unsigned QOpcodes0[] = { ARM::VST3LNq16a, ARM::VST3LNq32a }; unsigned QOpcodes1[] = { ARM::VST3LNq16b, ARM::VST3LNq32b }; - return SelectVLDSTLane(Op, false, 3, DOpcodes, QOpcodes0, QOpcodes1); + return SelectVLDSTLane(N, false, 3, DOpcodes, QOpcodes0, QOpcodes1); } case Intrinsic::arm_neon_vst4lane: { unsigned DOpcodes[] = { ARM::VST4LNd8, ARM::VST4LNd16, ARM::VST4LNd32 }; unsigned QOpcodes0[] = { ARM::VST4LNq16a, ARM::VST4LNq32a }; unsigned QOpcodes1[] = { ARM::VST4LNq16b, ARM::VST4LNq32b }; - return SelectVLDSTLane(Op, false, 4, DOpcodes, QOpcodes0, QOpcodes1); + return SelectVLDSTLane(N, false, 4, DOpcodes, QOpcodes0, QOpcodes1); } } } } - return SelectCode(Op); + return SelectCode(N); } bool ARMDAGToDAGISel:: diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index 334baae..7b62c00 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -3130,6 +3130,9 @@ ARMTargetLowering::EmitAtomicCmpSwap(MachineInstr *MI, // exitMBB: // ... BB = exitMBB; + + MF->DeleteMachineInstr(MI); // The instruction is gone now. + return BB; } @@ -3140,7 +3143,7 @@ ARMTargetLowering::EmitAtomicBinary(MachineInstr *MI, MachineBasicBlock *BB, const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); const BasicBlock *LLVM_BB = BB->getBasicBlock(); - MachineFunction *F = BB->getParent(); + MachineFunction *MF = BB->getParent(); MachineFunction::iterator It = BB; ++It; @@ -3155,7 +3158,7 @@ ARMTargetLowering::EmitAtomicBinary(MachineInstr *MI, MachineBasicBlock *BB, default: llvm_unreachable("unsupported size for AtomicCmpSwap!"); case 1: ldrOpc = isThumb2 ? ARM::t2LDREXB : ARM::LDREXB; - strOpc = isThumb2 ? ARM::t2LDREXB : ARM::STREXB; + strOpc = isThumb2 ? ARM::t2STREXB : ARM::STREXB; break; case 2: ldrOpc = isThumb2 ? ARM::t2LDREXH : ARM::LDREXH; @@ -3167,13 +3170,13 @@ ARMTargetLowering::EmitAtomicBinary(MachineInstr *MI, MachineBasicBlock *BB, break; } - MachineBasicBlock *loopMBB = F->CreateMachineBasicBlock(LLVM_BB); - MachineBasicBlock *exitMBB = F->CreateMachineBasicBlock(LLVM_BB); - F->insert(It, loopMBB); - F->insert(It, exitMBB); + MachineBasicBlock *loopMBB = MF->CreateMachineBasicBlock(LLVM_BB); + MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB); + MF->insert(It, loopMBB); + MF->insert(It, exitMBB); exitMBB->transferSuccessors(BB); - MachineRegisterInfo &RegInfo = F->getRegInfo(); + MachineRegisterInfo &RegInfo = MF->getRegInfo(); unsigned scratch = RegInfo.createVirtualRegister(ARM::GPRRegisterClass); unsigned scratch2 = (!BinOpcode) ? incr : RegInfo.createVirtualRegister(ARM::GPRRegisterClass); @@ -3216,7 +3219,7 @@ ARMTargetLowering::EmitAtomicBinary(MachineInstr *MI, MachineBasicBlock *BB, // ... BB = exitMBB; - F->DeleteMachineInstr(MI); // The instruction is gone now. + MF->DeleteMachineInstr(MI); // The instruction is gone now. return BB; } @@ -4258,10 +4261,10 @@ std::pair ARMTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint, EVT VT) const { if (Constraint.size() == 1) { - // GCC RS6000 Constraint Letters + // GCC ARM Constraint Letters switch (Constraint[0]) { case 'l': - if (Subtarget->isThumb1Only()) + if (Subtarget->isThumb()) return std::make_pair(0U, ARM::tGPRRegisterClass); else return std::make_pair(0U, ARM::GPRRegisterClass); diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index da8b373..f67e74a 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -127,8 +127,8 @@ def IsThumb2 : Predicate<"Subtarget->isThumb2()">; def IsARM : Predicate<"!Subtarget->isThumb()">; def IsDarwin : Predicate<"Subtarget->isTargetDarwin()">; def IsNotDarwin : Predicate<"!Subtarget->isTargetDarwin()">; -def CarryDefIsUnused : Predicate<"!N.getNode()->hasAnyUseOfValue(1)">; -def CarryDefIsUsed : Predicate<"N.getNode()->hasAnyUseOfValue(1)">; +def CarryDefIsUnused : Predicate<"!N->hasAnyUseOfValue(1)">; +def CarryDefIsUsed : Predicate<"N->hasAnyUseOfValue(1)">; // FIXME: Eventually this will be just "hasV6T2Ops". def UseMovt : Predicate<"Subtarget->useMovt()">; diff --git a/lib/Target/ARM/ARMInstrThumb.td b/lib/Target/ARM/ARMInstrThumb.td index 34d7d8f..603ccf5 100644 --- a/lib/Target/ARM/ARMInstrThumb.td +++ b/lib/Target/ARM/ARMInstrThumb.td @@ -113,7 +113,7 @@ def t_addrmode_s1 : Operand, def t_addrmode_sp : Operand, ComplexPattern { let PrintMethod = "printThumbAddrModeSPOperand"; - let MIOperandInfo = (ops JustSP:$base, i32imm:$offsimm); + let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); } //===----------------------------------------------------------------------===// @@ -208,9 +208,8 @@ let isReturn = 1, isTerminator = 1, isBarrier = 1 in { let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in { def tBRIND : TI<(outs), (ins GPR:$dst), IIC_Br, "mov\tpc, $dst", [(brind GPR:$dst)]>, - T1Special<{1,0,?,?}> { - // = pc - let Inst{7} = 1; + T1Special<{1,0,1,1}> { + // = Inst{7:2-0} = pc let Inst{2-0} = 0b111; } } @@ -342,16 +341,28 @@ def tLDR : T1pI4<(outs tGPR:$dst), (ins t_addrmode_s4:$addr), IIC_iLoadr, "ldr", "\t$dst, $addr", [(set tGPR:$dst, (load t_addrmode_s4:$addr))]>, T1LdSt<0b100>; +def tLDRi: T1pI4<(outs tGPR:$dst), (ins t_addrmode_s4:$addr), IIC_iLoadr, + "ldr", "\t$dst, $addr", + []>, + T1LdSt4Imm<{1,?,?}>; def tLDRB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_s1:$addr), IIC_iLoadr, "ldrb", "\t$dst, $addr", [(set tGPR:$dst, (zextloadi8 t_addrmode_s1:$addr))]>, T1LdSt<0b110>; +def tLDRBi: T1pI1<(outs tGPR:$dst), (ins t_addrmode_s1:$addr), IIC_iLoadr, + "ldrb", "\t$dst, $addr", + []>, + T1LdSt1Imm<{1,?,?}>; def tLDRH : T1pI2<(outs tGPR:$dst), (ins t_addrmode_s2:$addr), IIC_iLoadr, "ldrh", "\t$dst, $addr", [(set tGPR:$dst, (zextloadi16 t_addrmode_s2:$addr))]>, T1LdSt<0b101>; +def tLDRHi: T1pI2<(outs tGPR:$dst), (ins t_addrmode_s2:$addr), IIC_iLoadr, + "ldrh", "\t$dst, $addr", + []>, + T1LdSt2Imm<{1,?,?}>; let AddedComplexity = 10 in def tLDRSB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), IIC_iLoadr, @@ -397,16 +408,28 @@ def tSTR : T1pI4<(outs), (ins tGPR:$src, t_addrmode_s4:$addr), IIC_iStorer, "str", "\t$src, $addr", [(store tGPR:$src, t_addrmode_s4:$addr)]>, T1LdSt<0b000>; +def tSTRi: T1pI4<(outs), (ins tGPR:$src, t_addrmode_s4:$addr), IIC_iStorer, + "str", "\t$src, $addr", + []>, + T1LdSt4Imm<{0,?,?}>; def tSTRB : T1pI1<(outs), (ins tGPR:$src, t_addrmode_s1:$addr), IIC_iStorer, "strb", "\t$src, $addr", [(truncstorei8 tGPR:$src, t_addrmode_s1:$addr)]>, T1LdSt<0b010>; +def tSTRBi: T1pI1<(outs), (ins tGPR:$src, t_addrmode_s1:$addr), IIC_iStorer, + "strb", "\t$src, $addr", + []>, + T1LdSt1Imm<{0,?,?}>; def tSTRH : T1pI2<(outs), (ins tGPR:$src, t_addrmode_s2:$addr), IIC_iStorer, "strh", "\t$src, $addr", [(truncstorei16 tGPR:$src, t_addrmode_s2:$addr)]>, T1LdSt<0b001>; +def tSTRHi: T1pI2<(outs), (ins tGPR:$src, t_addrmode_s2:$addr), IIC_iStorer, + "strh", "\t$src, $addr", + []>, + T1LdSt2Imm<{0,?,?}>; def tSTRspi : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), IIC_iStorei, "str", "\t$src, $addr", @@ -748,7 +771,7 @@ let usesCustomInserter = 1 in // Expanded after instruction selection. // 16-bit movcc in IT blocks for Thumb2. def tMOVCCr : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iCMOVr, "mov", "\t$dst, $rhs", []>, - T1Special<{1,0,?,?}>; + T1Special<{1,0,1,1}>; def tMOVCCi : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), IIC_iCMOVi, "mov", "\t$dst, $rhs", []>, diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index 6f20ed4..769df7e 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -360,8 +360,8 @@ multiclass T2I_bin_ii12rs op23_21, string opc, PatFrag opnode, opc, ".w\t$dst, $lhs, $rhs", [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]> { let Inst{31-27} = 0b11101; - let Inst{24} = 1; let Inst{26-25} = 0b01; + let Inst{24} = 1; let Inst{23-21} = op23_21; let Inst{20} = 0; // The S bit. } diff --git a/lib/Target/ARM/ARMLoadStoreOptimizer.cpp b/lib/Target/ARM/ARMLoadStoreOptimizer.cpp index b13f98a..b78b95b 100644 --- a/lib/Target/ARM/ARMLoadStoreOptimizer.cpp +++ b/lib/Target/ARM/ARMLoadStoreOptimizer.cpp @@ -740,6 +740,18 @@ bool ARMLoadStoreOpt::MergeBaseUpdateLoadStore(MachineBasicBlock &MBB, /// isMemoryOp - Returns true if instruction is a memory operations (that this /// pass is capable of operating on). static bool isMemoryOp(const MachineInstr *MI) { + if (MI->hasOneMemOperand()) { + const MachineMemOperand *MMO = *MI->memoperands_begin(); + + // Don't touch volatile memory accesses - we may be changing their order. + if (MMO->isVolatile()) + return false; + + // Unaligned ldr/str is emulated by some kernels, but unaligned ldm/stm is not. + if (MMO->getAlignment() < 4) + return false; + } + int Opcode = MI->getOpcode(); switch (Opcode) { default: break; diff --git a/lib/Target/ARM/ARMRegisterInfo.td b/lib/Target/ARM/ARMRegisterInfo.td index 9fbde81..d393e8d 100644 --- a/lib/Target/ARM/ARMRegisterInfo.td +++ b/lib/Target/ARM/ARMRegisterInfo.td @@ -367,19 +367,6 @@ def QPR_8 : RegisterClass<"ARM", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], // Condition code registers. def CCR : RegisterClass<"ARM", [i32], 32, [CPSR]>; -// Just the stack pointer (for tSTRspi and friends). -def JustSP : RegisterClass<"ARM", [i32], 32, [SP]> { - let MethodProtos = [{ - iterator allocation_order_end(const MachineFunction &MF) const; - }]; - let MethodBodies = [{ - JustSPClass::iterator - JustSPClass::allocation_order_end(const MachineFunction &MF) const { - return allocation_order_begin(MF); - } - }]; -} - //===----------------------------------------------------------------------===// // Subregister Set Definitions... now that we have all of the pieces, define the // sub registers for each register. diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index ed4667b..132738e 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -12,6 +12,7 @@ #include "llvm/ADT/Twine.h" #include "llvm/MC/MCAsmLexer.h" #include "llvm/MC/MCAsmParser.h" +#include "llvm/MC/MCParsedAsmOperand.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" @@ -78,7 +79,7 @@ private: /// @name Auto-generated Match Functions /// { - bool MatchInstruction(SmallVectorImpl &Operands, + bool MatchInstruction(const SmallVectorImpl &Operands, MCInst &Inst); /// MatchRegisterName - Match the given string to a register name and return @@ -94,14 +95,15 @@ public: ARMAsmParser(const Target &T, MCAsmParser &_Parser) : TargetAsmParser(T), Parser(_Parser) {} - virtual bool ParseInstruction(const StringRef &Name, MCInst &Inst); + virtual bool ParseInstruction(const StringRef &Name, SMLoc NameLoc, + SmallVectorImpl &Operands); virtual bool ParseDirective(AsmToken DirectiveID); }; /// ARMOperand - Instances of this class represent a parsed ARM machine /// instruction. -struct ARMOperand { +struct ARMOperand : public MCParsedAsmOperand { enum { Token, Register, @@ -515,9 +517,10 @@ int ARMAsmParser::MatchRegisterName(const StringRef &Name) { } /// A hack to allow some testing, to be replaced by a real table gen version. -bool ARMAsmParser::MatchInstruction(SmallVectorImpl &Operands, - MCInst &Inst) { - struct ARMOperand Op0 = Operands[0]; +bool ARMAsmParser:: +MatchInstruction(const SmallVectorImpl &Operands, + MCInst &Inst) { + ARMOperand &Op0 = *(ARMOperand*)Operands[0]; assert(Op0.Kind == ARMOperand::Token && "First operand not a Token"); const StringRef &Mnemonic = Op0.getToken(); if (Mnemonic == "add" || @@ -578,33 +581,27 @@ bool ARMAsmParser::ParseOperand(ARMOperand &Op) { } /// Parse an arm instruction mnemonic followed by its operands. -bool ARMAsmParser::ParseInstruction(const StringRef &Name, MCInst &Inst) { - SmallVector Operands; - - Operands.push_back(ARMOperand::CreateToken(Name)); +bool ARMAsmParser::ParseInstruction(const StringRef &Name, SMLoc NameLoc, + SmallVectorImpl &Operands) { + Operands.push_back(new ARMOperand(ARMOperand::CreateToken(Name))); SMLoc Loc = getLexer().getTok().getLoc(); if (getLexer().isNot(AsmToken::EndOfStatement)) { // Read the first operand. - Operands.push_back(ARMOperand()); - if (ParseOperand(Operands.back())) - return true; + ARMOperand Op; + if (ParseOperand(Op)) return true; + Operands.push_back(new ARMOperand(Op)); while (getLexer().is(AsmToken::Comma)) { getLexer().Lex(); // Eat the comma. // Parse and remember the operand. - Operands.push_back(ARMOperand()); - if (ParseOperand(Operands.back())) - return true; + if (ParseOperand(Op)) return true; + Operands.push_back(new ARMOperand(Op)); } } - if (!MatchInstruction(Operands, Inst)) - return false; - - Error(Loc, "ARMAsmParser::ParseInstruction only partly implemented"); - return true; + return false; } /// ParseDirective parses the arm specific directives diff --git a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp index 931d8df..2d13533 100644 --- a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp +++ b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp @@ -175,16 +175,16 @@ namespace { printDataDirective(MCPV->getType()); ARMConstantPoolValue *ACPV = static_cast(MCPV); - std::string Name; + SmallString<128> TmpNameStr; if (ACPV->isLSDA()) { - SmallString<16> LSDAName; - raw_svector_ostream(LSDAName) << MAI->getPrivateGlobalPrefix() << + raw_svector_ostream(TmpNameStr) << MAI->getPrivateGlobalPrefix() << "_LSDA_" << getFunctionNumber(); - Name = LSDAName.str(); + O << TmpNameStr.str(); } else if (ACPV->isBlockAddress()) { - Name = GetBlockAddressSymbol(ACPV->getBlockAddress())->getName(); + O << GetBlockAddressSymbol(ACPV->getBlockAddress())->getName(); } else if (ACPV->isGlobalValue()) { + std::string Name; GlobalValue *GV = ACPV->getGV(); bool isIndirect = Subtarget->isTargetDarwin() && Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel()); @@ -201,16 +201,16 @@ namespace { GV->hasHiddenVisibility() ? MMIMachO.getHiddenGVStubEntry(Sym) : MMIMachO.getGVStubEntry(Sym); if (StubSym == 0) { - SmallString<128> NameStr; - Mang->getNameWithPrefix(NameStr, GV, false); - StubSym = OutContext.GetOrCreateSymbol(NameStr.str()); + Mang->getNameWithPrefix(TmpNameStr, GV, false); + StubSym = OutContext.GetOrCreateSymbol(TmpNameStr.str()); } } + O << Name; } else { assert(ACPV->isExtSymbol() && "unrecognized constant pool value"); - Name = Mang->makeNameProper(ACPV->getSymbol()); + Mang->getNameWithPrefix(TmpNameStr, ACPV->getSymbol()); + OutContext.GetOrCreateSymbol(TmpNameStr.str())->print(O, MAI); } - O << Name; if (ACPV->hasModifier()) O << "(" << ACPV->getModifier() << ")"; if (ACPV->getPCAdjustment() != 0) { @@ -392,9 +392,10 @@ void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum, } case MachineOperand::MO_ExternalSymbol: { bool isCallOp = Modifier && !strcmp(Modifier, "call"); - std::string Name = Mang->makeNameProper(MO.getSymbolName()); - - O << Name; + SmallString<128> NameStr; + Mang->getNameWithPrefix(NameStr, MO.getSymbolName()); + OutContext.GetOrCreateSymbol(NameStr.str())->print(O, MAI); + if (isCallOp && Subtarget->isTargetELF() && TM.getRelocationModel() == Reloc::PIC_) O << "(PLT)"; diff --git a/lib/Target/Alpha/AlphaISelDAGToDAG.cpp b/lib/Target/Alpha/AlphaISelDAGToDAG.cpp index 5b0a89d..eaefef9 100644 --- a/lib/Target/Alpha/AlphaISelDAGToDAG.cpp +++ b/lib/Target/Alpha/AlphaISelDAGToDAG.cpp @@ -157,7 +157,7 @@ namespace { // Select - Convert the specified operand from a target-independent to a // target-specific node if it hasn't already been changed. - SDNode *Select(SDValue Op); + SDNode *Select(SDNode *N); /// InstructionSelect - This callback is invoked by /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. @@ -202,7 +202,7 @@ private: SDNode *getGlobalBaseReg(); SDNode *getGlobalRetAddr(); - void SelectCALL(SDValue Op); + void SelectCALL(SDNode *Op); }; } @@ -232,8 +232,7 @@ void AlphaDAGToDAGISel::InstructionSelect() { // Select - Convert the specified operand from a target-independent to a // target-specific node if it hasn't already been changed. -SDNode *AlphaDAGToDAGISel::Select(SDValue Op) { - SDNode *N = Op.getNode(); +SDNode *AlphaDAGToDAGISel::Select(SDNode *N) { if (N->isMachineOpcode()) { return NULL; // Already selected. } @@ -242,7 +241,7 @@ SDNode *AlphaDAGToDAGISel::Select(SDValue Op) { switch (N->getOpcode()) { default: break; case AlphaISD::CALL: - SelectCALL(Op); + SelectCALL(N); return NULL; case ISD::FrameIndex: { @@ -258,9 +257,9 @@ SDNode *AlphaDAGToDAGISel::Select(SDValue Op) { case AlphaISD::DivCall: { SDValue Chain = CurDAG->getEntryNode(); - SDValue N0 = Op.getOperand(0); - SDValue N1 = Op.getOperand(1); - SDValue N2 = Op.getOperand(2); + SDValue N0 = N->getOperand(0); + SDValue N1 = N->getOperand(1); + SDValue N2 = N->getOperand(2); Chain = CurDAG->getCopyToReg(Chain, dl, Alpha::R24, N1, SDValue(0,0)); Chain = CurDAG->getCopyToReg(Chain, dl, Alpha::R25, N2, @@ -287,7 +286,7 @@ SDNode *AlphaDAGToDAGISel::Select(SDValue Op) { if (uval == 0) { SDValue Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl, Alpha::R31, MVT::i64); - ReplaceUses(Op, Result); + ReplaceUses(SDValue(N, 0), Result); return NULL; } @@ -415,13 +414,12 @@ SDNode *AlphaDAGToDAGISel::Select(SDValue Op) { } - return SelectCode(Op); + return SelectCode(N); } -void AlphaDAGToDAGISel::SelectCALL(SDValue Op) { +void AlphaDAGToDAGISel::SelectCALL(SDNode *N) { //TODO: add flag stuff to prevent nondeturministic breakage! - SDNode *N = Op.getNode(); SDValue Chain = N->getOperand(0); SDValue Addr = N->getOperand(1); SDValue InFlag = N->getOperand(N->getNumOperands() - 1); @@ -442,8 +440,8 @@ void AlphaDAGToDAGISel::SelectCALL(SDValue Op) { } InFlag = Chain.getValue(1); - ReplaceUses(Op.getValue(0), Chain); - ReplaceUses(Op.getValue(1), InFlag); + ReplaceUses(SDValue(N, 0), Chain); + ReplaceUses(SDValue(N, 1), InFlag); } diff --git a/lib/Target/Blackfin/AsmPrinter/BlackfinAsmPrinter.cpp b/lib/Target/Blackfin/AsmPrinter/BlackfinAsmPrinter.cpp index 917f7f5..0bd94d4 100644 --- a/lib/Target/Blackfin/AsmPrinter/BlackfinAsmPrinter.cpp +++ b/lib/Target/Blackfin/AsmPrinter/BlackfinAsmPrinter.cpp @@ -25,12 +25,14 @@ #include "llvm/CodeGen/MachineInstr.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCContext.h" #include "llvm/MC/MCSymbol.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetLoweringObjectFile.h" #include "llvm/Target/TargetRegistry.h" #include "llvm/Support/Mangler.h" #include "llvm/ADT/Statistic.h" +#include "llvm/ADT/SmallString.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FormattedStream.h" using namespace llvm; @@ -179,9 +181,12 @@ void BlackfinAsmPrinter::printOperand(const MachineInstr *MI, int opNum) { O << Mang->getMangledName(MO.getGlobal()); printOffset(MO.getOffset()); break; - case MachineOperand::MO_ExternalSymbol: - O << Mang->makeNameProper(MO.getSymbolName()); + case MachineOperand::MO_ExternalSymbol: { + SmallString<60> NameStr; + Mang->getNameWithPrefix(NameStr, MO.getSymbolName()); + OutContext.GetOrCreateSymbol(NameStr.str())->print(O, MAI); break; + } case MachineOperand::MO_ConstantPoolIndex: O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_" << MO.getIndex(); diff --git a/lib/Target/Blackfin/BlackfinISelDAGToDAG.cpp b/lib/Target/Blackfin/BlackfinISelDAGToDAG.cpp index 2217af4..e1b6008 100644 --- a/lib/Target/Blackfin/BlackfinISelDAGToDAG.cpp +++ b/lib/Target/Blackfin/BlackfinISelDAGToDAG.cpp @@ -51,8 +51,8 @@ namespace { #include "BlackfinGenDAGISel.inc" private: - SDNode *Select(SDValue Op); - bool SelectADDRspii(SDValue Op, SDValue Addr, + SDNode *Select(SDNode *N); + bool SelectADDRspii(SDNode *Op, SDValue Addr, SDValue &Base, SDValue &Offset); // Walk the DAG after instruction selection, fixing register class issues. @@ -82,8 +82,7 @@ void BlackfinDAGToDAGISel::InstructionSelect() { FixRegisterClasses(*CurDAG); } -SDNode *BlackfinDAGToDAGISel::Select(SDValue Op) { - SDNode *N = Op.getNode(); +SDNode *BlackfinDAGToDAGISel::Select(SDNode *N) { if (N->isMachineOpcode()) return NULL; // Already selected. @@ -99,10 +98,10 @@ SDNode *BlackfinDAGToDAGISel::Select(SDValue Op) { } } - return SelectCode(Op); + return SelectCode(N); } -bool BlackfinDAGToDAGISel::SelectADDRspii(SDValue Op, +bool BlackfinDAGToDAGISel::SelectADDRspii(SDNode *Op, SDValue Addr, SDValue &Base, SDValue &Offset) { diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp index 1ab3c0a..0fd975c 100644 --- a/lib/Target/CBackend/CBackend.cpp +++ b/lib/Target/CBackend/CBackend.cpp @@ -25,6 +25,7 @@ #include "llvm/IntrinsicInst.h" #include "llvm/InlineAsm.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/SmallString.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Analysis/ConstantsScanner.h" #include "llvm/Analysis/FindUsedTypes.h" @@ -34,6 +35,7 @@ #include "llvm/CodeGen/IntrinsicLowering.h" #include "llvm/Transforms/Scalar.h" #include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCSymbol.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetRegistry.h" #include "llvm/Support/CallSite.h" @@ -341,6 +343,15 @@ namespace { char CWriter::ID = 0; + +static std::string Mangle(const std::string &S) { + std::string Result; + raw_string_ostream OS(Result); + MCSymbol::printMangledName(S, OS, 0); + return OS.str(); +} + + /// This method inserts names for any unnamed structure types that are used by /// the program, and removes names from structure types that are not used by the /// program. @@ -1431,8 +1442,11 @@ void CWriter::printConstantWithCast(Constant* CPV, unsigned Opcode) { std::string CWriter::GetValueName(const Value *Operand) { // Mangle globals with the standard mangler interface for LLC compatibility. - if (const GlobalValue *GV = dyn_cast(Operand)) - return Mang->getMangledName(GV); + if (const GlobalValue *GV = dyn_cast(Operand)) { + SmallString<128> Str; + Mang->getNameWithPrefix(Str, GV, false); + return Mangle(Str.str().str()); + } std::string Name = Operand->getName(); @@ -1857,7 +1871,6 @@ bool CWriter::doInitialization(Module &M) { // Ensure that all structure types have names... Mang = new Mangler(M); - Mang->markCharUnacceptable('.'); // Keep track of which functions are static ctors/dtors so they can have // an attribute added to their prototypes. @@ -2210,7 +2223,7 @@ void CWriter::printModuleTypes(const TypeSymbolTable &TST) { // Print out forward declarations for structure types before anything else! Out << "/* Structure forward decls */\n"; for (; I != End; ++I) { - std::string Name = "struct l_" + Mang->makeNameProper(I->first); + std::string Name = "struct " + Mangle("l_"+I->first); Out << Name << ";\n"; TypeNames.insert(std::make_pair(I->second, Name)); } @@ -2221,7 +2234,7 @@ void CWriter::printModuleTypes(const TypeSymbolTable &TST) { // for struct or opaque types. Out << "/* Typedefs */\n"; for (I = TST.begin(); I != End; ++I) { - std::string Name = "l_" + Mang->makeNameProper(I->first); + std::string Name = Mangle("l_"+I->first); Out << "typedef "; printType(Out, I->second, false, Name); Out << ";\n"; @@ -2921,7 +2934,6 @@ void CWriter::lowerIntrinsics(Function &F) { case Intrinsic::setjmp: case Intrinsic::longjmp: case Intrinsic::prefetch: - case Intrinsic::dbg_stoppoint: case Intrinsic::powi: case Intrinsic::x86_sse_cmp_ss: case Intrinsic::x86_sse_cmp_ps: @@ -3178,20 +3190,6 @@ bool CWriter::visitBuiltinCall(CallInst &I, Intrinsic::ID ID, Out << "0; *((void**)&" << GetValueName(&I) << ") = __builtin_stack_save()"; return true; - case Intrinsic::dbg_stoppoint: { - // If we use writeOperand directly we get a "u" suffix which is rejected - // by gcc. - DbgStopPointInst &SPI = cast(I); - std::string dir; - GetConstantStringInfo(SPI.getDirectory(), dir); - std::string file; - GetConstantStringInfo(SPI.getFileName(), file); - Out << "\n#line " - << SPI.getLine() - << " \"" - << dir << '/' << file << "\"\n"; - return true; - } case Intrinsic::x86_sse_cmp_ss: case Intrinsic::x86_sse_cmp_ps: case Intrinsic::x86_sse2_cmp_sd: diff --git a/lib/Target/CellSPU/SPUISelDAGToDAG.cpp b/lib/Target/CellSPU/SPUISelDAGToDAG.cpp index c69a751..80693e1 100644 --- a/lib/Target/CellSPU/SPUISelDAGToDAG.cpp +++ b/lib/Target/CellSPU/SPUISelDAGToDAG.cpp @@ -277,10 +277,9 @@ namespace { return CurDAG->getTargetConstant(Imm, SPUtli.getPointerTy()); } - SDNode *emitBuildVector(SDValue build_vec) { - EVT vecVT = build_vec.getValueType(); + SDNode *emitBuildVector(SDNode *bvNode) { + EVT vecVT = bvNode->getValueType(0); EVT eltVT = vecVT.getVectorElementType(); - SDNode *bvNode = build_vec.getNode(); DebugLoc dl = bvNode->getDebugLoc(); // Check to see if this vector can be represented as a CellSPU immediate @@ -296,13 +295,13 @@ namespace { ((SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i64).getNode() != 0) || (SPU::get_ILHUvec_imm(bvNode, *CurDAG, MVT::i64).getNode() != 0) || (SPU::get_vec_u18imm(bvNode, *CurDAG, MVT::i64).getNode() != 0)))) - return Select(build_vec); + return Select(bvNode); // No, need to emit a constant pool spill: std::vector CV; - for (size_t i = 0; i < build_vec.getNumOperands(); ++i) { - ConstantSDNode *V = dyn_cast (build_vec.getOperand(i)); + for (size_t i = 0; i < bvNode->getNumOperands(); ++i) { + ConstantSDNode *V = dyn_cast (bvNode->getOperand(i)); CV.push_back(const_cast (V->getConstantIntValue())); } @@ -312,49 +311,49 @@ namespace { SDValue CGPoolOffset = SPU::LowerConstantPool(CPIdx, *CurDAG, SPUtli.getSPUTargetMachine()); - return SelectCode(CurDAG->getLoad(build_vec.getValueType(), dl, + return SelectCode(CurDAG->getLoad(vecVT, dl, CurDAG->getEntryNode(), CGPoolOffset, PseudoSourceValue::getConstantPool(), 0, - false, Alignment)); + false, Alignment).getNode()); } /// Select - Convert the specified operand from a target-independent to a /// target-specific node if it hasn't already been changed. - SDNode *Select(SDValue Op); + SDNode *Select(SDNode *N); //! Emit the instruction sequence for i64 shl - SDNode *SelectSHLi64(SDValue &Op, EVT OpVT); + SDNode *SelectSHLi64(SDNode *N, EVT OpVT); //! Emit the instruction sequence for i64 srl - SDNode *SelectSRLi64(SDValue &Op, EVT OpVT); + SDNode *SelectSRLi64(SDNode *N, EVT OpVT); //! Emit the instruction sequence for i64 sra - SDNode *SelectSRAi64(SDValue &Op, EVT OpVT); + SDNode *SelectSRAi64(SDNode *N, EVT OpVT); //! Emit the necessary sequence for loading i64 constants: - SDNode *SelectI64Constant(SDValue &Op, EVT OpVT, DebugLoc dl); + SDNode *SelectI64Constant(SDNode *N, EVT OpVT, DebugLoc dl); //! Alternate instruction emit sequence for loading i64 constants SDNode *SelectI64Constant(uint64_t i64const, EVT OpVT, DebugLoc dl); //! Returns true if the address N is an A-form (local store) address - bool SelectAFormAddr(SDValue Op, SDValue N, SDValue &Base, + bool SelectAFormAddr(SDNode *Op, SDValue N, SDValue &Base, SDValue &Index); //! D-form address predicate - bool SelectDFormAddr(SDValue Op, SDValue N, SDValue &Base, + bool SelectDFormAddr(SDNode *Op, SDValue N, SDValue &Base, SDValue &Index); /// Alternate D-form address using i7 offset predicate - bool SelectDForm2Addr(SDValue Op, SDValue N, SDValue &Disp, + bool SelectDForm2Addr(SDNode *Op, SDValue N, SDValue &Disp, SDValue &Base); /// D-form address selection workhorse - bool DFormAddressPredicate(SDValue Op, SDValue N, SDValue &Disp, + bool DFormAddressPredicate(SDNode *Op, SDValue N, SDValue &Disp, SDValue &Base, int minOffset, int maxOffset); //! Address predicate if N can be expressed as an indexed [r+r] operation. - bool SelectXFormAddr(SDValue Op, SDValue N, SDValue &Base, + bool SelectXFormAddr(SDNode *Op, SDValue N, SDValue &Base, SDValue &Index); /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for @@ -366,13 +365,13 @@ namespace { switch (ConstraintCode) { default: return true; case 'm': // memory - if (!SelectDFormAddr(Op, Op, Op0, Op1) - && !SelectAFormAddr(Op, Op, Op0, Op1)) - SelectXFormAddr(Op, Op, Op0, Op1); + if (!SelectDFormAddr(Op.getNode(), Op, Op0, Op1) + && !SelectAFormAddr(Op.getNode(), Op, Op0, Op1)) + SelectXFormAddr(Op.getNode(), Op, Op0, Op1); break; case 'o': // offsetable - if (!SelectDFormAddr(Op, Op, Op0, Op1) - && !SelectAFormAddr(Op, Op, Op0, Op1)) { + if (!SelectDFormAddr(Op.getNode(), Op, Op0, Op1) + && !SelectAFormAddr(Op.getNode(), Op, Op0, Op1)) { Op0 = Op; Op1 = getSmallIPtrImm(0); } @@ -429,7 +428,7 @@ SPUDAGToDAGISel::InstructionSelect() \arg Index The base address index */ bool -SPUDAGToDAGISel::SelectAFormAddr(SDValue Op, SDValue N, SDValue &Base, +SPUDAGToDAGISel::SelectAFormAddr(SDNode *Op, SDValue N, SDValue &Base, SDValue &Index) { // These match the addr256k operand type: EVT OffsVT = MVT::i16; @@ -479,7 +478,7 @@ SPUDAGToDAGISel::SelectAFormAddr(SDValue Op, SDValue N, SDValue &Base, } bool -SPUDAGToDAGISel::SelectDForm2Addr(SDValue Op, SDValue N, SDValue &Disp, +SPUDAGToDAGISel::SelectDForm2Addr(SDNode *Op, SDValue N, SDValue &Disp, SDValue &Base) { const int minDForm2Offset = -(1 << 7); const int maxDForm2Offset = (1 << 7) - 1; @@ -500,7 +499,7 @@ SPUDAGToDAGISel::SelectDForm2Addr(SDValue Op, SDValue N, SDValue &Disp, to non-empty SDValue instances. */ bool -SPUDAGToDAGISel::SelectDFormAddr(SDValue Op, SDValue N, SDValue &Base, +SPUDAGToDAGISel::SelectDFormAddr(SDNode *Op, SDValue N, SDValue &Base, SDValue &Index) { return DFormAddressPredicate(Op, N, Base, Index, SPUFrameInfo::minFrameOffset(), @@ -508,7 +507,7 @@ SPUDAGToDAGISel::SelectDFormAddr(SDValue Op, SDValue N, SDValue &Base, } bool -SPUDAGToDAGISel::DFormAddressPredicate(SDValue Op, SDValue N, SDValue &Base, +SPUDAGToDAGISel::DFormAddressPredicate(SDNode *Op, SDValue N, SDValue &Base, SDValue &Index, int minOffset, int maxOffset) { unsigned Opc = N.getOpcode(); @@ -618,7 +617,7 @@ SPUDAGToDAGISel::DFormAddressPredicate(SDValue Op, SDValue N, SDValue &Base, Index = N; return true; } else if (Opc == ISD::Register || Opc == ISD::CopyFromReg) { - unsigned OpOpc = Op.getOpcode(); + unsigned OpOpc = Op->getOpcode(); if (OpOpc == ISD::STORE || OpOpc == ISD::LOAD) { // Direct load/store without getelementptr @@ -630,7 +629,7 @@ SPUDAGToDAGISel::DFormAddressPredicate(SDValue Op, SDValue N, SDValue &Base, else Addr = N; // Register - Offs = ((OpOpc == ISD::STORE) ? Op.getOperand(3) : Op.getOperand(2)); + Offs = ((OpOpc == ISD::STORE) ? Op->getOperand(3) : Op->getOperand(2)); if (Offs.getOpcode() == ISD::Constant || Offs.getOpcode() == ISD::UNDEF) { if (Offs.getOpcode() == ISD::UNDEF) @@ -667,7 +666,7 @@ SPUDAGToDAGISel::DFormAddressPredicate(SDValue Op, SDValue N, SDValue &Base, (r)(r) X-form address. */ bool -SPUDAGToDAGISel::SelectXFormAddr(SDValue Op, SDValue N, SDValue &Base, +SPUDAGToDAGISel::SelectXFormAddr(SDNode *Op, SDValue N, SDValue &Base, SDValue &Index) { if (!SelectAFormAddr(Op, N, Base, Index) && !SelectDFormAddr(Op, N, Base, Index)) { @@ -685,12 +684,11 @@ SPUDAGToDAGISel::SelectXFormAddr(SDValue Op, SDValue N, SDValue &Base, /*! */ SDNode * -SPUDAGToDAGISel::Select(SDValue Op) { - SDNode *N = Op.getNode(); +SPUDAGToDAGISel::Select(SDNode *N) { unsigned Opc = N->getOpcode(); int n_ops = -1; unsigned NewOpc; - EVT OpVT = Op.getValueType(); + EVT OpVT = N->getValueType(0); SDValue Ops[8]; DebugLoc dl = N->getDebugLoc(); @@ -700,8 +698,8 @@ SPUDAGToDAGISel::Select(SDValue Op) { if (Opc == ISD::FrameIndex) { int FI = cast(N)->getIndex(); - SDValue TFI = CurDAG->getTargetFrameIndex(FI, Op.getValueType()); - SDValue Imm0 = CurDAG->getTargetConstant(0, Op.getValueType()); + SDValue TFI = CurDAG->getTargetFrameIndex(FI, N->getValueType(0)); + SDValue Imm0 = CurDAG->getTargetConstant(0, N->getValueType(0)); if (FI < 128) { NewOpc = SPU::AIr32; @@ -710,9 +708,9 @@ SPUDAGToDAGISel::Select(SDValue Op) { n_ops = 2; } else { NewOpc = SPU::Ar32; - Ops[0] = CurDAG->getRegister(SPU::R1, Op.getValueType()); + Ops[0] = CurDAG->getRegister(SPU::R1, N->getValueType(0)); Ops[1] = SDValue(CurDAG->getMachineNode(SPU::ILAr32, dl, - Op.getValueType(), TFI, Imm0), + N->getValueType(0), TFI, Imm0), 0); n_ops = 2; } @@ -720,10 +718,10 @@ SPUDAGToDAGISel::Select(SDValue Op) { // Catch the i64 constants that end up here. Note: The backend doesn't // attempt to legalize the constant (it's useless because DAGCombiner // will insert 64-bit constants and we can't stop it). - return SelectI64Constant(Op, OpVT, Op.getDebugLoc()); + return SelectI64Constant(N, OpVT, N->getDebugLoc()); } else if ((Opc == ISD::ZERO_EXTEND || Opc == ISD::ANY_EXTEND) && OpVT == MVT::i64) { - SDValue Op0 = Op.getOperand(0); + SDValue Op0 = N->getOperand(0); EVT Op0VT = Op0.getValueType(); EVT Op0VecVT = EVT::getVectorVT(*CurDAG->getContext(), Op0VT, (128 / Op0VT.getSizeInBits())); @@ -760,9 +758,10 @@ SPUDAGToDAGISel::Select(SDValue Op) { break; } - SDNode *shufMaskLoad = emitBuildVector(shufMask); + SDNode *shufMaskLoad = emitBuildVector(shufMask.getNode()); SDNode *PromoteScalar = - SelectCode(CurDAG->getNode(SPUISD::PREFSLOT2VEC, dl, Op0VecVT, Op0)); + SelectCode(CurDAG->getNode(SPUISD::PREFSLOT2VEC, dl, + Op0VecVT, Op0).getNode()); SDValue zextShuffle = CurDAG->getNode(SPUISD::SHUFB, dl, OpVecVT, @@ -773,32 +772,32 @@ SPUDAGToDAGISel::Select(SDValue Op) { // N.B.: BIT_CONVERT replaces and updates the zextShuffle node, so we // re-use it in the VEC2PREFSLOT selection without needing to explicitly // call SelectCode (it's already done for us.) - SelectCode(CurDAG->getNode(ISD::BIT_CONVERT, dl, OpVecVT, zextShuffle)); + SelectCode(CurDAG->getNode(ISD::BIT_CONVERT, dl, OpVecVT, zextShuffle).getNode()); return SelectCode(CurDAG->getNode(SPUISD::VEC2PREFSLOT, dl, OpVT, - zextShuffle)); + zextShuffle).getNode()); } else if (Opc == ISD::ADD && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) { SDNode *CGLoad = - emitBuildVector(getCarryGenerateShufMask(*CurDAG, dl)); + emitBuildVector(getCarryGenerateShufMask(*CurDAG, dl).getNode()); return SelectCode(CurDAG->getNode(SPUISD::ADD64_MARKER, dl, OpVT, - Op.getOperand(0), Op.getOperand(1), - SDValue(CGLoad, 0))); + N->getOperand(0), N->getOperand(1), + SDValue(CGLoad, 0)).getNode()); } else if (Opc == ISD::SUB && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) { SDNode *CGLoad = - emitBuildVector(getBorrowGenerateShufMask(*CurDAG, dl)); + emitBuildVector(getBorrowGenerateShufMask(*CurDAG, dl).getNode()); return SelectCode(CurDAG->getNode(SPUISD::SUB64_MARKER, dl, OpVT, - Op.getOperand(0), Op.getOperand(1), - SDValue(CGLoad, 0))); + N->getOperand(0), N->getOperand(1), + SDValue(CGLoad, 0)).getNode()); } else if (Opc == ISD::MUL && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) { SDNode *CGLoad = - emitBuildVector(getCarryGenerateShufMask(*CurDAG, dl)); + emitBuildVector(getCarryGenerateShufMask(*CurDAG, dl).getNode()); return SelectCode(CurDAG->getNode(SPUISD::MUL64_MARKER, dl, OpVT, - Op.getOperand(0), Op.getOperand(1), - SDValue(CGLoad, 0))); + N->getOperand(0), N->getOperand(1), + SDValue(CGLoad, 0)).getNode()); } else if (Opc == ISD::TRUNCATE) { - SDValue Op0 = Op.getOperand(0); + SDValue Op0 = N->getOperand(0); if ((Op0.getOpcode() == ISD::SRA || Op0.getOpcode() == ISD::SRL) && OpVT == MVT::i32 && Op0.getValueType() == MVT::i64) { @@ -834,22 +833,22 @@ SPUDAGToDAGISel::Select(SDValue Op) { } } else if (Opc == ISD::SHL) { if (OpVT == MVT::i64) { - return SelectSHLi64(Op, OpVT); + return SelectSHLi64(N, OpVT); } } else if (Opc == ISD::SRL) { if (OpVT == MVT::i64) { - return SelectSRLi64(Op, OpVT); + return SelectSRLi64(N, OpVT); } } else if (Opc == ISD::SRA) { if (OpVT == MVT::i64) { - return SelectSRAi64(Op, OpVT); + return SelectSRAi64(N, OpVT); } } else if (Opc == ISD::FNEG && (OpVT == MVT::f64 || OpVT == MVT::v2f64)) { - DebugLoc dl = Op.getDebugLoc(); + DebugLoc dl = N->getDebugLoc(); // Check if the pattern is a special form of DFNMS: // (fneg (fsub (fmul R64FP:$rA, R64FP:$rB), R64FP:$rC)) - SDValue Op0 = Op.getOperand(0); + SDValue Op0 = N->getOperand(0); if (Op0.getOpcode() == ISD::FSUB) { SDValue Op00 = Op0.getOperand(0); if (Op00.getOpcode() == ISD::FMUL) { @@ -869,28 +868,28 @@ SPUDAGToDAGISel::Select(SDValue Op) { unsigned Opc = SPU::XORfneg64; if (OpVT == MVT::f64) { - signMask = SelectI64Constant(negConst, MVT::i64, dl); + signMask = SelectI64Constant(negConst.getNode(), MVT::i64, dl); } else if (OpVT == MVT::v2f64) { Opc = SPU::XORfnegvec; signMask = emitBuildVector(CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v2i64, - negConst, negConst)); + negConst, negConst).getNode()); } return CurDAG->getMachineNode(Opc, dl, OpVT, - Op.getOperand(0), SDValue(signMask, 0)); + N->getOperand(0), SDValue(signMask, 0)); } else if (Opc == ISD::FABS) { if (OpVT == MVT::f64) { SDNode *signMask = SelectI64Constant(0x7fffffffffffffffULL, MVT::i64, dl); return CurDAG->getMachineNode(SPU::ANDfabs64, dl, OpVT, - Op.getOperand(0), SDValue(signMask, 0)); + N->getOperand(0), SDValue(signMask, 0)); } else if (OpVT == MVT::v2f64) { SDValue absConst = CurDAG->getConstant(0x7fffffffffffffffULL, MVT::i64); SDValue absVec = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v2i64, absConst, absConst); - SDNode *signMask = emitBuildVector(absVec); + SDNode *signMask = emitBuildVector(absVec.getNode()); return CurDAG->getMachineNode(SPU::ANDfabsvec, dl, OpVT, - Op.getOperand(0), SDValue(signMask, 0)); + N->getOperand(0), SDValue(signMask, 0)); } } else if (Opc == SPUISD::LDRESULT) { // Custom select instructions for LDRESULT @@ -925,7 +924,7 @@ SPUDAGToDAGISel::Select(SDValue Op) { // SPUInstrInfo catches the following patterns: // (SPUindirect (SPUhi ...), (SPUlo ...)) // (SPUindirect $sp, imm) - EVT VT = Op.getValueType(); + EVT VT = N->getValueType(0); SDValue Op0 = N->getOperand(0); SDValue Op1 = N->getOperand(1); RegisterSDNode *RN; @@ -952,7 +951,7 @@ SPUDAGToDAGISel::Select(SDValue Op) { else return CurDAG->getMachineNode(NewOpc, dl, OpVT, Ops, n_ops); } else - return SelectCode(Op); + return SelectCode(N); } /*! @@ -968,15 +967,15 @@ SPUDAGToDAGISel::Select(SDValue Op) { * @return The SDNode with the entire instruction sequence */ SDNode * -SPUDAGToDAGISel::SelectSHLi64(SDValue &Op, EVT OpVT) { - SDValue Op0 = Op.getOperand(0); +SPUDAGToDAGISel::SelectSHLi64(SDNode *N, EVT OpVT) { + SDValue Op0 = N->getOperand(0); EVT VecVT = EVT::getVectorVT(*CurDAG->getContext(), OpVT, (128 / OpVT.getSizeInBits())); - SDValue ShiftAmt = Op.getOperand(1); + SDValue ShiftAmt = N->getOperand(1); EVT ShiftAmtVT = ShiftAmt.getValueType(); SDNode *VecOp0, *SelMask, *ZeroFill, *Shift = 0; SDValue SelMaskVal; - DebugLoc dl = Op.getDebugLoc(); + DebugLoc dl = N->getDebugLoc(); VecOp0 = CurDAG->getMachineNode(SPU::ORv2i64_i64, dl, VecVT, Op0); SelMaskVal = CurDAG->getTargetConstant(0xff00ULL, MVT::i16); @@ -1034,14 +1033,14 @@ SPUDAGToDAGISel::SelectSHLi64(SDValue &Op, EVT OpVT) { * @return The SDNode with the entire instruction sequence */ SDNode * -SPUDAGToDAGISel::SelectSRLi64(SDValue &Op, EVT OpVT) { - SDValue Op0 = Op.getOperand(0); +SPUDAGToDAGISel::SelectSRLi64(SDNode *N, EVT OpVT) { + SDValue Op0 = N->getOperand(0); EVT VecVT = EVT::getVectorVT(*CurDAG->getContext(), OpVT, (128 / OpVT.getSizeInBits())); - SDValue ShiftAmt = Op.getOperand(1); + SDValue ShiftAmt = N->getOperand(1); EVT ShiftAmtVT = ShiftAmt.getValueType(); SDNode *VecOp0, *Shift = 0; - DebugLoc dl = Op.getDebugLoc(); + DebugLoc dl = N->getDebugLoc(); VecOp0 = CurDAG->getMachineNode(SPU::ORv2i64_i64, dl, VecVT, Op0); @@ -1101,16 +1100,16 @@ SPUDAGToDAGISel::SelectSRLi64(SDValue &Op, EVT OpVT) { * @return The SDNode with the entire instruction sequence */ SDNode * -SPUDAGToDAGISel::SelectSRAi64(SDValue &Op, EVT OpVT) { +SPUDAGToDAGISel::SelectSRAi64(SDNode *N, EVT OpVT) { // Promote Op0 to vector EVT VecVT = EVT::getVectorVT(*CurDAG->getContext(), OpVT, (128 / OpVT.getSizeInBits())); - SDValue ShiftAmt = Op.getOperand(1); + SDValue ShiftAmt = N->getOperand(1); EVT ShiftAmtVT = ShiftAmt.getValueType(); - DebugLoc dl = Op.getDebugLoc(); + DebugLoc dl = N->getDebugLoc(); SDNode *VecOp0 = - CurDAG->getMachineNode(SPU::ORv2i64_i64, dl, VecVT, Op.getOperand(0)); + CurDAG->getMachineNode(SPU::ORv2i64_i64, dl, VecVT, N->getOperand(0)); SDValue SignRotAmt = CurDAG->getTargetConstant(31, ShiftAmtVT); SDNode *SignRot = @@ -1170,9 +1169,9 @@ SPUDAGToDAGISel::SelectSRAi64(SDValue &Op, EVT OpVT) { /*! Do the necessary magic necessary to load a i64 constant */ -SDNode *SPUDAGToDAGISel::SelectI64Constant(SDValue& Op, EVT OpVT, +SDNode *SPUDAGToDAGISel::SelectI64Constant(SDNode *N, EVT OpVT, DebugLoc dl) { - ConstantSDNode *CN = cast(Op.getNode()); + ConstantSDNode *CN = cast(N); return SelectI64Constant(CN->getZExtValue(), OpVT, dl); } @@ -1192,7 +1191,7 @@ SDNode *SPUDAGToDAGISel::SelectI64Constant(uint64_t Value64, EVT OpVT, ReplaceUses(i64vec, Op0); return CurDAG->getMachineNode(SPU::ORi64_v2i64, dl, OpVT, - SDValue(emitBuildVector(Op0), 0)); + SDValue(emitBuildVector(Op0.getNode()), 0)); } else if (i64vec.getOpcode() == SPUISD::SHUFB) { SDValue lhs = i64vec.getOperand(0); SDValue rhs = i64vec.getOperand(1); @@ -1205,7 +1204,7 @@ SDNode *SPUDAGToDAGISel::SelectI64Constant(uint64_t Value64, EVT OpVT, SDNode *lhsNode = (lhs.getNode()->isMachineOpcode() ? lhs.getNode() - : emitBuildVector(lhs)); + : emitBuildVector(lhs.getNode())); if (rhs.getOpcode() == ISD::BIT_CONVERT) { ReplaceUses(rhs, rhs.getOperand(0)); @@ -1214,7 +1213,7 @@ SDNode *SPUDAGToDAGISel::SelectI64Constant(uint64_t Value64, EVT OpVT, SDNode *rhsNode = (rhs.getNode()->isMachineOpcode() ? rhs.getNode() - : emitBuildVector(rhs)); + : emitBuildVector(rhs.getNode())); if (shufmask.getOpcode() == ISD::BIT_CONVERT) { ReplaceUses(shufmask, shufmask.getOperand(0)); @@ -1223,18 +1222,18 @@ SDNode *SPUDAGToDAGISel::SelectI64Constant(uint64_t Value64, EVT OpVT, SDNode *shufMaskNode = (shufmask.getNode()->isMachineOpcode() ? shufmask.getNode() - : emitBuildVector(shufmask)); + : emitBuildVector(shufmask.getNode())); SDNode *shufNode = Select(CurDAG->getNode(SPUISD::SHUFB, dl, OpVecVT, SDValue(lhsNode, 0), SDValue(rhsNode, 0), - SDValue(shufMaskNode, 0))); + SDValue(shufMaskNode, 0)).getNode()); return CurDAG->getMachineNode(SPU::ORi64_v2i64, dl, OpVT, SDValue(shufNode, 0)); } else if (i64vec.getOpcode() == ISD::BUILD_VECTOR) { return CurDAG->getMachineNode(SPU::ORi64_v2i64, dl, OpVT, - SDValue(emitBuildVector(i64vec), 0)); + SDValue(emitBuildVector(i64vec.getNode()), 0)); } else { llvm_report_error("SPUDAGToDAGISel::SelectI64Constant: Unhandled i64vec" "condition"); diff --git a/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp b/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp index 4d40769..4eec757 100644 --- a/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp +++ b/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp @@ -146,12 +146,12 @@ namespace { private: DenseMap RMWStores; void PreprocessForRMW(); - SDNode *Select(SDValue Op); - SDNode *SelectIndexedLoad(SDValue Op); - SDNode *SelectIndexedBinOp(SDValue Op, SDValue N1, SDValue N2, + SDNode *Select(SDNode *N); + SDNode *SelectIndexedLoad(SDNode *Op); + SDNode *SelectIndexedBinOp(SDNode *Op, SDValue N1, SDValue N2, unsigned Opc8, unsigned Opc16); - bool SelectAddr(SDValue Op, SDValue Addr, SDValue &Base, SDValue &Disp); + bool SelectAddr(SDNode *Op, SDValue Addr, SDValue &Base, SDValue &Disp); #ifndef NDEBUG unsigned Indent; @@ -283,7 +283,7 @@ bool MSP430DAGToDAGISel::MatchAddress(SDValue N, MSP430ISelAddressMode &AM) { /// SelectAddr - returns true if it is able pattern match an addressing mode. /// It returns the operands which make up the maximal addressing mode it can /// match by reference. -bool MSP430DAGToDAGISel::SelectAddr(SDValue Op, SDValue N, +bool MSP430DAGToDAGISel::SelectAddr(SDNode *Op, SDValue N, SDValue &Base, SDValue &Disp) { MSP430ISelAddressMode AM; @@ -326,7 +326,7 @@ SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode, switch (ConstraintCode) { default: return true; case 'm': // memory - if (!SelectAddr(Op, Op, Op0, Op1)) + if (!SelectAddr(Op.getNode(), Op, Op0, Op1)) return true; break; } @@ -627,8 +627,8 @@ static bool isValidIndexedLoad(const LoadSDNode *LD) { return true; } -SDNode *MSP430DAGToDAGISel::SelectIndexedLoad(SDValue Op) { - LoadSDNode *LD = cast(Op); +SDNode *MSP430DAGToDAGISel::SelectIndexedLoad(SDNode *N) { + LoadSDNode *LD = cast(N); if (!isValidIndexedLoad(LD)) return NULL; @@ -646,17 +646,17 @@ SDNode *MSP430DAGToDAGISel::SelectIndexedLoad(SDValue Op) { return NULL; } - return CurDAG->getMachineNode(Opcode, Op.getDebugLoc(), + return CurDAG->getMachineNode(Opcode, N->getDebugLoc(), VT, MVT::i16, MVT::Other, LD->getBasePtr(), LD->getChain()); } -SDNode *MSP430DAGToDAGISel::SelectIndexedBinOp(SDValue Op, +SDNode *MSP430DAGToDAGISel::SelectIndexedBinOp(SDNode *Op, SDValue N1, SDValue N2, unsigned Opc8, unsigned Opc16) { if (N1.getOpcode() == ISD::LOAD && N1.hasOneUse() && - IsLegalAndProfitableToFold(N1.getNode(), Op.getNode(), Op.getNode())) { + IsLegalAndProfitableToFold(N1.getNode(), Op, Op)) { LoadSDNode *LD = cast(N1); if (!isValidIndexedLoad(LD)) return NULL; @@ -667,7 +667,7 @@ SDNode *MSP430DAGToDAGISel::SelectIndexedBinOp(SDValue Op, MemRefs0[0] = cast(N1)->getMemOperand(); SDValue Ops0[] = { N2, LD->getBasePtr(), LD->getChain() }; SDNode *ResNode = - CurDAG->SelectNodeTo(Op.getNode(), Opc, + CurDAG->SelectNodeTo(Op, Opc, VT, MVT::i16, MVT::Other, Ops0, 3); cast(ResNode)->setMemRefs(MemRefs0, MemRefs0 + 1); @@ -707,9 +707,8 @@ void MSP430DAGToDAGISel::InstructionSelect() { RMWStores.clear(); } -SDNode *MSP430DAGToDAGISel::Select(SDValue Op) { - SDNode *Node = Op.getNode(); - DebugLoc dl = Op.getDebugLoc(); +SDNode *MSP430DAGToDAGISel::Select(SDNode *Node) { + DebugLoc dl = Node->getDebugLoc(); // Dump information about the Node being selected DEBUG(errs().indent(Indent) << "Selecting: "); @@ -730,7 +729,7 @@ SDNode *MSP430DAGToDAGISel::Select(SDValue Op) { switch (Node->getOpcode()) { default: break; case ISD::FrameIndex: { - assert(Op.getValueType() == MVT::i16); + assert(Node->getValueType(0) == MVT::i16); int FI = cast(Node)->getIndex(); SDValue TFI = CurDAG->getTargetFrameIndex(FI, MVT::i16); if (Node->hasOneUse()) @@ -740,18 +739,18 @@ SDNode *MSP430DAGToDAGISel::Select(SDValue Op) { TFI, CurDAG->getTargetConstant(0, MVT::i16)); } case ISD::LOAD: - if (SDNode *ResNode = SelectIndexedLoad(Op)) + if (SDNode *ResNode = SelectIndexedLoad(Node)) return ResNode; // Other cases are autogenerated. break; case ISD::ADD: if (SDNode *ResNode = - SelectIndexedBinOp(Op, - Op.getOperand(0), Op.getOperand(1), + SelectIndexedBinOp(Node, + Node->getOperand(0), Node->getOperand(1), MSP430::ADD8rm_POST, MSP430::ADD16rm_POST)) return ResNode; else if (SDNode *ResNode = - SelectIndexedBinOp(Op, Op.getOperand(1), Op.getOperand(0), + SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0), MSP430::ADD8rm_POST, MSP430::ADD16rm_POST)) return ResNode; @@ -759,8 +758,8 @@ SDNode *MSP430DAGToDAGISel::Select(SDValue Op) { break; case ISD::SUB: if (SDNode *ResNode = - SelectIndexedBinOp(Op, - Op.getOperand(0), Op.getOperand(1), + SelectIndexedBinOp(Node, + Node->getOperand(0), Node->getOperand(1), MSP430::SUB8rm_POST, MSP430::SUB16rm_POST)) return ResNode; @@ -768,12 +767,12 @@ SDNode *MSP430DAGToDAGISel::Select(SDValue Op) { break; case ISD::AND: if (SDNode *ResNode = - SelectIndexedBinOp(Op, - Op.getOperand(0), Op.getOperand(1), + SelectIndexedBinOp(Node, + Node->getOperand(0), Node->getOperand(1), MSP430::AND8rm_POST, MSP430::AND16rm_POST)) return ResNode; else if (SDNode *ResNode = - SelectIndexedBinOp(Op, Op.getOperand(1), Op.getOperand(0), + SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0), MSP430::AND8rm_POST, MSP430::AND16rm_POST)) return ResNode; @@ -781,12 +780,12 @@ SDNode *MSP430DAGToDAGISel::Select(SDValue Op) { break; case ISD::OR: if (SDNode *ResNode = - SelectIndexedBinOp(Op, - Op.getOperand(0), Op.getOperand(1), + SelectIndexedBinOp(Node, + Node->getOperand(0), Node->getOperand(1), MSP430::OR8rm_POST, MSP430::OR16rm_POST)) return ResNode; else if (SDNode *ResNode = - SelectIndexedBinOp(Op, Op.getOperand(1), Op.getOperand(0), + SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0), MSP430::OR8rm_POST, MSP430::OR16rm_POST)) return ResNode; @@ -794,12 +793,12 @@ SDNode *MSP430DAGToDAGISel::Select(SDValue Op) { break; case ISD::XOR: if (SDNode *ResNode = - SelectIndexedBinOp(Op, - Op.getOperand(0), Op.getOperand(1), + SelectIndexedBinOp(Node, + Node->getOperand(0), Node->getOperand(1), MSP430::XOR8rm_POST, MSP430::XOR16rm_POST)) return ResNode; else if (SDNode *ResNode = - SelectIndexedBinOp(Op, Op.getOperand(1), Op.getOperand(0), + SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0), MSP430::XOR8rm_POST, MSP430::XOR16rm_POST)) return ResNode; @@ -808,11 +807,11 @@ SDNode *MSP430DAGToDAGISel::Select(SDValue Op) { } // Select the default instruction - SDNode *ResNode = SelectCode(Op); + SDNode *ResNode = SelectCode(Node); DEBUG(errs() << std::string(Indent-2, ' ') << "=> "); - if (ResNode == NULL || ResNode == Op.getNode()) - DEBUG(Op.getNode()->dump(CurDAG)); + if (ResNode == NULL || ResNode == Node) + DEBUG(Node->dump(CurDAG)); else DEBUG(ResNode->dump(CurDAG)); DEBUG(errs() << "\n"); diff --git a/lib/Target/MSP430/MSP430ISelLowering.cpp b/lib/Target/MSP430/MSP430ISelLowering.cpp index 5fe9b20..d3dce4b 100644 --- a/lib/Target/MSP430/MSP430ISelLowering.cpp +++ b/lib/Target/MSP430/MSP430ISelLowering.cpp @@ -660,16 +660,16 @@ static SDValue EmitCMP(SDValue &LHS, SDValue &RHS, SDValue &TargetCC, default: llvm_unreachable("Invalid integer condition!"); case ISD::SETEQ: TCC = MSP430CC::COND_E; // aka COND_Z - // Minor optimization: if RHS is a constant, swap operands, then the + // Minor optimization: if LHS is a constant, swap operands, then the // constant can be folded into comparison. - if (RHS.getOpcode() == ISD::Constant) + if (LHS.getOpcode() == ISD::Constant) std::swap(LHS, RHS); break; case ISD::SETNE: TCC = MSP430CC::COND_NE; // aka COND_NZ - // Minor optimization: if RHS is a constant, swap operands, then the + // Minor optimization: if LHS is a constant, swap operands, then the // constant can be folded into comparison. - if (RHS.getOpcode() == ISD::Constant) + if (LHS.getOpcode() == ISD::Constant) std::swap(LHS, RHS); break; case ISD::SETULE: @@ -1014,8 +1014,8 @@ MSP430TargetLowering::EmitShiftInstr(MachineInstr *MI, // BB: // cmp 0, N // je RemBB - BuildMI(BB, dl, TII.get(MSP430::CMP8ir)) - .addImm(0).addReg(ShiftAmtSrcReg); + BuildMI(BB, dl, TII.get(MSP430::CMP8ri)) + .addReg(ShiftAmtSrcReg).addImm(0); BuildMI(BB, dl, TII.get(MSP430::JCC)) .addMBB(RemBB) .addImm(MSP430CC::COND_E); @@ -1045,6 +1045,7 @@ MSP430TargetLowering::EmitShiftInstr(MachineInstr *MI, .addReg(SrcReg).addMBB(BB) .addReg(ShiftReg2).addMBB(LoopBB); + F->DeleteMachineInstr(MI); // The pseudo instruction is gone now. return RemBB; } diff --git a/lib/Target/MSP430/MSP430InstrInfo.td b/lib/Target/MSP430/MSP430InstrInfo.td index d67ba90..022d171 100644 --- a/lib/Target/MSP430/MSP430InstrInfo.td +++ b/lib/Target/MSP430/MSP430InstrInfo.td @@ -819,38 +819,40 @@ def SWPB16r : Pseudo<(outs GR16:$dst), (ins GR16:$src), // Integer comparisons let Defs = [SRW] in { def CMP8rr : Pseudo<(outs), (ins GR8:$src1, GR8:$src2), - "cmp.b\t{$src1, $src2}", + "cmp.b\t{$src2, $src1}", [(MSP430cmp GR8:$src1, GR8:$src2), (implicit SRW)]>; def CMP16rr : Pseudo<(outs), (ins GR16:$src1, GR16:$src2), - "cmp.w\t{$src1, $src2}", + "cmp.w\t{$src2, $src1}", [(MSP430cmp GR16:$src1, GR16:$src2), (implicit SRW)]>; -def CMP8ir : Pseudo<(outs), (ins i8imm:$src1, GR8:$src2), - "cmp.b\t{$src1, $src2}", - [(MSP430cmp imm:$src1, GR8:$src2), (implicit SRW)]>; -def CMP16ir : Pseudo<(outs), (ins i16imm:$src1, GR16:$src2), - "cmp.w\t{$src1, $src2}", - [(MSP430cmp imm:$src1, GR16:$src2), (implicit SRW)]>; - -def CMP8im : Pseudo<(outs), (ins i8imm:$src1, memsrc:$src2), - "cmp.b\t{$src1, $src2}", - [(MSP430cmp (i8 imm:$src1), (load addr:$src2)), (implicit SRW)]>; -def CMP16im : Pseudo<(outs), (ins i16imm:$src1, memsrc:$src2), - "cmp.w\t{$src1, $src2}", - [(MSP430cmp (i16 imm:$src1), (load addr:$src2)), (implicit SRW)]>; +def CMP8ri : Pseudo<(outs), (ins GR8:$src1, i8imm:$src2), + "cmp.b\t{$src2, $src1}", + [(MSP430cmp GR8:$src1, imm:$src2), (implicit SRW)]>; +def CMP16ri : Pseudo<(outs), (ins GR16:$src1, i16imm:$src2), + "cmp.w\t{$src2, $src1}", + [(MSP430cmp GR16:$src1, imm:$src2), (implicit SRW)]>; + +def CMP8mi : Pseudo<(outs), (ins memsrc:$src1, i8imm:$src2), + "cmp.b\t{$src2, $src1}", + [(MSP430cmp (load addr:$src1), + (i8 imm:$src2)), (implicit SRW)]>; +def CMP16mi : Pseudo<(outs), (ins memsrc:$src1, i16imm:$src2), + "cmp.w\t{$src2, $src1}", + [(MSP430cmp (load addr:$src1), + (i16 imm:$src2)), (implicit SRW)]>; def CMP8rm : Pseudo<(outs), (ins GR8:$src1, memsrc:$src2), - "cmp.b\t{$src1, $src2}", + "cmp.b\t{$src2, $src1}", [(MSP430cmp GR8:$src1, (load addr:$src2)), (implicit SRW)]>; def CMP16rm : Pseudo<(outs), (ins GR16:$src1, memsrc:$src2), - "cmp.w\t{$src1, $src2}", + "cmp.w\t{$src2, $src1}", [(MSP430cmp GR16:$src1, (load addr:$src2)), (implicit SRW)]>; def CMP8mr : Pseudo<(outs), (ins memsrc:$src1, GR8:$src2), - "cmp.b\t{$src1, $src2}", + "cmp.b\t{$src2, $src1}", [(MSP430cmp (load addr:$src1), GR8:$src2), (implicit SRW)]>; def CMP16mr : Pseudo<(outs), (ins memsrc:$src1, GR16:$src2), - "cmp.w\t{$src1, $src2}", + "cmp.w\t{$src2, $src1}", [(MSP430cmp (load addr:$src1), GR16:$src2), (implicit SRW)]>; diff --git a/lib/Target/Mips/MipsISelDAGToDAG.cpp b/lib/Target/Mips/MipsISelDAGToDAG.cpp index ede111d..a53e918 100644 --- a/lib/Target/Mips/MipsISelDAGToDAG.cpp +++ b/lib/Target/Mips/MipsISelDAGToDAG.cpp @@ -84,14 +84,14 @@ private: } SDNode *getGlobalBaseReg(); - SDNode *Select(SDValue N); + SDNode *Select(SDNode *N); // Complex Pattern. - bool SelectAddr(SDValue Op, SDValue N, + bool SelectAddr(SDNode *Op, SDValue N, SDValue &Base, SDValue &Offset); - SDNode *SelectLoadFp64(SDValue N); - SDNode *SelectStoreFp64(SDValue N); + SDNode *SelectLoadFp64(SDNode *N); + SDNode *SelectStoreFp64(SDNode *N); // getI32Imm - Return a target constant with the specified // value, of type i32. @@ -132,7 +132,7 @@ SDNode *MipsDAGToDAGISel::getGlobalBaseReg() { /// ComplexPattern used on MipsInstrInfo /// Used on Mips Load/Store instructions bool MipsDAGToDAGISel:: -SelectAddr(SDValue Op, SDValue Addr, SDValue &Offset, SDValue &Base) +SelectAddr(SDNode *Op, SDValue Addr, SDValue &Offset, SDValue &Base) { // if Address is FI, get the TargetFrameIndex. if (FrameIndexSDNode *FIN = dyn_cast(Addr)) { @@ -199,19 +199,19 @@ SelectAddr(SDValue Op, SDValue Addr, SDValue &Offset, SDValue &Base) return true; } -SDNode *MipsDAGToDAGISel::SelectLoadFp64(SDValue N) { +SDNode *MipsDAGToDAGISel::SelectLoadFp64(SDNode *N) { MVT::SimpleValueType NVT = - N.getNode()->getValueType(0).getSimpleVT().SimpleTy; + N->getValueType(0).getSimpleVT().SimpleTy; if (!Subtarget.isMips1() || NVT != MVT::f64) return NULL; - if (!Predicate_unindexedload(N.getNode()) || - !Predicate_load(N.getNode())) + if (!Predicate_unindexedload(N) || + !Predicate_load(N)) return NULL; - SDValue Chain = N.getOperand(0); - SDValue N1 = N.getOperand(1); + SDValue Chain = N->getOperand(0); + SDValue N1 = N->getOperand(1); SDValue Offset0, Offset1, Base; if (!SelectAddr(N, N1, Offset0, Base) || @@ -220,7 +220,7 @@ SDNode *MipsDAGToDAGISel::SelectLoadFp64(SDValue N) { MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1); MemRefs0[0] = cast(N)->getMemOperand(); - DebugLoc dl = N.getDebugLoc(); + DebugLoc dl = N->getDebugLoc(); // The second load should start after for 4 bytes. if (ConstantSDNode *C = dyn_cast(Offset0)) @@ -255,27 +255,27 @@ SDNode *MipsDAGToDAGISel::SelectLoadFp64(SDValue N) { SDValue I1 = CurDAG->getTargetInsertSubreg(Mips::SUBREG_FPODD, dl, MVT::f64, I0, SDValue(LD1, 0)); - ReplaceUses(N, I1); - ReplaceUses(N.getValue(1), Chain); + ReplaceUses(SDValue(N, 0), I1); + ReplaceUses(SDValue(N, 1), Chain); cast(LD0)->setMemRefs(MemRefs0, MemRefs0 + 1); cast(LD1)->setMemRefs(MemRefs0, MemRefs0 + 1); return I1.getNode(); } -SDNode *MipsDAGToDAGISel::SelectStoreFp64(SDValue N) { +SDNode *MipsDAGToDAGISel::SelectStoreFp64(SDNode *N) { if (!Subtarget.isMips1() || - N.getOperand(1).getValueType() != MVT::f64) + N->getOperand(1).getValueType() != MVT::f64) return NULL; - SDValue Chain = N.getOperand(0); + SDValue Chain = N->getOperand(0); - if (!Predicate_unindexedstore(N.getNode()) || - !Predicate_store(N.getNode())) + if (!Predicate_unindexedstore(N) || + !Predicate_store(N)) return NULL; - SDValue N1 = N.getOperand(1); - SDValue N2 = N.getOperand(2); + SDValue N1 = N->getOperand(1); + SDValue N2 = N->getOperand(2); SDValue Offset0, Offset1, Base; if (!SelectAddr(N, N2, Offset0, Base) || @@ -285,7 +285,7 @@ SDNode *MipsDAGToDAGISel::SelectStoreFp64(SDValue N) { MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1); MemRefs0[0] = cast(N)->getMemOperand(); - DebugLoc dl = N.getDebugLoc(); + DebugLoc dl = N->getDebugLoc(); // Get the even and odd part from the f64 register SDValue FPOdd = CurDAG->getTargetExtractSubreg(Mips::SUBREG_FPODD, @@ -318,14 +318,13 @@ SDNode *MipsDAGToDAGISel::SelectStoreFp64(SDValue N) { MVT::Other, Ops1, 4), 0); cast(Chain.getNode())->setMemRefs(MemRefs0, MemRefs0 + 1); - ReplaceUses(N.getValue(0), Chain); + ReplaceUses(SDValue(N, 0), Chain); return Chain.getNode(); } /// Select instructions not customized! Used for /// expanded, promoted and normal instructions -SDNode* MipsDAGToDAGISel::Select(SDValue N) { - SDNode *Node = N.getNode(); +SDNode* MipsDAGToDAGISel::Select(SDNode *Node) { unsigned Opcode = Node->getOpcode(); DebugLoc dl = Node->getDebugLoc(); @@ -379,7 +378,7 @@ SDNode* MipsDAGToDAGISel::Select(SDValue N) { SDNode *AddCarry = CurDAG->getMachineNode(Mips::ADDu, dl, VT, SDValue(Carry,0), RHS); - return CurDAG->SelectNodeTo(N.getNode(), MOp, VT, MVT::Flag, + return CurDAG->SelectNodeTo(Node, MOp, VT, MVT::Flag, LHS, SDValue(AddCarry,0)); } @@ -405,11 +404,11 @@ SDNode* MipsDAGToDAGISel::Select(SDValue N) { InFlag = SDValue(Lo,1); SDNode *Hi = CurDAG->getMachineNode(Mips::MFHI, dl, MVT::i32, InFlag); - if (!N.getValue(0).use_empty()) - ReplaceUses(N.getValue(0), SDValue(Lo,0)); + if (!SDValue(Node, 0).use_empty()) + ReplaceUses(SDValue(Node, 0), SDValue(Lo,0)); - if (!N.getValue(1).use_empty()) - ReplaceUses(N.getValue(1), SDValue(Hi,0)); + if (!SDValue(Node, 1).use_empty()) + ReplaceUses(SDValue(Node, 1), SDValue(Hi,0)); return NULL; } @@ -460,23 +459,23 @@ SDNode* MipsDAGToDAGISel::Select(SDValue N) { return getGlobalBaseReg(); case ISD::ConstantFP: { - ConstantFPSDNode *CN = dyn_cast(N); - if (N.getValueType() == MVT::f64 && CN->isExactlyValue(+0.0)) { + ConstantFPSDNode *CN = dyn_cast(Node); + if (Node->getValueType(0) == MVT::f64 && CN->isExactlyValue(+0.0)) { SDValue Zero = CurDAG->getRegister(Mips::ZERO, MVT::i32); - ReplaceUses(N, Zero); + ReplaceUses(SDValue(Node, 0), Zero); return Zero.getNode(); } break; } case ISD::LOAD: - if (SDNode *ResNode = SelectLoadFp64(N)) + if (SDNode *ResNode = SelectLoadFp64(Node)) return ResNode; // Other cases are autogenerated. break; case ISD::STORE: - if (SDNode *ResNode = SelectStoreFp64(N)) + if (SDNode *ResNode = SelectStoreFp64(Node)) return ResNode; // Other cases are autogenerated. break; @@ -523,11 +522,11 @@ SDNode* MipsDAGToDAGISel::Select(SDValue N) { } // Select the default instruction - SDNode *ResNode = SelectCode(N); + SDNode *ResNode = SelectCode(Node); DEBUG(errs().indent(Indent-2) << "=> "); - if (ResNode == NULL || ResNode == N.getNode()) - DEBUG(N.getNode()->dump(CurDAG)); + if (ResNode == NULL || ResNode == Node) + DEBUG(Node->dump(CurDAG)); else DEBUG(ResNode->dump(CurDAG)); DEBUG(errs() << "\n"); diff --git a/lib/Target/PIC16/PIC16ISelDAGToDAG.cpp b/lib/Target/PIC16/PIC16ISelDAGToDAG.cpp index e13e6cd..82197ae 100644 --- a/lib/Target/PIC16/PIC16ISelDAGToDAG.cpp +++ b/lib/Target/PIC16/PIC16ISelDAGToDAG.cpp @@ -36,7 +36,7 @@ void PIC16DAGToDAGISel::InstructionSelect() { /// Select - Select instructions not customized! Used for /// expanded, promoted and normal instructions. -SDNode* PIC16DAGToDAGISel::Select(SDValue N) { +SDNode* PIC16DAGToDAGISel::Select(SDNode *N) { // Select the default instruction. SDNode *ResNode = SelectCode(N); @@ -47,7 +47,7 @@ SDNode* PIC16DAGToDAGISel::Select(SDValue N) { // SelectDirectAddr - Match a direct address for DAG. // A direct address could be a globaladdress or externalsymbol. -bool PIC16DAGToDAGISel::SelectDirectAddr(SDValue Op, SDValue N, +bool PIC16DAGToDAGISel::SelectDirectAddr(SDNode *Op, SDValue N, SDValue &Address) { // Return true if TGA or ES. if (N.getOpcode() == ISD::TargetGlobalAddress diff --git a/lib/Target/PIC16/PIC16ISelDAGToDAG.h b/lib/Target/PIC16/PIC16ISelDAGToDAG.h index d9172f2..813a540 100644 --- a/lib/Target/PIC16/PIC16ISelDAGToDAG.h +++ b/lib/Target/PIC16/PIC16ISelDAGToDAG.h @@ -52,10 +52,10 @@ private: // Include the pieces autogenerated from the target description. #include "PIC16GenDAGISel.inc" - SDNode *Select(SDValue N); + SDNode *Select(SDNode *N); // Match direct address complex pattern. - bool SelectDirectAddr(SDValue Op, SDValue N, SDValue &Address); + bool SelectDirectAddr(SDNode *Op, SDValue N, SDValue &Address); }; diff --git a/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp b/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp index aae4607..d505d38 100644 --- a/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp +++ b/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp @@ -32,6 +32,7 @@ #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCContext.h" #include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" @@ -49,6 +50,7 @@ #include "llvm/ADT/Statistic.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSet.h" +#include "llvm/ADT/SmallString.h" using namespace llvm; STATISTIC(EmittedInsts, "Number of machine instrs printed"); @@ -57,27 +59,42 @@ namespace { class PPCAsmPrinter : public AsmPrinter { protected: struct FnStubInfo { - std::string Stub, LazyPtr, AnonSymbol; + MCSymbol *Stub, *LazyPtr, *AnonSymbol; - FnStubInfo() {} + FnStubInfo() { + Stub = LazyPtr = AnonSymbol = 0; + } - void Init(const GlobalValue *GV, Mangler *Mang) { + void Init(const GlobalValue *GV, Mangler *Mang, MCContext &Ctx) { // Already initialized. - if (!Stub.empty()) return; - Stub = Mang->getMangledName(GV, "$stub", true); - LazyPtr = Mang->getMangledName(GV, "$lazy_ptr", true); - AnonSymbol = Mang->getMangledName(GV, "$stub$tmp", true); + if (Stub != 0) return; + + // Get the names. + SmallString<128> TmpStr; + Mang->getNameWithPrefix(TmpStr, GV, true); + MakeSymbols(TmpStr, Ctx); } - void Init(const std::string &GV, Mangler *Mang) { - // Already initialized. - if (!Stub.empty()) return; - Stub = Mang->makeNameProper(GV + "$stub", - Mangler::Private); - LazyPtr = Mang->makeNameProper(GV + "$lazy_ptr", - Mangler::Private); - AnonSymbol = Mang->makeNameProper(GV + "$stub$tmp", - Mangler::Private); + void Init(StringRef GVName, Mangler *Mang, MCContext &Ctx) { + assert(!GVName.empty() && "external symbol name shouldn't be empty"); + if (Stub != 0) return; // Already initialized. + // Get the names for the external symbol name. + SmallString<128> TmpStr; + Mang->getNameWithPrefix(TmpStr, GVName, Mangler::Private); + MakeSymbols(TmpStr, Ctx); + } + + void MakeSymbols(SmallString<128> &TmpStr, MCContext &Ctx) { + TmpStr += "$stub"; + Stub = Ctx.GetOrCreateSymbol(TmpStr.str()); + TmpStr.erase(TmpStr.end()-5, TmpStr.end()); // Remove $stub + + TmpStr += "$lazy_ptr"; + LazyPtr = Ctx.GetOrCreateSymbol(TmpStr.str()); + TmpStr.erase(TmpStr.end()-9, TmpStr.end()); // Remove $lazy_ptr + + TmpStr += "$stub$tmp"; + AnonSymbol = Ctx.GetOrCreateSymbol(TmpStr.str()); } }; @@ -224,15 +241,17 @@ namespace { if (GV->isDeclaration() || GV->isWeakForLinker()) { // Dynamically-resolved functions need a stub for the function. FnStubInfo &FnInfo = FnStubs[Mang->getMangledName(GV)]; - FnInfo.Init(GV, Mang); - O << FnInfo.Stub; + FnInfo.Init(GV, Mang, OutContext); + FnInfo.Stub->print(O, MAI); return; } } if (MO.getType() == MachineOperand::MO_ExternalSymbol) { - FnStubInfo &FnInfo =FnStubs[Mang->makeNameProper(MO.getSymbolName())]; - FnInfo.Init(MO.getSymbolName(), Mang); - O << FnInfo.Stub; + SmallString<128> MangledName; + Mang->getNameWithPrefix(MangledName, MO.getSymbolName()); + FnStubInfo &FnInfo = FnStubs[MangledName.str()]; + FnInfo.Init(MO.getSymbolName(), Mang, OutContext); + FnInfo.Stub->print(O, MAI); return; } } @@ -550,50 +569,49 @@ void PPCAsmPrinter::printMachineInstruction(const MachineInstr *MI) { processDebugLoc(MI, true); // Check for slwi/srwi mnemonics. + bool useSubstituteMnemonic = false; if (MI->getOpcode() == PPC::RLWINM) { - bool FoundMnemonic = false; unsigned char SH = MI->getOperand(2).getImm(); unsigned char MB = MI->getOperand(3).getImm(); unsigned char ME = MI->getOperand(4).getImm(); if (SH <= 31 && MB == 0 && ME == (31-SH)) { - O << "\tslwi "; FoundMnemonic = true; + O << "\tslwi "; useSubstituteMnemonic = true; } if (SH <= 31 && MB == (32-SH) && ME == 31) { - O << "\tsrwi "; FoundMnemonic = true; + O << "\tsrwi "; useSubstituteMnemonic = true; SH = 32-SH; } - if (FoundMnemonic) { + if (useSubstituteMnemonic) { printOperand(MI, 0); O << ", "; printOperand(MI, 1); - O << ", " << (unsigned int)SH << '\n'; - return; + O << ", " << (unsigned int)SH; } } else if (MI->getOpcode() == PPC::OR || MI->getOpcode() == PPC::OR8) { if (MI->getOperand(1).getReg() == MI->getOperand(2).getReg()) { + useSubstituteMnemonic = true; O << "\tmr "; printOperand(MI, 0); O << ", "; printOperand(MI, 1); - O << '\n'; - return; } } else if (MI->getOpcode() == PPC::RLDICR) { unsigned char SH = MI->getOperand(2).getImm(); unsigned char ME = MI->getOperand(3).getImm(); // rldicr RA, RS, SH, 63-SH == sldi RA, RS, SH if (63-SH == ME) { + useSubstituteMnemonic = true; O << "\tsldi "; printOperand(MI, 0); O << ", "; printOperand(MI, 1); - O << ", " << (unsigned int)SH << '\n'; - return; + O << ", " << (unsigned int)SH; } } - printInstruction(MI); - + if (!useSubstituteMnemonic) + printInstruction(MI); + if (VerboseAsm) EmitComments(*MI); O << '\n'; @@ -1038,27 +1056,38 @@ bool PPCDarwinAsmPrinter::doFinalization(Module &M) { MCSectionMachO::S_SYMBOL_STUBS | MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 32, SectionKind::getText()); - for (StringMap::iterator I = FnStubs.begin(), E = FnStubs.end(); + for (StringMap::iterator I = FnStubs.begin(), E = FnStubs.end(); I != E; ++I) { OutStreamer.SwitchSection(StubSection); EmitAlignment(4); const FnStubInfo &Info = I->second; - O << Info.Stub << ":\n"; + Info.Stub->print(O, MAI); + O << ":\n"; O << "\t.indirect_symbol " << I->getKeyData() << '\n'; O << "\tmflr r0\n"; - O << "\tbcl 20,31," << Info.AnonSymbol << '\n'; - O << Info.AnonSymbol << ":\n"; + O << "\tbcl 20,31,"; + Info.AnonSymbol->print(O, MAI); + O << '\n'; + Info.AnonSymbol->print(O, MAI); + O << ":\n"; O << "\tmflr r11\n"; - O << "\taddis r11,r11,ha16(" << Info.LazyPtr << "-" << Info.AnonSymbol; + O << "\taddis r11,r11,ha16("; + Info.LazyPtr->print(O, MAI); + O << '-'; + Info.AnonSymbol->print(O, MAI); O << ")\n"; O << "\tmtlr r0\n"; O << (isPPC64 ? "\tldu" : "\tlwzu") << " r12,lo16("; - O << Info.LazyPtr << "-" << Info.AnonSymbol << ")(r11)\n"; + Info.LazyPtr->print(O, MAI); + O << '-'; + Info.AnonSymbol->print(O, MAI); + O << ")(r11)\n"; O << "\tmtctr r12\n"; O << "\tbctr\n"; OutStreamer.SwitchSection(LSPSection); - O << Info.LazyPtr << ":\n"; + Info.LazyPtr->print(O, MAI); + O << ":\n"; O << "\t.indirect_symbol " << I->getKeyData() << '\n'; O << (isPPC64 ? "\t.quad" : "\t.long") << " dyld_stub_binding_helper\n"; } @@ -1074,15 +1103,20 @@ bool PPCDarwinAsmPrinter::doFinalization(Module &M) { OutStreamer.SwitchSection(StubSection); EmitAlignment(4); const FnStubInfo &Info = I->second; - O << Info.Stub << ":\n"; + Info.Stub->print(O, MAI); + O << ":\n"; O << "\t.indirect_symbol " << I->getKeyData() << '\n'; - O << "\tlis r11,ha16(" << Info.LazyPtr << ")\n"; + O << "\tlis r11,ha16("; + Info.LazyPtr->print(O, MAI); + O << ")\n"; O << (isPPC64 ? "\tldu" : "\tlwzu") << " r12,lo16("; - O << Info.LazyPtr << ")(r11)\n"; + Info.LazyPtr->print(O, MAI); + O << ")(r11)\n"; O << "\tmtctr r12\n"; O << "\tbctr\n"; OutStreamer.SwitchSection(LSPSection); - O << Info.LazyPtr << ":\n"; + Info.LazyPtr->print(O, MAI); + O << ":\n"; O << "\t.indirect_symbol " << I->getKeyData() << '\n'; O << (isPPC64 ? "\t.quad" : "\t.long") << " dyld_stub_binding_helper\n"; } diff --git a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp index e7334b5..32c1879 100644 --- a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -95,7 +95,7 @@ namespace { // Select - Convert the specified operand from a target-independent to a // target-specific node if it hasn't already been changed. - SDNode *Select(SDValue Op); + SDNode *Select(SDNode *N); SDNode *SelectBitfieldInsert(SDNode *N); @@ -105,7 +105,7 @@ namespace { /// SelectAddrImm - Returns true if the address N can be represented by /// a base register plus a signed 16-bit displacement [r+imm]. - bool SelectAddrImm(SDValue Op, SDValue N, SDValue &Disp, + bool SelectAddrImm(SDNode *Op, SDValue N, SDValue &Disp, SDValue &Base) { return PPCLowering.SelectAddressRegImm(N, Disp, Base, *CurDAG); } @@ -113,7 +113,7 @@ namespace { /// SelectAddrImmOffs - Return true if the operand is valid for a preinc /// immediate field. Because preinc imms have already been validated, just /// accept it. - bool SelectAddrImmOffs(SDValue Op, SDValue N, SDValue &Out) const { + bool SelectAddrImmOffs(SDNode *Op, SDValue N, SDValue &Out) const { Out = N; return true; } @@ -121,14 +121,14 @@ namespace { /// SelectAddrIdx - Given the specified addressed, check to see if it can be /// represented as an indexed [r+r] operation. Returns false if it can /// be represented by [r+imm], which are preferred. - bool SelectAddrIdx(SDValue Op, SDValue N, SDValue &Base, + bool SelectAddrIdx(SDNode *Op, SDValue N, SDValue &Base, SDValue &Index) { return PPCLowering.SelectAddressRegReg(N, Base, Index, *CurDAG); } /// SelectAddrIdxOnly - Given the specified addressed, force it to be /// represented as an indexed [r+r] operation. - bool SelectAddrIdxOnly(SDValue Op, SDValue N, SDValue &Base, + bool SelectAddrIdxOnly(SDNode *Op, SDValue N, SDValue &Base, SDValue &Index) { return PPCLowering.SelectAddressRegRegOnly(N, Base, Index, *CurDAG); } @@ -136,7 +136,7 @@ namespace { /// SelectAddrImmShift - Returns true if the address N can be represented by /// a base register plus a signed 14-bit displacement [r+imm*4]. Suitable /// for use by STD and friends. - bool SelectAddrImmShift(SDValue Op, SDValue N, SDValue &Disp, + bool SelectAddrImmShift(SDNode *Op, SDValue N, SDValue &Disp, SDValue &Base) { return PPCLowering.SelectAddressRegImmShift(N, Disp, Base, *CurDAG); } @@ -180,7 +180,7 @@ namespace { #include "PPCGenDAGISel.inc" private: - SDNode *SelectSETCC(SDValue Op); + SDNode *SelectSETCC(SDNode *N); }; } @@ -635,8 +635,7 @@ static unsigned getCRIdxForSetCC(ISD::CondCode CC, bool &Invert, int &Other) { return 0; } -SDNode *PPCDAGToDAGISel::SelectSETCC(SDValue Op) { - SDNode *N = Op.getNode(); +SDNode *PPCDAGToDAGISel::SelectSETCC(SDNode *N) { DebugLoc dl = N->getDebugLoc(); unsigned Imm; ISD::CondCode CC = cast(N->getOperand(2))->get(); @@ -756,9 +755,8 @@ SDNode *PPCDAGToDAGISel::SelectSETCC(SDValue Op) { // Select - Convert the specified operand from a target-independent to a // target-specific node if it hasn't already been changed. -SDNode *PPCDAGToDAGISel::Select(SDValue Op) { - SDNode *N = Op.getNode(); - DebugLoc dl = Op.getDebugLoc(); +SDNode *PPCDAGToDAGISel::Select(SDNode *N) { + DebugLoc dl = N->getDebugLoc(); if (N->isMachineOpcode()) return NULL; // Already selected. @@ -841,18 +839,18 @@ SDNode *PPCDAGToDAGISel::Select(SDValue Op) { } case ISD::SETCC: - return SelectSETCC(Op); + return SelectSETCC(N); case PPCISD::GlobalBaseReg: return getGlobalBaseReg(); case ISD::FrameIndex: { int FI = cast(N)->getIndex(); - SDValue TFI = CurDAG->getTargetFrameIndex(FI, Op.getValueType()); - unsigned Opc = Op.getValueType() == MVT::i32 ? PPC::ADDI : PPC::ADDI8; + SDValue TFI = CurDAG->getTargetFrameIndex(FI, N->getValueType(0)); + unsigned Opc = N->getValueType(0) == MVT::i32 ? PPC::ADDI : PPC::ADDI8; if (N->hasOneUse()) - return CurDAG->SelectNodeTo(N, Opc, Op.getValueType(), TFI, + return CurDAG->SelectNodeTo(N, Opc, N->getValueType(0), TFI, getSmallIPtrImm(0)); - return CurDAG->getMachineNode(Opc, dl, Op.getValueType(), TFI, + return CurDAG->getMachineNode(Opc, dl, N->getValueType(0), TFI, getSmallIPtrImm(0)); } @@ -899,7 +897,7 @@ SDNode *PPCDAGToDAGISel::Select(SDValue Op) { case ISD::LOAD: { // Handle preincrement loads. - LoadSDNode *LD = cast(Op); + LoadSDNode *LD = cast(N); EVT LoadedVT = LD->getMemoryVT(); // Normal loads are handled by code generated from the .td file. @@ -1092,7 +1090,7 @@ SDNode *PPCDAGToDAGISel::Select(SDValue Op) { } } - return SelectCode(Op); + return SelectCode(N); } diff --git a/lib/Target/PowerPC/PPCInstrInfo.td b/lib/Target/PowerPC/PPCInstrInfo.td index 8fe151a..842f8ee 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.td +++ b/lib/Target/PowerPC/PPCInstrInfo.td @@ -430,9 +430,7 @@ let isCall = 1, PPC970_Unit = 7, F0,F1,F2,F3,F4,F5,F6,F7,F8,F9,F10,F11,F12,F13, V0,V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,V13,V14,V15,V16,V17,V18,V19, LR,CTR, - CR0,CR1,CR5,CR6,CR7, - CR0LT,CR0GT,CR0EQ,CR0UN,CR1LT,CR1GT,CR1EQ,CR1UN,CR5LT,CR5GT,CR5EQ, - CR5UN,CR6LT,CR6GT,CR6EQ,CR6UN,CR7LT,CR7GT,CR7EQ,CR7UN,CARRY] in { + CR0,CR1,CR5,CR6,CR7,CARRY] in { // Convenient aliases for call instructions let Uses = [RM] in { def BL_Darwin : IForm<18, 0, 1, @@ -457,9 +455,7 @@ let isCall = 1, PPC970_Unit = 7, F0,F1,F2,F3,F4,F5,F6,F7,F8,F9,F10,F11,F12,F13, V0,V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,V13,V14,V15,V16,V17,V18,V19, LR,CTR, - CR0,CR1,CR5,CR6,CR7, - CR0LT,CR0GT,CR0EQ,CR0UN,CR1LT,CR1GT,CR1EQ,CR1UN,CR5LT,CR5GT,CR5EQ, - CR5UN,CR6LT,CR6GT,CR6EQ,CR6UN,CR7LT,CR7GT,CR7EQ,CR7UN,CARRY] in { + CR0,CR1,CR5,CR6,CR7,CARRY] in { // Convenient aliases for call instructions let Uses = [RM] in { def BL_SVR4 : IForm<18, 0, 1, diff --git a/lib/Target/PowerPC/PPCJITInfo.cpp b/lib/Target/PowerPC/PPCJITInfo.cpp index be6e51e..daf4ec6 100644 --- a/lib/Target/PowerPC/PPCJITInfo.cpp +++ b/lib/Target/PowerPC/PPCJITInfo.cpp @@ -308,6 +308,7 @@ extern "C" void *PPCCompilationCallbackC(unsigned *StubCallAddrPlus4, // Rewrite the stub with an unconditional branch to the target, for any users // who took the address of the stub. EmitBranchToAt((intptr_t)StubCallAddr, (intptr_t)Target, false, is64Bit); + sys::Memory::InvalidateInstructionCache(StubCallAddr, 7*4); // Put the address of the target function to call and the address to return to // after calling the target function in a place that is easy to get on the @@ -441,4 +442,5 @@ void PPCJITInfo::relocate(void *Function, MachineRelocation *MR, void PPCJITInfo::replaceMachineCodeForFunction(void *Old, void *New) { EmitBranchToAt((intptr_t)Old, (intptr_t)New, false, is64Bit); + sys::Memory::InvalidateInstructionCache(Old, 7*4); } diff --git a/lib/Target/PowerPC/PPCMCAsmInfo.cpp b/lib/Target/PowerPC/PPCMCAsmInfo.cpp index c87879b..ee6deb5 100644 --- a/lib/Target/PowerPC/PPCMCAsmInfo.cpp +++ b/lib/Target/PowerPC/PPCMCAsmInfo.cpp @@ -22,6 +22,7 @@ PPCMCAsmInfoDarwin::PPCMCAsmInfoDarwin(bool is64Bit) { if (!is64Bit) Data64bitsDirective = 0; // We can't emit a 64-bit unit in PPC32 mode. AssemblerDialect = 1; // New-Style mnemonics. + SupportsDebugInformation= true; // Debug information. } PPCLinuxMCAsmInfo::PPCLinuxMCAsmInfo(bool is64Bit) { diff --git a/lib/Target/PowerPC/README.txt b/lib/Target/PowerPC/README.txt index f5e50fc..060d6a5 100644 --- a/lib/Target/PowerPC/README.txt +++ b/lib/Target/PowerPC/README.txt @@ -7,6 +7,39 @@ TODO: ===-------------------------------------------------------------------------=== +On PPC64, this: + +long f2 (long x) { return 0xfffffff000000000UL; } +long f3 (long x) { return 0x1ffffffffUL; } + +could compile into: + +_f2: + li r3,-1 + rldicr r3,r3,0,27 + blr +_f3: + li r3,-1 + rldicl r3,r3,0,31 + blr + +we produce: + +_f2: + lis r2, 4095 + ori r2, r2, 65535 + sldi r3, r2, 36 + blr +_f3: + li r2, 1 + sldi r2, r2, 32 + oris r2, r2, 65535 + ori r3, r2, 65535 + blr + + +===-------------------------------------------------------------------------=== + Support 'update' load/store instructions. These are cracked on the G5, but are still a codesize win. diff --git a/lib/Target/README.txt b/lib/Target/README.txt index a6e05fa..69da35f 100644 --- a/lib/Target/README.txt +++ b/lib/Target/README.txt @@ -282,19 +282,6 @@ this requires TBAA. //===---------------------------------------------------------------------===// -This should be optimized to one 'and' and one 'or', from PR4216: - -define i32 @test_bitfield(i32 %bf.prev.low) nounwind ssp { -entry: - %bf.prev.lo.cleared10 = or i32 %bf.prev.low, 32962 ; [#uses=1] - %0 = and i32 %bf.prev.low, -65536 ; [#uses=1] - %1 = and i32 %bf.prev.lo.cleared10, 40186 ; [#uses=1] - %2 = or i32 %1, %0 ; [#uses=1] - ret i32 %2 -} - -//===---------------------------------------------------------------------===// - This isn't recognized as bswap by instcombine (yes, it really is bswap): unsigned long reverse(unsigned v) { @@ -1661,38 +1648,9 @@ would delete the or instruction for us. //===---------------------------------------------------------------------===// -FunctionAttrs is not marking this function as readnone (just readonly): -$ clang t.c -emit-llvm -S -o - -O0 | opt -mem2reg -S -functionattrs - -int t(int a, int b, int c) { - int *p; - if (a) - p = &a; - else - p = &c; - return *p; -} - -This is because we codegen this to: - -define i32 @t(i32 %a, i32 %b, i32 %c) nounwind readonly ssp { -entry: - %a.addr = alloca i32 ; [#uses=3] - %c.addr = alloca i32 ; [#uses=2] -... - -if.end: - %p.0 = phi i32* [ %a.addr, %if.then ], [ %c.addr, %if.else ] - %tmp2 = load i32* %p.0 ; [#uses=1] - ret i32 %tmp2 -} - -And functionattrs doesn't realize that the p.0 load points to function local -memory. - -Also, functionattrs doesn't know about memcpy/memset. This function should be -marked readnone, since it only twiddles local memory, but functionattrs doesn't -handle memset/memcpy/memmove aggressively: +functionattrs doesn't know much about memcpy/memset. This function should be +marked readnone rather than readonly, since it only twiddles local memory, but +functionattrs doesn't handle memset/memcpy/memmove aggressively: struct X { int *p; int *q; }; int foo() { diff --git a/lib/Target/Sparc/SparcISelDAGToDAG.cpp b/lib/Target/Sparc/SparcISelDAGToDAG.cpp index b41917e..e1b3299 100644 --- a/lib/Target/Sparc/SparcISelDAGToDAG.cpp +++ b/lib/Target/Sparc/SparcISelDAGToDAG.cpp @@ -43,11 +43,11 @@ public: TM(tm) { } - SDNode *Select(SDValue Op); + SDNode *Select(SDNode *N); // Complex Pattern Selectors. - bool SelectADDRrr(SDValue Op, SDValue N, SDValue &R1, SDValue &R2); - bool SelectADDRri(SDValue Op, SDValue N, SDValue &Base, + bool SelectADDRrr(SDNode *Op, SDValue N, SDValue &R1, SDValue &R2); + bool SelectADDRri(SDNode *Op, SDValue N, SDValue &Base, SDValue &Offset); /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for @@ -87,7 +87,7 @@ SDNode* SparcDAGToDAGISel::getGlobalBaseReg() { return CurDAG->getRegister(GlobalBaseReg, TLI.getPointerTy()).getNode(); } -bool SparcDAGToDAGISel::SelectADDRri(SDValue Op, SDValue Addr, +bool SparcDAGToDAGISel::SelectADDRri(SDNode *Op, SDValue Addr, SDValue &Base, SDValue &Offset) { if (FrameIndexSDNode *FIN = dyn_cast(Addr)) { Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); @@ -128,7 +128,7 @@ bool SparcDAGToDAGISel::SelectADDRri(SDValue Op, SDValue Addr, return true; } -bool SparcDAGToDAGISel::SelectADDRrr(SDValue Op, SDValue Addr, +bool SparcDAGToDAGISel::SelectADDRrr(SDNode *Op, SDValue Addr, SDValue &R1, SDValue &R2) { if (Addr.getOpcode() == ISD::FrameIndex) return false; if (Addr.getOpcode() == ISD::TargetExternalSymbol || @@ -152,8 +152,7 @@ bool SparcDAGToDAGISel::SelectADDRrr(SDValue Op, SDValue Addr, return true; } -SDNode *SparcDAGToDAGISel::Select(SDValue Op) { - SDNode *N = Op.getNode(); +SDNode *SparcDAGToDAGISel::Select(SDNode *N) { DebugLoc dl = N->getDebugLoc(); if (N->isMachineOpcode()) return NULL; // Already selected. @@ -199,7 +198,7 @@ SDNode *SparcDAGToDAGISel::Select(SDValue Op) { } } - return SelectCode(Op); + return SelectCode(N); } @@ -213,8 +212,8 @@ SparcDAGToDAGISel::SelectInlineAsmMemoryOperand(const SDValue &Op, switch (ConstraintCode) { default: return true; case 'm': // memory - if (!SelectADDRrr(Op, Op, Op0, Op1)) - SelectADDRri(Op, Op, Op0, Op1); + if (!SelectADDRrr(Op.getNode(), Op, Op0, Op1)) + SelectADDRri(Op.getNode(), Op, Op0, Op1); break; } diff --git a/lib/Target/SubtargetFeature.cpp b/lib/Target/SubtargetFeature.cpp index 590574e..7cc4fd1 100644 --- a/lib/Target/SubtargetFeature.cpp +++ b/lib/Target/SubtargetFeature.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Target/SubtargetFeature.h" +#include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" #include "llvm/ADT/StringExtras.h" #include @@ -355,7 +356,7 @@ void SubtargetFeatures::print(raw_ostream &OS) const { /// dump - Dump feature info. /// void SubtargetFeatures::dump() const { - print(errs()); + print(dbgs()); } /// getDefaultSubtargetFeatures - Return a string listing diff --git a/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp b/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp index d64611d..7096c0e 100644 --- a/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp +++ b/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp @@ -128,23 +128,23 @@ namespace { #include "SystemZGenDAGISel.inc" private: - bool SelectAddrRI12Only(SDValue Op, SDValue& Addr, + bool SelectAddrRI12Only(SDNode *Op, SDValue& Addr, SDValue &Base, SDValue &Disp); - bool SelectAddrRI12(SDValue Op, SDValue& Addr, + bool SelectAddrRI12(SDNode *Op, SDValue& Addr, SDValue &Base, SDValue &Disp, bool is12BitOnly = false); - bool SelectAddrRI(SDValue Op, SDValue& Addr, + bool SelectAddrRI(SDNode *Op, SDValue& Addr, SDValue &Base, SDValue &Disp); - bool SelectAddrRRI12(SDValue Op, SDValue Addr, + bool SelectAddrRRI12(SDNode *Op, SDValue Addr, SDValue &Base, SDValue &Disp, SDValue &Index); - bool SelectAddrRRI20(SDValue Op, SDValue Addr, + bool SelectAddrRRI20(SDNode *Op, SDValue Addr, SDValue &Base, SDValue &Disp, SDValue &Index); - bool SelectLAAddr(SDValue Op, SDValue Addr, + bool SelectLAAddr(SDNode *Op, SDValue Addr, SDValue &Base, SDValue &Disp, SDValue &Index); - SDNode *Select(SDValue Op); + SDNode *Select(SDNode *Node); - bool TryFoldLoad(SDValue P, SDValue N, + bool TryFoldLoad(SDNode *P, SDValue N, SDValue &Base, SDValue &Disp, SDValue &Index); bool MatchAddress(SDValue N, SystemZRRIAddressMode &AM, @@ -367,12 +367,12 @@ void SystemZDAGToDAGISel::getAddressOperands(const SystemZRRIAddressMode &AM, /// Returns true if the address can be represented by a base register plus /// an unsigned 12-bit displacement [r+imm]. -bool SystemZDAGToDAGISel::SelectAddrRI12Only(SDValue Op, SDValue& Addr, +bool SystemZDAGToDAGISel::SelectAddrRI12Only(SDNode *Op, SDValue& Addr, SDValue &Base, SDValue &Disp) { return SelectAddrRI12(Op, Addr, Base, Disp, /*is12BitOnly*/true); } -bool SystemZDAGToDAGISel::SelectAddrRI12(SDValue Op, SDValue& Addr, +bool SystemZDAGToDAGISel::SelectAddrRI12(SDNode *Op, SDValue& Addr, SDValue &Base, SDValue &Disp, bool is12BitOnly) { SystemZRRIAddressMode AM20(/*isRI*/true), AM12(/*isRI*/true); @@ -422,7 +422,7 @@ bool SystemZDAGToDAGISel::SelectAddrRI12(SDValue Op, SDValue& Addr, /// Returns true if the address can be represented by a base register plus /// a signed 20-bit displacement [r+imm]. -bool SystemZDAGToDAGISel::SelectAddrRI(SDValue Op, SDValue& Addr, +bool SystemZDAGToDAGISel::SelectAddrRI(SDNode *Op, SDValue& Addr, SDValue &Base, SDValue &Disp) { SystemZRRIAddressMode AM(/*isRI*/true); bool Done = false; @@ -465,7 +465,7 @@ bool SystemZDAGToDAGISel::SelectAddrRI(SDValue Op, SDValue& Addr, /// Returns true if the address can be represented by a base register plus /// index register plus an unsigned 12-bit displacement [base + idx + imm]. -bool SystemZDAGToDAGISel::SelectAddrRRI12(SDValue Op, SDValue Addr, +bool SystemZDAGToDAGISel::SelectAddrRRI12(SDNode *Op, SDValue Addr, SDValue &Base, SDValue &Disp, SDValue &Index) { SystemZRRIAddressMode AM20, AM12; bool Done = false; @@ -514,7 +514,7 @@ bool SystemZDAGToDAGISel::SelectAddrRRI12(SDValue Op, SDValue Addr, /// Returns true if the address can be represented by a base register plus /// index register plus a signed 20-bit displacement [base + idx + imm]. -bool SystemZDAGToDAGISel::SelectAddrRRI20(SDValue Op, SDValue Addr, +bool SystemZDAGToDAGISel::SelectAddrRRI20(SDNode *Op, SDValue Addr, SDValue &Base, SDValue &Disp, SDValue &Index) { SystemZRRIAddressMode AM; bool Done = false; @@ -558,7 +558,7 @@ bool SystemZDAGToDAGISel::SelectAddrRRI20(SDValue Op, SDValue Addr, /// SelectLAAddr - it calls SelectAddr and determines if the maximal addressing /// mode it matches can be cost effectively emitted as an LA/LAY instruction. -bool SystemZDAGToDAGISel::SelectLAAddr(SDValue Op, SDValue Addr, +bool SystemZDAGToDAGISel::SelectLAAddr(SDNode *Op, SDValue Addr, SDValue &Base, SDValue &Disp, SDValue &Index) { SystemZRRIAddressMode AM; @@ -591,11 +591,11 @@ bool SystemZDAGToDAGISel::SelectLAAddr(SDValue Op, SDValue Addr, return false; } -bool SystemZDAGToDAGISel::TryFoldLoad(SDValue P, SDValue N, +bool SystemZDAGToDAGISel::TryFoldLoad(SDNode *P, SDValue N, SDValue &Base, SDValue &Disp, SDValue &Index) { if (ISD::isNON_EXTLoad(N.getNode()) && N.hasOneUse() && - IsLegalAndProfitableToFold(N.getNode(), P.getNode(), P.getNode())) + IsLegalAndProfitableToFold(N.getNode(), P, P)) return SelectAddrRRI20(P, N.getOperand(1), Base, Disp, Index); return false; } @@ -612,10 +612,9 @@ void SystemZDAGToDAGISel::InstructionSelect() { CurDAG->RemoveDeadNodes(); } -SDNode *SystemZDAGToDAGISel::Select(SDValue Op) { - SDNode *Node = Op.getNode(); +SDNode *SystemZDAGToDAGISel::Select(SDNode *Node) { EVT NVT = Node->getValueType(0); - DebugLoc dl = Op.getDebugLoc(); + DebugLoc dl = Node->getDebugLoc(); unsigned Opcode = Node->getOpcode(); // Dump information about the Node being selected @@ -643,20 +642,20 @@ SDNode *SystemZDAGToDAGISel::Select(SDValue Op) { EVT ResVT; bool is32Bit = false; switch (NVT.getSimpleVT().SimpleTy) { - default: assert(0 && "Unsupported VT!"); - case MVT::i32: - Opc = SystemZ::SDIVREM32r; MOpc = SystemZ::SDIVREM32m; - ResVT = MVT::v2i64; - is32Bit = true; - break; - case MVT::i64: - Opc = SystemZ::SDIVREM64r; MOpc = SystemZ::SDIVREM64m; - ResVT = MVT::v2i64; - break; + default: assert(0 && "Unsupported VT!"); + case MVT::i32: + Opc = SystemZ::SDIVREM32r; MOpc = SystemZ::SDIVREM32m; + ResVT = MVT::v2i64; + is32Bit = true; + break; + case MVT::i64: + Opc = SystemZ::SDIVREM64r; MOpc = SystemZ::SDIVREM64m; + ResVT = MVT::v2i64; + break; } SDValue Tmp0, Tmp1, Tmp2; - bool foldedLoad = TryFoldLoad(Op, N1, Tmp0, Tmp1, Tmp2); + bool foldedLoad = TryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2); // Prepare the dividend SDNode *Dividend; @@ -677,16 +676,16 @@ SDNode *SystemZDAGToDAGISel::Select(SDValue Op) { SDValue DivVal = SDValue(Dividend, 0); if (foldedLoad) { SDValue Ops[] = { DivVal, Tmp0, Tmp1, Tmp2, N1.getOperand(0) }; - Result = CurDAG->getMachineNode(MOpc, dl, ResVT, + Result = CurDAG->getMachineNode(MOpc, dl, ResVT, MVT::Other, Ops, array_lengthof(Ops)); // Update the chain. - ReplaceUses(N1.getValue(1), SDValue(Result, 0)); + ReplaceUses(N1.getValue(1), SDValue(Result, 1)); } else { Result = CurDAG->getMachineNode(Opc, dl, ResVT, SDValue(Dividend, 0), N1); } // Copy the division (odd subreg) result, if it is needed. - if (!Op.getValue(0).use_empty()) { + if (!SDValue(Node, 0).use_empty()) { unsigned SubRegIdx = (is32Bit ? subreg_odd32 : subreg_odd); SDNode *Div = CurDAG->getMachineNode(TargetInstrInfo::EXTRACT_SUBREG, dl, NVT, @@ -694,14 +693,14 @@ SDNode *SystemZDAGToDAGISel::Select(SDValue Op) { CurDAG->getTargetConstant(SubRegIdx, MVT::i32)); - ReplaceUses(Op.getValue(0), SDValue(Div, 0)); + ReplaceUses(SDValue(Node, 0), SDValue(Div, 0)); DEBUG(errs().indent(Indent-2) << "=> "; Result->dump(CurDAG); errs() << "\n"); } // Copy the remainder (even subreg) result, if it is needed. - if (!Op.getValue(1).use_empty()) { + if (!SDValue(Node, 1).use_empty()) { unsigned SubRegIdx = (is32Bit ? subreg_even32 : subreg_even); SDNode *Rem = CurDAG->getMachineNode(TargetInstrInfo::EXTRACT_SUBREG, dl, NVT, @@ -709,7 +708,7 @@ SDNode *SystemZDAGToDAGISel::Select(SDValue Op) { CurDAG->getTargetConstant(SubRegIdx, MVT::i32)); - ReplaceUses(Op.getValue(1), SDValue(Rem, 0)); + ReplaceUses(SDValue(Node, 1), SDValue(Rem, 0)); DEBUG(errs().indent(Indent-2) << "=> "; Result->dump(CurDAG); errs() << "\n"); @@ -729,22 +728,22 @@ SDNode *SystemZDAGToDAGISel::Select(SDValue Op) { bool is32Bit = false; switch (NVT.getSimpleVT().SimpleTy) { - default: assert(0 && "Unsupported VT!"); - case MVT::i32: - Opc = SystemZ::UDIVREM32r; MOpc = SystemZ::UDIVREM32m; - ClrOpc = SystemZ::MOV64Pr0_even; - ResVT = MVT::v2i32; - is32Bit = true; - break; - case MVT::i64: - Opc = SystemZ::UDIVREM64r; MOpc = SystemZ::UDIVREM64m; - ClrOpc = SystemZ::MOV128r0_even; - ResVT = MVT::v2i64; - break; + default: assert(0 && "Unsupported VT!"); + case MVT::i32: + Opc = SystemZ::UDIVREM32r; MOpc = SystemZ::UDIVREM32m; + ClrOpc = SystemZ::MOV64Pr0_even; + ResVT = MVT::v2i32; + is32Bit = true; + break; + case MVT::i64: + Opc = SystemZ::UDIVREM64r; MOpc = SystemZ::UDIVREM64m; + ClrOpc = SystemZ::MOV128r0_even; + ResVT = MVT::v2i64; + break; } SDValue Tmp0, Tmp1, Tmp2; - bool foldedLoad = TryFoldLoad(Op, N1, Tmp0, Tmp1, Tmp2); + bool foldedLoad = TryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2); // Prepare the dividend SDNode *Dividend = N0.getNode(); @@ -767,37 +766,37 @@ SDNode *SystemZDAGToDAGISel::Select(SDValue Op) { SDNode *Result; if (foldedLoad) { SDValue Ops[] = { DivVal, Tmp0, Tmp1, Tmp2, N1.getOperand(0) }; - Result = CurDAG->getMachineNode(MOpc, dl,ResVT, + Result = CurDAG->getMachineNode(MOpc, dl, ResVT, MVT::Other, Ops, array_lengthof(Ops)); // Update the chain. - ReplaceUses(N1.getValue(1), SDValue(Result, 0)); + ReplaceUses(N1.getValue(1), SDValue(Result, 1)); } else { Result = CurDAG->getMachineNode(Opc, dl, ResVT, DivVal, N1); } // Copy the division (odd subreg) result, if it is needed. - if (!Op.getValue(0).use_empty()) { + if (!SDValue(Node, 0).use_empty()) { unsigned SubRegIdx = (is32Bit ? subreg_odd32 : subreg_odd); SDNode *Div = CurDAG->getMachineNode(TargetInstrInfo::EXTRACT_SUBREG, dl, NVT, SDValue(Result, 0), CurDAG->getTargetConstant(SubRegIdx, MVT::i32)); - ReplaceUses(Op.getValue(0), SDValue(Div, 0)); + ReplaceUses(SDValue(Node, 0), SDValue(Div, 0)); DEBUG(errs().indent(Indent-2) << "=> "; Result->dump(CurDAG); errs() << "\n"); } // Copy the remainder (even subreg) result, if it is needed. - if (!Op.getValue(1).use_empty()) { + if (!SDValue(Node, 1).use_empty()) { unsigned SubRegIdx = (is32Bit ? subreg_even32 : subreg_even); SDNode *Rem = CurDAG->getMachineNode(TargetInstrInfo::EXTRACT_SUBREG, dl, NVT, SDValue(Result, 0), CurDAG->getTargetConstant(SubRegIdx, MVT::i32)); - ReplaceUses(Op.getValue(1), SDValue(Rem, 0)); + ReplaceUses(SDValue(Node, 1), SDValue(Rem, 0)); DEBUG(errs().indent(Indent-2) << "=> "; Result->dump(CurDAG); errs() << "\n"); @@ -812,11 +811,11 @@ SDNode *SystemZDAGToDAGISel::Select(SDValue Op) { } // Select the default instruction - SDNode *ResNode = SelectCode(Op); + SDNode *ResNode = SelectCode(Node); DEBUG(errs().indent(Indent-2) << "=> "; - if (ResNode == NULL || ResNode == Op.getNode()) - Op.getNode()->dump(CurDAG); + if (ResNode == NULL || ResNode == Node) + Node->dump(CurDAG); else ResNode->dump(CurDAG); errs() << "\n"; diff --git a/lib/Target/Target.cpp b/lib/Target/Target.cpp index cddf49e..f5c969a 100644 --- a/lib/Target/Target.cpp +++ b/lib/Target/Target.cpp @@ -34,7 +34,7 @@ char *LLVMCopyStringRepOfTargetData(LLVMTargetDataRef TD) { } LLVMByteOrdering LLVMByteOrder(LLVMTargetDataRef TD) { - return unwrap(TD)->isLittleEndian(); + return unwrap(TD)->isLittleEndian() ? LLVMLittleEndian : LLVMBigEndian; } unsigned LLVMPointerSize(LLVMTargetDataRef TD) { diff --git a/lib/Target/TargetLoweringObjectFile.cpp b/lib/Target/TargetLoweringObjectFile.cpp index f887523..70e8008 100644 --- a/lib/Target/TargetLoweringObjectFile.cpp +++ b/lib/Target/TargetLoweringObjectFile.cpp @@ -21,11 +21,13 @@ #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCSectionELF.h" +#include "llvm/MC/MCSymbol.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Mangler.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" using namespace llvm; @@ -492,16 +494,15 @@ getELFKindForNamedSection(const char *Name, SectionKind K) { } -static unsigned -getELFSectionType(const char *Name, SectionKind K) { +static unsigned getELFSectionType(StringRef Name, SectionKind K) { - if (strcmp(Name, ".init_array") == 0) + if (Name == ".init_array") return MCSectionELF::SHT_INIT_ARRAY; - if (strcmp(Name, ".fini_array") == 0) + if (Name == ".fini_array") return MCSectionELF::SHT_FINI_ARRAY; - if (strcmp(Name, ".preinit_array") == 0) + if (Name == ".preinit_array") return MCSectionELF::SHT_PREINIT_ARRAY; if (K.isBSS() || K.isThreadBSS()) @@ -577,10 +578,16 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, // into a 'uniqued' section name, create and return the section now. if (GV->isWeakForLinker()) { const char *Prefix = getSectionPrefixForUniqueGlobal(Kind); - std::string Name = Mang->makeNameProper(GV->getNameStr()); - - return getELFSection((Prefix+Name).c_str(), - getELFSectionType((Prefix+Name).c_str(), Kind), + SmallString<128> Name, MangledName; + Name.append(Prefix, Prefix+strlen(Prefix)); + Mang->getNameWithPrefix(Name, GV, false); + + raw_svector_ostream OS(MangledName); + MCSymbol::printMangledName(Name, OS, 0); + OS.flush(); + + return getELFSection(MangledName.str(), + getELFSectionType(MangledName.str(), Kind), getELFSectionFlags(Kind), Kind); } @@ -922,7 +929,7 @@ const MCSection * TargetLoweringObjectFileMachO::getSectionForConstant(SectionKind Kind) const { // If this constant requires a relocation, we have to put it in the data // segment, not in the text segment. - if (Kind.isDataRel()) + if (Kind.isDataRel() || Kind.isReadOnlyWithRel()) return ConstDataSection; if (Kind.isMergeableConst4()) @@ -983,7 +990,7 @@ TargetLoweringObjectFileCOFF::~TargetLoweringObjectFileCOFF() { const MCSection *TargetLoweringObjectFileCOFF:: -getCOFFSection(const char *Name, bool isDirective, SectionKind Kind) const { +getCOFFSection(StringRef Name, bool isDirective, SectionKind Kind) const { // Create the map if it doesn't already exist. if (UniquingMap == 0) UniquingMap = new MachOUniqueMapTy(); @@ -1078,8 +1085,9 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, // into a 'uniqued' section name, create and return the section now. if (GV->isWeakForLinker()) { const char *Prefix = getCOFFSectionPrefixForUniqueGlobal(Kind); - std::string Name = Mang->makeNameProper(GV->getNameStr()); - return getCOFFSection((Prefix+Name).c_str(), false, Kind); + SmallString<128> Name(Prefix, Prefix+strlen(Prefix)); + Mang->getNameWithPrefix(Name, GV, false); + return getCOFFSection(Name.str(), false, Kind); } if (Kind.isText()) diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp index c357b4d..c4ae5d2 100644 --- a/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Target/TargetAsmParser.h" #include "X86.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Twine.h" @@ -15,6 +16,7 @@ #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" +#include "llvm/MC/MCParsedAsmOperand.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Target/TargetRegistry.h" #include "llvm/Target/TargetAsmParser.h" @@ -46,7 +48,7 @@ private: /// @name Auto-generated Match Functions /// { - bool MatchInstruction(SmallVectorImpl &Operands, + bool MatchInstruction(const SmallVectorImpl &Operands, MCInst &Inst); /// MatchRegisterName - Match the given string to a register name, or 0 if @@ -59,7 +61,8 @@ public: X86ATTAsmParser(const Target &T, MCAsmParser &_Parser) : TargetAsmParser(T), Parser(_Parser) {} - virtual bool ParseInstruction(const StringRef &Name, MCInst &Inst); + virtual bool ParseInstruction(const StringRef &Name, SMLoc NameLoc, + SmallVectorImpl &Operands); virtual bool ParseDirective(AsmToken DirectiveID); }; @@ -71,7 +74,7 @@ namespace { /// X86Operand - Instances of this class represent a parsed X86 machine /// instruction. -struct X86Operand { +struct X86Operand : public MCParsedAsmOperand { enum { Token, Register, @@ -400,10 +403,11 @@ bool X86ATTAsmParser::ParseMemOperand(X86Operand &Op) { return false; } -bool X86ATTAsmParser::ParseInstruction(const StringRef &Name, MCInst &Inst) { - SmallVector Operands; +bool X86ATTAsmParser:: +ParseInstruction(const StringRef &Name, SMLoc NameLoc, + SmallVectorImpl &Operands) { - Operands.push_back(X86Operand::CreateToken(Name)); + Operands.push_back(new X86Operand(X86Operand::CreateToken(Name))); SMLoc Loc = getLexer().getTok().getLoc(); if (getLexer().isNot(AsmToken::EndOfStatement)) { @@ -411,31 +415,27 @@ bool X86ATTAsmParser::ParseInstruction(const StringRef &Name, MCInst &Inst) { // Parse '*' modifier. if (getLexer().is(AsmToken::Star)) { getLexer().Lex(); // Eat the star. - Operands.push_back(X86Operand::CreateToken("*")); + Operands.push_back(new X86Operand(X86Operand::CreateToken("*"))); } // Read the first operand. - Operands.push_back(X86Operand()); - if (ParseOperand(Operands.back())) + X86Operand Op; + if (ParseOperand(Op)) return true; + Operands.push_back(new X86Operand(Op)); + while (getLexer().is(AsmToken::Comma)) { getLexer().Lex(); // Eat the comma. // Parse and remember the operand. - Operands.push_back(X86Operand()); - if (ParseOperand(Operands.back())) + if (ParseOperand(Op)) return true; + Operands.push_back(new X86Operand(Op)); } } - if (!MatchInstruction(Operands, Inst)) - return false; - - // FIXME: We should give nicer diagnostics about the exact failure. - - Error(Loc, "unrecognized instruction"); - return true; + return false; } bool X86ATTAsmParser::ParseDirective(AsmToken DirectiveID) { diff --git a/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp b/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp index b88063f..70c6dd0 100644 --- a/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp +++ b/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp @@ -201,6 +201,7 @@ bool X86AsmPrinter::runOnMachineFunction(MachineFunction &MF) { /// jump tables, constant pools, global address and external symbols, all of /// which print to a label with various suffixes for relocation types etc. void X86AsmPrinter::printSymbolOperand(const MachineOperand &MO) { + SmallString<128> TempNameStr; switch (MO.getType()) { default: llvm_unreachable("unknown symbol type!"); case MachineOperand::MO_JumpTableIndex: @@ -236,41 +237,38 @@ void X86AsmPrinter::printSymbolOperand(const MachineOperand &MO) { if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY || MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE) { - SmallString<128> NameStr; - Mang->getNameWithPrefix(NameStr, GV, true); - NameStr += "$non_lazy_ptr"; - MCSymbol *Sym = OutContext.GetOrCreateSymbol(NameStr.str()); + Mang->getNameWithPrefix(TempNameStr, GV, true); + TempNameStr += "$non_lazy_ptr"; + MCSymbol *Sym = OutContext.GetOrCreateSymbol(TempNameStr.str()); const MCSymbol *&StubSym = MMI->getObjFileInfo().getGVStubEntry(Sym); if (StubSym == 0) { - NameStr.clear(); - Mang->getNameWithPrefix(NameStr, GV, false); - StubSym = OutContext.GetOrCreateSymbol(NameStr.str()); + TempNameStr.clear(); + Mang->getNameWithPrefix(TempNameStr, GV, false); + StubSym = OutContext.GetOrCreateSymbol(TempNameStr.str()); } } else if (MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE){ - SmallString<128> NameStr; - Mang->getNameWithPrefix(NameStr, GV, true); - NameStr += "$non_lazy_ptr"; - MCSymbol *Sym = OutContext.GetOrCreateSymbol(NameStr.str()); + Mang->getNameWithPrefix(TempNameStr, GV, true); + TempNameStr += "$non_lazy_ptr"; + MCSymbol *Sym = OutContext.GetOrCreateSymbol(TempNameStr.str()); const MCSymbol *&StubSym = MMI->getObjFileInfo().getHiddenGVStubEntry(Sym); if (StubSym == 0) { - NameStr.clear(); - Mang->getNameWithPrefix(NameStr, GV, false); - StubSym = OutContext.GetOrCreateSymbol(NameStr.str()); + TempNameStr.clear(); + Mang->getNameWithPrefix(TempNameStr, GV, false); + StubSym = OutContext.GetOrCreateSymbol(TempNameStr.str()); } } else if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB) { - SmallString<128> NameStr; - Mang->getNameWithPrefix(NameStr, GV, true); - NameStr += "$stub"; - MCSymbol *Sym = OutContext.GetOrCreateSymbol(NameStr.str()); + Mang->getNameWithPrefix(TempNameStr, GV, true); + TempNameStr += "$stub"; + MCSymbol *Sym = OutContext.GetOrCreateSymbol(TempNameStr.str()); const MCSymbol *&StubSym = MMI->getObjFileInfo().getFnStubEntry(Sym); if (StubSym == 0) { - NameStr.clear(); - Mang->getNameWithPrefix(NameStr, GV, false); - StubSym = OutContext.GetOrCreateSymbol(NameStr.str()); + TempNameStr.clear(); + Mang->getNameWithPrefix(TempNameStr, GV, false); + StubSym = OutContext.GetOrCreateSymbol(TempNameStr.str()); } } @@ -285,24 +283,32 @@ void X86AsmPrinter::printSymbolOperand(const MachineOperand &MO) { break; } case MachineOperand::MO_ExternalSymbol: { - std::string Name = Mang->makeNameProper(MO.getSymbolName()); + const MCSymbol *SymToPrint; if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB) { - Name += "$stub"; - MCSymbol *Sym = OutContext.GetOrCreateSymbol(StringRef(Name)); + Mang->getNameWithPrefix(TempNameStr, + StringRef(MO.getSymbolName())+"$stub"); + const MCSymbol *Sym = OutContext.GetOrCreateSymbol(TempNameStr.str()); const MCSymbol *&StubSym = MMI->getObjFileInfo().getFnStubEntry(Sym); if (StubSym == 0) { - Name.erase(Name.end()-5, Name.end()); - StubSym = OutContext.GetOrCreateSymbol(StringRef(Name)); + TempNameStr.erase(TempNameStr.end()-5, TempNameStr.end()); + StubSym = OutContext.GetOrCreateSymbol(TempNameStr.str()); } + SymToPrint = StubSym; + } else { + Mang->getNameWithPrefix(TempNameStr, MO.getSymbolName()); + SymToPrint = OutContext.GetOrCreateSymbol(TempNameStr.str()); } // If the name begins with a dollar-sign, enclose it in parens. We do this // to avoid having it look like an integer immediate to the assembler. - if (Name[0] == '$') - O << '(' << Name << ')'; - else - O << Name; + if (SymToPrint->getName()[0] != '$') + SymToPrint->print(O, MAI); + else { + O << '('; + SymToPrint->print(O, MAI); + O << '('; + } break; } } diff --git a/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp b/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp index 1015b69..9ee118c 100644 --- a/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp +++ b/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp @@ -25,6 +25,7 @@ #include "llvm/Support/FormattedStream.h" #include "llvm/Support/Mangler.h" #include "llvm/ADT/SmallString.h" +#include "llvm/Analysis/DebugInfo.h" using namespace llvm; @@ -399,6 +400,14 @@ void X86MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const { OutMI.setOpcode(X86::MOVZX32rm16); lower_subreg32(&OutMI, 0); break; + case X86::MOV16r0: + OutMI.setOpcode(X86::MOV32r0); + lower_subreg32(&OutMI, 0); + break; + case X86::MOV64r0: + OutMI.setOpcode(X86::MOV32r0); + lower_subreg32(&OutMI, 0); + break; } } @@ -412,6 +421,25 @@ void X86AsmPrinter::printInstructionThroughMCStreamer(const MachineInstr *MI) { case TargetInstrInfo::GC_LABEL: printLabel(MI); return; + case TargetInstrInfo::DEBUG_VALUE: { + if (!VerboseAsm) + return; + O << '\t' << MAI->getCommentString() << "DEBUG_VALUE: "; + // cast away const; DIetc do not take const operands for some reason + DIVariable V((MDNode*)(MI->getOperand(2).getMetadata())); + O << V.getName(); + O << " <- "; + if (MI->getOperand(0).getType()==MachineOperand::MO_Register) + printOperand(MI, 0); + else { + assert(MI->getOperand(0).getType()==MachineOperand::MO_Immediate); + int64_t imm = MI->getOperand(0).getImm(); + O << '[' << ((imm<0) ? "EBP" : "ESP+") << imm << ']'; + } + O << "+"; + printOperand(MI, 1); + return; + } case TargetInstrInfo::INLINEASM: printInlineAsm(MI); return; diff --git a/lib/Target/X86/README-SSE.txt b/lib/Target/X86/README-SSE.txt index 71ad51c..0f3e44b 100644 --- a/lib/Target/X86/README-SSE.txt +++ b/lib/Target/X86/README-SSE.txt @@ -916,3 +916,23 @@ cheaper to do fld1 than load from a constant pool for example, so "load, add 1.0, store" is better done in the fp stack, etc. //===---------------------------------------------------------------------===// + +The X86 backend should be able to if-convert SSE comparisons like "ucomisd" to +"cmpsd". For example, this code: + +double d1(double x) { return x == x ? x : x + x; } + +Compiles into: + +_d1: + ucomisd %xmm0, %xmm0 + jnp LBB1_2 + addsd %xmm0, %xmm0 + ret +LBB1_2: + ret + +Also, the 'ret's should be shared. This is PR6032. + +//===---------------------------------------------------------------------===// + diff --git a/lib/Target/X86/README.txt b/lib/Target/X86/README.txt index afd9f53..aa7bb3d 100644 --- a/lib/Target/X86/README.txt +++ b/lib/Target/X86/README.txt @@ -530,7 +530,7 @@ We should inline lrintf and probably other libc functions. //===---------------------------------------------------------------------===// -Start using the flags more. For example, compile: +Use the FLAGS values from arithmetic instructions more. For example, compile: int add_zf(int *x, int y, int a, int b) { if ((*x += y) == 0) @@ -554,31 +554,8 @@ _add_zf: movl %ecx, %eax ret -and: - -int add_zf(int *x, int y, int a, int b) { - if ((*x + y) < 0) - return a; - else - return b; -} - -to: - -add_zf: - addl (%rdi), %esi - movl %edx, %eax - cmovns %ecx, %eax - ret - -instead of: - -_add_zf: - addl (%rdi), %esi - testl %esi, %esi - cmovs %edx, %ecx - movl %ecx, %eax - ret +As another example, compile function f2 in test/CodeGen/X86/cmp-test.ll +without a test instruction. //===---------------------------------------------------------------------===// @@ -685,55 +662,6 @@ Though this probably isn't worth it. //===---------------------------------------------------------------------===// -We need to teach the codegen to convert two-address INC instructions to LEA -when the flags are dead (likewise dec). For example, on X86-64, compile: - -int foo(int A, int B) { - return A+1; -} - -to: - -_foo: - leal 1(%edi), %eax - ret - -instead of: - -_foo: - incl %edi - movl %edi, %eax - ret - -Another example is: - -;; X's live range extends beyond the shift, so the register allocator -;; cannot coalesce it with Y. Because of this, a copy needs to be -;; emitted before the shift to save the register value before it is -;; clobbered. However, this copy is not needed if the register -;; allocator turns the shift into an LEA. This also occurs for ADD. - -; Check that the shift gets turned into an LEA. -; RUN: llvm-as < %s | llc -march=x86 -x86-asm-syntax=intel | \ -; RUN: not grep {mov E.X, E.X} - -@G = external global i32 ; [#uses=3] - -define i32 @test1(i32 %X, i32 %Y) { - %Z = add i32 %X, %Y ; [#uses=1] - volatile store i32 %Y, i32* @G - volatile store i32 %Z, i32* @G - ret i32 %X -} - -define i32 @test2(i32 %X) { - %Z = add i32 %X, 1 ; [#uses=1] - volatile store i32 %Z, i32* @G - ret i32 %X -} - -//===---------------------------------------------------------------------===// - Sometimes it is better to codegen subtractions from a constant (e.g. 7-x) with a neg instead of a sub instruction. Consider: @@ -854,11 +782,6 @@ __Z11no_overflowjj: //===---------------------------------------------------------------------===// -Re-materialize MOV32r0 etc. with xor instead of changing them to moves if the -condition register is dead. xor reg reg is shorter than mov reg, #0. - -//===---------------------------------------------------------------------===// - The following code: bb114.preheader: ; preds = %cond_next94 diff --git a/lib/Target/X86/X86.td b/lib/Target/X86/X86.td index a6e1ca3..7919559 100644 --- a/lib/Target/X86/X86.td +++ b/lib/Target/X86/X86.td @@ -23,6 +23,7 @@ include "llvm/Target/Target.td" def FeatureCMOV : SubtargetFeature<"cmov","HasCMov", "true", "Enable conditional move instructions">; + def FeatureMMX : SubtargetFeature<"mmx","X86SSELevel", "MMX", "Enable MMX instructions">; def FeatureSSE1 : SubtargetFeature<"sse", "X86SSELevel", "SSE1", @@ -66,6 +67,9 @@ def FeatureFMA3 : SubtargetFeature<"fma3", "HasFMA3", "true", "Enable three-operand fused multiple-add">; def FeatureFMA4 : SubtargetFeature<"fma4", "HasFMA4", "true", "Enable four-operand fused multiple-add">; +def FeatureVectorUAMem : SubtargetFeature<"vector-unaligned-mem", + "HasVectorUAMem", "true", + "Allow unaligned memory operands on vector/SIMD instructions">; //===----------------------------------------------------------------------===// // X86 processors supported. diff --git a/lib/Target/X86/X86CodeEmitter.cpp b/lib/Target/X86/X86CodeEmitter.cpp index 4892e17..828e872 100644 --- a/lib/Target/X86/X86CodeEmitter.cpp +++ b/lib/Target/X86/X86CodeEmitter.cpp @@ -135,7 +135,7 @@ bool Emitter::runOnMachineFunction(MachineFunction &MF) { IsPIC = TM.getRelocationModel() == Reloc::PIC_; do { - DEBUG(errs() << "JITTing function '" + DEBUG(dbgs() << "JITTing function '" << MF.getFunction()->getName() << "'\n"); MCE.startFunction(MF); for (MachineFunction::iterator MBB = MF.begin(), E = MF.end(); @@ -477,7 +477,7 @@ void Emitter::emitMemModRMByte(const MachineInstr &MI, template void Emitter::emitInstruction(const MachineInstr &MI, const TargetInstrDesc *Desc) { - DEBUG(errs() << MI); + DEBUG(dbgs() << MI); MCE.processDebugLoc(MI.getDebugLoc(), true); @@ -618,11 +618,11 @@ void Emitter::emitInstruction(const MachineInstr &MI, const MachineOperand &MO = MI.getOperand(CurOp++); - DEBUG(errs() << "RawFrm CurOp " << CurOp << "\n"); - DEBUG(errs() << "isMBB " << MO.isMBB() << "\n"); - DEBUG(errs() << "isGlobal " << MO.isGlobal() << "\n"); - DEBUG(errs() << "isSymbol " << MO.isSymbol() << "\n"); - DEBUG(errs() << "isImm " << MO.isImm() << "\n"); + DEBUG(dbgs() << "RawFrm CurOp " << CurOp << "\n"); + DEBUG(dbgs() << "isMBB " << MO.isMBB() << "\n"); + DEBUG(dbgs() << "isGlobal " << MO.isGlobal() << "\n"); + DEBUG(dbgs() << "isSymbol " << MO.isSymbol() << "\n"); + DEBUG(dbgs() << "isImm " << MO.isImm() << "\n"); if (MO.isMBB()) { emitPCRelativeBlockAddress(MO.getMBB()); @@ -843,7 +843,7 @@ void Emitter::emitInstruction(const MachineInstr &MI, if (!Desc->isVariadic() && CurOp != NumOps) { #ifndef NDEBUG - errs() << "Cannot encode all operands of: " << MI << "\n"; + dbgs() << "Cannot encode all operands of: " << MI << "\n"; #endif llvm_unreachable(0); } @@ -1082,9 +1082,9 @@ public: } if (!OK) { - errs() << "couldn't convert inst '"; + dbgs() << "couldn't convert inst '"; MI.dump(); - errs() << "' to machine instr:\n"; + dbgs() << "' to machine instr:\n"; Instr->dump(); } diff --git a/lib/Target/X86/X86FastISel.cpp b/lib/Target/X86/X86FastISel.cpp index 431c120..7e02d59 100644 --- a/lib/Target/X86/X86FastISel.cpp +++ b/lib/Target/X86/X86FastISel.cpp @@ -786,8 +786,8 @@ bool X86FastISel::X86SelectCmp(Instruction *I) { bool X86FastISel::X86SelectZExt(Instruction *I) { // Handle zero-extension from i1 to i8, which is common. - if (I->getType() == Type::getInt8Ty(I->getContext()) && - I->getOperand(0)->getType() == Type::getInt1Ty(I->getContext())) { + if (I->getType()->isInteger(8) && + I->getOperand(0)->getType()->isInteger(1)) { unsigned ResultReg = getRegForValue(I->getOperand(0)); if (ResultReg == 0) return false; // Set the high bits to zero. @@ -948,7 +948,7 @@ bool X86FastISel::X86SelectBranch(Instruction *I) { bool X86FastISel::X86SelectShift(Instruction *I) { unsigned CReg = 0, OpReg = 0, OpImm = 0; const TargetRegisterClass *RC = NULL; - if (I->getType() == Type::getInt8Ty(I->getContext())) { + if (I->getType()->isInteger(8)) { CReg = X86::CL; RC = &X86::GR8RegClass; switch (I->getOpcode()) { @@ -957,7 +957,7 @@ bool X86FastISel::X86SelectShift(Instruction *I) { case Instruction::Shl: OpReg = X86::SHL8rCL; OpImm = X86::SHL8ri; break; default: return false; } - } else if (I->getType() == Type::getInt16Ty(I->getContext())) { + } else if (I->getType()->isInteger(16)) { CReg = X86::CX; RC = &X86::GR16RegClass; switch (I->getOpcode()) { @@ -966,7 +966,7 @@ bool X86FastISel::X86SelectShift(Instruction *I) { case Instruction::Shl: OpReg = X86::SHL16rCL; OpImm = X86::SHL16ri; break; default: return false; } - } else if (I->getType() == Type::getInt32Ty(I->getContext())) { + } else if (I->getType()->isInteger(32)) { CReg = X86::ECX; RC = &X86::GR32RegClass; switch (I->getOpcode()) { @@ -975,7 +975,7 @@ bool X86FastISel::X86SelectShift(Instruction *I) { case Instruction::Shl: OpReg = X86::SHL32rCL; OpImm = X86::SHL32ri; break; default: return false; } - } else if (I->getType() == Type::getInt64Ty(I->getContext())) { + } else if (I->getType()->isInteger(64)) { CReg = X86::RCX; RC = &X86::GR64RegClass; switch (I->getOpcode()) { @@ -1230,8 +1230,8 @@ bool X86FastISel::X86SelectCall(Instruction *I) { CC != CallingConv::X86_FastCall) return false; - // On X86, -tailcallopt changes the fastcc ABI. FastISel doesn't - // handle this for now. + // fastcc with -tailcallopt is intended to provide a guaranteed + // tail call optimization. Fastisel doesn't know how to do that. if (CC == CallingConv::Fast && PerformTailCallOpt) return false; diff --git a/lib/Target/X86/X86FloatingPoint.cpp b/lib/Target/X86/X86FloatingPoint.cpp index 044bd4b..503ac14 100644 --- a/lib/Target/X86/X86FloatingPoint.cpp +++ b/lib/Target/X86/X86FloatingPoint.cpp @@ -75,12 +75,12 @@ namespace { unsigned StackTop; // The current top of the FP stack. void dumpStack() const { - errs() << "Stack contents:"; + dbgs() << "Stack contents:"; for (unsigned i = 0; i != StackTop; ++i) { - errs() << " FP" << Stack[i]; + dbgs() << " FP" << Stack[i]; assert(RegMap[Stack[i]] == i && "Stack[] doesn't match RegMap[]!"); } - errs() << "\n"; + dbgs() << "\n"; } private: /// isStackEmpty - Return true if the FP stack is empty. @@ -246,7 +246,7 @@ bool FPS::processBasicBlock(MachineFunction &MF, MachineBasicBlock &BB) { PrevMI = prior(I); ++NumFP; // Keep track of # of pseudo instrs - DEBUG(errs() << "\nFPInst:\t" << *MI); + DEBUG(dbgs() << "\nFPInst:\t" << *MI); // Get dead variables list now because the MI pointer may be deleted as part // of processing! @@ -273,7 +273,7 @@ bool FPS::processBasicBlock(MachineFunction &MF, MachineBasicBlock &BB) { for (unsigned i = 0, e = DeadRegs.size(); i != e; ++i) { unsigned Reg = DeadRegs[i]; if (Reg >= X86::FP0 && Reg <= X86::FP6) { - DEBUG(errs() << "Register FP#" << Reg-X86::FP0 << " is dead!\n"); + DEBUG(dbgs() << "Register FP#" << Reg-X86::FP0 << " is dead!\n"); freeStackSlotAfter(I, Reg-X86::FP0); } } @@ -282,13 +282,13 @@ bool FPS::processBasicBlock(MachineFunction &MF, MachineBasicBlock &BB) { DEBUG( MachineBasicBlock::iterator PrevI(PrevMI); if (I == PrevI) { - errs() << "Just deleted pseudo instruction\n"; + dbgs() << "Just deleted pseudo instruction\n"; } else { MachineBasicBlock::iterator Start = I; // Rewind to first instruction newly inserted. while (Start != BB.begin() && prior(Start) != PrevI) --Start; - errs() << "Inserted instructions:\n\t"; - Start->print(errs(), &MF.getTarget()); + dbgs() << "Inserted instructions:\n\t"; + Start->print(dbgs(), &MF.getTarget()); while (++Start != llvm::next(I)) {} } dumpStack(); diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp index cb82383..e2a53d1 100644 --- a/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -113,37 +113,37 @@ namespace { } void dump() { - errs() << "X86ISelAddressMode " << this << '\n'; - errs() << "Base.Reg "; + dbgs() << "X86ISelAddressMode " << this << '\n'; + dbgs() << "Base.Reg "; if (Base.Reg.getNode() != 0) Base.Reg.getNode()->dump(); else - errs() << "nul"; - errs() << " Base.FrameIndex " << Base.FrameIndex << '\n' + dbgs() << "nul"; + dbgs() << " Base.FrameIndex " << Base.FrameIndex << '\n' << " Scale" << Scale << '\n' << "IndexReg "; if (IndexReg.getNode() != 0) IndexReg.getNode()->dump(); else - errs() << "nul"; - errs() << " Disp " << Disp << '\n' + dbgs() << "nul"; + dbgs() << " Disp " << Disp << '\n' << "GV "; if (GV) GV->dump(); else - errs() << "nul"; - errs() << " CP "; + dbgs() << "nul"; + dbgs() << " CP "; if (CP) CP->dump(); else - errs() << "nul"; - errs() << '\n' + dbgs() << "nul"; + dbgs() << '\n' << "ES "; if (ES) - errs() << ES; + dbgs() << ES; else - errs() << "nul"; - errs() << " JT" << JT << " Align" << Align << '\n'; + dbgs() << "nul"; + dbgs() << " JT" << JT << " Align" << Align << '\n'; } }; } @@ -190,7 +190,7 @@ namespace { #include "X86GenDAGISel.inc" private: - SDNode *Select(SDValue N); + SDNode *Select(SDNode *N); SDNode *SelectAtomic64(SDNode *Node, unsigned Opc); SDNode *SelectAtomicLoadAdd(SDNode *Node, EVT NVT); @@ -201,19 +201,19 @@ namespace { bool MatchAddressRecursively(SDValue N, X86ISelAddressMode &AM, unsigned Depth); bool MatchAddressBase(SDValue N, X86ISelAddressMode &AM); - bool SelectAddr(SDValue Op, SDValue N, SDValue &Base, + bool SelectAddr(SDNode *Op, SDValue N, SDValue &Base, SDValue &Scale, SDValue &Index, SDValue &Disp, SDValue &Segment); - bool SelectLEAAddr(SDValue Op, SDValue N, SDValue &Base, + bool SelectLEAAddr(SDNode *Op, SDValue N, SDValue &Base, SDValue &Scale, SDValue &Index, SDValue &Disp); - bool SelectTLSADDRAddr(SDValue Op, SDValue N, SDValue &Base, + bool SelectTLSADDRAddr(SDNode *Op, SDValue N, SDValue &Base, SDValue &Scale, SDValue &Index, SDValue &Disp); - bool SelectScalarSSELoad(SDValue Op, SDValue Pred, + bool SelectScalarSSELoad(SDNode *Op, SDValue Pred, SDValue N, SDValue &Base, SDValue &Scale, SDValue &Index, SDValue &Disp, SDValue &Segment, SDValue &InChain, SDValue &OutChain); - bool TryFoldLoad(SDValue P, SDValue N, + bool TryFoldLoad(SDNode *P, SDValue N, SDValue &Base, SDValue &Scale, SDValue &Index, SDValue &Disp, SDValue &Segment); @@ -310,6 +310,11 @@ bool X86DAGToDAGISel::IsLegalAndProfitableToFold(SDNode *N, SDNode *U, if (U == Root) switch (U->getOpcode()) { default: break; + case X86ISD::ADD: + case X86ISD::SUB: + case X86ISD::AND: + case X86ISD::XOR: + case X86ISD::OR: case ISD::ADD: case ISD::ADDC: case ISD::ADDE: @@ -675,12 +680,12 @@ void X86DAGToDAGISel::InstructionSelect() { // Codegen the basic block. #ifndef NDEBUG - DEBUG(errs() << "===== Instruction selection begins:\n"); + DEBUG(dbgs() << "===== Instruction selection begins:\n"); Indent = 0; #endif SelectRoot(*CurDAG); #ifndef NDEBUG - DEBUG(errs() << "===== Instruction selection ends:\n"); + DEBUG(dbgs() << "===== Instruction selection ends:\n"); #endif CurDAG->RemoveDeadNodes(); @@ -850,7 +855,7 @@ bool X86DAGToDAGISel::MatchAddressRecursively(SDValue N, X86ISelAddressMode &AM, bool is64Bit = Subtarget->is64Bit(); DebugLoc dl = N.getDebugLoc(); DEBUG({ - errs() << "MatchAddress: "; + dbgs() << "MatchAddress: "; AM.dump(); }); // Limit recursion. @@ -1268,7 +1273,7 @@ bool X86DAGToDAGISel::MatchAddressBase(SDValue N, X86ISelAddressMode &AM) { /// SelectAddr - returns true if it is able pattern match an addressing mode. /// It returns the operands which make up the maximal addressing mode it can /// match by reference. -bool X86DAGToDAGISel::SelectAddr(SDValue Op, SDValue N, SDValue &Base, +bool X86DAGToDAGISel::SelectAddr(SDNode *Op, SDValue N, SDValue &Base, SDValue &Scale, SDValue &Index, SDValue &Disp, SDValue &Segment) { X86ISelAddressMode AM; @@ -1291,7 +1296,7 @@ bool X86DAGToDAGISel::SelectAddr(SDValue Op, SDValue N, SDValue &Base, /// SelectScalarSSELoad - Match a scalar SSE load. In particular, we want to /// match a load whose top elements are either undef or zeros. The load flavor /// is derived from the type of N, which is either v4f32 or v2f64. -bool X86DAGToDAGISel::SelectScalarSSELoad(SDValue Op, SDValue Pred, +bool X86DAGToDAGISel::SelectScalarSSELoad(SDNode *Op, SDValue Pred, SDValue N, SDValue &Base, SDValue &Scale, SDValue &Index, SDValue &Disp, SDValue &Segment, @@ -1302,7 +1307,7 @@ bool X86DAGToDAGISel::SelectScalarSSELoad(SDValue Op, SDValue Pred, if (ISD::isNON_EXTLoad(InChain.getNode()) && InChain.getValue(0).hasOneUse() && N.hasOneUse() && - IsLegalAndProfitableToFold(N.getNode(), Pred.getNode(), Op.getNode())) { + IsLegalAndProfitableToFold(N.getNode(), Pred.getNode(), Op)) { LoadSDNode *LD = cast(InChain); if (!SelectAddr(Op, LD->getBasePtr(), Base, Scale, Index, Disp, Segment)) return false; @@ -1333,7 +1338,7 @@ bool X86DAGToDAGISel::SelectScalarSSELoad(SDValue Op, SDValue Pred, /// SelectLEAAddr - it calls SelectAddr and determines if the maximal addressing /// mode it matches can be cost effectively emitted as an LEA instruction. -bool X86DAGToDAGISel::SelectLEAAddr(SDValue Op, SDValue N, +bool X86DAGToDAGISel::SelectLEAAddr(SDNode *Op, SDValue N, SDValue &Base, SDValue &Scale, SDValue &Index, SDValue &Disp) { X86ISelAddressMode AM; @@ -1395,10 +1400,10 @@ bool X86DAGToDAGISel::SelectLEAAddr(SDValue Op, SDValue N, } /// SelectTLSADDRAddr - This is only run on TargetGlobalTLSAddress nodes. -bool X86DAGToDAGISel::SelectTLSADDRAddr(SDValue Op, SDValue N, SDValue &Base, +bool X86DAGToDAGISel::SelectTLSADDRAddr(SDNode *Op, SDValue N, SDValue &Base, SDValue &Scale, SDValue &Index, SDValue &Disp) { - assert(Op.getOpcode() == X86ISD::TLSADDR); + assert(Op->getOpcode() == X86ISD::TLSADDR); assert(N.getOpcode() == ISD::TargetGlobalTLSAddress); const GlobalAddressSDNode *GA = cast(N); @@ -1421,13 +1426,13 @@ bool X86DAGToDAGISel::SelectTLSADDRAddr(SDValue Op, SDValue N, SDValue &Base, } -bool X86DAGToDAGISel::TryFoldLoad(SDValue P, SDValue N, +bool X86DAGToDAGISel::TryFoldLoad(SDNode *P, SDValue N, SDValue &Base, SDValue &Scale, SDValue &Index, SDValue &Disp, SDValue &Segment) { if (ISD::isNON_EXTLoad(N.getNode()) && N.hasOneUse() && - IsLegalAndProfitableToFold(N.getNode(), P.getNode(), P.getNode())) + IsLegalAndProfitableToFold(N.getNode(), P, P)) return SelectAddr(P, N.getOperand(1), Base, Scale, Index, Disp, Segment); return false; } @@ -1454,7 +1459,7 @@ SDNode *X86DAGToDAGISel::SelectAtomic64(SDNode *Node, unsigned Opc) { SDValue In2L = Node->getOperand(2); SDValue In2H = Node->getOperand(3); SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4; - if (!SelectAddr(In1, In1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) + if (!SelectAddr(In1.getNode(), In1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) return NULL; MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); MemOp[0] = cast(Node)->getMemOperand(); @@ -1480,7 +1485,7 @@ SDNode *X86DAGToDAGISel::SelectAtomicLoadAdd(SDNode *Node, EVT NVT) { SDValue Ptr = Node->getOperand(1); SDValue Val = Node->getOperand(2); SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4; - if (!SelectAddr(Ptr, Ptr, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) + if (!SelectAddr(Ptr.getNode(), Ptr, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) return 0; bool isInc = false, isDec = false, isSub = false, isCN = false; @@ -1678,8 +1683,7 @@ static bool HasNoSignedComparisonUses(SDNode *N) { return true; } -SDNode *X86DAGToDAGISel::Select(SDValue N) { - SDNode *Node = N.getNode(); +SDNode *X86DAGToDAGISel::Select(SDNode *Node) { EVT NVT = Node->getValueType(0); unsigned Opc, MOpc; unsigned Opcode = Node->getOpcode(); @@ -1687,9 +1691,9 @@ SDNode *X86DAGToDAGISel::Select(SDValue N) { #ifndef NDEBUG DEBUG({ - errs() << std::string(Indent, ' ') << "Selecting: "; + dbgs() << std::string(Indent, ' ') << "Selecting: "; Node->dump(CurDAG); - errs() << '\n'; + dbgs() << '\n'; }); Indent += 2; #endif @@ -1697,9 +1701,9 @@ SDNode *X86DAGToDAGISel::Select(SDValue N) { if (Node->isMachineOpcode()) { #ifndef NDEBUG DEBUG({ - errs() << std::string(Indent-2, ' ') << "== "; + dbgs() << std::string(Indent-2, ' ') << "== "; Node->dump(CurDAG); - errs() << '\n'; + dbgs() << '\n'; }); Indent -= 2; #endif @@ -1767,10 +1771,10 @@ SDNode *X86DAGToDAGISel::Select(SDValue N) { } SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4; - bool foldedLoad = TryFoldLoad(N, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4); + bool foldedLoad = TryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4); // Multiply is commmutative. if (!foldedLoad) { - foldedLoad = TryFoldLoad(N, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4); + foldedLoad = TryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4); if (foldedLoad) std::swap(N0, N1); } @@ -1793,21 +1797,21 @@ SDNode *X86DAGToDAGISel::Select(SDValue N) { } // Copy the low half of the result, if it is needed. - if (!N.getValue(0).use_empty()) { + if (!SDValue(Node, 0).use_empty()) { SDValue Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl, LoReg, NVT, InFlag); InFlag = Result.getValue(2); - ReplaceUses(N.getValue(0), Result); + ReplaceUses(SDValue(Node, 0), Result); #ifndef NDEBUG DEBUG({ - errs() << std::string(Indent-2, ' ') << "=> "; + dbgs() << std::string(Indent-2, ' ') << "=> "; Result.getNode()->dump(CurDAG); - errs() << '\n'; + dbgs() << '\n'; }); #endif } // Copy the high half of the result, if it is needed. - if (!N.getValue(1).use_empty()) { + if (!SDValue(Node, 1).use_empty()) { SDValue Result; if (HiReg == X86::AH && Subtarget->is64Bit()) { // Prevent use of AH in a REX instruction by referencing AX instead. @@ -1826,12 +1830,12 @@ SDNode *X86DAGToDAGISel::Select(SDValue N) { HiReg, NVT, InFlag); InFlag = Result.getValue(2); } - ReplaceUses(N.getValue(1), Result); + ReplaceUses(SDValue(Node, 1), Result); #ifndef NDEBUG DEBUG({ - errs() << std::string(Indent-2, ' ') << "=> "; + dbgs() << std::string(Indent-2, ' ') << "=> "; Result.getNode()->dump(CurDAG); - errs() << '\n'; + dbgs() << '\n'; }); #endif } @@ -1869,7 +1873,6 @@ SDNode *X86DAGToDAGISel::Select(SDValue N) { unsigned LoReg, HiReg, ClrReg; unsigned ClrOpcode, SExtOpcode; - EVT ClrVT = NVT; switch (NVT.getSimpleVT().SimpleTy) { default: llvm_unreachable("Unsupported VT!"); case MVT::i8: @@ -1879,7 +1882,7 @@ SDNode *X86DAGToDAGISel::Select(SDValue N) { break; case MVT::i16: LoReg = X86::AX; HiReg = X86::DX; - ClrOpcode = X86::MOV32r0; ClrReg = X86::EDX; ClrVT = MVT::i32; + ClrOpcode = X86::MOV16r0; ClrReg = X86::DX; SExtOpcode = X86::CWD; break; case MVT::i32: @@ -1889,13 +1892,13 @@ SDNode *X86DAGToDAGISel::Select(SDValue N) { break; case MVT::i64: LoReg = X86::RAX; ClrReg = HiReg = X86::RDX; - ClrOpcode = ~0U; // NOT USED. + ClrOpcode = X86::MOV64r0; SExtOpcode = X86::CQO; break; } SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4; - bool foldedLoad = TryFoldLoad(N, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4); + bool foldedLoad = TryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4); bool signBitIsZero = CurDAG->SignBitIsZero(N0); SDValue InFlag; @@ -1903,7 +1906,7 @@ SDNode *X86DAGToDAGISel::Select(SDValue N) { // Special case for div8, just use a move with zero extension to AX to // clear the upper 8 bits (AH). SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, Move, Chain; - if (TryFoldLoad(N, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) { + if (TryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) { SDValue Ops[] = { Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, N0.getOperand(0) }; Move = SDValue(CurDAG->getMachineNode(X86::MOVZX16rm8, dl, MVT::i16, @@ -1928,24 +1931,8 @@ SDNode *X86DAGToDAGISel::Select(SDValue N) { SDValue(CurDAG->getMachineNode(SExtOpcode, dl, MVT::Flag, InFlag),0); } else { // Zero out the high part, effectively zero extending the input. - SDValue ClrNode; - - if (NVT.getSimpleVT() == MVT::i64) { - ClrNode = SDValue(CurDAG->getMachineNode(X86::MOV32r0, dl, MVT::i32), - 0); - // We just did a 32-bit clear, insert it into a 64-bit register to - // clear the whole 64-bit reg. - SDValue Zero = CurDAG->getTargetConstant(0, MVT::i64); - SDValue SubRegNo = - CurDAG->getTargetConstant(X86::SUBREG_32BIT, MVT::i32); - ClrNode = - SDValue(CurDAG->getMachineNode(TargetInstrInfo::SUBREG_TO_REG, dl, - MVT::i64, Zero, ClrNode, SubRegNo), - 0); - } else { - ClrNode = SDValue(CurDAG->getMachineNode(ClrOpcode, dl, ClrVT), 0); - } - + SDValue ClrNode = + SDValue(CurDAG->getMachineNode(ClrOpcode, dl, NVT), 0); InFlag = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, ClrReg, ClrNode, InFlag).getValue(1); } @@ -1966,21 +1953,21 @@ SDNode *X86DAGToDAGISel::Select(SDValue N) { } // Copy the division (low) result, if it is needed. - if (!N.getValue(0).use_empty()) { + if (!SDValue(Node, 0).use_empty()) { SDValue Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl, LoReg, NVT, InFlag); InFlag = Result.getValue(2); - ReplaceUses(N.getValue(0), Result); + ReplaceUses(SDValue(Node, 0), Result); #ifndef NDEBUG DEBUG({ - errs() << std::string(Indent-2, ' ') << "=> "; + dbgs() << std::string(Indent-2, ' ') << "=> "; Result.getNode()->dump(CurDAG); - errs() << '\n'; + dbgs() << '\n'; }); #endif } // Copy the remainder (high) result, if it is needed. - if (!N.getValue(1).use_empty()) { + if (!SDValue(Node, 1).use_empty()) { SDValue Result; if (HiReg == X86::AH && Subtarget->is64Bit()) { // Prevent use of AH in a REX instruction by referencing AX instead. @@ -2000,12 +1987,12 @@ SDNode *X86DAGToDAGISel::Select(SDValue N) { HiReg, NVT, InFlag); InFlag = Result.getValue(2); } - ReplaceUses(N.getValue(1), Result); + ReplaceUses(SDValue(Node, 1), Result); #ifndef NDEBUG DEBUG({ - errs() << std::string(Indent-2, ' ') << "=> "; + dbgs() << std::string(Indent-2, ' ') << "=> "; Result.getNode()->dump(CurDAG); - errs() << '\n'; + dbgs() << '\n'; }); #endif } @@ -2124,16 +2111,16 @@ SDNode *X86DAGToDAGISel::Select(SDValue N) { } } - SDNode *ResNode = SelectCode(N); + SDNode *ResNode = SelectCode(Node); #ifndef NDEBUG DEBUG({ - errs() << std::string(Indent-2, ' ') << "=> "; - if (ResNode == NULL || ResNode == N.getNode()) - N.getNode()->dump(CurDAG); + dbgs() << std::string(Indent-2, ' ') << "=> "; + if (ResNode == NULL || ResNode == Node) + Node->dump(CurDAG); else ResNode->dump(CurDAG); - errs() << '\n'; + dbgs() << '\n'; }); Indent -= 2; #endif @@ -2150,7 +2137,7 @@ SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode, case 'v': // not offsetable ?? default: return true; case 'm': // memory - if (!SelectAddr(Op, Op, Op0, Op1, Op2, Op3, Op4)) + if (!SelectAddr(Op.getNode(), Op, Op0, Op1, Op2, Op3, Op4)) return true; break; } diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index c722fbf..228ec9f 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -978,6 +978,7 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM) setTargetDAGCombine(ISD::SHL); setTargetDAGCombine(ISD::SRA); setTargetDAGCombine(ISD::SRL); + setTargetDAGCombine(ISD::OR); setTargetDAGCombine(ISD::STORE); setTargetDAGCombine(ISD::MEMBARRIER); setTargetDAGCombine(ISD::ZERO_EXTEND); @@ -2077,10 +2078,10 @@ X86TargetLowering::LowerCall(SDValue Chain, SDValue Callee, assert(((Callee.getOpcode() == ISD::Register && (cast(Callee)->getReg() == X86::EAX || - cast(Callee)->getReg() == X86::R9)) || + cast(Callee)->getReg() == X86::R11)) || Callee.getOpcode() == ISD::TargetExternalSymbol || Callee.getOpcode() == ISD::TargetGlobalAddress) && - "Expecting an global address, external symbol, or register"); + "Expecting a global address, external symbol, or scratch register"); return DAG.getNode(X86ISD::TC_RETURN, dl, NodeTys, &Ops[0], Ops.size()); @@ -5610,13 +5611,21 @@ SDValue X86TargetLowering::EmitTest(SDValue Op, unsigned X86CC, // because a TEST instruction will be better. bool NonFlagUse = false; for (SDNode::use_iterator UI = Op.getNode()->use_begin(), - UE = Op.getNode()->use_end(); UI != UE; ++UI) - if (UI->getOpcode() != ISD::BRCOND && - UI->getOpcode() != ISD::SELECT && - UI->getOpcode() != ISD::SETCC) { + UE = Op.getNode()->use_end(); UI != UE; ++UI) { + SDNode *User = *UI; + unsigned UOpNo = UI.getOperandNo(); + if (User->getOpcode() == ISD::TRUNCATE && User->hasOneUse()) { + // Look pass truncate. + UOpNo = User->use_begin().getOperandNo(); + User = *User->use_begin(); + } + if (User->getOpcode() != ISD::BRCOND && + User->getOpcode() != ISD::SETCC && + (User->getOpcode() != ISD::SELECT || UOpNo != 0)) { NonFlagUse = true; break; } + } if (!NonFlagUse) break; } @@ -5680,6 +5689,56 @@ SDValue X86TargetLowering::EmitCmp(SDValue Op0, SDValue Op1, unsigned X86CC, return DAG.getNode(X86ISD::CMP, dl, MVT::i32, Op0, Op1); } +/// LowerToBT - Result of 'and' is compared against zero. Turn it into a BT node +/// if it's possible. +static SDValue LowerToBT(SDValue Op0, ISD::CondCode CC, + DebugLoc dl, SelectionDAG &DAG) { + SDValue LHS, RHS; + if (Op0.getOperand(1).getOpcode() == ISD::SHL) { + if (ConstantSDNode *Op010C = + dyn_cast(Op0.getOperand(1).getOperand(0))) + if (Op010C->getZExtValue() == 1) { + LHS = Op0.getOperand(0); + RHS = Op0.getOperand(1).getOperand(1); + } + } else if (Op0.getOperand(0).getOpcode() == ISD::SHL) { + if (ConstantSDNode *Op000C = + dyn_cast(Op0.getOperand(0).getOperand(0))) + if (Op000C->getZExtValue() == 1) { + LHS = Op0.getOperand(1); + RHS = Op0.getOperand(0).getOperand(1); + } + } else if (Op0.getOperand(1).getOpcode() == ISD::Constant) { + ConstantSDNode *AndRHS = cast(Op0.getOperand(1)); + SDValue AndLHS = Op0.getOperand(0); + if (AndRHS->getZExtValue() == 1 && AndLHS.getOpcode() == ISD::SRL) { + LHS = AndLHS.getOperand(0); + RHS = AndLHS.getOperand(1); + } + } + + if (LHS.getNode()) { + // If LHS is i8, promote it to i16 with any_extend. There is no i8 BT + // instruction. Since the shift amount is in-range-or-undefined, we know + // that doing a bittest on the i16 value is ok. We extend to i32 because + // the encoding for the i16 version is larger than the i32 version. + if (LHS.getValueType() == MVT::i8) + LHS = DAG.getNode(ISD::ANY_EXTEND, dl, MVT::i32, LHS); + + // If the operand types disagree, extend the shift amount to match. Since + // BT ignores high bits (like shifts) we can use anyextend. + if (LHS.getValueType() != RHS.getValueType()) + RHS = DAG.getNode(ISD::ANY_EXTEND, dl, LHS.getValueType(), RHS); + + SDValue BT = DAG.getNode(X86ISD::BT, dl, MVT::i32, LHS, RHS); + unsigned Cond = CC == ISD::SETEQ ? X86::COND_AE : X86::COND_B; + return DAG.getNode(X86ISD::SETCC, dl, MVT::i8, + DAG.getConstant(Cond, MVT::i8), BT); + } + + return SDValue(); +} + SDValue X86TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) { assert(Op.getValueType() == MVT::i8 && "SetCC type must be 8-bit integer"); SDValue Op0 = Op.getOperand(0); @@ -5687,6 +5746,7 @@ SDValue X86TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) { DebugLoc dl = Op.getDebugLoc(); ISD::CondCode CC = cast(Op.getOperand(2))->get(); + // Optimize to BT if possible. // Lower (X & (1 << N)) == 0 to BT(X, N). // Lower ((X >>u N) & 1) != 0 to BT(X, N). // Lower ((X >>s N) & 1) != 0 to BT(X, N). @@ -5695,48 +5755,9 @@ SDValue X86TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) { Op1.getOpcode() == ISD::Constant && cast(Op1)->getZExtValue() == 0 && (CC == ISD::SETEQ || CC == ISD::SETNE)) { - SDValue LHS, RHS; - if (Op0.getOperand(1).getOpcode() == ISD::SHL) { - if (ConstantSDNode *Op010C = - dyn_cast(Op0.getOperand(1).getOperand(0))) - if (Op010C->getZExtValue() == 1) { - LHS = Op0.getOperand(0); - RHS = Op0.getOperand(1).getOperand(1); - } - } else if (Op0.getOperand(0).getOpcode() == ISD::SHL) { - if (ConstantSDNode *Op000C = - dyn_cast(Op0.getOperand(0).getOperand(0))) - if (Op000C->getZExtValue() == 1) { - LHS = Op0.getOperand(1); - RHS = Op0.getOperand(0).getOperand(1); - } - } else if (Op0.getOperand(1).getOpcode() == ISD::Constant) { - ConstantSDNode *AndRHS = cast(Op0.getOperand(1)); - SDValue AndLHS = Op0.getOperand(0); - if (AndRHS->getZExtValue() == 1 && AndLHS.getOpcode() == ISD::SRL) { - LHS = AndLHS.getOperand(0); - RHS = AndLHS.getOperand(1); - } - } - - if (LHS.getNode()) { - // If LHS is i8, promote it to i16 with any_extend. There is no i8 BT - // instruction. Since the shift amount is in-range-or-undefined, we know - // that doing a bittest on the i16 value is ok. We extend to i32 because - // the encoding for the i16 version is larger than the i32 version. - if (LHS.getValueType() == MVT::i8) - LHS = DAG.getNode(ISD::ANY_EXTEND, dl, MVT::i32, LHS); - - // If the operand types disagree, extend the shift amount to match. Since - // BT ignores high bits (like shifts) we can use anyextend. - if (LHS.getValueType() != RHS.getValueType()) - RHS = DAG.getNode(ISD::ANY_EXTEND, dl, LHS.getValueType(), RHS); - - SDValue BT = DAG.getNode(X86ISD::BT, dl, MVT::i32, LHS, RHS); - unsigned Cond = CC == ISD::SETEQ ? X86::COND_AE : X86::COND_B; - return DAG.getNode(X86ISD::SETCC, dl, MVT::i8, - DAG.getConstant(Cond, MVT::i8), BT); - } + SDValue NewSetCC = LowerToBT(Op0, CC, dl, DAG); + if (NewSetCC.getNode()) + return NewSetCC; } bool isFP = Op.getOperand(1).getValueType().isFloatingPoint(); @@ -5936,6 +5957,23 @@ SDValue X86TargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) { } if (addTest) { + // Look pass the truncate. + if (Cond.getOpcode() == ISD::TRUNCATE) + Cond = Cond.getOperand(0); + + // We know the result of AND is compared against zero. Try to match + // it to BT. + if (Cond.getOpcode() == ISD::AND && Cond.hasOneUse()) { + SDValue NewSetCC = LowerToBT(Cond, ISD::SETNE, dl, DAG); + if (NewSetCC.getNode()) { + CC = NewSetCC.getOperand(0); + Cond = NewSetCC.getOperand(1); + addTest = false; + } + } + } + + if (addTest) { CC = DAG.getConstant(X86::COND_NE, MVT::i8); Cond = EmitTest(Cond, X86::COND_NE, DAG); } @@ -6093,6 +6131,23 @@ SDValue X86TargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) { } if (addTest) { + // Look pass the truncate. + if (Cond.getOpcode() == ISD::TRUNCATE) + Cond = Cond.getOperand(0); + + // We know the result of AND is compared against zero. Try to match + // it to BT. + if (Cond.getOpcode() == ISD::AND && Cond.hasOneUse()) { + SDValue NewSetCC = LowerToBT(Cond, ISD::SETNE, dl, DAG); + if (NewSetCC.getNode()) { + CC = NewSetCC.getOperand(0); + Cond = NewSetCC.getOperand(1); + addTest = false; + } + } + } + + if (addTest) { CC = DAG.getConstant(X86::COND_NE, MVT::i8); Cond = EmitTest(Cond, X86::COND_NE, DAG); } @@ -7524,8 +7579,7 @@ bool X86TargetLowering::isTruncateFree(EVT VT1, EVT VT2) const { bool X86TargetLowering::isZExtFree(const Type *Ty1, const Type *Ty2) const { // x86-64 implicitly zero-extends 32-bit results in 64-bit registers. - return Ty1 == Type::getInt32Ty(Ty1->getContext()) && - Ty2 == Type::getInt64Ty(Ty1->getContext()) && Subtarget->is64Bit(); + return Ty1->isInteger(64) && Ty2->isInteger(64) && Subtarget->is64Bit(); } bool X86TargetLowering::isZExtFree(EVT VT1, EVT VT2) const { @@ -7749,7 +7803,7 @@ X86TargetLowering::EmitAtomicBit6432WithCustomInserter(MachineInstr *bInstr, for (int i=0; i < 2 + X86AddrNumOperands; ++i) argOpers[i] = &bInstr->getOperand(i+2); - // x86 address has 4 operands: base, index, scale, and displacement + // x86 address has 5 operands: base, index, scale, displacement, and segment. int lastAddrIndx = X86AddrNumOperands - 1; // [0,3] unsigned t1 = F->getRegInfo().createVirtualRegister(RC); @@ -7777,14 +7831,16 @@ X86TargetLowering::EmitAtomicBit6432WithCustomInserter(MachineInstr *bInstr, BuildMI(newMBB, dl, TII->get(X86::PHI), dest2Oper.getReg()) .addReg(t2).addMBB(thisMBB).addReg(t4).addMBB(newMBB); - unsigned tt1 = F->getRegInfo().createVirtualRegister(RC); - unsigned tt2 = F->getRegInfo().createVirtualRegister(RC); + // The subsequent operations should be using the destination registers of + //the PHI instructions. if (invSrc) { - MIB = BuildMI(newMBB, dl, TII->get(NotOpc), tt1).addReg(t1); - MIB = BuildMI(newMBB, dl, TII->get(NotOpc), tt2).addReg(t2); + t1 = F->getRegInfo().createVirtualRegister(RC); + t2 = F->getRegInfo().createVirtualRegister(RC); + MIB = BuildMI(newMBB, dl, TII->get(NotOpc), t1).addReg(dest1Oper.getReg()); + MIB = BuildMI(newMBB, dl, TII->get(NotOpc), t2).addReg(dest2Oper.getReg()); } else { - tt1 = t1; - tt2 = t2; + t1 = dest1Oper.getReg(); + t2 = dest2Oper.getReg(); } int valArgIndx = lastAddrIndx + 1; @@ -7798,7 +7854,7 @@ X86TargetLowering::EmitAtomicBit6432WithCustomInserter(MachineInstr *bInstr, else MIB = BuildMI(newMBB, dl, TII->get(immOpcL), t5); if (regOpcL != X86::MOV32rr) - MIB.addReg(tt1); + MIB.addReg(t1); (*MIB).addOperand(*argOpers[valArgIndx]); assert(argOpers[valArgIndx + 1]->isReg() == argOpers[valArgIndx]->isReg()); @@ -7809,7 +7865,7 @@ X86TargetLowering::EmitAtomicBit6432WithCustomInserter(MachineInstr *bInstr, else MIB = BuildMI(newMBB, dl, TII->get(immOpcH), t6); if (regOpcH != X86::MOV32rr) - MIB.addReg(tt2); + MIB.addReg(t2); (*MIB).addOperand(*argOpers[valArgIndx + 1]); MIB = BuildMI(newMBB, dl, TII->get(copyOpc), X86::EAX); @@ -9108,6 +9164,64 @@ static SDValue PerformShiftCombine(SDNode* N, SelectionDAG &DAG, return SDValue(); } +static SDValue PerformOrCombine(SDNode *N, SelectionDAG &DAG, + const X86Subtarget *Subtarget) { + EVT VT = N->getValueType(0); + if (VT != MVT::i64 || !Subtarget->is64Bit()) + return SDValue(); + + // fold (or (x << c) | (y >> (64 - c))) ==> (shld64 x, y, c) + SDValue N0 = N->getOperand(0); + SDValue N1 = N->getOperand(1); + if (N0.getOpcode() == ISD::SRL && N1.getOpcode() == ISD::SHL) + std::swap(N0, N1); + if (N0.getOpcode() != ISD::SHL || N1.getOpcode() != ISD::SRL) + return SDValue(); + + SDValue ShAmt0 = N0.getOperand(1); + if (ShAmt0.getValueType() != MVT::i8) + return SDValue(); + SDValue ShAmt1 = N1.getOperand(1); + if (ShAmt1.getValueType() != MVT::i8) + return SDValue(); + if (ShAmt0.getOpcode() == ISD::TRUNCATE) + ShAmt0 = ShAmt0.getOperand(0); + if (ShAmt1.getOpcode() == ISD::TRUNCATE) + ShAmt1 = ShAmt1.getOperand(0); + + DebugLoc DL = N->getDebugLoc(); + unsigned Opc = X86ISD::SHLD; + SDValue Op0 = N0.getOperand(0); + SDValue Op1 = N1.getOperand(0); + if (ShAmt0.getOpcode() == ISD::SUB) { + Opc = X86ISD::SHRD; + std::swap(Op0, Op1); + std::swap(ShAmt0, ShAmt1); + } + + if (ShAmt1.getOpcode() == ISD::SUB) { + SDValue Sum = ShAmt1.getOperand(0); + if (ConstantSDNode *SumC = dyn_cast(Sum)) { + if (SumC->getSExtValue() == 64 && + ShAmt1.getOperand(1) == ShAmt0) + return DAG.getNode(Opc, DL, VT, + Op0, Op1, + DAG.getNode(ISD::TRUNCATE, DL, + MVT::i8, ShAmt0)); + } + } else if (ConstantSDNode *ShAmt1C = dyn_cast(ShAmt1)) { + ConstantSDNode *ShAmt0C = dyn_cast(ShAmt0); + if (ShAmt0C && + ShAmt0C->getSExtValue() + ShAmt1C->getSExtValue() == 64) + return DAG.getNode(Opc, DL, VT, + N0.getOperand(0), N1.getOperand(0), + DAG.getNode(ISD::TRUNCATE, DL, + MVT::i8, ShAmt0)); + } + + return SDValue(); +} + /// PerformSTORECombine - Do target-specific dag combines on STORE nodes. static SDValue PerformSTORECombine(SDNode *N, SelectionDAG &DAG, const X86Subtarget *Subtarget) { @@ -9370,6 +9484,7 @@ SDValue X86TargetLowering::PerformDAGCombine(SDNode *N, case ISD::SHL: case ISD::SRA: case ISD::SRL: return PerformShiftCombine(N, DAG, Subtarget); + case ISD::OR: return PerformOrCombine(N, DAG, Subtarget); case ISD::STORE: return PerformSTORECombine(N, DAG, Subtarget); case X86ISD::FXOR: case X86ISD::FOR: return PerformFORCombine(N, DAG); @@ -9423,7 +9538,7 @@ bool X86TargetLowering::ExpandInlineAsm(CallInst *CI) const { std::string AsmStr = IA->getAsmString(); // TODO: should remove alternatives from the asmstring: "foo {a|b}" -> "foo a" - std::vector AsmPieces; + SmallVector AsmPieces; SplitString(AsmStr, AsmPieces, "\n"); // ; as separator? switch (AsmPieces.size()) { @@ -9445,7 +9560,7 @@ bool X86TargetLowering::ExpandInlineAsm(CallInst *CI) const { return LowerToBSwap(CI); } // rorw $$8, ${0:w} --> llvm.bswap.i16 - if (CI->getType() == Type::getInt16Ty(CI->getContext()) && + if (CI->getType()->isInteger(16) && AsmPieces.size() == 3 && AsmPieces[0] == "rorw" && AsmPieces[1] == "$$8," && @@ -9455,12 +9570,12 @@ bool X86TargetLowering::ExpandInlineAsm(CallInst *CI) const { } break; case 3: - if (CI->getType() == Type::getInt64Ty(CI->getContext()) && + if (CI->getType()->isInteger(64) && Constraints.size() >= 2 && Constraints[0].Codes.size() == 1 && Constraints[0].Codes[0] == "A" && Constraints[1].Codes.size() == 1 && Constraints[1].Codes[0] == "0") { // bswap %eax / bswap %edx / xchgl %eax, %edx -> llvm.bswap.i64 - std::vector Words; + SmallVector Words; SplitString(AsmPieces[0], Words, " \t"); if (Words.size() == 2 && Words[0] == "bswap" && Words[1] == "%eax") { Words.clear(); diff --git a/lib/Target/X86/X86Instr64bit.td b/lib/Target/X86/X86Instr64bit.td index 65fbbda..08e1dd1 100644 --- a/lib/Target/X86/X86Instr64bit.td +++ b/lib/Target/X86/X86Instr64bit.td @@ -1106,13 +1106,13 @@ def OR64rm : RI<0x0B, MRMSrcMem , (outs GR64:$dst), def OR64ri8 : RIi8<0x83, MRM1r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2), "or{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (or GR64:$src1, i64immSExt8:$src2)), - (implicit EFLAGS)]>; + [(set GR64:$dst, (or GR64:$src1, i64immSExt8:$src2)), + (implicit EFLAGS)]>; def OR64ri32 : RIi32<0x81, MRM1r, (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2), "or{q}\t{$src2, $dst|$dst, $src2}", - [(set GR64:$dst, (or GR64:$src1, i64immSExt32:$src2)), - (implicit EFLAGS)]>; + [(set GR64:$dst, (or GR64:$src1, i64immSExt32:$src2)), + (implicit EFLAGS)]>; } // isTwoAddress def OR64mr : RI<0x09, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src), @@ -1598,17 +1598,21 @@ def SLDT64m : RI<0x00, MRM0m, (outs i16mem:$dst), (ins), // Alias Instructions //===----------------------------------------------------------------------===// -// Alias instructions that map movr0 to xor. Use xorl instead of xorq; it's -// equivalent due to implicit zero-extending, and it sometimes has a smaller -// encoding. +// We want to rewrite MOV64r0 in terms of MOV32r0, because it's sometimes a +// smaller encoding, but doing so at isel time interferes with rematerialization +// in the current register allocator. For now, this is rewritten when the +// instruction is lowered to an MCInst. // FIXME: AddedComplexity gives this a higher priority than MOV64ri32. Remove // when we have a better way to specify isel priority. -let AddedComplexity = 1 in -def : Pat<(i64 0), - (SUBREG_TO_REG (i64 0), (MOV32r0), x86_subreg_32bit)>; - - -// Materialize i64 constant where top 32-bits are zero. +let Defs = [EFLAGS], + AddedComplexity = 1, isReMaterializable = 1, isAsCheapAsAMove = 1 in +def MOV64r0 : I<0x31, MRMInitReg, (outs GR64:$dst), (ins), + "", + [(set GR64:$dst, 0)]>; + +// Materialize i64 constant where top 32-bits are zero. This could theoretically +// use MOV32ri with a SUBREG_TO_REG to represent the zero-extension, however +// that would make it more difficult to rematerialize. let AddedComplexity = 1, isReMaterializable = 1, isAsCheapAsAMove = 1 in def MOV64ri64i32 : Ii32<0xB8, AddRegFrm, (outs GR64:$dst), (ins i64i32imm:$src), "", [(set GR64:$dst, i64immZExt32:$src)]>; @@ -1683,6 +1687,7 @@ def CMPXCHG64rr : RI<0xB1, MRMDestReg, (outs GR64:$dst), (ins GR64:$src), def CMPXCHG64rm : RI<0xB1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src), "cmpxchg{q}\t{$src, $dst|$dst, $src}", []>, TB; +let Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RBX, RCX, RDX] in def CMPXCHG16B : RI<0xC7, MRM1m, (outs), (ins i128mem:$dst), "cmpxchg16b\t$dst", []>, TB; @@ -1962,6 +1967,17 @@ def : Pat<(add GR64:$src1, 0x0000000080000000), def : Pat<(store (add (loadi64 addr:$dst), 0x00000000800000000), addr:$dst), (SUB64mi32 addr:$dst, 0xffffffff80000000)>; +// Use a 32-bit and with implicit zero-extension instead of a 64-bit and if it +// has an immediate with at least 32 bits of leading zeros, to avoid needing to +// materialize that immediate in a register first. +def : Pat<(and GR64:$src, i64immZExt32:$imm), + (SUBREG_TO_REG + (i64 0), + (AND32ri + (EXTRACT_SUBREG GR64:$src, x86_subreg_32bit), + imm:$imm), + x86_subreg_32bit)>; + // r & (2^32-1) ==> movz def : Pat<(and GR64:$src, 0x00000000FFFFFFFF), (MOVZX64rr32 (EXTRACT_SUBREG GR64:$src, x86_subreg_32bit))>; @@ -2028,7 +2044,7 @@ def : Pat<(and (srl_su GR32:$src, (i8 8)), (i32 255)), (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS GR32:$src, GR32_ABCD)), x86_subreg_8bit_hi))>, Requires<[In64BitMode]>; -def : Pat<(srl_su GR16:$src, (i8 8)), +def : Pat<(srl GR16:$src, (i8 8)), (EXTRACT_SUBREG (MOVZX32_NOREXrr8 (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)), @@ -2098,24 +2114,7 @@ def : Pat<(sra GR64:$src1, (and CL:$amt, 63)), def : Pat<(store (sra (loadi64 addr:$dst), (and CL:$amt, 63)), addr:$dst), (SAR64mCL addr:$dst)>; -// (or (x >> c) | (y << (64 - c))) ==> (shrd64 x, y, c) -def : Pat<(or (srl GR64:$src1, CL:$amt), - (shl GR64:$src2, (sub 64, CL:$amt))), - (SHRD64rrCL GR64:$src1, GR64:$src2)>; - -def : Pat<(store (or (srl (loadi64 addr:$dst), CL:$amt), - (shl GR64:$src2, (sub 64, CL:$amt))), addr:$dst), - (SHRD64mrCL addr:$dst, GR64:$src2)>; - -def : Pat<(or (srl GR64:$src1, (i8 (trunc RCX:$amt))), - (shl GR64:$src2, (i8 (trunc (sub 64, RCX:$amt))))), - (SHRD64rrCL GR64:$src1, GR64:$src2)>; - -def : Pat<(store (or (srl (loadi64 addr:$dst), (i8 (trunc RCX:$amt))), - (shl GR64:$src2, (i8 (trunc (sub 64, RCX:$amt))))), - addr:$dst), - (SHRD64mrCL addr:$dst, GR64:$src2)>; - +// Double shift patterns def : Pat<(shrd GR64:$src1, (i8 imm:$amt1), GR64:$src2, (i8 imm:$amt2)), (SHRD64rri8 GR64:$src1, GR64:$src2, (i8 imm:$amt1))>; @@ -2123,24 +2122,6 @@ def : Pat<(store (shrd (loadi64 addr:$dst), (i8 imm:$amt1), GR64:$src2, (i8 imm:$amt2)), addr:$dst), (SHRD64mri8 addr:$dst, GR64:$src2, (i8 imm:$amt1))>; -// (or (x << c) | (y >> (64 - c))) ==> (shld64 x, y, c) -def : Pat<(or (shl GR64:$src1, CL:$amt), - (srl GR64:$src2, (sub 64, CL:$amt))), - (SHLD64rrCL GR64:$src1, GR64:$src2)>; - -def : Pat<(store (or (shl (loadi64 addr:$dst), CL:$amt), - (srl GR64:$src2, (sub 64, CL:$amt))), addr:$dst), - (SHLD64mrCL addr:$dst, GR64:$src2)>; - -def : Pat<(or (shl GR64:$src1, (i8 (trunc RCX:$amt))), - (srl GR64:$src2, (i8 (trunc (sub 64, RCX:$amt))))), - (SHLD64rrCL GR64:$src1, GR64:$src2)>; - -def : Pat<(store (or (shl (loadi64 addr:$dst), (i8 (trunc RCX:$amt))), - (srl GR64:$src2, (i8 (trunc (sub 64, RCX:$amt))))), - addr:$dst), - (SHLD64mrCL addr:$dst, GR64:$src2)>; - def : Pat<(shld GR64:$src1, (i8 imm:$amt1), GR64:$src2, (i8 imm:$amt2)), (SHLD64rri8 GR64:$src1, GR64:$src2, (i8 imm:$amt1))>; @@ -2148,6 +2129,19 @@ def : Pat<(store (shld (loadi64 addr:$dst), (i8 imm:$amt1), GR64:$src2, (i8 imm:$amt2)), addr:$dst), (SHLD64mri8 addr:$dst, GR64:$src2, (i8 imm:$amt1))>; +// (or x1, x2) -> (add x1, x2) if two operands are known not to share bits. +let AddedComplexity = 5 in { // Try this before the selecting to OR +def : Pat<(parallel (or_is_add GR64:$src1, i64immSExt8:$src2), + (implicit EFLAGS)), + (ADD64ri8 GR64:$src1, i64immSExt8:$src2)>; +def : Pat<(parallel (or_is_add GR64:$src1, i64immSExt32:$src2), + (implicit EFLAGS)), + (ADD64ri32 GR64:$src1, i64immSExt32:$src2)>; +def : Pat<(parallel (or_is_add GR64:$src1, GR64:$src2), + (implicit EFLAGS)), + (ADD64rr GR64:$src1, GR64:$src2)>; +} // AddedComplexity + // X86 specific add which produces a flag. def : Pat<(addc GR64:$src1, GR64:$src2), (ADD64rr GR64:$src1, GR64:$src2)>; diff --git a/lib/Target/X86/X86InstrInfo.cpp b/lib/Target/X86/X86InstrInfo.cpp index e555cd1..7b39fb3 100644 --- a/lib/Target/X86/X86InstrInfo.cpp +++ b/lib/Target/X86/X86InstrInfo.cpp @@ -28,6 +28,7 @@ #include "llvm/CodeGen/LiveVariables.h" #include "llvm/CodeGen/PseudoSourceValue.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetOptions.h" @@ -711,6 +712,62 @@ bool X86InstrInfo::isMoveInstr(const MachineInstr& MI, } } +bool +X86InstrInfo::isCoalescableExtInstr(const MachineInstr &MI, + unsigned &SrcReg, unsigned &DstReg, + unsigned &SubIdx) const { + switch (MI.getOpcode()) { + default: break; + case X86::MOVSX16rr8: + case X86::MOVZX16rr8: + case X86::MOVSX32rr8: + case X86::MOVZX32rr8: + case X86::MOVSX64rr8: + case X86::MOVZX64rr8: + if (!TM.getSubtarget().is64Bit()) + // It's not always legal to reference the low 8-bit of the larger + // register in 32-bit mode. + return false; + case X86::MOVSX32rr16: + case X86::MOVZX32rr16: + case X86::MOVSX64rr16: + case X86::MOVZX64rr16: + case X86::MOVSX64rr32: + case X86::MOVZX64rr32: { + if (MI.getOperand(0).getSubReg() || MI.getOperand(1).getSubReg()) + // Be conservative. + return false; + SrcReg = MI.getOperand(1).getReg(); + DstReg = MI.getOperand(0).getReg(); + switch (MI.getOpcode()) { + default: + llvm_unreachable(0); + break; + case X86::MOVSX16rr8: + case X86::MOVZX16rr8: + case X86::MOVSX32rr8: + case X86::MOVZX32rr8: + case X86::MOVSX64rr8: + case X86::MOVZX64rr8: + SubIdx = 1; + break; + case X86::MOVSX32rr16: + case X86::MOVZX32rr16: + case X86::MOVSX64rr16: + case X86::MOVZX64rr16: + SubIdx = 3; + break; + case X86::MOVSX64rr32: + case X86::MOVZX64rr32: + SubIdx = 4; + break; + } + return true; + } + } + return false; +} + /// isFrameOperand - Return true and the FrameIndex if the specified /// operand and follow operands form a reference to the stack frame. bool X86InstrInfo::isFrameOperand(const MachineInstr *MI, unsigned int Op, @@ -1018,12 +1075,16 @@ void X86InstrInfo::reMaterialize(MachineBasicBlock &MBB, switch (Opc) { default: break; case X86::MOV8r0: - case X86::MOV32r0: { + case X86::MOV16r0: + case X86::MOV32r0: + case X86::MOV64r0: { if (!isSafeToClobberEFLAGS(MBB, I)) { switch (Opc) { default: break; case X86::MOV8r0: Opc = X86::MOV8ri; break; + case X86::MOV16r0: Opc = X86::MOV16ri; break; case X86::MOV32r0: Opc = X86::MOV32ri; break; + case X86::MOV64r0: Opc = X86::MOV64ri; break; } Clone = false; } @@ -2290,8 +2351,12 @@ X86InstrInfo::foldMemoryOperandImpl(MachineFunction &MF, OpcodeTablePtr = &RegOp2MemOpTable2Addr; isTwoAddrFold = true; } else if (i == 0) { // If operand 0 - if (MI->getOpcode() == X86::MOV32r0) + if (MI->getOpcode() == X86::MOV64r0) + NewMI = MakeM0Inst(*this, X86::MOV64mi32, MOs, MI); + else if (MI->getOpcode() == X86::MOV32r0) NewMI = MakeM0Inst(*this, X86::MOV32mi, MOs, MI); + else if (MI->getOpcode() == X86::MOV16r0) + NewMI = MakeM0Inst(*this, X86::MOV16mi, MOs, MI); else if (MI->getOpcode() == X86::MOV8r0) NewMI = MakeM0Inst(*this, X86::MOV8mi, MOs, MI); if (NewMI) @@ -2354,7 +2419,7 @@ X86InstrInfo::foldMemoryOperandImpl(MachineFunction &MF, // No fusion if (PrintFailedFusing) - errs() << "We failed to fuse operand " << i << " in " << *MI; + dbgs() << "We failed to fuse operand " << i << " in " << *MI; return NULL; } @@ -2559,7 +2624,9 @@ bool X86InstrInfo::canFoldMemoryOperand(const MachineInstr *MI, } else if (OpNum == 0) { // If operand 0 switch (Opc) { case X86::MOV8r0: + case X86::MOV16r0: case X86::MOV32r0: + case X86::MOV64r0: return true; default: break; } diff --git a/lib/Target/X86/X86InstrInfo.h b/lib/Target/X86/X86InstrInfo.h index b83441d..0ab85f4 100644 --- a/lib/Target/X86/X86InstrInfo.h +++ b/lib/Target/X86/X86InstrInfo.h @@ -448,6 +448,16 @@ public: unsigned &SrcReg, unsigned &DstReg, unsigned &SrcSubIdx, unsigned &DstSubIdx) const; + /// isCoalescableExtInstr - Return true if the instruction is a "coalescable" + /// extension instruction. That is, it's like a copy where it's legal for the + /// source to overlap the destination. e.g. X86::MOVSX64rr32. If this returns + /// true, then it's expected the pre-extension value is available as a subreg + /// of the result register. This also returns the sub-register index in + /// SubIdx. + virtual bool isCoalescableExtInstr(const MachineInstr &MI, + unsigned &SrcReg, unsigned &DstReg, + unsigned &SubIdx) const; + unsigned isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const; /// isLoadFromStackSlotPostFE - Check for post-frame ptr elimination /// stack locations as well. This uses a heuristic so it isn't diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td index 4d922a5..396cb53 100644 --- a/lib/Target/X86/X86InstrInfo.td +++ b/lib/Target/X86/X86InstrInfo.td @@ -160,15 +160,21 @@ def X86ehret : SDNode<"X86ISD::EH_RETURN", SDT_X86EHRET, def X86tcret : SDNode<"X86ISD::TC_RETURN", SDT_X86TCRET, [SDNPHasChain, SDNPOptInFlag]>; -def X86add_flag : SDNode<"X86ISD::ADD", SDTBinaryArithWithFlags>; +def X86add_flag : SDNode<"X86ISD::ADD", SDTBinaryArithWithFlags, + [SDNPCommutative]>; def X86sub_flag : SDNode<"X86ISD::SUB", SDTBinaryArithWithFlags>; -def X86smul_flag : SDNode<"X86ISD::SMUL", SDTBinaryArithWithFlags>; -def X86umul_flag : SDNode<"X86ISD::UMUL", SDTUnaryArithWithFlags>; +def X86smul_flag : SDNode<"X86ISD::SMUL", SDTBinaryArithWithFlags, + [SDNPCommutative]>; +def X86umul_flag : SDNode<"X86ISD::UMUL", SDTUnaryArithWithFlags, + [SDNPCommutative]>; def X86inc_flag : SDNode<"X86ISD::INC", SDTUnaryArithWithFlags>; def X86dec_flag : SDNode<"X86ISD::DEC", SDTUnaryArithWithFlags>; -def X86or_flag : SDNode<"X86ISD::OR", SDTBinaryArithWithFlags>; -def X86xor_flag : SDNode<"X86ISD::XOR", SDTBinaryArithWithFlags>; -def X86and_flag : SDNode<"X86ISD::AND", SDTBinaryArithWithFlags>; +def X86or_flag : SDNode<"X86ISD::OR", SDTBinaryArithWithFlags, + [SDNPCommutative]>; +def X86xor_flag : SDNode<"X86ISD::XOR", SDTBinaryArithWithFlags, + [SDNPCommutative]>; +def X86and_flag : SDNode<"X86ISD::AND", SDTBinaryArithWithFlags, + [SDNPCommutative]>; def X86mul_imm : SDNode<"X86ISD::MUL_IMM", SDTIntBinOp>; @@ -487,6 +493,21 @@ def trunc_su : PatFrag<(ops node:$src), (trunc node:$src), [{ return N->hasOneUse(); }]>; +// Treat an 'or' node is as an 'add' if the or'ed bits are known to be zero. +def or_is_add : PatFrag<(ops node:$lhs, node:$rhs), (or node:$lhs, node:$rhs),[{ + if (ConstantSDNode *CN = dyn_cast(N->getOperand(1))) + return CurDAG->MaskedValueIsZero(N->getOperand(0), CN->getAPIntValue()); + else { + unsigned BitWidth = N->getValueType(0).getScalarType().getSizeInBits(); + APInt Mask = APInt::getAllOnesValue(BitWidth); + APInt KnownZero0, KnownOne0; + CurDAG->ComputeMaskedBits(N->getOperand(0), Mask, KnownZero0, KnownOne0, 0); + APInt KnownZero1, KnownOne1; + CurDAG->ComputeMaskedBits(N->getOperand(1), Mask, KnownZero1, KnownOne1, 0); + return (~KnownZero0 & ~KnownZero1) == 0; + } +}]>; + // 'shld' and 'shrd' instruction patterns. Note that even though these have // the srl and shl in their patterns, the C++ code must still check for them, // because predicates are tested before children nodes are explored. @@ -3700,18 +3721,21 @@ let Defs = [EFLAGS], isReMaterializable = 1, isAsCheapAsAMove = 1, def MOV8r0 : I<0x30, MRMInitReg, (outs GR8 :$dst), (ins), "xor{b}\t$dst, $dst", [(set GR8:$dst, 0)]>; + +// We want to rewrite MOV16r0 in terms of MOV32r0, because it's a smaller +// encoding and avoids a partial-register update sometimes, but doing so +// at isel time interferes with rematerialization in the current register +// allocator. For now, this is rewritten when the instruction is lowered +// to an MCInst. +def MOV16r0 : I<0x31, MRMInitReg, (outs GR16:$dst), (ins), + "", + [(set GR16:$dst, 0)]>, OpSize; def MOV32r0 : I<0x31, MRMInitReg, (outs GR32:$dst), (ins), "xor{l}\t$dst, $dst", [(set GR32:$dst, 0)]>; } -// Use xorl instead of xorw since we don't care about the high 16 bits, -// it's smaller, and it avoids a partial-register update. -let AddedComplexity = 1 in -def : Pat<(i16 0), - (EXTRACT_SUBREG (MOV32r0), x86_subreg_16bit)>; - //===----------------------------------------------------------------------===// // Thread Local Storage Instructions // @@ -3792,7 +3816,7 @@ def LCMPXCHG32 : I<0xB1, MRMDestMem, (outs), (ins i32mem:$ptr, GR32:$swap), [(X86cas addr:$ptr, GR32:$swap, 4)]>, TB, LOCK; } let Defs = [EAX, EDX, EFLAGS], Uses = [EAX, EBX, ECX, EDX] in { -def LCMPXCHG8B : I<0xC7, MRM1m, (outs), (ins i32mem:$ptr), +def LCMPXCHG8B : I<0xC7, MRM1m, (outs), (ins i64mem:$ptr), "lock\n\t" "cmpxchg8b\t$ptr", [(X86cas8 addr:$ptr)]>, TB, LOCK; @@ -3858,6 +3882,7 @@ def CMPXCHG16rm : I<0xB1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src), def CMPXCHG32rm : I<0xB1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src), "cmpxchg{l}\t{$src, $dst|$dst, $src}", []>, TB; +let Defs = [EAX, EDX, EFLAGS], Uses = [EAX, EBX, ECX, EDX] in def CMPXCHG8B : I<0xC7, MRM1m, (outs), (ins i64mem:$dst), "cmpxchg8b\t$dst", []>, TB; @@ -4466,7 +4491,7 @@ def : Pat<(i8 (trunc (srl_su GR32:$src, (i8 8)))), (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR32:$src, GR32_ABCD)), x86_subreg_8bit_hi)>, Requires<[In32BitMode]>; -def : Pat<(srl_su GR16:$src, (i8 8)), +def : Pat<(srl GR16:$src, (i8 8)), (EXTRACT_SUBREG (MOVZX32rr8 (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)), @@ -4640,6 +4665,28 @@ def : Pat<(i16 (anyext (i8 (X86setcc_c X86_COND_B, EFLAGS)))), def : Pat<(i32 (anyext (i8 (X86setcc_c X86_COND_B, EFLAGS)))), (SETB_C32r)>; +// (or x1, x2) -> (add x1, x2) if two operands are known not to share bits. +let AddedComplexity = 5 in { // Try this before the selecting to OR +def : Pat<(parallel (or_is_add GR16:$src1, imm:$src2), + (implicit EFLAGS)), + (ADD16ri GR16:$src1, imm:$src2)>; +def : Pat<(parallel (or_is_add GR32:$src1, imm:$src2), + (implicit EFLAGS)), + (ADD32ri GR32:$src1, imm:$src2)>; +def : Pat<(parallel (or_is_add GR16:$src1, i16immSExt8:$src2), + (implicit EFLAGS)), + (ADD16ri8 GR16:$src1, i16immSExt8:$src2)>; +def : Pat<(parallel (or_is_add GR32:$src1, i32immSExt8:$src2), + (implicit EFLAGS)), + (ADD32ri8 GR32:$src1, i32immSExt8:$src2)>; +def : Pat<(parallel (or_is_add GR16:$src1, GR16:$src2), + (implicit EFLAGS)), + (ADD16rr GR16:$src1, GR16:$src2)>; +def : Pat<(parallel (or_is_add GR32:$src1, GR32:$src2), + (implicit EFLAGS)), + (ADD32rr GR32:$src1, GR32:$src2)>; +} // AddedComplexity + //===----------------------------------------------------------------------===// // EFLAGS-defining Patterns //===----------------------------------------------------------------------===// diff --git a/lib/Target/X86/X86InstrSSE.td b/lib/Target/X86/X86InstrSSE.td index b26e508..94b9b55 100644 --- a/lib/Target/X86/X86InstrSSE.td +++ b/lib/Target/X86/X86InstrSSE.td @@ -131,11 +131,13 @@ def alignedloadv2i64 : PatFrag<(ops node:$ptr), // Like 'load', but uses special alignment checks suitable for use in // memory operands in most SSE instructions, which are required to -// be naturally aligned on some targets but not on others. -// FIXME: Actually implement support for targets that don't require the -// alignment. This probably wants a subtarget predicate. +// be naturally aligned on some targets but not on others. If the subtarget +// allows unaligned accesses, match any load, though this may require +// setting a feature bit in the processor (on startup, for example). +// Opteron 10h and later implement such a feature. def memop : PatFrag<(ops node:$ptr), (load node:$ptr), [{ - return cast(N)->getAlignment() >= 16; + return Subtarget->hasVectorUAMem() + || cast(N)->getAlignment() >= 16; }]>; def memopfsf32 : PatFrag<(ops node:$ptr), (f32 (memop node:$ptr))>; diff --git a/lib/Target/X86/X86JITInfo.cpp b/lib/Target/X86/X86JITInfo.cpp index c69cc83..f363903 100644 --- a/lib/Target/X86/X86JITInfo.cpp +++ b/lib/Target/X86/X86JITInfo.cpp @@ -348,7 +348,7 @@ X86CompilationCallback2(intptr_t *StackPtr, intptr_t RetAddr) { #endif #if 0 - DEBUG(errs() << "In callback! Addr=" << (void*)RetAddr + DEBUG(dbgs() << "In callback! Addr=" << (void*)RetAddr << " ESP=" << (void*)StackPtr << ": Resolving call to function: " << TheVM->getFunctionReferencedName((void*)RetAddr) << "\n"); diff --git a/lib/Target/X86/X86RegisterInfo.cpp b/lib/Target/X86/X86RegisterInfo.cpp index d96aafd..9bd96af 100644 --- a/lib/Target/X86/X86RegisterInfo.cpp +++ b/lib/Target/X86/X86RegisterInfo.cpp @@ -591,6 +591,15 @@ X86RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, int FrameIndex = MI.getOperand(i).getIndex(); unsigned BasePtr; + // DEBUG_VALUE has a special representation, and is only robust enough to + // represent SP(or BP) +- offset addressing modes. We rewrite the + // FrameIndex to be a constant; implicitly positive constants are relative + // to ESP and negative ones to EBP. + if (MI.getOpcode()==TargetInstrInfo::DEBUG_VALUE) { + MI.getOperand(i).ChangeToImmediate(getFrameIndexOffset(MF, FrameIndex)); + return 0; + } + if (needsStackRealignment(MF)) BasePtr = (FrameIndex < 0 ? FramePtr : StackPtr); else diff --git a/lib/Target/X86/X86Subtarget.cpp b/lib/Target/X86/X86Subtarget.cpp index 75cdbad..2039be7 100644 --- a/lib/Target/X86/X86Subtarget.cpp +++ b/lib/Target/X86/X86Subtarget.cpp @@ -286,6 +286,7 @@ X86Subtarget::X86Subtarget(const std::string &TT, const std::string &FS, , HasFMA3(false) , HasFMA4(false) , IsBTMemSlow(false) + , HasVectorUAMem(false) , DarwinVers(0) , stackAlignment(8) // FIXME: this is a known good value for Yonah. How about others? @@ -317,7 +318,7 @@ X86Subtarget::X86Subtarget(const std::string &TT, const std::string &FS, if (Is64Bit) HasX86_64 = true; - DEBUG(errs() << "Subtarget features: SSELevel " << X86SSELevel + DEBUG(dbgs() << "Subtarget features: SSELevel " << X86SSELevel << ", 3DNowLevel " << X863DNowLevel << ", 64bit " << HasX86_64 << "\n"); assert((!Is64Bit || HasX86_64) && diff --git a/lib/Target/X86/X86Subtarget.h b/lib/Target/X86/X86Subtarget.h index ef6dbaf..618dd10 100644 --- a/lib/Target/X86/X86Subtarget.h +++ b/lib/Target/X86/X86Subtarget.h @@ -78,6 +78,10 @@ protected: /// IsBTMemSlow - True if BT (bit test) of memory instructions are slow. bool IsBTMemSlow; + /// HasVectorUAMem - True if SIMD operations can have unaligned memory operands. + /// This may require setting a feature bit in the processor. + bool HasVectorUAMem; + /// DarwinVers - Nonzero if this is a darwin platform: the numeric /// version of the platform, e.g. 8 = 10.4 (Tiger), 9 = 10.5 (Leopard), etc. unsigned char DarwinVers; // Is any darwin-x86 platform. @@ -142,6 +146,7 @@ public: bool hasFMA3() const { return HasFMA3; } bool hasFMA4() const { return HasFMA4; } bool isBTMemSlow() const { return IsBTMemSlow; } + bool hasVectorUAMem() const { return HasVectorUAMem; } bool isTargetDarwin() const { return TargetType == isDarwin; } bool isTargetELF() const { return TargetType == isELF; } @@ -169,7 +174,7 @@ public: p = "e-p:64:64-s:64-f64:64:64-i64:64:64-f80:128:128-n8:16:32:64"; else if (isTargetDarwin()) p = "e-p:32:32-f64:32:64-i64:32:64-f80:128:128-n8:16:32"; - else if (isTargetCygMing() || isTargetWindows()) + else if (isTargetMingw() || isTargetWindows()) p = "e-p:32:32-f64:64:64-i64:64:64-f80:128:128-n8:16:32"; else p = "e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32"; diff --git a/lib/Target/XCore/XCoreISelDAGToDAG.cpp b/lib/Target/XCore/XCoreISelDAGToDAG.cpp index da2fb04..383fd91 100644 --- a/lib/Target/XCore/XCoreISelDAGToDAG.cpp +++ b/lib/Target/XCore/XCoreISelDAGToDAG.cpp @@ -49,7 +49,7 @@ namespace { Lowering(*TM.getTargetLowering()), Subtarget(*TM.getSubtargetImpl()) { } - SDNode *Select(SDValue Op); + SDNode *Select(SDNode *N); /// getI32Imm - Return a target constant with the specified value, of type /// i32. @@ -58,11 +58,11 @@ namespace { } // Complex Pattern Selectors. - bool SelectADDRspii(SDValue Op, SDValue Addr, SDValue &Base, + bool SelectADDRspii(SDNode *Op, SDValue Addr, SDValue &Base, SDValue &Offset); - bool SelectADDRdpii(SDValue Op, SDValue Addr, SDValue &Base, + bool SelectADDRdpii(SDNode *Op, SDValue Addr, SDValue &Base, SDValue &Offset); - bool SelectADDRcpii(SDValue Op, SDValue Addr, SDValue &Base, + bool SelectADDRcpii(SDNode *Op, SDValue Addr, SDValue &Base, SDValue &Offset); virtual void InstructionSelect(); @@ -83,7 +83,7 @@ FunctionPass *llvm::createXCoreISelDag(XCoreTargetMachine &TM) { return new XCoreDAGToDAGISel(TM); } -bool XCoreDAGToDAGISel::SelectADDRspii(SDValue Op, SDValue Addr, +bool XCoreDAGToDAGISel::SelectADDRspii(SDNode *Op, SDValue Addr, SDValue &Base, SDValue &Offset) { FrameIndexSDNode *FIN = 0; if ((FIN = dyn_cast(Addr))) { @@ -105,7 +105,7 @@ bool XCoreDAGToDAGISel::SelectADDRspii(SDValue Op, SDValue Addr, return false; } -bool XCoreDAGToDAGISel::SelectADDRdpii(SDValue Op, SDValue Addr, +bool XCoreDAGToDAGISel::SelectADDRdpii(SDNode *Op, SDValue Addr, SDValue &Base, SDValue &Offset) { if (Addr.getOpcode() == XCoreISD::DPRelativeWrapper) { Base = Addr.getOperand(0); @@ -126,7 +126,7 @@ bool XCoreDAGToDAGISel::SelectADDRdpii(SDValue Op, SDValue Addr, return false; } -bool XCoreDAGToDAGISel::SelectADDRcpii(SDValue Op, SDValue Addr, +bool XCoreDAGToDAGISel::SelectADDRcpii(SDNode *Op, SDValue Addr, SDValue &Base, SDValue &Offset) { if (Addr.getOpcode() == XCoreISD::CPRelativeWrapper) { Base = Addr.getOperand(0); @@ -156,8 +156,7 @@ void XCoreDAGToDAGISel::InstructionSelect() { CurDAG->RemoveDeadNodes(); } -SDNode *XCoreDAGToDAGISel::Select(SDValue Op) { - SDNode *N = Op.getNode(); +SDNode *XCoreDAGToDAGISel::Select(SDNode *N) { DebugLoc dl = N->getDebugLoc(); EVT NVT = N->getValueType(0); if (NVT == MVT::i32) { @@ -185,7 +184,7 @@ SDNode *XCoreDAGToDAGISel::Select(SDValue Op) { // FIXME fold addition into the macc instruction SDValue Zero(CurDAG->getMachineNode(XCore::LDC_ru6, dl, MVT::i32, CurDAG->getTargetConstant(0, MVT::i32)), 0); - SDValue Ops[] = { Zero, Zero, Op.getOperand(0), Op.getOperand(1) }; + SDValue Ops[] = { Zero, Zero, N->getOperand(0), N->getOperand(1) }; SDNode *ResNode = CurDAG->getMachineNode(XCore::MACCS_l4r, dl, MVT::i32, MVT::i32, Ops, 4); ReplaceUses(SDValue(N, 0), SDValue(ResNode, 1)); @@ -196,7 +195,7 @@ SDNode *XCoreDAGToDAGISel::Select(SDValue Op) { // FIXME fold addition into the macc / lmul instruction SDValue Zero(CurDAG->getMachineNode(XCore::LDC_ru6, dl, MVT::i32, CurDAG->getTargetConstant(0, MVT::i32)), 0); - SDValue Ops[] = { Op.getOperand(0), Op.getOperand(1), + SDValue Ops[] = { N->getOperand(0), N->getOperand(1), Zero, Zero }; SDNode *ResNode = CurDAG->getMachineNode(XCore::LMUL_l6r, dl, MVT::i32, MVT::i32, Ops, 4); @@ -205,19 +204,19 @@ SDNode *XCoreDAGToDAGISel::Select(SDValue Op) { return NULL; } case XCoreISD::LADD: { - SDValue Ops[] = { Op.getOperand(0), Op.getOperand(1), - Op.getOperand(2) }; + SDValue Ops[] = { N->getOperand(0), N->getOperand(1), + N->getOperand(2) }; return CurDAG->getMachineNode(XCore::LADD_l5r, dl, MVT::i32, MVT::i32, Ops, 3); } case XCoreISD::LSUB: { - SDValue Ops[] = { Op.getOperand(0), Op.getOperand(1), - Op.getOperand(2) }; + SDValue Ops[] = { N->getOperand(0), N->getOperand(1), + N->getOperand(2) }; return CurDAG->getMachineNode(XCore::LSUB_l5r, dl, MVT::i32, MVT::i32, Ops, 3); } // Other cases are autogenerated. } } - return SelectCode(Op); + return SelectCode(N); } -- cgit v1.1